From 2a107ad5b90a5218b5ff6c211e802d73c59383d7 Mon Sep 17 00:00:00 2001 From: Yann MAGNIN Date: Thu, 25 Aug 2022 08:43:15 +0200 Subject: [PATCH] VxKernel 0.6.0-21 : Add SDL2 support (fake board) (WIP) @add <> board/ | [sdl2] add fake board for the SDL2 wrapper | [sdl2] fake CPU atomic operation | [sdl2] fake hypervisor world-switch | [sdl2] fake kernel init | [sdl2] use a modified Linux linker script for adding our Vhex special sections <> src/driver/mpu/x86/sdl2 | add fake window driver (simple wrapper around SDL2 surface) @update <> vxsdk.toml | move board specification to the user project | remove the SH compiler dependency @fix <> board/ | [fxcg50] move all "flags-specific" of the board in the board description file <> src/display | [common] support 64-bits API! <> src/hypervisor | [table] fix world initialization <> src/timer | [profiling] init default structure --- Makefile | 6 +- board/fxcg50/board.toml | 8 +- board/sdl2/board.toml | 19 ++ board/sdl2/cpu_atomic.c | 12 ++ board/sdl2/hypervisor.c | 22 +++ board/sdl2/initialize.c | 19 ++ board/sdl2/sdl2.ld | 267 +++++++++++++++++++++++++++ include/vhex/display/font/render.h | 2 +- include/vhex/display/shader.h | 6 +- include/vhex/display/stack.h | 8 +- include/vhex/driver.h | 4 +- include/vhex/module.h | 4 +- src/display/dclear.c | 4 +- src/display/draw/dcircle.c | 2 +- src/display/draw/dline.c | 6 +- src/display/draw/dpixel.c | 2 +- src/display/draw/drect.c | 2 +- src/display/dstack.c | 4 +- src/display/font/render/dfont_char.c | 7 +- src/display/image/render/dimage.c | 2 +- src/display/image/render/dsubimage.c | 4 +- src/display/image/shader/shadow.c | 6 +- src/display/text/render/dtext.c | 6 +- src/driver/mpu/x86/sdl2/window.c | 139 ++++++++++++++ src/hypervisor/table.c | 12 +- src/kernel.c | 1 - src/timer/profiling.c | 3 + vxsdk.toml | 6 +- 28 files changed, 532 insertions(+), 51 deletions(-) create mode 100644 board/sdl2/board.toml create mode 100644 board/sdl2/cpu_atomic.c create mode 100644 board/sdl2/hypervisor.c create mode 100644 board/sdl2/initialize.c create mode 100644 board/sdl2/sdl2.ld create mode 100644 src/driver/mpu/x86/sdl2/window.c diff --git a/Makefile b/Makefile index d1e5908..a2eab22 100644 --- a/Makefile +++ b/Makefile @@ -166,8 +166,6 @@ t-$1-$2-ld := $$(CONFIG.$1.TOOLCHAIN.PREFIX)ld t-$1-$2-gcc := $$(CONFIG.$1.TOOLCHAIN.PREFIX)gcc t-$1-$2-ldflags := $$(CONFIG.$1.TOOLCHAIN.LDFLAGS) t-$1-$2-cflags := $$(CONFIG.$1.TOOLCHAIN.CFLAGS) -t-$1-$2-cflags += -fpic -ffreestanding -nostdlib -fstrict-volatile-bitfields -O1 -t-$1-$2-cflags += -Wa,--dsp # generate compiler information (used to find some library like libgcc.a) t-$1-$2-gcc-base := $$(shell $$(CONFIG.$1.TOOLCHAIN.PREFIX)gcc --print-search-dirs | grep install | sed 's/install: //') @@ -223,11 +221,11 @@ t-$1-$2-asset := $(patsubst \ $(VXSDK_ASSETS_BUILD)/$1/$2/%.o: $(VXSDK_ASSETS_SRC)/% ifeq ($(CONFIG.VERBOSE),true) @ mkdir -p $$(dir $$@) - sh-elf-vhex-gcc $$(t-$1-$2-cflags) -o $$@ -c $$< + $$(CONFIG.$1.TOOLCHAIN.PREFIX)gcc $$(t-$1-$2-cflags) -o $$@ -c $$< else @ mkdir -p $$(dir $$@) @ printf "$(green)>$(nocolor) $(white)$@$(nocolor)\n" - @ sh-elf-vhex-gcc $$(t-$1-$2-cflags) -o $$@ -c $$< + @ $$(CONFIG.$1.TOOLCHAIN.PREFIX)gcc $$(t-$1-$2-cflags) -o $$@ -c $$< endif # generate the "main" rule for this lib diff --git a/board/fxcg50/board.toml b/board/fxcg50/board.toml index a266f66..a4b62dd 100644 --- a/board/fxcg50/board.toml +++ b/board/fxcg50/board.toml @@ -24,7 +24,13 @@ prefix = 'sh-elf-vhex-' cflags = [ '-DFXCG50', '-m4-nofpu', - '-mb' + '-mb', + '-ffreestanding', + '-nostdlib', + '-fPIE', + '-O1', + '-fstrict-volatile-bitfields', + '-Wa,--dsp' ] libs = [ '-lc', diff --git a/board/sdl2/board.toml b/board/sdl2/board.toml new file mode 100644 index 0000000..51eced5 --- /dev/null +++ b/board/sdl2/board.toml @@ -0,0 +1,19 @@ +[meta] +description = "Fake board for the DSL support" +author = 'Yann MAGNIN' + +[config] +modules = [ + 'display', + 'hypervisor', + 'timer' +] + +[drivers] +mpu = 'sdl2' + +[toolchain] +prefix = '' +cflags = [ + '-g3' +] diff --git a/board/sdl2/cpu_atomic.c b/board/sdl2/cpu_atomic.c new file mode 100644 index 0000000..db0b7c1 --- /dev/null +++ b/board/sdl2/cpu_atomic.c @@ -0,0 +1,12 @@ +void cpu_atomic_start(void) +{ + // Nothing to do, this is a fake driver + ; +} + +/* cpu_atomic_end(): Exit atomic mode */ +void cpu_atomic_end(void) +{ + // Nothing to do, this is a fake driver + ; +} diff --git a/board/sdl2/hypervisor.c b/board/sdl2/hypervisor.c new file mode 100644 index 0000000..903b640 --- /dev/null +++ b/board/sdl2/hypervisor.c @@ -0,0 +1,22 @@ +#include + +/* hypervisor_init() : initialize the hypervisor module */ +void hypervisor_init(void) +{ + hyp_world_t fake = hypervisor_world_new("fake"); + hyp_world_t vhex = hypervisor_world_new("vhex"); + + hypervisor_world_switch(fake, vhex); +} + +/* hypervisor_quit() : quit the hypervisor module */ +void hypervisor_quit(void) +{ + hyp_world_t fake = hypervisor_world_find("fake"); + hyp_world_t vhex = hypervisor_world_find("vhex"); + + hypervisor_world_switch(vhex, fake); + + hypervisor_world_delete(fake); + hypervisor_world_delete(vhex); +} diff --git a/board/sdl2/initialize.c b/board/sdl2/initialize.c new file mode 100644 index 0000000..c9235eb --- /dev/null +++ b/board/sdl2/initialize.c @@ -0,0 +1,19 @@ +#include +#include + +#include + +extern void kinit(void); + +__attribute__((constructor)) +int _initialize(void) +{ + printf("early kernel initialisation..."); + + /* initialize drivers and modules */ + kinit(); + + printf("OK\n"); + + return 0; +} diff --git a/board/sdl2/sdl2.ld b/board/sdl2/sdl2.ld new file mode 100644 index 0000000..335654c --- /dev/null +++ b/board/sdl2/sdl2.ld @@ -0,0 +1,267 @@ +/* Script for -pie -z combreloc -z separate-code */ +/* Copyright (C) 2014-2022 Free Software Foundation, Inc. + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) +ENTRY(_start) + +SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64"); +SEARCH_DIR("/usr/lib"); +SEARCH_DIR("/usr/local/lib"); +SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib"); + +SECTIONS +{ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0)); + . = SEGMENT_START("text-segment", 0) + SIZEOF_HEADERS; + + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*) + *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*) + *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*) + *(.rela.ifunc) + } + .rela.plt : + { + *(.rela.plt) + *(.rela.iplt) + } + .relr.dyn : { *(.relr.dyn) } + . = ALIGN(CONSTANT (MAXPAGESIZE)); + .init : + { + KEEP (*(SORT_NONE(.init))) + } + .plt : { *(.plt) *(.iplt) } +.plt.got : { *(.plt.got) } +.plt.sec : { *(.plt.sec) } + .text : + { + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(SORT(.text.sorted.*)) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf.em. */ + *(.gnu.warning) + } + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + . = ALIGN(CONSTANT (MAXPAGESIZE)); + /* Adjust the address for the rodata segment. We want to adjust up to + the same address within the page on the next page up. */ + . = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1))); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : + { + PROVIDE_HIDDEN (__tdata_start = .); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + .data : + { + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + + /* Exposed driver interfaces (.vhex.drivers) + The driver information is required to start and configure the + driver, even if the symbols are not referenced */ + .vhex.drivers : SUBALIGN(8) { + PROVIDE( vhex_drivers_start = . ); + KEEP( *(SORT_BY_NAME(.vhex.drivers.*)) ); + PROVIDE( vhex_drivers_end = . ); + } + + /* Exposed module interfaces (.vhex.modules) */ + .vhex.modules : SUBALIGN(8) { + PROVIDE( vhex_modules_start = . ); + KEEP( *(SORT_BY_NAME(.vhex.modules.*)) ); + PROVIDE( vhex_modules_end = . ); + } + + .data1 : { *(.data1) } + _edata = .; PROVIDE (edata = .); + . = .; + __bss_start = .; + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we do not + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + } + .lbss : + { + *(.dynlbss) + *(.lbss .lbss.* .gnu.linkonce.lb.*) + *(LARGE_COMMON) + } + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + .lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : + { + *(.lrodata .lrodata.* .gnu.linkonce.lr.*) + } + .ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : + { + *(.ldata .ldata.* .gnu.linkonce.l.*) + . = ALIGN(. != 0 ? 64 / 8 : 1); + } + . = ALIGN(64 / 8); + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1. */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions. */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2. */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2. */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions. */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3. */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF 5. */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} diff --git a/include/vhex/display/font/render.h b/include/vhex/display/font/render.h index fe5851a..df40c0e 100644 --- a/include/vhex/display/font/render.h +++ b/include/vhex/display/font/render.h @@ -17,7 +17,7 @@ extern void dfont_char(uint32_t n, int x, int y, int fg, int bg); extern void dfont_char_render( dsurface_t *surface, int glyph_idx, - uint32_t *arg + uintptr_t *arg ); #endif /* __VHEX_DISPLAY_FONT_RENDER__ */ diff --git a/include/vhex/display/shader.h b/include/vhex/display/shader.h index c549f2e..d0eb882 100644 --- a/include/vhex/display/shader.h +++ b/include/vhex/display/shader.h @@ -7,10 +7,10 @@ struct dshader_call { void (*routine)( dsurface_t *surface, - uint32_t *draw_args, - uint32_t *shader_args + uintptr_t *draw_args, + uintptr_t *shader_args ); - uint32_t args[8]; + uintptr_t args[8]; }; typedef struct dshader_call dshader_call_t; diff --git a/include/vhex/display/stack.h b/include/vhex/display/stack.h index 623aade..73309de 100644 --- a/include/vhex/display/stack.h +++ b/include/vhex/display/stack.h @@ -7,8 +7,8 @@ /* dstack_call - dstack indirect call (same as dshader) */ struct dstack_call { - void (*routine)(dsurface_t *surface, uint32_t *draw_args); - uint32_t args[12]; + void (*routine)(dsurface_t *surface, uintptr_t *draw_args); + uintptr_t args[12]; }; typedef struct dstack_call dstack_call_t; @@ -20,7 +20,7 @@ struct dstack_action { int number; int idx; } shader; - void (*quit)(uint32_t *arg); + void (*quit)(uintptr_t *arg); }; /* DSTACK_CALL - display indirect call */ @@ -41,7 +41,7 @@ extern int dstack_init(void); extern did_t dstack_add_action( dstack_call_t *call, dshader_call_t *shaders, - void (*quit)(uint32_t *args) + void (*quit)(uintptr_t *args) ); /* dstack_add_shader() : add shader on particular action */ diff --git a/include/vhex/driver.h b/include/vhex/driver.h index 1bf964c..4b5cb40 100644 --- a/include/vhex/driver.h +++ b/include/vhex/driver.h @@ -90,8 +90,8 @@ struct vhex_driver /* Number of drivers in the (vhex_drivers) array */ #define vhex_driver_count() \ - ((struct vhex_driver *)&vhex_drivers_end \ - - (struct vhex_driver *)&vhex_drivers_start) + ((struct vhex_driver *)&vhex_drivers_end - \ + (struct vhex_driver *)&vhex_drivers_start) /* driver table */ #define vhex_driver_table() \ diff --git a/include/vhex/module.h b/include/vhex/module.h index 5d27639..e1f0d3d 100644 --- a/include/vhex/module.h +++ b/include/vhex/module.h @@ -27,8 +27,8 @@ struct vhex_module /* Number of modules in the (vhex_modules) array */ #define vhex_module_count() \ - ((struct vhex_module *)&vhex_modules_end \ - - (struct vhex_module *)&vhex_modules_start) + ((struct vhex_module *)&vhex_modules_end - \ + (struct vhex_module *)&vhex_modules_start) /* driver table */ #define vhex_module_table() \ diff --git a/src/display/dclear.c b/src/display/dclear.c index 4da2575..8d35ea1 100644 --- a/src/display/dclear.c +++ b/src/display/dclear.c @@ -27,9 +27,9 @@ void dclear_render(dsurface_t *surface, uint32_t color) //--- /* dclear_dstack() : dstack rwrapper primitive */ -void dclear_dstack(dsurface_t *surface, uint32_t *arg) +void dclear_dstack(dsurface_t *surface, uintptr_t *arg) { - dclear_render(surface, arg[0]); + dclear_render(surface, (uint32_t)arg[0]); } //--- diff --git a/src/display/draw/dcircle.c b/src/display/draw/dcircle.c index 7388b18..2b72ba7 100644 --- a/src/display/draw/dcircle.c +++ b/src/display/draw/dcircle.c @@ -45,7 +45,7 @@ void dcircle_filled_render( //--- /* dcircle_filled_dstack() : dstack wrapper primitive */ -void dcircle_filled_dstack(dsurface_t *surface, uint32_t *args) +void dcircle_filled_dstack(dsurface_t *surface, uintptr_t *args) { dcircle_filled_render( surface, diff --git a/src/display/draw/dline.c b/src/display/draw/dline.c index b278b8f..45f6b5e 100644 --- a/src/display/draw/dline.c +++ b/src/display/draw/dline.c @@ -139,7 +139,7 @@ void dvline_render(dsurface_t *surface, int x, int y1, int y2, int color) //--- /* dline_dstack() : dstack wrapper line primitive */ -void dline_dstack(dsurface_t *surface, uint32_t *args) +void dline_dstack(dsurface_t *surface, uintptr_t *args) { dline_render( surface, @@ -152,7 +152,7 @@ void dline_dstack(dsurface_t *surface, uint32_t *args) } /* dhline_dstack() : dstack wrapper horizontal line primitive */ -void dhline_dstack(dsurface_t *surface, uint32_t *args) +void dhline_dstack(dsurface_t *surface, uintptr_t *args) { dhline_render( surface, @@ -164,7 +164,7 @@ void dhline_dstack(dsurface_t *surface, uint32_t *args) } /* dvline_dstack() : dstack wrapper vertical line primitive */ -void dvline_dstack(dsurface_t *surface, uint32_t *args) +void dvline_dstack(dsurface_t *surface, uintptr_t *args) { dvline_render( surface, diff --git a/src/display/draw/dpixel.c b/src/display/draw/dpixel.c index c673ff2..9c61f5e 100644 --- a/src/display/draw/dpixel.c +++ b/src/display/draw/dpixel.c @@ -39,7 +39,7 @@ void dpixel_render(dsurface_t *surface, int x, int y, int color) //--- /* dpixel_render_dstack() : dstack-API compatible render */ -void dpixel_dstack(dsurface_t *surface, uint32_t *arg) +void dpixel_dstack(dsurface_t *surface, uintptr_t *arg) { dpixel_render(surface, arg[0], arg[1], arg[2]); } diff --git a/src/display/draw/drect.c b/src/display/draw/drect.c index d0d540a..c44fcef 100644 --- a/src/display/draw/drect.c +++ b/src/display/draw/drect.c @@ -23,7 +23,7 @@ void drect_filled_render( //--- /* drect_filled_dstack() : dstack API wrapper */ -static void drect_filled_dstack(dsurface_t *surface, uint32_t *args) +static void drect_filled_dstack(dsurface_t *surface, uintptr_t *args) { drect_filled_render( surface, diff --git a/src/display/dstack.c b/src/display/dstack.c index 28c0075..14b5085 100644 --- a/src/display/dstack.c +++ b/src/display/dstack.c @@ -105,7 +105,7 @@ static void dstack_action_add_shader( static did_t dstack_action_alloc( dstack_call_t *call, dshader_call_t *shader, - void (*quit)(uint32_t *arg) + void (*quit)(uintptr_t *arg) ) { struct dstack_action *action; int i; @@ -147,7 +147,7 @@ struct dstack_action *dstack_action_get(did_t did) did_t dstack_add_action( dstack_call_t *call, dshader_call_t *shader, - void (*quit)(uint32_t *arg) + void (*quit)(uintptr_t *arg) ) { return dstack_action_alloc(call, shader, quit); } diff --git a/src/display/font/render/dfont_char.c b/src/display/font/render/dfont_char.c index 5c2ac79..4db0123 100644 --- a/src/display/font/render/dfont_char.c +++ b/src/display/font/render/dfont_char.c @@ -11,7 +11,7 @@ void dfont_char_render( dsurface_t *surface, int glyph_idx, - uint32_t *arg + uintptr_t *arg ) { uint32_t glyph_bitmap; uint32_t glyph_shift; @@ -26,6 +26,7 @@ void dfont_char_render( x = arg[0]; y = arg[1]; + /* generate font index / shift information */ font = dfont_get(); if (font->shape.prop == 1) { @@ -78,10 +79,10 @@ void dfont_char_render( //--- /* dfont_char_dstack() : dstack wrapper */ -void dfont_char_dstack(dsurface_t *surface, uint32_t *arg) +void dfont_char_dstack(dsurface_t *surface, uintptr_t *arg) { font_t *font = dfont_get(); - uint32_t buff[6] = { + uintptr_t buff[6] = { arg[1], arg[2], 0, 0, arg[3], arg[4] }; diff --git a/src/display/image/render/dimage.c b/src/display/image/render/dimage.c index b90d2ea..63d4e64 100644 --- a/src/display/image/render/dimage.c +++ b/src/display/image/render/dimage.c @@ -19,7 +19,7 @@ void dimage_render(dsurface_t *surface, image_t const *img, int x, int y) /* dimage(): Render a full image */ did_t dimage(image_t const *image, int x, int y, int mode) { - extern void dsubimage_dstack(dsurface_t *surface, uint32_t *args); + extern void dsubimage_dstack(dsurface_t *surface, uintptr_t *args); if (mode & DIMAGE_CENTER) { x -= image->width >> 1; } if (mode & DIMAGE_RIGHT) { x -= image->width; } diff --git a/src/display/image/render/dsubimage.c b/src/display/image/render/dsubimage.c index 61df626..ef0099a 100644 --- a/src/display/image/render/dsubimage.c +++ b/src/display/image/render/dsubimage.c @@ -210,11 +210,11 @@ void dsubimage_render( //--- /* dsubimage_dstack(): dstack wrapper primitive */ -void dsubimage_dstack(dsurface_t *surface, uint32_t *args) +void dsubimage_dstack(dsurface_t *surface, uintptr_t *args) { dsubimage_render( surface, - (image_t*)(uintptr_t)args[0], + (image_t*)args[0], (int)args[1], (int)args[2], (int)args[3], diff --git a/src/display/image/shader/shadow.c b/src/display/image/shader/shadow.c index 6e394d7..d6a87b4 100644 --- a/src/display/image/shader/shadow.c +++ b/src/display/image/shader/shadow.c @@ -158,8 +158,8 @@ static void dimg_shadow_alpha_render( /* dimage_shader_shadow() : add shadows in any image rendered */ static void dimage_shader_shadow_dstack( dsurface_t *surface, - uint32_t *draw, - uint32_t *shader + uintptr_t *draw, + uintptr_t *shader ) { struct imgbox imgbox; image_t *image; @@ -167,7 +167,7 @@ static void dimage_shader_shadow_dstack( int yoff; int ret; - image = (image_t*)(uintptr_t)draw[0]; + image = (image_t*)draw[0]; xoff = (int)shader[0]; yoff = (int)shader[1]; diff --git a/src/display/text/render/dtext.c b/src/display/text/render/dtext.c index f1b7971..eb4781b 100644 --- a/src/display/text/render/dtext.c +++ b/src/display/text/render/dtext.c @@ -100,7 +100,7 @@ static char *dtext_info_register(char const * const str) //--- /* dfont_render() : draw caracter in surface */ -void dtext_dstack(dsurface_t *surface, uint32_t *arg) +void dtext_dstack(dsurface_t *surface, uintptr_t *arg) { uint32_t code_point; uint8_t const * str; @@ -122,7 +122,7 @@ void dtext_dstack(dsurface_t *surface, uint32_t *arg) sy = arg[1]; counter = -1; font = dfont_get(); - str = (void*)(uintptr_t)arg[6]; + str = (void*)arg[6]; while (++counter < (int)arg[7]) { code_point = dfont_utf8_next(&str); @@ -186,7 +186,7 @@ did_t dtext_opt( &dtext_dstack, x, y, x + width, y + height, fg, bg, - (uint32_t)(uintptr_t)real_str, size, + (uintptr_t)real_str, size, ), NULL, (dtext_info.pool.idx == 0) ? (void*)&__dtext_quit : NULL diff --git a/src/driver/mpu/x86/sdl2/window.c b/src/driver/mpu/x86/sdl2/window.c new file mode 100644 index 0000000..625d67c --- /dev/null +++ b/src/driver/mpu/x86/sdl2/window.c @@ -0,0 +1,139 @@ +#include +#include +#include +#include + +/* Literal error message printed to stderr, evaluates to 1 for a combined + return/exit() call */ +#define err(fmt, ...) ({ \ + fprintf(stderr, "error: " fmt "\n", ##__VA_ARGS__); \ + 1; \ +}) + +static SDL_Window *__sdl_window = NULL; + +__attribute__((destructor)) +void quit(void) +{ + if(__sdl_window != NULL) { + SDL_DestroyWindow(__sdl_window); + __sdl_window = NULL; + } +} + +//--- +// Driver primitives +//--- + +uint32_t vhex_vram[(396*224) / 2]; + +/* sdl_frame_start() - prepar the screen and reset surfaces */ +int sdl_frame_start(dsurface_t *surface) +{ + surface->vram = (void*)vhex_vram; + surface->width = 396; + surface->height = 224; + surface->x1 = 0; + surface->y1 = 0; + surface->x2 = 395; + surface->y2 = 223; + return (0); +} + +/* sdl_frame_frag_next() : update the next fragment */ +int sdl_frame_frag_next(dsurface_t *surface) +{ + (void)surface; + return -1; +} + +/* sdl_frame_frag_send() : send fragment to the screen */ +int sdl_frame_frag_send(dsurface_t *surface) +{ + + SDL_SetWindowSize(__sdl_window, 396, 224); + SDL_Surface *src = SDL_CreateRGBSurface( + 0, 396, 224, 24, + 0x000000ff, 0x0000ff00, 0x0000ff00, 0 + ); + + uint16_t *vram = surface->vram; + uint8_t *display = src->pixels; + for (int i = 0; i < 396 * 224; ++i){ + display[(i * 3) + 0] = (((vram[i] & 0xf800) >> 11) * 255) / 31; + display[(i * 3) + 1] = (((vram[i] & 0x07e0) >> 5) * 255) / 63; + display[(i * 3) + 2] = (((vram[i] & 0x001f) >> 0) * 255) / 31; + } + + SDL_Surface *dst = SDL_GetWindowSurface(__sdl_window); + SDL_BlitSurface(src, NULL, dst, NULL); + SDL_FreeSurface(src); + + SDL_UpdateWindowSurface(__sdl_window); + return 0; +} + +/* sdl_frame_end() : destructor */ +int sdl_frame_end(dsurface_t *surface) +{ + (void)surface; + return 0; +} + +//--- +// Driver context management +//--- + +static int __sdl_configure(void) +{ + if(!SDL_WasInit(SDL_INIT_VIDEO)) { + int rc = SDL_Init(SDL_INIT_VIDEO); + if(rc < 0) + return err("Cannot initialize SDL: %s\n", SDL_GetError()); + } + + __sdl_window = SDL_CreateWindow( + "vxKernel", + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + 396, + 224, + 0 + ); + return 0; +} + +static void __sdl_hsave(void) +{ + // Nothing to do, this is a fake driver + ; +} + +static void __sdl_hrestore(void) +{ + // Nothing to do, this is a fake driver + ; +} + + +struct vhex_driver drv_sdl = { + .name = "SDL", + .hsave = (void*)&__sdl_hsave, + .hrestore = (void*)&__sdl_hrestore, + .configure = (void*)&__sdl_configure, + .state_size = 4, + .flags = { + .DISPLAY = 1, + .SHARED = 0, + .UNUSED = 0, + }, + .module_data = &(struct dstack_drv_interface){ + .frame_start = &sdl_frame_start, + .frame_frag_next = &sdl_frame_frag_next, + .frame_frag_send = &sdl_frame_frag_send, + .frame_end = &sdl_frame_end, + .display_width = 396, + .display_height = 224 + } +}; +VHEX_DECLARE_DRIVER(16, drv_sdl); diff --git a/src/hypervisor/table.c b/src/hypervisor/table.c index 2dda775..24c4300 100644 --- a/src/hypervisor/table.c +++ b/src/hypervisor/table.c @@ -51,12 +51,12 @@ hyp_world_t hypervisor_world_new(char const * const restrict name) ); for (int i = id; i < hyp.world.number; ++i) { - hyp.world.table[i].driver = NULL; - hyp.world.table[i].name = NULL; - hyp.world.table[id].status.LOCKED = 0; - hyp.world.table[id].status.ACTIVE = 0; - hyp.world.table[id].status.INIT = 0; - hyp.world.table[id].status.USED = 0; + memset( + &hyp.world.table[i], + 0x00, + sizeof(struct vhex_world) + ); + hyp.world.table[i].status.USED = 0; } } diff --git a/src/kernel.c b/src/kernel.c index 3ad510b..1680f67 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,7 +1,6 @@ #include #include - //--- // Initialization and unloading //--- diff --git a/src/timer/profiling.c b/src/timer/profiling.c index dc6ef00..7f231a0 100644 --- a/src/timer/profiling.c +++ b/src/timer/profiling.c @@ -1,6 +1,8 @@ #include #include +#include + /* internal timer information */ extern struct { struct timer_drv_interface driver; @@ -13,6 +15,7 @@ extern struct { /* timer_prof_init(): Create a new context object */ int timer_prof_init(timer_prof_t *prof) { + memset(prof, 0x00, sizeof(timer_prof_t)); if (timer_info.driver.timer_prof_init != NULL) return (timer_info.driver.timer_prof_init(prof)); return (-1); diff --git a/vxsdk.toml b/vxsdk.toml index 6f2f36c..bd6c8e8 100644 --- a/vxsdk.toml +++ b/vxsdk.toml @@ -3,11 +3,7 @@ name = 'vxkernel' type = 'lib' [build] -configure = 'python3 ./configure --board=fxcg50' +configure = 'python3 ./configure' # the user need to specify the board!! build = 'make' install = 'make install' uninstall = 'make uninstall' - -[dependencies] -sh-elf-vhex = 'master' -