diff options
Diffstat (limited to 'demo')
| -rw-r--r-- | demo/console.c | 99 | ||||
| -rw-r--r-- | demo/demo.h | 4 | ||||
| -rw-r--r-- | demo/link.ld | 3 | ||||
| -rw-r--r-- | demo/main.c | 10 | ||||
| -rw-r--r-- | demo/start.S | 10 | ||||
| -rw-r--r-- | demo/util.c | 25 |
6 files changed, 143 insertions, 8 deletions
diff --git a/demo/console.c b/demo/console.c index e531b2e..b35ace7 100644 --- a/demo/console.c +++ b/demo/console.c @@ -1,11 +1,12 @@ #include <stdarg.h> +#include <stddef.h> #include "demo.h" -struct lock console_lock; - #define JTAG_UART_BASE 0x30000000 #define JTAG_UART_DATA (*(volatile unsigned *)(JTAG_UART_BASE + 0)) +#define JTAG_UART_DATA_RVALID (1 << 15) +#define JTAG_UART_DATA_RAVAIL 0xffff0000 #define JTAG_UART_CONTROL (*(volatile unsigned *)(JTAG_UART_BASE + 4)) #define JTAG_UART_CONTROL_RE (1 << 0) #define JTAG_UART_CONTROL_AC (1 << 10) @@ -16,6 +17,13 @@ struct lock console_lock; #define INTC_MASK_TIMER (1 << 0) #define INTC_MASK_UART (1 << 1) +static struct lock console_lock; + +static int input_run = 0; +static unsigned input_len = 0; +static unsigned input_max; +static char *input_buf; + static void print_char(char c) { while (!(JTAG_UART_CONTROL & JTAG_UART_CONTROL_WSPACE)); @@ -65,6 +73,9 @@ void console_init(void) { spin_init(&console_lock); + input_buf = NULL; + input_max = 0; + // Habilitar irqs de entrada uart JTAG_UART_CONTROL = JTAG_UART_CONTROL_RE; @@ -85,7 +96,11 @@ void print(const char *fmt, ...) while (!(JTAG_UART_CONTROL & JTAG_UART_CONTROL_AC)); - print_str("cpu"); + print_str("\r "); + for (unsigned i = 0; i < input_len; ++i) + print_char(' '); + + print_str("\rcpu"); print_dec(this_cpu->num); print_str(": "); @@ -137,9 +152,85 @@ void print(const char *fmt, ...) } } - print_str("\r\n"); + print_str("\r\n> "); + if (!input_run && input_buf) + print_str(input_buf); + JTAG_UART_CONTROL = JTAG_UART_CONTROL_RE | JTAG_UART_CONTROL_AC; spin_unlock(&console_lock, irq_save); va_end(args); } + +void read_line(char *buf, unsigned size) +{ + if (!size) + return; + + buf[0] = '\0'; + + unsigned irq_save; + spin_lock(&console_lock, &irq_save); + input_buf = buf; + input_max = size; + input_len = 0; + spin_unlock(&console_lock, irq_save); + + while (1) { + spin_lock(&console_lock, &irq_save); + if (input_run) + break; + + spin_unlock(&console_lock, irq_save); + } + + input_buf = NULL; + input_len = 0; + input_max = 0; + input_run = 0; + spin_unlock(&console_lock, irq_save); +} + +void irq(void) +{ + unsigned irq_save; + spin_lock(&console_lock, &irq_save); + + unsigned data; + do { + data = JTAG_UART_DATA; + if (!(data & JTAG_UART_DATA_RVALID)) + break; + else if (input_run || !input_buf) + continue; + + char c = (char)data; + + switch (c) { + case 0x7f: // DEL + if (input_len > 0) { + --input_len; + print_str("\b \b"); + } + + break; + + case '\n': + input_run = 1; + input_len = 0; + print_str("\r\n> "); + break; + + default: + if (input_len < input_max - 1 && c >= ' ' && c <= '~') { + print_char(c); + input_buf[input_len++] = c; + input_buf[input_len] = '\0'; + } + + break; + } + } while (data & JTAG_UART_DATA_RAVAIL); + + spin_unlock(&console_lock, irq_save); +} diff --git a/demo/demo.h b/demo/demo.h index 1bff8d6..28677f6 100644 --- a/demo/demo.h +++ b/demo/demo.h @@ -24,6 +24,7 @@ void spin_unlock(struct lock *lock, unsigned irq_save); void console_init(void); void print(const char *fmt, ...); +void read_line(char *vuf, unsigned size); int cpus_ready(void); void run_cpu(unsigned num); @@ -31,4 +32,7 @@ void run_cpus(unsigned mask); void halt_cpu(unsigned num); void halt_cpus(unsigned mask); +int strcmp(const char *s1, const char *s2); +char *strtok_input(char **tokens); + #endif diff --git a/demo/link.ld b/demo/link.ld index 5f400c7..8a4d40b 100644 --- a/demo/link.ld +++ b/demo/link.ld @@ -21,8 +21,9 @@ SECTIONS } > HPS_SDRAM _stack_shift = 13; - _stack_size = (1 << _stack_shift) * 4; + _stack_size = (1 << _stack_shift) * (4 + 1); # Hay un stack extra para irq _stack_end = ORIGIN(HPS_SDRAM) + LENGTH(HPS_SDRAM); + _irq_stack = _stack_end; _stack_begin = (_stack_end - _stack_size) + (1 << _stack_shift); . = _stack_begin; diff --git a/demo/main.c b/demo/main.c index b984d6f..f75f6f1 100644 --- a/demo/main.c +++ b/demo/main.c @@ -12,6 +12,16 @@ void bsp_main(void) print("booted %u cpus", NUM_CPUS); while (1) { + char input[64]; + read_line(input, sizeof input); + + char *tokens = input; + + char *cmd = strtok_input(&tokens); + if (!cmd) + continue; + + print("unknown command '%s'", cmd); } } diff --git a/demo/start.S b/demo/start.S index 6e5e457..a0a9a4f 100644 --- a/demo/start.S +++ b/demo/start.S @@ -19,7 +19,7 @@ __reserved: b . __irq: - b irq + b _irq_entry __fiq: b . @@ -47,10 +47,14 @@ _start: _boot_num: .word 0 -irq: +_irq_entry: + ldr sp, =_irq_stack + push {r0-r11, lr} + bl irq + pop {r0-r11, lr} subs pc, lr, #4 -.weak undefined, swi, data_abort, prefetch_abort, irq +.weak undefined, swi, data_abort, prefetch_abort .set swi, __swi .set undefined, __undefined .set data_abort, __data_abort diff --git a/demo/util.c b/demo/util.c index 457a32c..99566bd 100644 --- a/demo/util.c +++ b/demo/util.c @@ -1,3 +1,7 @@ +#include <stddef.h> + +#include "demo.h" + int strcmp(const char *s1, const char *s2) { while (*s1 && *s1 == *s2) @@ -5,3 +9,24 @@ int strcmp(const char *s1, const char *s2) return (int)*(const unsigned char *)s1 - (int)*(const unsigned char *)s2; } + +char *strtok_input(char **tokens) +{ + char *start = *tokens; + while (*start && *start == ' ') + ++start; + + if (!*start) { + *tokens = start; + return NULL; + } + + char *end = start + 1; + while (*end && *end != ' ') + ++end; + + *tokens = *end ? end + 1 : end; + *end = '\0'; + + return start; +} |
