1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
#include <stdarg.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_CONTROL (*(volatile unsigned *)(JTAG_UART_BASE + 4))
#define JTAG_UART_CONTROL_RE (1 << 0)
#define JTAG_UART_CONTROL_AC (1 << 10)
#define JTAG_UART_CONTROL_WSPACE 0xffff0000
#define INTC_BASE 0x30070000
#define INTC_MASK (*(volatile unsigned *)(INTC_BASE + 4))
#define INTC_MASK_TIMER (1 << 0)
#define INTC_MASK_UART (1 << 1)
static void print_char(char c)
{
while (!(JTAG_UART_CONTROL & JTAG_UART_CONTROL_WSPACE));
JTAG_UART_DATA = (unsigned char)c;
}
static void print_str(const char *s)
{
while (*s)
print_char(*s++);
}
static void print_hex(unsigned val, unsigned bits)
{
static const char hex_digits[16] = "0123456789abcdef";
print_str("0x");
if (bits < 4)
bits = 4;
if (bits > 32)
bits = 32;
bits = bits & ~3;
do
print_char(hex_digits[(val >> (bits -= 4)) & 0xf]);
while (bits);
}
static void print_dec(unsigned val)
{
char dec[11] = {'\0'};
char *next = dec;
do {
*next++ = '0' + val % 10;
val /= 10;
} while (val && next < dec + sizeof dec);
const char *c = next;
while (c > dec)
print_char(*--c);
}
void console_init(void)
{
spin_init(&console_lock);
// Habilitar irqs de entrada uart
JTAG_UART_CONTROL = JTAG_UART_CONTROL_RE;
// Habilitar irqs en controlador de interrupciones
INTC_MASK = INTC_MASK_UART;
// Habilitar irqs en core
asm volatile("msr cpsr_c, #0x53");
}
void print(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
unsigned irq_save;
spin_lock(&console_lock, &irq_save);
while (!(JTAG_UART_CONTROL & JTAG_UART_CONTROL_AC));
print_str("cpu");
print_dec(this_cpu->num);
print_str(": ");
char c;
while ((c = *fmt++)) {
if (c != '%') {
print_char(c);
continue;
}
unsigned val;
switch ((c = *fmt++)) {
case 'c':
print_char((char)va_arg(args, int));
break;
case 'd':
case 'i':
print_dec((unsigned)va_arg(args, int));
break;
case 'p':
print_hex((unsigned)va_arg(args, const void *), 32);
break;
case 'r':
val = va_arg(args, unsigned);
print_hex(val, va_arg(args, unsigned));
break;
case 'u':
print_dec(va_arg(args, unsigned));
break;
case 's':
print_str(va_arg(args, const char *));
break;
case 'x':
print_hex(va_arg(args, unsigned), 32);
break;
default:
print_char('%');
if (c)
print_char(c);
break;
}
}
print_str("\r\n");
JTAG_UART_CONTROL = JTAG_UART_CONTROL_RE | JTAG_UART_CONTROL_AC;
spin_unlock(&console_lock, irq_save);
va_end(args);
}
|