forked from Lephenixnoir/gint
@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
This commit is contained in:
parent
6961a0feec
commit
c923ad24b1
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue