/[gxemul]/trunk/src/include/cpu_arm.h
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/src/include/cpu_arm.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 18 - (show annotations)
Mon Oct 8 16:19:11 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 9045 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1004 2005/10/27 14:01:10 debug Exp $
20051011        Passing -A as the default boot arg for CATS (works fine with
                OpenBSD/cats).
20051012	Fixing the VGA cursor offset bug, and speeding up framebuffer
		redraws if character cells contain the same thing as during
		the last redraw.
20051013	Adding a slow strd ARM instruction hack.
20051017	Minor updates: Adding a dummy i80321 Verde controller (for
		XScale emulation), fixing the disassembly of the ARM "ldrd"
		instruction, adding "support" for less-than-4KB pages for ARM
		(by not adding them to translation tables).
20051020	Continuing on some HPCarm stuff. A NetBSD/hpcarm kernel prints
		some boot messages on an emulated Jornada 720.
		Making dev_ram work better with dyntrans (speeds up some things
		quite a bit).
20051021	Automatically generating some of the most common ARM load/store
		multiple instructions.
20051022	Better statistics gathering for the ARM load/store multiple.
		Various other dyntrans and device updates.
20051023	Various minor updates.
20051024	Continuing; minor device and dyntrans fine-tuning. Adding the
		first "reasonable" instruction combination hacks for ARM (the
		cores of NetBSD/cats' memset and memcpy).
20051025	Fixing a dyntrans-related bug in dev_vga. Also changing the
		dyntrans low/high access notification to only be updated on
		writes, not reads. Hopefully it will be enough. (dev_vga in
		charcell mode now seems to work correctly with both reads and
		writes.)
		Experimenting with gathering dyntrans statistics (which parts
		of emulated RAM that are actually executed), and adding
		instruction combination hacks for cache cleaning and a part of
		NetBSD's scanc() function.
20051026	Adding a bitmap for ARM emulation which indicates if a page is
		(specifically) user accessible; loads and stores with the t-
		flag set can now use the translation arrays, which results in
		a measurable speedup.
20051027	Dyntrans updates; adding an extra bitmap array for 32-bit
		emulation modes, speeding up the check whether a physical page
		has any code translations or not (O(n) -> O(1)). Doing a
		similar reduction of O(n) to O(1) by avoiding the scan through
		the translation entries on a translation update (32-bit mode
		only).
		Various other minor hacks.
20051029	Quick release, without any testing at all.

==============  RELEASE 0.3.6.2  ==============


1 #ifndef CPU_ARM_H
2 #define CPU_ARM_H
3
4 /*
5 * Copyright (C) 2005 Anders Gavare. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 *
31 * $Id: cpu_arm.h,v 1.53 2005/10/27 14:01:15 debug Exp $
32 */
33
34 #include "misc.h"
35
36
37 struct cpu_family;
38
39 /* ARM CPU types: */
40 struct arm_cpu_type_def {
41 char *name;
42 uint32_t cpu_id;
43 int flags;
44 int icache_shift;
45 int iway;
46 int dcache_shift;
47 int dway;
48 };
49
50
51 #define ARM_SL 10
52 #define ARM_FP 11
53 #define ARM_IP 12
54 #define ARM_SP 13
55 #define ARM_LR 14
56 #define ARM_PC 15
57 #define N_ARM_REGS 16
58
59 #define ARM_REG_NAMES { \
60 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
61 "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }
62
63 #define ARM_CONDITION_STRINGS { \
64 "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", \
65 "hi", "ls", "ge", "lt", "gt", "le", "" /*Always*/ , "(INVALID)" }
66
67 /* Names of Data Processing Instructions: */
68 #define ARM_DPI_NAMES { \
69 "and", "eor", "sub", "rsb", "add", "adc", "sbc", "rsc", \
70 "tst", "teq", "cmp", "cmn", "orr", "mov", "bic", "mvn" }
71
72 #define ARM_N_IC_ARGS 3
73 #define ARM_INSTR_ALIGNMENT_SHIFT 2
74 #define ARM_IC_ENTRIES_SHIFT 10
75 #define ARM_IC_ENTRIES_PER_PAGE (1 << ARM_IC_ENTRIES_SHIFT)
76 #define ARM_PC_TO_IC_ENTRY(a) (((a)>>ARM_INSTR_ALIGNMENT_SHIFT) \
77 & (ARM_IC_ENTRIES_PER_PAGE-1))
78 #define ARM_ADDR_TO_PAGENR(a) ((a) >> (ARM_IC_ENTRIES_SHIFT \
79 + ARM_INSTR_ALIGNMENT_SHIFT))
80
81 struct arm_instr_call {
82 void (*f)(struct cpu *, struct arm_instr_call *);
83 size_t arg[ARM_N_IC_ARGS];
84 };
85
86 /* Translation cache struct for each physical page: */
87 struct arm_tc_physpage {
88 struct arm_instr_call ics[ARM_IC_ENTRIES_PER_PAGE + 1];
89 uint32_t next_ofs; /* or 0 for end of chain */
90 uint32_t physaddr;
91 int flags;
92 };
93
94
95 #define ARM_FLAG_N 0x80000000 /* Negative flag */
96 #define ARM_FLAG_Z 0x40000000 /* Zero flag */
97 #define ARM_FLAG_C 0x20000000 /* Carry flag */
98 #define ARM_FLAG_V 0x10000000 /* Overflow flag */
99 #define ARM_FLAG_Q 0x08000000 /* DSP saturation overflow */
100 #define ARM_FLAG_I 0x00000080 /* Interrupt disable */
101 #define ARM_FLAG_F 0x00000040 /* Fast Interrupt disable */
102 #define ARM_FLAG_T 0x00000020 /* Thumb mode */
103
104 #define ARM_FLAG_MODE 0x0000001f
105 #define ARM_MODE_USR26 0x00
106 #define ARM_MODE_FIQ26 0x01
107 #define ARM_MODE_IRQ26 0x02
108 #define ARM_MODE_SVC26 0x03
109 #define ARM_MODE_USR32 0x10
110 #define ARM_MODE_FIQ32 0x11
111 #define ARM_MODE_IRQ32 0x12
112 #define ARM_MODE_SVC32 0x13
113 #define ARM_MODE_ABT32 0x17
114 #define ARM_MODE_UND32 0x1b
115 #define ARM_MODE_SYS32 0x1f
116
117 #define ARM_EXCEPTION_TO_MODE { \
118 ARM_MODE_SVC32, ARM_MODE_UND32, ARM_MODE_SVC32, ARM_MODE_ABT32, \
119 ARM_MODE_ABT32, 0, ARM_MODE_IRQ32, ARM_MODE_FIQ32 }
120
121 #define N_ARM_EXCEPTIONS 8
122
123 #define ARM_EXCEPTION_RESET 0
124 #define ARM_EXCEPTION_UND 1
125 #define ARM_EXCEPTION_SWI 2
126 #define ARM_EXCEPTION_PREF_ABT 3
127 #define ARM_EXCEPTION_DATA_ABT 4
128 /* 5 was address exception in 26-bit ARM */
129 #define ARM_EXCEPTION_IRQ 6
130 #define ARM_EXCEPTION_FIQ 7
131
132
133 #define ARM_N_VPH_ENTRIES 1048576
134
135 #define ARM_MAX_VPH_TLB_ENTRIES 128
136 struct arm_vpg_tlb_entry {
137 int valid;
138 int writeflag;
139 int64_t timestamp;
140 unsigned char *host_page;
141 uint32_t vaddr_page;
142 uint32_t paddr_page;
143 };
144
145
146 struct arm_cpu {
147 /*
148 * Misc.:
149 */
150 struct arm_cpu_type_def cpu_type;
151 uint32_t of_emul_addr;
152
153 void (*coproc[16])(struct cpu *, int opcode1,
154 int opcode2, int l_bit, int crn, int crm,
155 int rd);
156
157 /*
158 * General Purpose Registers (including the program counter):
159 *
160 * r[] always contains the current register set. The others are
161 * only used to swap to/from when changing modes. (An exception is
162 * r[0..7], which are never swapped out, they are always present.)
163 */
164
165 uint32_t r[N_ARM_REGS];
166
167 uint32_t default_r8_r14[7]; /* usr and sys */
168 uint32_t fiq_r8_r14[7];
169 uint32_t irq_r13_r14[2];
170 uint32_t svc_r13_r14[2];
171 uint32_t abt_r13_r14[2];
172 uint32_t und_r13_r14[2];
173
174 uint32_t tmp_pc; /* Used for load/stores */
175
176 /* Flag/status registers: */
177 uint32_t cpsr;
178 uint32_t spsr_svc;
179 uint32_t spsr_abt;
180 uint32_t spsr_und;
181 uint32_t spsr_irq;
182 uint32_t spsr_fiq;
183
184
185 /*
186 * System Control Coprocessor registers:
187 */
188 uint32_t control;
189 uint32_t ttb; /* Translation Table Base */
190 uint32_t dacr; /* Domain Access Control */
191 uint32_t fsr; /* Fault Status Register */
192 uint32_t far; /* Fault Address Register */
193 uint32_t pid; /* Process Id Register */
194
195 /* For caching the host address of the L1 translation table: */
196 unsigned char *translation_table;
197 uint32_t last_ttb;
198
199
200 /*
201 * Interrupts:
202 */
203 int irq_asserted;
204
205
206 /*
207 * Instruction translation cache:
208 */
209
210 /* cur_ic_page is a pointer to an array of ARM_IC_ENTRIES_PER_PAGE
211 instruction call entries. next_ic points to the next such
212 call to be executed. */
213 struct arm_tc_physpage *cur_physpage;
214 struct arm_instr_call *cur_ic_page;
215 struct arm_instr_call *next_ic;
216
217
218 /*
219 * Virtual -> physical -> host address translation:
220 *
221 * host_load and host_store point to arrays of ARM_N_VPH_ENTRIES
222 * pointers (to host pages); phys_addr points to an array of
223 * ARM_N_VPH_ENTRIES uint32_t.
224 */
225
226 struct arm_vpg_tlb_entry vph_tlb_entry[ARM_MAX_VPH_TLB_ENTRIES];
227 unsigned char *host_load[ARM_N_VPH_ENTRIES];
228 unsigned char *host_store[ARM_N_VPH_ENTRIES];
229 uint32_t phys_addr[ARM_N_VPH_ENTRIES];
230 struct arm_tc_physpage *phys_page[ARM_N_VPH_ENTRIES];
231
232 uint32_t phystranslation[ARM_N_VPH_ENTRIES/32];
233 int16_t vaddr_to_tlbindex[ARM_N_VPH_ENTRIES];
234
235 /* ARM specific: */
236 unsigned char is_userpage[ARM_N_VPH_ENTRIES/8];
237 };
238
239
240 /* System Control Coprocessor, control bits: */
241 #define ARM_CONTROL_MMU 0x0001
242 #define ARM_CONTROL_ALIGN 0x0002
243 #define ARM_CONTROL_CACHE 0x0004
244 #define ARM_CONTROL_WBUFFER 0x0008
245 #define ARM_CONTROL_PROG32 0x0010
246 #define ARM_CONTROL_DATA32 0x0020
247 #define ARM_CONTROL_BIG 0x0080
248 #define ARM_CONTROL_S 0x0100
249 #define ARM_CONTROL_R 0x0200
250 #define ARM_CONTROL_F 0x0400
251 #define ARM_CONTROL_Z 0x0800
252 #define ARM_CONTROL_ICACHE 0x1000
253 #define ARM_CONTROL_V 0x2000
254 #define ARM_CONTROL_RR 0x4000
255 #define ARM_CONTROL_L4 0x8000
256
257 /* cpu_arm.c: */
258 void arm_setup_initial_translation_table(struct cpu *cpu, uint32_t ttb_addr);
259 void arm_translation_table_set_l1(struct cpu *cpu, uint32_t vaddr,
260 uint32_t paddr);
261 void arm_translation_table_set_l1_b(struct cpu *cpu, uint32_t vaddr,
262 uint32_t paddr);
263 void arm_exception(struct cpu *, int);
264 void arm_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,
265 unsigned char *host_page, int writeflag, uint64_t paddr_page);
266 void arm_invalidate_translation_caches(struct cpu *cpu, uint64_t, int);
267 void arm_invalidate_code_translation(struct cpu *cpu, uint64_t, int);
268 void arm_load_register_bank(struct cpu *cpu);
269 void arm_save_register_bank(struct cpu *cpu);
270 int arm_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr,
271 unsigned char *data, size_t len, int writeflag, int cache_flags);
272 int arm_cpu_family_init(struct cpu_family *);
273
274 /* cpu_arm_coproc.c: */
275 void arm_coproc_15(struct cpu *cpu, int opcode1, int opcode2, int l_bit,
276 int crn, int crm, int rd);
277 void arm_coproc_i80321(struct cpu *cpu, int opcode1, int opcode2, int l_bit,
278 int crn, int crm, int rd);
279 void arm_coproc_i80321_14(struct cpu *cpu, int opcode1, int opcode2, int l_bit,
280 int crn, int crm, int rd);
281
282 /* memory_arm.c: */
283 int arm_translate_address(struct cpu *cpu, uint64_t vaddr,
284 uint64_t *return_addr, int flags);
285 int arm_translate_address_mmu(struct cpu *cpu, uint64_t vaddr,
286 uint64_t *return_addr, int flags);
287
288 #endif /* CPU_ARM_H */

  ViewVC Help
Powered by ViewVC 1.1.26