/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20 - (hide annotations)
Mon Oct 8 16:19:23 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 9530 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1055 2005/11/25 22:48:36 debug Exp $
20051031	Adding disassembly support for more ARM instructions (clz,
		smul* etc), and adding a hack to support "new tiny" pages
		for StrongARM.
20051101	Minor documentation updates (NetBSD 2.0.2 -> 2.1, and OpenBSD
		3.7 -> 3.8, and lots of testing).
		Changing from 1-sector PIO mode 0 transfers to 128-sector PIO
		mode 3 (in dev_wdc).
		Various minor ARM dyntrans updates (pc-relative loads from
		within the same page as the instruction are now treated as
		constant "mov").
20051102	Re-enabling instruction combinations (they were accidentally
		disabled).
		Dyntrans TLB entries are now overwritten using a round-robin
		scheme instead of randomly. This increases performance.
		Fixing a typo in file.c (thanks to Chuan-Hua Chang for
		noticing it).
		Experimenting with adding ATAPI support to dev_wdc (to make
		emulated *BSD detect cdroms as cdroms, not harddisks).
20051104	Various minor updates.
20051105	Continuing on the ATAPI emulation. Seems to work well enough
		for a NetBSD/cats installation, but not OpenBSD/cats.
		Various other updates.
20051106	Modifying the -Y command line option to allow scaleup with
		certain graphic controllers (only dev_vga so far), not just
		scaledown.
		Some minor dyntrans cleanups.
20051107	Beginning a cleanup up the PCI subsystem (removing the
		read_register hack, etc).
20051108	Continuing the cleanup; splitting up some pci devices into a
		normal autodev device and some separate pci glue code.
20051109	Continuing on the PCI bus stuff; all old pci_*.c have been
		incorporated into normal devices and/or rewritten as glue code
		only, adding a dummy Intel 82371AB PIIX4 for Malta (not really
		tested yet).
		Minor pckbc fix so that Linux doesn't complain.
		Working on the DEC 21143 NIC (ethernet mac rom stuff mostly).
		Various other minor fixes.
20051110	Some more ARM dyntrans fine-tuning (e.g. some instruction
		combinations (cmps followed by conditional branch within the
		same page) and special cases for DPIs with regform when the
		shifter isn't used).
20051111	ARM dyntrans updates: O(n)->O(1) for just-mark-as-non-
		writable in the generic pc_to_pointers function, and some other
		minor hacks.
		Merging Cobalt and evbmips (Malta) ISA interrupt handling,
		and some minor fixes to allow Linux to accept harddisk irqs.
20051112	Minor device updates (pckbc, dec21143, lpt, ...), most
		importantly fixing the ALI M1543/M5229 so that harddisk irqs
		work with Linux/CATS.
20051113	Some more generalizations of the PCI subsystem.
		Finally took the time to add a hack for SCSI CDROM TOCs; this
		enables OpenBSD to use partition 'a' (as needed by the OpenBSD
		installer), and Windows NT's installer to get a bit further.
		Also fixing dev_wdc to allow Linux to detect ATAPI CDROMs.
		Continuing on the DEC 21143.
20051114	Minor ARM dyntrans tweaks; ARM cmps+branch optimization when
		comparing with 0, and generalizing the xchg instr. comb.
		Adding disassembly of ARM mrrc/mcrr and q{,d}{add,sub}.
20051115	Continuing on various PPC things (BATs, other address trans-
		lation things, various loads/stores, BeBox emulation, etc.).
		Beginning to work on PPC interrupt/exception support.
20051116	Factoring out some code which initializes legacy ISA devices
		from those machines that use them (bus_isa).
		Continuing on PPC interrupt/exception support.
20051117	Minor Malta fixes: RTC year offset = 80, disabling a speed hack
		which caused NetBSD to detect a too fast cpu, and adding a new
		hack to make Linux detect a faster cpu.
		Continuing on the Artesyn PM/PPC emulation mode.
		Adding an Algor emulation skeleton (P4032 and P5064);
		implementing some of the basics.
		Continuing on PPC emulation in general; usage of unimplemented
		SPRs is now easier to track, continuing on memory/exception
		related issues, etc.
20051118	More work on PPC emulation (tgpr0..3, exception handling,
		memory stuff, syscalls, etc.).
20051119	Changing the ARM dyntrans code to mostly use cpu->pc, and not
		necessarily use arm reg 15. Seems to work.
		Various PPC updates; continuing on the PReP emulation mode.
20051120	Adding a workaround/hack to dev_mc146818 to allow NetBSD/prep
		to detect the clock.
20051121	More cleanup of the PCI bus (memory and I/O bases, etc).
		Continuing on various PPC things (decrementer and timebase,
		WDCs on obio (on PReP) use irq 13, not 14/15).
20051122	Continuing on the CPC700 controller (interrupts etc) for PMPPC,
		and on PPC stuff in general.
		Finally! After some bug fixes to the virtual to physical addr
		translation, NetBSD/{prep,pmppc} 2.1 reach userland and are
		stable enough to be interacted with.
		More PCI updates; reverse-endian device access for PowerPC etc.
20051123	Generalizing the IEEE floating point subsystem (moving it out
		from src/cpus/cpu_mips_coproc.c into a new src/float_emul.c).
		Input via slave xterms was sometimes not really working; fixing
		this for ns16550, and a warning message is now displayed if
		multiple non-xterm consoles are active.
		Adding some PPC floating point support, etc.
		Various interrupt related updates (dev_wdc, _ns16550, _8259,
		and the isa32 common code in machine.c).
		NetBSD/prep can now be installed! :-) (Well, with some manual
		commands necessary before running sysinst.) Updating the
		documentation and various other things to reflect this.
20051124	Various minor documentation updates.
		Continuing the work on the DEC 21143 NIC.
20051125	LOTS of work on the 21143. Both OpenBSD and NetBSD work fine
		with it now, except that OpenBSD sometimes gives a time-out
		warning.
		Minor documentation updates.

==============  RELEASE 0.3.7  ==============


1 dpavlin 6 #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 dpavlin 20 * $Id: cpu_arm.h,v 1.57 2005/11/16 21:15:19 debug Exp $
32 dpavlin 6 */
33    
34     #include "misc.h"
35    
36    
37     struct cpu_family;
38    
39 dpavlin 14 /* 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 dpavlin 10 #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 dpavlin 12 #define ARM_REG_NAMES { \
60     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
61     "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }
62 dpavlin 10
63 dpavlin 12 #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 dpavlin 10 struct arm_instr_call {
82     void (*f)(struct cpu *, struct arm_instr_call *);
83 dpavlin 12 size_t arg[ARM_N_IC_ARGS];
84 dpavlin 10 };
85    
86 dpavlin 12 /* Translation cache struct for each physical page: */
87 dpavlin 10 struct arm_tc_physpage {
88 dpavlin 18 struct arm_instr_call ics[ARM_IC_ENTRIES_PER_PAGE + 1];
89 dpavlin 10 uint32_t next_ofs; /* or 0 for end of chain */
90     uint32_t physaddr;
91     int flags;
92     };
93    
94    
95 dpavlin 20 #define ARM_F_N 8 /* Same as ARM_FLAG_*, but */
96     #define ARM_F_Z 4 /* for the 'flags' field instead */
97     #define ARM_F_C 2 /* of cpsr. */
98     #define ARM_F_V 1
99    
100 dpavlin 10 #define ARM_FLAG_N 0x80000000 /* Negative flag */
101     #define ARM_FLAG_Z 0x40000000 /* Zero flag */
102     #define ARM_FLAG_C 0x20000000 /* Carry flag */
103     #define ARM_FLAG_V 0x10000000 /* Overflow flag */
104 dpavlin 14 #define ARM_FLAG_Q 0x08000000 /* DSP saturation overflow */
105 dpavlin 10 #define ARM_FLAG_I 0x00000080 /* Interrupt disable */
106     #define ARM_FLAG_F 0x00000040 /* Fast Interrupt disable */
107 dpavlin 14 #define ARM_FLAG_T 0x00000020 /* Thumb mode */
108 dpavlin 10
109     #define ARM_FLAG_MODE 0x0000001f
110     #define ARM_MODE_USR26 0x00
111     #define ARM_MODE_FIQ26 0x01
112     #define ARM_MODE_IRQ26 0x02
113     #define ARM_MODE_SVC26 0x03
114     #define ARM_MODE_USR32 0x10
115     #define ARM_MODE_FIQ32 0x11
116     #define ARM_MODE_IRQ32 0x12
117     #define ARM_MODE_SVC32 0x13
118     #define ARM_MODE_ABT32 0x17
119     #define ARM_MODE_UND32 0x1b
120 dpavlin 14 #define ARM_MODE_SYS32 0x1f
121 dpavlin 10
122 dpavlin 14 #define ARM_EXCEPTION_TO_MODE { \
123     ARM_MODE_SVC32, ARM_MODE_UND32, ARM_MODE_SVC32, ARM_MODE_ABT32, \
124     ARM_MODE_ABT32, 0, ARM_MODE_IRQ32, ARM_MODE_FIQ32 }
125 dpavlin 12
126 dpavlin 14 #define N_ARM_EXCEPTIONS 8
127    
128     #define ARM_EXCEPTION_RESET 0
129     #define ARM_EXCEPTION_UND 1
130     #define ARM_EXCEPTION_SWI 2
131     #define ARM_EXCEPTION_PREF_ABT 3
132     #define ARM_EXCEPTION_DATA_ABT 4
133     /* 5 was address exception in 26-bit ARM */
134     #define ARM_EXCEPTION_IRQ 6
135     #define ARM_EXCEPTION_FIQ 7
136    
137    
138 dpavlin 12 #define ARM_N_VPH_ENTRIES 1048576
139    
140 dpavlin 18 #define ARM_MAX_VPH_TLB_ENTRIES 128
141 dpavlin 12 struct arm_vpg_tlb_entry {
142 dpavlin 20 unsigned char valid;
143     unsigned char writeflag;
144 dpavlin 12 uint32_t vaddr_page;
145     uint32_t paddr_page;
146 dpavlin 20 unsigned char *host_page;
147 dpavlin 12 };
148    
149    
150 dpavlin 6 struct arm_cpu {
151 dpavlin 12 /*
152     * Misc.:
153     */
154 dpavlin 14 struct arm_cpu_type_def cpu_type;
155     uint32_t of_emul_addr;
156 dpavlin 10
157 dpavlin 14 void (*coproc[16])(struct cpu *, int opcode1,
158     int opcode2, int l_bit, int crn, int crm,
159     int rd);
160 dpavlin 12
161 dpavlin 10 /*
162     * General Purpose Registers (including the program counter):
163     *
164     * r[] always contains the current register set. The others are
165     * only used to swap to/from when changing modes. (An exception is
166     * r[0..7], which are never swapped out, they are always present.)
167     */
168 dpavlin 12
169 dpavlin 10 uint32_t r[N_ARM_REGS];
170 dpavlin 14
171     uint32_t default_r8_r14[7]; /* usr and sys */
172 dpavlin 10 uint32_t fiq_r8_r14[7];
173     uint32_t irq_r13_r14[2];
174     uint32_t svc_r13_r14[2];
175     uint32_t abt_r13_r14[2];
176     uint32_t und_r13_r14[2];
177    
178 dpavlin 14 uint32_t tmp_pc; /* Used for load/stores */
179 dpavlin 12
180 dpavlin 20 /*
181     * Flag/status registers:
182     *
183     * NOTE: 'flags' just contains the 4 flag bits. When cpsr is read,
184     * the flags should be copied from 'flags', and when cpsr is written
185     * to, 'flags' should be updated as well.
186     */
187     size_t flags;
188 dpavlin 14 uint32_t cpsr;
189     uint32_t spsr_svc;
190     uint32_t spsr_abt;
191     uint32_t spsr_und;
192     uint32_t spsr_irq;
193     uint32_t spsr_fiq;
194    
195    
196 dpavlin 10 /*
197 dpavlin 14 * System Control Coprocessor registers:
198     */
199     uint32_t control;
200     uint32_t ttb; /* Translation Table Base */
201     uint32_t dacr; /* Domain Access Control */
202     uint32_t fsr; /* Fault Status Register */
203     uint32_t far; /* Fault Address Register */
204     uint32_t pid; /* Process Id Register */
205    
206 dpavlin 18 /* For caching the host address of the L1 translation table: */
207     unsigned char *translation_table;
208     uint32_t last_ttb;
209 dpavlin 14
210 dpavlin 18
211 dpavlin 14 /*
212     * Interrupts:
213     */
214     int irq_asserted;
215    
216    
217     /*
218 dpavlin 10 * Instruction translation cache:
219     */
220    
221 dpavlin 12 /* cur_ic_page is a pointer to an array of ARM_IC_ENTRIES_PER_PAGE
222 dpavlin 10 instruction call entries. next_ic points to the next such
223     call to be executed. */
224     struct arm_tc_physpage *cur_physpage;
225     struct arm_instr_call *cur_ic_page;
226     struct arm_instr_call *next_ic;
227    
228 dpavlin 20 void (*combination_check)(struct cpu *,
229     struct arm_instr_call *, int low_addr);
230 dpavlin 12
231     /*
232     * Virtual -> physical -> host address translation:
233     *
234     * host_load and host_store point to arrays of ARM_N_VPH_ENTRIES
235     * pointers (to host pages); phys_addr points to an array of
236     * ARM_N_VPH_ENTRIES uint32_t.
237     */
238    
239     struct arm_vpg_tlb_entry vph_tlb_entry[ARM_MAX_VPH_TLB_ENTRIES];
240     unsigned char *host_load[ARM_N_VPH_ENTRIES];
241     unsigned char *host_store[ARM_N_VPH_ENTRIES];
242     uint32_t phys_addr[ARM_N_VPH_ENTRIES];
243     struct arm_tc_physpage *phys_page[ARM_N_VPH_ENTRIES];
244 dpavlin 18
245     uint32_t phystranslation[ARM_N_VPH_ENTRIES/32];
246 dpavlin 20 uint8_t vaddr_to_tlbindex[ARM_N_VPH_ENTRIES];
247 dpavlin 18
248     /* ARM specific: */
249 dpavlin 20 uint32_t is_userpage[ARM_N_VPH_ENTRIES/32];
250 dpavlin 6 };
251    
252    
253 dpavlin 14 /* System Control Coprocessor, control bits: */
254     #define ARM_CONTROL_MMU 0x0001
255     #define ARM_CONTROL_ALIGN 0x0002
256     #define ARM_CONTROL_CACHE 0x0004
257     #define ARM_CONTROL_WBUFFER 0x0008
258     #define ARM_CONTROL_PROG32 0x0010
259     #define ARM_CONTROL_DATA32 0x0020
260     #define ARM_CONTROL_BIG 0x0080
261     #define ARM_CONTROL_S 0x0100
262     #define ARM_CONTROL_R 0x0200
263     #define ARM_CONTROL_F 0x0400
264     #define ARM_CONTROL_Z 0x0800
265     #define ARM_CONTROL_ICACHE 0x1000
266     #define ARM_CONTROL_V 0x2000
267     #define ARM_CONTROL_RR 0x4000
268     #define ARM_CONTROL_L4 0x8000
269    
270 dpavlin 6 /* cpu_arm.c: */
271 dpavlin 18 void arm_setup_initial_translation_table(struct cpu *cpu, uint32_t ttb_addr);
272     void arm_translation_table_set_l1(struct cpu *cpu, uint32_t vaddr,
273     uint32_t paddr);
274     void arm_translation_table_set_l1_b(struct cpu *cpu, uint32_t vaddr,
275     uint32_t paddr);
276 dpavlin 14 void arm_exception(struct cpu *, int);
277 dpavlin 12 void arm_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,
278     unsigned char *host_page, int writeflag, uint64_t paddr_page);
279 dpavlin 18 void arm_invalidate_translation_caches(struct cpu *cpu, uint64_t, int);
280 dpavlin 14 void arm_invalidate_code_translation(struct cpu *cpu, uint64_t, int);
281     void arm_load_register_bank(struct cpu *cpu);
282     void arm_save_register_bank(struct cpu *cpu);
283 dpavlin 6 int arm_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr,
284     unsigned char *data, size_t len, int writeflag, int cache_flags);
285     int arm_cpu_family_init(struct cpu_family *);
286    
287 dpavlin 14 /* cpu_arm_coproc.c: */
288     void arm_coproc_15(struct cpu *cpu, int opcode1, int opcode2, int l_bit,
289     int crn, int crm, int rd);
290     void arm_coproc_i80321(struct cpu *cpu, int opcode1, int opcode2, int l_bit,
291     int crn, int crm, int rd);
292     void arm_coproc_i80321_14(struct cpu *cpu, int opcode1, int opcode2, int l_bit,
293     int crn, int crm, int rd);
294 dpavlin 6
295 dpavlin 14 /* memory_arm.c: */
296     int arm_translate_address(struct cpu *cpu, uint64_t vaddr,
297     uint64_t *return_addr, int flags);
298 dpavlin 18 int arm_translate_address_mmu(struct cpu *cpu, uint64_t vaddr,
299     uint64_t *return_addr, int flags);
300 dpavlin 14
301 dpavlin 6 #endif /* CPU_ARM_H */

  ViewVC Help
Powered by ViewVC 1.1.26