summaryrefslogtreecommitdiff
path: root/demo
diff options
context:
space:
mode:
Diffstat (limited to 'demo')
-rw-r--r--demo/console.c99
-rw-r--r--demo/demo.h4
-rw-r--r--demo/link.ld3
-rw-r--r--demo/main.c10
-rw-r--r--demo/start.S10
-rw-r--r--demo/util.c25
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;
+}