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:
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"