os-workshop

same materials and sample source for RV32 OS projects
git clone http://frotz.net/git/os-workshop.git
Log | Files | Refs

console.c (4772B)


      1 // Copyright 2022, Brian Swetland <swetland@frotz.net>
      2 // Licensed under the Apache License, Version 2.0
      3 
      4 #include <hw/riscv.h>
      5 #include <hw/intrinsics.h>
      6 #include <hw/context.h>
      7 #include <hw/debug.h>
      8 #include "boot.h"
      9 #include <string.h>
     10 
     11 int atoi(const char *s) {
     12 	unsigned c;
     13 	int n = 0;
     14 	while ((c = *s++)) {
     15 		if ((c >= '0') && (c <= '9')) {
     16 			n = n * 10 + (c - '0');
     17 		} else {
     18 			break;
     19 		}
     20 	}
     21 	return n;
     22 }
     23 
     24 uint32_t atox(const char *s) {
     25 	uint32_t n = 0;
     26 	uint32_t c;
     27 	while ((c = *s++)) {
     28 		switch (c) {
     29 		case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
     30 			c = c - 'a' + 10;
     31 			break;
     32 		case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
     33 			c = c - 'A' + 10;
     34 			break;
     35 		case '0': case '1': case '2': case '3': case '4':
     36 		case '5': case '6': case '7': case '8': case '9':
     37 			c = c - '0';
     38 			break;
     39 		default:
     40 			return n;
     41 		}
     42 		n = (n << 4) | c;
     43 	}
     44 	return n;
     45 }
     46 
     47 extern eframe_t* EF;
     48 extern volatile int STOP;
     49 
     50 
     51 // args: x hex number
     52 //       i integer number
     53 //       s string
     54 typedef struct {
     55 	const char* name;
     56 	const char* args;
     57 	const char* help;
     58 	void *fn;
     59 } console_cmd_t;
     60 
     61 void do_regs(void) {
     62 	eframe_t* ef = EF;
     63 	xprintf("pc %08x ra %08x sp %08x gp %08x  sstatus  %08x\n",
     64 		ef->pc, ef->ra, ef->sp, ef->gp, csr_read(CSR_SSTATUS));
     65 	xprintf("tp %08x t0 %08x t1 %08x t2 %08x  scause   %08x\n",
     66 		ef->tp, ef->t0, ef->t1, ef->t2, csr_read(CSR_SCAUSE));
     67 	xprintf("fp %08x s1 %08x a0 %08x a1 %08x  stval    %08x\n",
     68 		ef->s0, ef->s1, ef->a0, ef->a1, csr_read(CSR_STVAL));
     69 	xprintf("a2 %08x a3 %08x a4 %08x a5 %08x  stvec    %08x\n",
     70 		ef->a2, ef->a3, ef->a4, ef->a5, csr_read(CSR_STVEC));
     71 	xprintf("a6 %08x a7 %08x s2 %08x s3 %08x  sepc     %08x\n",
     72 		ef->a6, ef->a7, ef->s2, ef->s3, csr_read(CSR_SEPC));
     73 	xprintf("s4 %08x s5 %08x s6 %08x s7 %08x  sscratch %08x\n",
     74 		ef->s4, ef->s5, ef->s6, ef->s7, csr_read(CSR_SSCRATCH));
     75 	xprintf("s8 %08x s9 %08x 10 %08x 11 %08x  satp     %08x\n",
     76 		ef->s8, ef->s9, ef->s10, ef->s11, csr_read(CSR_SATP));
     77 	xprintf("t3 %08x t4 %08x t5 %08x t6 %08x  sip      %08x\n",
     78 		ef->t3, ef->t4, ef->t5, ef->t6, csr_read(CSR_SIP));
     79 }
     80 
     81 void do_help(void);
     82 
     83 void do_dw(unsigned n, unsigned addr, unsigned count) {
     84 	if (n < 2) count = 1;
     85 	if (count > 1024) count = 1024;
     86 
     87 	n = 0;
     88 	while (n < count) {
     89 		if ((n & 3) == 0) {
     90 			xprintf("\n%08x:", addr);
     91 		}
     92 		xprintf(" %08x", rd32safe(addr));
     93 		addr += 4;
     94 		n++;
     95 	}
     96 	if ((n & 3) == 0) {
     97 		xprintf("\n");
     98 	}
     99 }
    100 
    101 void do_db(unsigned n, unsigned addr, int count) {
    102 	char txt[17];
    103 	if (count < 0) {
    104 		return;
    105 	}
    106 	txt[16] = 0;
    107 	while (count > 0) {
    108 		xprintf("%08x:", addr);
    109 		for (int i = 0; i < 16; i++) {
    110 			uint32_t c;
    111 			if (i < count) {
    112 				c = rd8safe(addr + i) & 0xFF;
    113 				xprintf(" %02x", c);
    114 				if ((c < ' ') || (c > 126)) c = '.';
    115 			} else {
    116 				xprintf("   ");
    117 				c = ' ';
    118 			}
    119 			txt[i] = c;
    120 		}
    121 		xprintf("  %s\n", txt);
    122 		addr += 16;
    123 		count -= 16;
    124 	}
    125 }
    126 
    127 void do_stop(void) { STOP = 1; }
    128 void do_cont(void) { STOP = 0; };
    129 
    130 console_cmd_t CMDS[] = {
    131 	{ "help", "", "help", do_help },
    132 	{ "regs", "", "dump registers", do_regs },
    133 	{ "dw", "xx", "dump words <addr> <count>", do_dw },
    134 	{ "db", "xx", "dump bytes <addr> <count>", do_db },
    135 	{ "stop", "", "stop execution", do_stop },
    136 	{ "cont", "", "continue execution", do_cont },
    137 };
    138 
    139 void do_help(void) {
    140 	for (unsigned n = 0; n < (sizeof(CMDS)/sizeof(CMDS[0])); n++) {
    141 		xprintf("%-16s %s\n", CMDS[n].name, CMDS[n].help);
    142 	}
    143 }
    144 
    145 void console_cmd(console_cmd_t *cmd, char *args[], unsigned argc) {
    146 	uintptr_t argx[4];
    147 	unsigned max = strlen(cmd->args);
    148 
    149 	if ((argc > max) || (argc > 4)) {
    150 		xprintf("error: too many arguments\n");
    151 		return;
    152 	}
    153 
    154 	memset(argx, 0, sizeof(argx));
    155 	for (unsigned n = 0; n < max; n++) {
    156 		switch (cmd->args[n]) {
    157 		case 'x':
    158 			argx[n] = (n < argc) ? atox(args[n]) : 0;
    159 			break;
    160 		case 'i':
    161 			argx[n] = (n < argc) ? atoi(args[n]) : 0;
    162 			break;
    163 		case 's':
    164 			argx[n] = (n < argc) ? (uintptr_t) args[n] : (uintptr_t) "";
    165 			break;
    166 		default:
    167 			xprintf("error: internal: bad args '%s'\n", cmd->args);
    168 			return;
    169 		}
    170 	}
    171 
    172 	console_call_cmd(cmd->fn, argx[0], argx[1], argx[2], argx[3], argc);
    173 }
    174 
    175 #define MAXTOK 16
    176 
    177 void console_line(char* line) {
    178 	char *token[MAXTOK];
    179 	unsigned toklen = 0;
    180 
    181 	while (toklen < MAXTOK) {
    182 		while(*line == ' ') {
    183 			if (*line == 0) {
    184 				goto done;
    185 			}
    186 			*line++ = 0;
    187 		}
    188 		token[toklen] = line;
    189 		while (*line != ' ') {
    190 			if (*line == 0) {
    191 				if (token[toklen] != line) {
    192 					*line = 0;
    193 					toklen++;
    194 				}
    195 				goto done;
    196 			}
    197 			line++;
    198 		}
    199 		toklen++;
    200 	}
    201 done:
    202 	if (toklen) {
    203 		for (unsigned n = 0; n < (sizeof(CMDS)/sizeof(CMDS[0])); n++) {
    204 			if (!strcmp(CMDS[n].name, token[0])) {
    205 				console_cmd(CMDS + n, token + 1, toklen - 1);
    206 				goto prompt;
    207 			}
    208 		}
    209 		xprintf("unknown command '%s'\n", token[0]);
    210 	}
    211 prompt:
    212 	xputs("monitor> ");
    213 }
    214 
    215 
    216