forked from KolibriOS/kolibrios
a03882245a
git-svn-id: svn://kolibrios.org@8327 a494cfbc-eb01-0410-851d-a64ba20cac60
174 lines
4.9 KiB
C
Executable File
174 lines
4.9 KiB
C
Executable File
#ifndef _CPU_H_
|
|
#define _CPU_H_
|
|
|
|
|
|
//#define ARM_V6 //define to allow v6 instructions
|
|
//#define THUMB_2 //define to allow Thumb2
|
|
|
|
#include "types.h"
|
|
|
|
struct ArmCpu;
|
|
|
|
#define ARM_SR_N 0x80000000UL
|
|
#define ARM_SR_Z 0x40000000UL
|
|
#define ARM_SR_C 0x20000000UL
|
|
#define ARM_SR_V 0x10000000UL
|
|
#define ARM_SR_Q 0x08000000UL
|
|
#ifdef ARM_V6 //V6KT2, but without T2 to be exact (we implement things like MLS, but not Thumb2 or ThumbEE)
|
|
#define ARM_SR_J 0x01000000UL
|
|
#define ARM_SR_E 0x00000200UL
|
|
#define ARM_SR_A 0x00000100UL
|
|
#define ARM_SR_GE_0 0x00010000UL
|
|
#define ARM_SR_GE_1 0x00020000UL
|
|
#define ARM_SR_GE_2 0x00040000UL
|
|
#define ARM_SR_GE_3 0x00080000UL
|
|
#define ARM_SR_GE_MASK 0x000F0000UL
|
|
#define ARM_SR_GE_SHIFT 16
|
|
#endif
|
|
#define ARM_SR_I 0x00000080UL
|
|
#define ARM_SR_F 0x00000040UL
|
|
#define ARM_SR_T 0x00000020UL
|
|
#define ARM_SR_M 0x0000001FUL
|
|
|
|
#define ARM_SR_MODE_USR 0x00000010UL
|
|
#define ARM_SR_MODE_FIQ 0x00000011UL
|
|
#define ARM_SR_MODE_IRQ 0x00000012UL
|
|
#define ARM_SR_MODE_SVC 0x00000013UL
|
|
#define ARM_SR_MODE_ABT 0x00000017UL
|
|
#define ARM_SR_MODE_UND 0x0000001BUL
|
|
#define ARM_SR_MODE_SYS 0x0000001FUL
|
|
|
|
#define ARV_VECTOR_OFFT_RST 0x00000000UL
|
|
#define ARM_VECTOR_OFFT_UND 0x00000004UL
|
|
#define ARM_VECTOR_OFFT_SWI 0x00000008UL
|
|
#define ARM_VECTOR_OFFT_P_ABT 0x0000000CUL
|
|
#define ARM_VECTOR_OFFT_D_ABT 0x00000010UL
|
|
#define ARM_VECTOR_OFFT_UNUSED 0x00000014UL
|
|
#define ARM_VECTOR_OFFT_IRQ 0x00000018UL
|
|
#define ARM_VECTOR_OFFT_FIQ 0x0000001CUL
|
|
|
|
#define HYPERCALL_ARM 0xF7BBBBBBUL
|
|
#define HYPERCALL_THUMB 0xBBBBUL
|
|
|
|
//the following are for cpuGetRegExternal() and are generally used for debugging purposes
|
|
#define ARM_REG_NUM_CPSR 16
|
|
#define ARM_REG_NUM_SPSR 17
|
|
|
|
struct ArmCpu;
|
|
|
|
typedef Boolean (*ArmCoprocRegXferF) (struct ArmCpu* cpu, void* userData, Boolean two/* MCR2/MRC2 ? */, Boolean MRC, UInt8 op1, UInt8 Rx, UInt8 CRn, UInt8 CRm, UInt8 op2);
|
|
typedef Boolean (*ArmCoprocDatProcF) (struct ArmCpu* cpu, void* userData, Boolean two/* CDP2 ? */, UInt8 op1, UInt8 CRd, UInt8 CRn, UInt8 CRm, UInt8 op2);
|
|
typedef Boolean (*ArmCoprocMemAccsF) (struct ArmCpu* cpu, void* userData, Boolean two /* LDC2/STC2 ? */, Boolean N, Boolean store, UInt8 CRd, UInt32 addr, UInt8* option /* NULL if none */);
|
|
typedef Boolean (*ArmCoprocTwoRegF) (struct ArmCpu* cpu, void* userData, Boolean MRRC, UInt8 op, UInt8 Rd, UInt8 Rn, UInt8 CRm);
|
|
|
|
typedef Boolean (*ArmCpuMemF) (struct ArmCpu* cpu, void* buf, UInt32 vaddr, UInt8 size, Boolean write, Boolean priviledged, UInt8* fsr); //read/write
|
|
typedef Boolean (*ArmCpuHypercall) (struct ArmCpu* cpu); //return true if handled
|
|
typedef void (*ArmCpuEmulErr) (struct ArmCpu* cpu, const char* err_str);
|
|
|
|
typedef void (*ArmSetFaultAdrF) (struct ArmCpu* cpu, UInt32 adr, UInt8 faultStatus);
|
|
|
|
#include "icache.h"
|
|
|
|
|
|
/*
|
|
|
|
coprocessors:
|
|
|
|
0 - DSP (pxa only)
|
|
0, 1 - WMMX (pxa only)
|
|
11 - VFP (arm standard)
|
|
15 - system control (arm standard)
|
|
*/
|
|
|
|
|
|
typedef struct{
|
|
|
|
ArmCoprocRegXferF regXfer;
|
|
ArmCoprocDatProcF dataProcessing;
|
|
ArmCoprocMemAccsF memAccess;
|
|
ArmCoprocTwoRegF twoRegF;
|
|
void* userData;
|
|
|
|
}ArmCoprocessor;
|
|
|
|
typedef struct{
|
|
|
|
UInt32 R13, R14;
|
|
UInt32 SPSR; //usr mode doesn't have an SPSR
|
|
}ArmBankedRegs;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct ArmCpu{
|
|
|
|
UInt32 regs[16]; //current active regs as per current mode
|
|
UInt32 CPSR, SPSR;
|
|
|
|
ArmBankedRegs bank_usr; //usr regs when in another mode
|
|
ArmBankedRegs bank_svc; //svc regs when in another mode
|
|
ArmBankedRegs bank_abt; //abt regs when in another mode
|
|
ArmBankedRegs bank_und; //und regs when in another mode
|
|
ArmBankedRegs bank_irq; //irq regs when in another mode
|
|
ArmBankedRegs bank_fiq; //fiq regs when in another mode
|
|
UInt32 extra_regs[5]; //fiq regs when not in fiq mode, usr regs when in fiq mode. R8-12
|
|
|
|
UInt16 waitingIrqs;
|
|
UInt16 waitingFiqs;
|
|
UInt16 CPAR;
|
|
|
|
ArmCoprocessor coproc[16]; //coprocessors
|
|
|
|
// various other cpu config options
|
|
UInt32 vectorBase; //address of vector base
|
|
|
|
#ifdef ARM_V6
|
|
|
|
Boolean EEE; //endianness one exception entry
|
|
Boolean impreciseAbtWaiting;
|
|
#endif
|
|
|
|
ArmCpuMemF memF;
|
|
ArmCpuEmulErr emulErrF;
|
|
ArmCpuHypercall hypercallF;
|
|
ArmSetFaultAdrF setFaultAdrF;
|
|
|
|
icache ic;
|
|
|
|
void* userData; //shared by all callbacks
|
|
}ArmCpu;
|
|
|
|
|
|
Err cpuInit(ArmCpu* cpu, UInt32 pc, ArmCpuMemF memF, ArmCpuEmulErr emulErrF, ArmCpuHypercall hypercallF, ArmSetFaultAdrF setFaultAdrF);
|
|
Err cpuDeinit(ArmCpu* cp);
|
|
void cpuCycle(ArmCpu* cpu);
|
|
void cpuIrq(ArmCpu* cpu, Boolean fiq, Boolean raise); //unraise when acknowledged
|
|
|
|
#ifdef ARM_V6
|
|
|
|
void cpuSignalImpreciseAbt(ArmCpu* cpu, Boolean raise);
|
|
|
|
#endif
|
|
|
|
UInt32 cpuGetRegExternal(ArmCpu* cpu, UInt8 reg);
|
|
void cpuSetReg(ArmCpu* cpu, UInt8 reg, UInt32 val);
|
|
|
|
void cpuCoprocessorRegister(ArmCpu* cpu, UInt8 cpNum, ArmCoprocessor* coproc);
|
|
void cpuCoprocessorUnregister(ArmCpu* cpu, UInt8 cpNum);
|
|
|
|
void cpuSetVectorAddr(ArmCpu* cpu, UInt32 adr);
|
|
|
|
UInt16 cpuGetCPAR(ArmCpu* cpu);
|
|
void cpuSetCPAR(ArmCpu* cpu, UInt16 cpar);
|
|
|
|
void cpuIcacheInval(ArmCpu* cpu);
|
|
void cpuIcacheInvalAddr(ArmCpu* cpu, UInt32 addr);
|
|
|
|
|
|
#endif
|
|
|