os-workshop

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

commit 727b47915b7d4d76ed69d6d8c8b13a232b3fb8b6
parent 23aced7b0db54cc9239d2bd0912903ab5cd6081b
Author: Brian Swetland <swetland@frotz.net>
Date:   Wed, 18 May 2022 22:18:08 -0700

xos: improved syscall plumbing, libxos, demo app

- xos/syscall-tmpl.h provides templates for syscalls
- used for user/kernel headers, library stubs, kernel glue
- add libxos for syscall stubs and helpers
- add xos-mandelbrot demo app

Diffstat:
Mproject/xos-kernel.app.mk | 3++-
Aproject/xos-mandelbrot.app.mk | 10++++++++++
Aproject/xos.lib.mk | 6++++++
Axos/inc/xos/syscall-tmpl.h | 8++++++++
Axos/inc/xos/syscalls.h | 10++++++++++
Axos/inc/xos/types.h | 13+++++++++++++
Axos/lib/debug-io.c | 27+++++++++++++++++++++++++++
Axos/lib/syscalls.S | 6++++++
Mxos/src/entry.S | 12++++++------
Mxos/src/kernel.c | 23+++++++++++++++++++----
Mxos/src/kernel.h | 8++++----
Axos/usr/mandelbrot.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 files changed, 203 insertions(+), 15 deletions(-)

diff --git a/project/xos-kernel.app.mk b/project/xos-kernel.app.mk @@ -6,6 +6,7 @@ MOD_SRC += hw/src/context-switch.S MOD_SRC += hw/src/debug-printf.c hw/src/debug-io.c hw/src/print-exception.c MOD_LIB := c MOD_INC := xos/inc -MOD_EXT := out/ex25-user.bin +MOD_EXT := out/xos-mandelbrot.bin MOD_LDSCRIPT := make/kernel.ram.ld +MOD_QEMU_FB := 1 include make/app.mk diff --git a/project/xos-mandelbrot.app.mk b/project/xos-mandelbrot.app.mk @@ -0,0 +1,10 @@ + +MOD_NAME := xos-mandelbrot +MOD_SRC := hw/src/start.S xos/user/mandelbrot.c +MOD_LIB := gfx xos c +MOD_LDSCRIPT := make/user.ram.ld + +# TODO: fix this +MOD_INC := xos/inc + +include make/app.mk diff --git a/project/xos.lib.mk b/project/xos.lib.mk @@ -0,0 +1,6 @@ + +MOD_NAME := xos +MOD_SRC := xos/lib/syscalls.S xos/lib/debug-io.c +MOD_INC := xos/inc +MOD_LIB := c +include make/lib.mk diff --git a/xos/inc/xos/syscall-tmpl.h b/xos/inc/xos/syscall-tmpl.h @@ -0,0 +1,8 @@ +// Copyright 2022, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0 + +__SYSCALL(0,void,exit,(int n)) +__SYSCALL(1,void,xputc,(unsigned ch)) +__SYSCALL(2,status_t,thread_create,(handle_t *out, void *entry, void *arg)) + +#define SYSCALL_COUNT 3 diff --git a/xos/inc/xos/syscalls.h b/xos/inc/xos/syscalls.h @@ -0,0 +1,10 @@ +// Copyright 2022, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0 + +#pragma once +#include <xos/status.h> +#include <xos/types.h> + +#define __SYSCALL(n,rtype,name,args) rtype name args; +#include <xos/syscall-tmpl.h> +#undef __SYSCALL diff --git a/xos/inc/xos/types.h b/xos/inc/xos/types.h @@ -0,0 +1,13 @@ +// Copyright 2022, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0 + +#pragma once + +#include <stdint.h> + +typedef uint32_t handle_t; +typedef uint32_t status_t; +typedef uint32_t paddr_t; +typedef uint32_t vaddr_t; + + diff --git a/xos/lib/debug-io.c b/xos/lib/debug-io.c @@ -0,0 +1,27 @@ +// Copyright 2022, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0. + +#include <stdio.h> +#include <stdarg.h> + +#include <hw/debug.h> + +void xputs(const char* s) { + while (*s != 0) { + xputc(*s++); + } +} + +int xgetc(void) { + return -1; +} + +void xprintf(const char* fmt, ...) { + char msg[128]; + va_list ap; + va_start(ap, fmt); + vsnprintf(msg, sizeof(msg), fmt, ap); + va_end(ap); + xputs(msg); +} + diff --git a/xos/lib/syscalls.S b/xos/lib/syscalls.S @@ -0,0 +1,6 @@ +// Copyright 2022, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0 + +#define __SYSCALL(n,rtype,name,args) .globl name; name:; addi t0, x0, n; ecall; ret + +#include <xos/syscall-tmpl.h> diff --git a/xos/src/entry.S b/xos/src/entry.S @@ -127,8 +127,13 @@ exception_entry: la ra, trap_exit j exception_handler +syscall_table: +#define __SYSCALL(n,rtype,name,args) .word sys_##name +#include <xos/syscall-tmpl.h> +syscall_table_end: + syscall_entry: - li t1, 2 // SYSCALL_COUNT + li t1, SYSCALL_COUNT bgeu t0, t1, illegal_syscall // fn = [syscall_table + (syscall_number << 2)] @@ -148,11 +153,6 @@ syscall_entry: j trap_exit -syscall_table: - .word sys_exit - .word sys_xputc -syscall_table_end: - illegal_syscall: addi t0, zero, XOS_ERR_BAD_SYSCALL sw t0, 0x20(sp) diff --git a/xos/src/kernel.c b/xos/src/kernel.c @@ -26,6 +26,17 @@ typedef struct { thread_t thread; } kstack_top_t; +#define FRAMEBUFFER_SIZE (640*480*2) + +void map_framebuffer(uint32_t* pgdir) { + paddr_t pa = FRAMEBUFFER_BASE; + vaddr_t va = 0x20000000; + for (unsigned n = 0; n < FRAMEBUFFER_SIZE; n += PAGE_SIZE) { + // TODO: remove the pa from the freelist + vm_map_4k(pgdir, va + n, pa + n, USER_RW); + } +} + void start_user_program(void) { vaddr_t user_start = 0x10000000; vaddr_t user_stack = 0x10400000; @@ -41,6 +52,8 @@ void start_user_program(void) { // allocate a 4KB (1 page) for user stack vm_map_4k(kpgdir, user_stack - 1*PAGE_SIZE, ppage_alloc_z(), USER_RW); + map_framebuffer(kpgdir); + // allow S-MODE writes to U-MODE pages csr_set(CSR_SSTATUS, SSTATUS_SUM); @@ -131,15 +144,17 @@ void start(void) { start_user_program(); } -status_t sys_xputc(uint32_t ch) { +status_t sys_thread_create(handle_t* out, void *entry, void *arg) { + return XOS_ERR_NOT_SUPPORTED; +} + +void sys_xputc(unsigned ch) { xputc(ch); - return XOS_OK; } -status_t sys_exit(int n) { +void sys_exit(int n) { xprintf("\n[ user exit (status %d) ]\n", n); for (;;) ; - return XOS_OK; } void interrupt_handler(void) { diff --git a/xos/src/kernel.h b/xos/src/kernel.h @@ -4,6 +4,7 @@ #pragma once #include <xos/status.h> +#include <xos/types.h> #include <hw/riscv.h> #include <hw/context.h> @@ -17,10 +18,6 @@ void panic(const char* msg); // vm.c -typedef uint32_t paddr_t; -typedef uint32_t vaddr_t; -typedef uint32_t status_t; - static inline void* pa_to_kva(paddr_t pa) { return (void*) (pa + (KVA_BASE - KPA_BASE)); } @@ -59,3 +56,6 @@ typedef struct { uint32_t reserved3; } thread_t; +// syscall entry points +#define __SYSCALL(n,rtype,name,args) rtype sys_##name args; +#include <xos/syscall-tmpl.h> diff --git a/xos/usr/mandelbrot.c b/xos/usr/mandelbrot.c @@ -0,0 +1,92 @@ +// Copyright 2022, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0 + +#include <xos/syscalls.h> +#include <hw/debug.h> +#include <gfx/gfx.h> +#include <string.h> + +uint16_t colors[12] = { + 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, + 0x7777, 0x8888, 0x9999, 0xAAAA, 0xBBBB, 0xCCCC, +}; + +int render(gfx_surface_t* _gs, + uint32_t px0, uint32_t py0, + uint32_t px1, uint32_t py1) { + gfx_surface_t gs; + memcpy(&gs, _gs, sizeof(gs)); + + for (int py = py0; py < py1; py++) { + int y0 = 650 - (1300 * py) / gs.height; + for (int px = px0; px < px1; px++) { + int x0 = -1250 + (1750 * px) / gs.width; + int x = 0, y = 0; + for (int i = 0; i < 500; i++) { + int x2 = x * x / 1000; + int y2 = y * y / 1000; + if ((x2 + y2) > 4000) { + gs.fgcolor = colors[(i > 11) ? 11 : i]; + gfx_plot(&gs, px, py); + goto done; + } + y = 2 * x * y / 1000 + y0; + x = x2 - y2 + x0; + } + gs.fgcolor = 0; + gfx_plot(&gs, px, py); + done: + ; + } + } + + return 2; +} + +#if 0 +int t1(void* arg) { + gfx_surface_t *gs = arg; + gfx_fill(gs, 0, 0, 320, 240, gfx_color(gs, C_WHITE)); + gfx_puts(gs, 0, 240-16, "Thread One"); + return render(gs, 0, 0, 320, 240); +} +int t2(void* arg) { + gfx_surface_t *gs = arg; + gfx_fill(gs, 320, 240, 640, 480, gfx_color(gs, C_GRAY75)); + gfx_puts(gs, 320, 480-16, "Thread Two"); + return render(gs, 320, 240, 640, 480); +} +int t3(void* arg) { + gfx_surface_t *gs = arg; + gfx_fill(gs, 320, 0, 640, 240, gfx_color(gs, C_GRAY25)); + gfx_puts(gs, 320, 240-16, "Thread Three"); + return render(gs, 320, 0, 640, 240); +} +int t4(void* arg) { + gfx_surface_t *gs = arg; + gfx_fill(gs, 0, 240, 320, 480, gfx_color(gs, C_GRAY50)); + gfx_puts(gs, 0, 480-16, "Thread Four"); + return render(gs, 0, 240, 320, 480); +} +#endif + +static gfx_surface_t screen; + +void start(void) { + xprintf("X/OS Example - Mandelbrot\n\n"); + + screen.width = 640; + screen.height = 480; + screen.stride = 640; + screen.pixels = (void*) 0x20000000; + screen.pixfmt = PIXFMT_RGB565; + screen.fgcolor = C_WHITE; + screen.bgcolor = C_BLUE; + gfx_init(&screen); + + gfx_clear(&screen, C_BLUE); + render(&screen, 0, 0, 640, 480); + + exit(0); +} +