mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-29 13:03: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.
|
Crucial, missing things.
|
||||||
! core: the four basic memory functions (with automated tests)
|
! core: the four basic memory functions (with automated tests)
|
||||||
! core: use gint_switch() to handle TLB misses
|
! core: use gint_switch() to handle TLB misses
|
||||||
! bfile: solve stability issues
|
! core: recheck SH3 compatibility
|
||||||
|
|
||||||
Issues.
|
Issues.
|
||||||
* #3 make drawing functions parameterized
|
* #3 make drawing functions parameterized
|
||||||
|
@ -16,6 +16,7 @@ Issues.
|
||||||
* #10 support fx-CG 20
|
* #10 support fx-CG 20
|
||||||
|
|
||||||
Complementary elements on existing code.
|
Complementary elements on existing code.
|
||||||
|
* gray: add gprint()
|
||||||
* gray: double-buffer gray settings and unify d* with g*
|
* gray: double-buffer gray settings and unify d* with g*
|
||||||
* display: deprecate image_t and rename it bopti_image_t
|
* display: deprecate image_t and rename it bopti_image_t
|
||||||
* topti: support unicode fonts
|
* topti: support unicode fonts
|
||||||
|
|
|
@ -162,18 +162,18 @@ static void gint_switch_out(void)
|
||||||
gint_ctx_save(&gint_ctx);
|
gint_ctx_save(&gint_ctx);
|
||||||
|
|
||||||
/* Restore the system context */
|
/* 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;
|
if(!drv->ctx_save || !drv->ctx_restore) continue;
|
||||||
drv->ctx_restore(drv->sys_ctx);
|
drv->ctx_restore(drv->sys_ctx);
|
||||||
}
|
}
|
||||||
gint_ctx_restore(&sys_ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gint_switch_in(void)
|
static void gint_switch_in(void)
|
||||||
{
|
{
|
||||||
/* Save system state again */
|
/* 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;
|
if(!drv->ctx_save || !drv->ctx_restore) continue;
|
||||||
drv->ctx_save(drv->sys_ctx);
|
drv->ctx_save(drv->sys_ctx);
|
||||||
|
@ -181,12 +181,12 @@ static void gint_switch_in(void)
|
||||||
gint_ctx_save(&sys_ctx);
|
gint_ctx_save(&sys_ctx);
|
||||||
|
|
||||||
/* Restore all drivers to their gint state */
|
/* Restore all drivers to their gint state */
|
||||||
|
gint_ctx_restore(&gint_ctx);
|
||||||
for(gint_driver_t *drv = &bdrv; drv < &edrv; drv++)
|
for(gint_driver_t *drv = &bdrv; drv < &edrv; drv++)
|
||||||
{
|
{
|
||||||
if(!drv->ctx_save || !drv->ctx_restore) continue;
|
if(!drv->ctx_save || !drv->ctx_restore) continue;
|
||||||
drv->ctx_restore(drv->gint_ctx);
|
drv->ctx_restore(drv->gint_ctx);
|
||||||
}
|
}
|
||||||
gint_ctx_restore(&gint_ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gint_switch() - temporarily switch out of gint */
|
/* gint_switch() - temporarily switch out of gint */
|
||||||
|
@ -200,6 +200,24 @@ void gint_switch(void (*function)(void))
|
||||||
|
|
||||||
gint_setvbr(system_vbr, gint_switch_out);
|
gint_setvbr(system_vbr, gint_switch_out);
|
||||||
if(function) function();
|
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);
|
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 */
|
/* Initialize all drivers by saving the system settings */
|
||||||
for(drv = &bdrv; drv < &edrv; drv++)
|
for(drv = &bdrv; drv < &edrv; drv++)
|
||||||
{
|
{
|
||||||
|
/* Wait for hardware availability */
|
||||||
|
if(drv->wait) drv->wait();
|
||||||
|
|
||||||
/* Hook for old SH3 fx9860g machines */
|
/* Hook for old SH3 fx9860g machines */
|
||||||
if(isSH3() && drv->driver_sh3) drv->driver_sh3();
|
if(isSH3() && drv->driver_sh3) drv->driver_sh3();
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
mov.l 1f, r0 ;\
|
mov.l 1f, r0 ;\
|
||||||
jmp @r2 ;\
|
jmp @r2 ;\
|
||||||
nop ;\
|
nop ;\
|
||||||
|
.align 4 ;\
|
||||||
1: .long id
|
1: .long id
|
||||||
|
|
||||||
#ifdef FX9860G
|
#ifdef FX9860G
|
||||||
|
@ -123,10 +124,12 @@ _realloc:
|
||||||
/* BFile driver */
|
/* BFile driver */
|
||||||
|
|
||||||
_BFile_Remove:
|
_BFile_Remove:
|
||||||
|
mov #0, r5
|
||||||
syscall(0x1db4)
|
syscall(0x1db4)
|
||||||
_BFile_Create:
|
_BFile_Create:
|
||||||
syscall(0x1dae)
|
syscall(0x1dae)
|
||||||
_BFile_Open:
|
_BFile_Open:
|
||||||
|
mov #0, r6
|
||||||
syscall(0x1da3)
|
syscall(0x1da3)
|
||||||
_BFile_Close:
|
_BFile_Close:
|
||||||
syscall(0x1da4)
|
syscall(0x1da4)
|
||||||
|
|
|
@ -138,9 +138,10 @@ void dma_transfer_wait(int channel)
|
||||||
if(ch->SAR >= 0xe5007000 && ch->SAR < 0xe5204000) onchip = 1;
|
if(ch->SAR >= 0xe5007000 && ch->SAR < 0xe5204000) onchip = 1;
|
||||||
if(ch->DAR >= 0xe5007000 && ch->DAR < 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
|
typedef struct
|
||||||
{
|
{
|
||||||
channel_t ch[6];
|
channel_t ch[6];
|
||||||
uint16_t OR;
|
|
||||||
int clock;
|
int clock;
|
||||||
|
uint16_t OR;
|
||||||
|
|
||||||
} GPACKED(4) ctx_t;
|
} GPACKED(4) ctx_t;
|
||||||
|
|
||||||
|
@ -257,8 +258,6 @@ static void ctx_save(void *buf)
|
||||||
|
|
||||||
static void ctx_restore(void *buf)
|
static void ctx_restore(void *buf)
|
||||||
{
|
{
|
||||||
dma_transfer_wait(-1);
|
|
||||||
|
|
||||||
ctx_t *ctx = buf;
|
ctx_t *ctx = buf;
|
||||||
|
|
||||||
/* Restore the supply status of the DMA0 clock first. If the DMA was
|
/* 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 it up again for the writes to registers to have any effect */
|
||||||
POWER.MSTPCR0.DMAC0 = ctx->clock;
|
POWER.MSTPCR0.DMAC0 = ctx->clock;
|
||||||
|
|
||||||
|
/* Disable the DMA while editing */
|
||||||
|
DMA.OR.DME = 0;
|
||||||
|
|
||||||
for(int i = 0; i < 6; i++)
|
for(int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
channel_t *ch = dma_channel(i);
|
channel_t *ch = dma_channel(i);
|
||||||
|
@ -275,7 +277,6 @@ static void ctx_restore(void *buf)
|
||||||
ch->TCR = ctx->ch[i].TCR;
|
ch->TCR = ctx->ch[i].TCR;
|
||||||
ch->CHCR.lword = ctx->ch[i].CHCR.lword;
|
ch->CHCR.lword = ctx->ch[i].CHCR.lword;
|
||||||
}
|
}
|
||||||
|
|
||||||
DMA.OR.word = ctx->OR;
|
DMA.OR.word = ctx->OR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue