Subversion Repositories HelenOS

Rev

Rev 2019 | Rev 2027 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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