From c923ad24b19e01ca012be07362d86b874a4f252e Mon Sep 17 00:00:00 2001 From: Yatis Date: Sat, 13 Mar 2021 17:59:03 +0100 Subject: [PATCH] @add * special fxcg50 dupdate_noint() which display the content of the VRM without using the DMA (usefull for debugging) @update * update the drivers interface to get some information about the current running drivers' context * remove the old cpu_setVBR() function @fix * fix cpu_setVBR() returned value * fix kquit() drivers restore atomic error --- include/gint/display-cg.h | 2 + include/gint/drivers.h | 15 ++++-- src/cpu/helpers.S | 53 ++----------------- src/kernel/drivers.c | 106 +++++++++++++++++++++++++++++--------- src/kernel/hypervisor.c | 24 +++++---- src/kernel/kernel.c | 7 ++- src/render-cg/dupdate.c | 6 +++ 7 files changed, 121 insertions(+), 92 deletions(-) diff --git a/include/gint/display-cg.h b/include/gint/display-cg.h index 6b5fbf2..320b7dc 100644 --- a/include/gint/display-cg.h +++ b/include/gint/display-cg.h @@ -122,6 +122,8 @@ void dsetvram(uint16_t *main, uint16_t *secondary); Returns the VRAM buffer addresses used to render on fx-CG 50. */ void dgetvram(uint16_t **main, uint16_t **secondary); +/* vdupdate_noint(): Push the VRAM to the display driver without DMA */ +extern void dupdate_noint(void); #endif /* FXCG50 */ #endif /* GINT_DISPLAY_CG */ diff --git a/include/gint/drivers.h b/include/gint/drivers.h index 8a61e4f..5c73e8a 100644 --- a/include/gint/drivers.h +++ b/include/gint/drivers.h @@ -123,8 +123,15 @@ typedef struct extern void *drivers_context_create(void); extern void drivers_context_destroy(void **buffctx); extern void drivers_wait(void); -extern void drivers_save_and_init(void *buffctx); -extern void drivers_save(void *buffctx); -extern void drivers_restore(void *buffctx); -extern void drivers_switch(void *currctx, void *nextctx); +extern void *drivers_switch(void *buffctx); +extern void *drivers_restore(void *buffctx); +extern int drivers_save_and_init(void *buffctx); +extern int drivers_save(void *buffctx); +extern int drivers_context_duplicate(void **dst, void *src); +extern void *drivers_init(void *buffctx); +extern void *drivers_get_current(void); + +// default world +extern void *kernel_env_casio; +extern void *kernel_env_gint; #endif /* GINT_DRIVERS */ diff --git a/src/cpu/helpers.S b/src/cpu/helpers.S index 0ab2854..cf138dd 100644 --- a/src/cpu/helpers.S +++ b/src/cpu/helpers.S @@ -2,6 +2,7 @@ ** gint:core:vbr - Assembler-level VBR management */ +.text .global _cpu_setCPUOPM .global _cpu_getCPUOPM .global _cpu_getSR @@ -10,51 +11,6 @@ .global _cpu_getVBR -/* cpu_setVBR(): Change VBR address */ -#if 0 -.section .gint.mapped, "ax" -_cpu_setVBR_reloc: - mov.l r8, @-r15 - mov.l r9, @-r15 - sts.l pr, @-r15 - - /* Block all interrupts by setting IMASK=15 */ - mov #0xf, r9 - shll2 r9 - shll2 r9 - stc sr, r0 - or r9, r0 - ldc r0, sr - - /* Set the new VBR address */ - stc vbr, r8 - ldc r4, vbr - - /* Call the configuration function */ - jsr @r5 - mov r6, r4 - - /* Enable interrupts again */ - stc sr, r0 - not r9, r9 - and r9, r0 - ldc r0, sr - - /* Return the previous VBR address */ - mov r8, r0 - - lds.l @r15+, pr - mov.l @r15+, r9 - rts - mov.l @r15+, r8 - -.section .gint.mappedrel, "aw" -_cpu_setVBR: - .long _cpu_setVBR_reloc -#endif - -.text - /* cpu_setCPUOPM(): Change the CPU Operation Mode register */ _cpu_setCPUOPM: /* Set CPUOPM as requested */ @@ -100,15 +56,16 @@ _cpu_setVBR: mov #0xf, r1 shll2 r1 shll2 r1 - stc sr, r0 - or r0, r1 + stc sr, r2 + or r2, r1 ldc r1, sr /* switch VBR */ + stc vbr, r0 ldc r4, vbr /* resotre old SR */ - ldc r0, sr + ldc r2, sr rts nop diff --git a/src/kernel/drivers.c b/src/kernel/drivers.c index b47073a..77b21aa 100644 --- a/src/kernel/drivers.c +++ b/src/kernel/drivers.c @@ -2,9 +2,10 @@ // gint:core:drivers - Drivers manager //--- #include -#include #include #include +#include +#include #include "drivers.h" @@ -33,6 +34,21 @@ void *drivers_context_create(void) } +/* drivers_context_duplicate(): Duplicate an environment */ +int drivers_context_duplicate(void **dst, void *src) +{ + if (src == NULL) + return (-1); + size_t ctxsz = drivers_context_get_size(); + *dst = realloc(*dst, ctxsz); + if (*dst == NULL) + return (-2); + atomic_begin(); + memcpy(*dst, src, ctxsz); + atomic_end(); + return (0); +} + /* drivers_context_destroy(): Destroy generated context */ void drivers_context_destroy(void **buffctx) { @@ -47,6 +63,8 @@ void drivers_context_destroy(void **buffctx) //--- // Drivers interface //--- +/* current env drivers information */ +void *kernel_env_current = NULL; /* driver_wait(): Wait until all driver have finished */ void drivers_wait(void) @@ -57,26 +75,16 @@ void drivers_wait(void) } } -/* drivers_save_and_exit(): save the current context and init the next */ -void drivers_save_and_init(void *buffctx) -{ - atomic_begin(); - for driver_asc(drv) { - if (isSH3() && drv->driver_sh3 != NULL) - drv->driver_sh3(); - if (drv->ctx_save != NULL) - drv->ctx_save(buffctx); - if (drv->ctx_size != NULL) - buffctx += (drv->ctx_size() + 3) & ~3; - if (drv->init != NULL) - drv->init(); - } - atomic_end(); -} - /* drivers_save(): save the current drivers' context */ -void drivers_save(void *buffctx) +int drivers_save(void *buffctx) { + if (buffctx == NULL) + return (-1); + + /* we need to wait until all transction has been done */ + drivers_wait(); + + /* save the current drivers state into the given env */ atomic_begin(); buffctx += drivers_context_get_size(); for driver_dsc(drv) { @@ -86,12 +94,24 @@ void drivers_save(void *buffctx) drv->ctx_save(buffctx); } atomic_end(); + return (0); } /* drivers_restore(): restore entier drivers' context */ -void drivers_restore(void *buffctx) +void *drivers_restore(void *buffctx) { + void *tmp; + + if (buffctx == NULL) + return (NULL); + + /* we need to wait until all transction has been done */ + drivers_wait(); + + /* switch current env then restore the saved drivers' env */ atomic_begin(); + tmp = kernel_env_current; + kernel_env_current = buffctx; for driver_asc(drv) { if (drv->ctx_restore != NULL) drv->ctx_restore(buffctx); @@ -99,12 +119,48 @@ void drivers_restore(void *buffctx) buffctx += (drv->ctx_size() + 3) & ~3; } atomic_end(); + + /* return the previous env */ + return (tmp); } -/* drivers_switch(): Switch between two world */ -void drivers_switch(void *currctx, void *nextctx) +/* drivers_save_and_exit(): save the current context and init the next */ +void *drivers_init(void *buffctx) { - drivers_wait(); - drivers_save(currctx); - drivers_restore(nextctx); + void *tmp; + + if (buffctx == NULL) + return (NULL); + + /* switch the current env then initialize it */ + atomic_begin(); + tmp = kernel_env_current; + kernel_env_current = buffctx; + for driver_asc(drv) { + if (isSH3() && drv->driver_sh3 != NULL) + drv->driver_sh3(); + if (drv->init != NULL) + drv->init(); + } + atomic_end(); + + /* return the previous env */ + return (tmp); +} + +//--- +// abstraction +//--- + +/* drivers_switch(): Switch between two world */ +void *drivers_switch(void *buffctx) +{ + drivers_save(kernel_env_current); + return (drivers_restore(buffctx)); +} + +/* drivers_get_current(): return the current context information */ +void *drivers_get_current(void) +{ + return (kernel_env_current); } diff --git a/src/kernel/hypervisor.c b/src/kernel/hypervisor.c index 064e46c..c272145 100644 --- a/src/kernel/hypervisor.c +++ b/src/kernel/hypervisor.c @@ -10,21 +10,23 @@ extern void *kernel_env_casio; extern void *kernel_env_gint; +#if 0 /* gint_switch(): Temporarily switch out of gint */ GWEAK void gint_switch(void (*function)(void)) { - /* Switch from gint to the OS after a short wait */ - atomic_begin(); - drivers_wait(); - drivers_switch(kernel_env_gint, kernel_env_casio); - atomic_end(); + void *buffctx; - if(function != NULL) - function(); + /* check useless switch */ + if(function == NULL) + return; + + /* Switch from gint to the OS after a short wait */ + buffctx = drivers_switch(kernel_env_casio); + + /* involve function */ + function(); /* Then switch back to gint once the OS finishes working */ - atomic_begin(); - drivers_wait(); - drivers_switch(kernel_env_casio, kernel_env_gint); - atomic_end(); + drivers_switch(buffctx); } +#endif diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 4a76cc2..5bcd54a 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -31,17 +31,16 @@ void kinit(void) /* create Casio's context, switch to Gint and save Gint context */ kernel_env_gint = drivers_context_create(); kernel_env_casio = drivers_context_create(); - drivers_wait(); - drivers_save_and_init(kernel_env_casio); + drivers_save(kernel_env_casio); + drivers_init(kernel_env_gint); drivers_save(kernel_env_gint); } /* kquit(): Quit gint and give back control to the system */ void kquit(void) { - drivers_wait(); - atomic_begin(); drivers_restore(kernel_env_casio); + atomic_begin(); drivers_context_destroy(&kernel_env_casio); drivers_context_destroy(&kernel_env_gint); atomic_end(); diff --git a/src/render-cg/dupdate.c b/src/render-cg/dupdate.c index 35c0192..3e563db 100644 --- a/src/render-cg/dupdate.c +++ b/src/render-cg/dupdate.c @@ -11,3 +11,9 @@ void dupdate(void) overwriting the data which is about to be sent. */ dvram_switch(); } + +/* dupdate_noint(): Push the video RAM to the display driver without DMA */ +void dupdate_noint(void) +{ + r61524_display(gint_vram, 0, 224, R61524_CPU); +}