9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 18e04a044a1f3cac642ecae08ed5f4a82e5b7acf
parent 244bf0ba8a407b3dcc613323a920dd9278a097cb
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 11 Jul 2020 23:55:30 +0200

build: Rename romfw to kernel

Change-Id: I1dac20fb53cc6e4f9fca4ee097036057bb4ccdf8

Diffstat:
Mdrivers/dev.c | 2+-
Rinclude/rcode/romfw.h -> include/rcode/kernel.h | 0
Dinclude/rcode/ramfw.h | 1-
Dinclude/rcode/rmu.h | 28----------------------------
Msrc/Makefile | 2+-
Rsrc/romfw/.gitignore -> src/kernel/.gitignore | 0
Rsrc/romfw/Makefile -> src/kernel/Makefile | 0
Asrc/kernel/dlang.c | 437+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rsrc/romfw/dlang.h -> src/kernel/dlang.h | 0
Rsrc/romfw/ec.h -> src/kernel/ec.h | 0
Rsrc/romfw/mkecstr -> src/kernel/mkecstr | 0
Asrc/kernel/rmc.c | 190+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/romfw/dlang.c | 437-------------------------------------------------------------------------------
Dsrc/romfw/mkrmu | 38--------------------------------------
Dsrc/romfw/rmc.c | 233-------------------------------------------------------------------------------
Mtarget/hosted/Makefile | 10+++++-----
Atarget/hosted/kernel.c | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtarget/hosted/rom.c | 93-------------------------------------------------------------------------------
Mtarget/native/Makefile | 27++++++++++++---------------
Rtarget/native/crt.s -> target/native/crt-kernel.s | 0
Rtarget/native/rom.c -> target/native/kernel.c | 0
Dtarget/native/rom-crt.s | 2--
22 files changed, 739 insertions(+), 854 deletions(-)

diff --git a/drivers/dev.c b/drivers/dev.c @@ -3,7 +3,7 @@ #include <string.h> #include <rcode/rcode.h> -#include <rcode/romfw.h> +#include <rcode/kernel.h> #include <rcode/io.h> #include "dev.h" diff --git a/include/rcode/romfw.h b/include/rcode/kernel.h diff --git a/include/rcode/ramfw.h b/include/rcode/ramfw.h @@ -1 +0,0 @@ - diff --git a/include/rcode/rmu.h b/include/rcode/rmu.h @@ -1,28 +0,0 @@ -#define RMU_MAJ_VER 0 -#define RMU_MIN_VER 1 - -enum rmcerr { - SUCCESS = 0, /* Command completed successfully */ - NOTCOMPLETE = 1, /* Interruptible command did not complete */ - EPARAMETER = 2, /* Invalid input param provided */ - ERESOURCESTATE = 3, /* RMU object state pre-cond violation */ - ERESOURCEINUSE = 4, /* RMU object busy */ - EREALMSTATE = 5, /* Realm state pre-cond violation */ - EGRANULEOWNER = 6, /* RPG owner pre-cond violation */ - EGRANULESTATE = 7, /* RPG state pre-cond violation */ - EGRANULEVISIB = 8, /* RPG visibility pre-cond violation */ - EGRANULEINTEG = 9, /* RPG integrity pre-cond violation */ - ECRYPTO = 10, /* Crypto check failed */ - EGRANULEACCESS = 11, /* Mapped addr not within PAR */ - FGRANULEPINNED = 12, /* RPG is RMU pinned */ - FRETRY = 13, /* Caller should retry the command */ - FFAULT = 14, /* Input address translation fault */ - EDEBUGSTATE = 15, /* Realm debug is not allowed */ - FGRANULEFUSED = 16, /* RPG is fused */ - NR_RMCERRS -}; - -extern void RMU_System_InterfaceVersion(unsigned long *maj, - unsigned long *min); -extern void RMU_System_Status(int *enabled); -extern void RMU_System_Enable(void); diff --git a/src/Makefile b/src/Makefile @@ -3,7 +3,7 @@ PROJECTDIR=.. include $(PROJECTDIR)/scripts/rules.mk LIBS = lib9p libk libc -IMGS = romfw +IMGS = kernel DIRS = $(LIBS) $(IMGS) all: $(IMGS) diff --git a/src/romfw/.gitignore b/src/kernel/.gitignore diff --git a/src/romfw/Makefile b/src/kernel/Makefile diff --git a/src/kernel/dlang.c b/src/kernel/dlang.c @@ -0,0 +1,437 @@ +#include <ctype.h> +#include <errno.h> +#include <setjmp.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <libk.h> +#include <rcode/rcode.h> +#include <rcode/kernel.h> + +#include "ec.h" +#include "dlang.h" + +#define PREFIX "> " +#define NR_ARGC_MAX 5 + +unsigned in_debug; +jmp_buf dbgrecover; + +struct args { + char *argv[NR_ARGC_MAX]; + int argc; + int status; +}; + +struct cmd { + char *name; + char *helpmsg; + int (*eval)(const struct cmd *cmd, struct args *args); + unsigned char min; + unsigned char max; +}; + +static const struct cmd cmds[]; + +static void +error(char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + kputs(kerr, PREFIX "ERR "); + kvprint(kerr, fmt, va); + kputc(kerr, '\n'); + longjmp(dbgrecover, 1); +} + +static void +ready(void) +{ + kputs(kout, PREFIX "READY\n"); +} + +/* Read a value in a given base between 2 and 16 0 means default base; + * 10, unless the string begins with "0x" or "0b" + */ +static unsigned long long +estrtoull(char *str, int base) +{ + unsigned long long val; + char *endptr; + + errno = 0; + val = strtoull(str, &endptr, base); + if (*str == '\0' || *endptr != '\0') + error("estrtoull: %s: not an integer", str); + if (errno) + error("estrtoull: %s: %s", strerror(errno)); + return val; +} + +/* Get reg struct for named reg */ +static unsigned long long * +get_named_reg(char *name, struct trapframe *fp) +{ + int i; + + for (i = 0; i < NR_REGS; i++) + if (strcmp(name, regnames[i]) == 0) + return &fp->r[i]; + return NULL; +} + +/* Get cmd struct for named cmd */ +static const struct cmd * +get_cmd(char *name) +{ + const struct cmd *cmd; + + for (cmd = cmds; cmd->name; cmd++) { + if (strcmp(cmd->name, name) == 0) + return cmd; + } + return NULL; +} + +static int +do_set(const struct cmd *cmd, struct args *args) +{ + unsigned long long *reg = NULL; + unsigned long long setval = 0; + + reg = get_named_reg(args->argv[1], framep); + if (reg == NULL) + error("set: %s: not found", args->argv[1]); + + setval = estrtoull(args->argv[2], 0); + *reg = setval; + return 0; +} + +static int +do_get(const struct cmd *cmd, struct args *args) +{ + unsigned long long *reg = NULL; + + reg = get_named_reg(args->argv[1], framep); + if (reg == NULL) + error("get: %s: not found", args->argv[1]); + + kprint(kout, "%llx\n", *reg); + return 0; +} + +static int +do_dump(const struct cmd *cmd, struct args *args) +{ + dumpregs(framep, kout); + return 0; +} + +static int +do_trap(const struct cmd *cmd, struct args *args) +{ + trap(framep); + return 0; +} + +static int +do_rmc(const struct cmd *cmd, struct args *args) +{ + unsigned char class; + unsigned char func; + + class = estrtoull(args->argv[1], 0); + func = estrtoull(args->argv[2], 0); + + framep->r[ESR] = (unsigned long long) RMC << 26; + framep->r[ESR] |= class; + framep->r[ESR] |= (func << 8); + trap(framep); + return 0; +} + +static int +do_exit(const struct cmd *cmd, struct args *args) +{ + args->status = 0; + if (args->argc == 2) + args->status = estrtoull(args->argv[1], 0); + return -1; +} + +static int +do_help(const struct cmd *cmd, struct args *args) +{ + for (cmd = cmds; cmd->name; cmd++) { + char *s = cmd->helpmsg; + kprint(kout, "%s\n", s); + } + return 0; +} + +static int +do_cat(const struct cmd *cmd, struct args *args) +{ + int fd, n; + char buf[100]; + + if ((fd = open(args->argv[1], O_READ)) < 0) + goto err; + + while ((n = read(fd, buf, sizeof(buf))) > 0) + write(kin, buf, n); + + if (close(fd) < 0 || n < 0) + goto err; + + return 0; + +err: + kerror(PREFIX "ERR cat"); + return 0; +} + +static int +do_ls(const struct cmd *cmd, struct args *args) +{ + int n; + DIR *dir; + struct dirent d; + + if ((dir = opendir(args->argv[1])) == NULL) + goto err; + + while ((n = readdir(dir, &d)) > 0) + kprint(kout, "%s\n", d.d_name); + + if (closedir(dir) < 0 || n < 0) + goto err; + + return 0; + +err: + kerror(PREFIX "ERR ls"); + return 0; +} + +static int +do_echo(const struct cmd *cmd, struct args *args) +{ + int fd, i, len, offset, n; + char *s, buffer[LINELEN]; + + if ((fd = open(args->argv[1], O_WRITE)) < 0) + goto err; + + offset = 0; + for (i = 2; i < args->argc; i++) { + s = args->argv[i]; + len = strlen(s); + if (len + offset >= LINELEN-2) + error("line too long"); + memcpy(buffer + offset, s, len); + offset += len; + buffer[offset++] = ' '; + } + buffer[offset] = '\n'; + n = write(fd, buffer, offset); + + if (close(fd) < 0 || n < 0) + goto err; + + return 0; +err: + kerror(PREFIX "ERR echo"); + return 0; +} + +static int +do_stat(const struct cmd *cmd, struct args *args) +{ + Dir dir; + + if (dirstat(args->argv[1], &dir) < 0) + goto err; + kprint(kout, + "name: %s\n" + "length: %ld\n" + "mode: %x\n" + "type: %d\n" + "dev: %d\n" + "qid: %x\n", + dir.name, + dir.length, + dir.mode, + dir.type, + dir.dev, + dir.qid + ); + + return 0; + +err: + kerror(PREFIX "ERR stat"); + return 0; +} + +static const struct cmd * +parse_cmd(char *buf, struct args *args) +{ + char *p; + const struct cmd *cmd; + const static char ws[] = " \t\r"; + + args->argc = 0; + for (p = strtok(buf, ws); p; p = strtok(NULL, ws)) { + if (args->argc == NR_ARGC_MAX) + error("too many parameters"); + args->argv[args->argc++] = p; + } + + if (args->argc == 0) + return NULL; + + if ((cmd = get_cmd(args->argv[0])) == NULL) + error("%s: not found", args->argv[0]); + + return cmd; +} + +static int +run(struct args *args) +{ + const struct cmd *cmd; + size_t len; + char buffer[LINELEN]; + + if (kgets(kin, buffer, sizeof(buffer)) == NULL) { + args->status = 1; + return -1; + } + + if ((len = strlen(buffer)) != 0) { + if (buffer[len-1] != '\n') + error("line too long"); + buffer[len-1] = '\0'; + cmd = parse_cmd(buffer, args); + if (cmd) { + int (*fn)(const struct cmd *, struct args *); + void *bp; + + if (args->argc < cmd->min || args->argc > cmd->max) + error(cmd->helpmsg); + bp = cmd->eval; + fn = (int (*)(const struct cmd *, struct args *)) bp; + return (*fn)(cmd, args); + } + } + + return 0; +} + +int +debug(void) +{ + struct args args; + + kprint(kout, "begin debug language interface\n"); + in_debug = 1; + setjmp(dbgrecover); + + for (ready(); !run(&args); ready()) + ; + kprint(kout, "end debug language interface\n"); + in_debug = 0; + + return args.status; +} + +/* + * definition of arrays + */ +static const struct cmd cmds[] = { + { + .name = "set", + .eval = do_set, + .min = 3, + .max = 3, + .helpmsg = "Set a register: set <reg> <value>", + }, + { + .name = "get", + .eval = do_get, + .min = 2, + .max = 2, + .helpmsg = "Get a register: get <reg>", + }, + { + .name = "dump", + .eval = do_dump, + .min = 1, + .max = 1, + .helpmsg = "Dump trapframe: dump", + }, + { + .name = "trap", + .eval = do_trap, + .min = 1, + .max = 1, + .helpmsg = "Call trap handler: trap", + }, + { + .name = "rmc", + .eval = do_rmc, + .min = 3, + .max = 3, + .helpmsg = "Call RMC handler: rmc imm1 imm2", + }, + { + .name = "exit", + .eval = do_exit, + .min = 1, + .max = 2, + .helpmsg = "Exit debug environment: exit [status]", + }, + { + .name = "help", + .eval = do_help, + .min = 1, + .max = 1, + .helpmsg = "Print this help menu: help", + }, + { + .name = "ls", + .eval = do_ls, + .min = 2, + .max = 2, + .helpmsg = "list content of a directory: ls path", + }, + { + .name = "cat", + .eval = do_cat, + .min = 2, + .max = 2, + .helpmsg = "read content from a file: cat path", + }, + { + .name = "echo", + .eval = do_echo, + .min = 3, + .max = NR_ARGC_MAX, + .helpmsg = "write content to a file: echo path string ...", + }, + { + .name = "stat", + .eval = do_stat, + .min = 2, + .max = 2, + .helpmsg = "display stat attribute: stat path", + }, + { + .name = NULL + } +}; diff --git a/src/romfw/dlang.h b/src/kernel/dlang.h diff --git a/src/romfw/ec.h b/src/kernel/ec.h diff --git a/src/romfw/mkecstr b/src/kernel/mkecstr diff --git a/src/kernel/rmc.c b/src/kernel/rmc.c @@ -0,0 +1,190 @@ +#include <setjmp.h> +#include <stdint.h> + +#include <libk.h> +#include <rcode/rcode.h> +#include <rcode/kernel.h> + +#include "ec.h" + +struct rmctab *rmctab; + +static unsigned in_panic; +static unsigned in_dumpstack; +static unsigned in_backtrace; +static struct rmucmd *rmucmd; +static char *errstr; + +const char *const regnames[] = { + [X0] = "x0", + [X1] = "x1", + [X2] = "x2", + [X3] = "x3", + [X4] = "x4", + [X5] = "x5", + [X6] = "x6", + [X7] = "x7", + [X8] = "x8", + [X9] = "x9", + [X10] = "x10", + [X11] = "x11", + [X12] = "x12", + [X13] = "x13", + [X14] = "x14", + [X15] = "x15", + [X16] = "x16", + [X17] = "x17", + [X18] = "x18", + [X19] = "x19", + [X20] = "x20", + [X21] = "x21", + [X22] = "x22", + [X23] = "x23", + [X24] = "x24", + [X25] = "x25", + [X26] = "x26", + [X27] = "x27", + [X28] = "x28", + [X29] = "x29", + [ELR] = "elr", + [X30] = "x30", + [SPSR] = "spsr", + [ESR] = "esr", + [SP] = "sp", + [FAR] = "far", + [SCR] = "scr", + [UNUSED] = "unused", + NULL +}; + +void +dumpregs(struct trapframe *fp, int fd) +{ + int i; + + for (i = 0; i < NR_REGS; i++) + kprint(fd, "%s=0x%llx%c", regnames[i], fp->r[i], + (i > 0 && i % 3 == 0) ? '\n' : ' '); + if (i % 4 != 3) + kputc(fd, '\n'); +} + +static void +backtrace(struct trapframe *fp) +{ + void **bp; + + if (!in_backtrace) + return; + kprint(kerr, "backtrace:\n"); + kprint(kerr, "%0llx\n", fp->r[X30]); + for (bp = (void **) fp->r[X29]; *bp; bp = (void **) *bp) + kprint(kerr, "%p\n", bp[1]); +} + +static void +dumpstack(struct trapframe *fp) +{ + long long *sp, i; + + if (!in_dumpstack) + return; + kprint(kerr, "stack dump:\n"); + sp = (long long *)fp->r[SP]; + for (i = 1; i <= 16; i++) + kprint(kerr, "%0llx%c", *sp++, (i % 4 == 0) ? '\n' : ' '); +} + +static void +panicfmt(const char *msg, struct trapframe *fp) +{ + /* + * check against 1 to be more robust + * against memory corruptions + */ + if (in_panic == 1) { + for (;;) + ; + } + + in_panic = 1; + kprint(kerr, "panic: %s\n", msg); + + dumpregs(fp, kerr); + backtrace(fp); + dumpstack(fp); +} + +void +halt(void) +{ + if (in_debug) + longjmp(dbgrecover, 1); + dohalt(); +} + +void +panic(const char *msg) +{ + if (in_debug) { + kprint(kerr, "panic: %s\n", msg); + longjmp(dbgrecover, 1); + } + + errstr = msg; + dopanic(); +} + +void +swtch(struct trapframe *fp) +{ + if (in_debug) + longjmp(dbgrecover, 1); + doswtch(fp); +} + +void +trap(struct trapframe *fp) +{ + Rmucmd cmd; + enum ecvals ec; + const char *msg; + + if (errstr) { + panicfmt(errstr, fp); + halt(); + } + dbg(kerr, "exception handler\n"); + + ec = (fp->r[ESR] >> 26) & 0x3f; + + if (ec != RMC) { + msg = (ec < NR_EC_VALS) ? ecstr[ec] : "unknown reason"; + panicfmt(msg, fp); + halt(); + } + + cmd.class = fp->r[ESR] & 0xff; + cmd.func = (fp->r[ESR] >> 8) & 0xff; + framep = cmd.fp = fp; + rmucmd = &cmd; + + rmc(&cmd); + swtch(fp); +} + +void +badcmd(int error) +{ + Rmucmd *cmd = rmucmd; + + dbg(kerr, "bad RMC: %d, %d = %d\n", cmd->class, cmd->func, error); + framep->r[X0] = error; + swtch(framep); +} + +void +rmc(Rmucmd *cmd) +{ + cmd->fp->r[X0] = -1; +} diff --git a/src/romfw/dlang.c b/src/romfw/dlang.c @@ -1,437 +0,0 @@ -#include <ctype.h> -#include <errno.h> -#include <setjmp.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <libk.h> -#include <rcode/rcode.h> -#include <rcode/romfw.h> - -#include "ec.h" -#include "dlang.h" - -#define PREFIX "> " -#define NR_ARGC_MAX 5 - -unsigned in_debug; -jmp_buf dbgrecover; - -struct args { - char *argv[NR_ARGC_MAX]; - int argc; - int status; -}; - -struct cmd { - char *name; - char *helpmsg; - int (*eval)(const struct cmd *cmd, struct args *args); - unsigned char min; - unsigned char max; -}; - -static const struct cmd cmds[]; - -static void -error(char *fmt, ...) -{ - va_list va; - - va_start(va, fmt); - kputs(kerr, PREFIX "ERR "); - kvprint(kerr, fmt, va); - kputc(kerr, '\n'); - longjmp(dbgrecover, 1); -} - -static void -ready(void) -{ - kputs(kout, PREFIX "READY\n"); -} - -/* Read a value in a given base between 2 and 16 0 means default base; - * 10, unless the string begins with "0x" or "0b" - */ -static unsigned long long -estrtoull(char *str, int base) -{ - unsigned long long val; - char *endptr; - - errno = 0; - val = strtoull(str, &endptr, base); - if (*str == '\0' || *endptr != '\0') - error("estrtoull: %s: not an integer", str); - if (errno) - error("estrtoull: %s: %s", strerror(errno)); - return val; -} - -/* Get reg struct for named reg */ -static unsigned long long * -get_named_reg(char *name, struct trapframe *fp) -{ - int i; - - for (i = 0; i < NR_REGS; i++) - if (strcmp(name, regnames[i]) == 0) - return &fp->r[i]; - return NULL; -} - -/* Get cmd struct for named cmd */ -static const struct cmd * -get_cmd(char *name) -{ - const struct cmd *cmd; - - for (cmd = cmds; cmd->name; cmd++) { - if (strcmp(cmd->name, name) == 0) - return cmd; - } - return NULL; -} - -static int -do_set(const struct cmd *cmd, struct args *args) -{ - unsigned long long *reg = NULL; - unsigned long long setval = 0; - - reg = get_named_reg(args->argv[1], framep); - if (reg == NULL) - error("set: %s: not found", args->argv[1]); - - setval = estrtoull(args->argv[2], 0); - *reg = setval; - return 0; -} - -static int -do_get(const struct cmd *cmd, struct args *args) -{ - unsigned long long *reg = NULL; - - reg = get_named_reg(args->argv[1], framep); - if (reg == NULL) - error("get: %s: not found", args->argv[1]); - - kprint(kout, "%llx\n", *reg); - return 0; -} - -static int -do_dump(const struct cmd *cmd, struct args *args) -{ - dumpregs(framep, kout); - return 0; -} - -static int -do_trap(const struct cmd *cmd, struct args *args) -{ - trap(framep); - return 0; -} - -static int -do_rmc(const struct cmd *cmd, struct args *args) -{ - unsigned char class; - unsigned char func; - - class = estrtoull(args->argv[1], 0); - func = estrtoull(args->argv[2], 0); - - framep->r[ESR] = (unsigned long long) RMC << 26; - framep->r[ESR] |= class; - framep->r[ESR] |= (func << 8); - trap(framep); - return 0; -} - -static int -do_exit(const struct cmd *cmd, struct args *args) -{ - args->status = 0; - if (args->argc == 2) - args->status = estrtoull(args->argv[1], 0); - return -1; -} - -static int -do_help(const struct cmd *cmd, struct args *args) -{ - for (cmd = cmds; cmd->name; cmd++) { - char *s = cmd->helpmsg; - kprint(kout, "%s\n", s); - } - return 0; -} - -static int -do_cat(const struct cmd *cmd, struct args *args) -{ - int fd, n; - char buf[100]; - - if ((fd = open(args->argv[1], O_READ)) < 0) - goto err; - - while ((n = read(fd, buf, sizeof(buf))) > 0) - write(kin, buf, n); - - if (close(fd) < 0 || n < 0) - goto err; - - return 0; - -err: - kerror(PREFIX "ERR cat"); - return 0; -} - -static int -do_ls(const struct cmd *cmd, struct args *args) -{ - int n; - DIR *dir; - struct dirent d; - - if ((dir = opendir(args->argv[1])) == NULL) - goto err; - - while ((n = readdir(dir, &d)) > 0) - kprint(kout, "%s\n", d.d_name); - - if (closedir(dir) < 0 || n < 0) - goto err; - - return 0; - -err: - kerror(PREFIX "ERR ls"); - return 0; -} - -static int -do_echo(const struct cmd *cmd, struct args *args) -{ - int fd, i, len, offset, n; - char *s, buffer[LINELEN]; - - if ((fd = open(args->argv[1], O_WRITE)) < 0) - goto err; - - offset = 0; - for (i = 2; i < args->argc; i++) { - s = args->argv[i]; - len = strlen(s); - if (len + offset >= LINELEN-2) - error("line too long"); - memcpy(buffer + offset, s, len); - offset += len; - buffer[offset++] = ' '; - } - buffer[offset] = '\n'; - n = write(fd, buffer, offset); - - if (close(fd) < 0 || n < 0) - goto err; - - return 0; -err: - kerror(PREFIX "ERR echo"); - return 0; -} - -static int -do_stat(const struct cmd *cmd, struct args *args) -{ - Dir dir; - - if (dirstat(args->argv[1], &dir) < 0) - goto err; - kprint(kout, - "name: %s\n" - "length: %ld\n" - "mode: %x\n" - "type: %d\n" - "dev: %d\n" - "qid: %x\n", - dir.name, - dir.length, - dir.mode, - dir.type, - dir.dev, - dir.qid - ); - - return 0; - -err: - kerror(PREFIX "ERR stat"); - return 0; -} - -static const struct cmd * -parse_cmd(char *buf, struct args *args) -{ - char *p; - const struct cmd *cmd; - const static char ws[] = " \t\r"; - - args->argc = 0; - for (p = strtok(buf, ws); p; p = strtok(NULL, ws)) { - if (args->argc == NR_ARGC_MAX) - error("too many parameters"); - args->argv[args->argc++] = p; - } - - if (args->argc == 0) - return NULL; - - if ((cmd = get_cmd(args->argv[0])) == NULL) - error("%s: not found", args->argv[0]); - - return cmd; -} - -static int -run(struct args *args) -{ - const struct cmd *cmd; - size_t len; - char buffer[LINELEN]; - - if (kgets(kin, buffer, sizeof(buffer)) == NULL) { - args->status = 1; - return -1; - } - - if ((len = strlen(buffer)) != 0) { - if (buffer[len-1] != '\n') - error("line too long"); - buffer[len-1] = '\0'; - cmd = parse_cmd(buffer, args); - if (cmd) { - int (*fn)(const struct cmd *, struct args *); - void *bp; - - if (args->argc < cmd->min || args->argc > cmd->max) - error(cmd->helpmsg); - bp = cmd->eval; - fn = (int (*)(const struct cmd *, struct args *)) bp; - return (*fn)(cmd, args); - } - } - - return 0; -} - -int -debug(void) -{ - struct args args; - - kprint(kout, "begin debug language interface\n"); - in_debug = 1; - setjmp(dbgrecover); - - for (ready(); !run(&args); ready()) - ; - kprint(kout, "end debug language interface\n"); - in_debug = 0; - - return args.status; -} - -/* - * definition of arrays - */ -static const struct cmd cmds[] = { - { - .name = "set", - .eval = do_set, - .min = 3, - .max = 3, - .helpmsg = "Set a register: set <reg> <value>", - }, - { - .name = "get", - .eval = do_get, - .min = 2, - .max = 2, - .helpmsg = "Get a register: get <reg>", - }, - { - .name = "dump", - .eval = do_dump, - .min = 1, - .max = 1, - .helpmsg = "Dump trapframe: dump", - }, - { - .name = "trap", - .eval = do_trap, - .min = 1, - .max = 1, - .helpmsg = "Call trap handler: trap", - }, - { - .name = "rmc", - .eval = do_rmc, - .min = 3, - .max = 3, - .helpmsg = "Call RMC handler: rmc imm1 imm2", - }, - { - .name = "exit", - .eval = do_exit, - .min = 1, - .max = 2, - .helpmsg = "Exit debug environment: exit [status]", - }, - { - .name = "help", - .eval = do_help, - .min = 1, - .max = 1, - .helpmsg = "Print this help menu: help", - }, - { - .name = "ls", - .eval = do_ls, - .min = 2, - .max = 2, - .helpmsg = "list content of a directory: ls path", - }, - { - .name = "cat", - .eval = do_cat, - .min = 2, - .max = 2, - .helpmsg = "read content from a file: cat path", - }, - { - .name = "echo", - .eval = do_echo, - .min = 3, - .max = NR_ARGC_MAX, - .helpmsg = "write content to a file: echo path string ...", - }, - { - .name = "stat", - .eval = do_stat, - .min = 2, - .max = 2, - .helpmsg = "display stat attribute: stat path", - }, - { - .name = NULL - } -}; diff --git a/src/romfw/mkrmu b/src/romfw/mkrmu @@ -1,38 +0,0 @@ -#!/bin/sh - -set -e - -trap 'r=$?; rm -f $$.tmp; exit $r' EXIT HUP INT QUIT TERM - -for i -do - case $1 in - -o) - out=$2 - shift 2 - ;; - --) - break - ;; - -*) - echo usage: gendlang.sh -o out [file ...] - exit 1 - ;; - esac -done - -out=${out-dlang.h} - -cat $@ | -tr 'A-Z' 'a-z' | -sed 's/\./_/' | -cat <<EOF >$$.tmp && mv $$.tmp $out -#include <stddef.h> - -#include "dlang.h" - -const struct rmudesc rmudescs[] = { -$(awk 'NF == 4 {printf("\t{%d, %d, \"%s\"},\n", $1, $2, $3)}' "$@") - {0, 0, NULL} -}; -EOF diff --git a/src/romfw/rmc.c b/src/romfw/rmc.c @@ -1,233 +0,0 @@ -#include <setjmp.h> -#include <stdint.h> - -#include <libk.h> -#include <rcode/rmu.h> -#include <rcode/rcode.h> -#include <rcode/romfw.h> - -#include "ec.h" - -struct rmctab *rmctab; - -static unsigned in_panic; -static unsigned in_dumpstack; -static unsigned in_backtrace; -static struct rmucmd *rmucmd; -static char *errstr; - -const char *const regnames[] = { - [X0] = "x0", - [X1] = "x1", - [X2] = "x2", - [X3] = "x3", - [X4] = "x4", - [X5] = "x5", - [X6] = "x6", - [X7] = "x7", - [X8] = "x8", - [X9] = "x9", - [X10] = "x10", - [X11] = "x11", - [X12] = "x12", - [X13] = "x13", - [X14] = "x14", - [X15] = "x15", - [X16] = "x16", - [X17] = "x17", - [X18] = "x18", - [X19] = "x19", - [X20] = "x20", - [X21] = "x21", - [X22] = "x22", - [X23] = "x23", - [X24] = "x24", - [X25] = "x25", - [X26] = "x26", - [X27] = "x27", - [X28] = "x28", - [X29] = "x29", - [ELR] = "elr", - [X30] = "x30", - [SPSR] = "spsr", - [ESR] = "esr", - [SP] = "sp", - [FAR] = "far", - [SCR] = "scr", - [UNUSED] = "unused", - NULL -}; - -void -dumpregs(struct trapframe *fp, int fd) -{ - int i; - - for (i = 0; i < NR_REGS; i++) - kprint(fd, "%s=0x%llx%c", regnames[i], fp->r[i], - (i > 0 && i % 3 == 0) ? '\n' : ' '); - if (i % 4 != 3) - kputc(fd, '\n'); -} - -static void -backtrace(struct trapframe *fp) -{ - void **bp; - - if (!in_backtrace) - return; - kprint(kerr, "backtrace:\n"); - kprint(kerr, "%0llx\n", fp->r[X30]); - for (bp = (void **) fp->r[X29]; *bp; bp = (void **) *bp) - kprint(kerr, "%p\n", bp[1]); -} - -static void -dumpstack(struct trapframe *fp) -{ - long long *sp, i; - - if (!in_dumpstack) - return; - kprint(kerr, "stack dump:\n"); - sp = (long long *)fp->r[SP]; - for (i = 1; i <= 16; i++) - kprint(kerr, "%0llx%c", *sp++, (i % 4 == 0) ? '\n' : ' '); -} - -static void -panicfmt(const char *msg, struct trapframe *fp) -{ - /* - * check against 1 to be more robust - * against memory corruptions - */ - if (in_panic == 1) { - for (;;) - ; - } - - in_panic = 1; - kprint(kerr, "panic: %s\n", msg); - - dumpregs(fp, kerr); - backtrace(fp); - dumpstack(fp); -} - -void -halt(void) -{ - if (in_debug) - longjmp(dbgrecover, 1); - dohalt(); -} - -void -panic(const char *msg) -{ - if (in_debug) { - kprint(kerr, "panic: %s\n", msg); - longjmp(dbgrecover, 1); - } - - errstr = msg; - dopanic(); -} - -void -swtch(struct trapframe *fp) -{ - if (in_debug) - longjmp(dbgrecover, 1); - doswtch(fp); -} - -void -trap(struct trapframe *fp) -{ - Rmucmd cmd; - enum ecvals ec; - const char *msg; - - if (errstr) { - panicfmt(errstr, fp); - halt(); - } - dbg(kerr, "exception handler\n"); - - ec = (fp->r[ESR] >> 26) & 0x3f; - - if (ec != RMC) { - msg = (ec < NR_EC_VALS) ? ecstr[ec] : "unknown reason"; - panicfmt(msg, fp); - halt(); - } - - cmd.class = fp->r[ESR] & 0xff; - cmd.func = (fp->r[ESR] >> 8) & 0xff; - framep = cmd.fp = fp; - rmucmd = &cmd; - - rmc(&cmd); - swtch(fp); -} - -void -badcmd(int error) -{ - Rmucmd *cmd = rmucmd; - - dbg(kerr, "bad RMC: %d, %d = %d\n", cmd->class, cmd->func, error); - framep->r[X0] = error; - swtch(framep); -} - -/* - * The dispatcher cannot be implemented using a table - * because the rmu command number is composed by two - * immediates, class and func, which don't generate - * consecutive values. The approach is to use a sparse - * matrix, where we store all the function pointers - * consecutive and we create a row index table which - * the offset from the beginning of the handler table - * and number of entries in that table for that row. - * - * rowidx handler - * --------------- -------- - * | off = 0,cnt=1 | | fun0 | - * --------------- -------- - * class --> | off = 1,cnt=2 | ---> off + func --> | fun1 | - * --------------- -------- - * | off = 3,cnt=1 | | fun2 | - * --------------- -------- - * ... ... - */ -void -rmc(Rmucmd *cmd) -{ - struct rmctab *tab; - const struct rmcclass *class; - void (*fn)(Rmucmd *cmd); - void *bp; - unsigned off; - - if (cmd->class > 255 || cmd->func > 255) - panic("rmc1"); - - tab = rmctab; - class = &tab->class[cmd->class]; - if (cmd->func >= class->cnt) - badcmd(-1); /* TODO: put the correct code */ - - off = class->off + cmd->func; - if (off > 255) - panic("rmc2"); - - bp = tab->handler[off]; - fn = (void (*) (Rmucmd *)) bp; - (*fn)(cmd); - - cmd->fp->r[X0] = SUCCESS; -} diff --git a/target/hosted/Makefile b/target/hosted/Makefile @@ -6,23 +6,23 @@ CRT = $(LIBDIR)/crt.o ROMOBJS = arch.o \ lock.o \ - rom.o \ + kernel.o \ $(CRT) \ $(DRVDIR)/builtin.o \ - $(SRCDIR)/romfw/builtin.o \ + $(SRCDIR)/kernel/builtin.o \ -TARGET = $(BINDIR)/romfw.elf +TARGET = $(BINDIR)/kernel.elf all: $(TARGET) $(BINDIR)/blkfile $(DIRS): FORCE cd $@ && $(MAKE) -$(BINDIR)/romfw.elf: $(ROMOBJS) $(LIBDEP) +$(BINDIR)/kernel.elf: $(ROMOBJS) $(LIBDEP) $(LD) $(PROJ_LDFLAGS) $(ROMOBJS) $(PROJ_LDLIBS) -o $@ $(BINDIR)/blkfile: dd bs=512 count=2 if=/dev/zero of=$(BINDIR)/blkfile clean: - rm -f romtab.c $(BINDIR)/blkfile + rm -f $(BINDIR)/blkfile diff --git a/target/hosted/kernel.c b/target/hosted/kernel.c @@ -0,0 +1,93 @@ +#include <setjmp.h> +#include <stdlib.h> +#include <string.h> + +#include <libk.h> +#include <rcode/rcode.h> +#include <rcode/kernel.h> + +#include "hosted.h" + +static struct trapframe *frame(void); + +struct trapframe trapframe, *framep; +struct trapframe *(*getframe)(void) = frame; + +static struct trapframe * +frame(void) +{ + return framep; +} + +void * +alloc(size_t size) +{ + static int lock; + void *p; + + if (size == 0) { + lock = 1; + return NULL; + } + + if (lock) + panic("alloc"); + + if ((p = malloc(size)) == NULL) + panic("alloc"); + return p; +} + +static void +imach(void) +{ + if (setjmp(recover)) + exit(EXIT_FAILURE); + framep = &trapframe; +} + +static void +namespace(void) +{ + int fd; + static char setin[] = "addin /dev/uart0/raw\n"; + static char setout[] = "addout /dev/uart0/raw\n"; + + /* Standard input set to 0 */ + if ((kin = open("#c/raw", O_READ)) < 0) + panic("open:#c/raw read"); + + /* Standard output set to 1 */ + if ((kout = open("#c/raw", O_WRITE)) < 0) + panic("open:#c/raw write"); + + /* Standard error set to 2 */ + if ((kerr = open("#c/raw", O_WRITE)) < 0) + panic("open:#c/raw write"); + + if (bind("#t0", "/dev/uart0") < 0) + panic("bind:/dev/uart0"); + if (bind("#c", "/dev/cons") < 0) + panic("bind:/dev/cons"); + if (bind("#b", "/dev/blk") < 0) + panic("bind:/dev/blk"); + + if ((fd = open("/dev/cons/ctl", O_WRITE)) < 0) + panic("open:/dev/cons/ctl write"); + if (write(fd, setin, sizeof(setin)) < 0) + panic("write:setin"); + if (write(fd, setout, sizeof(setout)) < 0) + panic("write:setout"); + if (close(fd) < 0) + panic("close:/dev/cons/ctl"); +} + +int +main(int argc, char *argv[]) +{ + imach(); + idev(); + namespace(); + + return debug(); +} diff --git a/target/hosted/rom.c b/target/hosted/rom.c @@ -1,93 +0,0 @@ -#include <setjmp.h> -#include <stdlib.h> -#include <string.h> - -#include <libk.h> -#include <rcode/rcode.h> -#include <rcode/romfw.h> - -#include "hosted.h" - -static struct trapframe *frame(void); - -struct trapframe trapframe, *framep; -struct trapframe *(*getframe)(void) = frame; - -static struct trapframe * -frame(void) -{ - return framep; -} - -void * -alloc(size_t size) -{ - static int lock; - void *p; - - if (size == 0) { - lock = 1; - return NULL; - } - - if (lock) - panic("alloc"); - - if ((p = malloc(size)) == NULL) - panic("alloc"); - return p; -} - -static void -imach(void) -{ - if (setjmp(recover)) - exit(EXIT_FAILURE); - framep = &trapframe; -} - -static void -namespace(void) -{ - int fd; - static char setin[] = "addin /dev/uart0/raw\n"; - static char setout[] = "addout /dev/uart0/raw\n"; - - /* Standard input set to 0 */ - if ((kin = open("#c/raw", O_READ)) < 0) - panic("open:#c/raw read"); - - /* Standard output set to 1 */ - if ((kout = open("#c/raw", O_WRITE)) < 0) - panic("open:#c/raw write"); - - /* Standard error set to 2 */ - if ((kerr = open("#c/raw", O_WRITE)) < 0) - panic("open:#c/raw write"); - - if (bind("#t0", "/dev/uart0") < 0) - panic("bind:/dev/uart0"); - if (bind("#c", "/dev/cons") < 0) - panic("bind:/dev/cons"); - if (bind("#b", "/dev/blk") < 0) - panic("bind:/dev/blk"); - - if ((fd = open("/dev/cons/ctl", O_WRITE)) < 0) - panic("open:/dev/cons/ctl write"); - if (write(fd, setin, sizeof(setin)) < 0) - panic("write:setin"); - if (write(fd, setout, sizeof(setout)) < 0) - panic("write:setout"); - if (close(fd) < 0) - panic("close:/dev/cons/ctl"); -} - -int -main(int argc, char *argv[]) -{ - imach(); - idev(); - namespace(); - - return debug(); -} diff --git a/target/native/Makefile b/target/native/Makefile @@ -2,23 +2,21 @@ PROJECTDIR = ../.. include $(PROJECTDIR)/scripts/rules.mk -ROMOBJS = rom-crt.o \ - rom.o \ - arch.o \ - debug_lock.o \ - sysreg.o \ - romtab.o \ - $(DRVDIR)/builtin.o \ - $(SRCDIR)/romfw/builtin.o \ - cache.o \ - -TARGET = $(BINDIR)/romfw.bin +KERNELOBJS =\ + kernel-crt.o \ + kernel.o \ + arch.o \ + debug_lock.o \ + sysreg.o \ + $(DRVDIR)/builtin.o \ + $(SRCDIR)/romfw/builtin.o \ + cache.o \ + +TARGET = $(BINDIR)/kernel.bin all: $(TARGET) -rom-crt.o: crt.s - -rom.o: sysreg.h version.h +kernel.o.o: sysreg.h version.h cache.o: sysreg.h sysreg.h: sysreg.lst @@ -36,4 +34,3 @@ $(BINDIR)/romfw.elf: $(ROMOBJS) $(LIBDEP) clean: rm -f $(TARGET:.bin=.elf) rm -f sysreg.h sysreg.s version.h - rm -f romtab.c diff --git a/target/native/crt.s b/target/native/crt-kernel.s diff --git a/target/native/rom.c b/target/native/kernel.c diff --git a/target/native/rom-crt.s b/target/native/rom-crt.s @@ -1,2 +0,0 @@ - .file "rom-crt.s" - .include "crt.s"