fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/cpu/arm/arm.h *
7 * Created: 2004-11-03 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2004-2009 Hampa Hug <hampa@hampa.ch> *
9 * Copyright: (C) 2004-2006 Lukas Ruf <ruf@lpr.ch> *
10 *****************************************************************************/
11
12/*****************************************************************************
13 * This program is free software. You can redistribute it and / or modify it *
14 * under the terms of the GNU General Public License version 2 as published *
15 * by the Free Software Foundation. *
16 * *
17 * This program is distributed in the hope that it will be useful, but *
18 * WITHOUT ANY WARRANTY, without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
20 * Public License for more details. *
21 *****************************************************************************/
22
23/*****************************************************************************
24 * This software was developed at the Computer Engineering and Networks *
25 * Laboratory (TIK), Swiss Federal Institute of Technology (ETH) Zurich. *
26 *****************************************************************************/
27
28
29#ifndef ARM_H
30#define ARM_H 1
31
32
33#include <stdint.h>
34
35
36/*****************************************************************************
37 * ARM
38 *****************************************************************************/
39
40/* PSR fields */
41#define ARM_PSR_N (1UL << 31)
42#define ARM_PSR_Z (1UL << 30)
43#define ARM_PSR_C (1UL << 29)
44#define ARM_PSR_V (1UL << 28)
45#define ARM_PSR_CC 0xf0000000UL
46#define ARM_PSR_Q (1UL << 27)
47#define ARM_PSR_I (1UL << 7)
48#define ARM_PSR_F (1UL << 6)
49#define ARM_PSR_T (1UL << 5)
50#define ARM_PSR_M 0x1fUL
51
52
53#define ARM_MODE_USR 0x10
54#define ARM_MODE_FIQ 0x11
55#define ARM_MODE_IRQ 0x12
56#define ARM_MODE_SVC 0x13
57#define ARM_MODE_ABT 0x17
58#define ARM_MODE_UND 0x1b
59#define ARM_MODE_SYS 0x1f
60
61
62/* enable big endian mode */
63#define ARM_FLAG_BIGENDIAN 1
64#define ARM_FLAG_T 2 /* thumb mode */
65#define ARM_FLAG_M 4 /* multiply instructions */
66#define ARM_FLAG_E 8 /* enhanced dsp instructions */
67#define ARM_FLAG_CPAR 16 /* coprocessor access register */
68#define ARM_FLAG_XSCALE (ARM_FLAG_T | ARM_FLAG_M | ARM_FLAG_E | ARM_FLAG_CPAR)
69#define ARM_FLAG_ALL 0xffff
70
71
72#define ARM_C15_ID_XSCALE_V5TE 0x69052000UL
73#define ARM_C15_ID_IXP2400 0x69054190UL
74
75#define ARM_C15_ID 0x69052000UL
76#define ARM_C15_CR_M 0x00000001UL
77#define ARM_C15_CR_A 0x00000002UL
78#define ARM_C15_CR_C 0x00000004UL
79#define ARM_C15_CR_W 0x00000008UL
80#define ARM_C15_CR_P 0x00000010UL
81#define ARM_C15_CR_D 0x00000020UL
82#define ARM_C15_CR_L 0x00000040UL
83#define ARM_C15_CR_B 0x00000080UL
84#define ARM_C15_CR_S 0x00000100UL
85#define ARM_C15_CR_R 0x00000200UL
86#define ARM_C15_CR_F 0x00000400UL
87#define ARM_C15_CR_Z 0x00000800UL
88#define ARM_C15_CR_I 0x00001000UL
89#define ARM_C15_CR_V 0x00002000UL
90
91
92#define ARM_XLAT_CPU 0
93#define ARM_XLAT_REAL 1
94#define ARM_XLAT_VIRTUAL 2
95
96
97#define ARM_REG_ALT_CNT 24
98#define ARM_SPSR_CNT 6
99
100#define arm_set_bits(var, bits, val) do { \
101 if (val) (var) |= (bits); else (var) &= ~(bits); \
102 } while (0)
103
104#define arm_get_gpr(c, n) ((c)->reg[(n)])
105#define arm_get_pc(c) ((c)->reg[15])
106#define arm_get_lr(c) ((c)->reg[14])
107#define arm_get_cpsr(c) ((c)->cpsr)
108#define arm_get_spsr(c) ((c)->spsr)
109#define arm_get_last_pc(c) ((c)->lastpc[1])
110
111#define arm_set_gpr(c, n, v) do { (c)->reg[(n)] = (v); } while (0)
112#define arm_set_pc(c, v) do { (c)->reg[15] = (v); } while (0)
113#define arm_set_lr(c, v) do { (c)->reg[14] = (v); } while (0)
114#define arm_set_cpsr(c, v) do { (c)->cpsr = (v); } while (0)
115#define arm_set_spsr(c, v) do { (c)->spsr = (v); } while (0)
116
117#define arm_get_cc_n(c) (((c)->cpsr & ARM_PSR_N) != 0)
118#define arm_get_cc_z(c) (((c)->cpsr & ARM_PSR_Z) != 0)
119#define arm_get_cc_c(c) (((c)->cpsr & ARM_PSR_C) != 0)
120#define arm_get_cc_v(c) (((c)->cpsr & ARM_PSR_V) != 0)
121#define arm_get_cc_q(c) (((c)->cpsr & ARM_PSR_Q) != 0)
122
123#define arm_get_cpsr_i(c) (((c)->cpsr & ARM_PSR_I) != 0)
124#define arm_get_cpsr_f(c) (((c)->cpsr & ARM_PSR_F) != 0)
125#define arm_get_cpsr_t(c) (((c)->cpsr & ARM_PSR_T) != 0)
126#define arm_get_cpsr_m(c) ((c)->cpsr & ARM_PSR_M)
127
128#define arm_set_cc_n(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_N, (v))
129#define arm_set_cc_z(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_Z, (v))
130#define arm_set_cc_c(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_C, (v))
131#define arm_set_cc_v(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_V, (v))
132#define arm_set_cc_q(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_Q, (v))
133
134#define arm_set_cpsr_i(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_I, (v))
135#define arm_set_cpsr_f(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_F, (v))
136#define arm_set_cpsr_t(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_T, (v))
137#define arm_set_cpsr_m(c, v) do { \
138 (c)->cpsr &= ~0x1fUL; \
139 (c)->cpsr |= (v) & 0x1f; \
140 } while (0)
141
142#define arm_get_mmu(c) (&(c)->copr15)
143
144
145struct arm_s;
146struct arm_copr_s;
147
148
149typedef unsigned char (*arm_get_uint8_f) (void *ext, unsigned long addr);
150typedef unsigned short (*arm_get_uint16_f) (void *ext, unsigned long addr);
151typedef unsigned long (*arm_get_uint32_f) (void *ext, unsigned long addr);
152
153typedef void (*arm_set_uint8_f) (void *ext, unsigned long addr, unsigned char val);
154typedef void (*arm_set_uint16_f) (void *ext, unsigned long addr, unsigned short val);
155typedef void (*arm_set_uint32_f) (void *ext, unsigned long addr, unsigned long val);
156
157typedef void (*arm_opcode_f) (struct arm_s *c);
158
159
160/*****************************************************************************
161 * @short The ARM coprocessor context
162 *****************************************************************************/
163typedef struct arm_copr_s {
164 unsigned copr_idx;
165
166 int (*reset) (struct arm_s *c, struct arm_copr_s *p);
167 int (*exec) (struct arm_s *c, struct arm_copr_s *p);
168
169 void *ext;
170} arm_copr_t;
171
172
173typedef struct {
174 int valid;
175
176 uint32_t vaddr;
177 uint32_t vmask;
178
179 uint32_t raddr;
180 uint32_t rmask;
181} arm_tbuf_t;
182
183
184typedef struct {
185 arm_copr_t copr;
186
187 arm_tbuf_t tbuf_exec;
188 arm_tbuf_t tbuf_read;
189 arm_tbuf_t tbuf_write;
190
191 uint32_t reg[16];
192
193 uint32_t cache_type;
194 uint32_t auxiliary_control;
195} arm_copr15_t;
196
197
198typedef struct {
199 arm_copr_t copr;
200
201 uint32_t cclkcfg;
202 uint32_t pwrmode;
203} arm_copr14_t;
204
205
206/*****************************************************************************
207 * @short The ARM CPU context
208 *****************************************************************************/
209typedef struct arm_s {
210 unsigned flags;
211
212 void *mem_ext;
213
214 arm_get_uint8_f get_uint8;
215 arm_get_uint16_f get_uint16;
216 arm_get_uint32_f get_uint32;
217
218 arm_set_uint8_f set_uint8;
219 arm_set_uint16_f set_uint16;
220 arm_set_uint32_f set_uint32;
221
222 unsigned char *ram;
223 unsigned long ram_cnt;
224
225 void *log_ext;
226 int (*log_opcode) (void *ext, unsigned long ir);
227 void (*log_undef) (void *ext, unsigned long ir);
228 void (*log_exception) (void *ext, unsigned long addr);
229
230 uint32_t cpsr;
231
232 uint32_t spsr;
233 uint32_t spsr_alt[ARM_SPSR_CNT];
234
235 uint32_t reg[16];
236 uint32_t reg_alt[ARM_REG_ALT_CNT];
237
238 uint32_t lastpc[2];
239
240 /* the current register mapping */
241 unsigned reg_map;
242
243 arm_copr_t *copr[16];
244
245 arm_copr14_t copr14;
246
247 /* system control coprocessor */
248 arm_copr15_t copr15;
249
250 uint32_t ir;
251
252 uint32_t exception_base;
253
254 /* this reflects the B bit in copr15 reg 1 */
255 int bigendian;
256
257 /* cpu is in a privileged mode */
258 int privileged;
259
260 unsigned char irq;
261 unsigned char fiq;
262 unsigned char irq_or_fiq;
263
264 unsigned long delay;
265
266 unsigned long long oprcnt;
267 unsigned long long clkcnt;
268
269 arm_opcode_f opcodes[256];
270} arm_t;
271
272
273
274/*****************************************************************************
275 * MMU
276 *****************************************************************************/
277
278int arm_translate_extern (arm_t *c, uint32_t *addr, unsigned xlat,
279 unsigned *domn, unsigned *perm
280);
281
282int arm_get_mem8 (arm_t *c, uint32_t addr, unsigned xlat, uint8_t *val);
283int arm_get_mem16 (arm_t *c, uint32_t addr, unsigned xlat, uint16_t *val);
284int arm_get_mem32 (arm_t *c, uint32_t addr, unsigned xlat, uint32_t *val);
285
286int arm_set_mem8 (arm_t *c, uint32_t addr, unsigned xlat, uint8_t val);
287int arm_set_mem16 (arm_t *c, uint32_t addr, unsigned xlat, uint16_t val);
288int arm_set_mem32 (arm_t *c, uint32_t addr, unsigned xlat, uint32_t val);
289
290
291/*!***************************************************************************
292 * @short Initialize an ARM context
293 *****************************************************************************/
294void arm_init (arm_t *c);
295
296/*!***************************************************************************
297 * @short Create and initialize an ARM context
298 * @return The ARM context or NULL on error
299 *****************************************************************************/
300arm_t *arm_new (void);
301
302/*!***************************************************************************
303 * @short Free the resources used by an ARM context
304 *****************************************************************************/
305void arm_free (arm_t *c);
306
307/*!***************************************************************************
308 * @short Delete an ARM context
309 *****************************************************************************/
310void arm_del (arm_t *c);
311
312/*!***************************************************************************
313 * @short Set the memory access functions
314 *****************************************************************************/
315void arm_set_mem_fct (arm_t *c, void *ext,
316 void *get8, void *get16, void *get32,
317 void *set8, void *set16, void *set32
318);
319
320void arm_set_ram (arm_t *c, unsigned char *ram, unsigned long cnt);
321
322
323/*!***************************************************************************
324 * @short Get CPU flags
325 * @short c The cpu context
326 * @short flags The flags to get
327 * @return The current cpu flags masked by flags.
328 *****************************************************************************/
329unsigned arm_get_flags (const arm_t *c, unsigned flags);
330
331/*!***************************************************************************
332 * @short Set CPU flags
333 * @short c The cpu context
334 * @short flags The flags to set (ARM_FLAG_*)
335 * @short val Set the flags if non-zero, clear them otherwise
336 *
337 * Flags must be set before arm_reset() is called.
338 *****************************************************************************/
339void arm_set_flags (arm_t *c, unsigned flags, int val);
340
341unsigned long arm_get_id (arm_t *c);
342void arm_set_id (arm_t *c, unsigned long id);
343
344
345int arm_get_reg (arm_t *c, const char *reg, unsigned long *val);
346int arm_set_reg (arm_t *c, const char *reg, unsigned long val);
347
348
349/*!***************************************************************************
350 * @short Get the number of executed instructions
351 *****************************************************************************/
352unsigned long long arm_get_opcnt (arm_t *c);
353
354/*!***************************************************************************
355 * @short Get the number of clock cycles
356 *****************************************************************************/
357unsigned long long arm_get_clkcnt (arm_t *c);
358
359/*!***************************************************************************
360 * @short Get the previous instruction delay
361 *****************************************************************************/
362unsigned long arm_get_delay (arm_t *c);
363
364
365/*!***************************************************************************
366 * @short Initialize a coprocessor context
367 *****************************************************************************/
368void arm_copr_init (arm_copr_t *p);
369
370/*!***************************************************************************
371 * @short Free a coprocessor context
372 *****************************************************************************/
373void arm_copr_free (arm_copr_t *p);
374
375/*!***************************************************************************
376 * @short Check if coprocessor is present and enabled
377 * @param i The coprocessor index
378 * @return Zero if coprocessor i is present and enabled, non-zero otherwise.
379 *****************************************************************************/
380int arm_copr_check (arm_t *c, unsigned i);
381
382/*!***************************************************************************
383 * @short Set a coprocessor
384 * @param c The ARM CPU context
385 * @param i The coprocessor index
386 * @param p The coprocessor context
387 *
388 * The coprocessor context p is owned by the caller.
389 *****************************************************************************/
390void arm_set_copr (arm_t *c, unsigned i, arm_copr_t *p);
391
392
393void cp14_init (arm_copr14_t *c);
394void cp14_free (arm_copr14_t *p);
395arm_copr_t *cp14_new (void);
396void cp14_del (arm_copr14_t *p);
397
398
399/*!***************************************************************************
400 * @short Initialize a system control coprocessor context
401 *****************************************************************************/
402void cp15_init (arm_copr15_t *c);
403void cp15_free (arm_copr15_t *p);
404arm_copr_t *cp15_new (void);
405void cp15_del (arm_copr15_t *p);
406
407
408void arm_set_reg_map (arm_t *arm, unsigned mode);
409
410
411/*!***************************************************************************
412 * @short Reset an arm cpu core
413 *****************************************************************************/
414void arm_reset (arm_t *c);
415
416/*!***************************************************************************
417 * @short Execute an exception
418 *****************************************************************************/
419void arm_exception (arm_t *c, uint32_t addr, uint32_t ret, unsigned mode);
420
421void arm_exception_reset (arm_t *c);
422
423void arm_exception_undefined (arm_t *c);
424
425void arm_exception_swi (arm_t *c);
426
427void arm_exception_prefetch_abort (arm_t *c);
428
429void arm_exception_data_abort (arm_t *c);
430
431void arm_exception_irq (arm_t *c);
432
433void arm_exception_fiq (arm_t *c);
434
435/*!***************************************************************************
436 * @short The external interrupt input signal
437 *****************************************************************************/
438void arm_set_irq (arm_t *c, unsigned char val);
439
440/*!***************************************************************************
441 * @short The external fast interrupt input signal
442 *****************************************************************************/
443void arm_set_fiq (arm_t *c, unsigned char val);
444
445/*!***************************************************************************
446 * @short Execute one instruction
447 *****************************************************************************/
448void arm_execute (arm_t *c);
449
450/*!***************************************************************************
451 * @short Clock an ARM cpu core
452 *****************************************************************************/
453void arm_clock (arm_t *c, unsigned long n);
454
455
456/*****************************************************************************
457 * disasm
458 *****************************************************************************/
459
460#define ARM_DFLAG_PRIV 0x0001
461#define ARM_DFLAG_TLBM 0x0002
462#define ARM_DFLAG_CALL 0x0100
463
464typedef struct {
465 unsigned flags;
466
467 uint32_t pc;
468 uint32_t ir;
469
470 unsigned argn;
471
472 char op[64];
473 char arg[8][64];
474} arm_dasm_t;
475
476
477typedef void (*arm_dasm_f) (arm_dasm_t *da);
478
479
480void arm_dasm (arm_dasm_t *dis, uint32_t pc, uint32_t ir);
481void arm_dasm_mem (arm_t *c, arm_dasm_t *da, uint32_t pc, unsigned xlat);
482
483
484#endif