Update drivers management
This commit is contained in:
parent
126a619942
commit
bc52765c6f
|
@ -0,0 +1,19 @@
|
|||
#ifndef __KERNEL_BITS_CONTEXT_H__
|
||||
# define __KERNEL_BITS_CONTEXT_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Define the SuperH CPU hardware context
|
||||
struct cpu_context
|
||||
{
|
||||
uint32_t reg[16];
|
||||
uint32_t gbr;
|
||||
uint32_t macl;
|
||||
uint32_t mach;
|
||||
uint32_t ssr;
|
||||
uint32_t spc;
|
||||
uint32_t pr;
|
||||
};
|
||||
|
||||
#endif /*__KERNEL_BITS_CONTEXT_H__*/
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef __KERNEL_BITS_DRIVER_H__
|
||||
# define __KERNEL_BITS_DRIVER_H__
|
||||
|
||||
#include <kernel/bits/mpu.h>
|
||||
|
||||
// Macros used to declare new driver object
|
||||
// @note:
|
||||
// Level 1: Should be installed first (power management)
|
||||
// Level 2: Higher priority (clock and bus control)
|
||||
// Level 3: High priority (timer, rtc, ...)
|
||||
// Level 4: General drivers
|
||||
#define VHEX_DRIVER(level, name) \
|
||||
__attribute__((section(".driver." #level))) struct driver name
|
||||
|
||||
// Define driver object
|
||||
struct driver
|
||||
{
|
||||
mpu_t arch;
|
||||
void (*install)(void);
|
||||
void (*uninstall)(void);
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#endif /*__KERNEL_BITS_DRIVER_H__*/
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef __KERNEL_HARDWARE_MPU_H__
|
||||
# define __KERNEL_HARDWARE_MPU_H__
|
||||
#ifndef __KERNEL_BITS_MPU_H__
|
||||
# define __KERNEL_BITS_MPU_H__
|
||||
|
||||
// Define MPU arch.
|
||||
typedef enum mpu_e
|
||||
|
@ -11,4 +11,4 @@ typedef enum mpu_e
|
|||
MPU_UNKNOWN,
|
||||
} mpu_t;
|
||||
|
||||
#endif /*__KERNEL_HARDWARE_MPU_H__*/
|
||||
#endif /*__KERNEL_BITS_MPU_H__*/
|
|
@ -1,67 +0,0 @@
|
|||
#ifndef __KERNEL_CONTEXT_H__
|
||||
# define __KERNEL_CONTEXT_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct fx9860_context_s
|
||||
{
|
||||
struct {
|
||||
uint16_t control;
|
||||
uint16_t autofix;
|
||||
uint16_t scan_mode;
|
||||
uint16_t scan_state;
|
||||
uint16_t interrupt;
|
||||
uint16_t scan_wait;
|
||||
uint16_t scan_interval;
|
||||
uint16_t kyoutdr;
|
||||
uint16_t kyindr;
|
||||
} keyboard;
|
||||
struct {
|
||||
uint16_t ipra;
|
||||
uint16_t iprb;
|
||||
uint16_t iprc;
|
||||
uint16_t iprd;
|
||||
uint16_t ipre;
|
||||
uint16_t iprf;
|
||||
uint16_t iprg;
|
||||
uint16_t iprh;
|
||||
uint16_t ipri;
|
||||
uint16_t iprj;
|
||||
uint16_t iprk;
|
||||
uint16_t iprl;
|
||||
} intc;
|
||||
struct {
|
||||
uint32_t stbcr;
|
||||
uint32_t mstpcr0;
|
||||
uint32_t mstpcr1;
|
||||
uint32_t mstpcr2;
|
||||
} power;
|
||||
struct {
|
||||
uint8_t tstr;
|
||||
struct {
|
||||
uint32_t tcor;
|
||||
uint32_t tcnt;
|
||||
uint16_t tcr;
|
||||
} timer[3];
|
||||
} tmu;
|
||||
uint32_t vbr;
|
||||
//TODO: SR SSR SPC GBR MACL MACH
|
||||
} fx9860_context_t;
|
||||
|
||||
typedef struct common_context_s
|
||||
{
|
||||
uint32_t reg[16];
|
||||
uint32_t gbr;
|
||||
uint32_t macl;
|
||||
uint32_t mach;
|
||||
uint32_t ssr;
|
||||
uint32_t spc;
|
||||
uint32_t pr;
|
||||
} common_context_t;
|
||||
|
||||
// Context primitive.
|
||||
extern void fx9860_context_save(fx9860_context_t *context);
|
||||
extern void fx9860_context_restore(fx9860_context_t *context);
|
||||
|
||||
#endif /*__KERNEL_CONTEXT_H__*/
|
|
@ -5,9 +5,11 @@
|
|||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// Macros which generate keycode
|
||||
#define KEYCODE_GEN(row, column) \
|
||||
(((row & 0x0f) << 4) | ((column & 0x0f) << 0))
|
||||
|
||||
// Internal struct used by the keyboard abstraction
|
||||
struct keycache_s
|
||||
{
|
||||
uint8_t keycode;
|
||||
|
@ -26,7 +28,7 @@ struct keyscan_s
|
|||
};
|
||||
typedef struct keyscan_s keyscan_t;
|
||||
|
||||
|
||||
// Define all keycode
|
||||
typedef enum key_e
|
||||
{
|
||||
KEY_F1 = 0x41,
|
||||
|
@ -90,10 +92,11 @@ typedef enum key_e
|
|||
KEY_UNUSED = 0xff
|
||||
} key_t;
|
||||
|
||||
// Primitives
|
||||
extern int keyboard_open(void);
|
||||
extern ssize_t keyboard_read(void *buffer, size_t count);
|
||||
extern int keyboard_close(void);
|
||||
|
||||
// key cache abstrations functions
|
||||
extern void keycache_initialize(void);
|
||||
extern void keycache_clean(int key_frame);
|
||||
extern void keycache_update(int row, int column, uint8_t key_frame);
|
||||
|
||||
// Helpers
|
||||
extern void keyboard_wait_event(keyscan_t *list);
|
||||
|
|
|
@ -19,7 +19,23 @@
|
|||
//---
|
||||
// Interruption code
|
||||
//---
|
||||
//TODO
|
||||
//TODO: chech SH7724 code validity (?)
|
||||
#define INT_CODE_TMU0_TUNI0 0x400
|
||||
#define INT_CODE_TMU0_TUNI1 0x420
|
||||
#define INT_CODE_TMU0_TUNI2 0x440
|
||||
#define INT_CODE_KEYSC 0xbe0
|
||||
|
||||
// Macros helpers
|
||||
// @note:
|
||||
// First interrupt code start at 0x400 (TLB miss are redirect)
|
||||
// and the last interrupt code is 0xfe0 (undocumented)
|
||||
// Each interrupt code are gapped by 0x20
|
||||
#define VBR_GET_INTERRUPT_CODE(id, code) (id = ((code - 0x400) / 0x20))
|
||||
#define VBR_INTERRUPT_NB ((0xfe0 - 0x400) / 0x20)
|
||||
|
||||
// Driver primitives
|
||||
extern void *vbr_interrupt_set(int intcode, void (*handler)(void));
|
||||
extern void *vbr_set(void *vbr);
|
||||
extern void *vbr_get(void);
|
||||
|
||||
#endif /*__KERNEL_DRIVERS_VBR_H__*/
|
||||
|
|
|
@ -6,6 +6,58 @@
|
|||
#include <sys/types.h>
|
||||
#include <kernel/fs/file.h>
|
||||
|
||||
|
||||
|
||||
/*******************************************/
|
||||
/** **/
|
||||
/** Common SMEM driver part **/
|
||||
/** **/
|
||||
/*******************************************/
|
||||
extern void smemfs_initialize(void);
|
||||
extern void smemfd_uninitialize(void);
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************/
|
||||
/** **/
|
||||
/** USB Power Graphic II SMEM driver part **/
|
||||
/** **/
|
||||
/*******************************************/
|
||||
// Internal Casio's structure to dump file's informations
|
||||
struct smem_USB3_file_info
|
||||
{
|
||||
uint16_t id; // File index
|
||||
uint16_t type; // File type
|
||||
struct {
|
||||
uint32_t file; // File size (data + header)
|
||||
uint32_t data; // Data size (without header)
|
||||
} size;
|
||||
uint32_t address; // Data address ?
|
||||
};
|
||||
|
||||
// Superblock primitives
|
||||
extern void * smemfs_USB3_mount(void);
|
||||
extern int smemfs_USB3_umount(void);
|
||||
|
||||
// File primitives
|
||||
extern ssize_t smemfs_USB3_read(void *inode, void *buf, size_t count, off_t pos);
|
||||
|
||||
// Inode primitive
|
||||
extern void * smemfs_USB3_find_parent(void *inode);
|
||||
extern void * smemfs_USB3_find_first_child(void *inode);
|
||||
extern void * smemfs_USB3_find_next_sibling(void *inode);
|
||||
extern int smemfs_USB3_get_name(void *inode, char *name, size_t count);
|
||||
extern mode_t smemfs_USB3_get_mode(void *inode);
|
||||
|
||||
|
||||
/*******************************************/
|
||||
/** **/
|
||||
/** USB Power Graphic II SMEM driver part **/
|
||||
/** **/
|
||||
/*******************************************/
|
||||
|
||||
// Define internal SMEM informations /flags
|
||||
#define CASIO_SMEM_NAME_LENGHT 12
|
||||
#define CASIO_SMEM_ROOT_ID 0xffff
|
||||
#define CASIO_SMEM_BLOCK_ENTRY_MAGIC 0x4200
|
||||
|
@ -18,7 +70,6 @@
|
|||
#define CASIO_SMEM_FRAGMENT_MAGIC 0x0120
|
||||
#define CASIO_SMEM_ROOT_ID 0xffff
|
||||
|
||||
|
||||
// Define block data.
|
||||
struct casio_smem_block_s
|
||||
{
|
||||
|
@ -86,28 +137,26 @@ struct smemfs_superblock_s
|
|||
smemfs_sector_t *sector_table;
|
||||
};
|
||||
|
||||
// Constructor
|
||||
extern void smemfs_initialize();
|
||||
|
||||
// Superblock primitives
|
||||
extern void *smemfs_mount(void);
|
||||
extern int smemfs_umount(void);
|
||||
extern void * smemfs_USB2_mount(void);
|
||||
extern int smemfs_USB2_umount(void);
|
||||
|
||||
// File primitives
|
||||
extern ssize_t smemfs_read(void *inode, void *buf, size_t count, off_t pos);
|
||||
extern ssize_t smemfs_USB2_read(void *inode, void *buf, size_t count, off_t pos);
|
||||
|
||||
// Inode primitive
|
||||
extern void *smemfs_find_next_sibling(void *inode);
|
||||
extern void *smemfs_find_first_child(void *inode);
|
||||
extern void *smemfs_find_parent(void *inode);
|
||||
extern int smemfs_get_name(void *inode, char *name, size_t count);
|
||||
extern mode_t smemfs_get_mode(void *inode);
|
||||
extern void * smemfs_USB2_find_parent(void *inode);
|
||||
extern void * smemfs_USB2_find_first_child(void *inode);
|
||||
extern void * smemfs_USB2_find_next_sibling(void *inode);
|
||||
extern int smemfs_USB2_get_name(void *inode, char *name, size_t count);
|
||||
extern mode_t smemfs_USB2_get_mode(void *inode);
|
||||
|
||||
|
||||
// Internal helper !
|
||||
#define WALK_FLAG_ID_CHECK_PARENT (1 << 0)
|
||||
#define WALK_FLAG_ID_CHECK_DIRECTORY (0 << 0)
|
||||
extern smemfs_inode_t *smemfs_walk(smemfs_inode_t *current,
|
||||
smemfs_inode_t *entry, uint16_t folder_id, int flags);
|
||||
extern smemfs_inode_t *smemfs_USB2_walk(smemfs_inode_t *current,
|
||||
smemfs_inode_t *entry, uint16_t folder_id, int flags);
|
||||
|
||||
#endif /*_CASIO_SMEM_H__*/
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <kernel/def/union_types.h>
|
||||
#include <kernel/def/attributes.h>
|
||||
#include <kernel/bits/union_types.h>
|
||||
#include <kernel/bits/attributes.h>
|
||||
|
||||
struct SH7305_cpg_s
|
||||
{
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef __KERNEL_MODULES_SH7724_INTC_H__
|
||||
# define __KERNEL_MODULES_SH7724_INTC_H__
|
||||
#ifndef __KERNEL_HARDWARE_INTC_H__
|
||||
# define __KERNEL_HARDWARE_INTC_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel/def/union_types.h>
|
||||
#include <kernel/def/attributes.h>
|
||||
#include <kernel/bits/union_types.h>
|
||||
#include <kernel/bits/attributes.h>
|
||||
|
||||
struct SH7305_intc_s
|
||||
struct __sh7305_intc_s
|
||||
{
|
||||
//---
|
||||
// Interrupt priority register.
|
||||
|
@ -510,5 +510,29 @@ struct SH7305_intc_s
|
|||
);
|
||||
};
|
||||
|
||||
#define SH7305_INTC (*(volatile struct SH7305_intc_s *)0xa4080000)
|
||||
#endif /*__KERNEL_MODULES_SH7724_INTC_H__*/
|
||||
struct __sh7305_intc_context
|
||||
{
|
||||
uint16_t ipra;
|
||||
uint16_t iprb;
|
||||
uint16_t iprc;
|
||||
uint16_t iprd;
|
||||
uint16_t ipre;
|
||||
uint16_t iprf;
|
||||
uint16_t iprg;
|
||||
uint16_t iprh;
|
||||
uint16_t ipri;
|
||||
uint16_t iprj;
|
||||
uint16_t iprk;
|
||||
uint16_t iprl;
|
||||
uint8_t imr[12];
|
||||
uint16_t icr[2];
|
||||
uint32_t intpri00;
|
||||
uint8_t intreq00;
|
||||
uint8_t intmsk00;
|
||||
uint8_t intmskclr00;
|
||||
uint16_t nmifcr;
|
||||
uint32_t usermsk;
|
||||
} __attribute__((packed, aligned(2)));
|
||||
|
||||
#define SH7305_INTC (*(volatile struct __sh7305_intc_s *)0xa4080000)
|
||||
#endif /*__KERNEL_HARDWARE_INTC_H__*/
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef __KERNEL_MODULES_SH7724_KEYSC_H__
|
||||
# define __KERNEL_MODULES_SH7724_KEYSC_H__
|
||||
#ifndef __KERNEL_HARDWARE_KEYSC_H__
|
||||
# define __KERNEL_HARDWARE_KEYSC_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel/def/union_types.h>
|
||||
#include <kernel/def/attributes.h>
|
||||
#include <kernel/bits/union_types.h>
|
||||
#include <kernel/bits/attributes.h>
|
||||
|
||||
struct sh7305_keysc_s
|
||||
struct __sh7305_keysc_s
|
||||
{
|
||||
volatile const uint16_t KIUDATA[6];
|
||||
volatile word_union(CONTROL,
|
||||
|
@ -61,6 +61,19 @@ struct sh7305_keysc_s
|
|||
);
|
||||
};
|
||||
|
||||
#define SH7305_KEYSC (*(volatile struct sh7305_keysc_s *)0xa44b0000)
|
||||
struct __sh7305_keysc_context
|
||||
{
|
||||
uint16_t control;
|
||||
uint16_t autofix;
|
||||
uint16_t scan_mode;
|
||||
uint16_t scan_state;
|
||||
uint16_t interrupt;
|
||||
uint16_t scan_wait;
|
||||
uint16_t scan_interval;
|
||||
uint16_t kyoutdr;
|
||||
uint16_t kyindr;
|
||||
};
|
||||
|
||||
#endif /*__KERNEL_MODULES_SH7724_KEYSC_H__*/
|
||||
#define SH7305_KEYSC (*(volatile struct __sh7305_keysc_s *)0xa44b0000)
|
||||
|
||||
#endif /*__KERNEL_HARDWARE_KEYSC_H__*/
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef __KERNEL_MODULES_SH7724_STANDBY_H__
|
||||
# define __KERNEL_MODULES_SH7724_STANDBY_H__
|
||||
#ifndef __KERNEL_HARDWARE_POWER_H__
|
||||
# define __KERNEL_HARDWARE_POWER_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel/def/union_types.h>
|
||||
#include <kernel/def/attributes.h>
|
||||
#include <kernel/bits/union_types.h>
|
||||
#include <kernel/bits/attributes.h>
|
||||
|
||||
struct power_s
|
||||
struct __sh7305_power_s
|
||||
{
|
||||
volatile long_union(STBCR, /* Standby Control Register */
|
||||
uint32_t const : 24;
|
||||
|
@ -63,39 +63,46 @@ struct power_s
|
|||
volatile long_union(MSTPCR2, /* Module Stop Register 2 */
|
||||
uint32_t const : 2; /* All 0 */
|
||||
uint32_t MMC : 1; /* Multi Media Card Interface (?) */
|
||||
uint32_t EMAC : 1; /* Ether Controller */
|
||||
uint32_t const : 1; /* unknwon */
|
||||
uint32_t const : 1; /* All 0 */
|
||||
uint32_t ATAPI : 1; /* ATAPI */
|
||||
uint32_t const : 1; /* unknown */
|
||||
uint32_t TPU : 1; /* Timer Pulse Unit */
|
||||
uint32_t IrDA : 1; /* IrDA interface */
|
||||
uint32_t IrDA : 1; /* IrDA interface ? */
|
||||
uint32_t const : 1; /* All 0 */
|
||||
uint32_t TSIF : 1; /* TS interface */
|
||||
uint32_t USB1 : 1; /* USB 1 */
|
||||
uint32_t const : 1; /* unknown */
|
||||
uint32_t const : 1; /* unknown */
|
||||
uint32_t USB0 : 1; /* USB 0 */
|
||||
uint32_t _2DG : 1; /* 2D graphics accelerator */
|
||||
uint32_t SDHI0 : 1; /* SD card host */
|
||||
uint32_t SDHI1 : 1; /* IrDA interface */
|
||||
uint32_t const : 1; /* unknown */
|
||||
uint32_t SDHI0 : 1; /* SD card host 0 ? */
|
||||
uint32_t SDHI1 : 1; /* SD card host 1 ? */
|
||||
uint32_t const : 1; /* All 0 */
|
||||
uint32_t VEU1 : 1; /* */
|
||||
uint32_t const : 1; /* unknown */
|
||||
uint32_t const : 1; /* All 0 */
|
||||
uint32_t CEU1 : 1; /* */
|
||||
uint32_t BEU1 : 1; /* */
|
||||
uint32_t const : 1; /* unknown */
|
||||
uint32_t const : 1; /* unknown */
|
||||
uint32_t const : 1; /* All 0 */
|
||||
uint32_t _2DDMAC: 1; /* */
|
||||
uint32_t SPU : 1; /* Sound Processing Unit */
|
||||
uint32_t const : 1; /* All 0 */
|
||||
uint32_t GCU : 1; /* */
|
||||
uint32_t JPU : 1; /* JPEG processing Unit */
|
||||
uint32_t VOU : 1; /* Video Output Unit */
|
||||
uint32_t BEU0 : 1; /* */
|
||||
uint32_t CEU0 : 1; /* */
|
||||
uint32_t VPU : 1; /* Video Processing Unit */
|
||||
uint32_t LCDC : 1; /* LCD controller */
|
||||
uint32_t const : 1; /* unknown */
|
||||
uint32_t SPU : 1; /* Sound Processing Unit ? */
|
||||
uint32_t const : 1; /* all 0 */
|
||||
uint32_t const : 1; /* unknown */
|
||||
uint32_t LCD : 1; /* LCD driver */
|
||||
uint32_t const : 1; /* unknown */
|
||||
uint32_t const : 1; /* unknown */
|
||||
uint32_t const : 1; /* unknown */
|
||||
uint32_t const : 1; /* unknown */
|
||||
uint32_t LCDC : 1; /* LCD controller ? */
|
||||
);
|
||||
GAPS(4);
|
||||
volatile uint32_t const BAR; /* Boot Address Register */
|
||||
volatile uint32_t BAR; /* Boot Address Register */
|
||||
};
|
||||
|
||||
#define SH7305_POWER (*(volatile struct power_s *)0xa4150020)
|
||||
struct __sh7305_power_context
|
||||
{
|
||||
uint32_t stbcr;
|
||||
uint32_t mstpcr[3];
|
||||
uint32_t bar;
|
||||
};
|
||||
|
||||
#endif /*__KERNEL_MODULES_SH7724_STANDBY_H__*/
|
||||
#define SH7305_POWER (*(volatile struct __sh7305_power_s *)0xa4150020)
|
||||
|
||||
#endif /*__KERNEL_HARDWARE_POWER_H__*/
|
||||
|
|
|
@ -3,8 +3,18 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel/def/union_types.h>
|
||||
#include <kernel/def/attributes.h>
|
||||
#include <kernel/bits/union_types.h>
|
||||
#include <kernel/bits/attributes.h>
|
||||
|
||||
struct __sh7305_tmu_context
|
||||
{
|
||||
uint8_t tstr;
|
||||
struct {
|
||||
uint32_t tcor;
|
||||
uint32_t tcnt;
|
||||
uint16_t tcr;
|
||||
} timer[3];
|
||||
};
|
||||
|
||||
struct timer_s
|
||||
{
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel/def/union_types.h>
|
||||
#include <kernel/def/attributes.h>
|
||||
#include <kernel/bits/union_types.h>
|
||||
#include <kernel/bits/attributes.h>
|
||||
|
||||
struct sh7305_ubc_s
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <stdint.h>
|
||||
#include <kernel/fs/file.h>
|
||||
#include <kernel/fs/filesystem.h>
|
||||
#include <kernel/context.h>
|
||||
#include <kernel/bits/context.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
@ -33,7 +33,7 @@ struct process
|
|||
//---
|
||||
// Context management
|
||||
//---
|
||||
common_context_t context;
|
||||
struct cpu_context context;
|
||||
|
||||
|
||||
//---
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <kernel/process.h>
|
||||
#include <kernel/bits/context.h>
|
||||
|
||||
// Define the number of task
|
||||
#define SCHED_TASK_NB_MAX PROCESS_MAX
|
||||
|
@ -78,12 +79,12 @@ extern void sched_start(void);
|
|||
** Get the current task context and the next one
|
||||
** based on internal task priority / status.
|
||||
*/
|
||||
extern int sched_schedule(common_context_t **current, common_context_t **next);
|
||||
extern int sched_schedule(struct cpu_context **current, struct cpu_context **next);
|
||||
|
||||
/*
|
||||
** Internal function wich will switch current process
|
||||
** context with the next context
|
||||
*/
|
||||
extern void sched_context_switch(common_context_t *current, common_context_t *next);
|
||||
extern void sched_context_switch(struct cpu_context *current, struct cpu_context *next);
|
||||
|
||||
#endif /*__KERNEL_SHEDULER_H__*/
|
||||
|
|
|
@ -4,6 +4,13 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
//---
|
||||
// Casio's wrapper
|
||||
//---
|
||||
extern void casio_return_menu(int mode);
|
||||
|
||||
|
||||
|
||||
// Internal Casio datat structure
|
||||
struct rect
|
||||
{
|
||||
|
@ -13,6 +20,11 @@ struct rect
|
|||
int bottom;
|
||||
};
|
||||
|
||||
// GetKeyWait macros
|
||||
#define KEYWAIT_HALTON_TIMEROFF 0
|
||||
#define KEYWAIT_HALTOFF_TIMEROFF 1
|
||||
#define KEYWAIT_HALTON_TIMERON 2
|
||||
|
||||
//
|
||||
// Casio prototypes.
|
||||
//
|
||||
|
@ -60,6 +72,12 @@ static inline void dclear_area(int x1, int y1, int x2, int y2)
|
|||
casio_Bdisp_AreaClr_VRAM(&area);
|
||||
}
|
||||
|
||||
// Timer syscalls
|
||||
extern int casio_TimerInstall(int id, void (*handler)(void), int delay_ms);
|
||||
extern int casio_TimerUninstall(int id);
|
||||
extern int casio_TimerStart(int id);
|
||||
extern int casio_TimerStop(int id);
|
||||
|
||||
|
||||
|
||||
#endif /*__KERNEL_UTIL_CASIO_H__*/
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
#include <stdint.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
#include <kernel/bits/driver.h>
|
||||
#include <kernel/bits/mpu.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// Internal bootstrap funtions
|
||||
extern mpu_t mpu_get(void);
|
||||
|
||||
//TODO: secure if no driver is found !!
|
||||
void bootstrap_drivers_install(void)
|
||||
{
|
||||
extern uint32_t bdrivers_section;
|
||||
extern uint32_t edrivers_section;
|
||||
struct driver *driver;
|
||||
mpu_t mpu;
|
||||
int i;
|
||||
|
||||
// Start atomic operations
|
||||
earlyterm_write("Load drivers...\n");
|
||||
atomic_start();
|
||||
|
||||
i = -1;
|
||||
mpu = mpu_get();
|
||||
driver = (void *)&bdrivers_section;
|
||||
while ((uint32_t)&driver[++i] < (uint32_t)&edrivers_section)
|
||||
{
|
||||
// Check driver
|
||||
if (driver[i].arch != mpu)
|
||||
continue;
|
||||
|
||||
// Check driver integrity
|
||||
if (driver[i].install == NULL || driver[i].uninstall == NULL) {
|
||||
earlyterm_write("* WARNING - driver integrity [%s]\n", driver[i].name);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to install the driver
|
||||
// TODO: check driver error ?
|
||||
earlyterm_write("* install driver [%s]\n", driver[i].name);
|
||||
(*driver[i].install)();
|
||||
}
|
||||
|
||||
// Stop atomic operations
|
||||
atomic_stop();
|
||||
}
|
||||
|
||||
void bootstrap_drivers_uninstall(void)
|
||||
{
|
||||
extern uint32_t bdrivers_section;
|
||||
extern uint32_t edrivers_section;
|
||||
struct driver *driver;
|
||||
mpu_t mpu;
|
||||
int i;
|
||||
|
||||
// Start atomic operations
|
||||
earlyterm_write("Unload drivers...\n");
|
||||
atomic_start();
|
||||
|
||||
// Uninstall driver (fifo style)
|
||||
mpu = mpu_get();
|
||||
driver = (void *)&bdrivers_section;
|
||||
i = ((uint32_t)&edrivers_section - (uint32_t)&bdrivers_section) / sizeof(struct driver);
|
||||
while (--i >= 0)
|
||||
{
|
||||
// Check driver
|
||||
if (driver[i].arch != mpu)
|
||||
continue;
|
||||
|
||||
// Check driver integrity
|
||||
if (driver[i].install == NULL || driver[i].uninstall == NULL) {
|
||||
earlyterm_write("* WARNING - driver integrity [%s]\n", driver[i].name);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to uninstall the driver
|
||||
// TODO: check driver error ?
|
||||
earlyterm_write("* uninstall driver [%s]\n", driver[i].name);
|
||||
(*driver[i].uninstall)();
|
||||
}
|
||||
|
||||
// Stop atomic operations
|
||||
atomic_stop();
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#include <kernel/devices/earlyterm.h>
|
||||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/fs/smemfs.h>
|
||||
#include <kernel/fs/gladfs.h>
|
||||
#include <kernel/fs/stat.h>
|
||||
#include <kernel/fs/vfs.h>
|
||||
|
||||
//---
|
||||
// Initialize File System and Virtual File System !
|
||||
//---
|
||||
void bootstrap_filesystem_init(void)
|
||||
{
|
||||
extern struct file_system_type gladfs_filesystem;
|
||||
extern struct file_system_type smemfs_filesystem;
|
||||
|
||||
// Internal FS init !
|
||||
earlyterm_write("Initialize File System...\n");
|
||||
gladfs_initialize();
|
||||
smemfs_initialize();
|
||||
|
||||
// Initialize Virtual File System
|
||||
earlyterm_write("Init. Virtual File System...\n");
|
||||
vfs_register_filesystem(&gladfs_filesystem);
|
||||
vfs_register_filesystem(&smemfs_filesystem);
|
||||
|
||||
// Creat initial FileSystem Hierarchy
|
||||
earlyterm_write("Create Filesystem Hierarchy...\n");
|
||||
vfs_mount(NULL, NULL, "gladfs", VFS_MOUNT_ROOT, NULL);
|
||||
vfs_mkdir("/dev", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vfs_mkdir("/home", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vfs_mkdir("/mnt", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vfs_mkdir("/mnt/casio", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vfs_mount(NULL, "/mnt/casio", "smemfs", /*MS_RDONLY*/0, NULL);
|
||||
|
||||
// Add devices
|
||||
earlyterm_write("Add devices...\n");
|
||||
vfs_mknod("/dev/tty", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH,
|
||||
dev_make_major(TTY_DEV_MAJOR));
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
#include <stdint.h>
|
||||
#include <kernel/hardware/mpu.h>
|
||||
#include <kernel/bits/mpu.h>
|
||||
|
||||
// Internal symbols
|
||||
mpu_t current_mpu = MPU_UNKNOWN;
|
||||
|
||||
/* check_sh3 - Detecting sh3-based MPU */
|
||||
static mpu_t check_sh3(uint16_t tplcr)
|
||||
|
@ -50,7 +53,10 @@ mpu_t mpu_get(void)
|
|||
volatile uint16_t *plcr = (void *)0xa4000114;
|
||||
uint16_t splcr;
|
||||
uint16_t tplcr;
|
||||
mpu_t mpu;
|
||||
|
||||
// Check if the MPU is already find
|
||||
if (current_mpu != MPU_UNKNOWN)
|
||||
return (current_mpu);
|
||||
|
||||
// Check port L control register.
|
||||
splcr = *plcr;
|
||||
|
@ -58,8 +64,9 @@ mpu_t mpu_get(void)
|
|||
tplcr = *plcr;
|
||||
*plcr = splcr;
|
||||
|
||||
mpu = check_sh3(tplcr);
|
||||
if (mpu != MPU_UNKNOWN)
|
||||
return (mpu);
|
||||
return (check_sh4());
|
||||
// Check MPU arch
|
||||
current_mpu = check_sh3(tplcr);
|
||||
if (current_mpu == MPU_UNKNOWN)
|
||||
current_mpu = check_sh4();
|
||||
return (current_mpu);
|
||||
}
|
||||
|
|
|
@ -1,48 +1,29 @@
|
|||
// Types
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
// Hardware
|
||||
#include <kernel/hardware/mpu.h>
|
||||
#include <kernel/bits/mpu.h>
|
||||
// Internal helpers
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/util/casio.h>
|
||||
// Modules
|
||||
#include <kernel/context.h>
|
||||
#include <kernel/bits/context.h>
|
||||
#include <kernel/process.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <kernel/scheduler.h>
|
||||
#include <kernel/loader.h>
|
||||
// Devices
|
||||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
// File System
|
||||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/fs/stat.h>
|
||||
#include <kernel/fs/smemfs.h>
|
||||
#include <kernel/fs/gladfs.h>
|
||||
// Libs
|
||||
#include <lib/display.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
// Internal symbols
|
||||
mpu_t current_mpu = MPU_UNKNOWN;
|
||||
|
||||
// Internal hardware context.
|
||||
fx9860_context_t casio_context;
|
||||
fx9860_context_t vhex_context;
|
||||
|
||||
// Symbols defined by the linker
|
||||
extern uint32_t bbss;
|
||||
extern uint32_t sbss;
|
||||
extern uint32_t bdata_ram;
|
||||
extern uint32_t bdata_rom;
|
||||
extern uint32_t sdata;
|
||||
extern uint32_t bvhex_ram;
|
||||
extern uint32_t bvhex_rom;
|
||||
extern uint32_t svhex;
|
||||
extern uint32_t bubc_ram;
|
||||
extern uint32_t bubc_rom;
|
||||
extern uint32_t subc;
|
||||
extern uint32_t brom;
|
||||
extern uint32_t srom;
|
||||
extern uint32_t bctors;
|
||||
|
@ -50,16 +31,10 @@ extern uint32_t ectors;
|
|||
extern uint32_t bdtors;
|
||||
extern uint32_t edtors;
|
||||
|
||||
// Internal functions.
|
||||
extern void vhex_context_set(void);
|
||||
extern void kernel_switch(common_context_t *context);
|
||||
// Internal bootstrap funtions
|
||||
extern mpu_t mpu_get(void);
|
||||
extern int main(void);
|
||||
|
||||
// Internal object
|
||||
extern struct file_system_type gladfs_filesystem;
|
||||
extern struct file_system_type smemfs_filesystem;
|
||||
|
||||
extern void bootstrap_drivers_install(void);
|
||||
extern void bootstrap_filesystem_init(void);
|
||||
|
||||
//
|
||||
// rom_explore() - explore all add-in ROM part.
|
||||
|
@ -93,37 +68,19 @@ static void section_execute(void *bsection, void *esection)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* start() - Kernel entry point */
|
||||
__attribute__((section(".pretext")))
|
||||
int start(void)
|
||||
{
|
||||
//--
|
||||
// Bootstrap part !
|
||||
//--
|
||||
// Casio do not load all add-in page and we can not use the MMU.
|
||||
// So we need to "force" update TLB before switching the VBR to
|
||||
// avoid TLB miss exception that we can not handle for now.
|
||||
rom_explore(&brom, (int32_t)&srom);
|
||||
|
||||
// Wipe .bss section and dump .data / Vhex sections
|
||||
memset(&bbss, 0x00, (size_t)&sbss);
|
||||
memcpy(&bdata_ram, &bdata_rom, (size_t)&sdata);
|
||||
|
||||
// Check MPU hardware.
|
||||
current_mpu = mpu_get();
|
||||
if (current_mpu != MPU_SH7305)
|
||||
return (0);
|
||||
|
||||
// Load UBC / VBR space.
|
||||
memcpy(&bubc_ram, &bubc_rom, (size_t)&subc);
|
||||
memcpy(&bvhex_ram, &bvhex_rom, (size_t)&svhex);
|
||||
|
||||
// Casio do not load all add-in
|
||||
// page. So we need to "force" update TLB
|
||||
// before switching the VBR.
|
||||
rom_explore(&brom, (int32_t)&srom);
|
||||
|
||||
// TODO: load driver on-the-fly
|
||||
extern void screen_driver_load(void);
|
||||
screen_driver_load();
|
||||
|
||||
// Start early terminal device
|
||||
// This device is used by the kernel to display
|
||||
// some logs on screen
|
||||
|
@ -132,59 +89,23 @@ int start(void)
|
|||
earlyterm_clear();
|
||||
earlyterm_write("Kernel initialisation...\n");
|
||||
|
||||
// Load all drivers on-the-fly
|
||||
bootstrap_drivers_install();
|
||||
|
||||
// Execute constructor.
|
||||
// FIXME: remove me ?
|
||||
section_execute(&bctors, &ectors);
|
||||
|
||||
|
||||
|
||||
// Save Casio's hardware context and set
|
||||
// Vhex hardware context.
|
||||
// @note:
|
||||
// This operation should be atomic
|
||||
// because if an interruption or exception
|
||||
// occur during the hardware context change
|
||||
// the calculator will crash.
|
||||
// And this is why between each `atomic_start`
|
||||
// and `atomic_end()` the code *SHOULD* be
|
||||
// exception safe.
|
||||
earlyterm_write("Environment switch...\n");
|
||||
atomic_start();
|
||||
fx9860_context_save(&casio_context);
|
||||
vhex_context_set();
|
||||
atomic_stop();
|
||||
|
||||
//---
|
||||
// File System part !
|
||||
//---
|
||||
|
||||
// Internal FS init !
|
||||
earlyterm_write("Initialize File System...\n");
|
||||
gladfs_initialize();
|
||||
smemfs_initialize();
|
||||
|
||||
// Initilize Virtual File System
|
||||
earlyterm_write("Init. Virtual File System...\n");
|
||||
vfs_register_filesystem(&gladfs_filesystem);
|
||||
vfs_register_filesystem(&smemfs_filesystem);
|
||||
|
||||
// Creat initial file tree
|
||||
earlyterm_write("Create Filesystem Hierarchy...\n");
|
||||
vfs_mount(NULL, NULL, "gladfs", VFS_MOUNT_ROOT, NULL);
|
||||
vfs_mkdir("/dev", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vfs_mkdir("/home", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vfs_mkdir("/mnt", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vfs_mkdir("/mnt/casio", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vfs_mount(NULL, "/mnt/casio", "smemfs", /*MS_RDONLY*/0, NULL);
|
||||
|
||||
// Add devices
|
||||
earlyterm_write("Add devices...\n");
|
||||
vfs_mknod("/dev/tty", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH,
|
||||
dev_make_major(TTY_DEV_MAJOR));
|
||||
// Initialize all File Systems and Virtual File System
|
||||
// TODO: rename into initramfs ?
|
||||
bootstrap_filesystem_init();
|
||||
|
||||
|
||||
//---
|
||||
// Start first process !
|
||||
//---
|
||||
//TODO: move me !!
|
||||
|
||||
// Load programe.
|
||||
earlyterm_write("Create first process...\n");
|
||||
|
@ -201,29 +122,15 @@ int start(void)
|
|||
earlyterm_write("File \"VHEX/shell.elf\" not found !\n");
|
||||
earlyterm_write("Press [MENU key]...\n");
|
||||
|
||||
// Restore Casio context.
|
||||
fx9860_context_restore(&casio_context);
|
||||
atomic_stop();
|
||||
|
||||
// Casio VRAM workaround
|
||||
// @note: GetKey will call Bdisp_PutDD_VRAM(),
|
||||
// so save the current internal Video RAM data into
|
||||
// Casio's VRAM.
|
||||
extern struct earlyterm earlyterm;
|
||||
memcpy(casio_Bdisp_GetVRAM(), earlyterm.display.vram, 1024);
|
||||
|
||||
// Wait MENU key.
|
||||
unsigned int key;
|
||||
while (1)
|
||||
{
|
||||
casio_GetKey(&key);
|
||||
}
|
||||
// Restore Casio's context and wait MENU key
|
||||
casio_return_menu(1);
|
||||
}
|
||||
|
||||
|
||||
//---
|
||||
// Initialize sheduler !!
|
||||
//---
|
||||
//TODO: move me ?
|
||||
earlyterm_write("Initialize scheduler...\n");
|
||||
sched_initialize();
|
||||
sched_task_add(vhex_process);
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
#include <kernel/context.h>
|
||||
#include <kernel/hardware/keysc.h>
|
||||
#include <kernel/hardware/intc.h>
|
||||
#include <kernel/hardware/power.h>
|
||||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/util/extra.h>
|
||||
|
||||
void fx9860_context_restore(fx9860_context_t *context)
|
||||
{
|
||||
// Restore VBR.
|
||||
vbr_set((void*)context->vbr);
|
||||
|
||||
// Restore TMU context.
|
||||
SH7305_TMU.TSTR.BYTE = 0x00; // stop all timer.
|
||||
SH7305_TMU.TIMER[0].TCOR = context->tmu.timer[0].tcor;
|
||||
SH7305_TMU.TIMER[0].TCNT = context->tmu.timer[0].tcnt;
|
||||
SH7305_TMU.TIMER[0].TCR.WORD = context->tmu.timer[0].tcr;
|
||||
SH7305_TMU.TIMER[1].TCOR = context->tmu.timer[1].tcor;
|
||||
SH7305_TMU.TIMER[1].TCNT = context->tmu.timer[1].tcnt;
|
||||
SH7305_TMU.TIMER[1].TCR.WORD = context->tmu.timer[1].tcr;
|
||||
SH7305_TMU.TIMER[2].TCOR = context->tmu.timer[2].tcor;
|
||||
SH7305_TMU.TIMER[2].TCNT = context->tmu.timer[2].tcnt;
|
||||
SH7305_TMU.TIMER[2].TCR.WORD = context->tmu.timer[2].tcr;
|
||||
SH7305_TMU.TSTR.BYTE = context->tmu.tstr;
|
||||
|
||||
// Restore power context.
|
||||
SH7305_POWER.STBCR.LONG_WORD = context->power.stbcr;
|
||||
SH7305_POWER.MSTPCR0.LONG_WORD = context->power.mstpcr0;
|
||||
SH7305_POWER.MSTPCR1.LONG_WORD = context->power.mstpcr1;
|
||||
SH7305_POWER.MSTPCR2.LONG_WORD = context->power.mstpcr2;
|
||||
|
||||
// Restore Key Scan (KEYSC) context.
|
||||
SH7305_KEYSC.CONTROL.WORD = context->keyboard.control;
|
||||
SH7305_KEYSC.AUTOFIX.WORD = context->keyboard.autofix;
|
||||
SH7305_KEYSC.SCAN_MODE.WORD = context->keyboard.scan_mode;
|
||||
SH7305_KEYSC.SCAN_STATE.WORD = context->keyboard.scan_state;
|
||||
SH7305_KEYSC.INTERRUPT.WORD = context->keyboard.interrupt;
|
||||
SH7305_KEYSC.SCAN_WAIT.WORD = context->keyboard.scan_wait;
|
||||
SH7305_KEYSC.SCAN_INTERVAL = context->keyboard.scan_interval;
|
||||
SH7305_KEYSC.KYOUTDR.WORD = context->keyboard.kyoutdr;
|
||||
SH7305_KEYSC.KYINDR.WORD = context->keyboard.kyindr;
|
||||
|
||||
// Restore Interrupt Controller (INTC)
|
||||
SH7305_INTC.IPRA.WORD = context->intc.ipra;
|
||||
SH7305_INTC.IPRB.WORD = context->intc.iprb;
|
||||
SH7305_INTC.IPRC.WORD = context->intc.iprc;
|
||||
SH7305_INTC.IPRD.WORD = context->intc.iprd;
|
||||
SH7305_INTC.IPRE.WORD = context->intc.ipre;
|
||||
SH7305_INTC.IPRF.WORD = context->intc.iprf;
|
||||
SH7305_INTC.IPRG.WORD = context->intc.iprg;
|
||||
SH7305_INTC.IPRH.WORD = context->intc.iprh;
|
||||
SH7305_INTC.IPRI.WORD = context->intc.ipri;
|
||||
SH7305_INTC.IPRJ.WORD = context->intc.iprj;
|
||||
SH7305_INTC.IPRK.WORD = context->intc.iprk;
|
||||
SH7305_INTC.IPRL.WORD = context->intc.iprl;
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
#include <kernel/context.h>
|
||||
#include <kernel/hardware/keysc.h>
|
||||
#include <kernel/hardware/power.h>
|
||||
#include <kernel/hardware/intc.h>
|
||||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/util/extra.h>
|
||||
|
||||
void fx9860_context_save(fx9860_context_t *context)
|
||||
{
|
||||
// Save Interrupt Controller (INTC)
|
||||
context->intc.ipra = SH7305_INTC.IPRA.WORD;
|
||||
context->intc.iprb = SH7305_INTC.IPRB.WORD;
|
||||
context->intc.iprc = SH7305_INTC.IPRC.WORD;
|
||||
context->intc.iprd = SH7305_INTC.IPRD.WORD;
|
||||
context->intc.ipre = SH7305_INTC.IPRE.WORD;
|
||||
context->intc.iprf = SH7305_INTC.IPRF.WORD;
|
||||
context->intc.iprg = SH7305_INTC.IPRG.WORD;
|
||||
context->intc.iprh = SH7305_INTC.IPRH.WORD;
|
||||
context->intc.ipri = SH7305_INTC.IPRI.WORD;
|
||||
context->intc.iprj = SH7305_INTC.IPRJ.WORD;
|
||||
context->intc.iprk = SH7305_INTC.IPRK.WORD;
|
||||
context->intc.iprl = SH7305_INTC.IPRL.WORD;
|
||||
|
||||
// Save Key Scan (KEYSC) context.
|
||||
context->keyboard.control = SH7305_KEYSC.CONTROL.WORD;
|
||||
context->keyboard.autofix = SH7305_KEYSC.AUTOFIX.WORD;
|
||||
context->keyboard.scan_mode = SH7305_KEYSC.SCAN_MODE.WORD;
|
||||
context->keyboard.scan_state = SH7305_KEYSC.SCAN_STATE.WORD;
|
||||
context->keyboard.interrupt = SH7305_KEYSC.INTERRUPT.WORD;
|
||||
context->keyboard.scan_wait = SH7305_KEYSC.SCAN_WAIT.WORD;
|
||||
context->keyboard.scan_interval = SH7305_KEYSC.SCAN_INTERVAL;
|
||||
context->keyboard.kyoutdr = SH7305_KEYSC.KYOUTDR.WORD;
|
||||
context->keyboard.kyindr = SH7305_KEYSC.KYINDR.WORD;
|
||||
|
||||
// Save power context.
|
||||
context->power.stbcr = SH7305_POWER.STBCR.LONG_WORD;
|
||||
context->power.mstpcr0 = SH7305_POWER.MSTPCR0.LONG_WORD;
|
||||
context->power.mstpcr1 = SH7305_POWER.MSTPCR1.LONG_WORD;
|
||||
context->power.mstpcr2 = SH7305_POWER.MSTPCR2.LONG_WORD;
|
||||
|
||||
// Save TMU context.
|
||||
context->tmu.tstr = SH7305_TMU.TSTR.BYTE;
|
||||
SH7305_TMU.TSTR.BYTE = 0x00; // stop all timer.
|
||||
context->tmu.timer[0].tcor = SH7305_TMU.TIMER[0].TCOR;
|
||||
context->tmu.timer[0].tcnt = SH7305_TMU.TIMER[0].TCNT;
|
||||
context->tmu.timer[0].tcr = SH7305_TMU.TIMER[0].TCR.WORD;
|
||||
context->tmu.timer[1].tcor = SH7305_TMU.TIMER[1].TCOR;
|
||||
context->tmu.timer[1].tcnt = SH7305_TMU.TIMER[1].TCNT;
|
||||
context->tmu.timer[1].tcr = SH7305_TMU.TIMER[1].TCR.WORD;
|
||||
context->tmu.timer[2].tcor = SH7305_TMU.TIMER[2].TCOR;
|
||||
context->tmu.timer[2].tcnt = SH7305_TMU.TIMER[2].TCNT;
|
||||
context->tmu.timer[2].tcr = SH7305_TMU.TIMER[2].TCR.WORD;
|
||||
|
||||
// Save current VBR.
|
||||
context->vbr = (uint32_t)vbr_get();
|
||||
}
|
||||
|
|
@ -1,10 +1,7 @@
|
|||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
#include <kernel/drivers/keyboard.h>
|
||||
#include <kernel/drivers/timer.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/context.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <kernel/signal.h>
|
||||
#include <sys/signal.h>
|
||||
#include <pthread.h>
|
||||
|
|
|
@ -43,13 +43,10 @@ void tty_keyboard_check_signal(struct tty *tty)
|
|||
}
|
||||
|
||||
|
||||
//TODO update ?
|
||||
//TODO update me
|
||||
//@note: Call this function ONLY if the device is locked !!
|
||||
int tty_keyboard_check_special(struct tty *tty, key_t key)
|
||||
{
|
||||
extern fx9860_context_t casio_context;
|
||||
extern fx9860_context_t vhex_context;
|
||||
|
||||
// Check CTRL key (KEY_OPT)
|
||||
if (key == KEY_OPTN) {
|
||||
tty->keyboard.mode.ctrl = 1;
|
||||
|
@ -81,25 +78,8 @@ int tty_keyboard_check_special(struct tty *tty, key_t key)
|
|||
}
|
||||
|
||||
// Check MENU key.
|
||||
// TODO: fix me !
|
||||
if (key == KEY_MENU)
|
||||
{
|
||||
// Save current Vhex context and restore Casio's context.
|
||||
atomic_start();
|
||||
fx9860_context_save(&vhex_context);
|
||||
fx9860_context_restore(&casio_context);
|
||||
atomic_stop();
|
||||
|
||||
// Inject MENU key and call GetKey().
|
||||
// FIXME !!!
|
||||
//casio_GetKeyWait(&row, &column, 0, 0, 0, &key);
|
||||
casio_GetKey(&key);
|
||||
|
||||
// Save current Casio's context and restore Vhex's context.
|
||||
atomic_start();
|
||||
fx9860_context_save(&casio_context);
|
||||
fx9860_context_restore(&vhex_context);
|
||||
atomic_stop();
|
||||
if (key == KEY_MENU) {
|
||||
casio_return_menu(0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#include <kernel/drivers/cpg.h>
|
||||
#include <kernel/hardware/cpg.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
#include <kernel/bits/driver.h>
|
||||
|
||||
// Internal struct
|
||||
struct cpg cpg_info;
|
||||
|
||||
__attribute__((constructor))
|
||||
static void cpg_init(void)
|
||||
// @note: we just get the frequencies
|
||||
static void sh7305_cpg_driver_install(void)
|
||||
{
|
||||
// Calculate FLL frequency (Khz)
|
||||
// @note: RCLK = 32 768 Hz
|
||||
|
@ -27,7 +27,8 @@ static void cpg_init(void)
|
|||
|
||||
|
||||
// Debug
|
||||
earlyterm_write("Calibrate frequencies...\n");
|
||||
// TODO: device
|
||||
/*earlyterm_write("Calibrate frequencies...\n");
|
||||
earlyterm_write(
|
||||
"* FLL freq: %d.%d Mhz\n"
|
||||
"* PLL freq: %d.%d Mhz\n"
|
||||
|
@ -39,6 +40,18 @@ static void cpg_init(void)
|
|||
cpg_info.cpu_freq / 1000000, (((cpg_info.cpu_freq - ((cpg_info.cpu_freq / 1000000)) * 1000000)) + 999) / 1000,
|
||||
cpg_info.bus_freq / 1000000, (((cpg_info.bus_freq - ((cpg_info.bus_freq / 1000000)) * 1000000)) + 999) / 1000,
|
||||
cpg_info.per_freq / 1000000, (((cpg_info.per_freq - ((cpg_info.per_freq / 1000000)) * 1000000)) + 999) / 1000
|
||||
);
|
||||
DBG_WAIT;
|
||||
);*/
|
||||
}
|
||||
|
||||
static void sh7305_cpg_driver_uninstall(void)
|
||||
{
|
||||
// Nothing for now
|
||||
}
|
||||
|
||||
// Create driver object
|
||||
VHEX_DRIVER(2, driver_cpg_sh7305) = {
|
||||
.arch = MPU_SH7305,
|
||||
.install = &sh7305_cpg_driver_install,
|
||||
.uninstall = &sh7305_cpg_driver_uninstall,
|
||||
.name = "cpg"
|
||||
};
|
|
@ -0,0 +1,138 @@
|
|||
#include <kernel/hardware/intc.h>
|
||||
#include <kernel/bits/driver.h>
|
||||
|
||||
// Internal hardware context
|
||||
struct __sh7305_intc_context intc_context;
|
||||
|
||||
static void sh7305_intc_driver_install(void)
|
||||
{
|
||||
// Dump current context
|
||||
intc_context.ipra = SH7305_INTC.IPRA.WORD;
|
||||
intc_context.iprb = SH7305_INTC.IPRB.WORD;
|
||||
intc_context.iprc = SH7305_INTC.IPRC.WORD;
|
||||
intc_context.iprd = SH7305_INTC.IPRD.WORD;
|
||||
intc_context.ipre = SH7305_INTC.IPRE.WORD;
|
||||
intc_context.iprf = SH7305_INTC.IPRF.WORD;
|
||||
intc_context.iprg = SH7305_INTC.IPRG.WORD;
|
||||
intc_context.iprh = SH7305_INTC.IPRH.WORD;
|
||||
intc_context.ipri = SH7305_INTC.IPRI.WORD;
|
||||
intc_context.iprj = SH7305_INTC.IPRJ.WORD;
|
||||
intc_context.iprk = SH7305_INTC.IPRK.WORD;
|
||||
intc_context.iprl = SH7305_INTC.IPRL.WORD;
|
||||
intc_context.imr[0] = SH7305_INTC.IMR0.BYTE;
|
||||
intc_context.imr[1] = SH7305_INTC.IMR1.BYTE;
|
||||
intc_context.imr[2] = SH7305_INTC.IMR2.BYTE;
|
||||
intc_context.imr[3] = SH7305_INTC.IMR3.BYTE;
|
||||
intc_context.imr[4] = SH7305_INTC.IMR4.BYTE;
|
||||
intc_context.imr[5] = SH7305_INTC.IMR5.BYTE;
|
||||
intc_context.imr[6] = SH7305_INTC.IMR6.BYTE;
|
||||
intc_context.imr[7] = SH7305_INTC.IMR7.BYTE;
|
||||
intc_context.imr[8] = SH7305_INTC.IMR8.BYTE;
|
||||
intc_context.imr[9] = SH7305_INTC.IMR9.BYTE;
|
||||
intc_context.imr[10] = SH7305_INTC.IMR10.BYTE;
|
||||
intc_context.imr[11] = SH7305_INTC.IMR11.BYTE;
|
||||
intc_context.icr[0] = SH7305_INTC.ICR0.WORD;
|
||||
intc_context.icr[1] = SH7305_INTC.ICR1.WORD;
|
||||
intc_context.intpri00 = SH7305_INTC.INTPRI00.LONG_WORD;
|
||||
intc_context.intreq00 = SH7305_INTC.INTREQ00.BYTE;
|
||||
intc_context.intmsk00 = SH7305_INTC.INTMSK00.BYTE;
|
||||
intc_context.intmskclr00 = SH7305_INTC.INTMSKCLR00.BYTE;
|
||||
intc_context.nmifcr = SH7305_INTC.NMIFCR.WORD;
|
||||
intc_context.usermsk = SH7305_INTC.USERMSK.LONG_WORD;
|
||||
|
||||
// Initialize Interrupt Controller (INTC).
|
||||
SH7305_INTC.IPRA.WORD = 0x0000;
|
||||
SH7305_INTC.IPRB.WORD = 0x0000;
|
||||
SH7305_INTC.IPRC.WORD = 0x0000;
|
||||
SH7305_INTC.IPRD.WORD = 0x0000;
|
||||
SH7305_INTC.IPRE.WORD = 0x0000;
|
||||
SH7305_INTC.IPRF.WORD = 0x0000;
|
||||
SH7305_INTC.IPRG.WORD = 0x0000;
|
||||
SH7305_INTC.IPRH.WORD = 0x0000;
|
||||
SH7305_INTC.IPRI.WORD = 0x0000;
|
||||
SH7305_INTC.IPRJ.WORD = 0x0000;
|
||||
SH7305_INTC.IPRK.WORD = 0x0000;
|
||||
SH7305_INTC.IPRL.WORD = 0x0000;
|
||||
|
||||
SH7305_INTC.IMR0.BYTE = 0xff;
|
||||
SH7305_INTC.IMR1.BYTE = 0xff;
|
||||
SH7305_INTC.IMR2.BYTE = 0xff;
|
||||
SH7305_INTC.IMR3.BYTE = 0xff;
|
||||
SH7305_INTC.IMR4.BYTE = 0xff;
|
||||
SH7305_INTC.IMR5.BYTE = 0xff;
|
||||
SH7305_INTC.IMR6.BYTE = 0xff;
|
||||
SH7305_INTC.IMR7.BYTE = 0xff;
|
||||
SH7305_INTC.IMR8.BYTE = 0xff;
|
||||
SH7305_INTC.IMR9.BYTE = 0xff;
|
||||
SH7305_INTC.IMR10.BYTE = 0xff;
|
||||
SH7305_INTC.IMR11.BYTE = 0xff;
|
||||
|
||||
SH7305_INTC.ICR0.NMIL = 0; // NMI input level to low
|
||||
SH7305_INTC.ICR0.MAI = 1; // disable NMI interrupt when input is low
|
||||
SH7305_INTC.ICR0.NMIB = 0; // keep NMI interrupt pending when BL bit is set
|
||||
SH7305_INTC.ICR0.NMIE = 0; // select faling edge interrupt
|
||||
SH7305_INTC.ICR0.LVLMODE = 1; // retain interrupt request
|
||||
SH7305_INTC.ICR1.WORD = 0x0000; // select (all) interrupt request on falling edge
|
||||
SH7305_INTC.INTPRI00.LONG_WORD = 0x00000000; // disable all interrupt request
|
||||
SH7305_INTC.INTMSK00.BYTE = 0x00; // mask all interrupt request
|
||||
SH7305_INTC.NMIFCR.NMIFL = 0; // clear NMI flags
|
||||
|
||||
SH7305_INTC.USERMSK.SECRET = 0xa5; // secret
|
||||
SH7305_INTC.USERMSK.UIMASK = 0b0000; // enable all interrupt in user mode (not used here)
|
||||
}
|
||||
|
||||
static void sh7305_intc_driver_uninstall(void)
|
||||
{
|
||||
SH7305_INTC.IPRA.WORD = intc_context.ipra;
|
||||
SH7305_INTC.IPRB.WORD = intc_context.iprb;
|
||||
SH7305_INTC.IPRC.WORD = intc_context.iprc;
|
||||
SH7305_INTC.IPRD.WORD = intc_context.iprd;
|
||||
SH7305_INTC.IPRE.WORD = intc_context.ipre;
|
||||
SH7305_INTC.IPRF.WORD = intc_context.iprf;
|
||||
SH7305_INTC.IPRG.WORD = intc_context.iprg;
|
||||
SH7305_INTC.IPRH.WORD = intc_context.iprh;
|
||||
SH7305_INTC.IPRI.WORD = intc_context.ipri;
|
||||
SH7305_INTC.IPRJ.WORD = intc_context.iprj;
|
||||
SH7305_INTC.IPRK.WORD = intc_context.iprk;
|
||||
SH7305_INTC.IPRL.WORD = intc_context.iprl;
|
||||
SH7305_INTC.IMR0.BYTE = intc_context.imr[0];
|
||||
SH7305_INTC.IMR1.BYTE = intc_context.imr[1];
|
||||
SH7305_INTC.IMR2.BYTE = intc_context.imr[2];
|
||||
SH7305_INTC.IMR3.BYTE = intc_context.imr[3];
|
||||
SH7305_INTC.IMR4.BYTE = intc_context.imr[4];
|
||||
SH7305_INTC.IMR5.BYTE = intc_context.imr[5];
|
||||
SH7305_INTC.IMR6.BYTE = intc_context.imr[6];
|
||||
SH7305_INTC.IMR7.BYTE = intc_context.imr[7];
|
||||
SH7305_INTC.IMR8.BYTE = intc_context.imr[8];
|
||||
SH7305_INTC.IMR9.BYTE = intc_context.imr[9];
|
||||
SH7305_INTC.IMR10.BYTE = intc_context.imr[10];
|
||||
SH7305_INTC.IMR11.BYTE = intc_context.imr[11];
|
||||
SH7305_INTC.IMCR0.BYTE = ~intc_context.imr[0];
|
||||
SH7305_INTC.IMCR1.BYTE = ~intc_context.imr[1];
|
||||
SH7305_INTC.IMCR2.BYTE = ~intc_context.imr[2];
|
||||
SH7305_INTC.IMCR3.BYTE = ~intc_context.imr[3];
|
||||
SH7305_INTC.IMCR4.BYTE = ~intc_context.imr[4];
|
||||
SH7305_INTC.IMCR5.BYTE = ~intc_context.imr[5];
|
||||
SH7305_INTC.IMCR6.BYTE = ~intc_context.imr[6];
|
||||
SH7305_INTC.IMCR7.BYTE = ~intc_context.imr[7];
|
||||
SH7305_INTC.IMCR8.BYTE = ~intc_context.imr[8];
|
||||
SH7305_INTC.IMCR9.BYTE = ~intc_context.imr[9];
|
||||
SH7305_INTC.IMCR10.BYTE = intc_context.imr[10];
|
||||
SH7305_INTC.IMCR11.BYTE = intc_context.imr[11];
|
||||
SH7305_INTC.ICR0.WORD = intc_context.icr[0];
|
||||
SH7305_INTC.ICR1.WORD = intc_context.icr[1];
|
||||
SH7305_INTC.INTPRI00.LONG_WORD = intc_context.intpri00;
|
||||
SH7305_INTC.INTREQ00.BYTE = intc_context.intreq00;
|
||||
SH7305_INTC.INTMSK00.BYTE = intc_context.intmsk00;
|
||||
SH7305_INTC.INTMSKCLR00.BYTE = intc_context.intmskclr00;
|
||||
SH7305_INTC.NMIFCR.WORD = intc_context.nmifcr;
|
||||
SH7305_INTC.USERMSK.LONG_WORD = intc_context.usermsk;
|
||||
}
|
||||
|
||||
// Create driver object
|
||||
VHEX_DRIVER(2, driver_intc_sh7305) = {
|
||||
.arch = MPU_SH7305,
|
||||
.install = &sh7305_intc_driver_install,
|
||||
.uninstall = &sh7305_intc_driver_uninstall,
|
||||
.name = "cpg"
|
||||
};
|
|
@ -1,34 +0,0 @@
|
|||
#include <kernel/drivers/keyboard.h>
|
||||
|
||||
/*
|
||||
** Internal cache, used like chained list.
|
||||
**
|
||||
** @note:
|
||||
** The KEYSC have 6 key data 16-bits registers
|
||||
** this is why we used 6 * 16 = 96 cache slot.
|
||||
*/
|
||||
struct keycache_s keycache[96];
|
||||
struct keycache_s *keylist;
|
||||
|
||||
/*
|
||||
** keycache_init()
|
||||
**
|
||||
** @info
|
||||
** Constructor used by the kernel during the
|
||||
** bootstrap part. It will initialize keycache
|
||||
** and the chained list.
|
||||
** This function sould not be called anymore.
|
||||
*/
|
||||
__attribute__((constructor))
|
||||
static void keycache_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 96;
|
||||
while (--i >= 0)
|
||||
{
|
||||
keycache[i].keycode = KEY_UNUSED;
|
||||
keycache[i].next = NULL;
|
||||
}
|
||||
keylist = NULL;
|
||||
}
|
|
@ -1,47 +1,40 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel/drivers/keyboard.h>
|
||||
#include <kernel/drivers/vbr.h>
|
||||
#include <kernel/hardware/keysc.h>
|
||||
#include <kernel/hardware/intc.h>
|
||||
#include <kernel/hardware/power.h>
|
||||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/util/extra.h>
|
||||
#include <kernel/bits/driver.h>
|
||||
|
||||
void vhex_context_set(void)
|
||||
// Internal module functions
|
||||
extern void sh7305_keysc_int_handler(void);
|
||||
|
||||
// Internal hardware context
|
||||
struct __sh7305_keysc_context keysc_context;
|
||||
|
||||
// Configure Key Scan (KEYSC)
|
||||
static void sh7305_keysc_driver_install(void)
|
||||
{
|
||||
extern uint32_t vhex_vbr;
|
||||
|
||||
// Initialize Interrupt Controller (INTC).
|
||||
SH7305_INTC.IPRA.WORD = 0x0000;
|
||||
SH7305_INTC.IPRB.WORD = 0x0000;
|
||||
SH7305_INTC.IPRC.WORD = 0x0000;
|
||||
SH7305_INTC.IPRD.WORD = 0x0000;
|
||||
SH7305_INTC.IPRE.WORD = 0x0000;
|
||||
SH7305_INTC.IPRF.WORD = 0x0000;
|
||||
SH7305_INTC.IPRG.WORD = 0x0000;
|
||||
SH7305_INTC.IPRH.WORD = 0x0000;
|
||||
SH7305_INTC.IPRI.WORD = 0x0000;
|
||||
SH7305_INTC.IPRJ.WORD = 0x0000;
|
||||
SH7305_INTC.IPRK.WORD = 0x0000;
|
||||
SH7305_INTC.IPRL.WORD = 0x0000;
|
||||
|
||||
// Switch VBR
|
||||
// @note:
|
||||
// The VBR swtich *SHOULD* be atomic
|
||||
// because one exepction / interrupt will
|
||||
// crash the calculator.
|
||||
vbr_set(&vhex_vbr);
|
||||
|
||||
// Configure Key Scan (KEYSC)
|
||||
// Mask interrupt (requered)
|
||||
SH7305_INTC.IMR5.KEYI = 1; // Mask KEYSC interrupt.
|
||||
SH7305_INTC.IPRF.KEYSC = 0; // Disable KEYSC interrupt.
|
||||
SH7305_TMU.TIMER[0].TCOR = 0xffffffff; // Disable Timer 2
|
||||
|
||||
// Save current keysc context
|
||||
keysc_context.control = SH7305_KEYSC.CONTROL.WORD;
|
||||
keysc_context.autofix = SH7305_KEYSC.AUTOFIX.WORD;
|
||||
keysc_context.scan_mode = SH7305_KEYSC.SCAN_MODE.WORD;
|
||||
keysc_context.scan_state = SH7305_KEYSC.SCAN_STATE.WORD;
|
||||
keysc_context.interrupt = SH7305_KEYSC.INTERRUPT.WORD;
|
||||
keysc_context.scan_wait = SH7305_KEYSC.SCAN_WAIT.WORD;
|
||||
keysc_context.scan_interval = SH7305_KEYSC.SCAN_INTERVAL;
|
||||
keysc_context.kyoutdr = SH7305_KEYSC.KYOUTDR.WORD;
|
||||
keysc_context.kyindr = SH7305_KEYSC.KYINDR.WORD;
|
||||
|
||||
// Intialize key scan interface
|
||||
SH7305_KEYSC.CONTROL.KEYIE = 1; // Enable KEYSC interrupt.
|
||||
SH7305_KEYSC.CONTROL.INTMODE = 0b00; // Use default (?) interrupt mode.
|
||||
SH7305_KEYSC.AUTOFIX.ENABLE = 1; // Enable key bounce fix (?)
|
||||
SH7305_KEYSC.AUTOFIX.UNKNOWN0 = 0b100; // Unknown, use Casio's value. (autofix)
|
||||
SH7305_KEYSC.AUTOFIX.UNKNOWN1 = 0b10; // Unknown, use Casio's value. (autofix)
|
||||
SH7305_KEYSC.SCAN_MODE.UNKNOWN = 0b001; // Unknown, use Casio's value. (scan mode)
|
||||
//SH7305_KEYSC.INTERRUPT.KYCPU_IE = 0b0000100; // Interrupt when keys are pressed or released.
|
||||
SH7305_KEYSC.INTERRUPT.KYCPU_IE = 0b0000010; // Falling + pressed + rising.
|
||||
SH7305_KEYSC.SCAN_WAIT.TIME = 0x05; // No time between each interrupt.
|
||||
SH7305_KEYSC.SCAN_INTERVAL = 0x98; // Unknown, use Casio's value. (scan interval)
|
||||
|
@ -57,28 +50,42 @@ void vhex_context_set(void)
|
|||
SH7305_KEYSC.KYINDR.KYDIR3 = 1; // Scan [F4],[MENU],[EXIT],[sin],[)],[DEL],[x],[+],[(-)]
|
||||
SH7305_KEYSC.KYINDR.KYDIR2 = 1; // Scan [F5],[left],[down],[cos],[,],[%],[-],[EXE]
|
||||
SH7305_KEYSC.KYINDR.KYDIR1 = 1; // Scan [F6],[up],[right],[tan],[->]
|
||||
|
||||
// Install the interrupt handler
|
||||
vbr_interrupt_set(INT_CODE_KEYSC, &sh7305_keysc_int_handler);
|
||||
|
||||
// Initialize high level abstractions
|
||||
keycache_initialize();
|
||||
|
||||
// Enable interrupt
|
||||
SH7305_INTC.IPRF.KEYSC = 10; // Set KEYSC interrupt priority (max).
|
||||
SH7305_INTC.IMCR5.KEYI = 1; // Clear KEYSC interrupt mask.
|
||||
|
||||
// Configure power / sleep mode.
|
||||
SH7305_POWER.STBCR.LONG_WORD = 0x00000000;
|
||||
//SH7305_POWER.STBCR.STBY = 1;
|
||||
//TODO: handle real-power on.
|
||||
|
||||
// Configure TMU.
|
||||
SH7305_TMU.TSTR.BYTE = 0x00; // Stop all timer
|
||||
for (int i = 0 ; i < 3 ; i = i + 1)
|
||||
{
|
||||
SH7305_TMU.TIMER[i].TCOR = 0xffffffff; // Reset Timer
|
||||
SH7305_TMU.TIMER[i].TCOR = 0xffffffff; // Reset Timer
|
||||
SH7305_TMU.TIMER[i].TCR.UNF = 0; // Clear interrupt flag.
|
||||
SH7305_TMU.TIMER[i].TCR.UNIE = 0; // Disable interrupt.
|
||||
SH7305_TMU.TIMER[i].TCR.TPSC = 0b0000; // Select clock deviser.
|
||||
}
|
||||
SH7305_INTC.IPRA.TMU0_0 = 12;
|
||||
SH7305_INTC.IPRA.TMU0_1 = 12;
|
||||
SH7305_INTC.IPRA.TMU0_2 = 12;
|
||||
SH7305_INTC.IMCR4.TUNI2 = 1;
|
||||
SH7305_INTC.IMCR4.TUNI1 = 1;
|
||||
SH7305_INTC.IMCR4.TUNI0 = 1;
|
||||
}
|
||||
|
||||
// Restore old context
|
||||
// @note: the interrupt priority will be restored by the INTC driver
|
||||
static void sh7305_keysc_driver_uninstall(void)
|
||||
{
|
||||
// Mask interrupt (requered)
|
||||
SH7305_INTC.IMR5.KEYI = 1;
|
||||
SH7305_INTC.IPRF.KEYSC = 0;
|
||||
|
||||
// Restore keysc context
|
||||
SH7305_KEYSC.CONTROL.WORD = keysc_context.control;
|
||||
SH7305_KEYSC.AUTOFIX.WORD = keysc_context.autofix;
|
||||
SH7305_KEYSC.SCAN_MODE.WORD = keysc_context.scan_mode;
|
||||
SH7305_KEYSC.SCAN_STATE.WORD = keysc_context.scan_state;
|
||||
SH7305_KEYSC.INTERRUPT.WORD = keysc_context.interrupt;
|
||||
SH7305_KEYSC.SCAN_WAIT.WORD = keysc_context.scan_wait;
|
||||
SH7305_KEYSC.SCAN_INTERVAL = keysc_context.scan_interval;
|
||||
SH7305_KEYSC.KYOUTDR.WORD = keysc_context.kyoutdr;
|
||||
SH7305_KEYSC.KYINDR.WORD = keysc_context.kyindr;
|
||||
}
|
||||
|
||||
// Create driver object
|
||||
VHEX_DRIVER(4, driver_keyboard_sh7305) = {
|
||||
.arch = MPU_SH7305,
|
||||
.install = &sh7305_keysc_driver_install,
|
||||
.uninstall = &sh7305_keysc_driver_uninstall,
|
||||
.name = "keysc"
|
||||
};
|
|
@ -1,15 +1,12 @@
|
|||
#include <kernel/drivers/keyboard.h>
|
||||
#include <kernel/hardware/keysc.h>
|
||||
#include <kernel/hardware/intc.h>
|
||||
|
||||
// Internal functions
|
||||
extern void keycache_update(int row, int column, uint8_t key_frame);
|
||||
extern void keycache_clean(uint8_t key_frame);
|
||||
|
||||
// Device internal indicator to
|
||||
// avoid reentrace with the key list.
|
||||
volatile uint8_t keylist_isUpdate = 0;
|
||||
|
||||
void keysc_handler(void)
|
||||
void sh7305_keysc_int_handler(void)
|
||||
{
|
||||
static uint8_t key_frame = 0;
|
||||
int column;
|
|
@ -1,6 +1,38 @@
|
|||
#include <kernel/drivers/keyboard.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
|
||||
/*
|
||||
** Internal cache, used like chained list.
|
||||
**
|
||||
** @note:
|
||||
** The KEYSC have 6 key data 16-bits registers
|
||||
** this is why we used 6 * 16 = 96 cache slot.
|
||||
*/
|
||||
struct keycache_s keycache[96];
|
||||
struct keycache_s *keylist;
|
||||
|
||||
/*
|
||||
** keycache_init()
|
||||
**
|
||||
** @info
|
||||
** Constructor used by the kernel during the
|
||||
** bootstrap part. It will initialize keycache
|
||||
** and the chained list.
|
||||
** This function sould not be called anymore.
|
||||
*/
|
||||
void keycache_initialize(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 96;
|
||||
while (--i >= 0)
|
||||
{
|
||||
keycache[i].keycode = KEY_UNUSED;
|
||||
keycache[i].next = NULL;
|
||||
}
|
||||
keylist = NULL;
|
||||
}
|
||||
|
||||
/* keycache_alloc() - Try to alloc a new keycache node */
|
||||
static struct keycache_s *keycache_alloc(void)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
#include <kernel/hardware/power.h>
|
||||
#include <kernel/bits/driver.h>
|
||||
#include <kernel/util/extra.h>
|
||||
#include <string.h>
|
||||
|
||||
// Internal globals for abstractions
|
||||
struct __sh7305_power_context vhex_power_context;
|
||||
struct __sh7305_power_context casio_power_context;
|
||||
int power_driver_is_installed = 0;
|
||||
|
||||
// TODO: save area before dump ?
|
||||
static void power_driver_install(void)
|
||||
{
|
||||
// Save current context (Casio)
|
||||
casio_power_context.stbcr = SH7305_POWER.STBCR.LONG_WORD;
|
||||
casio_power_context.mstpcr[0] = SH7305_POWER.MSTPCR0.LONG_WORD;
|
||||
casio_power_context.mstpcr[1] = SH7305_POWER.MSTPCR1.LONG_WORD;
|
||||
casio_power_context.mstpcr[2] = SH7305_POWER.MSTPCR2.LONG_WORD;
|
||||
casio_power_context.bar = SH7305_POWER.BAR;
|
||||
|
||||
// Check if we need to install the default Vhex context
|
||||
if (power_driver_is_installed != 0)
|
||||
{
|
||||
SH7305_POWER.STBCR.LONG_WORD = vhex_power_context.stbcr;
|
||||
SH7305_POWER.MSTPCR0.LONG_WORD = vhex_power_context.mstpcr[0];
|
||||
SH7305_POWER.MSTPCR1.LONG_WORD = vhex_power_context.mstpcr[1];
|
||||
SH7305_POWER.MSTPCR2.LONG_WORD = vhex_power_context.mstpcr[2];
|
||||
SH7305_POWER.BAR = vhex_power_context.bar;
|
||||
icbi((void*)0xa0000000);
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup new power context
|
||||
// Selecte SLEEP mode (the CPU is stopped but all
|
||||
// peripheral continue to operates)
|
||||
SH7305_POWER.STBCR.RSTBY = 0;
|
||||
SH7305_POWER.STBCR.STBY = 0;
|
||||
SH7305_POWER.STBCR.USTBY = 0;
|
||||
|
||||
// Start Vhex peripheral
|
||||
// @note: We can't stop peripherals that we don't
|
||||
// use because we don't known if Casio use them >_<
|
||||
SH7305_POWER.MSTPCR0.TLB = 0; // start TLB
|
||||
SH7305_POWER.MSTPCR0.IC = 0; // start instruction cache
|
||||
SH7305_POWER.MSTPCR0.OC = 0; // start operand cache
|
||||
SH7305_POWER.MSTPCR0.RS = 0; // start RS memory
|
||||
SH7305_POWER.MSTPCR0.IL = 0; // start IL memroy
|
||||
SH7305_POWER.MSTPCR0.SC = 0; // start secondary cache
|
||||
SH7305_POWER.MSTPCR0.INTC = 0; // start interrupt controller
|
||||
SH7305_POWER.MSTPCR0.TMU0 = 0; // start Timer Unit 0
|
||||
SH7305_POWER.MSTPCR1.KEYSC = 0; // start Key Scan Interface
|
||||
SH7305_POWER.MSTPCR1.RTC = 0; // start Real Time Clock
|
||||
SH7305_POWER.MSTPCR2.LCD = 0; // start LCD module
|
||||
|
||||
// Force CPU update
|
||||
icbi((void*)0xa0000000);
|
||||
|
||||
// Indicate that the driver is installed
|
||||
power_driver_is_installed = 1;
|
||||
}
|
||||
|
||||
static void power_driver_uninstall(void)
|
||||
{
|
||||
// Save current context (Vhex)
|
||||
vhex_power_context.stbcr = SH7305_POWER.STBCR.LONG_WORD;
|
||||
vhex_power_context.mstpcr[0] = SH7305_POWER.MSTPCR0.LONG_WORD;
|
||||
vhex_power_context.mstpcr[1] = SH7305_POWER.MSTPCR1.LONG_WORD;
|
||||
vhex_power_context.mstpcr[2] = SH7305_POWER.MSTPCR2.LONG_WORD;
|
||||
vhex_power_context.bar = SH7305_POWER.BAR;
|
||||
|
||||
// Restore Casio context
|
||||
SH7305_POWER.STBCR.LONG_WORD = casio_power_context.stbcr;
|
||||
SH7305_POWER.MSTPCR0.LONG_WORD = casio_power_context.mstpcr[0];
|
||||
SH7305_POWER.MSTPCR1.LONG_WORD = casio_power_context.mstpcr[1];
|
||||
SH7305_POWER.MSTPCR2.LONG_WORD = casio_power_context.mstpcr[2];
|
||||
SH7305_POWER.BAR = casio_power_context.bar;
|
||||
|
||||
// Force CPU update
|
||||
icbi((void*)0xa0000000);
|
||||
}
|
||||
|
||||
// Create driver object
|
||||
VHEX_DRIVER(1, driver_power) = {
|
||||
.arch = MPU_SH7305,
|
||||
.install = &power_driver_install,
|
||||
.uninstall = &power_driver_uninstall,
|
||||
.name = "power"
|
||||
};
|
|
@ -1,21 +0,0 @@
|
|||
#include <kernel/drivers/screen.h>
|
||||
|
||||
// Internal drivers
|
||||
extern void t6k11_variant_lcd_driver(void *vram);
|
||||
extern void t6k11_lcd_driver(void *vram);
|
||||
|
||||
// Primitives
|
||||
void (*screen_driver)(void *vram);
|
||||
|
||||
__attribute__((constructor))
|
||||
void screen_driver_load(void)
|
||||
{
|
||||
// Check T6K11 variant which appear during
|
||||
// the OS >= 03.00.0000
|
||||
if (*(uint8_t*)0xa0010021 == '3') {
|
||||
screen_driver = (void*)&t6k11_variant_lcd_driver;
|
||||
return;
|
||||
}
|
||||
// Default driver
|
||||
screen_driver = &t6k11_lcd_driver;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#include <kernel/drivers/screen.h>
|
||||
#include <kernel/bits/driver.h>
|
||||
|
||||
// Internal drivers
|
||||
extern void t6k11_variant_lcd_driver(void *vram);
|
||||
extern void t6k11_lcd_driver(void *vram);
|
||||
|
||||
//TODO: save screen context !!
|
||||
static void t6k11_driver_install(void)
|
||||
{
|
||||
extern void (*screen_driver)(void *vram);
|
||||
|
||||
// The T6K11 variant which appear during
|
||||
// the OS >= 03.00.0000, so check it
|
||||
// @note: The OS version is stored at 0xa0010021
|
||||
// TODO: get the OS version properly !!
|
||||
if (*(uint8_t*)0xa0010021 == '3') {
|
||||
screen_driver = (void*)&t6k11_variant_lcd_driver;
|
||||
return;
|
||||
}
|
||||
|
||||
// Default driver
|
||||
screen_driver = &t6k11_lcd_driver;
|
||||
}
|
||||
|
||||
static void t6k11_driver_uninstall(void)
|
||||
{
|
||||
//FIXME: restore screen context !!!
|
||||
}
|
||||
|
||||
// Create driver object
|
||||
VHEX_DRIVER(4, driver_screen_t6k11) = {
|
||||
.arch = MPU_SH7305,
|
||||
.install = &t6k11_driver_install,
|
||||
.uninstall = &t6k11_driver_uninstall,
|
||||
.name = "t6k11"
|
||||
};
|
|
@ -1,11 +1,10 @@
|
|||
#include <kernel/drivers/screen.h>
|
||||
|
||||
// Driver install indicator
|
||||
void (*screen_driver)(void *vram) = NULL;
|
||||
|
||||
void screen_update(void *vram)
|
||||
{
|
||||
extern void (*screen_driver)(void *vram);
|
||||
|
||||
// Check driver validity
|
||||
if (screen_driver == NULL)
|
||||
return;
|
||||
screen_driver(vram);
|
||||
if (screen_driver != NULL)
|
||||
screen_driver(vram);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include <kernel/drivers/timer.h>
|
||||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
|
||||
// Internal timer "cache".
|
||||
|
@ -26,22 +25,6 @@ void timer_constructor(void)
|
|||
timercache[i].arg = NULL;
|
||||
}
|
||||
|
||||
// Configure TMU
|
||||
SH7305_TMU.TSTR.STR0 = 0; // Stop timer 0
|
||||
SH7305_TMU.TSTR.STR1 = 0; // Stop timer 1
|
||||
SH7305_TMU.TSTR.STR2 = 0; // Stop timer 2
|
||||
|
||||
// Configure TMU timers
|
||||
for (int i = 0 ; i < 3 ; ++i)
|
||||
{
|
||||
SH7305_TMU.TIMER[i].TCOR = 0xffffffff; // Reset timer constant register
|
||||
SH7305_TMU.TIMER[i].TCNT = 0xffffffff; // Reset timer counter
|
||||
SH7305_TMU.TIMER[i].TCR.UNF = 0; // Clear interrupt flags
|
||||
SH7305_TMU.TIMER[i].TCR.UNIE = 0; // Disable timerinterrupt
|
||||
SH7305_TMU.TIMER[i].TCR.CKREG = 0b00; // Count on rising edge
|
||||
SH7305_TMU.TIMER[i].TCR.TPSC = 0b000; // Select P/4 prescaler
|
||||
}
|
||||
|
||||
// Stop atomic operations
|
||||
atomic_stop();
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ int timer_install(void *callback, void *arg, int hertz, tmode_t mode)
|
|||
// Calculate real ticks needed
|
||||
// FIXME: correct ticks calculation (remove / 2 ?)
|
||||
ticks = cpg_get_frequency(CPG_PERIPHERAL) / 2;
|
||||
ticks = ticks / prescaler[SH7305_TMU.TIMER[timerID].TCR.TPSC];
|
||||
ticks = ticks / prescaler[SH7305_TMU.TIMER[timerID].TCR.TPSC];
|
||||
ticks = ticks / hertz;
|
||||
|
||||
// Setup Timer
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
#include <kernel/drivers/screen.h>
|
||||
#include <kernel/drivers/vbr.h>
|
||||
#include <kernel/hardware/intc.h>
|
||||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/bits/driver.h>
|
||||
|
||||
// Internal handlers
|
||||
extern void sh7305_tmu_handler(void);
|
||||
|
||||
// Internal hardware context
|
||||
struct __sh7305_tmu_context casio_tmu_context;
|
||||
struct __sh7305_tmu_context vhex_tmu_context;
|
||||
int tmu_driver_is_installed = 0;
|
||||
|
||||
static void tmu_driver_install(void)
|
||||
{
|
||||
// Save current TMU timer's status and stop all
|
||||
casio_tmu_context.tstr = SH7305_TMU.TSTR.BYTE;
|
||||
SH7305_TMU.TSTR.BYTE = 0x00; // Stop all timer
|
||||
|
||||
// Configure TMU.
|
||||
for (int i = 0 ; i < 3 ; ++i)
|
||||
{
|
||||
// Save timmer context
|
||||
casio_tmu_context.timer[i].tcor = SH7305_TMU.TIMER[i].TCOR;
|
||||
casio_tmu_context.timer[i].tcnt = SH7305_TMU.TIMER[i].TCNT;
|
||||
casio_tmu_context.timer[i].tcr = SH7305_TMU.TIMER[i].TCR.WORD;
|
||||
|
||||
// Re-install driver if possible
|
||||
if (tmu_driver_is_installed != 0)
|
||||
{
|
||||
SH7305_TMU.TIMER[i].TCOR = vhex_tmu_context.timer[i].tcor;
|
||||
SH7305_TMU.TIMER[i].TCNT = vhex_tmu_context.timer[i].tcnt;
|
||||
SH7305_TMU.TIMER[i].TCR.WORD = vhex_tmu_context.timer[i].tcr;
|
||||
} else {
|
||||
SH7305_TMU.TIMER[i].TCOR = 0xffffffff; // Reset Timer
|
||||
SH7305_TMU.TIMER[i].TCOR = 0xffffffff; // Reset Timer
|
||||
SH7305_TMU.TIMER[i].TCR.UNF = 0; // Clear interrupt flag.
|
||||
SH7305_TMU.TIMER[i].TCR.UNIE = 0; // Disable interrupt.
|
||||
SH7305_TMU.TIMER[i].TCR.TPSC = 0b0000; // Select clock deviser.
|
||||
}
|
||||
}
|
||||
|
||||
// Install interrupt handlers for each timer
|
||||
vbr_interrupt_set(INT_CODE_TMU0_TUNI0, &sh7305_tmu_handler);
|
||||
vbr_interrupt_set(INT_CODE_TMU0_TUNI1, &sh7305_tmu_handler);
|
||||
vbr_interrupt_set(INT_CODE_TMU0_TUNI2, &sh7305_tmu_handler);
|
||||
|
||||
// Set interruptions priority
|
||||
SH7305_INTC.IPRA.TMU0_0 = 12;
|
||||
SH7305_INTC.IPRA.TMU0_1 = 12;
|
||||
SH7305_INTC.IPRA.TMU0_2 = 12;
|
||||
|
||||
// Enable interruptions
|
||||
SH7305_INTC.IMCR4.TUNI2 = 1;
|
||||
SH7305_INTC.IMCR4.TUNI1 = 1;
|
||||
SH7305_INTC.IMCR4.TUNI0 = 1;
|
||||
|
||||
// Restart timer if possible
|
||||
if (tmu_driver_is_installed != 0)
|
||||
SH7305_TMU.TSTR.BYTE = vhex_tmu_context.tstr;
|
||||
|
||||
// Indicate that the driver has been installed
|
||||
tmu_driver_is_installed = 1;
|
||||
}
|
||||
|
||||
// Restore context
|
||||
static void tmu_driver_uninstall(void)
|
||||
{
|
||||
// Save Vhex TMU timer's status and stop all
|
||||
vhex_tmu_context.tstr = SH7305_TMU.TSTR.BYTE;
|
||||
SH7305_TMU.TSTR.BYTE = 0x00;
|
||||
|
||||
for (int i = 0; i < 3 ; ++i)
|
||||
{
|
||||
// Save timer context (Vhex)
|
||||
vhex_tmu_context.timer[i].tcor = SH7305_TMU.TIMER[i].TCOR;
|
||||
vhex_tmu_context.timer[i].tcnt = SH7305_TMU.TIMER[i].TCNT;
|
||||
vhex_tmu_context.timer[i].tcr = SH7305_TMU.TIMER[i].TCR.WORD;
|
||||
|
||||
// Restore Casio's TMU context
|
||||
SH7305_TMU.TIMER[i].TCOR = casio_tmu_context.timer[i].tcor;
|
||||
SH7305_TMU.TIMER[i].TCNT = casio_tmu_context.timer[i].tcnt;
|
||||
SH7305_TMU.TIMER[i].TCR.WORD = casio_tmu_context.timer[i].tcr;
|
||||
}
|
||||
|
||||
// Restart timer
|
||||
SH7305_TMU.TSTR.BYTE = casio_tmu_context.tstr;
|
||||
}
|
||||
|
||||
// Create driver object
|
||||
VHEX_DRIVER(3, driver_tmu) = {
|
||||
.arch = MPU_SH7305,
|
||||
.install = &tmu_driver_install,
|
||||
.uninstall = &tmu_driver_uninstall,
|
||||
.name = "tmu"
|
||||
};
|
|
@ -1,10 +1,9 @@
|
|||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/drivers/timer.h>
|
||||
|
||||
void timer_handler(void)
|
||||
void sh7305_tmu_handler(void)
|
||||
{
|
||||
extern struct timer_cache_s timercache[TIMER_NUMBER];
|
||||
//static uint32_t counter = 0;
|
||||
uint32_t intevt;
|
||||
int timer_ID;
|
||||
|
||||
|
@ -14,22 +13,12 @@ void timer_handler(void)
|
|||
intevt = *(uint32_t*)0xff000028;
|
||||
timer_ID = (intevt - 0x400) / 0x20;
|
||||
|
||||
/*if (intevt != 0x400)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "Timer ID: %d\n", timer_ID);
|
||||
printk(0, 1, "Interrupt: %#x\n", intevt);
|
||||
printk(0, 2, "counter: %d\n", counter++);
|
||||
kvram_display();
|
||||
}*/
|
||||
|
||||
// Clear interrupt flags.
|
||||
SH7305_TMU.TIMER[timer_ID].TCR.UNF = 0;
|
||||
|
||||
// Execute callback if possible.
|
||||
if (timercache[timer_ID].status != TIMER_UNUSED &&
|
||||
timercache[timer_ID].callback != NULL)
|
||||
{
|
||||
timercache[timer_ID].callback != NULL) {
|
||||
((void (*)(volatile void *))timercache[timer_ID].callback)(timercache[timer_ID].arg);
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#include <kernel/drivers/vbr.h>
|
||||
#include <kernel/bits/driver.h>
|
||||
#include <string.h>
|
||||
|
||||
// Internal globals for abstractions
|
||||
void (*int_handler[VBR_INTERRUPT_NB])(void);
|
||||
int vbr_driver_is_installed = 0;
|
||||
void *old_vbr;
|
||||
|
||||
// TODO: save area before dump ?
|
||||
static void vbr_driver_install(void)
|
||||
{
|
||||
extern uint32_t vhex_vbr;
|
||||
extern uint32_t bvhex_ram;
|
||||
extern uint32_t bvhex_rom;
|
||||
extern uint32_t svhex;
|
||||
|
||||
// Save and switch the VBR
|
||||
// @note: The VBR swtich *SHOULD* be atomic because
|
||||
// one exepction / interrupt will crash the calculator.
|
||||
old_vbr = vbr_set(&vhex_vbr);
|
||||
|
||||
// Check if the VBR driver is already installed
|
||||
if (vbr_driver_is_installed != 0)
|
||||
return;
|
||||
|
||||
// Dump VBR handlers (interrupt and exception)
|
||||
memcpy(&bvhex_ram, &bvhex_rom, (size_t)&svhex);
|
||||
|
||||
// Initialize pseudo-abtraction
|
||||
// TODO: Find better way to do the job
|
||||
for (int i = 0 ; i < VBR_INTERRUPT_NB ; ++i)
|
||||
int_handler[i] = NULL;
|
||||
|
||||
// Indicate that the driver is installed
|
||||
vbr_driver_is_installed = 1;
|
||||
}
|
||||
|
||||
static void vbr_driver_uninstall(void)
|
||||
{
|
||||
// restore old VBR
|
||||
vbr_set(old_vbr);
|
||||
}
|
||||
|
||||
// Create driver object
|
||||
VHEX_DRIVER(3, driver_vbr) = {
|
||||
.arch = MPU_SH7305,
|
||||
.install = &vbr_driver_install,
|
||||
.uninstall = &vbr_driver_uninstall,
|
||||
.name = "vbr"
|
||||
};
|
|
@ -1,35 +1,56 @@
|
|||
#include <kernel/drivers/vbr.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
|
||||
// Handler prototype.
|
||||
extern void keysc_handler(void);
|
||||
extern void timer_handler(void);
|
||||
|
||||
// TODO: update me
|
||||
void interrupt_handler(void)
|
||||
{
|
||||
extern void (*int_handler[VBR_INTERRUPT_NB])(void);
|
||||
uint32_t intevt = *(uint32_t*)0xff000028;
|
||||
int id;
|
||||
|
||||
// Get the interrupt ID
|
||||
VBR_GET_INTERRUPT_CODE(id, intevt);
|
||||
|
||||
// Check KEYSC interrupt.
|
||||
if (intevt == 0xbe0)
|
||||
// Check id validity and handler error
|
||||
if (id < 0 || id >= VBR_INTERRUPT_NB || int_handler[id] == NULL)
|
||||
{
|
||||
keysc_handler();
|
||||
return;
|
||||
}
|
||||
if (intevt == 0x400 ||
|
||||
intevt == 0x410 ||
|
||||
intevt == 0x420)
|
||||
{
|
||||
timer_handler();
|
||||
return;
|
||||
earlyterm_write(
|
||||
"Ho crap ! Interrupt error !\n"
|
||||
"Interrupt ID (%#x)\n"
|
||||
"Error: handler not foud !\n",
|
||||
intevt
|
||||
);
|
||||
while (1);
|
||||
}
|
||||
|
||||
// Display error.
|
||||
earlyterm_clear();
|
||||
earlyterm_write(
|
||||
"Ho crap ! Interrupt error !\n"
|
||||
"Interrupt ID (%#x)\n"
|
||||
"Error: handler not foud !\n",
|
||||
intevt
|
||||
);
|
||||
while (1);
|
||||
// Call handler and exit
|
||||
(*int_handler[id])();
|
||||
}
|
||||
|
||||
void *vbr_interrupt_set(int intcode, void (*handler)(void))
|
||||
{
|
||||
extern void (*int_handler[VBR_INTERRUPT_NB])(void);
|
||||
void *old;
|
||||
int id;
|
||||
|
||||
// Get the interrupt ID
|
||||
VBR_GET_INTERRUPT_CODE(id, intcode);
|
||||
|
||||
// Check id validity
|
||||
if (id < 0 || id >= VBR_INTERRUPT_NB)
|
||||
return (NULL);
|
||||
|
||||
// Start atomic operations
|
||||
atomic_start();
|
||||
|
||||
// Switch interupt handler
|
||||
old = int_handler[id];
|
||||
int_handler[id] = handler;
|
||||
|
||||
// Stop atomic operations
|
||||
atomic_stop();
|
||||
|
||||
// Return old interrupt handler
|
||||
return (old);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
#include <kernel/devices/earlyterm.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
|
||||
// Kernel FS block
|
||||
// Casio SMEM FileSystem primitives
|
||||
// @note: We use USB PowerGraphic 2 primitives
|
||||
struct file_system_type smemfs_filesystem =
|
||||
{
|
||||
// internal informations
|
||||
|
@ -12,22 +13,23 @@ struct file_system_type smemfs_filesystem =
|
|||
|
||||
// FS specific openrations
|
||||
.filesystem_operations = {
|
||||
.mount = &smemfs_mount,
|
||||
.umount = &smemfs_umount
|
||||
.mount = &smemfs_USB2_mount,
|
||||
.umount = &smemfs_USB2_umount
|
||||
},
|
||||
|
||||
// File operations
|
||||
.file_operations = {
|
||||
.read = &smemfs_read,
|
||||
.write = NULL
|
||||
.read = &smemfs_USB2_read,
|
||||
.write = NULL,
|
||||
.ioctl = NULL
|
||||
},
|
||||
|
||||
// Inode operations
|
||||
.inode_operations = {
|
||||
// Walk
|
||||
.find_next_sibling = &smemfs_find_next_sibling,
|
||||
.find_first_child = &smemfs_find_first_child,
|
||||
.find_parent = &smemfs_find_parent,
|
||||
.find_next_sibling = &smemfs_USB2_find_next_sibling,
|
||||
.find_first_child = &smemfs_USB2_find_first_child,
|
||||
.find_parent = &smemfs_USB2_find_parent,
|
||||
|
||||
// Memory
|
||||
.create = NULL,
|
||||
|
@ -36,13 +38,32 @@ struct file_system_type smemfs_filesystem =
|
|||
.rename = NULL,
|
||||
|
||||
// Informations
|
||||
.get_name = &smemfs_get_name,
|
||||
.get_mode = &smemfs_get_mode
|
||||
.get_name = &smemfs_USB2_get_name,
|
||||
.get_mode = &smemfs_USB2_get_mode
|
||||
}
|
||||
};
|
||||
|
||||
// Internal superblock informations
|
||||
struct smemfs_superblock_s smemfs_superblock;
|
||||
|
||||
|
||||
// switch USB Power Graphic II driver to
|
||||
// USB Power Graphic III (Casio syscall wrapper)
|
||||
static void use_dump_smem_driver(void)
|
||||
{
|
||||
/* smemfs_filesystem.filesystem_operations.mount = &smemfs_USB3_mount;
|
||||
smemfs_filesystem.filesystem_operations.umount = &smemfs_USB3_umount;
|
||||
smemfs_filesystem.file_operations.read = &smemfs_USB3_read;
|
||||
smemfs_filesystem.inode_operations.find_next_sibling = &smemfs_USB3_find_next_sibling;
|
||||
smemfs_filesystem.inode_operations.find_first_child = &smemfs_USB3_find_first_child;
|
||||
smemfs_filesystem.inode_operations.find_parent = &smemfs_USB3_find_parent;
|
||||
smemfs_filesystem.inode_operations.get_name = &smemfs_USB3_get_name;
|
||||
smemfs_filesystem.inode_operations.get_mode = &smemfs_USB3_get_mode;
|
||||
smemfs_superblock.sector_table = NULL;
|
||||
smemfs_superblock.inode_table = NULL;*/
|
||||
while (1);
|
||||
}
|
||||
|
||||
void smemfs_initialize(void)
|
||||
{
|
||||
// Start atomic operations
|
||||
|
@ -56,11 +77,8 @@ void smemfs_initialize(void)
|
|||
smemfs_superblock.sector_table = (void *)0xa0270000;
|
||||
if (smemfs_superblock.sector_table->magic_start != CASIO_SMEM_BLOCK_ENTRY_MAGIC)
|
||||
{
|
||||
earlyterm_clear();
|
||||
earlyterm_write("SMEMFS: Casio sector table error !");
|
||||
earlyterm_write("Wait manual reset...");
|
||||
atomic_stop();
|
||||
while (1){ __asm__ volatile ("sleep"); }
|
||||
return (use_dump_smem_driver());
|
||||
}
|
||||
|
||||
// Try to find Casio SMEM inode table start always at the end of
|
||||
|
@ -76,11 +94,8 @@ void smemfs_initialize(void)
|
|||
smemfs_superblock.inode_table->parent.id != 0xffff ||
|
||||
smemfs_superblock.inode_table->parent.type != 0xffff)
|
||||
{
|
||||
earlyterm_clear();
|
||||
earlyterm_write("SMEMFS: Casio inode table error !");
|
||||
earlyterm_write("Wait manual reset...");
|
||||
atomic_stop();
|
||||
while (1){ __asm__ volatile ("sleep"); }
|
||||
return (use_dump_smem_driver());
|
||||
}
|
||||
|
||||
// Stop atomic operations
|
||||
|
|
|
@ -24,7 +24,7 @@ static void *casio_smem_get_data_base_address(smemfs_fragdata_t *fragment)
|
|||
}
|
||||
|
||||
/* casio_smem_read() - Read the file data (based on internal cursor) */
|
||||
ssize_t smemfs_read(void *inode, void *buf, size_t count, off_t pos)
|
||||
ssize_t smemfs_USB2_read(void *inode, void *buf, size_t count, off_t pos)
|
||||
{
|
||||
smemfs_fragdata_t *fragment;
|
||||
smemfs_header_t *header;
|
||||
|
@ -33,9 +33,6 @@ ssize_t smemfs_read(void *inode, void *buf, size_t count, off_t pos)
|
|||
size_t current_size;
|
||||
size_t real_size;
|
||||
|
||||
//earlyterm_write("pos = %#x\n", pos);
|
||||
//DBG_WAIT;
|
||||
|
||||
// Get Check obvious error.
|
||||
if (inode == NULL || buf == NULL)
|
||||
return (-1);
|
||||
|
@ -66,7 +63,6 @@ ssize_t smemfs_read(void *inode, void *buf, size_t count, off_t pos)
|
|||
if (fragment->magic != CASIO_SMEM_FRAGMENT_MAGIC ||
|
||||
fragment->info != CASIO_SMEM_FRAGMENT_INFO_EXIST)
|
||||
{
|
||||
atomic_stop();
|
||||
earlyterm_write("smemfs: fragment error !\n");
|
||||
earlyterm_write("* current_size = %d\n", current_size);
|
||||
earlyterm_write("* pos = %#x\n", pos);
|
||||
|
@ -75,6 +71,7 @@ ssize_t smemfs_read(void *inode, void *buf, size_t count, off_t pos)
|
|||
DBG_WAIT;
|
||||
DBG_WAIT;
|
||||
DBG_WAIT;
|
||||
atomic_stop();
|
||||
return (-1);
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
#include <kernel/util/atomic.h>
|
||||
|
||||
/* casio_smem_mount() - Mount the file system (sync) */
|
||||
void *smemfs_mount(void)
|
||||
void *smemfs_USB2_mount(void)
|
||||
{
|
||||
extern struct smemfs_superblock_s smemfs_superblock;
|
||||
void *root_inode;
|
|
@ -1,7 +1,7 @@
|
|||
#include <kernel/fs/smemfs.h>
|
||||
|
||||
/* casio_smem_umount() - Unmount the File System */
|
||||
int smemfs_umount(void)
|
||||
int smemfs_USB2_umount(void)
|
||||
{
|
||||
// Do nothing for now
|
||||
return (0);
|
|
@ -2,7 +2,7 @@
|
|||
#include <kernel/util/atomic.h>
|
||||
|
||||
/* smemfs_find_first_child() - Find the fist file in the (folder) inode (sync) */
|
||||
void *smemfs_find_first_child(void *inode)
|
||||
void *smemfs_USB2_find_first_child(void *inode)
|
||||
{
|
||||
extern struct smemfs_superblock_s smemfs_superblock;
|
||||
uint16_t folder_id;
|
||||
|
@ -33,7 +33,7 @@ void *smemfs_find_first_child(void *inode)
|
|||
}
|
||||
|
||||
// Return the first child of the file.
|
||||
child_inode = smemfs_walk(inode, smemfs_superblock.inode_table,
|
||||
child_inode = smemfs_USB2_walk(inode, smemfs_superblock.inode_table,
|
||||
folder_id, WALK_FLAG_ID_CHECK_PARENT);
|
||||
|
||||
// Stop atomic operation
|
|
@ -2,7 +2,7 @@
|
|||
#include <kernel/util/atomic.h>
|
||||
|
||||
/* smemfs_find_next_sibling() - Find the next file from the same parent (sync) */
|
||||
void *smemfs_find_next_sibling(void *inode)
|
||||
void *smemfs_USB2_find_next_sibling(void *inode)
|
||||
{
|
||||
extern struct smemfs_superblock_s smemfs_superblock;
|
||||
void *sibling_inode;
|
||||
|
@ -27,7 +27,7 @@ void *smemfs_find_next_sibling(void *inode)
|
|||
folder_id = ((struct casio_smem_header_s *)inode)->parent.id;
|
||||
|
||||
// Return the next file of the directory.
|
||||
sibling_inode = smemfs_walk(inode, inode, folder_id, WALK_FLAG_ID_CHECK_PARENT);
|
||||
sibling_inode = smemfs_USB2_walk(inode, inode, folder_id, WALK_FLAG_ID_CHECK_PARENT);
|
||||
|
||||
// Stop atomic operation
|
||||
atomic_stop();
|
|
@ -2,7 +2,7 @@
|
|||
#include <kernel/util/atomic.h>
|
||||
|
||||
/* smemfs_find_parent() - Return the parent inode */
|
||||
void *smemfs_find_parent(void *inode)
|
||||
void *smemfs_USB2_find_parent(void *inode)
|
||||
{
|
||||
extern struct smemfs_superblock_s smemfs_superblock;
|
||||
void *parent_inode;
|
||||
|
@ -27,7 +27,7 @@ void *smemfs_find_parent(void *inode)
|
|||
folder_id = ((struct casio_smem_header_s *)inode)->parent.id;
|
||||
|
||||
// Return first inode find
|
||||
parent_inode = smemfs_walk(inode, smemfs_superblock.inode_table, folder_id,
|
||||
parent_inode = smemfs_USB2_walk(inode, smemfs_superblock.inode_table, folder_id,
|
||||
WALK_FLAG_ID_CHECK_DIRECTORY);
|
||||
|
||||
// Stop atomic operation
|
|
@ -3,7 +3,7 @@
|
|||
#include <kernel/util/atomic.h>
|
||||
|
||||
/* smemfs_get_mode() - Return the permission dans the type of a file (sync) */
|
||||
mode_t smemfs_get_mode(void *inode)
|
||||
mode_t smemfs_USB2_get_mode(void *inode)
|
||||
{
|
||||
extern struct smemfs_superblock_s smemfs_superblock;
|
||||
struct casio_smem_header_s *header;
|
|
@ -2,7 +2,7 @@
|
|||
#include <kernel/util/atomic.h>
|
||||
|
||||
/* smemfs_get_name() - Dump the name of a file (sync) */
|
||||
int smemfs_get_name(void *inode, char *buf, size_t count)
|
||||
int smemfs_USB2_get_name(void *inode, char *buf, size_t count)
|
||||
{
|
||||
extern struct smemfs_superblock_s smemfs_superblock;
|
||||
struct casio_smem_header_s *header;
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
/* smemfs_walk() - Find inode based on directory ID and flags */
|
||||
/* @note: This function is internal of smemFS, do not call it ! */
|
||||
smemfs_inode_t *smemfs_walk(smemfs_inode_t *current,
|
||||
smemfs_inode_t *smemfs_USB2_walk(smemfs_inode_t *current,
|
||||
smemfs_inode_t *file, uint16_t folder_id, int flags)
|
||||
{
|
||||
smemfs_fragdata_t *fragdata;
|
|
@ -0,0 +1,29 @@
|
|||
#include <kernel/fs/smemfs.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
|
||||
/*
|
||||
** smemfs_USB3_mount() - Mount the file system (sync)
|
||||
** @note:
|
||||
** We don't known how the file system work, so we should use
|
||||
** Casio's "Bfile_*" sycalls to dump all internal informations
|
||||
** to avoid OS switch (Vhex -> Casio -> Vhex)
|
||||
*/
|
||||
void *smemfs_USB3_mount(void)
|
||||
{
|
||||
extern struct smemfs_superblock_s smemfs_superblock;
|
||||
void *root_inode = NULL;
|
||||
|
||||
// Start atomic operation
|
||||
atomic_start();
|
||||
|
||||
//TODO
|
||||
//TODO Use Bfile_FindFirst and Bfile_Find_Next to dump
|
||||
//TODO All internal FS informations
|
||||
//TODO
|
||||
|
||||
// Stop atomic operation
|
||||
atomic_stop();
|
||||
|
||||
// Return the sector table to simulate the root inode.
|
||||
return (root_inode);
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
#include <kernel/context.h>
|
||||
/*#include <kernel/bits/context.h>
|
||||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
// Test
|
||||
uint32_t counter = 0;
|
||||
|
||||
void sched_debug(common_context_t *context_current, common_context_t *context_next)
|
||||
void sched_debug(struct cpu_context *context_current, struct cpu_context *context_next)
|
||||
{
|
||||
extern uint32_t sched_timer_id;
|
||||
extern uint32_t sched_timer_address;
|
||||
|
@ -33,4 +33,4 @@ void sched_debug(common_context_t *context_current, common_context_t *context_ne
|
|||
earlyterm_write("TCOR: %#x", tcor);
|
||||
earlyterm_write("TCNT: %#x", tcnt);
|
||||
earlyterm_write("TCR: %#x", tcr);
|
||||
}
|
||||
}*/
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#include <kernel/scheduler.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
#include <kernel/process.h>
|
||||
#include <kernel/signal.h>
|
||||
|
||||
//TODO: assembly ?
|
||||
//TODO: preemptive handling !!
|
||||
// @note: This part *SHOULD* be exeption safe !
|
||||
int sched_schedule(common_context_t **context_current, common_context_t **context_next)
|
||||
int sched_schedule(struct cpu_context **context_current, struct cpu_context **context_next)
|
||||
{
|
||||
extern struct sched_task *sched_task_current;
|
||||
extern struct sched_task *sched_task_queue;
|
||||
|
|
|
@ -40,11 +40,12 @@ void sched_start(void)
|
|||
sched_timer_tstr_bit = 1 << sched_timer_id;
|
||||
|
||||
// Debug
|
||||
//earlyterm_write("* timer ID: %d\n", sched_timer_id);
|
||||
//earlyterm_write("* timer addr: %#x\n", sched_timer_address);
|
||||
//earlyterm_write("* timer event: %#x\n", sched_timer_intevt);
|
||||
//earlyterm_write("* timer TSTR: %#x\n", sched_timer_tstr_bit);
|
||||
//DBG_WAIT;
|
||||
/*earlyterm_write("* timer ID: %d\n", sched_timer_id);
|
||||
earlyterm_write("* timer addr: %#x\n", sched_timer_address);
|
||||
earlyterm_write("* timer event: %#x\n", sched_timer_intevt);
|
||||
earlyterm_write("* timer TSTR: %#x\n", sched_timer_tstr_bit);
|
||||
DBG_WAIT;
|
||||
while (1);*/
|
||||
|
||||
// Start scheduler timer
|
||||
timer_start(sched_timer_id);
|
||||
|
|
|
@ -10,7 +10,7 @@ static void sys_test(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
|
|||
earlyterm_write("* b = %#x\n", b);
|
||||
earlyterm_write("* c = %#x\n", c);
|
||||
earlyterm_write("* d = %#x\n", d);
|
||||
DBG_WAIT;
|
||||
while (1);
|
||||
}
|
||||
|
||||
static const void *sys_handler[__NR_MAX] = {
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
#include <kernel/util/casio.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/bits/context.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
// Internal bootstrap primitives
|
||||
extern void bootstrap_drivers_install(void);
|
||||
extern void bootstrap_drivers_uninstall(void);
|
||||
|
||||
// Internal informations
|
||||
int casio_timer_id;
|
||||
|
||||
static void casio_keycode_inject(void)
|
||||
{
|
||||
uint16_t keycode;
|
||||
|
||||
keycode = 0x308;
|
||||
casio_Bkey_PutKeymatrix(&keycode);
|
||||
casio_TimerUninstall(casio_timer_id);
|
||||
}
|
||||
|
||||
//@note:
|
||||
// * mode 0 - Involve menu manually
|
||||
// * mode 1 - Use GetKey_wait
|
||||
// FIXME: WAIT DMA transfert !!
|
||||
void casio_return_menu(int mode)
|
||||
{
|
||||
unsigned int keycode;
|
||||
int row;
|
||||
int col;
|
||||
|
||||
// unistall / restore all drivers
|
||||
bootstrap_drivers_uninstall();
|
||||
|
||||
// If we should involve main menu manually
|
||||
// we need to setup one timer which will inject
|
||||
// Casio's [MENU] keycode to force the GetKey_wait syscall
|
||||
// to return in main menu
|
||||
if (mode == 0) {
|
||||
casio_timer_id = casio_TimerInstall(0, &casio_keycode_inject, 25);
|
||||
casio_TimerStart(casio_timer_id);
|
||||
}
|
||||
|
||||
// Use GetKeyWait to wait key event (or keycode inject)
|
||||
do {
|
||||
casio_GetKeyWait(&row, &col, KEYWAIT_HALTON_TIMERON, 25, 0, &keycode);
|
||||
} while (mode == 1);
|
||||
|
||||
// Re-install Vhex drivers
|
||||
bootstrap_drivers_install();
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/*.text
|
||||
.global _casio_return_menu
|
||||
.type _casio_return_menu, @function
|
||||
|
||||
;;
|
||||
;; casio_return_menu(int mode) - return to the Casio menu
|
||||
;; mode 0 - involve menu manually
|
||||
;; mode 1 - use GetKeyWait and inf. loop
|
||||
;;
|
||||
_casio_return_menu:
|
||||
mov.l r8, @-r15
|
||||
sts.l pr, @-r15
|
||||
|
||||
! save the mode
|
||||
mov r4, r8
|
||||
|
||||
! Uninstall all drivers
|
||||
mov.l .bootstrap_drivers_uninstall, r0
|
||||
jsr @r0
|
||||
nop
|
||||
|
||||
! TODO
|
||||
! TODO Handle mode !!
|
||||
! TODO
|
||||
|
||||
! Save critical register
|
||||
sts.l mach, @-r15 ! get mach regsiter
|
||||
sts.l macl, @-r15 ! get macl regsiter
|
||||
stc.l gbr, @-r15 ! get gbr regsiter
|
||||
mov.l r14, @-r15 ! get r14 regsiter
|
||||
mov.l r13, @-r15 ! get r13 regsiter
|
||||
mov.l r12, @-r15 ! get r12 regsiter
|
||||
mov.l r11, @-r15 ! get r11 regsiter
|
||||
mov.l r10, @-r15 ! get r10 regsiter
|
||||
mov.l r9, @-r15 ! get r9 regsiter
|
||||
mov.l r8, @-r15 ! get r8 regsiter
|
||||
|
||||
! Save current stack
|
||||
mov.l .test_stack, r0
|
||||
mov.l r15, @r0
|
||||
|
||||
|
||||
! Call GetKeyWait(int *row, int *col, int mode,
|
||||
! int timeout, int menu, int *keycode)
|
||||
add #-4, r15 ! get space
|
||||
mov r15,r7 ! r7 = &keycode
|
||||
add #-4, r15 ! get space
|
||||
mov r15,r5 ! r5 = &col
|
||||
add #-4, r15 ! get space
|
||||
mov r15,r4 ! r4 = &row
|
||||
mov #0,r2 ! r2 = menu = 0 (press [MENU] return to the menu)
|
||||
mov.l r7,@-r15 ! place the keycode address into the seventh aguments position
|
||||
mov.l r2,@-r15 ! place the menu option into the sixth arguments position
|
||||
mov #0,r6 ! r6 = mode = 0 (KEYWAIT_HALTON_TIMEROFF)
|
||||
mov #0,r7 ! r7 = timeout = 0
|
||||
|
||||
GetKeyWait:
|
||||
mov.l .casio_GetKeyWait, r0 ! get GetKeyWait syscall
|
||||
jsr @r0 ! GetKeyWait(int*col, int*row, int waittype, int timeout, int menu,u16*key)
|
||||
nop
|
||||
|
||||
|
||||
!add #20, r15 ! restore stack
|
||||
mov.l .test_stack, r0
|
||||
mov.l @r0, r15
|
||||
|
||||
! Restore critical register
|
||||
mov.l @r15+, r8 ! set r8 regsiter
|
||||
mov.l @r15+, r9 ! set r9 regsiter
|
||||
mov.l @r15+, r10 ! set r10 regsiter
|
||||
mov.l @r15+, r11 ! set r11 regsiter
|
||||
mov.l @r15+, r12 ! set r12 regsiter
|
||||
mov.l @r15+, r13 ! set r13 regsiter
|
||||
mov.l @r15+, r14 ! set r14 regsiter
|
||||
ldc.l @r15+, gbr ! set gbr regsiter
|
||||
lds.l @r15+, macl ! set macl regsiter
|
||||
lds.l @r15+, mach ! set mach regsiter
|
||||
|
||||
! re-install all drivers
|
||||
mov.l .bootstrap_drivers_install, r0
|
||||
jsr @r0
|
||||
nop
|
||||
|
||||
! epilogue
|
||||
lds.l @r15+, pr
|
||||
rts
|
||||
nop
|
||||
|
||||
.align 4
|
||||
.bootstrap_drivers_install: .long _bootstrap_drivers_install
|
||||
.bootstrap_drivers_uninstall: .long _bootstrap_drivers_uninstall
|
||||
.casio_GetKeyWait: .long _casio_GetKeyWait
|
||||
.test_stack: .long _test_stack
|
||||
|
||||
.data
|
||||
.align 4
|
||||
.global _test_stack
|
||||
.type _test_stack, @object
|
||||
_test_stack: .long 0
|
||||
.end*/
|
|
@ -23,6 +23,10 @@
|
|||
.global _casio_WriteFile
|
||||
.global _casio_CloseFile
|
||||
|
||||
.global _casio_TimerInstall
|
||||
.global _casio_TimerUninstall
|
||||
.global _casio_TimerStart
|
||||
.global _casio_TimerStop
|
||||
|
||||
|
||||
|
||||
|
@ -51,6 +55,9 @@
|
|||
.type _casio_CloseFile, @function
|
||||
|
||||
|
||||
.type _casio_SetTimer, @function
|
||||
.type _casio_KillTimer, @function
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -174,8 +181,29 @@ _casio_CloseFile:
|
|||
nop
|
||||
|
||||
|
||||
_casio_TimerInstall:
|
||||
mov.l .syscall_entry, r1
|
||||
mov.l .sys_TimerInstall, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
_casio_TimerStart:
|
||||
mov.l .syscall_entry, r1
|
||||
mov.l .sys_TimerStart, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
_casio_TimerUninstall:
|
||||
mov.l .syscall_entry, r1
|
||||
mov.l .sys_TimerUninstall, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
_casio_TimerStop:
|
||||
mov.l .syscall_entry, r1
|
||||
mov.l .sys_TimerStop, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
.align 4
|
||||
.syscall_entry: .long 0x80010070
|
||||
|
@ -198,4 +226,8 @@ _casio_CloseFile:
|
|||
.sys_closeFile: .long 0x0000042d
|
||||
.sys_getkeywait: .long 0x00000247
|
||||
.sys_putKeycode: .long 0x0000024f
|
||||
.sys_TimerInstall: .long 0x00000118
|
||||
.sys_TimerUninstall: .long 0x00000119
|
||||
.sys_TimerStart: .long 0x0000011a
|
||||
.sys_TimerStop: .long 0x0000011b
|
||||
.end
|
||||
|
|
|
@ -47,6 +47,11 @@ SECTIONS
|
|||
. = ALIGN(4);
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
|
||||
/* Drivers */
|
||||
_bdrivers_section = ALIGN(4);
|
||||
*(SORT_BY_NAME(.driver.*));
|
||||
_edrivers_section = . ;
|
||||
|
||||
/* Constructors, destructors */
|
||||
_bctors = ALIGN(4) ;
|
||||
|
|
Loading…
Reference in New Issue