Subversion Repositories HelenOS

Rev

Rev 2071 | Rev 2114 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2071 Rev 2089
1
/*
1
/*
2
 * Copyright (c) 2005 Jakub Jermar
2
 * Copyright (c) 2005 Jakub Jermar
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup genericconsole
29
/** @addtogroup genericconsole
30
 * @{
30
 * @{
31
 */
31
 */
32
 
32
 
33
/**
33
/**
34
 * @file    cmd.c
34
 * @file    cmd.c
35
 * @brief   Kernel console command wrappers.
35
 * @brief   Kernel console command wrappers.
36
 *
36
 *
37
 * This file is meant to contain all wrapper functions for
37
 * This file is meant to contain all wrapper functions for
38
 * all kconsole commands. The point is in separating
38
 * all kconsole commands. The point is in separating
39
 * kconsole specific wrappers from kconsole-unaware functions
39
 * kconsole specific wrappers from kconsole-unaware functions
40
 * from other subsystems.
40
 * from other subsystems.
41
 */
41
 */
42
 
42
 
43
#include <console/cmd.h>
43
#include <console/cmd.h>
44
#include <console/console.h>
44
#include <console/console.h>
45
#include <console/kconsole.h>
45
#include <console/kconsole.h>
46
#include <print.h>
46
#include <print.h>
47
#include <panic.h>
47
#include <panic.h>
48
#include <typedefs.h>
-
 
49
#include <arch/types.h>
48
#include <arch/types.h>
50
#include <adt/list.h>
49
#include <adt/list.h>
51
#include <arch.h>
50
#include <arch.h>
52
#include <func.h>
51
#include <func.h>
53
#include <macros.h>
52
#include <macros.h>
54
#include <debug.h>
53
#include <debug.h>
55
#include <symtab.h>
54
#include <symtab.h>
56
#include <cpu.h>
55
#include <cpu.h>
57
#include <mm/tlb.h>
56
#include <mm/tlb.h>
58
#include <arch/mm/tlb.h>
57
#include <arch/mm/tlb.h>
59
#include <mm/frame.h>
58
#include <mm/frame.h>
60
#include <main/version.h>
59
#include <main/version.h>
61
#include <mm/slab.h>
60
#include <mm/slab.h>
62
#include <proc/scheduler.h>
61
#include <proc/scheduler.h>
63
#include <proc/thread.h>
62
#include <proc/thread.h>
64
#include <proc/task.h>
63
#include <proc/task.h>
65
#include <ipc/ipc.h>
64
#include <ipc/ipc.h>
66
#include <ipc/irq.h>
65
#include <ipc/irq.h>
67
 
66
 
68
#ifdef CONFIG_TEST
67
#ifdef CONFIG_TEST
69
#include <test.h>
68
#include <test.h>
70
#endif
69
#endif
71
 
70
 
72
/* Data and methods for 'help' command. */
71
/* Data and methods for 'help' command. */
73
static int cmd_help(cmd_arg_t *argv);
72
static int cmd_help(cmd_arg_t *argv);
74
static cmd_info_t help_info = {
73
static cmd_info_t help_info = {
75
    .name = "help",
74
    .name = "help",
76
    .description = "List of supported commands.",
75
    .description = "List of supported commands.",
77
    .func = cmd_help,
76
    .func = cmd_help,
78
    .argc = 0
77
    .argc = 0
79
};
78
};
80
 
79
 
81
static cmd_info_t exit_info = {
80
static cmd_info_t exit_info = {
82
    .name = "exit",
81
    .name = "exit",
83
    .description = "Exit kconsole",
82
    .description = "Exit kconsole",
84
    .argc = 0
83
    .argc = 0
85
};
84
};
86
 
85
 
87
static int cmd_continue(cmd_arg_t *argv);
86
static int cmd_continue(cmd_arg_t *argv);
88
static cmd_info_t continue_info = {
87
static cmd_info_t continue_info = {
89
    .name = "continue",
88
    .name = "continue",
90
    .description = "Return console back to userspace.",
89
    .description = "Return console back to userspace.",
91
    .func = cmd_continue,
90
    .func = cmd_continue,
92
    .argc = 0
91
    .argc = 0
93
};
92
};
94
 
93
 
95
#ifdef CONFIG_TEST
94
#ifdef CONFIG_TEST
96
static int cmd_tests(cmd_arg_t *argv);
95
static int cmd_tests(cmd_arg_t *argv);
97
static cmd_info_t tests_info = {
96
static cmd_info_t tests_info = {
98
    .name = "tests",
97
    .name = "tests",
99
    .description = "Print available kernel tests.",
98
    .description = "Print available kernel tests.",
100
    .func = cmd_tests,
99
    .func = cmd_tests,
101
    .argc = 0
100
    .argc = 0
102
};
101
};
103
 
102
 
104
static char test_buf[MAX_CMDLINE + 1];
103
static char test_buf[MAX_CMDLINE + 1];
105
static int cmd_test(cmd_arg_t *argv);
104
static int cmd_test(cmd_arg_t *argv);
106
static cmd_arg_t test_argv[] = {
105
static cmd_arg_t test_argv[] = {
107
    {
106
    {
108
        .type = ARG_TYPE_STRING,
107
        .type = ARG_TYPE_STRING,
109
        .buffer = test_buf,
108
        .buffer = test_buf,
110
        .len = sizeof(test_buf)
109
        .len = sizeof(test_buf)
111
    }
110
    }
112
};
111
};
113
static cmd_info_t test_info = {
112
static cmd_info_t test_info = {
114
    .name = "test",
113
    .name = "test",
115
    .description = "Run kernel test.",
114
    .description = "Run kernel test.",
116
    .func = cmd_test,
115
    .func = cmd_test,
117
    .argc = 1,
116
    .argc = 1,
118
    .argv = test_argv
117
    .argv = test_argv
119
};
118
};
120
 
119
 
121
static int cmd_bench(cmd_arg_t *argv);
120
static int cmd_bench(cmd_arg_t *argv);
122
static cmd_arg_t bench_argv[] = {
121
static cmd_arg_t bench_argv[] = {
123
    {
122
    {
124
        .type = ARG_TYPE_STRING,
123
        .type = ARG_TYPE_STRING,
125
        .buffer = test_buf,
124
        .buffer = test_buf,
126
        .len = sizeof(test_buf)
125
        .len = sizeof(test_buf)
127
    },
126
    },
128
    {
127
    {
129
        .type = ARG_TYPE_INT,
128
        .type = ARG_TYPE_INT,
130
    }
129
    }
131
};
130
};
132
static cmd_info_t bench_info = {
131
static cmd_info_t bench_info = {
133
    .name = "bench",
132
    .name = "bench",
134
    .description = "Run kernel test as benchmark.",
133
    .description = "Run kernel test as benchmark.",
135
    .func = cmd_bench,
134
    .func = cmd_bench,
136
    .argc = 2,
135
    .argc = 2,
137
    .argv = bench_argv
136
    .argv = bench_argv
138
};
137
};
139
#endif
138
#endif
140
 
139
 
141
/* Data and methods for 'description' command. */
140
/* Data and methods for 'description' command. */
142
static int cmd_desc(cmd_arg_t *argv);
141
static int cmd_desc(cmd_arg_t *argv);
143
static void desc_help(void);
142
static void desc_help(void);
144
static char desc_buf[MAX_CMDLINE+1];
143
static char desc_buf[MAX_CMDLINE+1];
145
static cmd_arg_t desc_argv = {
144
static cmd_arg_t desc_argv = {
146
    .type = ARG_TYPE_STRING,
145
    .type = ARG_TYPE_STRING,
147
    .buffer = desc_buf,
146
    .buffer = desc_buf,
148
    .len = sizeof(desc_buf)
147
    .len = sizeof(desc_buf)
149
};
148
};
150
static cmd_info_t desc_info = {
149
static cmd_info_t desc_info = {
151
    .name = "describe",
150
    .name = "describe",
152
    .description = "Describe specified command.",
151
    .description = "Describe specified command.",
153
    .help = desc_help,
152
    .help = desc_help,
154
    .func = cmd_desc,
153
    .func = cmd_desc,
155
    .argc = 1,
154
    .argc = 1,
156
    .argv = &desc_argv
155
    .argv = &desc_argv
157
};
156
};
158
 
157
 
159
/* Data and methods for 'symaddr' command. */
158
/* Data and methods for 'symaddr' command. */
160
static int cmd_symaddr(cmd_arg_t *argv);
159
static int cmd_symaddr(cmd_arg_t *argv);
161
static char symaddr_buf[MAX_CMDLINE+1];
160
static char symaddr_buf[MAX_CMDLINE+1];
162
static cmd_arg_t symaddr_argv = {
161
static cmd_arg_t symaddr_argv = {
163
    .type = ARG_TYPE_STRING,
162
    .type = ARG_TYPE_STRING,
164
    .buffer = symaddr_buf,
163
    .buffer = symaddr_buf,
165
    .len = sizeof(symaddr_buf)
164
    .len = sizeof(symaddr_buf)
166
};
165
};
167
static cmd_info_t symaddr_info = {
166
static cmd_info_t symaddr_info = {
168
    .name = "symaddr",
167
    .name = "symaddr",
169
    .description = "Return symbol address.",
168
    .description = "Return symbol address.",
170
    .func = cmd_symaddr,
169
    .func = cmd_symaddr,
171
    .argc = 1,
170
    .argc = 1,
172
    .argv = &symaddr_argv
171
    .argv = &symaddr_argv
173
};
172
};
174
 
173
 
175
static char set_buf[MAX_CMDLINE+1];
174
static char set_buf[MAX_CMDLINE+1];
176
static int cmd_set4(cmd_arg_t *argv);
175
static int cmd_set4(cmd_arg_t *argv);
177
static cmd_arg_t set4_argv[] = {
176
static cmd_arg_t set4_argv[] = {
178
    {
177
    {
179
        .type = ARG_TYPE_STRING,
178
        .type = ARG_TYPE_STRING,
180
        .buffer = set_buf,
179
        .buffer = set_buf,
181
        .len = sizeof(set_buf)
180
        .len = sizeof(set_buf)
182
    },
181
    },
183
    {
182
    {
184
        .type = ARG_TYPE_INT
183
        .type = ARG_TYPE_INT
185
    }
184
    }
186
};
185
};
187
static cmd_info_t set4_info = {
186
static cmd_info_t set4_info = {
188
    .name = "set4",
187
    .name = "set4",
189
    .description = "set <dest_addr> <value> - 4byte version",
188
    .description = "set <dest_addr> <value> - 4byte version",
190
    .func = cmd_set4,
189
    .func = cmd_set4,
191
    .argc = 2,
190
    .argc = 2,
192
    .argv = set4_argv
191
    .argv = set4_argv
193
};
192
};
194
 
193
 
195
/* Data and methods for 'call0' command. */
194
/* Data and methods for 'call0' command. */
196
static char call0_buf[MAX_CMDLINE+1];
195
static char call0_buf[MAX_CMDLINE+1];
197
static char carg1_buf[MAX_CMDLINE+1];
196
static char carg1_buf[MAX_CMDLINE+1];
198
static char carg2_buf[MAX_CMDLINE+1];
197
static char carg2_buf[MAX_CMDLINE+1];
199
static char carg3_buf[MAX_CMDLINE+1];
198
static char carg3_buf[MAX_CMDLINE+1];
200
 
199
 
201
static int cmd_call0(cmd_arg_t *argv);
200
static int cmd_call0(cmd_arg_t *argv);
202
static cmd_arg_t call0_argv = {
201
static cmd_arg_t call0_argv = {
203
    .type = ARG_TYPE_STRING,
202
    .type = ARG_TYPE_STRING,
204
    .buffer = call0_buf,
203
    .buffer = call0_buf,
205
    .len = sizeof(call0_buf)
204
    .len = sizeof(call0_buf)
206
};
205
};
207
static cmd_info_t call0_info = {
206
static cmd_info_t call0_info = {
208
    .name = "call0",
207
    .name = "call0",
209
    .description = "call0 <function> -> call function().",
208
    .description = "call0 <function> -> call function().",
210
    .func = cmd_call0,
209
    .func = cmd_call0,
211
    .argc = 1,
210
    .argc = 1,
212
    .argv = &call0_argv
211
    .argv = &call0_argv
213
};
212
};
214
 
213
 
215
/* Data and methods for 'call1' command. */
214
/* Data and methods for 'call1' command. */
216
static int cmd_call1(cmd_arg_t *argv);
215
static int cmd_call1(cmd_arg_t *argv);
217
static cmd_arg_t call1_argv[] = {
216
static cmd_arg_t call1_argv[] = {
218
    {
217
    {
219
        .type = ARG_TYPE_STRING,
218
        .type = ARG_TYPE_STRING,
220
        .buffer = call0_buf,
219
        .buffer = call0_buf,
221
        .len = sizeof(call0_buf)
220
        .len = sizeof(call0_buf)
222
    },
221
    },
223
    {
222
    {
224
        .type = ARG_TYPE_VAR,
223
        .type = ARG_TYPE_VAR,
225
        .buffer = carg1_buf,
224
        .buffer = carg1_buf,
226
        .len = sizeof(carg1_buf)
225
        .len = sizeof(carg1_buf)
227
    }
226
    }
228
};
227
};
229
static cmd_info_t call1_info = {
228
static cmd_info_t call1_info = {
230
    .name = "call1",
229
    .name = "call1",
231
    .description = "call1 <function> <arg1> -> call function(arg1).",
230
    .description = "call1 <function> <arg1> -> call function(arg1).",
232
    .func = cmd_call1,
231
    .func = cmd_call1,
233
    .argc = 2,
232
    .argc = 2,
234
    .argv = call1_argv
233
    .argv = call1_argv
235
};
234
};
236
 
235
 
237
/* Data and methods for 'call2' command. */
236
/* Data and methods for 'call2' command. */
238
static int cmd_call2(cmd_arg_t *argv);
237
static int cmd_call2(cmd_arg_t *argv);
239
static cmd_arg_t call2_argv[] = {
238
static cmd_arg_t call2_argv[] = {
240
    {
239
    {
241
        .type = ARG_TYPE_STRING,
240
        .type = ARG_TYPE_STRING,
242
        .buffer = call0_buf,
241
        .buffer = call0_buf,
243
        .len = sizeof(call0_buf)
242
        .len = sizeof(call0_buf)
244
    },
243
    },
245
    {
244
    {
246
        .type = ARG_TYPE_VAR,
245
        .type = ARG_TYPE_VAR,
247
        .buffer = carg1_buf,
246
        .buffer = carg1_buf,
248
        .len = sizeof(carg1_buf)
247
        .len = sizeof(carg1_buf)
249
    },
248
    },
250
    {
249
    {
251
        .type = ARG_TYPE_VAR,
250
        .type = ARG_TYPE_VAR,
252
        .buffer = carg2_buf,
251
        .buffer = carg2_buf,
253
        .len = sizeof(carg2_buf)
252
        .len = sizeof(carg2_buf)
254
    }
253
    }
255
};
254
};
256
static cmd_info_t call2_info = {
255
static cmd_info_t call2_info = {
257
    .name = "call2",
256
    .name = "call2",
258
    .description = "call2 <function> <arg1> <arg2> -> call function(arg1,arg2).",
257
    .description = "call2 <function> <arg1> <arg2> -> call function(arg1,arg2).",
259
    .func = cmd_call2,
258
    .func = cmd_call2,
260
    .argc = 3,
259
    .argc = 3,
261
    .argv = call2_argv
260
    .argv = call2_argv
262
};
261
};
263
 
262
 
264
/* Data and methods for 'call3' command. */
263
/* Data and methods for 'call3' command. */
265
static int cmd_call3(cmd_arg_t *argv);
264
static int cmd_call3(cmd_arg_t *argv);
266
static cmd_arg_t call3_argv[] = {
265
static cmd_arg_t call3_argv[] = {
267
    {
266
    {
268
        .type = ARG_TYPE_STRING,
267
        .type = ARG_TYPE_STRING,
269
        .buffer = call0_buf,
268
        .buffer = call0_buf,
270
        .len = sizeof(call0_buf)
269
        .len = sizeof(call0_buf)
271
    },
270
    },
272
    {
271
    {
273
        .type = ARG_TYPE_VAR,
272
        .type = ARG_TYPE_VAR,
274
        .buffer = carg1_buf,
273
        .buffer = carg1_buf,
275
        .len = sizeof(carg1_buf)
274
        .len = sizeof(carg1_buf)
276
    },
275
    },
277
    {
276
    {
278
        .type = ARG_TYPE_VAR,
277
        .type = ARG_TYPE_VAR,
279
        .buffer = carg2_buf,
278
        .buffer = carg2_buf,
280
        .len = sizeof(carg2_buf)
279
        .len = sizeof(carg2_buf)
281
    },
280
    },
282
    {
281
    {
283
        .type = ARG_TYPE_VAR,
282
        .type = ARG_TYPE_VAR,
284
        .buffer = carg3_buf,
283
        .buffer = carg3_buf,
285
        .len = sizeof(carg3_buf)
284
        .len = sizeof(carg3_buf)
286
    }
285
    }
287
 
286
 
288
};
287
};
289
static cmd_info_t call3_info = {
288
static cmd_info_t call3_info = {
290
    .name = "call3",
289
    .name = "call3",
291
    .description = "call3 <function> <arg1> <arg2> <arg3> -> call function(arg1,arg2,arg3).",
290
    .description = "call3 <function> <arg1> <arg2> <arg3> -> call function(arg1,arg2,arg3).",
292
    .func = cmd_call3,
291
    .func = cmd_call3,
293
    .argc = 4,
292
    .argc = 4,
294
    .argv = call3_argv
293
    .argv = call3_argv
295
};
294
};
296
 
295
 
297
/* Data and methods for 'halt' command. */
296
/* Data and methods for 'halt' command. */
298
static int cmd_halt(cmd_arg_t *argv);
297
static int cmd_halt(cmd_arg_t *argv);
299
static cmd_info_t halt_info = {
298
static cmd_info_t halt_info = {
300
    .name = "halt",
299
    .name = "halt",
301
    .description = "Halt the kernel.",
300
    .description = "Halt the kernel.",
302
    .func = cmd_halt,
301
    .func = cmd_halt,
303
    .argc = 0
302
    .argc = 0
304
};
303
};
305
 
304
 
306
/* Data and methods for 'tlb' command. */
305
/* Data and methods for 'tlb' command. */
307
static int cmd_tlb(cmd_arg_t *argv);
306
static int cmd_tlb(cmd_arg_t *argv);
308
cmd_info_t tlb_info = {
307
cmd_info_t tlb_info = {
309
    .name = "tlb",
308
    .name = "tlb",
310
    .description = "Print TLB of current processor.",
309
    .description = "Print TLB of current processor.",
311
    .help = NULL,
310
    .help = NULL,
312
    .func = cmd_tlb,
311
    .func = cmd_tlb,
313
    .argc = 0,
312
    .argc = 0,
314
    .argv = NULL
313
    .argv = NULL
315
};
314
};
316
 
315
 
317
static int cmd_threads(cmd_arg_t *argv);
316
static int cmd_threads(cmd_arg_t *argv);
318
static cmd_info_t threads_info = {
317
static cmd_info_t threads_info = {
319
    .name = "threads",
318
    .name = "threads",
320
    .description = "List all threads.",
319
    .description = "List all threads.",
321
    .func = cmd_threads,
320
    .func = cmd_threads,
322
    .argc = 0
321
    .argc = 0
323
};
322
};
324
 
323
 
325
static int cmd_tasks(cmd_arg_t *argv);
324
static int cmd_tasks(cmd_arg_t *argv);
326
static cmd_info_t tasks_info = {
325
static cmd_info_t tasks_info = {
327
    .name = "tasks",
326
    .name = "tasks",
328
    .description = "List all tasks.",
327
    .description = "List all tasks.",
329
    .func = cmd_tasks,
328
    .func = cmd_tasks,
330
    .argc = 0
329
    .argc = 0
331
};
330
};
332
 
331
 
333
 
332
 
334
static int cmd_sched(cmd_arg_t *argv);
333
static int cmd_sched(cmd_arg_t *argv);
335
static cmd_info_t sched_info = {
334
static cmd_info_t sched_info = {
336
    .name = "scheduler",
335
    .name = "scheduler",
337
    .description = "List all scheduler information.",
336
    .description = "List all scheduler information.",
338
    .func = cmd_sched,
337
    .func = cmd_sched,
339
    .argc = 0
338
    .argc = 0
340
};
339
};
341
 
340
 
342
static int cmd_slabs(cmd_arg_t *argv);
341
static int cmd_slabs(cmd_arg_t *argv);
343
static cmd_info_t slabs_info = {
342
static cmd_info_t slabs_info = {
344
    .name = "slabs",
343
    .name = "slabs",
345
    .description = "List slab caches.",
344
    .description = "List slab caches.",
346
    .func = cmd_slabs,
345
    .func = cmd_slabs,
347
    .argc = 0
346
    .argc = 0
348
};
347
};
349
 
348
 
350
/* Data and methods for 'zones' command */
349
/* Data and methods for 'zones' command */
351
static int cmd_zones(cmd_arg_t *argv);
350
static int cmd_zones(cmd_arg_t *argv);
352
static cmd_info_t zones_info = {
351
static cmd_info_t zones_info = {
353
    .name = "zones",
352
    .name = "zones",
354
    .description = "List of memory zones.",
353
    .description = "List of memory zones.",
355
    .func = cmd_zones,
354
    .func = cmd_zones,
356
    .argc = 0
355
    .argc = 0
357
};
356
};
358
 
357
 
359
/* Data and methods for 'ipc_task' command */
358
/* Data and methods for 'ipc_task' command */
360
static int cmd_ipc_task(cmd_arg_t *argv);
359
static int cmd_ipc_task(cmd_arg_t *argv);
361
static cmd_arg_t ipc_task_argv = {
360
static cmd_arg_t ipc_task_argv = {
362
    .type = ARG_TYPE_INT,
361
    .type = ARG_TYPE_INT,
363
};
362
};
364
static cmd_info_t ipc_task_info = {
363
static cmd_info_t ipc_task_info = {
365
    .name = "ipc_task",
364
    .name = "ipc_task",
366
    .description = "ipc_task <taskid> Show IPC information of given task.",
365
    .description = "ipc_task <taskid> Show IPC information of given task.",
367
    .func = cmd_ipc_task,
366
    .func = cmd_ipc_task,
368
    .argc = 1,
367
    .argc = 1,
369
    .argv = &ipc_task_argv
368
    .argv = &ipc_task_argv
370
};
369
};
371
 
370
 
372
/* Data and methods for 'zone' command */
371
/* Data and methods for 'zone' command */
373
static int cmd_zone(cmd_arg_t *argv);
372
static int cmd_zone(cmd_arg_t *argv);
374
static cmd_arg_t zone_argv = {
373
static cmd_arg_t zone_argv = {
375
    .type = ARG_TYPE_INT,
374
    .type = ARG_TYPE_INT,
376
};
375
};
377
 
376
 
378
static cmd_info_t zone_info = {
377
static cmd_info_t zone_info = {
379
    .name = "zone",
378
    .name = "zone",
380
    .description = "Show memory zone structure.",
379
    .description = "Show memory zone structure.",
381
    .func = cmd_zone,
380
    .func = cmd_zone,
382
    .argc = 1,
381
    .argc = 1,
383
    .argv = &zone_argv
382
    .argv = &zone_argv
384
};
383
};
385
 
384
 
386
/* Data and methods for 'cpus' command. */
385
/* Data and methods for 'cpus' command. */
387
static int cmd_cpus(cmd_arg_t *argv);
386
static int cmd_cpus(cmd_arg_t *argv);
388
cmd_info_t cpus_info = {
387
cmd_info_t cpus_info = {
389
    .name = "cpus",
388
    .name = "cpus",
390
    .description = "List all processors.",
389
    .description = "List all processors.",
391
    .help = NULL,
390
    .help = NULL,
392
    .func = cmd_cpus,
391
    .func = cmd_cpus,
393
    .argc = 0,
392
    .argc = 0,
394
    .argv = NULL
393
    .argv = NULL
395
};
394
};
396
 
395
 
397
/* Data and methods for 'version' command. */
396
/* Data and methods for 'version' command. */
398
static int cmd_version(cmd_arg_t *argv);
397
static int cmd_version(cmd_arg_t *argv);
399
cmd_info_t version_info = {
398
cmd_info_t version_info = {
400
    .name = "version",
399
    .name = "version",
401
    .description = "Print version information.",
400
    .description = "Print version information.",
402
    .help = NULL,
401
    .help = NULL,
403
    .func = cmd_version,
402
    .func = cmd_version,
404
    .argc = 0,
403
    .argc = 0,
405
    .argv = NULL
404
    .argv = NULL
406
};
405
};
407
 
406
 
408
static cmd_info_t *basic_commands[] = {
407
static cmd_info_t *basic_commands[] = {
409
    &call0_info,
408
    &call0_info,
410
    &call1_info,
409
    &call1_info,
411
    &call2_info,
410
    &call2_info,
412
    &call3_info,
411
    &call3_info,
413
    &continue_info,
412
    &continue_info,
414
    &cpus_info,
413
    &cpus_info,
415
    &desc_info,
414
    &desc_info,
416
    &exit_info,
415
    &exit_info,
417
    &halt_info,
416
    &halt_info,
418
    &help_info,
417
    &help_info,
419
    &ipc_task_info,
418
    &ipc_task_info,
420
    &set4_info,
419
    &set4_info,
421
    &slabs_info,
420
    &slabs_info,
422
    &symaddr_info,
421
    &symaddr_info,
423
    &sched_info,
422
    &sched_info,
424
    &threads_info,
423
    &threads_info,
425
    &tasks_info,
424
    &tasks_info,
426
    &tlb_info,
425
    &tlb_info,
427
    &version_info,
426
    &version_info,
428
    &zones_info,
427
    &zones_info,
429
    &zone_info,
428
    &zone_info,
430
#ifdef CONFIG_TEST
429
#ifdef CONFIG_TEST
431
    &tests_info,
430
    &tests_info,
432
    &test_info,
431
    &test_info,
433
    &bench_info,
432
    &bench_info,
434
#endif
433
#endif
435
    NULL
434
    NULL
436
};
435
};
437
 
436
 
438
 
437
 
439
/** Initialize command info structure.
438
/** Initialize command info structure.
440
 *
439
 *
441
 * @param cmd Command info structure.
440
 * @param cmd Command info structure.
442
 *
441
 *
443
 */
442
 */
444
void cmd_initialize(cmd_info_t *cmd)
443
void cmd_initialize(cmd_info_t *cmd)
445
{
444
{
446
    spinlock_initialize(&cmd->lock, "cmd");
445
    spinlock_initialize(&cmd->lock, "cmd");
447
    link_initialize(&cmd->link);
446
    link_initialize(&cmd->link);
448
}
447
}
449
 
448
 
450
/** Initialize and register commands. */
449
/** Initialize and register commands. */
451
void cmd_init(void)
450
void cmd_init(void)
452
{
451
{
453
    int i;
452
    int i;
454
 
453
 
455
    for (i=0;basic_commands[i]; i++) {
454
    for (i=0;basic_commands[i]; i++) {
456
        cmd_initialize(basic_commands[i]);
455
        cmd_initialize(basic_commands[i]);
457
        if (!cmd_register(basic_commands[i]))
456
        if (!cmd_register(basic_commands[i]))
458
            panic("could not register command %s\n",
457
            panic("could not register command %s\n",
459
                  basic_commands[i]->name);
458
                  basic_commands[i]->name);
460
    }
459
    }
461
}
460
}
462
 
461
 
463
 
462
 
464
/** List supported commands.
463
/** List supported commands.
465
 *
464
 *
466
 * @param argv Argument vector.
465
 * @param argv Argument vector.
467
 *
466
 *
468
 * @return 0 on failure, 1 on success.
467
 * @return 0 on failure, 1 on success.
469
 */
468
 */
470
int cmd_help(cmd_arg_t *argv)
469
int cmd_help(cmd_arg_t *argv)
471
{
470
{
472
    link_t *cur;
471
    link_t *cur;
473
 
472
 
474
    spinlock_lock(&cmd_lock);
473
    spinlock_lock(&cmd_lock);
475
   
474
   
476
    for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
475
    for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
477
        cmd_info_t *hlp;
476
        cmd_info_t *hlp;
478
       
477
       
479
        hlp = list_get_instance(cur, cmd_info_t, link);
478
        hlp = list_get_instance(cur, cmd_info_t, link);
480
        spinlock_lock(&hlp->lock);
479
        spinlock_lock(&hlp->lock);
481
       
480
       
482
        printf("%s - %s\n", hlp->name, hlp->description);
481
        printf("%s - %s\n", hlp->name, hlp->description);
483
 
482
 
484
        spinlock_unlock(&hlp->lock);
483
        spinlock_unlock(&hlp->lock);
485
    }
484
    }
486
   
485
   
487
    spinlock_unlock(&cmd_lock);
486
    spinlock_unlock(&cmd_lock);
488
 
487
 
489
    return 1;
488
    return 1;
490
}
489
}
491
 
490
 
492
/** Describe specified command.
491
/** Describe specified command.
493
 *
492
 *
494
 * @param argv Argument vector.
493
 * @param argv Argument vector.
495
 *
494
 *
496
 * @return 0 on failure, 1 on success.
495
 * @return 0 on failure, 1 on success.
497
 */
496
 */
498
int cmd_desc(cmd_arg_t *argv)
497
int cmd_desc(cmd_arg_t *argv)
499
{
498
{
500
    link_t *cur;
499
    link_t *cur;
501
 
500
 
502
    spinlock_lock(&cmd_lock);
501
    spinlock_lock(&cmd_lock);
503
   
502
   
504
    for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
503
    for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
505
        cmd_info_t *hlp;
504
        cmd_info_t *hlp;
506
       
505
       
507
        hlp = list_get_instance(cur, cmd_info_t, link);
506
        hlp = list_get_instance(cur, cmd_info_t, link);
508
        spinlock_lock(&hlp->lock);
507
        spinlock_lock(&hlp->lock);
509
 
508
 
510
        if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
509
        if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
511
            printf("%s - %s\n", hlp->name, hlp->description);
510
            printf("%s - %s\n", hlp->name, hlp->description);
512
            if (hlp->help)
511
            if (hlp->help)
513
                hlp->help();
512
                hlp->help();
514
            spinlock_unlock(&hlp->lock);
513
            spinlock_unlock(&hlp->lock);
515
            break;
514
            break;
516
        }
515
        }
517
 
516
 
518
        spinlock_unlock(&hlp->lock);
517
        spinlock_unlock(&hlp->lock);
519
    }
518
    }
520
   
519
   
521
    spinlock_unlock(&cmd_lock);
520
    spinlock_unlock(&cmd_lock);
522
 
521
 
523
    return 1;
522
    return 1;
524
}
523
}
525
 
524
 
526
/** Search symbol table */
525
/** Search symbol table */
527
int cmd_symaddr(cmd_arg_t *argv)
526
int cmd_symaddr(cmd_arg_t *argv)
528
{
527
{
529
    symtab_print_search(argv->buffer);
528
    symtab_print_search(argv->buffer);
530
   
529
   
531
    return 1;
530
    return 1;
532
}
531
}
533
 
532
 
534
/** Call function with zero parameters */
533
/** Call function with zero parameters */
535
int cmd_call0(cmd_arg_t *argv)
534
int cmd_call0(cmd_arg_t *argv)
536
{
535
{
537
    uintptr_t symaddr;
536
    uintptr_t symaddr;
538
    char *symbol;
537
    char *symbol;
539
    unative_t (*f)(void);
538
    unative_t (*f)(void);
540
#ifdef ia64
539
#ifdef ia64
541
    struct {
540
    struct {
542
        unative_t f;
541
        unative_t f;
543
        unative_t gp;
542
        unative_t gp;
544
    }fptr;
543
    }fptr;
545
#endif
544
#endif
546
 
545
 
547
    symaddr = get_symbol_addr(argv->buffer);
546
    symaddr = get_symbol_addr(argv->buffer);
548
    if (!symaddr)
547
    if (!symaddr)
549
        printf("Symbol %s not found.\n", argv->buffer);
548
        printf("Symbol %s not found.\n", argv->buffer);
550
    else if (symaddr == (uintptr_t) -1) {
549
    else if (symaddr == (uintptr_t) -1) {
551
        symtab_print_search(argv->buffer);
550
        symtab_print_search(argv->buffer);
552
        printf("Duplicate symbol, be more specific.\n");
551
        printf("Duplicate symbol, be more specific.\n");
553
    } else {
552
    } else {
554
        symbol = get_symtab_entry(symaddr);
553
        symbol = get_symtab_entry(symaddr);
555
        printf("Calling f(): %.*p: %s\n", sizeof(uintptr_t) * 2, symaddr, symbol);
554
        printf("Calling f(): %.*p: %s\n", sizeof(uintptr_t) * 2, symaddr, symbol);
556
#ifdef ia64
555
#ifdef ia64
557
        fptr.f = symaddr;
556
        fptr.f = symaddr;
558
        fptr.gp = ((unative_t *)cmd_call2)[1];
557
        fptr.gp = ((unative_t *)cmd_call2)[1];
559
        f =  (unative_t (*)(void)) &fptr;
558
        f =  (unative_t (*)(void)) &fptr;
560
#else
559
#else
561
        f =  (unative_t (*)(void)) symaddr;
560
        f =  (unative_t (*)(void)) symaddr;
562
#endif
561
#endif
563
        printf("Result: %#zx\n", f());
562
        printf("Result: %#zx\n", f());
564
    }
563
    }
565
   
564
   
566
    return 1;
565
    return 1;
567
}
566
}
568
 
567
 
569
/** Call function with one parameter */
568
/** Call function with one parameter */
570
int cmd_call1(cmd_arg_t *argv)
569
int cmd_call1(cmd_arg_t *argv)
571
{
570
{
572
    uintptr_t symaddr;
571
    uintptr_t symaddr;
573
    char *symbol;
572
    char *symbol;
574
    unative_t (*f)(unative_t,...);
573
    unative_t (*f)(unative_t,...);
575
    unative_t arg1 = argv[1].intval;
574
    unative_t arg1 = argv[1].intval;
576
#ifdef ia64
575
#ifdef ia64
577
    struct {
576
    struct {
578
        unative_t f;
577
        unative_t f;
579
        unative_t gp;
578
        unative_t gp;
580
    }fptr;
579
    }fptr;
581
#endif
580
#endif
582
 
581
 
583
    symaddr = get_symbol_addr(argv->buffer);
582
    symaddr = get_symbol_addr(argv->buffer);
584
    if (!symaddr)
583
    if (!symaddr)
585
        printf("Symbol %s not found.\n", argv->buffer);
584
        printf("Symbol %s not found.\n", argv->buffer);
586
    else if (symaddr == (uintptr_t) -1) {
585
    else if (symaddr == (uintptr_t) -1) {
587
        symtab_print_search(argv->buffer);
586
        symtab_print_search(argv->buffer);
588
        printf("Duplicate symbol, be more specific.\n");
587
        printf("Duplicate symbol, be more specific.\n");
589
    } else {
588
    } else {
590
        symbol = get_symtab_entry(symaddr);
589
        symbol = get_symtab_entry(symaddr);
591
 
590
 
592
        printf("Calling f(%#zx): %.*p: %s\n", arg1, sizeof(uintptr_t) * 2, symaddr, symbol);
591
        printf("Calling f(%#zx): %.*p: %s\n", arg1, sizeof(uintptr_t) * 2, symaddr, symbol);
593
#ifdef ia64
592
#ifdef ia64
594
        fptr.f = symaddr;
593
        fptr.f = symaddr;
595
        fptr.gp = ((unative_t *)cmd_call2)[1];
594
        fptr.gp = ((unative_t *)cmd_call2)[1];
596
        f =  (unative_t (*)(unative_t,...)) &fptr;
595
        f =  (unative_t (*)(unative_t,...)) &fptr;
597
#else
596
#else
598
        f =  (unative_t (*)(unative_t,...)) symaddr;
597
        f =  (unative_t (*)(unative_t,...)) symaddr;
599
#endif
598
#endif
600
        printf("Result: %#zx\n", f(arg1));
599
        printf("Result: %#zx\n", f(arg1));
601
    }
600
    }
602
   
601
   
603
    return 1;
602
    return 1;
604
}
603
}
605
 
604
 
606
/** Call function with two parameters */
605
/** Call function with two parameters */
607
int cmd_call2(cmd_arg_t *argv)
606
int cmd_call2(cmd_arg_t *argv)
608
{
607
{
609
    uintptr_t symaddr;
608
    uintptr_t symaddr;
610
    char *symbol;
609
    char *symbol;
611
    unative_t (*f)(unative_t,unative_t,...);
610
    unative_t (*f)(unative_t,unative_t,...);
612
    unative_t arg1 = argv[1].intval;
611
    unative_t arg1 = argv[1].intval;
613
    unative_t arg2 = argv[2].intval;
612
    unative_t arg2 = argv[2].intval;
614
#ifdef ia64
613
#ifdef ia64
615
    struct {
614
    struct {
616
        unative_t f;
615
        unative_t f;
617
        unative_t gp;
616
        unative_t gp;
618
    }fptr;
617
    }fptr;
619
#endif
618
#endif
620
 
619
 
621
    symaddr = get_symbol_addr(argv->buffer);
620
    symaddr = get_symbol_addr(argv->buffer);
622
    if (!symaddr)
621
    if (!symaddr)
623
        printf("Symbol %s not found.\n", argv->buffer);
622
        printf("Symbol %s not found.\n", argv->buffer);
624
    else if (symaddr == (uintptr_t) -1) {
623
    else if (symaddr == (uintptr_t) -1) {
625
        symtab_print_search(argv->buffer);
624
        symtab_print_search(argv->buffer);
626
        printf("Duplicate symbol, be more specific.\n");
625
        printf("Duplicate symbol, be more specific.\n");
627
    } else {
626
    } else {
628
        symbol = get_symtab_entry(symaddr);
627
        symbol = get_symtab_entry(symaddr);
629
        printf("Calling f(0x%zx,0x%zx): %.*p: %s\n",
628
        printf("Calling f(0x%zx,0x%zx): %.*p: %s\n",
630
               arg1, arg2, sizeof(uintptr_t) * 2, symaddr, symbol);
629
               arg1, arg2, sizeof(uintptr_t) * 2, symaddr, symbol);
631
#ifdef ia64
630
#ifdef ia64
632
        fptr.f = symaddr;
631
        fptr.f = symaddr;
633
        fptr.gp = ((unative_t *)cmd_call2)[1];
632
        fptr.gp = ((unative_t *)cmd_call2)[1];
634
        f =  (unative_t (*)(unative_t,unative_t,...)) &fptr;
633
        f =  (unative_t (*)(unative_t,unative_t,...)) &fptr;
635
#else
634
#else
636
        f =  (unative_t (*)(unative_t,unative_t,...)) symaddr;
635
        f =  (unative_t (*)(unative_t,unative_t,...)) symaddr;
637
#endif
636
#endif
638
        printf("Result: %#zx\n", f(arg1, arg2));
637
        printf("Result: %#zx\n", f(arg1, arg2));
639
    }
638
    }
640
   
639
   
641
    return 1;
640
    return 1;
642
}
641
}
643
 
642
 
644
/** Call function with three parameters */
643
/** Call function with three parameters */
645
int cmd_call3(cmd_arg_t *argv)
644
int cmd_call3(cmd_arg_t *argv)
646
{
645
{
647
    uintptr_t symaddr;
646
    uintptr_t symaddr;
648
    char *symbol;
647
    char *symbol;
649
    unative_t (*f)(unative_t,unative_t,unative_t,...);
648
    unative_t (*f)(unative_t,unative_t,unative_t,...);
650
    unative_t arg1 = argv[1].intval;
649
    unative_t arg1 = argv[1].intval;
651
    unative_t arg2 = argv[2].intval;
650
    unative_t arg2 = argv[2].intval;
652
    unative_t arg3 = argv[3].intval;
651
    unative_t arg3 = argv[3].intval;
653
#ifdef ia64
652
#ifdef ia64
654
    struct {
653
    struct {
655
        unative_t f;
654
        unative_t f;
656
        unative_t gp;
655
        unative_t gp;
657
    }fptr;
656
    }fptr;
658
#endif
657
#endif
659
 
658
 
660
    symaddr = get_symbol_addr(argv->buffer);
659
    symaddr = get_symbol_addr(argv->buffer);
661
    if (!symaddr)
660
    if (!symaddr)
662
        printf("Symbol %s not found.\n", argv->buffer);
661
        printf("Symbol %s not found.\n", argv->buffer);
663
    else if (symaddr == (uintptr_t) -1) {
662
    else if (symaddr == (uintptr_t) -1) {
664
        symtab_print_search(argv->buffer);
663
        symtab_print_search(argv->buffer);
665
        printf("Duplicate symbol, be more specific.\n");
664
        printf("Duplicate symbol, be more specific.\n");
666
    } else {
665
    } else {
667
        symbol = get_symtab_entry(symaddr);
666
        symbol = get_symtab_entry(symaddr);
668
        printf("Calling f(0x%zx,0x%zx, 0x%zx): %.*p: %s\n",
667
        printf("Calling f(0x%zx,0x%zx, 0x%zx): %.*p: %s\n",
669
               arg1, arg2, arg3, sizeof(uintptr_t) * 2, symaddr, symbol);
668
               arg1, arg2, arg3, sizeof(uintptr_t) * 2, symaddr, symbol);
670
#ifdef ia64
669
#ifdef ia64
671
        fptr.f = symaddr;
670
        fptr.f = symaddr;
672
        fptr.gp = ((unative_t *)cmd_call2)[1];
671
        fptr.gp = ((unative_t *)cmd_call2)[1];
673
        f =  (unative_t (*)(unative_t,unative_t,unative_t,...)) &fptr;
672
        f =  (unative_t (*)(unative_t,unative_t,unative_t,...)) &fptr;
674
#else
673
#else
675
        f =  (unative_t (*)(unative_t,unative_t,unative_t,...)) symaddr;
674
        f =  (unative_t (*)(unative_t,unative_t,unative_t,...)) symaddr;
676
#endif
675
#endif
677
        printf("Result: %#zx\n", f(arg1, arg2, arg3));
676
        printf("Result: %#zx\n", f(arg1, arg2, arg3));
678
    }
677
    }
679
   
678
   
680
    return 1;
679
    return 1;
681
}
680
}
682
 
681
 
683
 
682
 
684
/** Print detailed description of 'describe' command. */
683
/** Print detailed description of 'describe' command. */
685
void desc_help(void)
684
void desc_help(void)
686
{
685
{
687
    printf("Syntax: describe command_name\n");
686
    printf("Syntax: describe command_name\n");
688
}
687
}
689
 
688
 
690
/** Halt the kernel.
689
/** Halt the kernel.
691
 *
690
 *
692
 * @param argv Argument vector (ignored).
691
 * @param argv Argument vector (ignored).
693
 *
692
 *
694
 * @return 0 on failure, 1 on success (never returns).
693
 * @return 0 on failure, 1 on success (never returns).
695
 */
694
 */
696
int cmd_halt(cmd_arg_t *argv)
695
int cmd_halt(cmd_arg_t *argv)
697
{
696
{
698
    halt();
697
    halt();
699
    return 1;
698
    return 1;
700
}
699
}
701
 
700
 
702
/** Command for printing TLB contents.
701
/** Command for printing TLB contents.
703
 *
702
 *
704
 * @param argv Not used.
703
 * @param argv Not used.
705
 *
704
 *
706
 * @return Always returns 1.
705
 * @return Always returns 1.
707
 */
706
 */
708
int cmd_tlb(cmd_arg_t *argv)
707
int cmd_tlb(cmd_arg_t *argv)
709
{
708
{
710
    tlb_print();
709
    tlb_print();
711
    return 1;
710
    return 1;
712
}
711
}
713
 
712
 
714
/** Write 4 byte value to address */
713
/** Write 4 byte value to address */
715
int cmd_set4(cmd_arg_t *argv)
714
int cmd_set4(cmd_arg_t *argv)
716
{
715
{
717
    uint32_t *addr ;
716
    uint32_t *addr ;
718
    uint32_t arg1 = argv[1].intval;
717
    uint32_t arg1 = argv[1].intval;
719
    bool pointer = false;
718
    bool pointer = false;
720
 
719
 
721
    if (((char *)argv->buffer)[0] == '*') {
720
    if (((char *)argv->buffer)[0] == '*') {
722
        addr = (uint32_t *) get_symbol_addr(argv->buffer+1);
721
        addr = (uint32_t *) get_symbol_addr(argv->buffer+1);
723
        pointer = true;
722
        pointer = true;
724
    } else if (((char *)argv->buffer)[0] >= '0' &&
723
    } else if (((char *)argv->buffer)[0] >= '0' &&
725
           ((char *)argv->buffer)[0] <= '9')
724
           ((char *)argv->buffer)[0] <= '9')
726
        addr = (uint32_t *)atoi((char *)argv->buffer);
725
        addr = (uint32_t *)atoi((char *)argv->buffer);
727
    else
726
    else
728
        addr = (uint32_t *)get_symbol_addr(argv->buffer);
727
        addr = (uint32_t *)get_symbol_addr(argv->buffer);
729
 
728
 
730
    if (!addr)
729
    if (!addr)
731
        printf("Symbol %s not found.\n", argv->buffer);
730
        printf("Symbol %s not found.\n", argv->buffer);
732
    else if (addr == (uint32_t *) -1) {
731
    else if (addr == (uint32_t *) -1) {
733
        symtab_print_search(argv->buffer);
732
        symtab_print_search(argv->buffer);
734
        printf("Duplicate symbol, be more specific.\n");
733
        printf("Duplicate symbol, be more specific.\n");
735
    } else {
734
    } else {
736
        if (pointer)
735
        if (pointer)
737
            addr = (uint32_t *)(*(unative_t *)addr);
736
            addr = (uint32_t *)(*(unative_t *)addr);
738
        printf("Writing 0x%x -> %.*p\n", arg1, sizeof(uintptr_t) * 2, addr);
737
        printf("Writing 0x%x -> %.*p\n", arg1, sizeof(uintptr_t) * 2, addr);
739
        *addr = arg1;
738
        *addr = arg1;
740
       
739
       
741
    }
740
    }
742
   
741
   
743
    return 1;
742
    return 1;
744
}
743
}
745
 
744
 
746
/** Command for listings SLAB caches
745
/** Command for listings SLAB caches
747
 *
746
 *
748
 * @param argv Ignores
747
 * @param argv Ignores
749
 *
748
 *
750
 * @return Always 1
749
 * @return Always 1
751
 */
750
 */
752
int cmd_slabs(cmd_arg_t * argv) {
751
int cmd_slabs(cmd_arg_t * argv) {
753
    slab_print_list();
752
    slab_print_list();
754
    return 1;
753
    return 1;
755
}
754
}
756
 
755
 
757
 
756
 
758
/** Command for listings Thread information
757
/** Command for listings Thread information
759
 *
758
 *
760
 * @param argv Ignores
759
 * @param argv Ignores
761
 *
760
 *
762
 * @return Always 1
761
 * @return Always 1
763
 */
762
 */
764
int cmd_threads(cmd_arg_t * argv) {
763
int cmd_threads(cmd_arg_t * argv) {
765
    thread_print_list();
764
    thread_print_list();
766
    return 1;
765
    return 1;
767
}
766
}
768
 
767
 
769
/** Command for listings Task information
768
/** Command for listings Task information
770
 *
769
 *
771
 * @param argv Ignores
770
 * @param argv Ignores
772
 *
771
 *
773
 * @return Always 1
772
 * @return Always 1
774
 */
773
 */
775
int cmd_tasks(cmd_arg_t * argv) {
774
int cmd_tasks(cmd_arg_t * argv) {
776
    task_print_list();
775
    task_print_list();
777
    return 1;
776
    return 1;
778
}
777
}
779
 
778
 
780
/** Command for listings Thread information
779
/** Command for listings Thread information
781
 *
780
 *
782
 * @param argv Ignores
781
 * @param argv Ignores
783
 *
782
 *
784
 * @return Always 1
783
 * @return Always 1
785
 */
784
 */
786
int cmd_sched(cmd_arg_t * argv) {
785
int cmd_sched(cmd_arg_t * argv) {
787
    sched_print_list();
786
    sched_print_list();
788
    return 1;
787
    return 1;
789
}
788
}
790
 
789
 
791
/** Command for listing memory zones
790
/** Command for listing memory zones
792
 *
791
 *
793
 * @param argv Ignored
792
 * @param argv Ignored
794
 *
793
 *
795
 * return Always 1
794
 * return Always 1
796
 */
795
 */
797
int cmd_zones(cmd_arg_t * argv) {
796
int cmd_zones(cmd_arg_t * argv) {
798
    zone_print_list();
797
    zone_print_list();
799
    return 1;
798
    return 1;
800
}
799
}
801
 
800
 
802
/** Command for memory zone details
801
/** Command for memory zone details
803
 *
802
 *
804
 * @param argv Integer argument from cmdline expected
803
 * @param argv Integer argument from cmdline expected
805
 *
804
 *
806
 * return Always 1
805
 * return Always 1
807
 */
806
 */
808
int cmd_zone(cmd_arg_t * argv) {
807
int cmd_zone(cmd_arg_t * argv) {
809
    zone_print_one(argv[0].intval);
808
    zone_print_one(argv[0].intval);
810
    return 1;
809
    return 1;
811
}
810
}
812
 
811
 
813
/** Command for printing task ipc details
812
/** Command for printing task ipc details
814
 *
813
 *
815
 * @param argv Integer argument from cmdline expected
814
 * @param argv Integer argument from cmdline expected
816
 *
815
 *
817
 * return Always 1
816
 * return Always 1
818
 */
817
 */
819
int cmd_ipc_task(cmd_arg_t * argv) {
818
int cmd_ipc_task(cmd_arg_t * argv) {
820
    ipc_print_task(argv[0].intval);
819
    ipc_print_task(argv[0].intval);
821
    return 1;
820
    return 1;
822
}
821
}
823
 
822
 
824
 
823
 
825
/** Command for listing processors.
824
/** Command for listing processors.
826
 *
825
 *
827
 * @param argv Ignored.
826
 * @param argv Ignored.
828
 *
827
 *
829
 * return Always 1.
828
 * return Always 1.
830
 */
829
 */
831
int cmd_cpus(cmd_arg_t *argv)
830
int cmd_cpus(cmd_arg_t *argv)
832
{
831
{
833
    cpu_list();
832
    cpu_list();
834
    return 1;
833
    return 1;
835
}
834
}
836
 
835
 
837
/** Command for printing kernel version.
836
/** Command for printing kernel version.
838
 *
837
 *
839
 * @param argv Ignored.
838
 * @param argv Ignored.
840
 *
839
 *
841
 * return Always 1.
840
 * return Always 1.
842
 */
841
 */
843
int cmd_version(cmd_arg_t *argv)
842
int cmd_version(cmd_arg_t *argv)
844
{
843
{
845
    version_print();
844
    version_print();
846
    return 1;
845
    return 1;
847
}
846
}
848
 
847
 
849
/** Command for returning console back to userspace.
848
/** Command for returning console back to userspace.
850
 *
849
 *
851
 * @param argv Ignored.
850
 * @param argv Ignored.
852
 *
851
 *
853
 * return Always 1.
852
 * return Always 1.
854
 */
853
 */
855
int cmd_continue(cmd_arg_t *argv)
854
int cmd_continue(cmd_arg_t *argv)
856
{
855
{
857
    printf("The kernel will now relinquish the console.\n");
856
    printf("The kernel will now relinquish the console.\n");
858
    printf("Use userspace controls to redraw the screen.\n");
857
    printf("Use userspace controls to redraw the screen.\n");
859
    arch_release_console();
858
    arch_release_console();
860
    return 1;
859
    return 1;
861
}
860
}
862
 
861
 
863
#ifdef CONFIG_TEST
862
#ifdef CONFIG_TEST
864
/** Command for printing kernel tests list.
863
/** Command for printing kernel tests list.
865
 *
864
 *
866
 * @param argv Ignored.
865
 * @param argv Ignored.
867
 *
866
 *
868
 * return Always 1.
867
 * return Always 1.
869
 */
868
 */
870
int cmd_tests(cmd_arg_t *argv)
869
int cmd_tests(cmd_arg_t *argv)
871
{
870
{
872
    test_t *test;
871
    test_t *test;
873
   
872
   
874
    for (test = tests; test->name != NULL; test++)
873
    for (test = tests; test->name != NULL; test++)
875
        printf("%s\t\t%s%s\n", test->name, test->desc, (test->safe ? "" : " (unsafe)"));
874
        printf("%s\t\t%s%s\n", test->name, test->desc, (test->safe ? "" : " (unsafe)"));
876
   
875
   
877
    printf("*\t\tRun all safe tests\n");
876
    printf("*\t\tRun all safe tests\n");
878
    return 1;
877
    return 1;
879
}
878
}
880
 
879
 
881
static bool run_test(const test_t *test)
880
static bool run_test(const test_t *test)
882
{
881
{
883
    printf("%s\t\t%s\n", test->name, test->desc);
882
    printf("%s\t\t%s\n", test->name, test->desc);
884
   
883
   
885
    /* Update and read thread accounting
884
    /* Update and read thread accounting
886
       for benchmarking */
885
       for benchmarking */
887
    ipl_t ipl = interrupts_disable();
886
    ipl_t ipl = interrupts_disable();
888
    spinlock_lock(&TASK->lock);
887
    spinlock_lock(&TASK->lock);
889
    uint64_t t0 = task_get_accounting(TASK);
888
    uint64_t t0 = task_get_accounting(TASK);
890
    spinlock_unlock(&TASK->lock);
889
    spinlock_unlock(&TASK->lock);
891
    interrupts_restore(ipl);
890
    interrupts_restore(ipl);
892
   
891
   
893
    /* Execute the test */
892
    /* Execute the test */
894
    char * ret = test->entry(false);
893
    char * ret = test->entry(false);
895
   
894
   
896
    /* Update and read thread accounting */
895
    /* Update and read thread accounting */
897
    ipl = interrupts_disable();
896
    ipl = interrupts_disable();
898
    spinlock_lock(&TASK->lock);
897
    spinlock_lock(&TASK->lock);
899
    uint64_t dt = task_get_accounting(TASK) - t0;
898
    uint64_t dt = task_get_accounting(TASK) - t0;
900
    spinlock_unlock(&TASK->lock);
899
    spinlock_unlock(&TASK->lock);
901
    interrupts_restore(ipl);
900
    interrupts_restore(ipl);
902
   
901
   
903
    uint64_t cycles;
902
    uint64_t cycles;
904
    char suffix;
903
    char suffix;
905
    order(dt, &cycles, &suffix);
904
    order(dt, &cycles, &suffix);
906
       
905
       
907
    printf("Time: %llu%c cycles\n", cycles, suffix);
906
    printf("Time: %llu%c cycles\n", cycles, suffix);
908
   
907
   
909
    if (ret == NULL) {
908
    if (ret == NULL) {
910
        printf("Test passed\n");
909
        printf("Test passed\n");
911
        return true;
910
        return true;
912
    }
911
    }
913
 
912
 
914
    printf("%s\n", ret);
913
    printf("%s\n", ret);
915
    return false;
914
    return false;
916
}
915
}
917
 
916
 
918
static bool run_bench(const test_t *test, const uint32_t cnt)
917
static bool run_bench(const test_t *test, const uint32_t cnt)
919
{
918
{
920
    uint32_t i;
919
    uint32_t i;
921
    bool ret = true;
920
    bool ret = true;
922
    uint64_t cycles;
921
    uint64_t cycles;
923
    char suffix;
922
    char suffix;
924
   
923
   
925
    if (cnt < 1)
924
    if (cnt < 1)
926
        return true;
925
        return true;
927
   
926
   
928
    uint64_t *data = malloc(sizeof(uint64_t) * cnt, 0);
927
    uint64_t *data = malloc(sizeof(uint64_t) * cnt, 0);
929
    if (data == NULL) {
928
    if (data == NULL) {
930
        printf("Error allocating memory for statistics\n");
929
        printf("Error allocating memory for statistics\n");
931
        return false;
930
        return false;
932
    }
931
    }
933
   
932
   
934
    for (i = 0; i < cnt; i++) {
933
    for (i = 0; i < cnt; i++) {
935
        printf("%s (%d/%d) ... ", test->name, i + 1, cnt);
934
        printf("%s (%d/%d) ... ", test->name, i + 1, cnt);
936
       
935
       
937
        /* Update and read thread accounting
936
        /* Update and read thread accounting
938
           for benchmarking */
937
           for benchmarking */
939
        ipl_t ipl = interrupts_disable();
938
        ipl_t ipl = interrupts_disable();
940
        spinlock_lock(&TASK->lock);
939
        spinlock_lock(&TASK->lock);
941
        uint64_t t0 = task_get_accounting(TASK);
940
        uint64_t t0 = task_get_accounting(TASK);
942
        spinlock_unlock(&TASK->lock);
941
        spinlock_unlock(&TASK->lock);
943
        interrupts_restore(ipl);
942
        interrupts_restore(ipl);
944
       
943
       
945
        /* Execute the test */
944
        /* Execute the test */
946
        char * ret = test->entry(true);
945
        char * ret = test->entry(true);
947
       
946
       
948
        /* Update and read thread accounting */
947
        /* Update and read thread accounting */
949
        ipl = interrupts_disable();
948
        ipl = interrupts_disable();
950
        spinlock_lock(&TASK->lock);
949
        spinlock_lock(&TASK->lock);
951
        uint64_t dt = task_get_accounting(TASK) - t0;
950
        uint64_t dt = task_get_accounting(TASK) - t0;
952
        spinlock_unlock(&TASK->lock);
951
        spinlock_unlock(&TASK->lock);
953
        interrupts_restore(ipl);
952
        interrupts_restore(ipl);
954
       
953
       
955
        if (ret != NULL) {
954
        if (ret != NULL) {
956
            printf("%s\n", ret);
955
            printf("%s\n", ret);
957
            ret = false;
956
            ret = false;
958
            break;
957
            break;
959
        }
958
        }
960
       
959
       
961
        data[i] = dt;
960
        data[i] = dt;
962
        order(dt, &cycles, &suffix);
961
        order(dt, &cycles, &suffix);
963
        printf("OK (%llu%c cycles)\n", cycles, suffix);
962
        printf("OK (%llu%c cycles)\n", cycles, suffix);
964
    }
963
    }
965
   
964
   
966
    if (ret) {
965
    if (ret) {
967
        printf("\n");
966
        printf("\n");
968
       
967
       
969
        uint64_t sum = 0;
968
        uint64_t sum = 0;
970
       
969
       
971
        for (i = 0; i < cnt; i++) {
970
        for (i = 0; i < cnt; i++) {
972
            sum += data[i];
971
            sum += data[i];
973
        }
972
        }
974
       
973
       
975
        order(sum / (uint64_t) cnt, &cycles, &suffix);
974
        order(sum / (uint64_t) cnt, &cycles, &suffix);
976
        printf("Average\t\t%llu%c\n", cycles, suffix);
975
        printf("Average\t\t%llu%c\n", cycles, suffix);
977
    }
976
    }
978
   
977
   
979
    free(data);
978
    free(data);
980
   
979
   
981
    return ret;
980
    return ret;
982
}
981
}
983
 
982
 
984
/** Command for returning kernel tests
983
/** Command for returning kernel tests
985
 *
984
 *
986
 * @param argv Argument vector.
985
 * @param argv Argument vector.
987
 *
986
 *
988
 * return Always 1.
987
 * return Always 1.
989
 */
988
 */
990
int cmd_test(cmd_arg_t *argv)
989
int cmd_test(cmd_arg_t *argv)
991
{
990
{
992
    test_t *test;
991
    test_t *test;
993
   
992
   
994
    if (strcmp(argv->buffer, "*") == 0) {
993
    if (strcmp(argv->buffer, "*") == 0) {
995
        for (test = tests; test->name != NULL; test++) {
994
        for (test = tests; test->name != NULL; test++) {
996
            if (test->safe) {
995
            if (test->safe) {
997
                printf("\n");
996
                printf("\n");
998
                if (!run_test(test))
997
                if (!run_test(test))
999
                    break;
998
                    break;
1000
            }
999
            }
1001
        }
1000
        }
1002
    } else {
1001
    } else {
1003
        bool fnd = false;
1002
        bool fnd = false;
1004
       
1003
       
1005
        for (test = tests; test->name != NULL; test++) {
1004
        for (test = tests; test->name != NULL; test++) {
1006
            if (strcmp(test->name, argv->buffer) == 0) {
1005
            if (strcmp(test->name, argv->buffer) == 0) {
1007
                fnd = true;
1006
                fnd = true;
1008
                run_test(test);
1007
                run_test(test);
1009
                break;
1008
                break;
1010
            }
1009
            }
1011
        }
1010
        }
1012
       
1011
       
1013
        if (!fnd)
1012
        if (!fnd)
1014
            printf("Unknown test\n");
1013
            printf("Unknown test\n");
1015
    }
1014
    }
1016
   
1015
   
1017
    return 1;
1016
    return 1;
1018
}
1017
}
1019
 
1018
 
1020
/** Command for returning kernel tests as benchmarks
1019
/** Command for returning kernel tests as benchmarks
1021
 *
1020
 *
1022
 * @param argv Argument vector.
1021
 * @param argv Argument vector.
1023
 *
1022
 *
1024
 * return Always 1.
1023
 * return Always 1.
1025
 */
1024
 */
1026
int cmd_bench(cmd_arg_t *argv)
1025
int cmd_bench(cmd_arg_t *argv)
1027
{
1026
{
1028
    test_t *test;
1027
    test_t *test;
1029
    uint32_t cnt = argv[1].intval;
1028
    uint32_t cnt = argv[1].intval;
1030
   
1029
   
1031
    bool fnd = false;
1030
    bool fnd = false;
1032
   
1031
   
1033
    for (test = tests; test->name != NULL; test++) {
1032
    for (test = tests; test->name != NULL; test++) {
1034
        if (strcmp(test->name, argv->buffer) == 0) {
1033
        if (strcmp(test->name, argv->buffer) == 0) {
1035
            fnd = true;
1034
            fnd = true;
1036
           
1035
           
1037
            if (test->safe)
1036
            if (test->safe)
1038
                run_bench(test, cnt);
1037
                run_bench(test, cnt);
1039
            else
1038
            else
1040
                printf("Unsafe test\n");
1039
                printf("Unsafe test\n");
1041
           
1040
           
1042
            break;
1041
            break;
1043
        }
1042
        }
1044
    }
1043
    }
1045
       
1044
       
1046
    if (!fnd)
1045
    if (!fnd)
1047
        printf("Unknown test\n");
1046
        printf("Unknown test\n");
1048
 
1047
 
1049
    return 1;
1048
    return 1;
1050
}
1049
}
1051
 
1050
 
1052
#endif
1051
#endif
1053
 
1052
 
1054
/** @}
1053
/** @}
1055
 */
1054
 */
1056
 
1055