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