mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-07-04 03:26:37 +02:00
world: new gint_world_enter() and gint_world_leave() primitives
This commit is contained in:
parent
dff487b20a
commit
4442d27b62
3 changed files with 62 additions and 2 deletions
|
@ -41,6 +41,15 @@ int gint_world_switch(gint_call_t function);
|
||||||
__attribute__((deprecated("Use gint_world_switch() instead")))
|
__attribute__((deprecated("Use gint_world_switch() instead")))
|
||||||
void gint_switch(void (*function)(void));
|
void gint_switch(void (*function)(void));
|
||||||
|
|
||||||
|
#define GINT_WORLD_ADDIN 1
|
||||||
|
#define GINT_WORLD_OS 0
|
||||||
|
|
||||||
|
/* gint_world_enter(): Enter in a new world */
|
||||||
|
void gint_world_enter(int world);
|
||||||
|
|
||||||
|
/* gint_world_leave(): Leave a world set by gint_world_enter() */
|
||||||
|
void gint_world_leave(void);
|
||||||
|
|
||||||
/* gint_world_sync(): Synchronize asynchronous drivers
|
/* gint_world_sync(): Synchronize asynchronous drivers
|
||||||
|
|
||||||
This function waits for asynchronous tasks to complete by unbinding all
|
This function waits for asynchronous tasks to complete by unbinding all
|
||||||
|
|
|
@ -81,6 +81,7 @@ GNORETURN static void gint_default_panic(GUNUSED uint32_t code)
|
||||||
if(code == 0x1080) name = "Stack overflow";
|
if(code == 0x1080) name = "Stack overflow";
|
||||||
if(code == 0x10a0) name = "UBC in bank 1 code";
|
if(code == 0x10a0) name = "UBC in bank 1 code";
|
||||||
// if(code == 0x10c0) name = "Missing syscall"; // not on FX
|
// if(code == 0x10c0) name = "Missing syscall"; // not on FX
|
||||||
|
if(code == 0x1100) name = "World-switch error";
|
||||||
|
|
||||||
if(name[0]) dtext(1, 9, name);
|
if(name[0]) dtext(1, 9, name);
|
||||||
else dprint(1, 9, "%03x", code);
|
else dprint(1, 9, "%03x", code);
|
||||||
|
@ -124,6 +125,7 @@ GNORETURN static void gint_default_panic(GUNUSED uint32_t code)
|
||||||
if(code == 0x10a0) name = "UBC break in register bank 1 code";
|
if(code == 0x10a0) name = "UBC break in register bank 1 code";
|
||||||
if(code == 0x10c0) name = "Missing syscall for this OS version";
|
if(code == 0x10c0) name = "Missing syscall for this OS version";
|
||||||
if(code == 0x10e0) name = "I2C (touch-screen) error";
|
if(code == 0x10e0) name = "I2C (touch-screen) error";
|
||||||
|
if(code == 0x1100) name = "World-switch error";
|
||||||
|
|
||||||
dprint(6, 25, "%03x %s", code, name);
|
dprint(6, 25, "%03x %s", code, name);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <gint/gint.h>
|
#include <gint/gint.h>
|
||||||
#include <gint/exc.h>
|
#include <gint/exc.h>
|
||||||
#include <gint/defs/call.h>
|
#include <gint/defs/call.h>
|
||||||
|
#include <gint/defs/util.h>
|
||||||
#include <gint/hardware.h>
|
#include <gint/hardware.h>
|
||||||
#include <gint/display.h>
|
#include <gint/display.h>
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
@ -146,10 +147,58 @@ void gint_world_switch_out(gint_world_t world_addin, gint_world_t world_os)
|
||||||
cpu_atomic_end();
|
cpu_atomic_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WORLD_SWITCH_STACK_SIZE
|
||||||
|
# define WORLD_SWITCH_STACK_SIZE 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
u8 stack[WORLD_SWITCH_STACK_SIZE];
|
||||||
|
int idx;
|
||||||
|
} world_switch_stack = {
|
||||||
|
.stack = { GINT_WORLD_ADDIN },
|
||||||
|
.idx = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME: support CPU atomic operation
|
||||||
|
void gint_world_enter(int world)
|
||||||
|
{
|
||||||
|
GAUTOTYPE wss = &world_switch_stack;
|
||||||
|
|
||||||
|
if (world != GINT_WORLD_OS && world != GINT_WORLD_ADDIN)
|
||||||
|
gint_panic(0x1100);
|
||||||
|
if (wss->idx >= WORLD_SWITCH_STACK_SIZE)
|
||||||
|
gint_panic(0x1100);
|
||||||
|
if (world != wss->stack[wss->idx])
|
||||||
|
{
|
||||||
|
if (world == GINT_WORLD_OS)
|
||||||
|
gint_world_switch_out(gint_world_addin, gint_world_os);
|
||||||
|
if (world == GINT_WORLD_ADDIN)
|
||||||
|
gint_world_switch_in(gint_world_os, gint_world_addin);
|
||||||
|
}
|
||||||
|
wss->stack[++(wss->idx)] = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: support CPU atomic operation
|
||||||
|
void gint_world_leave(void)
|
||||||
|
{
|
||||||
|
GAUTOTYPE wss = &world_switch_stack;
|
||||||
|
|
||||||
|
if (wss->idx == 0)
|
||||||
|
gint_panic(0x1100);
|
||||||
|
if (wss->stack[wss->idx - 0] != wss->stack[wss->idx - 1])
|
||||||
|
{
|
||||||
|
if (wss->stack[wss->idx] == GINT_WORLD_OS)
|
||||||
|
gint_world_switch_in(gint_world_os, gint_world_addin);
|
||||||
|
if (wss->stack[wss->idx] == GINT_WORLD_ADDIN)
|
||||||
|
gint_world_switch_out(gint_world_addin, gint_world_os);
|
||||||
|
}
|
||||||
|
wss->idx -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
int gint_world_switch(gint_call_t call)
|
int gint_world_switch(gint_call_t call)
|
||||||
{
|
{
|
||||||
extern void *gint_stack_top;
|
extern void *gint_stack_top;
|
||||||
gint_world_switch_out(gint_world_addin, gint_world_os);
|
gint_world_enter(GINT_WORLD_OS);
|
||||||
|
|
||||||
void *ILRAM = (void *)0xe5200000;
|
void *ILRAM = (void *)0xe5200000;
|
||||||
void *XRAM = (void *)0xe500e000;
|
void *XRAM = (void *)0xe500e000;
|
||||||
|
@ -194,7 +243,7 @@ int gint_world_switch(gint_call_t call)
|
||||||
if(canary && *canary != 0xb7c0ffee)
|
if(canary && *canary != 0xb7c0ffee)
|
||||||
gint_panic(0x1080);
|
gint_panic(0x1080);
|
||||||
|
|
||||||
gint_world_switch_in(gint_world_os, gint_world_addin);
|
gint_world_leave();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue