28 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
29 |
* |
* |
30 |
* |
* |
31 |
* $Id: cpu_arm.h,v 1.1 2005/06/03 07:39:28 debug Exp $ |
* $Id: cpu_arm.h,v 1.26 2005/08/14 23:44:23 debug Exp $ |
32 |
*/ |
*/ |
33 |
|
|
34 |
#include "misc.h" |
#include "misc.h" |
36 |
|
|
37 |
struct cpu_family; |
struct cpu_family; |
38 |
|
|
39 |
|
#define ARM_SL 10 |
40 |
|
#define ARM_FP 11 |
41 |
|
#define ARM_IP 12 |
42 |
|
#define ARM_SP 13 |
43 |
|
#define ARM_LR 14 |
44 |
|
#define ARM_PC 15 |
45 |
|
#define N_ARM_REGS 16 |
46 |
|
|
47 |
|
#define ARM_REG_NAMES { \ |
48 |
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ |
49 |
|
"r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" } |
50 |
|
|
51 |
|
#define ARM_CONDITION_STRINGS { \ |
52 |
|
"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", \ |
53 |
|
"hi", "ls", "ge", "lt", "gt", "le", "" /*Always*/ , "(INVALID)" } |
54 |
|
|
55 |
|
/* Names of Data Processing Instructions: */ |
56 |
|
#define ARM_DPI_NAMES { \ |
57 |
|
"and", "eor", "sub", "rsb", "add", "adc", "sbc", "rsc", \ |
58 |
|
"tst", "teq", "cmp", "cmn", "orr", "mov", "bic", "mvn" } |
59 |
|
|
60 |
|
#define ARM_N_IC_ARGS 3 |
61 |
|
#define ARM_INSTR_ALIGNMENT_SHIFT 2 |
62 |
|
#define ARM_IC_ENTRIES_SHIFT 10 |
63 |
|
#define ARM_IC_ENTRIES_PER_PAGE (1 << ARM_IC_ENTRIES_SHIFT) |
64 |
|
#define ARM_PC_TO_IC_ENTRY(a) (((a)>>ARM_INSTR_ALIGNMENT_SHIFT) \ |
65 |
|
& (ARM_IC_ENTRIES_PER_PAGE-1)) |
66 |
|
#define ARM_ADDR_TO_PAGENR(a) ((a) >> (ARM_IC_ENTRIES_SHIFT \ |
67 |
|
+ ARM_INSTR_ALIGNMENT_SHIFT)) |
68 |
|
|
69 |
|
struct arm_instr_call { |
70 |
|
void (*f)(struct cpu *, struct arm_instr_call *); |
71 |
|
size_t arg[ARM_N_IC_ARGS]; |
72 |
|
}; |
73 |
|
|
74 |
|
/* Translation cache struct for each physical page: */ |
75 |
|
struct arm_tc_physpage { |
76 |
|
uint32_t next_ofs; /* or 0 for end of chain */ |
77 |
|
uint32_t physaddr; |
78 |
|
int flags; |
79 |
|
struct arm_instr_call ics[ARM_IC_ENTRIES_PER_PAGE + 1]; |
80 |
|
}; |
81 |
|
|
82 |
|
|
83 |
|
#define ARM_FLAG_N 0x80000000 /* Negative flag */ |
84 |
|
#define ARM_FLAG_Z 0x40000000 /* Zero flag */ |
85 |
|
#define ARM_FLAG_C 0x20000000 /* Carry flag */ |
86 |
|
#define ARM_FLAG_V 0x10000000 /* Overflow flag */ |
87 |
|
#define ARM_FLAG_I 0x00000080 /* Interrupt disable */ |
88 |
|
#define ARM_FLAG_F 0x00000040 /* Fast Interrupt disable */ |
89 |
|
|
90 |
|
#define ARM_FLAG_MODE 0x0000001f |
91 |
|
#define ARM_MODE_USR26 0x00 |
92 |
|
#define ARM_MODE_FIQ26 0x01 |
93 |
|
#define ARM_MODE_IRQ26 0x02 |
94 |
|
#define ARM_MODE_SVC26 0x03 |
95 |
|
#define ARM_MODE_USR32 0x10 |
96 |
|
#define ARM_MODE_FIQ32 0x11 |
97 |
|
#define ARM_MODE_IRQ32 0x12 |
98 |
|
#define ARM_MODE_SVC32 0x13 |
99 |
|
#define ARM_MODE_ABT32 0x17 |
100 |
|
#define ARM_MODE_UND32 0x1b |
101 |
|
|
102 |
|
|
103 |
|
#define ARM_N_VPH_ENTRIES 1048576 |
104 |
|
|
105 |
|
#define ARM_MAX_VPH_TLB_ENTRIES 256 |
106 |
|
struct arm_vpg_tlb_entry { |
107 |
|
int valid; |
108 |
|
int writeflag; |
109 |
|
int64_t timestamp; |
110 |
|
unsigned char *host_page; |
111 |
|
uint32_t vaddr_page; |
112 |
|
uint32_t paddr_page; |
113 |
|
}; |
114 |
|
|
115 |
|
|
116 |
struct arm_cpu { |
struct arm_cpu { |
117 |
int dummy; |
/* |
118 |
|
* Misc.: |
119 |
|
*/ |
120 |
|
uint32_t flags; |
121 |
|
|
122 |
|
|
123 |
|
/* |
124 |
|
* General Purpose Registers (including the program counter): |
125 |
|
* |
126 |
|
* r[] always contains the current register set. The others are |
127 |
|
* only used to swap to/from when changing modes. (An exception is |
128 |
|
* r[0..7], which are never swapped out, they are always present.) |
129 |
|
*/ |
130 |
|
|
131 |
|
uint32_t r[N_ARM_REGS]; |
132 |
|
uint32_t usr_r8_r14[7]; |
133 |
|
uint32_t fiq_r8_r14[7]; |
134 |
|
uint32_t irq_r13_r14[2]; |
135 |
|
uint32_t svc_r13_r14[2]; |
136 |
|
uint32_t abt_r13_r14[2]; |
137 |
|
uint32_t und_r13_r14[2]; |
138 |
|
|
139 |
|
|
140 |
|
/* |
141 |
|
* Instruction translation cache: |
142 |
|
*/ |
143 |
|
|
144 |
|
/* cur_ic_page is a pointer to an array of ARM_IC_ENTRIES_PER_PAGE |
145 |
|
instruction call entries. next_ic points to the next such |
146 |
|
call to be executed. */ |
147 |
|
struct arm_tc_physpage *cur_physpage; |
148 |
|
struct arm_instr_call *cur_ic_page; |
149 |
|
struct arm_instr_call *next_ic; |
150 |
|
|
151 |
|
|
152 |
|
/* |
153 |
|
* Virtual -> physical -> host address translation: |
154 |
|
* |
155 |
|
* host_load and host_store point to arrays of ARM_N_VPH_ENTRIES |
156 |
|
* pointers (to host pages); phys_addr points to an array of |
157 |
|
* ARM_N_VPH_ENTRIES uint32_t. |
158 |
|
*/ |
159 |
|
|
160 |
|
struct arm_vpg_tlb_entry vph_tlb_entry[ARM_MAX_VPH_TLB_ENTRIES]; |
161 |
|
unsigned char *host_load[ARM_N_VPH_ENTRIES]; |
162 |
|
unsigned char *host_store[ARM_N_VPH_ENTRIES]; |
163 |
|
uint32_t phys_addr[ARM_N_VPH_ENTRIES]; |
164 |
|
struct arm_tc_physpage *phys_page[ARM_N_VPH_ENTRIES]; |
165 |
}; |
}; |
166 |
|
|
167 |
|
|
168 |
/* cpu_arm.c: */ |
/* cpu_arm.c: */ |
169 |
|
void arm_update_translation_table(struct cpu *cpu, uint64_t vaddr_page, |
170 |
|
unsigned char *host_page, int writeflag, uint64_t paddr_page); |
171 |
|
void arm_invalidate_translation_caches_paddr(struct cpu *cpu, uint64_t paddr); |
172 |
|
void arm_invalidate_code_translation_caches(struct cpu *cpu); |
173 |
int arm_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr, |
int arm_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr, |
174 |
unsigned char *data, size_t len, int writeflag, int cache_flags); |
unsigned char *data, size_t len, int writeflag, int cache_flags); |
175 |
int arm_cpu_family_init(struct cpu_family *); |
int arm_cpu_family_init(struct cpu_family *); |