mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 04:23:36 +01:00
some cleanup in src/core and in the repository
This commit is contained in:
parent
de4881244e
commit
b7de559b78
10 changed files with 151 additions and 136 deletions
9
TODO
9
TODO
|
@ -2,37 +2,28 @@ For the 2.1.0 release:
|
|||
* core: the four basic memory functions (with automated tests)
|
||||
* bopti: remove the deprecated image_t definition
|
||||
* project: remove the compat branch
|
||||
* gray: remove g*() functions
|
||||
* core: remove the boot log
|
||||
|
||||
Issues:
|
||||
* #3 make drawing functions parameterized
|
||||
* #8 support fx-CG Manager
|
||||
* #10 support fx-CG 20
|
||||
|
||||
Extensions on existing code:
|
||||
* bopti: try to display fullscreen images with TLB access + DMA on fxcg50
|
||||
* gray: add gprint()
|
||||
* gray: double-buffer gray settings and unify d* with g*
|
||||
* topti: support unicode fonts
|
||||
* gray: find good values for more models than the Graph 35+E II
|
||||
* dma: fx9860g support (need to switch it on and update the Makefile)
|
||||
* core: try to leave add-in without reset in case of panic
|
||||
* hardware: fill in the HWMEM_FITTLB flag
|
||||
* keyboard: think of extended functions
|
||||
* cpg: spread spectrum on fxcg50
|
||||
* display: use more of topti's assembler in drect()
|
||||
* core: use cmp/str for memchr()
|
||||
* r61524: brightness control and clean the file
|
||||
* t6k11: check if dupdate() can be done by the DMA
|
||||
* core: review forgotten globals and MPU addresses not in <gint/mpu/*.h>
|
||||
* build: make the build system simpler (two targets are enough by default)
|
||||
* core: run destructors when a task-switch results in leaving the app
|
||||
* core: invoke main menu instead of returning after main() ends
|
||||
* prizm: don't hardcode stack address in fxcg50.ld (if possible)
|
||||
* prizm: detect P1 static RAM (stack) in TLB
|
||||
* core rtc: use qdiv10 to massively improve division performance
|
||||
* core: document the SH7305 PFC in <gint/mpu/pfc.h>
|
||||
|
||||
Future directions.
|
||||
* A complete file system abstraction
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
//---
|
||||
// core:setup - Installing and unloading the library
|
||||
//---
|
||||
|
||||
#ifndef GINT_CORE_SETUP
|
||||
#define GINT_CORE_SETUP
|
||||
|
||||
#include <gint/defs/types.h>
|
||||
|
||||
/* Prototypes for the library management functions are in <gint/gint.h> */
|
||||
|
||||
/* gint_setvbr()
|
||||
Changes the VBR address and calls the configuration function while
|
||||
interrupts are disabled. The configuration function must disable all
|
||||
interrupts that the new handlers cannot handle, either by clearing the
|
||||
priority registers or by setting the interrupt masks.
|
||||
|
||||
@vbr New VBR address
|
||||
@configure Configuration function
|
||||
Returns the previous VBR address. */
|
||||
uint32_t gint_setvbr(uint32_t vbr, void (*configure)(void));
|
||||
|
||||
void gint_setcpuopm(uint32_t CPUOPM);
|
||||
uint32_t gint_getcpuopm(void);
|
||||
|
||||
/* gint_exch(): Exception handler */
|
||||
void gint_exch(void);
|
||||
/* gint_tlbh(): TLB miss handler */
|
||||
void gint_tlbh(void);
|
||||
|
||||
/* gint_inth_7705(): SH7705 exception handler */
|
||||
void gint_inth_7705(void);
|
||||
/* gint_inth_7305(): SH7305 exception handler */
|
||||
void gint_inth_7305(void);
|
||||
|
||||
#endif /* GINT_CORE_SETUP */
|
|
@ -8,60 +8,74 @@
|
|||
#include <gint/defs/attributes.h>
|
||||
#include <gint/defs/types.h>
|
||||
|
||||
//---
|
||||
// Driver procedure flow
|
||||
//
|
||||
// Drivers are initialized in priority order, and in linking order within
|
||||
// the same priority level (pretty much undefined). Make sure every
|
||||
// driver's priority level is higher than those of its dependencies. In
|
||||
// the description below, every function can be NULL.
|
||||
//
|
||||
// At initialization, the following functions are called:
|
||||
// 1. driver_sh3() [on SH3-based fx9860g only]
|
||||
// 2. ctx_save(sys_ctx)
|
||||
// 3. init()
|
||||
//
|
||||
// If the gint_switch() function is called to temporarily give back
|
||||
// control to the operating system, the state of each driver is saved to
|
||||
// the stack, then restored from there.
|
||||
// 4. wait()
|
||||
// 5. ctx_save(gint_ctx)
|
||||
// 6. ctx_restore(sys_ctx)
|
||||
// (stuff happening outside of gint)
|
||||
// 7. ctx_save(sys_ctx)
|
||||
// 8. ctx_restore(gint_ctx)
|
||||
//
|
||||
// When finally the driver is unloaded, the system context is restored.
|
||||
// 9. wait()
|
||||
// 10. ctx_restore(sys_ctx)
|
||||
//---
|
||||
/* Driver procedure flow
|
||||
|
||||
/* gint_driver_t - driver meta-information used by gint */
|
||||
Drivers are initialized in priority order, and in linking order within the
|
||||
the same priority level (which is pretty much undefined). Every driver's
|
||||
priority level must be higher than those of its dependencies; the numbers
|
||||
are fixed, see the documentation for level assignments.
|
||||
|
||||
At initialization, drivers are first called to wait for the hardware to
|
||||
become available before initialization. Then the system state is saved. We
|
||||
still support SH3-based SH7705-like MPUs, so a function init_sh3() is called
|
||||
for every driver that need to make adjustments to support them. Finally, the
|
||||
driver is initialized. The calls are as follow; every function pointer can
|
||||
be NULL in which case it is ignored.
|
||||
|
||||
1. wait()
|
||||
2. ctx_save(sys_ctx)
|
||||
3. driver_sh3() [SH3-based fx9860g]
|
||||
4. init()
|
||||
|
||||
During the execution, gint_switch() can be called to temporarily give back
|
||||
control to the OS. In this case, the state of each driver is saved to a
|
||||
context from gint, then restored from there afterwards.
|
||||
|
||||
5. wait()
|
||||
6. ctx_save(gint_ctx)
|
||||
7. ctx_restore(sys_ctx)
|
||||
(stuff happening outside of gint)
|
||||
8. wait()
|
||||
9. ctx_save(sys_ctx)
|
||||
10. ctx_restore(gint_ctx)
|
||||
|
||||
When finally the driver is unloaded, the system context is restored.
|
||||
|
||||
11. wait()
|
||||
12. ctx_restore(sys_ctx)
|
||||
|
||||
The wait() function is called both when gint has control and when the OS has
|
||||
control; thus, it must not rely on any internal state other than the
|
||||
hardware itself.
|
||||
|
||||
The ctx_save() and ctx_restore() function are called with interrupts
|
||||
disabled (IMASK=15) so you should not rely on interrupts. However, TLB
|
||||
misses are still enabled so you can rely on TLB updates. */
|
||||
|
||||
/* gint_driver_t: Metadata and interface of kernel drivers */
|
||||
typedef struct
|
||||
{
|
||||
/* Driver name */
|
||||
char const *name;
|
||||
|
||||
/* SH3-specific preinitializaton; called before init() when running on
|
||||
SH3. May be NULL. */
|
||||
/* SH3-specific initialization step. May be NULL. */
|
||||
void (*driver_sh3)(void);
|
||||
|
||||
/* Must initialize the hardware so that the driver can start working.
|
||||
This is called only once when the add-in starts, and should not save
|
||||
hardware state (ctx_save() is called before). May be NULL. */
|
||||
/* Should initialize the hardware so that the driver can start working.
|
||||
Usually installs interrupt handlers and configures interrupts. Only
|
||||
called once when the add-in starts. May be NULL. */
|
||||
void (*init)(void);
|
||||
|
||||
/* This function can be used to enforce a waiting period before the
|
||||
driver is unloaded. It is called before returning to the OS in
|
||||
gint_switch() and if the add-in exits. May be NULL. */
|
||||
/* Should wait for the hardware to become available. Called both under
|
||||
gint control and OS control every time control is passed around. It
|
||||
is used for instance to wait for DMA transfers. May be NULL. */
|
||||
void (*wait)(void);
|
||||
|
||||
/* System's context and gint's context. These should point to enough
|
||||
memory to store a full driver state each. These are used when
|
||||
switching from the system to gint and back to the main menu. If they
|
||||
don't need to be initialized, put them in gint's uninitialized BSS
|
||||
section using the GBSS macro of <gint/defs/attributes.h>. May be
|
||||
NULL only if both ctx_save() and ctx_restore() are NULL. */
|
||||
memory to store a full driver state each. Used when switching from
|
||||
the system to gint and back to the main menu. If they don't need to
|
||||
be initialized, put them in gint's uninitialized BSS section using
|
||||
the GBSS macro of <gint/defs/attributes.h>. May be NULL only if both
|
||||
ctx_save() and ctx_restore() are NULL. */
|
||||
void *sys_ctx;
|
||||
void *gint_ctx;
|
||||
|
||||
|
@ -69,30 +83,29 @@ typedef struct
|
|||
possible (memory-mapped MPU registers, port state, etc). This
|
||||
function is called to save the system's hardware state and gint's
|
||||
hardware state when moving from one into the other. The parameter
|
||||
[ctx] is always either [sys_ctx] or [gint_ctx]. */
|
||||
is always either sys_ctx or gint_ctx. */
|
||||
void (*ctx_save)(void *ctx);
|
||||
|
||||
/* Must restore the state of the driver as saved by ctx_save(). */
|
||||
void (*ctx_restore)(void *ctx);
|
||||
|
||||
} GPACKED(4) gint_driver_t;
|
||||
|
||||
/* GINT_DECLARE_DRIVER() - make a driver visible to gint
|
||||
/* GINT_DECLARE_DRIVER(): Declare a driver to the kernel
|
||||
|
||||
Use this macro to expose a driver by passing it the name of a gint_driver_t
|
||||
Use this macro to declare a driver by passing it the name of a gint_driver_t
|
||||
structure. This macro moves the structure to the .gint.drivers.* sections,
|
||||
which are automatically traversed at startup.
|
||||
|
||||
The @level argument represents the priority level: lower numbers mean that
|
||||
The level argument represents the priority level: lower numbers mean that
|
||||
drivers will be loaded sooner. This numbering allows a primitive form of
|
||||
dependency for drivers. You need to specify a level which is strictly
|
||||
higher than the level of all the drivers you depend on. */
|
||||
#define GINT_DECLARE_DRIVER(level, name) \
|
||||
GSECTION(".gint.drivers." #level) extern gint_driver_t name;
|
||||
|
||||
/* GINT_DRIVER_SH3() - declare a function for SH3 preinitialization
|
||||
This macro makes its argument NULL on fxcg50, this way the named function
|
||||
can be defined under #ifdef FX9860G while keeping the structure clean. */
|
||||
/* GINT_DRIVER_SH3(): Declare an init_sh3() function
|
||||
This macro is NULL on fxcg50, so that the named function can be defined
|
||||
under #ifdef FX9860G while keeping the structure clean. */
|
||||
|
||||
#ifdef FXCG50
|
||||
#define GINT_DRIVER_SH3(name) NULL
|
||||
|
|
|
@ -95,6 +95,7 @@ version_hash = 0x0$(shell git rev-parse --short HEAD)
|
|||
all: $(target)
|
||||
|
||||
$(target): $(obj)
|
||||
@ rm -f $@
|
||||
$(call cmd_l,ar,$@) $(ar) rcs $(arflags) $@ $^
|
||||
|
||||
# Assembler sources
|
||||
|
|
34
src/core/cpu.h
Normal file
34
src/core/cpu.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
//---
|
||||
// core:cpu - CPU registers and operation management
|
||||
//---
|
||||
|
||||
#ifndef GINT_CORE_CPU
|
||||
#define GINT_CORE_CPU
|
||||
|
||||
#include <gint/defs/types.h>
|
||||
|
||||
/* cpu_setVBR(): Change VBR address
|
||||
|
||||
Blocks interrupts then changes the VBR address and calls the provided INTC
|
||||
configuration function before restoring interrupts. This function must
|
||||
configure the INTC in a way that is safe for the new VBR controller,
|
||||
including disabling all interrupts that it cannot handle.
|
||||
|
||||
@vbr New VBR address
|
||||
@conf_intc Configuration function
|
||||
Returns the previous VBR address. */
|
||||
uint32_t cpu_setVBR(uint32_t vbr, void (*conf_intc)(void));
|
||||
|
||||
/* cpu_setCPUOPM(): Change the CPU Operation Mode register
|
||||
|
||||
Updates the CPU Operation Mode with the specified settings, then performs a
|
||||
read and an ICBI to register the change. Only writable bits of CPUOPM should
|
||||
be changed, other bits must be left at the value given by cpu_getcpuopm().
|
||||
|
||||
@CPUOPM New operation mode */
|
||||
void cpu_setCPUOPM(uint32_t CPUOPM);
|
||||
|
||||
/* cpu_getCPUOPM(): Get the CPU OperatioN Mode register */
|
||||
uint32_t cpu_getCPUOPM(void);
|
||||
|
||||
#endif /* GINT_CORE_CPU */
|
|
@ -2,22 +2,14 @@
|
|||
** gint:core:vbr - Assembler-level VBR management
|
||||
*/
|
||||
|
||||
.global _gint_setvbr
|
||||
.global _gint_setcpuopm
|
||||
.global _gint_getcpuopm
|
||||
.global _cpu_setVBR
|
||||
.global _cpu_setCPUOPM
|
||||
.global _cpu_getCPUOPM
|
||||
|
||||
.section .gint.mapped
|
||||
|
||||
/* gint_setvbr()
|
||||
Changes the VBR address and the calls the configuration function while
|
||||
interrupts are disabled. The configuration function must change either the
|
||||
priority registers or the interrupt masks, and make sure that all the
|
||||
interrupts that it leaves enabled are handled by the new VBR handlers.
|
||||
|
||||
@r4 vbr New VBR address (uint32_t)
|
||||
@r5 configure Configuration function (void -> void)
|
||||
Returns the previous VBR address. */
|
||||
_gint_setvbr:
|
||||
/* cpu_setVBR(): Change VBR address */
|
||||
_cpu_setVBR:
|
||||
mov.l r9, @-r15
|
||||
mov.l r8, @-r15
|
||||
sts.l pr, @-r15
|
||||
|
@ -53,11 +45,8 @@ _gint_setvbr:
|
|||
|
||||
.text
|
||||
|
||||
/* gint_setcpuopm()
|
||||
Changes the CPUOPM value and executes an ICBI to register the change.
|
||||
|
||||
@r4 New value of CPUOPM (uint32_t) */
|
||||
_gint_setcpuopm:
|
||||
/* cpu_setCPUOPM(): Change the CPU Operation Mode register */
|
||||
_cpu_setCPUOPM:
|
||||
/* Set CPUOPM as requested */
|
||||
mov.l 1f, r0
|
||||
mov.l r4, @r0
|
||||
|
@ -74,7 +63,8 @@ _gint_setcpuopm:
|
|||
rts
|
||||
nop
|
||||
|
||||
_gint_getcpuopm:
|
||||
/* cpu_getCPUOPM(): Get the CPU OperatioN Mode register */
|
||||
_cpu_getCPUOPM:
|
||||
mov.l 1f, r0
|
||||
rts
|
||||
mov.l @r0, r0
|
|
@ -6,6 +6,7 @@
|
|||
#include <gint/std/string.h>
|
||||
#include <gint/hardware.h>
|
||||
#include <gint/mpu/intc.h>
|
||||
#include "vbr.h"
|
||||
|
||||
/* Interrupt controllers */
|
||||
|
||||
|
@ -49,8 +50,6 @@ int gint_intlevel(int intid, int level)
|
|||
/* gint_inthandler() - configure interrupt handlers */
|
||||
void *gint_inthandler(int event_code, const void *handler, size_t size)
|
||||
{
|
||||
extern uint32_t gint_vbr;
|
||||
|
||||
/* Normalize the event code */
|
||||
event_code -= 0x400;
|
||||
event_code &= ~0x1f;
|
||||
|
|
|
@ -5,27 +5,16 @@
|
|||
#include <gint/gint.h>
|
||||
#include <gint/drivers.h>
|
||||
#include <gint/std/string.h>
|
||||
#include <core/setup.h>
|
||||
#include <gint/hardware.h>
|
||||
#include <gint/mpu/intc.h>
|
||||
#include <gint/defs/util.h>
|
||||
#include <gint/display.h>
|
||||
|
||||
/* VBR address, from the linker script */
|
||||
#ifdef FX9860G
|
||||
extern char gint_vbr_fx9860g[];
|
||||
#endif
|
||||
#ifdef FXCG50
|
||||
extern char gint_vbr_fxcg50[];
|
||||
extern char gint_vbr_fxcg20[];
|
||||
#endif
|
||||
#include "cpu.h"
|
||||
#include "vbr.h"
|
||||
|
||||
/* VBR addresses for gint and the system */
|
||||
GBSS uint32_t gint_vbr;
|
||||
GBSS static uint32_t system_vbr;
|
||||
/* Size of exception and TLB handler */
|
||||
extern char gint_exch_size;
|
||||
extern char gint_tlbh_size;
|
||||
/* Driver table */
|
||||
extern gint_driver_t bdrv, edrv;
|
||||
|
||||
|
@ -59,7 +48,7 @@ GMAPPED static void gint_ctx_save(gint_core_ctx *ctx)
|
|||
for(int i = 0; i < 13; i++, IMR += 4)
|
||||
ctx->masks[i] = *IMR;
|
||||
|
||||
ctx->CPUOPM = gint_getcpuopm();
|
||||
ctx->CPUOPM = cpu_getCPUOPM();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,7 +75,7 @@ GMAPPED static void gint_ctx_restore(gint_core_ctx *ctx)
|
|||
*IMR = ctx->masks[i];
|
||||
}
|
||||
|
||||
gint_setcpuopm(ctx->CPUOPM);
|
||||
cpu_setCPUOPM(ctx->CPUOPM);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,7 +95,7 @@ GMAPPED static void lock(void)
|
|||
else for(int i = 0; i < 12; i++)
|
||||
SH7305_INTC.IPRS[2 * i] = 0x0000;
|
||||
|
||||
gint_setcpuopm(gint_getcpuopm() | 0x00000008);
|
||||
cpu_setCPUOPM(cpu_getCPUOPM() | 0x00000008);
|
||||
}
|
||||
|
||||
/* gint_install() - install and start gint */
|
||||
|
@ -141,7 +130,7 @@ void gint_install(void)
|
|||
memcpy(vbr + 0x600, inth_entry, 64);
|
||||
|
||||
/* Time to switch VBR and roll! */
|
||||
system_vbr = gint_setvbr(gint_vbr, lock);
|
||||
system_vbr = cpu_setVBR(gint_vbr, lock);
|
||||
}
|
||||
|
||||
/* unlock() - unlock interrupts, restoring system settings */
|
||||
|
@ -166,7 +155,7 @@ void gint_unload(void)
|
|||
if(drv->wait) drv->wait();
|
||||
}
|
||||
|
||||
gint_setvbr(system_vbr, unlock);
|
||||
cpu_setVBR(system_vbr, unlock);
|
||||
}
|
||||
|
||||
//---
|
||||
|
@ -223,7 +212,7 @@ void gint_switch(void (*function)(void))
|
|||
if(drv->wait) drv->wait();
|
||||
}
|
||||
|
||||
gint_setvbr(system_vbr, gint_switch_out);
|
||||
cpu_setVBR(system_vbr, gint_switch_out);
|
||||
if(function) function();
|
||||
|
||||
/* Wait for the OS to finish working */
|
||||
|
@ -231,7 +220,7 @@ void gint_switch(void (*function)(void))
|
|||
{
|
||||
if(drv->wait) drv->wait();
|
||||
}
|
||||
gint_setvbr(gint_vbr, gint_switch_in);
|
||||
cpu_setVBR(gint_vbr, gint_switch_in);
|
||||
}
|
||||
|
||||
int __Timer_Install(int id, void (*handler)(void), int delay);
|
||||
|
|
32
src/core/vbr.h
Normal file
32
src/core/vbr.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
//---
|
||||
// core:vbr - VBR-related functions and linker script symbols
|
||||
//---
|
||||
|
||||
#ifndef GINT_CORE_VBR
|
||||
#define GINT_CORE_VBR
|
||||
|
||||
#include <gint/defs/types.h>
|
||||
|
||||
/* VBR addresses from the linker script */
|
||||
#ifdef FX9860G
|
||||
extern char gint_vbr_fx9860g[];
|
||||
#endif
|
||||
#ifdef FXCG50
|
||||
extern char gint_vbr_fxcg50[];
|
||||
extern char gint_vbr_fxcg20[];
|
||||
#endif
|
||||
|
||||
/* gint's VBR address as determined at runtime; not valid before kinit() */
|
||||
extern uint32_t gint_vbr;
|
||||
|
||||
/* The kernel's interrupt and exception handlers' entry points */
|
||||
void gint_exch(void);
|
||||
void gint_tlbh(void);
|
||||
void gint_inth_7705(void);
|
||||
void gint_inth_7305(void);
|
||||
|
||||
/* Size of exception and TLB handlers */
|
||||
extern char gint_exch_size;
|
||||
extern char gint_tlbh_size;
|
||||
|
||||
#endif /* GINT_CORE_VBR */
|
|
@ -4,6 +4,8 @@
|
|||
static uint16_t *main = (void *)0xac0f0000;
|
||||
static uint16_t *scnd = (void *)0xac11b500;
|
||||
|
||||
/* On Prizm: should be: 0xa80f0000 and 0xa811b500 */
|
||||
|
||||
/* Shared VRAM pointer, the one exposed by <gint/display.h> */
|
||||
uint16_t *gint_vram = (void *)0xac0f0000;
|
||||
|
||||
|
|
Loading…
Reference in a new issue