* 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
This commit is contained in:
Yatis 2021-03-13 17:59:03 +01:00
parent 6961a0feec
commit c923ad24b1
7 changed files with 121 additions and 92 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -2,9 +2,10 @@
// gint:core:drivers - Drivers manager
//---
#include <gint/drivers.h>
#include <gint/std/stdlib.h>
#include <gint/hardware.h>
#include <gint/atomic.h>
#include <gint/std/string.h>
#include <gint/std/stdlib.h>
#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);
}

View File

@ -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

View File

@ -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();

View File

@ -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);
}