1 #include "armv5te/uArm/uArmGlue.h"
2 #include "armv5te/uArm/CPU_2.h"
3 
4 #include "emulator.h"
5 #include "armv5te/cpu.h"
6 #include "armv5te/asmcode.h"
7 #include "armv5te/cpudefs.h"
8 #include "pxa260/pxa260.h"
9 
10 
11 static ArmCoprocessor uArmCp14;
12 static ArmCoprocessor uArmCp15;
13 
14 
uArmCp14RegXferF(struct ArmCpu * cpu,void * userData,Boolean two,Boolean MRC,UInt8 op1,UInt8 Rx,UInt8 CRn,UInt8 CRm,UInt8 op2)15 Boolean	uArmCp14RegXferF	(struct ArmCpu* cpu, void* userData, Boolean two/* MCR2/MRC2 ? */, Boolean MRC, UInt8 op1, UInt8 Rx, UInt8 CRn, UInt8 CRm, UInt8 op2){
16    //if(!cpu->coproc[vb8].regXfer(cpu, cpu->coproc[vb8].userData, specialInstr, (instr & 0x00100000UL) != 0, (instr >> 21) & 0x07, (instr >> 12) & 0x0F, (instr >> 16) & 0x0F, instr & 0x0F, (instr >> 5) & 0x07)) goto invalid_instr;
17    Instruction inst;
18 
19    inst.raw = 0xE000E10 | op1 << 21 | Rx << 12 | CRn << 16 | CRm | op2 << 5;
20 
21    if(MRC)
22       inst.raw |= 0x00100000;
23 
24    do_cp14_instruction(inst);
25    return true;
26 }
27 
uArmCp14DatProcF(struct ArmCpu * cpu,void * userData,Boolean two,UInt8 op1,UInt8 CRd,UInt8 CRn,UInt8 CRm,UInt8 op2)28 Boolean	uArmCp14DatProcF	(struct ArmCpu* cpu, void* userData, Boolean two/* CDP2 ? */, UInt8 op1, UInt8 CRd, UInt8 CRn, UInt8 CRm, UInt8 op2){
29    debugLog("uARM CP14 dat proc unimplemented\n");
30    return false;
31 }
32 
uArmCp14MemAccsF(struct ArmCpu * cpu,void * userData,Boolean two,Boolean N,Boolean store,UInt8 CRd,UInt32 addr,UInt8 * option)33 Boolean	uArmCp14MemAccsF	(struct ArmCpu* cpu, void* userData, Boolean two /* LDC2/STC2 ? */, Boolean N, Boolean store, UInt8 CRd, UInt32 addr, UInt8* option /* NULL if none */){
34    debugLog("uARM CP14 mem access unimplemented\n");
35    return false;
36 }
37 
uArmCp14TwoRegF(struct ArmCpu * cpu,void * userData,Boolean MRRC,UInt8 op,UInt8 Rd,UInt8 Rn,UInt8 CRm)38 Boolean uArmCp14TwoRegF	(struct ArmCpu* cpu, void* userData, Boolean MRRC, UInt8 op, UInt8 Rd, UInt8 Rn, UInt8 CRm){
39    debugLog("uARM CP14 2 reg access unimplemented\n");
40    return false;
41 }
42 
uArmCp15RegXferF(struct ArmCpu * cpu,void * userData,Boolean two,Boolean MRC,UInt8 op1,UInt8 Rx,UInt8 CRn,UInt8 CRm,UInt8 op2)43 Boolean	uArmCp15RegXferF	(struct ArmCpu* cpu, void* userData, Boolean two/* MCR2/MRC2 ? */, Boolean MRC, UInt8 op1, UInt8 Rx, UInt8 CRn, UInt8 CRm, UInt8 op2){
44    //if(!cpu->coproc[vb8].regXfer(cpu, cpu->coproc[vb8].userData, specialInstr, (instr & 0x00100000UL) != 0, (instr >> 21) & 0x07, (instr >> 12) & 0x0F, (instr >> 16) & 0x0F, instr & 0x0F, (instr >> 5) & 0x07)) goto invalid_instr;
45    Instruction inst;
46 
47    if(two)
48       debugLog("uARM unimplemented 2 register CP15 access\n");
49 
50    if(Rx == 15)
51       set_cpsr_full(pxa260CpuState.CPSR);
52    else
53       arm.reg[Rx] = pxa260CpuState.regs[Rx];
54 
55    inst.raw = 0xE000F10 | op1 << 21 | Rx << 12 | CRn << 16 | CRm | op2 << 5;
56 
57    if(MRC)
58       inst.raw |= 0x00100000;
59 
60    do_cp15_instruction(inst);
61    //addr_cache_flush handles icache flushing too
62 
63    if(Rx == 15)
64       pxa260CpuState.CPSR = get_cpsr();//this could be catastrophic in any other circumstance but only the CPSR data flags can be changed by CP15
65    else
66       pxa260CpuState.regs[Rx] = arm.reg[Rx];
67 
68    return true;
69 }
70 
uArmCp15DatProcF(struct ArmCpu * cpu,void * userData,Boolean two,UInt8 op1,UInt8 CRd,UInt8 CRn,UInt8 CRm,UInt8 op2)71 Boolean	uArmCp15DatProcF	(struct ArmCpu* cpu, void* userData, Boolean two/* CDP2 ? */, UInt8 op1, UInt8 CRd, UInt8 CRn, UInt8 CRm, UInt8 op2){
72    debugLog("uARM CP15 dat proc unimplemented\n");
73    return false;
74 }
75 
uArmCp15MemAccsF(struct ArmCpu * cpu,void * userData,Boolean two,Boolean N,Boolean store,UInt8 CRd,UInt32 addr,UInt8 * option)76 Boolean	uArmCp15MemAccsF	(struct ArmCpu* cpu, void* userData, Boolean two /* LDC2/STC2 ? */, Boolean N, Boolean store, UInt8 CRd, UInt32 addr, UInt8* option /* NULL if none */){
77    debugLog("uARM CP15 mem access unimplemented\n");
78    return false;
79 }
80 
uArmCp15TwoRegF(struct ArmCpu * cpu,void * userData,Boolean MRRC,UInt8 op,UInt8 Rd,UInt8 Rn,UInt8 CRm)81 Boolean uArmCp15TwoRegF	(struct ArmCpu* cpu, void* userData, Boolean MRRC, UInt8 op, UInt8 Rd, UInt8 Rn, UInt8 CRm){
82    debugLog("uARM CP15 2 reg access unimplemented\n");
83    return false;
84 }
85 
uArmMemAccess(struct ArmCpu * cpu,void * buf,UInt32 vaddr,UInt8 size,Boolean write,Boolean priviledged,UInt8 * fsr)86 Boolean	uArmMemAccess(struct ArmCpu* cpu, void* buf, UInt32 vaddr, UInt8 size, Boolean write, Boolean priviledged, UInt8* fsr){
87    if(write){
88       switch(size){
89          case 1:
90             write_byte(vaddr, *(uint8_t*)buf);
91             return true;
92 
93          case 2:
94             write_half(vaddr, *(uint16_t*)buf);
95             return true;
96 
97          case 4:
98             write_word(vaddr, *(uint32_t*)buf);
99             return true;
100 
101          default:
102             debugLog("uARM wrote memory with invalid byte count:%d\n", size);
103             return false;
104       }
105    }
106    else{
107       switch(size){
108          case 1:
109             *(uint8_t*)buf = read_byte(vaddr);
110             return true;
111 
112          case 2:
113             *(uint16_t*)buf = read_half(vaddr);
114             return true;
115 
116          case 4:
117             *(uint32_t*)buf = read_word(vaddr);
118             return true;
119 
120          case 32:
121             ((uint32_t*)buf)[0] = read_word(vaddr);
122             ((uint32_t*)buf)[1] = read_word(vaddr + 4);
123             ((uint32_t*)buf)[2] = read_word(vaddr + 8);
124             ((uint32_t*)buf)[3] = read_word(vaddr + 12);
125             ((uint32_t*)buf)[4] = read_word(vaddr + 16);
126             ((uint32_t*)buf)[5] = read_word(vaddr + 20);
127             ((uint32_t*)buf)[6] = read_word(vaddr + 24);
128             ((uint32_t*)buf)[7] = read_word(vaddr + 28);
129             return true;
130 
131          default:
132             debugLog("uARM read memory with invalid byte count:%d\n", size);
133             return false;
134       }
135    }
136 }
137 
uArmHypercall(struct ArmCpu * cpu)138 Boolean	uArmHypercall(struct ArmCpu* cpu){
139    //no hypercalls
140    return true;
141 }
142 
uArmEmulErr(struct ArmCpu * cpu,const char * err_str)143 void	uArmEmulErr	(struct ArmCpu* cpu, const char* err_str){
144    debugLog("uARM error:%s\n", err_str);
145 }
146 
uArmSetFaultAddr(struct ArmCpu * cpu,UInt32 adr,UInt8 faultStatus)147 void	uArmSetFaultAddr(struct ArmCpu* cpu, UInt32 adr, UInt8 faultStatus){
148    debugLog("uARM set fault addr:0x%08X, status:0x%02X\n", adr, faultStatus);
149 }
150 
uArmInitCpXX(ArmCpu * cpu)151 void uArmInitCpXX(ArmCpu* cpu){
152    uArmCp14.regXfer = uArmCp14RegXferF;
153    uArmCp14.dataProcessing = uArmCp14DatProcF;
154    uArmCp14.memAccess = uArmCp14MemAccsF;
155    uArmCp14.twoRegF = uArmCp14TwoRegF;
156 
157    uArmCp15.regXfer = uArmCp15RegXferF;
158    uArmCp15.dataProcessing = uArmCp15DatProcF;
159    uArmCp15.memAccess = uArmCp15MemAccsF;
160    uArmCp15.twoRegF = uArmCp15TwoRegF;
161 
162    cpuCoprocessorRegister(cpu, 14, &uArmCp14);
163    cpuCoprocessorRegister(cpu, 15, &uArmCp15);
164 }
165