Statistics
| Branch: | Revision:

root / target-arm / helper.c @ 9ee6e8bb

History | View | Annotate | Download (50.3 kB)

1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4

    
5
#include "cpu.h"
6
#include "exec-all.h"
7
#include "gdbstub.h"
8

    
9
static uint32_t cortexa8_cp15_c0_c1[8] =
10
{ 0x1031, 0x11, 0x400, 0, 0x31100003, 0x20000000, 0x01202000, 0x11 };
11

    
12
static uint32_t cortexa8_cp15_c0_c2[8] =
13
{ 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00111142, 0, 0, 0 };
14

    
15
static uint32_t mpcore_cp15_c0_c1[8] =
16
{ 0x111, 0x1, 0, 0x2, 0x01100103, 0x10020302, 0x01222000, 0 };
17

    
18
static uint32_t mpcore_cp15_c0_c2[8] =
19
{ 0x00100011, 0x12002111, 0x11221011, 0x01102131, 0x141, 0, 0, 0 };
20

    
21
static uint32_t arm1136_cp15_c0_c1[8] =
22
{ 0x111, 0x1, 0x2, 0x3, 0x01130003, 0x10030302, 0x01222110, 0 };
23

    
24
static uint32_t arm1136_cp15_c0_c2[8] =
25
{ 0x00140011, 0x12002111, 0x11231111, 0x01102131, 0x141, 0, 0, 0 };
26

    
27
static uint32_t cpu_arm_find_by_name(const char *name);
28

    
29
static inline void set_feature(CPUARMState *env, int feature)
30
{
31
    env->features |= 1u << feature;
32
}
33

    
34
static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
35
{
36
    env->cp15.c0_cpuid = id;
37
    switch (id) {
38
    case ARM_CPUID_ARM926:
39
        set_feature(env, ARM_FEATURE_VFP);
40
        env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
41
        env->cp15.c0_cachetype = 0x1dd20d2;
42
        env->cp15.c1_sys = 0x00090078;
43
        break;
44
    case ARM_CPUID_ARM946:
45
        set_feature(env, ARM_FEATURE_MPU);
46
        env->cp15.c0_cachetype = 0x0f004006;
47
        env->cp15.c1_sys = 0x00000078;
48
        break;
49
    case ARM_CPUID_ARM1026:
50
        set_feature(env, ARM_FEATURE_VFP);
51
        set_feature(env, ARM_FEATURE_AUXCR);
52
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
53
        env->cp15.c0_cachetype = 0x1dd20d2;
54
        env->cp15.c1_sys = 0x00090078;
55
        break;
56
    case ARM_CPUID_ARM1136:
57
        set_feature(env, ARM_FEATURE_V6);
58
        set_feature(env, ARM_FEATURE_VFP);
59
        set_feature(env, ARM_FEATURE_AUXCR);
60
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
61
        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
62
        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
63
        memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t));
64
        memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t));
65
        env->cp15.c0_cachetype = 0x1dd20d2;
66
        break;
67
    case ARM_CPUID_ARM11MPCORE:
68
        set_feature(env, ARM_FEATURE_V6);
69
        set_feature(env, ARM_FEATURE_V6K);
70
        set_feature(env, ARM_FEATURE_VFP);
71
        set_feature(env, ARM_FEATURE_AUXCR);
72
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
73
        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
74
        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
75
        memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t));
76
        memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t));
77
        env->cp15.c0_cachetype = 0x1dd20d2;
78
        break;
79
    case ARM_CPUID_CORTEXA8:
80
        set_feature(env, ARM_FEATURE_V6);
81
        set_feature(env, ARM_FEATURE_V6K);
82
        set_feature(env, ARM_FEATURE_V7);
83
        set_feature(env, ARM_FEATURE_AUXCR);
84
        set_feature(env, ARM_FEATURE_THUMB2);
85
        set_feature(env, ARM_FEATURE_VFP);
86
        set_feature(env, ARM_FEATURE_VFP3);
87
        set_feature(env, ARM_FEATURE_NEON);
88
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0;
89
        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
90
        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100;
91
        memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t));
92
        memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t));
93
        env->cp15.c0_cachetype = 0x1dd20d2;
94
        break;
95
    case ARM_CPUID_CORTEXM3:
96
        set_feature(env, ARM_FEATURE_V6);
97
        set_feature(env, ARM_FEATURE_THUMB2);
98
        set_feature(env, ARM_FEATURE_V7);
99
        set_feature(env, ARM_FEATURE_M);
100
        set_feature(env, ARM_FEATURE_DIV);
101
        break;
102
    case ARM_CPUID_ANY: /* For userspace emulation.  */
103
        set_feature(env, ARM_FEATURE_V6);
104
        set_feature(env, ARM_FEATURE_V6K);
105
        set_feature(env, ARM_FEATURE_V7);
106
        set_feature(env, ARM_FEATURE_THUMB2);
107
        set_feature(env, ARM_FEATURE_VFP);
108
        set_feature(env, ARM_FEATURE_VFP3);
109
        set_feature(env, ARM_FEATURE_NEON);
110
        set_feature(env, ARM_FEATURE_DIV);
111
        break;
112
    case ARM_CPUID_TI915T:
113
    case ARM_CPUID_TI925T:
114
        set_feature(env, ARM_FEATURE_OMAPCP);
115
        env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring.  */
116
        env->cp15.c0_cachetype = 0x5109149;
117
        env->cp15.c1_sys = 0x00000070;
118
        env->cp15.c15_i_max = 0x000;
119
        env->cp15.c15_i_min = 0xff0;
120
        break;
121
    case ARM_CPUID_PXA250:
122
    case ARM_CPUID_PXA255:
123
    case ARM_CPUID_PXA260:
124
    case ARM_CPUID_PXA261:
125
    case ARM_CPUID_PXA262:
126
        set_feature(env, ARM_FEATURE_XSCALE);
127
        /* JTAG_ID is ((id << 28) | 0x09265013) */
128
        env->cp15.c0_cachetype = 0xd172172;
129
        env->cp15.c1_sys = 0x00000078;
130
        break;
131
    case ARM_CPUID_PXA270_A0:
132
    case ARM_CPUID_PXA270_A1:
133
    case ARM_CPUID_PXA270_B0:
134
    case ARM_CPUID_PXA270_B1:
135
    case ARM_CPUID_PXA270_C0:
136
    case ARM_CPUID_PXA270_C5:
137
        set_feature(env, ARM_FEATURE_XSCALE);
138
        /* JTAG_ID is ((id << 28) | 0x09265013) */
139
        set_feature(env, ARM_FEATURE_IWMMXT);
140
        env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
141
        env->cp15.c0_cachetype = 0xd172172;
142
        env->cp15.c1_sys = 0x00000078;
143
        break;
144
    default:
145
        cpu_abort(env, "Bad CPU ID: %x\n", id);
146
        break;
147
    }
148
}
149

    
150
void cpu_reset(CPUARMState *env)
151
{
152
    uint32_t id;
153
    id = env->cp15.c0_cpuid;
154
    memset(env, 0, offsetof(CPUARMState, breakpoints));
155
    if (id)
156
        cpu_reset_model_id(env, id);
157
#if defined (CONFIG_USER_ONLY)
158
    env->uncached_cpsr = ARM_CPU_MODE_USR;
159
    env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;
160
#else
161
    /* SVC mode with interrupts disabled.  */
162
    env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
163
    /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
164
       clear at reset.  */
165
    if (IS_M(env))
166
        env->uncached_cpsr &= ~CPSR_I;
167
    env->vfp.xregs[ARM_VFP_FPEXC] = 0;
168
#endif
169
    env->regs[15] = 0;
170
    tlb_flush(env, 1);
171
}
172

    
173
CPUARMState *cpu_arm_init(const char *cpu_model)
174
{
175
    CPUARMState *env;
176
    uint32_t id;
177

    
178
    id = cpu_arm_find_by_name(cpu_model);
179
    if (id == 0)
180
        return NULL;
181
    env = qemu_mallocz(sizeof(CPUARMState));
182
    if (!env)
183
        return NULL;
184
    cpu_exec_init(env);
185
    env->cp15.c0_cpuid = id;
186
    cpu_reset(env);
187
    return env;
188
}
189

    
190
struct arm_cpu_t {
191
    uint32_t id;
192
    const char *name;
193
};
194

    
195
static const struct arm_cpu_t arm_cpu_names[] = {
196
    { ARM_CPUID_ARM926, "arm926"},
197
    { ARM_CPUID_ARM946, "arm946"},
198
    { ARM_CPUID_ARM1026, "arm1026"},
199
    { ARM_CPUID_ARM1136, "arm1136"},
200
    { ARM_CPUID_ARM11MPCORE, "arm11mpcore"},
201
    { ARM_CPUID_CORTEXM3, "cortex-m3"},
202
    { ARM_CPUID_CORTEXA8, "cortex-a8"},
203
    { ARM_CPUID_TI925T, "ti925t" },
204
    { ARM_CPUID_PXA250, "pxa250" },
205
    { ARM_CPUID_PXA255, "pxa255" },
206
    { ARM_CPUID_PXA260, "pxa260" },
207
    { ARM_CPUID_PXA261, "pxa261" },
208
    { ARM_CPUID_PXA262, "pxa262" },
209
    { ARM_CPUID_PXA270, "pxa270" },
210
    { ARM_CPUID_PXA270_A0, "pxa270-a0" },
211
    { ARM_CPUID_PXA270_A1, "pxa270-a1" },
212
    { ARM_CPUID_PXA270_B0, "pxa270-b0" },
213
    { ARM_CPUID_PXA270_B1, "pxa270-b1" },
214
    { ARM_CPUID_PXA270_C0, "pxa270-c0" },
215
    { ARM_CPUID_PXA270_C5, "pxa270-c5" },
216
    { ARM_CPUID_ANY, "any"},
217
    { 0, NULL}
218
};
219

    
220
void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
221
{
222
    int i;
223

    
224
    (*cpu_fprintf)(f, "Available CPUs:\n");
225
    for (i = 0; arm_cpu_names[i].name; i++) {
226
        (*cpu_fprintf)(f, "  %s\n", arm_cpu_names[i].name);
227
    }
228
}
229

    
230
/* return 0 if not found */
231
static uint32_t cpu_arm_find_by_name(const char *name)
232
{
233
    int i;
234
    uint32_t id;
235

    
236
    id = 0;
237
    for (i = 0; arm_cpu_names[i].name; i++) {
238
        if (strcmp(name, arm_cpu_names[i].name) == 0) {
239
            id = arm_cpu_names[i].id;
240
            break;
241
        }
242
    }
243
    return id;
244
}
245

    
246
void cpu_arm_close(CPUARMState *env)
247
{
248
    free(env);
249
}
250

    
251
/* Polynomial multiplication is like integer multiplcation except the
252
   partial products are XORed, not added.  */
253
uint32_t helper_neon_mul_p8(uint32_t op1, uint32_t op2)
254
{
255
    uint32_t mask;
256
    uint32_t result;
257
    result = 0;
258
    while (op1) {
259
        mask = 0;
260
        if (op1 & 1)
261
            mask |= 0xff;
262
        if (op1 & (1 << 8))
263
            mask |= (0xff << 8);
264
        if (op1 & (1 << 16))
265
            mask |= (0xff << 16);
266
        if (op1 & (1 << 24))
267
            mask |= (0xff << 24);
268
        result ^= op2 & mask;
269
        op1 = (op1 >> 1) & 0x7f7f7f7f;
270
        op2 = (op2 << 1) & 0xfefefefe;
271
    }
272
    return result;
273
}
274

    
275
#if defined(CONFIG_USER_ONLY)
276

    
277
void do_interrupt (CPUState *env)
278
{
279
    env->exception_index = -1;
280
}
281

    
282
/* Structure used to record exclusive memory locations.  */
283
typedef struct mmon_state {
284
    struct mmon_state *next;
285
    CPUARMState *cpu_env;
286
    uint32_t addr;
287
} mmon_state;
288

    
289
/* Chain of current locks.  */
290
static mmon_state* mmon_head = NULL;
291

    
292
int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
293
                              int mmu_idx, int is_softmmu)
294
{
295
    if (rw == 2) {
296
        env->exception_index = EXCP_PREFETCH_ABORT;
297
        env->cp15.c6_insn = address;
298
    } else {
299
        env->exception_index = EXCP_DATA_ABORT;
300
        env->cp15.c6_data = address;
301
    }
302
    return 1;
303
}
304

    
305
static void allocate_mmon_state(CPUState *env)
306
{
307
    env->mmon_entry = malloc(sizeof (mmon_state));
308
    if (!env->mmon_entry)
309
        abort();
310
    memset (env->mmon_entry, 0, sizeof (mmon_state));
311
    env->mmon_entry->cpu_env = env;
312
    mmon_head = env->mmon_entry;
313
}
314

    
315
/* Flush any monitor locks for the specified address.  */
316
static void flush_mmon(uint32_t addr)
317
{
318
    mmon_state *mon;
319

    
320
    for (mon = mmon_head; mon; mon = mon->next)
321
      {
322
        if (mon->addr != addr)
323
          continue;
324

    
325
        mon->addr = 0;
326
        break;
327
      }
328
}
329

    
330
/* Mark an address for exclusive access.  */
331
void helper_mark_exclusive(CPUState *env, uint32_t addr)
332
{
333
    if (!env->mmon_entry)
334
        allocate_mmon_state(env);
335
    /* Clear any previous locks.  */
336
    flush_mmon(addr);
337
    env->mmon_entry->addr = addr;
338
}
339

    
340
/* Test if an exclusive address is still exclusive.  Returns zero
341
   if the address is still exclusive.   */
342
int helper_test_exclusive(CPUState *env, uint32_t addr)
343
{
344
    int res;
345

    
346
    if (!env->mmon_entry)
347
        return 1;
348
    if (env->mmon_entry->addr == addr)
349
        res = 0;
350
    else
351
        res = 1;
352
    flush_mmon(addr);
353
    return res;
354
}
355

    
356
void helper_clrex(CPUState *env)
357
{
358
    if (!(env->mmon_entry && env->mmon_entry->addr))
359
        return;
360
    flush_mmon(env->mmon_entry->addr);
361
}
362

    
363
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
364
{
365
    return addr;
366
}
367

    
368
/* These should probably raise undefined insn exceptions.  */
369
void helper_set_cp(CPUState *env, uint32_t insn, uint32_t val)
370
{
371
    int op1 = (insn >> 8) & 0xf;
372
    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
373
    return;
374
}
375

    
376
uint32_t helper_get_cp(CPUState *env, uint32_t insn)
377
{
378
    int op1 = (insn >> 8) & 0xf;
379
    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
380
    return 0;
381
}
382

    
383
void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val)
384
{
385
    cpu_abort(env, "cp15 insn %08x\n", insn);
386
}
387

    
388
uint32_t helper_get_cp15(CPUState *env, uint32_t insn)
389
{
390
    cpu_abort(env, "cp15 insn %08x\n", insn);
391
    return 0;
392
}
393

    
394
/* These should probably raise undefined insn exceptions.  */
395
void helper_v7m_msr(CPUState *env, int reg, uint32_t val)
396
{
397
    cpu_abort(env, "v7m_mrs %d\n", reg);
398
}
399

    
400
uint32_t helper_v7m_mrs(CPUState *env, int reg)
401
{
402
    cpu_abort(env, "v7m_mrs %d\n", reg);
403
    return 0;
404
}
405

    
406
void switch_mode(CPUState *env, int mode)
407
{
408
    if (mode != ARM_CPU_MODE_USR)
409
        cpu_abort(env, "Tried to switch out of user mode\n");
410
}
411

    
412
void helper_set_r13_banked(CPUState *env, int mode, uint32_t val)
413
{
414
    cpu_abort(env, "banked r13 write\n");
415
}
416

    
417
uint32_t helper_get_r13_banked(CPUState *env, int mode)
418
{
419
    cpu_abort(env, "banked r13 read\n");
420
    return 0;
421
}
422

    
423
#else
424

    
425
extern int semihosting_enabled;
426

    
427
/* Map CPU modes onto saved register banks.  */
428
static inline int bank_number (int mode)
429
{
430
    switch (mode) {
431
    case ARM_CPU_MODE_USR:
432
    case ARM_CPU_MODE_SYS:
433
        return 0;
434
    case ARM_CPU_MODE_SVC:
435
        return 1;
436
    case ARM_CPU_MODE_ABT:
437
        return 2;
438
    case ARM_CPU_MODE_UND:
439
        return 3;
440
    case ARM_CPU_MODE_IRQ:
441
        return 4;
442
    case ARM_CPU_MODE_FIQ:
443
        return 5;
444
    }
445
    cpu_abort(cpu_single_env, "Bad mode %x\n", mode);
446
    return -1;
447
}
448

    
449
void switch_mode(CPUState *env, int mode)
450
{
451
    int old_mode;
452
    int i;
453

    
454
    old_mode = env->uncached_cpsr & CPSR_M;
455
    if (mode == old_mode)
456
        return;
457

    
458
    if (old_mode == ARM_CPU_MODE_FIQ) {
459
        memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
460
        memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
461
    } else if (mode == ARM_CPU_MODE_FIQ) {
462
        memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
463
        memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
464
    }
465

    
466
    i = bank_number(old_mode);
467
    env->banked_r13[i] = env->regs[13];
468
    env->banked_r14[i] = env->regs[14];
469
    env->banked_spsr[i] = env->spsr;
470

    
471
    i = bank_number(mode);
472
    env->regs[13] = env->banked_r13[i];
473
    env->regs[14] = env->banked_r14[i];
474
    env->spsr = env->banked_spsr[i];
475
}
476

    
477
static void v7m_push(CPUARMState *env, uint32_t val)
478
{
479
    env->regs[13] -= 4;
480
    stl_phys(env->regs[13], val);
481
}
482

    
483
static uint32_t v7m_pop(CPUARMState *env)
484
{
485
    uint32_t val;
486
    val = ldl_phys(env->regs[13]);
487
    env->regs[13] += 4;
488
    return val;
489
}
490

    
491
/* Switch to V7M main or process stack pointer.  */
492
static void switch_v7m_sp(CPUARMState *env, int process)
493
{
494
    uint32_t tmp;
495
    if (env->v7m.current_sp != process) {
496
        tmp = env->v7m.other_sp;
497
        env->v7m.other_sp = env->regs[13];
498
        env->regs[13] = tmp;
499
        env->v7m.current_sp = process;
500
    }
501
}
502

    
503
static void do_v7m_exception_exit(CPUARMState *env)
504
{
505
    uint32_t type;
506
    uint32_t xpsr;
507

    
508
    type = env->regs[15];
509
    if (env->v7m.exception != 0)
510
        armv7m_nvic_complete_irq(env->v7m.nvic, env->v7m.exception);
511

    
512
    /* Switch to the target stack.  */
513
    switch_v7m_sp(env, (type & 4) != 0);
514
    /* Pop registers.  */
515
    env->regs[0] = v7m_pop(env);
516
    env->regs[1] = v7m_pop(env);
517
    env->regs[2] = v7m_pop(env);
518
    env->regs[3] = v7m_pop(env);
519
    env->regs[12] = v7m_pop(env);
520
    env->regs[14] = v7m_pop(env);
521
    env->regs[15] = v7m_pop(env);
522
    xpsr = v7m_pop(env);
523
    xpsr_write(env, xpsr, 0xfffffdff);
524
    /* Undo stack alignment.  */
525
    if (xpsr & 0x200)
526
        env->regs[13] |= 4;
527
    /* ??? The exception return type specifies Thread/Handler mode.  However
528
       this is also implied by the xPSR value. Not sure what to do
529
       if there is a mismatch.  */
530
    /* ??? Likewise for mismatches between the CONTROL register and the stack
531
       pointer.  */
532
}
533

    
534
void do_interrupt_v7m(CPUARMState *env)
535
{
536
    uint32_t xpsr = xpsr_read(env);
537
    uint32_t lr;
538
    uint32_t addr;
539

    
540
    lr = 0xfffffff1;
541
    if (env->v7m.current_sp)
542
        lr |= 4;
543
    if (env->v7m.exception == 0)
544
        lr |= 8;
545

    
546
    /* For exceptions we just mark as pending on the NVIC, and let that
547
       handle it.  */
548
    /* TODO: Need to escalate if the current priority is higher than the
549
       one we're raising.  */
550
    switch (env->exception_index) {
551
    case EXCP_UDEF:
552
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_USAGE);
553
        return;
554
    case EXCP_SWI:
555
        env->regs[15] += 2;
556
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_SVC);
557
        return;
558
    case EXCP_PREFETCH_ABORT:
559
    case EXCP_DATA_ABORT:
560
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_MEM);
561
        return;
562
    case EXCP_BKPT:
563
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_DEBUG);
564
        return;
565
    case EXCP_IRQ:
566
        env->v7m.exception = armv7m_nvic_acknowledge_irq(env->v7m.nvic);
567
        break;
568
    case EXCP_EXCEPTION_EXIT:
569
        do_v7m_exception_exit(env);
570
        return;
571
    default:
572
        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
573
        return; /* Never happens.  Keep compiler happy.  */
574
    }
575

    
576
    /* Align stack pointer.  */
577
    /* ??? Should only do this if Configuration Control Register
578
       STACKALIGN bit is set.  */
579
    if (env->regs[13] & 4) {
580
        env->regs[13] += 4;
581
        xpsr |= 0x200;
582
    }
583
    /* Switch to the hander mode.  */
584
    v7m_push(env, xpsr);
585
    v7m_push(env, env->regs[15]);
586
    v7m_push(env, env->regs[14]);
587
    v7m_push(env, env->regs[12]);
588
    v7m_push(env, env->regs[3]);
589
    v7m_push(env, env->regs[2]);
590
    v7m_push(env, env->regs[1]);
591
    v7m_push(env, env->regs[0]);
592
    switch_v7m_sp(env, 0);
593
    env->uncached_cpsr &= ~CPSR_IT;
594
    env->regs[14] = lr;
595
    addr = ldl_phys(env->v7m.vecbase + env->v7m.exception * 4);
596
    env->regs[15] = addr & 0xfffffffe;
597
    env->thumb = addr & 1;
598
}
599

    
600
/* Handle a CPU exception.  */
601
void do_interrupt(CPUARMState *env)
602
{
603
    uint32_t addr;
604
    uint32_t mask;
605
    int new_mode;
606
    uint32_t offset;
607

    
608
    if (IS_M(env)) {
609
        do_interrupt_v7m(env);
610
        return;
611
    }
612
    /* TODO: Vectored interrupt controller.  */
613
    switch (env->exception_index) {
614
    case EXCP_UDEF:
615
        new_mode = ARM_CPU_MODE_UND;
616
        addr = 0x04;
617
        mask = CPSR_I;
618
        if (env->thumb)
619
            offset = 2;
620
        else
621
            offset = 4;
622
        break;
623
    case EXCP_SWI:
624
        if (semihosting_enabled) {
625
            /* Check for semihosting interrupt.  */
626
            if (env->thumb) {
627
                mask = lduw_code(env->regs[15] - 2) & 0xff;
628
            } else {
629
                mask = ldl_code(env->regs[15] - 4) & 0xffffff;
630
            }
631
            /* Only intercept calls from privileged modes, to provide some
632
               semblance of security.  */
633
            if (((mask == 0x123456 && !env->thumb)
634
                    || (mask == 0xab && env->thumb))
635
                  && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
636
                env->regs[0] = do_arm_semihosting(env);
637
                return;
638
            }
639
        }
640
        new_mode = ARM_CPU_MODE_SVC;
641
        addr = 0x08;
642
        mask = CPSR_I;
643
        /* The PC already points to the next instructon.  */
644
        offset = 0;
645
        break;
646
    case EXCP_BKPT:
647
        /* See if this is a semihosting syscall.  */
648
        if (env->thumb) {
649
            mask = lduw_code(env->regs[15]) & 0xff;
650
            if (mask == 0xab
651
                  && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
652
                env->regs[15] += 2;
653
                env->regs[0] = do_arm_semihosting(env);
654
                return;
655
            }
656
        }
657
        /* Fall through to prefetch abort.  */
658
    case EXCP_PREFETCH_ABORT:
659
        new_mode = ARM_CPU_MODE_ABT;
660
        addr = 0x0c;
661
        mask = CPSR_A | CPSR_I;
662
        offset = 4;
663
        break;
664
    case EXCP_DATA_ABORT:
665
        new_mode = ARM_CPU_MODE_ABT;
666
        addr = 0x10;
667
        mask = CPSR_A | CPSR_I;
668
        offset = 8;
669
        break;
670
    case EXCP_IRQ:
671
        new_mode = ARM_CPU_MODE_IRQ;
672
        addr = 0x18;
673
        /* Disable IRQ and imprecise data aborts.  */
674
        mask = CPSR_A | CPSR_I;
675
        offset = 4;
676
        break;
677
    case EXCP_FIQ:
678
        new_mode = ARM_CPU_MODE_FIQ;
679
        addr = 0x1c;
680
        /* Disable FIQ, IRQ and imprecise data aborts.  */
681
        mask = CPSR_A | CPSR_I | CPSR_F;
682
        offset = 4;
683
        break;
684
    default:
685
        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
686
        return; /* Never happens.  Keep compiler happy.  */
687
    }
688
    /* High vectors.  */
689
    if (env->cp15.c1_sys & (1 << 13)) {
690
        addr += 0xffff0000;
691
    }
692
    switch_mode (env, new_mode);
693
    env->spsr = cpsr_read(env);
694
    /* Clear IT bits.  */
695
    env->condexec_bits = 0;
696
    /* Switch to the new mode, and switch to Arm mode.  */
697
    /* ??? Thumb interrupt handlers not implemented.  */
698
    env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
699
    env->uncached_cpsr |= mask;
700
    env->thumb = 0;
701
    env->regs[14] = env->regs[15] + offset;
702
    env->regs[15] = addr;
703
    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
704
}
705

    
706
/* Check section/page access permissions.
707
   Returns the page protection flags, or zero if the access is not
708
   permitted.  */
709
static inline int check_ap(CPUState *env, int ap, int domain, int access_type,
710
                           int is_user)
711
{
712
  int prot_ro;
713

    
714
  if (domain == 3)
715
    return PAGE_READ | PAGE_WRITE;
716

    
717
  if (access_type == 1)
718
      prot_ro = 0;
719
  else
720
      prot_ro = PAGE_READ;
721

    
722
  switch (ap) {
723
  case 0:
724
      if (access_type == 1)
725
          return 0;
726
      switch ((env->cp15.c1_sys >> 8) & 3) {
727
      case 1:
728
          return is_user ? 0 : PAGE_READ;
729
      case 2:
730
          return PAGE_READ;
731
      default:
732
          return 0;
733
      }
734
  case 1:
735
      return is_user ? 0 : PAGE_READ | PAGE_WRITE;
736
  case 2:
737
      if (is_user)
738
          return prot_ro;
739
      else
740
          return PAGE_READ | PAGE_WRITE;
741
  case 3:
742
      return PAGE_READ | PAGE_WRITE;
743
  case 4: case 7: /* Reserved.  */
744
      return 0;
745
  case 5:
746
      return is_user ? 0 : prot_ro;
747
  case 6:
748
      return prot_ro;
749
  default:
750
      abort();
751
  }
752
}
753

    
754
static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
755
                            int is_user, uint32_t *phys_ptr, int *prot)
756
{
757
    int code;
758
    uint32_t table;
759
    uint32_t desc;
760
    int type;
761
    int ap;
762
    int domain;
763
    uint32_t phys_addr;
764

    
765
    /* Pagetable walk.  */
766
    /* Lookup l1 descriptor.  */
767
    if (address & env->cp15.c2_mask)
768
        table = env->cp15.c2_base1;
769
    else
770
        table = env->cp15.c2_base0;
771
    table = (table & 0xffffc000) | ((address >> 18) & 0x3ffc);
772
    desc = ldl_phys(table);
773
    type = (desc & 3);
774
    domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3;
775
    if (type == 0) {
776
        /* Secton translation fault.  */
777
        code = 5;
778
        goto do_fault;
779
    }
780
    if (domain == 0 || domain == 2) {
781
        if (type == 2)
782
            code = 9; /* Section domain fault.  */
783
        else
784
            code = 11; /* Page domain fault.  */
785
        goto do_fault;
786
    }
787
    if (type == 2) {
788
        /* 1Mb section.  */
789
        phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
790
        ap = (desc >> 10) & 3;
791
        code = 13;
792
    } else {
793
        /* Lookup l2 entry.  */
794
        if (type == 1) {
795
            /* Coarse pagetable.  */
796
            table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
797
        } else {
798
            /* Fine pagetable.  */
799
            table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
800
        }
801
        desc = ldl_phys(table);
802
        switch (desc & 3) {
803
        case 0: /* Page translation fault.  */
804
            code = 7;
805
            goto do_fault;
806
        case 1: /* 64k page.  */
807
            phys_addr = (desc & 0xffff0000) | (address & 0xffff);
808
            ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
809
            break;
810
        case 2: /* 4k page.  */
811
            phys_addr = (desc & 0xfffff000) | (address & 0xfff);
812
            ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
813
            break;
814
        case 3: /* 1k page.  */
815
            if (type == 1) {
816
                if (arm_feature(env, ARM_FEATURE_XSCALE)) {
817
                    phys_addr = (desc & 0xfffff000) | (address & 0xfff);
818
                } else {
819
                    /* Page translation fault.  */
820
                    code = 7;
821
                    goto do_fault;
822
                }
823
            } else {
824
                phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
825
            }
826
            ap = (desc >> 4) & 3;
827
            break;
828
        default:
829
            /* Never happens, but compiler isn't smart enough to tell.  */
830
            abort();
831
        }
832
        code = 15;
833
    }
834
    *prot = check_ap(env, ap, domain, access_type, is_user);
835
    if (!*prot) {
836
        /* Access permission fault.  */
837
        goto do_fault;
838
    }
839
    *phys_ptr = phys_addr;
840
    return 0;
841
do_fault:
842
    return code | (domain << 4);
843
}
844

    
845
static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
846
                            int is_user, uint32_t *phys_ptr, int *prot)
847
{
848
    int code;
849
    uint32_t table;
850
    uint32_t desc;
851
    uint32_t xn;
852
    int type;
853
    int ap;
854
    int domain;
855
    uint32_t phys_addr;
856

    
857
    /* Pagetable walk.  */
858
    /* Lookup l1 descriptor.  */
859
    if (address & env->cp15.c2_mask)
860
        table = env->cp15.c2_base1;
861
    else
862
        table = env->cp15.c2_base0;
863
    table = (table & 0xffffc000) | ((address >> 18) & 0x3ffc);
864
    desc = ldl_phys(table);
865
    type = (desc & 3);
866
    if (type == 0) {
867
        /* Secton translation fault.  */
868
        code = 5;
869
        domain = 0;
870
        goto do_fault;
871
    } else if (type == 2 && (desc & (1 << 18))) {
872
        /* Supersection.  */
873
        domain = 0;
874
    } else {
875
        /* Section or page.  */
876
        domain = (desc >> 4) & 0x1e;
877
    }
878
    domain = (env->cp15.c3 >> domain) & 3;
879
    if (domain == 0 || domain == 2) {
880
        if (type == 2)
881
            code = 9; /* Section domain fault.  */
882
        else
883
            code = 11; /* Page domain fault.  */
884
        goto do_fault;
885
    }
886
    if (type == 2) {
887
        if (desc & (1 << 18)) {
888
            /* Supersection.  */
889
            phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
890
        } else {
891
            /* Section.  */
892
            phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
893
        }
894
        ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
895
        xn = desc & (1 << 4);
896
        code = 13;
897
    } else {
898
        /* Lookup l2 entry.  */
899
        table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
900
        desc = ldl_phys(table);
901
        ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
902
        switch (desc & 3) {
903
        case 0: /* Page translation fault.  */
904
            code = 7;
905
            goto do_fault;
906
        case 1: /* 64k page.  */
907
            phys_addr = (desc & 0xffff0000) | (address & 0xffff);
908
            xn = desc & (1 << 15);
909
            break;
910
        case 2: case 3: /* 4k page.  */
911
            phys_addr = (desc & 0xfffff000) | (address & 0xfff);
912
            xn = desc & 1;
913
            break;
914
        default:
915
            /* Never happens, but compiler isn't smart enough to tell.  */
916
            abort();
917
        }
918
        code = 15;
919
    }
920
    if (xn && access_type == 2)
921
        goto do_fault;
922

    
923
    *prot = check_ap(env, ap, domain, access_type, is_user);
924
    if (!*prot) {
925
        /* Access permission fault.  */
926
        goto do_fault;
927
    }
928
    *phys_ptr = phys_addr;
929
    return 0;
930
do_fault:
931
    return code | (domain << 4);
932
}
933

    
934
static int get_phys_addr_mpu(CPUState *env, uint32_t address, int access_type,
935
                             int is_user, uint32_t *phys_ptr, int *prot)
936
{
937
    int n;
938
    uint32_t mask;
939
    uint32_t base;
940

    
941
    *phys_ptr = address;
942
    for (n = 7; n >= 0; n--) {
943
        base = env->cp15.c6_region[n];
944
        if ((base & 1) == 0)
945
            continue;
946
        mask = 1 << ((base >> 1) & 0x1f);
947
        /* Keep this shift separate from the above to avoid an
948
           (undefined) << 32.  */
949
        mask = (mask << 1) - 1;
950
        if (((base ^ address) & ~mask) == 0)
951
            break;
952
    }
953
    if (n < 0)
954
        return 2;
955

    
956
    if (access_type == 2) {
957
        mask = env->cp15.c5_insn;
958
    } else {
959
        mask = env->cp15.c5_data;
960
    }
961
    mask = (mask >> (n * 4)) & 0xf;
962
    switch (mask) {
963
    case 0:
964
        return 1;
965
    case 1:
966
        if (is_user)
967
          return 1;
968
        *prot = PAGE_READ | PAGE_WRITE;
969
        break;
970
    case 2:
971
        *prot = PAGE_READ;
972
        if (!is_user)
973
            *prot |= PAGE_WRITE;
974
        break;
975
    case 3:
976
        *prot = PAGE_READ | PAGE_WRITE;
977
        break;
978
    case 5:
979
        if (is_user)
980
            return 1;
981
        *prot = PAGE_READ;
982
        break;
983
    case 6:
984
        *prot = PAGE_READ;
985
        break;
986
    default:
987
        /* Bad permission.  */
988
        return 1;
989
    }
990
    return 0;
991
}
992

    
993
static inline int get_phys_addr(CPUState *env, uint32_t address,
994
                                int access_type, int is_user,
995
                                uint32_t *phys_ptr, int *prot)
996
{
997
    /* Fast Context Switch Extension.  */
998
    if (address < 0x02000000)
999
        address += env->cp15.c13_fcse;
1000

    
1001
    if ((env->cp15.c1_sys & 1) == 0) {
1002
        /* MMU/MPU disabled.  */
1003
        *phys_ptr = address;
1004
        *prot = PAGE_READ | PAGE_WRITE;
1005
        return 0;
1006
    } else if (arm_feature(env, ARM_FEATURE_MPU)) {
1007
        return get_phys_addr_mpu(env, address, access_type, is_user, phys_ptr,
1008
                                 prot);
1009
    } else if (env->cp15.c1_sys & (1 << 23)) {
1010
        return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,
1011
                                prot);
1012
    } else {
1013
        return get_phys_addr_v5(env, address, access_type, is_user, phys_ptr,
1014
                                prot);
1015
    }
1016
}
1017

    
1018
int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
1019
                              int access_type, int mmu_idx, int is_softmmu)
1020
{
1021
    uint32_t phys_addr;
1022
    int prot;
1023
    int ret, is_user;
1024

    
1025
    is_user = mmu_idx == MMU_USER_IDX;
1026
    ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot);
1027
    if (ret == 0) {
1028
        /* Map a single [sub]page.  */
1029
        phys_addr &= ~(uint32_t)0x3ff;
1030
        address &= ~(uint32_t)0x3ff;
1031
        return tlb_set_page (env, address, phys_addr, prot, mmu_idx,
1032
                             is_softmmu);
1033
    }
1034

    
1035
    if (access_type == 2) {
1036
        env->cp15.c5_insn = ret;
1037
        env->cp15.c6_insn = address;
1038
        env->exception_index = EXCP_PREFETCH_ABORT;
1039
    } else {
1040
        env->cp15.c5_data = ret;
1041
        if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6))
1042
            env->cp15.c5_data |= (1 << 11);
1043
        env->cp15.c6_data = address;
1044
        env->exception_index = EXCP_DATA_ABORT;
1045
    }
1046
    return 1;
1047
}
1048

    
1049
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1050
{
1051
    uint32_t phys_addr;
1052
    int prot;
1053
    int ret;
1054

    
1055
    ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot);
1056

    
1057
    if (ret != 0)
1058
        return -1;
1059

    
1060
    return phys_addr;
1061
}
1062

    
1063
/* Not really implemented.  Need to figure out a sane way of doing this.
1064
   Maybe add generic watchpoint support and use that.  */
1065

    
1066
void helper_mark_exclusive(CPUState *env, uint32_t addr)
1067
{
1068
    env->mmon_addr = addr;
1069
}
1070

    
1071
int helper_test_exclusive(CPUState *env, uint32_t addr)
1072
{
1073
    return (env->mmon_addr != addr);
1074
}
1075

    
1076
void helper_clrex(CPUState *env)
1077
{
1078
    env->mmon_addr = -1;
1079
}
1080

    
1081
void helper_set_cp(CPUState *env, uint32_t insn, uint32_t val)
1082
{
1083
    int cp_num = (insn >> 8) & 0xf;
1084
    int cp_info = (insn >> 5) & 7;
1085
    int src = (insn >> 16) & 0xf;
1086
    int operand = insn & 0xf;
1087

    
1088
    if (env->cp[cp_num].cp_write)
1089
        env->cp[cp_num].cp_write(env->cp[cp_num].opaque,
1090
                                 cp_info, src, operand, val);
1091
}
1092

    
1093
uint32_t helper_get_cp(CPUState *env, uint32_t insn)
1094
{
1095
    int cp_num = (insn >> 8) & 0xf;
1096
    int cp_info = (insn >> 5) & 7;
1097
    int dest = (insn >> 16) & 0xf;
1098
    int operand = insn & 0xf;
1099

    
1100
    if (env->cp[cp_num].cp_read)
1101
        return env->cp[cp_num].cp_read(env->cp[cp_num].opaque,
1102
                                       cp_info, dest, operand);
1103
    return 0;
1104
}
1105

    
1106
/* Return basic MPU access permission bits.  */
1107
static uint32_t simple_mpu_ap_bits(uint32_t val)
1108
{
1109
    uint32_t ret;
1110
    uint32_t mask;
1111
    int i;
1112
    ret = 0;
1113
    mask = 3;
1114
    for (i = 0; i < 16; i += 2) {
1115
        ret |= (val >> i) & mask;
1116
        mask <<= 2;
1117
    }
1118
    return ret;
1119
}
1120

    
1121
/* Pad basic MPU access permission bits to extended format.  */
1122
static uint32_t extended_mpu_ap_bits(uint32_t val)
1123
{
1124
    uint32_t ret;
1125
    uint32_t mask;
1126
    int i;
1127
    ret = 0;
1128
    mask = 3;
1129
    for (i = 0; i < 16; i += 2) {
1130
        ret |= (val & mask) << i;
1131
        mask <<= 2;
1132
    }
1133
    return ret;
1134
}
1135

    
1136
void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val)
1137
{
1138
    int op1;
1139
    int op2;
1140
    int crm;
1141

    
1142
    op1 = (insn >> 21) & 7;
1143
    op2 = (insn >> 5) & 7;
1144
    crm = insn & 0xf;
1145
    switch ((insn >> 16) & 0xf) {
1146
    case 0:
1147
        if (((insn >> 21) & 7) == 2) {
1148
            /* ??? Select cache level.  Ignore.  */
1149
            return;
1150
        }
1151
        /* ID codes.  */
1152
        if (arm_feature(env, ARM_FEATURE_XSCALE))
1153
            break;
1154
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1155
            break;
1156
        goto bad_reg;
1157
    case 1: /* System configuration.  */
1158
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1159
            op2 = 0;
1160
        switch (op2) {
1161
        case 0:
1162
            if (!arm_feature(env, ARM_FEATURE_XSCALE) || crm == 0)
1163
                env->cp15.c1_sys = val;
1164
            /* ??? Lots of these bits are not implemented.  */
1165
            /* This may enable/disable the MMU, so do a TLB flush.  */
1166
            tlb_flush(env, 1);
1167
            break;
1168
        case 1: /* Auxiliary cotrol register.  */
1169
            if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1170
                env->cp15.c1_xscaleauxcr = val;
1171
                break;
1172
            }
1173
            /* Not implemented.  */
1174
            break;
1175
        case 2:
1176
            if (arm_feature(env, ARM_FEATURE_XSCALE))
1177
                goto bad_reg;
1178
            env->cp15.c1_coproc = val;
1179
            /* ??? Is this safe when called from within a TB?  */
1180
            tb_flush(env);
1181
            break;
1182
        default:
1183
            goto bad_reg;
1184
        }
1185
        break;
1186
    case 2: /* MMU Page table control / MPU cache control.  */
1187
        if (arm_feature(env, ARM_FEATURE_MPU)) {
1188
            switch (op2) {
1189
            case 0:
1190
                env->cp15.c2_data = val;
1191
                break;
1192
            case 1:
1193
                env->cp15.c2_insn = val;
1194
                break;
1195
            default:
1196
                goto bad_reg;
1197
            }
1198
        } else {
1199
            switch (op2) {
1200
            case 0:
1201
                env->cp15.c2_base0 = val;
1202
                break;
1203
            case 1:
1204
                env->cp15.c2_base1 = val;
1205
                break;
1206
            case 2:
1207
                env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val);
1208
                break;
1209
            default:
1210
                goto bad_reg;
1211
            }
1212
        }
1213
        break;
1214
    case 3: /* MMU Domain access control / MPU write buffer control.  */
1215
        env->cp15.c3 = val;
1216
        tlb_flush(env, 1); /* Flush TLB as domain not tracked in TLB */
1217
        break;
1218
    case 4: /* Reserved.  */
1219
        goto bad_reg;
1220
    case 5: /* MMU Fault status / MPU access permission.  */
1221
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1222
            op2 = 0;
1223
        switch (op2) {
1224
        case 0:
1225
            if (arm_feature(env, ARM_FEATURE_MPU))
1226
                val = extended_mpu_ap_bits(val);
1227
            env->cp15.c5_data = val;
1228
            break;
1229
        case 1:
1230
            if (arm_feature(env, ARM_FEATURE_MPU))
1231
                val = extended_mpu_ap_bits(val);
1232
            env->cp15.c5_insn = val;
1233
            break;
1234
        case 2:
1235
            if (!arm_feature(env, ARM_FEATURE_MPU))
1236
                goto bad_reg;
1237
            env->cp15.c5_data = val;
1238
            break;
1239
        case 3:
1240
            if (!arm_feature(env, ARM_FEATURE_MPU))
1241
                goto bad_reg;
1242
            env->cp15.c5_insn = val;
1243
            break;
1244
        default:
1245
            goto bad_reg;
1246
        }
1247
        break;
1248
    case 6: /* MMU Fault address / MPU base/size.  */
1249
        if (arm_feature(env, ARM_FEATURE_MPU)) {
1250
            if (crm >= 8)
1251
                goto bad_reg;
1252
            env->cp15.c6_region[crm] = val;
1253
        } else {
1254
            if (arm_feature(env, ARM_FEATURE_OMAPCP))
1255
                op2 = 0;
1256
            switch (op2) {
1257
            case 0:
1258
                env->cp15.c6_data = val;
1259
                break;
1260
            case 1: /* ??? This is WFAR on armv6 */
1261
            case 2:
1262
                env->cp15.c6_insn = val;
1263
                break;
1264
            default:
1265
                goto bad_reg;
1266
            }
1267
        }
1268
        break;
1269
    case 7: /* Cache control.  */
1270
        env->cp15.c15_i_max = 0x000;
1271
        env->cp15.c15_i_min = 0xff0;
1272
        /* No cache, so nothing to do.  */
1273
        /* ??? MPCore has VA to PA translation functions.  */
1274
        break;
1275
    case 8: /* MMU TLB control.  */
1276
        switch (op2) {
1277
        case 0: /* Invalidate all.  */
1278
            tlb_flush(env, 0);
1279
            break;
1280
        case 1: /* Invalidate single TLB entry.  */
1281
#if 0
1282
            /* ??? This is wrong for large pages and sections.  */
1283
            /* As an ugly hack to make linux work we always flush a 4K
1284
               pages.  */
1285
            val &= 0xfffff000;
1286
            tlb_flush_page(env, val);
1287
            tlb_flush_page(env, val + 0x400);
1288
            tlb_flush_page(env, val + 0x800);
1289
            tlb_flush_page(env, val + 0xc00);
1290
#else
1291
            tlb_flush(env, 1);
1292
#endif
1293
            break;
1294
        case 2: /* Invalidate on ASID.  */
1295
            tlb_flush(env, val == 0);
1296
            break;
1297
        case 3: /* Invalidate single entry on MVA.  */
1298
            /* ??? This is like case 1, but ignores ASID.  */
1299
            tlb_flush(env, 1);
1300
            break;
1301
        default:
1302
            goto bad_reg;
1303
        }
1304
        break;
1305
    case 9:
1306
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1307
            break;
1308
        switch (crm) {
1309
        case 0: /* Cache lockdown.  */
1310
            switch (op1) {
1311
            case 0: /* L1 cache.  */
1312
                switch (op2) {
1313
                case 0:
1314
                    env->cp15.c9_data = val;
1315
                    break;
1316
                case 1:
1317
                    env->cp15.c9_insn = val;
1318
                    break;
1319
                default:
1320
                    goto bad_reg;
1321
                }
1322
                break;
1323
            case 1: /* L2 cache.  */
1324
                /* Ignore writes to L2 lockdown/auxiliary registers.  */
1325
                break;
1326
            default:
1327
                goto bad_reg;
1328
            }
1329
            break;
1330
        case 1: /* TCM memory region registers.  */
1331
            /* Not implemented.  */
1332
            goto bad_reg;
1333
        default:
1334
            goto bad_reg;
1335
        }
1336
        break;
1337
    case 10: /* MMU TLB lockdown.  */
1338
        /* ??? TLB lockdown not implemented.  */
1339
        break;
1340
    case 12: /* Reserved.  */
1341
        goto bad_reg;
1342
    case 13: /* Process ID.  */
1343
        switch (op2) {
1344
        case 0:
1345
            /* Unlike real hardware the qemu TLB uses virtual addresses,
1346
               not modified virtual addresses, so this causes a TLB flush.
1347
             */
1348
            if (env->cp15.c13_fcse != val)
1349
              tlb_flush(env, 1);
1350
            env->cp15.c13_fcse = val;
1351
            break;
1352
        case 1:
1353
            /* This changes the ASID, so do a TLB flush.  */
1354
            if (env->cp15.c13_context != val
1355
                && !arm_feature(env, ARM_FEATURE_MPU))
1356
              tlb_flush(env, 0);
1357
            env->cp15.c13_context = val;
1358
            break;
1359
        case 2:
1360
            env->cp15.c13_tls1 = val;
1361
            break;
1362
        case 3:
1363
            env->cp15.c13_tls2 = val;
1364
            break;
1365
        case 4:
1366
            env->cp15.c13_tls3 = val;
1367
            break;
1368
        default:
1369
            goto bad_reg;
1370
        }
1371
        break;
1372
    case 14: /* Reserved.  */
1373
        goto bad_reg;
1374
    case 15: /* Implementation specific.  */
1375
        if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1376
            if (op2 == 0 && crm == 1) {
1377
                if (env->cp15.c15_cpar != (val & 0x3fff)) {
1378
                    /* Changes cp0 to cp13 behavior, so needs a TB flush.  */
1379
                    tb_flush(env);
1380
                    env->cp15.c15_cpar = val & 0x3fff;
1381
                }
1382
                break;
1383
            }
1384
            goto bad_reg;
1385
        }
1386
        if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
1387
            switch (crm) {
1388
            case 0:
1389
                break;
1390
            case 1: /* Set TI925T configuration.  */
1391
                env->cp15.c15_ticonfig = val & 0xe7;
1392
                env->cp15.c0_cpuid = (val & (1 << 5)) ? /* OS_TYPE bit */
1393
                        ARM_CPUID_TI915T : ARM_CPUID_TI925T;
1394
                break;
1395
            case 2: /* Set I_max.  */
1396
                env->cp15.c15_i_max = val;
1397
                break;
1398
            case 3: /* Set I_min.  */
1399
                env->cp15.c15_i_min = val;
1400
                break;
1401
            case 4: /* Set thread-ID.  */
1402
                env->cp15.c15_threadid = val & 0xffff;
1403
                break;
1404
            case 8: /* Wait-for-interrupt (deprecated).  */
1405
                cpu_interrupt(env, CPU_INTERRUPT_HALT);
1406
                break;
1407
            default:
1408
                goto bad_reg;
1409
            }
1410
        }
1411
        break;
1412
    }
1413
    return;
1414
bad_reg:
1415
    /* ??? For debugging only.  Should raise illegal instruction exception.  */
1416
    cpu_abort(env, "Unimplemented cp15 register write (c%d, c%d, {%d, %d})\n",
1417
              (insn >> 16) & 0xf, crm, op1, op2);
1418
}
1419

    
1420
uint32_t helper_get_cp15(CPUState *env, uint32_t insn)
1421
{
1422
    int op1;
1423
    int op2;
1424
    int crm;
1425

    
1426
    op1 = (insn >> 21) & 7;
1427
    op2 = (insn >> 5) & 7;
1428
    crm = insn & 0xf;
1429
    switch ((insn >> 16) & 0xf) {
1430
    case 0: /* ID codes.  */
1431
        switch (op1) {
1432
        case 0:
1433
            switch (crm) {
1434
            case 0:
1435
                switch (op2) {
1436
                case 0: /* Device ID.  */
1437
                    return env->cp15.c0_cpuid;
1438
                case 1: /* Cache Type.  */
1439
                    return env->cp15.c0_cachetype;
1440
                case 2: /* TCM status.  */
1441
                    return 0;
1442
                case 3: /* TLB type register.  */
1443
                    return 0; /* No lockable TLB entries.  */
1444
                case 5: /* CPU ID */
1445
                    return env->cpu_index;
1446
                default:
1447
                    goto bad_reg;
1448
                }
1449
            case 1:
1450
                if (!arm_feature(env, ARM_FEATURE_V6))
1451
                    goto bad_reg;
1452
                return env->cp15.c0_c1[op2];
1453
            case 2:
1454
                if (!arm_feature(env, ARM_FEATURE_V6))
1455
                    goto bad_reg;
1456
                return env->cp15.c0_c2[op2];
1457
            case 3: case 4: case 5: case 6: case 7:
1458
                return 0;
1459
            default:
1460
                goto bad_reg;
1461
            }
1462
        case 1:
1463
            /* These registers aren't documented on arm11 cores.  However
1464
               Linux looks at them anyway.  */
1465
            if (!arm_feature(env, ARM_FEATURE_V6))
1466
                goto bad_reg;
1467
            if (crm != 0)
1468
                goto bad_reg;
1469
            if (arm_feature(env, ARM_FEATURE_XSCALE))
1470
                goto bad_reg;
1471
            return 0;
1472
        default:
1473
            goto bad_reg;
1474
        }
1475
    case 1: /* System configuration.  */
1476
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1477
            op2 = 0;
1478
        switch (op2) {
1479
        case 0: /* Control register.  */
1480
            return env->cp15.c1_sys;
1481
        case 1: /* Auxiliary control register.  */
1482
            if (arm_feature(env, ARM_FEATURE_XSCALE))
1483
                return env->cp15.c1_xscaleauxcr;
1484
            if (!arm_feature(env, ARM_FEATURE_AUXCR))
1485
                goto bad_reg;
1486
            switch (ARM_CPUID(env)) {
1487
            case ARM_CPUID_ARM1026:
1488
                return 1;
1489
            case ARM_CPUID_ARM1136:
1490
                return 7;
1491
            case ARM_CPUID_ARM11MPCORE:
1492
                return 1;
1493
            case ARM_CPUID_CORTEXA8:
1494
                return 0;
1495
            default:
1496
                goto bad_reg;
1497
            }
1498
        case 2: /* Coprocessor access register.  */
1499
            if (arm_feature(env, ARM_FEATURE_XSCALE))
1500
                goto bad_reg;
1501
            return env->cp15.c1_coproc;
1502
        default:
1503
            goto bad_reg;
1504
        }
1505
    case 2: /* MMU Page table control / MPU cache control.  */
1506
        if (arm_feature(env, ARM_FEATURE_MPU)) {
1507
            switch (op2) {
1508
            case 0:
1509
                return env->cp15.c2_data;
1510
                break;
1511
            case 1:
1512
                return env->cp15.c2_insn;
1513
                break;
1514
            default:
1515
                goto bad_reg;
1516
            }
1517
        } else {
1518
            switch (op2) {
1519
            case 0:
1520
                return env->cp15.c2_base0;
1521
            case 1:
1522
                return env->cp15.c2_base1;
1523
            case 2:
1524
                {
1525
                    int n;
1526
                    uint32_t mask;
1527
                    n = 0;
1528
                    mask = env->cp15.c2_mask;
1529
                    while (mask) {
1530
                        n++;
1531
                        mask <<= 1;
1532
                    }
1533
                    return n;
1534
                }
1535
            default:
1536
                goto bad_reg;
1537
            }
1538
        }
1539
    case 3: /* MMU Domain access control / MPU write buffer control.  */
1540
        return env->cp15.c3;
1541
    case 4: /* Reserved.  */
1542
        goto bad_reg;
1543
    case 5: /* MMU Fault status / MPU access permission.  */
1544
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1545
            op2 = 0;
1546
        switch (op2) {
1547
        case 0:
1548
            if (arm_feature(env, ARM_FEATURE_MPU))
1549
                return simple_mpu_ap_bits(env->cp15.c5_data);
1550
            return env->cp15.c5_data;
1551
        case 1:
1552
            if (arm_feature(env, ARM_FEATURE_MPU))
1553
                return simple_mpu_ap_bits(env->cp15.c5_data);
1554
            return env->cp15.c5_insn;
1555
        case 2:
1556
            if (!arm_feature(env, ARM_FEATURE_MPU))
1557
                goto bad_reg;
1558
            return env->cp15.c5_data;
1559
        case 3:
1560
            if (!arm_feature(env, ARM_FEATURE_MPU))
1561
                goto bad_reg;
1562
            return env->cp15.c5_insn;
1563
        default:
1564
            goto bad_reg;
1565
        }
1566
    case 6: /* MMU Fault address.  */
1567
        if (arm_feature(env, ARM_FEATURE_MPU)) {
1568
            if (crm >= 8)
1569
                goto bad_reg;
1570
            return env->cp15.c6_region[crm];
1571
        } else {
1572
            if (arm_feature(env, ARM_FEATURE_OMAPCP))
1573
                op2 = 0;
1574
            switch (op2) {
1575
            case 0:
1576
                return env->cp15.c6_data;
1577
            case 1:
1578
                if (arm_feature(env, ARM_FEATURE_V6)) {
1579
                    /* Watchpoint Fault Adrress.  */
1580
                    return 0; /* Not implemented.  */
1581
                } else {
1582
                    /* Instruction Fault Adrress.  */
1583
                    /* Arm9 doesn't have an IFAR, but implementing it anyway
1584
                       shouldn't do any harm.  */
1585
                    return env->cp15.c6_insn;
1586
                }
1587
            case 2:
1588
                if (arm_feature(env, ARM_FEATURE_V6)) {
1589
                    /* Instruction Fault Adrress.  */
1590
                    return env->cp15.c6_insn;
1591
                } else {
1592
                    goto bad_reg;
1593
                }
1594
            default:
1595
                goto bad_reg;
1596
            }
1597
        }
1598
    case 7: /* Cache control.  */
1599
        /* ??? This is for test, clean and invaidate operations that set the
1600
           Z flag.  We can't represent N = Z = 1, so it also clears
1601
           the N flag.  Oh well.  */
1602
        env->NZF = 0;
1603
        return 0;
1604
    case 8: /* MMU TLB control.  */
1605
        goto bad_reg;
1606
    case 9: /* Cache lockdown.  */
1607
        switch (op1) {
1608
        case 0: /* L1 cache.  */
1609
            if (arm_feature(env, ARM_FEATURE_OMAPCP))
1610
                return 0;
1611
            switch (op2) {
1612
            case 0:
1613
                return env->cp15.c9_data;
1614
            case 1:
1615
                return env->cp15.c9_insn;
1616
            default:
1617
                goto bad_reg;
1618
            }
1619
        case 1: /* L2 cache */
1620
            if (crm != 0)
1621
                goto bad_reg;
1622
            /* L2 Lockdown and Auxiliary control.  */
1623
            return 0;
1624
        default:
1625
            goto bad_reg;
1626
        }
1627
    case 10: /* MMU TLB lockdown.  */
1628
        /* ??? TLB lockdown not implemented.  */
1629
        return 0;
1630
    case 11: /* TCM DMA control.  */
1631
    case 12: /* Reserved.  */
1632
        goto bad_reg;
1633
    case 13: /* Process ID.  */
1634
        switch (op2) {
1635
        case 0:
1636
            return env->cp15.c13_fcse;
1637
        case 1:
1638
            return env->cp15.c13_context;
1639
        case 2:
1640
            return env->cp15.c13_tls1;
1641
        case 3:
1642
            return env->cp15.c13_tls2;
1643
        case 4:
1644
            return env->cp15.c13_tls3;
1645
        default:
1646
            goto bad_reg;
1647
        }
1648
    case 14: /* Reserved.  */
1649
        goto bad_reg;
1650
    case 15: /* Implementation specific.  */
1651
        if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1652
            if (op2 == 0 && crm == 1)
1653
                return env->cp15.c15_cpar;
1654

    
1655
            goto bad_reg;
1656
        }
1657
        if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
1658
            switch (crm) {
1659
            case 0:
1660
                return 0;
1661
            case 1: /* Read TI925T configuration.  */
1662
                return env->cp15.c15_ticonfig;
1663
            case 2: /* Read I_max.  */
1664
                return env->cp15.c15_i_max;
1665
            case 3: /* Read I_min.  */
1666
                return env->cp15.c15_i_min;
1667
            case 4: /* Read thread-ID.  */
1668
                return env->cp15.c15_threadid;
1669
            case 8: /* TI925T_status */
1670
                return 0;
1671
            }
1672
            goto bad_reg;
1673
        }
1674
        return 0;
1675
    }
1676
bad_reg:
1677
    /* ??? For debugging only.  Should raise illegal instruction exception.  */
1678
    cpu_abort(env, "Unimplemented cp15 register read (c%d, c%d, {%d, %d})\n",
1679
              (insn >> 16) & 0xf, crm, op1, op2);
1680
    return 0;
1681
}
1682

    
1683
void helper_set_r13_banked(CPUState *env, int mode, uint32_t val)
1684
{
1685
    env->banked_r13[bank_number(mode)] = val;
1686
}
1687

    
1688
uint32_t helper_get_r13_banked(CPUState *env, int mode)
1689
{
1690
    return env->banked_r13[bank_number(mode)];
1691
}
1692

    
1693
uint32_t helper_v7m_mrs(CPUState *env, int reg)
1694
{
1695
    switch (reg) {
1696
    case 0: /* APSR */
1697
        return xpsr_read(env) & 0xf8000000;
1698
    case 1: /* IAPSR */
1699
        return xpsr_read(env) & 0xf80001ff;
1700
    case 2: /* EAPSR */
1701
        return xpsr_read(env) & 0xff00fc00;
1702
    case 3: /* xPSR */
1703
        return xpsr_read(env) & 0xff00fdff;
1704
    case 5: /* IPSR */
1705
        return xpsr_read(env) & 0x000001ff;
1706
    case 6: /* EPSR */
1707
        return xpsr_read(env) & 0x0700fc00;
1708
    case 7: /* IEPSR */
1709
        return xpsr_read(env) & 0x0700edff;
1710
    case 8: /* MSP */
1711
        return env->v7m.current_sp ? env->v7m.other_sp : env->regs[13];
1712
    case 9: /* PSP */
1713
        return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp;
1714
    case 16: /* PRIMASK */
1715
        return (env->uncached_cpsr & CPSR_I) != 0;
1716
    case 17: /* FAULTMASK */
1717
        return (env->uncached_cpsr & CPSR_F) != 0;
1718
    case 18: /* BASEPRI */
1719
    case 19: /* BASEPRI_MAX */
1720
        return env->v7m.basepri;
1721
    case 20: /* CONTROL */
1722
        return env->v7m.control;
1723
    default:
1724
        /* ??? For debugging only.  */
1725
        cpu_abort(env, "Unimplemented system register read (%d)\n", reg);
1726
        return 0;
1727
    }
1728
}
1729

    
1730
void helper_v7m_msr(CPUState *env, int reg, uint32_t val)
1731
{
1732
    switch (reg) {
1733
    case 0: /* APSR */
1734
        xpsr_write(env, val, 0xf8000000);
1735
        break;
1736
    case 1: /* IAPSR */
1737
        xpsr_write(env, val, 0xf8000000);
1738
        break;
1739
    case 2: /* EAPSR */
1740
        xpsr_write(env, val, 0xfe00fc00);
1741
        break;
1742
    case 3: /* xPSR */
1743
        xpsr_write(env, val, 0xfe00fc00);
1744
        break;
1745
    case 5: /* IPSR */
1746
        /* IPSR bits are readonly.  */
1747
        break;
1748
    case 6: /* EPSR */
1749
        xpsr_write(env, val, 0x0600fc00);
1750
        break;
1751
    case 7: /* IEPSR */
1752
        xpsr_write(env, val, 0x0600fc00);
1753
        break;
1754
    case 8: /* MSP */
1755
        if (env->v7m.current_sp)
1756
            env->v7m.other_sp = val;
1757
        else
1758
            env->regs[13] = val;
1759
        break;
1760
    case 9: /* PSP */
1761
        if (env->v7m.current_sp)
1762
            env->regs[13] = val;
1763
        else
1764
            env->v7m.other_sp = val;
1765
        break;
1766
    case 16: /* PRIMASK */
1767
        if (val & 1)
1768
            env->uncached_cpsr |= CPSR_I;
1769
        else
1770
            env->uncached_cpsr &= ~CPSR_I;
1771
        break;
1772
    case 17: /* FAULTMASK */
1773
        if (val & 1)
1774
            env->uncached_cpsr |= CPSR_F;
1775
        else
1776
            env->uncached_cpsr &= ~CPSR_F;
1777
        break;
1778
    case 18: /* BASEPRI */
1779
        env->v7m.basepri = val & 0xff;
1780
        break;
1781
    case 19: /* BASEPRI_MAX */
1782
        val &= 0xff;
1783
        if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0))
1784
            env->v7m.basepri = val;
1785
        break;
1786
    case 20: /* CONTROL */
1787
        env->v7m.control = val & 3;
1788
        switch_v7m_sp(env, (val & 2) != 0);
1789
        break;
1790
    default:
1791
        /* ??? For debugging only.  */
1792
        cpu_abort(env, "Unimplemented system register write (%d)\n", reg);
1793
        return;
1794
    }
1795
}
1796

    
1797
void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
1798
                ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
1799
                void *opaque)
1800
{
1801
    if (cpnum < 0 || cpnum > 14) {
1802
        cpu_abort(env, "Bad coprocessor number: %i\n", cpnum);
1803
        return;
1804
    }
1805

    
1806
    env->cp[cpnum].cp_read = cp_read;
1807
    env->cp[cpnum].cp_write = cp_write;
1808
    env->cp[cpnum].opaque = opaque;
1809
}
1810

    
1811
#endif