import cbaos v0.1
[cbaos.git] / cbashell / command.c
blob4e98387846a7337c033e97f0410012655f7ce69c
1 /* Author: Domen Puncer <domen@cba.si>. License: WTFPL, see file LICENSE */
2 #include <ctype.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdio.h>
6 #include "command.h"
7 #include "types.h"
8 #ifdef ARCH_ARM_CORTEX_M3
9 #include <arch/cm3_regs.h>
10 #endif
13 static int command_x(const char *_cmd)
15 static int len = 1;
16 static int size = 4;
17 static u32 addr;
18 char *cmd = (char*)_cmd; /* we don't change it, but strtol is idiotic */
20 if (cmd[0] != 'x' || isalpha(cmd[1]))
21 return 0;
23 cmd++;
24 if (*cmd == '/') {
25 cmd++;
26 if (isdigit(*cmd)) {
27 len = strtoul(cmd, &cmd, 0);
28 /* just some sanity */
29 if (len > 1024)
30 len = 1024;
32 // while, check for xs...
33 if (isalpha(*cmd)) {
34 if (*cmd == 'b')
35 size = 1;
36 else if (*cmd == 'h')
37 size = 2;
38 else if (*cmd == 'w')
39 size = 4;
40 else {
41 printf("E: invalid argument for size\n");
42 return -1;
44 cmd++;
47 if (*cmd == ' ') {
48 cmd++;
49 if (isdigit(*cmd))
50 addr = strtoul(cmd, NULL, 0);
53 /* currently it only works for hex, with size 4 */
54 int i;
55 printf("%#010x: ", addr);
56 for (i=0; i<len; i++) {
57 if (i % 8 == 0 && i) {
58 printf("\n%#010x: ", addr);
60 printf("%#010x ", *(u32*)addr);
61 addr += size;
63 printf("\n");
65 return 1;
68 static int command_boot(const char *cmd)
70 if (strcmp(cmd, "boot") != 0)
71 return 0;
73 #ifdef ARCH_ARM_CORTEX_M3
74 AIRCR = (AIRCR & 0x8700) | 0x05FA<<16 /* magic */ | 1<<2 /* SYSRESETREQ */;
75 #endif
77 while (1)
81 static int command_fail(const char *cmd)
83 volatile u32 *tmp = (volatile u32*)0x12345678;
84 void (*f)() = (void (*)())0x23456789;
86 if (strncmp(cmd, "fail ", 5) != 0)
87 return 0;
89 switch (cmd[5]) {
90 case '0':
91 /* invalid pointer deference */
92 *tmp = 0xcba;
93 break;
94 case '1':
95 /* invalid pointer deference */
96 f();
97 break;
98 case 's':
99 /* invalid stack pointer */
100 #ifdef ARCH_ARM_CORTEX_M3
101 asm volatile ("ldr sp, =#0x87654321\n\t");
102 #endif
103 break;
104 case 'u':
105 /* undefined instruction */
106 #ifdef ARCH_ARM_CORTEX_M3
107 *(u32*)0xe000ed24 |= 1<<18; /* enable usage fault */
108 /* http://www.keil.com/support/man/docs/armasm/armasm_cihjijca.htm */
109 asm volatile (".short 0xdead\n\t"); /* arm arm says, 0xdexx for thumb */
110 /* some other document said 1101 011... 1 xxxx for arm mode */
111 #endif
112 break;
113 case '2':
114 /* svc */
115 #ifdef ARCH_ARM_CORTEX_M3
116 asm volatile ("svc #0\n");
117 #endif
118 break;
119 default:
120 if (cmd[5])
121 printf("%s: unknown argument %c\n", __func__, cmd[5]);
122 printf("fail arguments: \n"
123 "\t0 - write to invalid pointer\n"
124 "\t1 - call invalid function\n"
125 "\ts - corrupt stack pointer\n"
126 "\tu - undefined instruction\n"
129 return 1;
132 static int command_test(const char *cmd)
134 if (strncmp(cmd, "test ", 5) != 0)
135 return 0;
136 char foo[16];
137 strncpy(foo, cmd+5, 16);
138 foo[15] = 0;
139 //eprom_test(foo);
141 printf("%s: %02x %02x %02x %02x\n", __func__, foo[0], foo[1], foo[2], foo[3]);
142 return 1;
145 static int command_help(const char *cmd)
147 if (strcmp(cmd, "help") != 0)
148 return 0;
149 printf("something helpful should be written here\n");
150 return 1;
152 static int command_invalid(const char *cmd)
154 if (*cmd)
155 printf("invalid command\n");
156 return 1;
159 /* 1 for handled, 0 for not handled, negative for error (should abort handling) */
160 int (* const command_list[])(const char *cmd) = {
161 command_x,
162 command_boot,
163 command_fail,
164 command_test,
165 command_help,
166 command_invalid,
167 NULL