Subversion Repositories HelenOS

Rev

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

Rev 4090 Rev 4132
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 <arch/types.h>
48
#include <arch/types.h>
49
#include <adt/list.h>
49
#include <adt/list.h>
50
#include <arch.h>
50
#include <arch.h>
51
#include <config.h>
51
#include <config.h>
52
#include <func.h>
52
#include <func.h>
53
#include <string.h>
53
#include <string.h>
54
#include <macros.h>
54
#include <macros.h>
55
#include <debug.h>
55
#include <debug.h>
56
#include <symtab.h>
-
 
57
#include <cpu.h>
56
#include <cpu.h>
58
#include <mm/tlb.h>
57
#include <mm/tlb.h>
59
#include <arch/mm/tlb.h>
58
#include <arch/mm/tlb.h>
60
#include <mm/frame.h>
59
#include <mm/frame.h>
61
#include <main/version.h>
60
#include <main/version.h>
62
#include <mm/slab.h>
61
#include <mm/slab.h>
63
#include <proc/scheduler.h>
62
#include <proc/scheduler.h>
64
#include <proc/thread.h>
63
#include <proc/thread.h>
65
#include <proc/task.h>
64
#include <proc/task.h>
66
#include <ipc/ipc.h>
65
#include <ipc/ipc.h>
67
#include <ipc/irq.h>
66
#include <ipc/irq.h>
68
 
67
 
-
 
68
#ifdef CONFIG_SYMTAB
-
 
69
#include <symtab.h>
-
 
70
#endif
-
 
71
 
69
#ifdef CONFIG_TEST
72
#ifdef CONFIG_TEST
70
#include <test.h>
73
#include <test.h>
71
#endif
74
#endif
72
 
75
 
73
/* Data and methods for 'help' command. */
76
/* Data and methods for 'help' command. */
74
static int cmd_help(cmd_arg_t *argv);
77
static int cmd_help(cmd_arg_t *argv);
75
static cmd_info_t help_info = {
78
static cmd_info_t help_info = {
76
    .name = "help",
79
    .name = "help",
77
    .description = "List of supported commands.",
80
    .description = "List of supported commands.",
78
    .func = cmd_help,
81
    .func = cmd_help,
79
    .argc = 0
82
    .argc = 0
80
};
83
};
81
 
84
 
82
static int cmd_reboot(cmd_arg_t *argv);
85
static int cmd_reboot(cmd_arg_t *argv);
83
static cmd_info_t reboot_info = {
86
static cmd_info_t reboot_info = {
84
    .name = "reboot",
87
    .name = "reboot",
85
    .description = "Reboot.",
88
    .description = "Reboot.",
86
    .func = cmd_reboot,
89
    .func = cmd_reboot,
87
    .argc = 0
90
    .argc = 0
88
};
91
};
89
 
92
 
90
static int cmd_uptime(cmd_arg_t *argv);
93
static int cmd_uptime(cmd_arg_t *argv);
91
static cmd_info_t uptime_info = {
94
static cmd_info_t uptime_info = {
92
    .name = "uptime",
95
    .name = "uptime",
93
    .description = "Print uptime information.",
96
    .description = "Print uptime information.",
94
    .func = cmd_uptime,
97
    .func = cmd_uptime,
95
    .argc = 0
98
    .argc = 0
96
};
99
};
97
 
100
 
98
static int cmd_continue(cmd_arg_t *argv);
101
static int cmd_continue(cmd_arg_t *argv);
99
static cmd_info_t continue_info = {
102
static cmd_info_t continue_info = {
100
    .name = "continue",
103
    .name = "continue",
101
    .description = "Return console back to userspace.",
104
    .description = "Return console back to userspace.",
102
    .func = cmd_continue,
105
    .func = cmd_continue,
103
    .argc = 0
106
    .argc = 0
104
};
107
};
105
 
108
 
106
#ifdef CONFIG_TEST
109
#ifdef CONFIG_TEST
107
static int cmd_tests(cmd_arg_t *argv);
110
static int cmd_tests(cmd_arg_t *argv);
108
static cmd_info_t tests_info = {
111
static cmd_info_t tests_info = {
109
    .name = "tests",
112
    .name = "tests",
110
    .description = "Print available kernel tests.",
113
    .description = "Print available kernel tests.",
111
    .func = cmd_tests,
114
    .func = cmd_tests,
112
    .argc = 0
115
    .argc = 0
113
};
116
};
114
 
117
 
115
static char test_buf[MAX_CMDLINE + 1];
118
static char test_buf[MAX_CMDLINE + 1];
116
static int cmd_test(cmd_arg_t *argv);
119
static int cmd_test(cmd_arg_t *argv);
117
static cmd_arg_t test_argv[] = {
120
static cmd_arg_t test_argv[] = {
118
    {
121
    {
119
        .type = ARG_TYPE_STRING,
122
        .type = ARG_TYPE_STRING,
120
        .buffer = test_buf,
123
        .buffer = test_buf,
121
        .len = sizeof(test_buf)
124
        .len = sizeof(test_buf)
122
    }
125
    }
123
};
126
};
124
static cmd_info_t test_info = {
127
static cmd_info_t test_info = {
125
    .name = "test",
128
    .name = "test",
126
    .description = "Run kernel test.",
129
    .description = "Run kernel test.",
127
    .func = cmd_test,
130
    .func = cmd_test,
128
    .argc = 1,
131
    .argc = 1,
129
    .argv = test_argv
132
    .argv = test_argv
130
};
133
};
131
 
134
 
132
static int cmd_bench(cmd_arg_t *argv);
135
static int cmd_bench(cmd_arg_t *argv);
133
static cmd_arg_t bench_argv[] = {
136
static cmd_arg_t bench_argv[] = {
134
    {
137
    {
135
        .type = ARG_TYPE_STRING,
138
        .type = ARG_TYPE_STRING,
136
        .buffer = test_buf,
139
        .buffer = test_buf,
137
        .len = sizeof(test_buf)
140
        .len = sizeof(test_buf)
138
    },
141
    },
139
    {
142
    {
140
        .type = ARG_TYPE_INT,
143
        .type = ARG_TYPE_INT,
141
    }
144
    }
142
};
145
};
143
static cmd_info_t bench_info = {
146
static cmd_info_t bench_info = {
144
    .name = "bench",
147
    .name = "bench",
145
    .description = "Run kernel test as benchmark.",
148
    .description = "Run kernel test as benchmark.",
146
    .func = cmd_bench,
149
    .func = cmd_bench,
147
    .argc = 2,
150
    .argc = 2,
148
    .argv = bench_argv
151
    .argv = bench_argv
149
};
152
};
150
#endif
153
#endif
151
 
154
 
152
/* Data and methods for 'description' command. */
155
/* Data and methods for 'description' command. */
153
static int cmd_desc(cmd_arg_t *argv);
156
static int cmd_desc(cmd_arg_t *argv);
154
static void desc_help(void);
157
static void desc_help(void);
155
static char desc_buf[MAX_CMDLINE+1];
158
static char desc_buf[MAX_CMDLINE+1];
156
static cmd_arg_t desc_argv = {
159
static cmd_arg_t desc_argv = {
157
    .type = ARG_TYPE_STRING,
160
    .type = ARG_TYPE_STRING,
158
    .buffer = desc_buf,
161
    .buffer = desc_buf,
159
    .len = sizeof(desc_buf)
162
    .len = sizeof(desc_buf)
160
};
163
};
161
static cmd_info_t desc_info = {
164
static cmd_info_t desc_info = {
162
    .name = "describe",
165
    .name = "describe",
163
    .description = "Describe specified command.",
166
    .description = "Describe specified command.",
164
    .help = desc_help,
167
    .help = desc_help,
165
    .func = cmd_desc,
168
    .func = cmd_desc,
166
    .argc = 1,
169
    .argc = 1,
167
    .argv = &desc_argv
170
    .argv = &desc_argv
168
};
171
};
169
 
172
 
-
 
173
#ifdef CONFIG_SYMTAB
170
/* Data and methods for 'symaddr' command. */
174
/* Data and methods for 'symaddr' command. */
171
static int cmd_symaddr(cmd_arg_t *argv);
175
static int cmd_symaddr(cmd_arg_t *argv);
172
static char symaddr_buf[MAX_CMDLINE+1];
176
static char symaddr_buf[MAX_CMDLINE+1];
173
static cmd_arg_t symaddr_argv = {
177
static cmd_arg_t symaddr_argv = {
174
    .type = ARG_TYPE_STRING,
178
    .type = ARG_TYPE_STRING,
175
    .buffer = symaddr_buf,
179
    .buffer = symaddr_buf,
176
    .len = sizeof(symaddr_buf)
180
    .len = sizeof(symaddr_buf)
177
};
181
};
178
static cmd_info_t symaddr_info = {
182
static cmd_info_t symaddr_info = {
179
    .name = "symaddr",
183
    .name = "symaddr",
180
    .description = "Return symbol address.",
184
    .description = "Return symbol address.",
181
    .func = cmd_symaddr,
185
    .func = cmd_symaddr,
182
    .argc = 1,
186
    .argc = 1,
183
    .argv = &symaddr_argv
187
    .argv = &symaddr_argv
184
};
188
};
-
 
189
#endif
185
 
190
 
186
static char set_buf[MAX_CMDLINE+1];
191
static char set_buf[MAX_CMDLINE+1];
187
static int cmd_set4(cmd_arg_t *argv);
192
static int cmd_set4(cmd_arg_t *argv);
188
static cmd_arg_t set4_argv[] = {
193
static cmd_arg_t set4_argv[] = {
189
    {
194
    {
190
        .type = ARG_TYPE_STRING,
195
        .type = ARG_TYPE_STRING,
191
        .buffer = set_buf,
196
        .buffer = set_buf,
192
        .len = sizeof(set_buf)
197
        .len = sizeof(set_buf)
193
    },
198
    },
194
    {
199
    {
195
        .type = ARG_TYPE_INT
200
        .type = ARG_TYPE_INT
196
    }
201
    }
197
};
202
};
198
static cmd_info_t set4_info = {
203
static cmd_info_t set4_info = {
199
    .name = "set4",
204
    .name = "set4",
200
    .description = "set <dest_addr> <value> - 4byte version",
205
    .description = "set <dest_addr> <value> - 4byte version",
201
    .func = cmd_set4,
206
    .func = cmd_set4,
202
    .argc = 2,
207
    .argc = 2,
203
    .argv = set4_argv
208
    .argv = set4_argv
204
};
209
};
205
 
210
 
206
/* Data and methods for 'call0' command. */
211
/* Data and methods for 'call0' command. */
207
static char call0_buf[MAX_CMDLINE + 1];
212
static char call0_buf[MAX_CMDLINE + 1];
208
static char carg1_buf[MAX_CMDLINE + 1];
213
static char carg1_buf[MAX_CMDLINE + 1];
209
static char carg2_buf[MAX_CMDLINE + 1];
214
static char carg2_buf[MAX_CMDLINE + 1];
210
static char carg3_buf[MAX_CMDLINE + 1];
215
static char carg3_buf[MAX_CMDLINE + 1];
211
 
216
 
212
static int cmd_call0(cmd_arg_t *argv);
217
static int cmd_call0(cmd_arg_t *argv);
213
static cmd_arg_t call0_argv = {
218
static cmd_arg_t call0_argv = {
214
    .type = ARG_TYPE_STRING,
219
    .type = ARG_TYPE_STRING,
215
    .buffer = call0_buf,
220
    .buffer = call0_buf,
216
    .len = sizeof(call0_buf)
221
    .len = sizeof(call0_buf)
217
};
222
};
218
static cmd_info_t call0_info = {
223
static cmd_info_t call0_info = {
219
    .name = "call0",
224
    .name = "call0",
220
    .description = "call0 <function> -> call function().",
225
    .description = "call0 <function> -> call function().",
221
    .func = cmd_call0,
226
    .func = cmd_call0,
222
    .argc = 1,
227
    .argc = 1,
223
    .argv = &call0_argv
228
    .argv = &call0_argv
224
};
229
};
225
 
230
 
226
/* Data and methods for 'mcall0' command. */
231
/* Data and methods for 'mcall0' command. */
227
static int cmd_mcall0(cmd_arg_t *argv);
232
static int cmd_mcall0(cmd_arg_t *argv);
228
static cmd_arg_t mcall0_argv = {
233
static cmd_arg_t mcall0_argv = {
229
    .type = ARG_TYPE_STRING,
234
    .type = ARG_TYPE_STRING,
230
    .buffer = call0_buf,
235
    .buffer = call0_buf,
231
    .len = sizeof(call0_buf)
236
    .len = sizeof(call0_buf)
232
};
237
};
233
static cmd_info_t mcall0_info = {
238
static cmd_info_t mcall0_info = {
234
    .name = "mcall0",
239
    .name = "mcall0",
235
    .description = "mcall0 <function> -> call function() on each CPU.",
240
    .description = "mcall0 <function> -> call function() on each CPU.",
236
    .func = cmd_mcall0,
241
    .func = cmd_mcall0,
237
    .argc = 1,
242
    .argc = 1,
238
    .argv = &mcall0_argv
243
    .argv = &mcall0_argv
239
};
244
};
240
 
245
 
241
/* Data and methods for 'call1' command. */
246
/* Data and methods for 'call1' command. */
242
static int cmd_call1(cmd_arg_t *argv);
247
static int cmd_call1(cmd_arg_t *argv);
243
static cmd_arg_t call1_argv[] = {
248
static cmd_arg_t call1_argv[] = {
244
    {
249
    {
245
        .type = ARG_TYPE_STRING,
250
        .type = ARG_TYPE_STRING,
246
        .buffer = call0_buf,
251
        .buffer = call0_buf,
247
        .len = sizeof(call0_buf)
252
        .len = sizeof(call0_buf)
248
    },
253
    },
249
    {
254
    {
250
        .type = ARG_TYPE_VAR,
255
        .type = ARG_TYPE_VAR,
251
        .buffer = carg1_buf,
256
        .buffer = carg1_buf,
252
        .len = sizeof(carg1_buf)
257
        .len = sizeof(carg1_buf)
253
    }
258
    }
254
};
259
};
255
static cmd_info_t call1_info = {
260
static cmd_info_t call1_info = {
256
    .name = "call1",
261
    .name = "call1",
257
    .description = "call1 <function> <arg1> -> call function(arg1).",
262
    .description = "call1 <function> <arg1> -> call function(arg1).",
258
    .func = cmd_call1,
263
    .func = cmd_call1,
259
    .argc = 2,
264
    .argc = 2,
260
    .argv = call1_argv
265
    .argv = call1_argv
261
};
266
};
262
 
267
 
263
/* Data and methods for 'call2' command. */
268
/* Data and methods for 'call2' command. */
264
static int cmd_call2(cmd_arg_t *argv);
269
static int cmd_call2(cmd_arg_t *argv);
265
static cmd_arg_t call2_argv[] = {
270
static cmd_arg_t call2_argv[] = {
266
    {
271
    {
267
        .type = ARG_TYPE_STRING,
272
        .type = ARG_TYPE_STRING,
268
        .buffer = call0_buf,
273
        .buffer = call0_buf,
269
        .len = sizeof(call0_buf)
274
        .len = sizeof(call0_buf)
270
    },
275
    },
271
    {
276
    {
272
        .type = ARG_TYPE_VAR,
277
        .type = ARG_TYPE_VAR,
273
        .buffer = carg1_buf,
278
        .buffer = carg1_buf,
274
        .len = sizeof(carg1_buf)
279
        .len = sizeof(carg1_buf)
275
    },
280
    },
276
    {
281
    {
277
        .type = ARG_TYPE_VAR,
282
        .type = ARG_TYPE_VAR,
278
        .buffer = carg2_buf,
283
        .buffer = carg2_buf,
279
        .len = sizeof(carg2_buf)
284
        .len = sizeof(carg2_buf)
280
    }
285
    }
281
};
286
};
282
static cmd_info_t call2_info = {
287
static cmd_info_t call2_info = {
283
    .name = "call2",
288
    .name = "call2",
284
    .description = "call2 <function> <arg1> <arg2> -> call function(arg1,arg2).",
289
    .description = "call2 <function> <arg1> <arg2> -> call function(arg1,arg2).",
285
    .func = cmd_call2,
290
    .func = cmd_call2,
286
    .argc = 3,
291
    .argc = 3,
287
    .argv = call2_argv
292
    .argv = call2_argv
288
};
293
};
289
 
294
 
290
/* Data and methods for 'call3' command. */
295
/* Data and methods for 'call3' command. */
291
static int cmd_call3(cmd_arg_t *argv);
296
static int cmd_call3(cmd_arg_t *argv);
292
static cmd_arg_t call3_argv[] = {
297
static cmd_arg_t call3_argv[] = {
293
    {
298
    {
294
        .type = ARG_TYPE_STRING,
299
        .type = ARG_TYPE_STRING,
295
        .buffer = call0_buf,
300
        .buffer = call0_buf,
296
        .len = sizeof(call0_buf)
301
        .len = sizeof(call0_buf)
297
    },
302
    },
298
    {
303
    {
299
        .type = ARG_TYPE_VAR,
304
        .type = ARG_TYPE_VAR,
300
        .buffer = carg1_buf,
305
        .buffer = carg1_buf,
301
        .len = sizeof(carg1_buf)
306
        .len = sizeof(carg1_buf)
302
    },
307
    },
303
    {
308
    {
304
        .type = ARG_TYPE_VAR,
309
        .type = ARG_TYPE_VAR,
305
        .buffer = carg2_buf,
310
        .buffer = carg2_buf,
306
        .len = sizeof(carg2_buf)
311
        .len = sizeof(carg2_buf)
307
    },
312
    },
308
    {
313
    {
309
        .type = ARG_TYPE_VAR,
314
        .type = ARG_TYPE_VAR,
310
        .buffer = carg3_buf,
315
        .buffer = carg3_buf,
311
        .len = sizeof(carg3_buf)
316
        .len = sizeof(carg3_buf)
312
    }
317
    }
313
 
318
 
314
};
319
};
315
static cmd_info_t call3_info = {
320
static cmd_info_t call3_info = {
316
    .name = "call3",
321
    .name = "call3",
317
    .description = "call3 <function> <arg1> <arg2> <arg3> -> call function(arg1,arg2,arg3).",
322
    .description = "call3 <function> <arg1> <arg2> <arg3> -> call function(arg1,arg2,arg3).",
318
    .func = cmd_call3,
323
    .func = cmd_call3,
319
    .argc = 4,
324
    .argc = 4,
320
    .argv = call3_argv
325
    .argv = call3_argv
321
};
326
};
322
 
327
 
323
/* Data and methods for 'halt' command. */
328
/* Data and methods for 'halt' command. */
324
static int cmd_halt(cmd_arg_t *argv);
329
static int cmd_halt(cmd_arg_t *argv);
325
static cmd_info_t halt_info = {
330
static cmd_info_t halt_info = {
326
    .name = "halt",
331
    .name = "halt",
327
    .description = "Halt the kernel.",
332
    .description = "Halt the kernel.",
328
    .func = cmd_halt,
333
    .func = cmd_halt,
329
    .argc = 0
334
    .argc = 0
330
};
335
};
331
 
336
 
332
/* Data and methods for 'physmem' command. */
337
/* Data and methods for 'physmem' command. */
333
static int cmd_physmem(cmd_arg_t *argv);
338
static int cmd_physmem(cmd_arg_t *argv);
334
cmd_info_t physmem_info = {
339
cmd_info_t physmem_info = {
335
    .name = "physmem",
340
    .name = "physmem",
336
    .description = "Print physical memory configuration.",
341
    .description = "Print physical memory configuration.",
337
    .help = NULL,
342
    .help = NULL,
338
    .func = cmd_physmem,
343
    .func = cmd_physmem,
339
    .argc = 0,
344
    .argc = 0,
340
    .argv = NULL
345
    .argv = NULL
341
};
346
};
342
 
347
 
343
/* Data and methods for 'tlb' command. */
348
/* Data and methods for 'tlb' command. */
344
static int cmd_tlb(cmd_arg_t *argv);
349
static int cmd_tlb(cmd_arg_t *argv);
345
cmd_info_t tlb_info = {
350
cmd_info_t tlb_info = {
346
    .name = "tlb",
351
    .name = "tlb",
347
    .description = "Print TLB of current processor.",
352
    .description = "Print TLB of current processor.",
348
    .help = NULL,
353
    .help = NULL,
349
    .func = cmd_tlb,
354
    .func = cmd_tlb,
350
    .argc = 0,
355
    .argc = 0,
351
    .argv = NULL
356
    .argv = NULL
352
};
357
};
353
 
358
 
354
static int cmd_threads(cmd_arg_t *argv);
359
static int cmd_threads(cmd_arg_t *argv);
355
static cmd_info_t threads_info = {
360
static cmd_info_t threads_info = {
356
    .name = "threads",
361
    .name = "threads",
357
    .description = "List all threads.",
362
    .description = "List all threads.",
358
    .func = cmd_threads,
363
    .func = cmd_threads,
359
    .argc = 0
364
    .argc = 0
360
};
365
};
361
 
366
 
362
static int cmd_tasks(cmd_arg_t *argv);
367
static int cmd_tasks(cmd_arg_t *argv);
363
static cmd_info_t tasks_info = {
368
static cmd_info_t tasks_info = {
364
    .name = "tasks",
369
    .name = "tasks",
365
    .description = "List all tasks.",
370
    .description = "List all tasks.",
366
    .func = cmd_tasks,
371
    .func = cmd_tasks,
367
    .argc = 0
372
    .argc = 0
368
};
373
};
369
 
374
 
370
 
375
 
371
static int cmd_sched(cmd_arg_t *argv);
376
static int cmd_sched(cmd_arg_t *argv);
372
static cmd_info_t sched_info = {
377
static cmd_info_t sched_info = {
373
    .name = "scheduler",
378
    .name = "scheduler",
374
    .description = "List all scheduler information.",
379
    .description = "List all scheduler information.",
375
    .func = cmd_sched,
380
    .func = cmd_sched,
376
    .argc = 0
381
    .argc = 0
377
};
382
};
378
 
383
 
379
static int cmd_slabs(cmd_arg_t *argv);
384
static int cmd_slabs(cmd_arg_t *argv);
380
static cmd_info_t slabs_info = {
385
static cmd_info_t slabs_info = {
381
    .name = "slabs",
386
    .name = "slabs",
382
    .description = "List slab caches.",
387
    .description = "List slab caches.",
383
    .func = cmd_slabs,
388
    .func = cmd_slabs,
384
    .argc = 0
389
    .argc = 0
385
};
390
};
386
 
391
 
387
/* Data and methods for 'zones' command */
392
/* Data and methods for 'zones' command */
388
static int cmd_zones(cmd_arg_t *argv);
393
static int cmd_zones(cmd_arg_t *argv);
389
static cmd_info_t zones_info = {
394
static cmd_info_t zones_info = {
390
    .name = "zones",
395
    .name = "zones",
391
    .description = "List of memory zones.",
396
    .description = "List of memory zones.",
392
    .func = cmd_zones,
397
    .func = cmd_zones,
393
    .argc = 0
398
    .argc = 0
394
};
399
};
395
 
400
 
396
/* Data and methods for 'ipc' command */
401
/* Data and methods for 'ipc' command */
397
static int cmd_ipc(cmd_arg_t *argv);
402
static int cmd_ipc(cmd_arg_t *argv);
398
static cmd_arg_t ipc_argv = {
403
static cmd_arg_t ipc_argv = {
399
    .type = ARG_TYPE_INT,
404
    .type = ARG_TYPE_INT,
400
};
405
};
401
static cmd_info_t ipc_info = {
406
static cmd_info_t ipc_info = {
402
    .name = "ipc",
407
    .name = "ipc",
403
    .description = "ipc <taskid> Show IPC information of given task.",
408
    .description = "ipc <taskid> Show IPC information of given task.",
404
    .func = cmd_ipc,
409
    .func = cmd_ipc,
405
    .argc = 1,
410
    .argc = 1,
406
    .argv = &ipc_argv
411
    .argv = &ipc_argv
407
};
412
};
408
 
413
 
409
/* Data and methods for 'zone' command */
414
/* Data and methods for 'zone' command */
410
static int cmd_zone(cmd_arg_t *argv);
415
static int cmd_zone(cmd_arg_t *argv);
411
static cmd_arg_t zone_argv = {
416
static cmd_arg_t zone_argv = {
412
    .type = ARG_TYPE_INT,
417
    .type = ARG_TYPE_INT,
413
};
418
};
414
 
419
 
415
static cmd_info_t zone_info = {
420
static cmd_info_t zone_info = {
416
    .name = "zone",
421
    .name = "zone",
417
    .description = "Show memory zone structure.",
422
    .description = "Show memory zone structure.",
418
    .func = cmd_zone,
423
    .func = cmd_zone,
419
    .argc = 1,
424
    .argc = 1,
420
    .argv = &zone_argv
425
    .argv = &zone_argv
421
};
426
};
422
 
427
 
423
/* Data and methods for 'cpus' command. */
428
/* Data and methods for 'cpus' command. */
424
static int cmd_cpus(cmd_arg_t *argv);
429
static int cmd_cpus(cmd_arg_t *argv);
425
cmd_info_t cpus_info = {
430
cmd_info_t cpus_info = {
426
    .name = "cpus",
431
    .name = "cpus",
427
    .description = "List all processors.",
432
    .description = "List all processors.",
428
    .help = NULL,
433
    .help = NULL,
429
    .func = cmd_cpus,
434
    .func = cmd_cpus,
430
    .argc = 0,
435
    .argc = 0,
431
    .argv = NULL
436
    .argv = NULL
432
};
437
};
433
 
438
 
434
/* Data and methods for 'version' command. */
439
/* Data and methods for 'version' command. */
435
static int cmd_version(cmd_arg_t *argv);
440
static int cmd_version(cmd_arg_t *argv);
436
cmd_info_t version_info = {
441
cmd_info_t version_info = {
437
    .name = "version",
442
    .name = "version",
438
    .description = "Print version information.",
443
    .description = "Print version information.",
439
    .help = NULL,
444
    .help = NULL,
440
    .func = cmd_version,
445
    .func = cmd_version,
441
    .argc = 0,
446
    .argc = 0,
442
    .argv = NULL
447
    .argv = NULL
443
};
448
};
444
 
449
 
445
static cmd_info_t *basic_commands[] = {
450
static cmd_info_t *basic_commands[] = {
446
    &call0_info,
451
    &call0_info,
447
    &mcall0_info,
452
    &mcall0_info,
448
    &call1_info,
453
    &call1_info,
449
    &call2_info,
454
    &call2_info,
450
    &call3_info,
455
    &call3_info,
451
    &continue_info,
456
    &continue_info,
452
    &cpus_info,
457
    &cpus_info,
453
    &desc_info,
458
    &desc_info,
454
    &reboot_info,
459
    &reboot_info,
455
    &uptime_info,
460
    &uptime_info,
456
    &halt_info,
461
    &halt_info,
457
    &help_info,
462
    &help_info,
458
    &ipc_info,
463
    &ipc_info,
459
    &set4_info,
464
    &set4_info,
460
    &slabs_info,
465
    &slabs_info,
-
 
466
#ifdef CONFIG_SYMTAB
461
    &symaddr_info,
467
    &symaddr_info,
-
 
468
#endif
462
    &sched_info,
469
    &sched_info,
463
    &threads_info,
470
    &threads_info,
464
    &tasks_info,
471
    &tasks_info,
465
    &physmem_info,
472
    &physmem_info,
466
    &tlb_info,
473
    &tlb_info,
467
    &version_info,
474
    &version_info,
468
    &zones_info,
475
    &zones_info,
469
    &zone_info,
476
    &zone_info,
470
#ifdef CONFIG_TEST
477
#ifdef CONFIG_TEST
471
    &tests_info,
478
    &tests_info,
472
    &test_info,
479
    &test_info,
473
    &bench_info,
480
    &bench_info,
474
#endif
481
#endif
475
    NULL
482
    NULL
476
};
483
};
477
 
484
 
478
 
485
 
479
/** Initialize command info structure.
486
/** Initialize command info structure.
480
 *
487
 *
481
 * @param cmd Command info structure.
488
 * @param cmd Command info structure.
482
 *
489
 *
483
 */
490
 */
484
void cmd_initialize(cmd_info_t *cmd)
491
void cmd_initialize(cmd_info_t *cmd)
485
{
492
{
486
    spinlock_initialize(&cmd->lock, "cmd");
493
    spinlock_initialize(&cmd->lock, "cmd");
487
    link_initialize(&cmd->link);
494
    link_initialize(&cmd->link);
488
}
495
}
489
 
496
 
490
/** Initialize and register commands. */
497
/** Initialize and register commands. */
491
void cmd_init(void)
498
void cmd_init(void)
492
{
499
{
493
    unsigned int i;
500
    unsigned int i;
494
 
501
 
495
    for (i = 0; basic_commands[i]; i++) {
502
    for (i = 0; basic_commands[i]; i++) {
496
        cmd_initialize(basic_commands[i]);
503
        cmd_initialize(basic_commands[i]);
497
        if (!cmd_register(basic_commands[i]))
504
        if (!cmd_register(basic_commands[i]))
498
            printf("Cannot register command %s\n", basic_commands[i]->name);
505
            printf("Cannot register command %s\n", basic_commands[i]->name);
499
    }
506
    }
500
}
507
}
501
 
508
 
502
 
509
 
503
/** List supported commands.
510
/** List supported commands.
504
 *
511
 *
505
 * @param argv Argument vector.
512
 * @param argv Argument vector.
506
 *
513
 *
507
 * @return 0 on failure, 1 on success.
514
 * @return 0 on failure, 1 on success.
508
 */
515
 */
509
int cmd_help(cmd_arg_t *argv)
516
int cmd_help(cmd_arg_t *argv)
510
{
517
{
511
    spinlock_lock(&cmd_lock);
518
    spinlock_lock(&cmd_lock);
512
   
519
   
513
    link_t *cur;
520
    link_t *cur;
514
    size_t len = 0;
521
    size_t len = 0;
515
    for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
522
    for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
516
        cmd_info_t *hlp;
523
        cmd_info_t *hlp;
517
        hlp = list_get_instance(cur, cmd_info_t, link);
524
        hlp = list_get_instance(cur, cmd_info_t, link);
518
       
525
       
519
        spinlock_lock(&hlp->lock);
526
        spinlock_lock(&hlp->lock);
520
        if (strlen(hlp->name) > len)
527
        if (strlen(hlp->name) > len)
521
            len = strlen(hlp->name);
528
            len = strlen(hlp->name);
522
        spinlock_unlock(&hlp->lock);
529
        spinlock_unlock(&hlp->lock);
523
    }
530
    }
524
   
531
   
525
    for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
532
    for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
526
        cmd_info_t *hlp;
533
        cmd_info_t *hlp;
527
        hlp = list_get_instance(cur, cmd_info_t, link);
534
        hlp = list_get_instance(cur, cmd_info_t, link);
528
       
535
       
529
        spinlock_lock(&hlp->lock);
536
        spinlock_lock(&hlp->lock);
530
        printf("%-*s %s\n", len, hlp->name, hlp->description);
537
        printf("%-*s %s\n", len, hlp->name, hlp->description);
531
        spinlock_unlock(&hlp->lock);
538
        spinlock_unlock(&hlp->lock);
532
    }
539
    }
533
   
540
   
534
    spinlock_unlock(&cmd_lock);
541
    spinlock_unlock(&cmd_lock);
535
   
542
   
536
    return 1;
543
    return 1;
537
}
544
}
538
 
545
 
539
 
546
 
540
/** Reboot the system.
547
/** Reboot the system.
541
 *
548
 *
542
 * @param argv Argument vector.
549
 * @param argv Argument vector.
543
 *
550
 *
544
 * @return 0 on failure, 1 on success.
551
 * @return 0 on failure, 1 on success.
545
 */
552
 */
546
int cmd_reboot(cmd_arg_t *argv)
553
int cmd_reboot(cmd_arg_t *argv)
547
{
554
{
548
    reboot();
555
    reboot();
549
   
556
   
550
    /* Not reached */
557
    /* Not reached */
551
    return 1;
558
    return 1;
552
}
559
}
553
 
560
 
554
 
561
 
555
/** Print system uptime information.
562
/** Print system uptime information.
556
 *
563
 *
557
 * @param argv Argument vector.
564
 * @param argv Argument vector.
558
 *
565
 *
559
 * @return 0 on failure, 1 on success.
566
 * @return 0 on failure, 1 on success.
560
 */
567
 */
561
int cmd_uptime(cmd_arg_t *argv)
568
int cmd_uptime(cmd_arg_t *argv)
562
{
569
{
563
    ASSERT(uptime);
570
    ASSERT(uptime);
564
   
571
   
565
    /* This doesn't have to be very accurate */
572
    /* This doesn't have to be very accurate */
566
    unative_t sec = uptime->seconds1;
573
    unative_t sec = uptime->seconds1;
567
   
574
   
568
    printf("Up %" PRIun " days, %" PRIun " hours, %" PRIun " minutes, %" PRIun " seconds\n",
575
    printf("Up %" PRIun " days, %" PRIun " hours, %" PRIun " minutes, %" PRIun " seconds\n",
569
        sec / 86400, (sec % 86400) / 3600, (sec % 3600) / 60, sec % 60);
576
        sec / 86400, (sec % 86400) / 3600, (sec % 3600) / 60, sec % 60);
570
   
577
   
571
    return 1;
578
    return 1;
572
}
579
}
573
 
580
 
574
/** Describe specified command.
581
/** Describe specified command.
575
 *
582
 *
576
 * @param argv Argument vector.
583
 * @param argv Argument vector.
577
 *
584
 *
578
 * @return 0 on failure, 1 on success.
585
 * @return 0 on failure, 1 on success.
579
 */
586
 */
580
int cmd_desc(cmd_arg_t *argv)
587
int cmd_desc(cmd_arg_t *argv)
581
{
588
{
582
    link_t *cur;
589
    link_t *cur;
583
 
590
 
584
    spinlock_lock(&cmd_lock);
591
    spinlock_lock(&cmd_lock);
585
   
592
   
586
    for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
593
    for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
587
        cmd_info_t *hlp;
594
        cmd_info_t *hlp;
588
       
595
       
589
        hlp = list_get_instance(cur, cmd_info_t, link);
596
        hlp = list_get_instance(cur, cmd_info_t, link);
590
        spinlock_lock(&hlp->lock);
597
        spinlock_lock(&hlp->lock);
591
 
598
 
592
        if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
599
        if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
593
            printf("%s - %s\n", hlp->name, hlp->description);
600
            printf("%s - %s\n", hlp->name, hlp->description);
594
            if (hlp->help)
601
            if (hlp->help)
595
                hlp->help();
602
                hlp->help();
596
            spinlock_unlock(&hlp->lock);
603
            spinlock_unlock(&hlp->lock);
597
            break;
604
            break;
598
        }
605
        }
599
 
606
 
600
        spinlock_unlock(&hlp->lock);
607
        spinlock_unlock(&hlp->lock);
601
    }
608
    }
602
   
609
   
603
    spinlock_unlock(&cmd_lock);
610
    spinlock_unlock(&cmd_lock);
604
 
611
 
605
    return 1;
612
    return 1;
606
}
613
}
607
 
614
 
-
 
615
#ifdef CONFIG_SYMTAB
-
 
616
 
608
/** Search symbol table */
617
/** Search symbol table */
609
int cmd_symaddr(cmd_arg_t *argv)
618
int cmd_symaddr(cmd_arg_t *argv)
610
{
619
{
611
    symtab_print_search((char *) argv->buffer);
620
    symtab_print_search((char *) argv->buffer);
612
   
621
   
613
    return 1;
622
    return 1;
614
}
623
}
615
 
624
 
-
 
625
#endif
-
 
626
 
616
/** Call function with zero parameters */
627
/** Call function with zero parameters */
617
int cmd_call0(cmd_arg_t *argv)
628
int cmd_call0(cmd_arg_t *argv)
618
{
629
{
-
 
630
#ifdef CONFIG_SYMTAB
619
    uintptr_t symaddr;
631
    uintptr_t symaddr;
620
    char *symbol;
-
 
621
    unative_t (*fnc)(void);
632
    unative_t (*fnc)(void);
622
    fncptr_t fptr;
633
    fncptr_t fptr;
623
   
634
 
624
    symaddr = get_symbol_addr((char *) argv->buffer);
635
    symaddr = get_symbol_addr((char *) argv->buffer);
625
    if (!symaddr)
636
    if (!symaddr)
626
        printf("Symbol %s not found.\n", argv->buffer);
637
        printf("Symbol %s not found.\n", argv->buffer);
627
    else if (symaddr == (uintptr_t) -1) {
638
    else if (symaddr == (uintptr_t) -1) {
628
        symtab_print_search((char *) argv->buffer);
639
        symtab_print_search((char *) argv->buffer);
629
        printf("Duplicate symbol, be more specific.\n");
640
        printf("Duplicate symbol, be more specific.\n");
630
    } else {
641
    } else {
631
        symbol = get_symtab_entry(symaddr);
-
 
632
        fnc = (unative_t (*)(void)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call0);
642
        fnc = (unative_t (*)(void)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call0);
633
        printf("Calling %s() (%p)\n", symbol, symaddr);
643
        printf("Calling %s() (%p)\n", argv->buffer, symaddr);
634
        printf("Result: %#" PRIxn "\n", fnc());
644
        printf("Result: %#" PRIxn "\n", fnc());
635
    }
645
    }
636
   
646
#endif
637
    return 1;
647
    return 1;
638
}
648
}
639
 
649
 
640
/** Call function with zero parameters on each CPU */
650
/** Call function with zero parameters on each CPU */
641
int cmd_mcall0(cmd_arg_t *argv)
651
int cmd_mcall0(cmd_arg_t *argv)
642
{
652
{
643
    /*
653
    /*
644
     * For each CPU, create a thread which will
654
     * For each CPU, create a thread which will
645
     * call the function.
655
     * call the function.
646
     */
656
     */
647
   
657
   
648
    count_t i;
658
    count_t i;
649
    for (i = 0; i < config.cpu_count; i++) {
659
    for (i = 0; i < config.cpu_count; i++) {
650
        if (!cpus[i].active)
660
        if (!cpus[i].active)
651
            continue;
661
            continue;
652
       
662
       
653
        thread_t *t;
663
        thread_t *t;
654
        if ((t = thread_create((void (*)(void *)) cmd_call0, (void *) argv, TASK, THREAD_FLAG_WIRED, "call0", false))) {
664
        if ((t = thread_create((void (*)(void *)) cmd_call0, (void *) argv, TASK, THREAD_FLAG_WIRED, "call0", false))) {
655
            spinlock_lock(&t->lock);
665
            spinlock_lock(&t->lock);
656
            t->cpu = &cpus[i];
666
            t->cpu = &cpus[i];
657
            spinlock_unlock(&t->lock);
667
            spinlock_unlock(&t->lock);
658
            printf("cpu%u: ", i);
668
            printf("cpu%u: ", i);
659
            thread_ready(t);
669
            thread_ready(t);
660
            thread_join(t);
670
            thread_join(t);
661
            thread_detach(t);
671
            thread_detach(t);
662
        } else
672
        } else
663
            printf("Unable to create thread for cpu%u\n", i);
673
            printf("Unable to create thread for cpu%u\n", i);
664
    }
674
    }
665
   
675
   
666
    return 1;
676
    return 1;
667
}
677
}
668
 
678
 
669
/** Call function with one parameter */
679
/** Call function with one parameter */
670
int cmd_call1(cmd_arg_t *argv)
680
int cmd_call1(cmd_arg_t *argv)
671
{
681
{
-
 
682
#ifdef CONFIG_SYMTAB
672
    uintptr_t symaddr;
683
    uintptr_t symaddr;
673
    char *symbol;
684
    char *symbol;
674
    unative_t (*fnc)(unative_t, ...);
685
    unative_t (*fnc)(unative_t, ...);
675
    unative_t arg1 = argv[1].intval;
686
    unative_t arg1 = argv[1].intval;
676
    fncptr_t fptr;
687
    fncptr_t fptr;
677
   
688
   
678
    symaddr = get_symbol_addr((char *) argv->buffer);
689
    symaddr = get_symbol_addr((char *) argv->buffer);
-
 
690
 
679
    if (!symaddr)
691
    if (!symaddr)
680
        printf("Symbol %s not found.\n", argv->buffer);
692
        printf("Symbol %s not found.\n", argv->buffer);
681
    else if (symaddr == (uintptr_t) -1) {
693
    else if (symaddr == (uintptr_t) -1) {
682
        symtab_print_search((char *) argv->buffer);
694
        symtab_print_search((char *) argv->buffer);
683
        printf("Duplicate symbol, be more specific.\n");
695
        printf("Duplicate symbol, be more specific.\n");
684
    } else {
696
    } else {
685
        symbol = get_symtab_entry(symaddr);
697
        symbol = get_symtab_entry(symaddr);
686
        fnc = (unative_t (*)(unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call1);
698
        fnc = (unative_t (*)(unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call1);
687
        printf("Calling f(%#" PRIxn "): %p: %s\n", arg1, symaddr, symbol);
699
        printf("Calling f(%#" PRIxn "): %p: %s\n", arg1, symaddr, symbol);
688
        printf("Result: %#" PRIxn "\n", fnc(arg1));
700
        printf("Result: %#" PRIxn "\n", fnc(arg1));
689
    }
701
    }
690
   
702
#endif
691
    return 1;
703
    return 1;
692
}
704
}
693
 
705
 
694
/** Call function with two parameters */
706
/** Call function with two parameters */
695
int cmd_call2(cmd_arg_t *argv)
707
int cmd_call2(cmd_arg_t *argv)
696
{
708
{
-
 
709
#ifdef CONFIG_SYMTAB
697
    uintptr_t symaddr;
710
    uintptr_t symaddr;
698
    char *symbol;
711
    char *symbol;
699
    unative_t (*fnc)(unative_t, unative_t, ...);
712
    unative_t (*fnc)(unative_t, unative_t, ...);
700
    unative_t arg1 = argv[1].intval;
713
    unative_t arg1 = argv[1].intval;
701
    unative_t arg2 = argv[2].intval;
714
    unative_t arg2 = argv[2].intval;
702
    fncptr_t fptr;
715
    fncptr_t fptr;
703
   
716
   
704
    symaddr = get_symbol_addr((char *) argv->buffer);
717
    symaddr = get_symbol_addr((char *) argv->buffer);
705
    if (!symaddr)
718
    if (!symaddr)
706
        printf("Symbol %s not found.\n", argv->buffer);
719
        printf("Symbol %s not found.\n", argv->buffer);
707
    else if (symaddr == (uintptr_t) -1) {
720
    else if (symaddr == (uintptr_t) -1) {
708
        symtab_print_search((char *) argv->buffer);
721
        symtab_print_search((char *) argv->buffer);
709
        printf("Duplicate symbol, be more specific.\n");
722
        printf("Duplicate symbol, be more specific.\n");
710
    } else {
723
    } else {
711
        symbol = get_symtab_entry(symaddr);
724
        symbol = get_symtab_entry(symaddr);
712
        fnc = (unative_t (*)(unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call2);
725
        fnc = (unative_t (*)(unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call2);
713
        printf("Calling f(%#" PRIxn ", %#" PRIxn "): %p: %s\n",
726
        printf("Calling f(%#" PRIxn ", %#" PRIxn "): %p: %s\n",
714
               arg1, arg2, symaddr, symbol);
727
               arg1, arg2, symaddr, symbol);
715
        printf("Result: %#" PRIxn "\n", fnc(arg1, arg2));
728
        printf("Result: %#" PRIxn "\n", fnc(arg1, arg2));
716
    }
729
    }  
717
   
730
#endif
718
    return 1;
731
    return 1;
719
}
732
}
720
 
733
 
721
/** Call function with three parameters */
734
/** Call function with three parameters */
722
int cmd_call3(cmd_arg_t *argv)
735
int cmd_call3(cmd_arg_t *argv)
723
{
736
{
-
 
737
#ifdef CONFIG_SYMTAB
724
    uintptr_t symaddr;
738
    uintptr_t symaddr;
725
    char *symbol;
739
    char *symbol;
726
    unative_t (*fnc)(unative_t, unative_t, unative_t, ...);
740
    unative_t (*fnc)(unative_t, unative_t, unative_t, ...);
727
    unative_t arg1 = argv[1].intval;
741
    unative_t arg1 = argv[1].intval;
728
    unative_t arg2 = argv[2].intval;
742
    unative_t arg2 = argv[2].intval;
729
    unative_t arg3 = argv[3].intval;
743
    unative_t arg3 = argv[3].intval;
730
    fncptr_t fptr;
744
    fncptr_t fptr;
731
   
745
   
732
    symaddr = get_symbol_addr((char *) argv->buffer);
746
    symaddr = get_symbol_addr((char *) argv->buffer);
733
    if (!symaddr)
747
    if (!symaddr)
734
        printf("Symbol %s not found.\n", argv->buffer);
748
        printf("Symbol %s not found.\n", argv->buffer);
735
    else if (symaddr == (uintptr_t) -1) {
749
    else if (symaddr == (uintptr_t) -1) {
736
        symtab_print_search((char *) argv->buffer);
750
        symtab_print_search((char *) argv->buffer);
737
        printf("Duplicate symbol, be more specific.\n");
751
        printf("Duplicate symbol, be more specific.\n");
738
    } else {
752
    } else {
739
        symbol = get_symtab_entry(symaddr);
753
        symbol = get_symtab_entry(symaddr);
740
        fnc = (unative_t (*)(unative_t, unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call3);
754
        fnc = (unative_t (*)(unative_t, unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call3);
741
        printf("Calling f(%#" PRIxn ",%#" PRIxn ", %#" PRIxn "): %p: %s\n",
755
        printf("Calling f(%#" PRIxn ",%#" PRIxn ", %#" PRIxn "): %p: %s\n",
742
               arg1, arg2, arg3, symaddr, symbol);
756
               arg1, arg2, arg3, symaddr, symbol);
743
        printf("Result: %#" PRIxn "\n", fnc(arg1, arg2, arg3));
757
        printf("Result: %#" PRIxn "\n", fnc(arg1, arg2, arg3));
744
    }
758
    }
745
   
759
#endif
746
    return 1;
760
    return 1;
747
}
761
}
748
 
762
 
749
 
763
 
750
/** Print detailed description of 'describe' command. */
764
/** Print detailed description of 'describe' command. */
751
void desc_help(void)
765
void desc_help(void)
752
{
766
{
753
    printf("Syntax: describe command_name\n");
767
    printf("Syntax: describe command_name\n");
754
}
768
}
755
 
769
 
756
/** Halt the kernel.
770
/** Halt the kernel.
757
 *
771
 *
758
 * @param argv Argument vector (ignored).
772
 * @param argv Argument vector (ignored).
759
 *
773
 *
760
 * @return 0 on failure, 1 on success (never returns).
774
 * @return 0 on failure, 1 on success (never returns).
761
 */
775
 */
762
int cmd_halt(cmd_arg_t *argv)
776
int cmd_halt(cmd_arg_t *argv)
763
{
777
{
764
    halt();
778
    halt();
765
    return 1;
779
    return 1;
766
}
780
}
767
 
781
 
768
/** Command for printing TLB contents.
782
/** Command for printing TLB contents.
769
 *
783
 *
770
 * @param argv Not used.
784
 * @param argv Not used.
771
 *
785
 *
772
 * @return Always returns 1.
786
 * @return Always returns 1.
773
 */
787
 */
774
int cmd_tlb(cmd_arg_t *argv)
788
int cmd_tlb(cmd_arg_t *argv)
775
{
789
{
776
    tlb_print();
790
    tlb_print();
777
    return 1;
791
    return 1;
778
}
792
}
779
 
793
 
780
/** Command for printing physical memory configuration.
794
/** Command for printing physical memory configuration.
781
 *
795
 *
782
 * @param argv Not used.
796
 * @param argv Not used.
783
 *
797
 *
784
 * @return Always returns 1.
798
 * @return Always returns 1.
785
 */
799
 */
786
int cmd_physmem(cmd_arg_t *argv)
800
int cmd_physmem(cmd_arg_t *argv)
787
{
801
{
788
    physmem_print();
802
    physmem_print();
789
    return 1;
803
    return 1;
790
}
804
}
791
 
805
 
792
/** Write 4 byte value to address */
806
/** Write 4 byte value to address */
793
int cmd_set4(cmd_arg_t *argv)
807
int cmd_set4(cmd_arg_t *argv)
794
{
808
{
795
    uint32_t *addr;
809
    uint32_t *addr;
796
    uint32_t arg1 = argv[1].intval;
810
    uint32_t arg1 = argv[1].intval;
797
    bool pointer = false;
811
    bool pointer = false;
798
 
812
 
799
    if (((char *)argv->buffer)[0] == '*') {
813
    if (((char *)argv->buffer)[0] == '*') {
-
 
814
#ifdef CONFIG_SYMTAB
800
        addr = (uint32_t *) get_symbol_addr((char *) argv->buffer + 1);
815
        addr = (uint32_t *) get_symbol_addr((char *) argv->buffer + 1);
-
 
816
#else
-
 
817
        addr = 0;
-
 
818
#endif
801
        pointer = true;
819
        pointer = true;
802
    } else if (((char *) argv->buffer)[0] >= '0' &&
820
    } else if (((char *) argv->buffer)[0] >= '0' &&
803
           ((char *)argv->buffer)[0] <= '9')
821
           ((char *)argv->buffer)[0] <= '9') {
804
        addr = (uint32_t *)atoi((char *)argv->buffer);
822
        addr = (uint32_t *)atoi((char *)argv->buffer);
805
    else
823
    } else {
-
 
824
#ifdef CONFIG_SYMTAB
806
        addr = (uint32_t *)get_symbol_addr((char *) argv->buffer);
825
        addr = (uint32_t *)get_symbol_addr((char *) argv->buffer);
-
 
826
#else
-
 
827
        addr = 0;
-
 
828
#endif
-
 
829
    }
807
 
830
 
808
    if (!addr)
831
    if (!addr)
809
        printf("Symbol %s not found.\n", argv->buffer);
832
        printf("Symbol %s not found.\n", argv->buffer);
810
    else if (addr == (uint32_t *) -1) {
833
    else if (addr == (uint32_t *) -1) {
-
 
834
#ifdef CONFIG_SYMTAB
811
        symtab_print_search((char *) argv->buffer);
835
        symtab_print_search((char *) argv->buffer);
-
 
836
#endif
812
        printf("Duplicate symbol, be more specific.\n");
837
        printf("Duplicate symbol, be more specific.\n");
813
    } else {
838
    } else {
814
        if (pointer)
839
        if (pointer)
815
            addr = (uint32_t *)(*(unative_t *)addr);
840
            addr = (uint32_t *)(*(unative_t *)addr);
816
        printf("Writing %#" PRIx64 " -> %p\n", arg1, addr);
841
        printf("Writing %#" PRIx64 " -> %p\n", arg1, addr);
817
        *addr = arg1;
842
        *addr = arg1;
818
       
843
       
819
    }
844
    }
820
   
845
   
821
    return 1;
846
    return 1;
822
}
847
}
823
 
848
 
824
/** Command for listings SLAB caches
849
/** Command for listings SLAB caches
825
 *
850
 *
826
 * @param argv Ignores
851
 * @param argv Ignores
827
 *
852
 *
828
 * @return Always 1
853
 * @return Always 1
829
 */
854
 */
830
int cmd_slabs(cmd_arg_t * argv) {
855
int cmd_slabs(cmd_arg_t * argv) {
831
    slab_print_list();
856
    slab_print_list();
832
    return 1;
857
    return 1;
833
}
858
}
834
 
859
 
835
 
860
 
836
/** Command for listings Thread information
861
/** Command for listings Thread information
837
 *
862
 *
838
 * @param argv Ignores
863
 * @param argv Ignores
839
 *
864
 *
840
 * @return Always 1
865
 * @return Always 1
841
 */
866
 */
842
int cmd_threads(cmd_arg_t * argv) {
867
int cmd_threads(cmd_arg_t * argv) {
843
    thread_print_list();
868
    thread_print_list();
844
    return 1;
869
    return 1;
845
}
870
}
846
 
871
 
847
/** Command for listings Task information
872
/** Command for listings Task information
848
 *
873
 *
849
 * @param argv Ignores
874
 * @param argv Ignores
850
 *
875
 *
851
 * @return Always 1
876
 * @return Always 1
852
 */
877
 */
853
int cmd_tasks(cmd_arg_t * argv) {
878
int cmd_tasks(cmd_arg_t * argv) {
854
    task_print_list();
879
    task_print_list();
855
    return 1;
880
    return 1;
856
}
881
}
857
 
882
 
858
/** Command for listings Thread information
883
/** Command for listings Thread information
859
 *
884
 *
860
 * @param argv Ignores
885
 * @param argv Ignores
861
 *
886
 *
862
 * @return Always 1
887
 * @return Always 1
863
 */
888
 */
864
int cmd_sched(cmd_arg_t * argv) {
889
int cmd_sched(cmd_arg_t * argv) {
865
    sched_print_list();
890
    sched_print_list();
866
    return 1;
891
    return 1;
867
}
892
}
868
 
893
 
869
/** Command for listing memory zones
894
/** Command for listing memory zones
870
 *
895
 *
871
 * @param argv Ignored
896
 * @param argv Ignored
872
 *
897
 *
873
 * return Always 1
898
 * return Always 1
874
 */
899
 */
875
int cmd_zones(cmd_arg_t * argv) {
900
int cmd_zones(cmd_arg_t * argv) {
876
    zone_print_list();
901
    zone_print_list();
877
    return 1;
902
    return 1;
878
}
903
}
879
 
904
 
880
/** Command for memory zone details
905
/** Command for memory zone details
881
 *
906
 *
882
 * @param argv Integer argument from cmdline expected
907
 * @param argv Integer argument from cmdline expected
883
 *
908
 *
884
 * return Always 1
909
 * return Always 1
885
 */
910
 */
886
int cmd_zone(cmd_arg_t * argv) {
911
int cmd_zone(cmd_arg_t * argv) {
887
    zone_print_one(argv[0].intval);
912
    zone_print_one(argv[0].intval);
888
    return 1;
913
    return 1;
889
}
914
}
890
 
915
 
891
/** Command for printing task ipc details
916
/** Command for printing task ipc details
892
 *
917
 *
893
 * @param argv Integer argument from cmdline expected
918
 * @param argv Integer argument from cmdline expected
894
 *
919
 *
895
 * return Always 1
920
 * return Always 1
896
 */
921
 */
897
int cmd_ipc(cmd_arg_t * argv) {
922
int cmd_ipc(cmd_arg_t * argv) {
898
    ipc_print_task(argv[0].intval);
923
    ipc_print_task(argv[0].intval);
899
    return 1;
924
    return 1;
900
}
925
}
901
 
926
 
902
 
927
 
903
/** Command for listing processors.
928
/** Command for listing processors.
904
 *
929
 *
905
 * @param argv Ignored.
930
 * @param argv Ignored.
906
 *
931
 *
907
 * return Always 1.
932
 * return Always 1.
908
 */
933
 */
909
int cmd_cpus(cmd_arg_t *argv)
934
int cmd_cpus(cmd_arg_t *argv)
910
{
935
{
911
    cpu_list();
936
    cpu_list();
912
    return 1;
937
    return 1;
913
}
938
}
914
 
939
 
915
/** Command for printing kernel version.
940
/** Command for printing kernel version.
916
 *
941
 *
917
 * @param argv Ignored.
942
 * @param argv Ignored.
918
 *
943
 *
919
 * return Always 1.
944
 * return Always 1.
920
 */
945
 */
921
int cmd_version(cmd_arg_t *argv)
946
int cmd_version(cmd_arg_t *argv)
922
{
947
{
923
    version_print();
948
    version_print();
924
    return 1;
949
    return 1;
925
}
950
}
926
 
951
 
927
/** Command for returning console back to userspace.
952
/** Command for returning console back to userspace.
928
 *
953
 *
929
 * @param argv Ignored.
954
 * @param argv Ignored.
930
 *
955
 *
931
 * return Always 1.
956
 * return Always 1.
932
 */
957
 */
933
int cmd_continue(cmd_arg_t *argv)
958
int cmd_continue(cmd_arg_t *argv)
934
{
959
{
935
    printf("The kernel will now relinquish the console.\n");
960
    printf("The kernel will now relinquish the console.\n");
936
    release_console();
961
    release_console();
937
   
962
   
938
    if ((kconsole_notify) && (kconsole_irq.notif_cfg.notify))
963
    if ((kconsole_notify) && (kconsole_irq.notif_cfg.notify))
939
        ipc_irq_send_msg_0(&kconsole_irq);
964
        ipc_irq_send_msg_0(&kconsole_irq);
940
   
965
   
941
    return 1;
966
    return 1;
942
}
967
}
943
 
968
 
944
#ifdef CONFIG_TEST
969
#ifdef CONFIG_TEST
945
/** Command for printing kernel tests list.
970
/** Command for printing kernel tests list.
946
 *
971
 *
947
 * @param argv Ignored.
972
 * @param argv Ignored.
948
 *
973
 *
949
 * return Always 1.
974
 * return Always 1.
950
 */
975
 */
951
int cmd_tests(cmd_arg_t *argv)
976
int cmd_tests(cmd_arg_t *argv)
952
{
977
{
953
    size_t len = 0;
978
    size_t len = 0;
954
    test_t *test;
979
    test_t *test;
955
    for (test = tests; test->name != NULL; test++) {
980
    for (test = tests; test->name != NULL; test++) {
956
        if (strlen(test->name) > len)
981
        if (strlen(test->name) > len)
957
            len = strlen(test->name);
982
            len = strlen(test->name);
958
    }
983
    }
959
   
984
   
960
    for (test = tests; test->name != NULL; test++)
985
    for (test = tests; test->name != NULL; test++)
961
        printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
986
        printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
962
   
987
   
963
    printf("%-*s Run all safe tests\n", len, "*");
988
    printf("%-*s Run all safe tests\n", len, "*");
964
    return 1;
989
    return 1;
965
}
990
}
966
 
991
 
967
static bool run_test(const test_t *test)
992
static bool run_test(const test_t *test)
968
{
993
{
969
    printf("%s (%s)\n", test->name, test->desc);
994
    printf("%s (%s)\n", test->name, test->desc);
970
   
995
   
971
    /* Update and read thread accounting
996
    /* Update and read thread accounting
972
       for benchmarking */
997
       for benchmarking */
973
    ipl_t ipl = interrupts_disable();
998
    ipl_t ipl = interrupts_disable();
974
    spinlock_lock(&TASK->lock);
999
    spinlock_lock(&TASK->lock);
975
    uint64_t t0 = task_get_accounting(TASK);
1000
    uint64_t t0 = task_get_accounting(TASK);
976
    spinlock_unlock(&TASK->lock);
1001
    spinlock_unlock(&TASK->lock);
977
    interrupts_restore(ipl);
1002
    interrupts_restore(ipl);
978
   
1003
   
979
    /* Execute the test */
1004
    /* Execute the test */
980
    char * ret = test->entry(false);
1005
    char * ret = test->entry(false);
981
   
1006
   
982
    /* Update and read thread accounting */
1007
    /* Update and read thread accounting */
983
    ipl = interrupts_disable();
1008
    ipl = interrupts_disable();
984
    spinlock_lock(&TASK->lock);
1009
    spinlock_lock(&TASK->lock);
985
    uint64_t dt = task_get_accounting(TASK) - t0;
1010
    uint64_t dt = task_get_accounting(TASK) - t0;
986
    spinlock_unlock(&TASK->lock);
1011
    spinlock_unlock(&TASK->lock);
987
    interrupts_restore(ipl);
1012
    interrupts_restore(ipl);
988
   
1013
   
989
    uint64_t cycles;
1014
    uint64_t cycles;
990
    char suffix;
1015
    char suffix;
991
    order(dt, &cycles, &suffix);
1016
    order(dt, &cycles, &suffix);
992
       
1017
       
993
    printf("Time: %" PRIu64 "%c cycles\n", cycles, suffix);
1018
    printf("Time: %" PRIu64 "%c cycles\n", cycles, suffix);
994
   
1019
   
995
    if (ret == NULL) {
1020
    if (ret == NULL) {
996
        printf("Test passed\n");
1021
        printf("Test passed\n");
997
        return true;
1022
        return true;
998
    }
1023
    }
999
 
1024
 
1000
    printf("%s\n", ret);
1025
    printf("%s\n", ret);
1001
    return false;
1026
    return false;
1002
}
1027
}
1003
 
1028
 
1004
static bool run_bench(const test_t *test, const uint32_t cnt)
1029
static bool run_bench(const test_t *test, const uint32_t cnt)
1005
{
1030
{
1006
    uint32_t i;
1031
    uint32_t i;
1007
    bool ret = true;
1032
    bool ret = true;
1008
    uint64_t cycles;
1033
    uint64_t cycles;
1009
    char suffix;
1034
    char suffix;
1010
   
1035
   
1011
    if (cnt < 1)
1036
    if (cnt < 1)
1012
        return true;
1037
        return true;
1013
   
1038
   
1014
    uint64_t *data = (uint64_t *) malloc(sizeof(uint64_t) * cnt, 0);
1039
    uint64_t *data = (uint64_t *) malloc(sizeof(uint64_t) * cnt, 0);
1015
    if (data == NULL) {
1040
    if (data == NULL) {
1016
        printf("Error allocating memory for statistics\n");
1041
        printf("Error allocating memory for statistics\n");
1017
        return false;
1042
        return false;
1018
    }
1043
    }
1019
   
1044
   
1020
    for (i = 0; i < cnt; i++) {
1045
    for (i = 0; i < cnt; i++) {
1021
        printf("%s (%u/%u) ... ", test->name, i + 1, cnt);
1046
        printf("%s (%u/%u) ... ", test->name, i + 1, cnt);
1022
       
1047
       
1023
        /* Update and read thread accounting
1048
        /* Update and read thread accounting
1024
           for benchmarking */
1049
           for benchmarking */
1025
        ipl_t ipl = interrupts_disable();
1050
        ipl_t ipl = interrupts_disable();
1026
        spinlock_lock(&TASK->lock);
1051
        spinlock_lock(&TASK->lock);
1027
        uint64_t t0 = task_get_accounting(TASK);
1052
        uint64_t t0 = task_get_accounting(TASK);
1028
        spinlock_unlock(&TASK->lock);
1053
        spinlock_unlock(&TASK->lock);
1029
        interrupts_restore(ipl);
1054
        interrupts_restore(ipl);
1030
       
1055
       
1031
        /* Execute the test */
1056
        /* Execute the test */
1032
        char * ret = test->entry(true);
1057
        char * ret = test->entry(true);
1033
       
1058
       
1034
        /* Update and read thread accounting */
1059
        /* Update and read thread accounting */
1035
        ipl = interrupts_disable();
1060
        ipl = interrupts_disable();
1036
        spinlock_lock(&TASK->lock);
1061
        spinlock_lock(&TASK->lock);
1037
        uint64_t dt = task_get_accounting(TASK) - t0;
1062
        uint64_t dt = task_get_accounting(TASK) - t0;
1038
        spinlock_unlock(&TASK->lock);
1063
        spinlock_unlock(&TASK->lock);
1039
        interrupts_restore(ipl);
1064
        interrupts_restore(ipl);
1040
       
1065
       
1041
        if (ret != NULL) {
1066
        if (ret != NULL) {
1042
            printf("%s\n", ret);
1067
            printf("%s\n", ret);
1043
            ret = false;
1068
            ret = false;
1044
            break;
1069
            break;
1045
        }
1070
        }
1046
       
1071
       
1047
        data[i] = dt;
1072
        data[i] = dt;
1048
        order(dt, &cycles, &suffix);
1073
        order(dt, &cycles, &suffix);
1049
        printf("OK (%" PRIu64 "%c cycles)\n", cycles, suffix);
1074
        printf("OK (%" PRIu64 "%c cycles)\n", cycles, suffix);
1050
    }
1075
    }
1051
   
1076
   
1052
    if (ret) {
1077
    if (ret) {
1053
        printf("\n");
1078
        printf("\n");
1054
       
1079
       
1055
        uint64_t sum = 0;
1080
        uint64_t sum = 0;
1056
       
1081
       
1057
        for (i = 0; i < cnt; i++) {
1082
        for (i = 0; i < cnt; i++) {
1058
            sum += data[i];
1083
            sum += data[i];
1059
        }
1084
        }
1060
       
1085
       
1061
        order(sum / (uint64_t) cnt, &cycles, &suffix);
1086
        order(sum / (uint64_t) cnt, &cycles, &suffix);
1062
        printf("Average\t\t%" PRIu64 "%c\n", cycles, suffix);
1087
        printf("Average\t\t%" PRIu64 "%c\n", cycles, suffix);
1063
    }
1088
    }
1064
   
1089
   
1065
    free(data);
1090
    free(data);
1066
   
1091
   
1067
    return ret;
1092
    return ret;
1068
}
1093
}
1069
 
1094
 
1070
/** Command for returning kernel tests
1095
/** Command for returning kernel tests
1071
 *
1096
 *
1072
 * @param argv Argument vector.
1097
 * @param argv Argument vector.
1073
 *
1098
 *
1074
 * return Always 1.
1099
 * return Always 1.
1075
 */
1100
 */
1076
int cmd_test(cmd_arg_t *argv)
1101
int cmd_test(cmd_arg_t *argv)
1077
{
1102
{
1078
    test_t *test;
1103
    test_t *test;
1079
   
1104
   
1080
    if (strcmp((char *) argv->buffer, "*") == 0) {
1105
    if (strcmp((char *) argv->buffer, "*") == 0) {
1081
        for (test = tests; test->name != NULL; test++) {
1106
        for (test = tests; test->name != NULL; test++) {
1082
            if (test->safe) {
1107
            if (test->safe) {
1083
                printf("\n");
1108
                printf("\n");
1084
                if (!run_test(test))
1109
                if (!run_test(test))
1085
                    break;
1110
                    break;
1086
            }
1111
            }
1087
        }
1112
        }
1088
    } else {
1113
    } else {
1089
        bool fnd = false;
1114
        bool fnd = false;
1090
       
1115
       
1091
        for (test = tests; test->name != NULL; test++) {
1116
        for (test = tests; test->name != NULL; test++) {
1092
            if (strcmp(test->name, (char *) argv->buffer) == 0) {
1117
            if (strcmp(test->name, (char *) argv->buffer) == 0) {
1093
                fnd = true;
1118
                fnd = true;
1094
                run_test(test);
1119
                run_test(test);
1095
                break;
1120
                break;
1096
            }
1121
            }
1097
        }
1122
        }
1098
       
1123
       
1099
        if (!fnd)
1124
        if (!fnd)
1100
            printf("Unknown test\n");
1125
            printf("Unknown test\n");
1101
    }
1126
    }
1102
   
1127
   
1103
    return 1;
1128
    return 1;
1104
}
1129
}
1105
 
1130
 
1106
/** Command for returning kernel tests as benchmarks
1131
/** Command for returning kernel tests as benchmarks
1107
 *
1132
 *
1108
 * @param argv Argument vector.
1133
 * @param argv Argument vector.
1109
 *
1134
 *
1110
 * return Always 1.
1135
 * return Always 1.
1111
 */
1136
 */
1112
int cmd_bench(cmd_arg_t *argv)
1137
int cmd_bench(cmd_arg_t *argv)
1113
{
1138
{
1114
    test_t *test;
1139
    test_t *test;
1115
    uint32_t cnt = argv[1].intval;
1140
    uint32_t cnt = argv[1].intval;
1116
   
1141
   
1117
    bool fnd = false;
1142
    bool fnd = false;
1118
   
1143
   
1119
    for (test = tests; test->name != NULL; test++) {
1144
    for (test = tests; test->name != NULL; test++) {
1120
        if (strcmp(test->name, (char *) argv->buffer) == 0) {
1145
        if (strcmp(test->name, (char *) argv->buffer) == 0) {
1121
            fnd = true;
1146
            fnd = true;
1122
           
1147
           
1123
            if (test->safe)
1148
            if (test->safe)
1124
                run_bench(test, cnt);
1149
                run_bench(test, cnt);
1125
            else
1150
            else
1126
                printf("Unsafe test\n");
1151
                printf("Unsafe test\n");
1127
           
1152
           
1128
            break;
1153
            break;
1129
        }
1154
        }
1130
    }
1155
    }
1131
       
1156
       
1132
    if (!fnd)
1157
    if (!fnd)
1133
        printf("Unknown test\n");
1158
        printf("Unknown test\n");
1134
 
1159
 
1135
    return 1;
1160
    return 1;
1136
}
1161
}
1137
 
1162
 
1138
#endif
1163
#endif
1139
 
1164
 
1140
/** @}
1165
/** @}
1141
 */
1166
 */
1142
 
1167