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
|
#include "demo.h"
static struct cpu cpu0, cpu1, cpu2, cpu3;
struct cpu *__cpus[] = { &cpu0, &cpu1, &cpu2, &cpu3 };
static volatile unsigned boot_done;
static void unknown_command(const char *cmd)
{
print("unknown command '%s'", cmd);
}
static void cmd_run(char **tokens)
{
unsigned mask;
if (parse_cpu_mask(tokens, &mask) < 0)
return;
run_cpus(mask);
}
static void cmd_halt(char **tokens)
{
unsigned mask;
if (parse_cpu_mask(tokens, &mask) < 0)
return;
halt_cpus(mask);
}
static void cmd_read(char **tokens)
{
void *ptr;
if (parse_aligned(tokens, &ptr) < 0 || expect_end(tokens) < 0)
return;
print("%p: %x", ptr, *(volatile unsigned *)ptr);
}
static void cmd_write(char **tokens)
{
void *ptr;
unsigned val;
if (parse_aligned(tokens, &ptr) < 0 || parse_hex(tokens, &val) < 0 || expect_end(tokens) < 0)
return;
*(volatile unsigned *)ptr = val;
}
static void cmd_cache(char **tokens)
{
void *ptr;
unsigned cpu;
if (parse_cpu(tokens, &cpu) < 0 || parse_ptr(tokens, &ptr) < 0)
return;
cache_debug(cpu, ptr);
}
static void cmd_perf(char **tokens)
{
unsigned cpu;
const char *cmd;
if (parse_cpu(tokens, &cpu) < 0)
return;
else if (!(cmd = strtok_input(tokens))) {
unexpected_eof();
return;
} else if (expect_end(tokens) < 0)
return;
if (!strcmp(cmd, "clear"))
perf_clear(cpu);
else if (!strcmp(cmd, "show"))
perf_show(cpu);
else
unknown_command(cmd);
}
static void bsp_main(void)
{
boot_done = 0;
run_cpu(1);
while (!boot_done);
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;
if (!strcmp(cmd, "run"))
cmd_run(&tokens);
else if (!strcmp(cmd, "halt"))
cmd_halt(&tokens);
else if (!strcmp(cmd, "read"))
cmd_read(&tokens);
else if (!strcmp(cmd, "write"))
cmd_write(&tokens);
else if (!strcmp(cmd, "cache"))
cmd_cache(&tokens);
else if (!strcmp(cmd, "perf"))
cmd_perf(&tokens);
else
unknown_command(cmd);
}
}
static void ap_main(void)
{
if (this_cpu->num < NUM_CPUS - 1)
run_cpu(this_cpu->num + 1);
else
boot_done = 1;
halt_cpu(this_cpu->num);
while (1) {
}
}
void reset(void)
{
if (this_cpu->num == 0)
console_init();
print("exited reset");
if (this_cpu->num == 0)
bsp_main();
else
ap_main();
}
|