#ifndef _KERNEL_ARCH_M68K_CPU_H
#define _KERNEL_ARCH_M68K_CPU_H
#ifndef _ASSEMBLER
#include <arch/m68k/arch_thread_types.h>
#include <kernel.h>
#endif
#define CPU_MAX_CACHE_LEVEL 8
#define CACHE_LINE_SIZE 16
#define arch_cpu_enable_user_access()
#define arch_cpu_disable_user_access()
#define SR_IP_MASK 0x0700
#define SR_S 0x2000
#define M68K_SR_S 13
#define M68K_SR_T_MASK 0xC000
#define M68K_SR_T0 14
#define M68K_SR_T1 15
#ifndef _ASSEMBLER
struct mc68030_ssw {
uint16 fc:1;
uint16 fb:1;
uint16 rc:1;
uint16 rb:1;
uint16 :3;
uint16 df:1;
uint16 rm:1;
uint16 rw:1;
uint16 size:2;
uint16 :1;
uint16 as:3;
} _PACKED;
struct mc68040_ssw {
uint16 cp:1;
uint16 cu:1;
uint16 ct:1;
uint16 cm:1;
uint16 ma:1;
uint16 atc:1;
uint16 lk:1;
uint16 rw:1;
uint16 :1;
uint16 size:2;
uint16 tt:2;
uint16 tm:3;
} _PACKED;
struct mc68060_fslw {
uint32 :4;
uint32 ma:1;
uint32 :1;
uint32 lk:1;
uint32 rw:2;
uint32 size:2;
uint32 tt:2;
uint32 tm:2;
uint32 io:1;
uint32 pbe:1;
uint32 sbe:1;
uint32 pta:1;
uint32 ptb:1;
uint32 il:1;
uint32 pf:1;
uint32 sb:1;
uint32 wp:1;
uint32 twe:1;
uint32 re:1;
uint32 we:1;
uint32 ttr:1;
uint32 bpe:1;
uint32 :1;
uint32 see:1;
} _PACKED;
struct mc680x0_type_0_frame {
uint16 sr;
addr_t pc;
uint16 type:4;
uint16 vector:12;
};
struct mc680x0_type_1_frame {
uint16 sr;
addr_t pc;
uint16 type:4;
uint16 vector:12;
};
struct mc680x0_type_2_frame {
uint16 sr;
addr_t pc;
uint16 type:4;
uint16 vector:12;
addr_t instruction_address;
};
struct mc680x0_type_3_frame {
uint16 sr;
addr_t pc;
uint16 type:4;
uint16 vector:12;
addr_t effective_address;
};
struct mc68040_type_7_frame {
uint16 sr;
addr_t pc;
uint16 type:4;
uint16 vector:12;
addr_t effective_address;
struct mc68040_ssw ssw;
uint16 wb3s;
uint16 wb2s;
uint16 wb1s;
addr_t fault_address;
addr_t wb3a;
uint32 wb3d;
addr_t wb2a;
uint32 wb2d;
addr_t wb1a;
uint32 wb1d;
uint32 pd1;
uint32 pd2;
uint32 pd3;
};
struct mc680x0_type_9_frame {
uint16 sr;
addr_t pc;
uint16 type:4;
uint16 vector:12;
addr_t instruction_address;
uint16 intregs[4];
};
struct mc68030_type_a_frame {
uint16 sr;
addr_t pc;
uint16 type:4;
uint16 vector:12;
uint16 intreg1;
struct mc68030_ssw ssw;
uint16 instpipe_c;
uint16 instpipe_b;
addr_t fault_address;
uint16 intregs2[2];
uint32 dataout;
uint16 intregs3[2];
};
struct mc68030_type_b_frame {
uint16 sr;
addr_t pc;
uint16 type:4;
uint16 vector:12;
uint16 intreg1;
struct mc68030_ssw ssw;
uint16 instpipe_c;
uint16 instpipe_b;
addr_t fault_address;
uint16 intregs2[2];
uint32 dataout;
uint16 intregs3[4];
uint32 stbaddr;
uint16 intregs4[2];
uint32 datain;
uint16 intregs5[3];
uint16 intinfo;
uint16 intregs6[18];
};
struct mc680x0_frame {
union {
struct {
uint16 sr;
addr_t pc;
uint16 type:4;
uint16 vector:12;
};
struct mc680x0_type_0_frame type_0;
struct mc680x0_type_1_frame type_1;
struct mc680x0_type_3_frame type_3;
struct mc680x0_type_2_frame type_2;
struct mc68040_type_7_frame type_7;
struct mc680x0_type_9_frame type_9;
struct mc68030_type_a_frame type_a;
struct mc68030_type_b_frame type_b;
};
};
struct mc680x0_null_fpu_state {
uint8 version;
uint8 type;
uint16 dummy;
};
struct mc680x0_type_00_fpu_state {
uint8 version;
uint8 type;
uint16 dummy;
};
struct mc680x0_type_28_fpu_state {
uint8 version;
uint8 type;
uint16 dummy;
uint32 dummies[0x28/4];
};
struct mc680x0_type_60_fpu_state {
uint8 version;
uint8 type;
uint16 dummy;
uint32 dummies[0x60/4];
};
struct mc68882_type_d4_fpu_state {
uint8 version;
uint8 type;
uint16 dummy;
uint32 dummies[0xd4/4];
};
struct mc680x0_fpu_state {
union {
struct {
uint8 version;
uint8 type;
uint16 dummy;
};
struct mc680x0_null_fpu_state null;
struct mc680x0_type_00_fpu_state type_00;
struct mc680x0_type_28_fpu_state type_28;
struct mc680x0_type_60_fpu_state type_60;
struct mc68882_type_d4_fpu_state type_d4;
};
};
struct mc680x0_fp_data_reg {
uint8 data[12];
};
struct mc680x0_fp_control_regs {
uint32 fpcr;
uint32 fpsr;
uint32 fpiar;
};
#warning M68K: check for missing regs/movem
struct iframe {
#warning M68K: sizeof(fp*)
struct mc680x0_fp_data_reg fp[8];
struct mc680x0_fp_control_regs fpc;
struct mc680x0_fpu_state fpu;
uint32 d[8];
uint32 a[7];
struct mc680x0_frame cpu;
} _PACKED;
#if 0
enum machine_state {
MSR_EXCEPTIONS_ENABLED = 1L << 15,
MSR_PRIVILEGE_LEVEL = 1L << 14,
MSR_FP_AVAILABLE = 1L << 13,
MSR_MACHINE_CHECK_ENABLED = 1L << 12,
MSR_EXCEPTION_PREFIX = 1L << 6,
MSR_INST_ADDRESS_TRANSLATION = 1L << 5,
MSR_DATA_ADDRESS_TRANSLATION = 1L << 4,
};
#endif
typedef struct arch_cpu_info {
int null;
} arch_cpu_info;
#ifdef __cplusplus
extern "C" {
#endif
#if 0
extern uint32 get_sdr1(void);
extern void set_sdr1(uint32 value);
extern uint32 get_sr(void *virtualAddress);
extern void set_sr(void *virtualAddress, uint32 value);
extern uint32 get_msr(void);
extern uint32 set_msr(uint32 value);
extern uint32 get_pvr(void);
extern void set_ibat0(struct block_address_translation *bat);
extern void set_ibat1(struct block_address_translation *bat);
extern void set_ibat2(struct block_address_translation *bat);
extern void set_ibat3(struct block_address_translation *bat);
extern void set_dbat0(struct block_address_translation *bat);
extern void set_dbat1(struct block_address_translation *bat);
extern void set_dbat2(struct block_address_translation *bat);
extern void set_dbat3(struct block_address_translation *bat);
extern void get_ibat0(struct block_address_translation *bat);
extern void get_ibat1(struct block_address_translation *bat);
extern void get_ibat2(struct block_address_translation *bat);
extern void get_ibat3(struct block_address_translation *bat);
extern void get_dbat0(struct block_address_translation *bat);
extern void get_dbat1(struct block_address_translation *bat);
extern void get_dbat2(struct block_address_translation *bat);
extern void get_dbat3(struct block_address_translation *bat);
extern void reset_ibats(void);
extern void reset_dbats(void);
#endif
extern long long get_time_base(void);
void __m68k_setup_system_time(vint32 *cvFactor);
int64 __m68k_get_time_base(void);
extern void m68k_context_switch(void **_oldStackPointer, void *newStackPointer);
extern bool m68k_set_fault_handler(addr_t *handlerLocation, addr_t handler)
__attribute__((noinline));
extern bool m68k_is_hw_register_readable(addr_t address);
extern bool m68k_is_hw_register_writable(addr_t address, uint16 value);
static inline void
arch_cpu_idle(void)
{
}
static inline void
arch_cpu_pause(void)
{
}
#ifdef __cplusplus
}
#endif
struct m68k_cpu_ops {
void (*flush_insn_pipeline)(void);
void (*flush_atc_all)(void);
void (*flush_atc_user)(void);
void (*flush_atc_addr)(addr_t addr);
void (*flush_dcache)(addr_t address, size_t len);
void (*flush_icache)(addr_t address, size_t len);
void (*idle)(void);
};
extern struct m68k_cpu_ops cpu_ops;
#if 0
#define eieio() asm volatile("eieio")
#define isync() asm volatile("isync")
#define tlbsync() asm volatile("tlbsync")
#define ppc_sync() asm volatile("sync")
#define tlbia() asm volatile("tlbia")
#define tlbie(addr) asm volatile("tlbie %0" :: "r" (addr))
#endif
#if 0
enum m68k_processor_version {
CPU_68000 = 0x0000,
CPU_68010 = 0x0001,
CPU_68020 = 0x0002,
CPU_68030 = 0x0003,
CPU_68040 = 0x0004,
CPU_68060 = 0x0006,
CPU_MASK = 0x000F
};
enum m68k_fpu_version {
FPU_NONE = 0x0000,
FPU_68881 = 0x0010,
FPU_68882 = 0x0020,
FPU_030 = 0x0030,
FPU_040 = 0x0040,
FPU_060 = 0x0060,
FPU_MASK = 0x00F0
};
enum m68k_mmu_version {
MMU_NONE = 0x0000,
MMU_68551 = 0x0100,
MMU_68030 = 0x0300,
MMU_68040 = 0x0400,
MMU_68060 = 0x0600,
MMU_MASK = 0x0F00
};
#endif
extern int arch_cpu_type;
extern int arch_fpu_type;
extern int arch_mmu_type;
extern int arch_platform;
extern int arch_machine;
#endif
#endif