mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 04:23:36 +01:00
bfile: solve stability issues on fx9860g and fxcg50
This commit improves the stability of gint_switch() in two ways: 1. Wait for hardware availability every time driver contexts are saved or reloaded; this solves crashes due to DMA use when gint takes control after a BFile call, since BFile_Create() (and possibly BFile_Write()) leave the DMA running after returning. 2. Remap the add-in after a switch, as apparently calling BFile functions causes some pages to be evicted. This is more noticeable on fxcg50 when the size of add-ins nears 220k. Additionally, dma_transfer_wait() has been updated to not sleep() unless it is certain that the conditions for wakeup are fulfilled, as this would sometimes freeze.
This commit is contained in:
parent
14e59690a5
commit
5ff1662e61
5 changed files with 37 additions and 11 deletions
3
TODO
3
TODO
|
@ -7,7 +7,7 @@ For the 2.0.0 release:
|
|||
Crucial, missing things.
|
||||
! core: the four basic memory functions (with automated tests)
|
||||
! core: use gint_switch() to handle TLB misses
|
||||
! bfile: solve stability issues
|
||||
! core: recheck SH3 compatibility
|
||||
|
||||
Issues.
|
||||
* #3 make drawing functions parameterized
|
||||
|
@ -16,6 +16,7 @@ Issues.
|
|||
* #10 support fx-CG 20
|
||||
|
||||
Complementary elements on existing code.
|
||||
* gray: add gprint()
|
||||
* gray: double-buffer gray settings and unify d* with g*
|
||||
* display: deprecate image_t and rename it bopti_image_t
|
||||
* topti: support unicode fonts
|
||||
|
|
|
@ -162,18 +162,18 @@ static void gint_switch_out(void)
|
|||
gint_ctx_save(&gint_ctx);
|
||||
|
||||
/* Restore the system context */
|
||||
for(gint_driver_t *drv = &edrv; (--drv) >= &bdrv;)
|
||||
gint_ctx_restore(&sys_ctx);
|
||||
for(gint_driver_t *drv = &bdrv; drv < &edrv; drv++)
|
||||
{
|
||||
if(!drv->ctx_save || !drv->ctx_restore) continue;
|
||||
drv->ctx_restore(drv->sys_ctx);
|
||||
}
|
||||
gint_ctx_restore(&sys_ctx);
|
||||
}
|
||||
|
||||
static void gint_switch_in(void)
|
||||
{
|
||||
/* Save system state again */
|
||||
for(gint_driver_t *drv = &bdrv; drv < &edrv; drv++)
|
||||
for(gint_driver_t *drv = &edrv; (--drv) >= &bdrv;)
|
||||
{
|
||||
if(!drv->ctx_save || !drv->ctx_restore) continue;
|
||||
drv->ctx_save(drv->sys_ctx);
|
||||
|
@ -181,12 +181,12 @@ static void gint_switch_in(void)
|
|||
gint_ctx_save(&sys_ctx);
|
||||
|
||||
/* Restore all drivers to their gint state */
|
||||
gint_ctx_restore(&gint_ctx);
|
||||
for(gint_driver_t *drv = &bdrv; drv < &edrv; drv++)
|
||||
{
|
||||
if(!drv->ctx_save || !drv->ctx_restore) continue;
|
||||
drv->ctx_restore(drv->gint_ctx);
|
||||
}
|
||||
gint_ctx_restore(&gint_ctx);
|
||||
}
|
||||
|
||||
/* gint_switch() - temporarily switch out of gint */
|
||||
|
@ -200,6 +200,24 @@ void gint_switch(void (*function)(void))
|
|||
|
||||
gint_setvbr(system_vbr, gint_switch_out);
|
||||
if(function) function();
|
||||
|
||||
/* Remap all of the ROM */
|
||||
extern uint32_t brom, srom;
|
||||
volatile void *b = &brom;
|
||||
int32_t s = (int32_t)&srom;
|
||||
GUNUSED uint8_t x;
|
||||
while(s > 0)
|
||||
{
|
||||
x = *(volatile uint8_t *)b;
|
||||
b += 1024;
|
||||
s -= 1024;
|
||||
}
|
||||
|
||||
/* Wait for the OS to finish working */
|
||||
for(gint_driver_t *drv = &edrv; (--drv) >= &bdrv;)
|
||||
{
|
||||
if(drv->wait) drv->wait();
|
||||
}
|
||||
gint_setvbr((uint32_t)&gint_vbr, gint_switch_in);
|
||||
}
|
||||
|
||||
|
|
|
@ -156,6 +156,9 @@ int start(int isappli, int optnum)
|
|||
/* Initialize all drivers by saving the system settings */
|
||||
for(drv = &bdrv; drv < &edrv; drv++)
|
||||
{
|
||||
/* Wait for hardware availability */
|
||||
if(drv->wait) drv->wait();
|
||||
|
||||
/* Hook for old SH3 fx9860g machines */
|
||||
if(isSH3() && drv->driver_sh3) drv->driver_sh3();
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
mov.l 1f, r0 ;\
|
||||
jmp @r2 ;\
|
||||
nop ;\
|
||||
.align 4 ;\
|
||||
1: .long id
|
||||
|
||||
#ifdef FX9860G
|
||||
|
@ -123,10 +124,12 @@ _realloc:
|
|||
/* BFile driver */
|
||||
|
||||
_BFile_Remove:
|
||||
mov #0, r5
|
||||
syscall(0x1db4)
|
||||
_BFile_Create:
|
||||
syscall(0x1dae)
|
||||
_BFile_Open:
|
||||
mov #0, r6
|
||||
syscall(0x1da3)
|
||||
_BFile_Close:
|
||||
syscall(0x1da4)
|
||||
|
|
|
@ -138,9 +138,10 @@ void dma_transfer_wait(int channel)
|
|||
if(ch->SAR >= 0xe5007000 && ch->SAR < 0xe5204000) onchip = 1;
|
||||
if(ch->DAR >= 0xe5007000 && ch->DAR < 0xe5204000) onchip = 1;
|
||||
|
||||
while(ch->CHCR.DE)
|
||||
while(ch->CHCR.DE && !ch->CHCR.TE)
|
||||
{
|
||||
if(!onchip) sleep();
|
||||
/* Sleep only if the interrupt is enabled to wake us up */
|
||||
if(!onchip && ch->CHCR.IE) sleep();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,8 +229,8 @@ static void wait(void)
|
|||
typedef struct
|
||||
{
|
||||
channel_t ch[6];
|
||||
uint16_t OR;
|
||||
int clock;
|
||||
uint16_t OR;
|
||||
|
||||
} GPACKED(4) ctx_t;
|
||||
|
||||
|
@ -257,8 +258,6 @@ static void ctx_save(void *buf)
|
|||
|
||||
static void ctx_restore(void *buf)
|
||||
{
|
||||
dma_transfer_wait(-1);
|
||||
|
||||
ctx_t *ctx = buf;
|
||||
|
||||
/* Restore the supply status of the DMA0 clock first. If the DMA was
|
||||
|
@ -267,6 +266,9 @@ static void ctx_restore(void *buf)
|
|||
power it up again for the writes to registers to have any effect */
|
||||
POWER.MSTPCR0.DMAC0 = ctx->clock;
|
||||
|
||||
/* Disable the DMA while editing */
|
||||
DMA.OR.DME = 0;
|
||||
|
||||
for(int i = 0; i < 6; i++)
|
||||
{
|
||||
channel_t *ch = dma_channel(i);
|
||||
|
@ -275,7 +277,6 @@ static void ctx_restore(void *buf)
|
|||
ch->TCR = ctx->ch[i].TCR;
|
||||
ch->CHCR.lword = ctx->ch[i].CHCR.lword;
|
||||
}
|
||||
|
||||
DMA.OR.word = ctx->OR;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue