Statistics
| Branch: | Revision:

root / target-arm / helper.c @ f51bbbfe

History | View | Annotate | Download (52.5 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
#include "helpers.h"
9

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

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

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

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

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

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

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

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

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

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

    
174
CPUARMState *cpu_arm_init(const char *cpu_model)
175
{
176
    CPUARMState *env;
177
    uint32_t id;
178
    static int inited = 0;
179

    
180
    id = cpu_arm_find_by_name(cpu_model);
181
    if (id == 0)
182
        return NULL;
183
    env = qemu_mallocz(sizeof(CPUARMState));
184
    if (!env)
185
        return NULL;
186
    cpu_exec_init(env);
187
    if (!inited) {
188
        inited = 1;
189
        arm_translate_init();
190
    }
191

    
192
    env->cpu_model_str = cpu_model;
193
    env->cp15.c0_cpuid = id;
194
    cpu_reset(env);
195
    return env;
196
}
197

    
198
struct arm_cpu_t {
199
    uint32_t id;
200
    const char *name;
201
};
202

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

    
228
void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
229
{
230
    int i;
231

    
232
    (*cpu_fprintf)(f, "Available CPUs:\n");
233
    for (i = 0; arm_cpu_names[i].name; i++) {
234
        (*cpu_fprintf)(f, "  %s\n", arm_cpu_names[i].name);
235
    }
236
}
237

    
238
/* return 0 if not found */
239
static uint32_t cpu_arm_find_by_name(const char *name)
240
{
241
    int i;
242
    uint32_t id;
243

    
244
    id = 0;
245
    for (i = 0; arm_cpu_names[i].name; i++) {
246
        if (strcmp(name, arm_cpu_names[i].name) == 0) {
247
            id = arm_cpu_names[i].id;
248
            break;
249
        }
250
    }
251
    return id;
252
}
253

    
254
void cpu_arm_close(CPUARMState *env)
255
{
256
    free(env);
257
}
258

    
259
/* Polynomial multiplication is like integer multiplcation except the
260
   partial products are XORed, not added.  */
261
uint32_t helper_neon_mul_p8(uint32_t op1, uint32_t op2)
262
{
263
    uint32_t mask;
264
    uint32_t result;
265
    result = 0;
266
    while (op1) {
267
        mask = 0;
268
        if (op1 & 1)
269
            mask |= 0xff;
270
        if (op1 & (1 << 8))
271
            mask |= (0xff << 8);
272
        if (op1 & (1 << 16))
273
            mask |= (0xff << 16);
274
        if (op1 & (1 << 24))
275
            mask |= (0xff << 24);
276
        result ^= op2 & mask;
277
        op1 = (op1 >> 1) & 0x7f7f7f7f;
278
        op2 = (op2 << 1) & 0xfefefefe;
279
    }
280
    return result;
281
}
282

    
283
uint32_t cpsr_read(CPUARMState *env)
284
{
285
    int ZF;
286
    ZF = (env->NZF == 0);
287
    return env->uncached_cpsr | (env->NZF & 0x80000000) | (ZF << 30) |
288
        (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
289
        | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
290
        | ((env->condexec_bits & 0xfc) << 8)
291
        | (env->GE << 16);
292
}
293

    
294
void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
295
{
296
    /* NOTE: N = 1 and Z = 1 cannot be stored currently */
297
    if (mask & CPSR_NZCV) {
298
        env->NZF = (val & 0xc0000000) ^ 0x40000000;
299
        env->CF = (val >> 29) & 1;
300
        env->VF = (val << 3) & 0x80000000;
301
    }
302
    if (mask & CPSR_Q)
303
        env->QF = ((val & CPSR_Q) != 0);
304
    if (mask & CPSR_T)
305
        env->thumb = ((val & CPSR_T) != 0);
306
    if (mask & CPSR_IT_0_1) {
307
        env->condexec_bits &= ~3;
308
        env->condexec_bits |= (val >> 25) & 3;
309
    }
310
    if (mask & CPSR_IT_2_7) {
311
        env->condexec_bits &= 3;
312
        env->condexec_bits |= (val >> 8) & 0xfc;
313
    }
314
    if (mask & CPSR_GE) {
315
        env->GE = (val >> 16) & 0xf;
316
    }
317

    
318
    if ((env->uncached_cpsr ^ val) & mask & CPSR_M) {
319
        switch_mode(env, val & CPSR_M);
320
    }
321
    mask &= ~CACHED_CPSR_BITS;
322
    env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
323
}
324

    
325
#define HELPER(x) helper_##x
326
/* Sign/zero extend */
327
uint32_t HELPER(sxtb16)(uint32_t x)
328
{
329
    uint32_t res;
330
    res = (uint16_t)(int8_t)x;
331
    res |= (uint32_t)(int8_t)(x >> 16) << 16;
332
    return res;
333
}
334

    
335
uint32_t HELPER(uxtb16)(uint32_t x)
336
{
337
    uint32_t res;
338
    res = (uint16_t)(uint8_t)x;
339
    res |= (uint32_t)(uint8_t)(x >> 16) << 16;
340
    return res;
341
}
342

    
343
uint32_t HELPER(clz)(uint32_t x)
344
{
345
    int count;
346
    for (count = 32; x; count--)
347
        x >>= 1;
348
    return count;
349
}
350

    
351
#if defined(CONFIG_USER_ONLY)
352

    
353
void do_interrupt (CPUState *env)
354
{
355
    env->exception_index = -1;
356
}
357

    
358
/* Structure used to record exclusive memory locations.  */
359
typedef struct mmon_state {
360
    struct mmon_state *next;
361
    CPUARMState *cpu_env;
362
    uint32_t addr;
363
} mmon_state;
364

    
365
/* Chain of current locks.  */
366
static mmon_state* mmon_head = NULL;
367

    
368
int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
369
                              int mmu_idx, int is_softmmu)
370
{
371
    if (rw == 2) {
372
        env->exception_index = EXCP_PREFETCH_ABORT;
373
        env->cp15.c6_insn = address;
374
    } else {
375
        env->exception_index = EXCP_DATA_ABORT;
376
        env->cp15.c6_data = address;
377
    }
378
    return 1;
379
}
380

    
381
static void allocate_mmon_state(CPUState *env)
382
{
383
    env->mmon_entry = malloc(sizeof (mmon_state));
384
    if (!env->mmon_entry)
385
        abort();
386
    memset (env->mmon_entry, 0, sizeof (mmon_state));
387
    env->mmon_entry->cpu_env = env;
388
    mmon_head = env->mmon_entry;
389
}
390

    
391
/* Flush any monitor locks for the specified address.  */
392
static void flush_mmon(uint32_t addr)
393
{
394
    mmon_state *mon;
395

    
396
    for (mon = mmon_head; mon; mon = mon->next)
397
      {
398
        if (mon->addr != addr)
399
          continue;
400

    
401
        mon->addr = 0;
402
        break;
403
      }
404
}
405

    
406
/* Mark an address for exclusive access.  */
407
void helper_mark_exclusive(CPUState *env, uint32_t addr)
408
{
409
    if (!env->mmon_entry)
410
        allocate_mmon_state(env);
411
    /* Clear any previous locks.  */
412
    flush_mmon(addr);
413
    env->mmon_entry->addr = addr;
414
}
415

    
416
/* Test if an exclusive address is still exclusive.  Returns zero
417
   if the address is still exclusive.   */
418
int helper_test_exclusive(CPUState *env, uint32_t addr)
419
{
420
    int res;
421

    
422
    if (!env->mmon_entry)
423
        return 1;
424
    if (env->mmon_entry->addr == addr)
425
        res = 0;
426
    else
427
        res = 1;
428
    flush_mmon(addr);
429
    return res;
430
}
431

    
432
void helper_clrex(CPUState *env)
433
{
434
    if (!(env->mmon_entry && env->mmon_entry->addr))
435
        return;
436
    flush_mmon(env->mmon_entry->addr);
437
}
438

    
439
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
440
{
441
    return addr;
442
}
443

    
444
/* These should probably raise undefined insn exceptions.  */
445
void helper_set_cp(CPUState *env, uint32_t insn, uint32_t val)
446
{
447
    int op1 = (insn >> 8) & 0xf;
448
    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
449
    return;
450
}
451

    
452
uint32_t helper_get_cp(CPUState *env, uint32_t insn)
453
{
454
    int op1 = (insn >> 8) & 0xf;
455
    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
456
    return 0;
457
}
458

    
459
void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val)
460
{
461
    cpu_abort(env, "cp15 insn %08x\n", insn);
462
}
463

    
464
uint32_t helper_get_cp15(CPUState *env, uint32_t insn)
465
{
466
    cpu_abort(env, "cp15 insn %08x\n", insn);
467
    return 0;
468
}
469

    
470
/* These should probably raise undefined insn exceptions.  */
471
void helper_v7m_msr(CPUState *env, int reg, uint32_t val)
472
{
473
    cpu_abort(env, "v7m_mrs %d\n", reg);
474
}
475

    
476
uint32_t helper_v7m_mrs(CPUState *env, int reg)
477
{
478
    cpu_abort(env, "v7m_mrs %d\n", reg);
479
    return 0;
480
}
481

    
482
void switch_mode(CPUState *env, int mode)
483
{
484
    if (mode != ARM_CPU_MODE_USR)
485
        cpu_abort(env, "Tried to switch out of user mode\n");
486
}
487

    
488
void helper_set_r13_banked(CPUState *env, int mode, uint32_t val)
489
{
490
    cpu_abort(env, "banked r13 write\n");
491
}
492

    
493
uint32_t helper_get_r13_banked(CPUState *env, int mode)
494
{
495
    cpu_abort(env, "banked r13 read\n");
496
    return 0;
497
}
498

    
499
#else
500

    
501
extern int semihosting_enabled;
502

    
503
/* Map CPU modes onto saved register banks.  */
504
static inline int bank_number (int mode)
505
{
506
    switch (mode) {
507
    case ARM_CPU_MODE_USR:
508
    case ARM_CPU_MODE_SYS:
509
        return 0;
510
    case ARM_CPU_MODE_SVC:
511
        return 1;
512
    case ARM_CPU_MODE_ABT:
513
        return 2;
514
    case ARM_CPU_MODE_UND:
515
        return 3;
516
    case ARM_CPU_MODE_IRQ:
517
        return 4;
518
    case ARM_CPU_MODE_FIQ:
519
        return 5;
520
    }
521
    cpu_abort(cpu_single_env, "Bad mode %x\n", mode);
522
    return -1;
523
}
524

    
525
void switch_mode(CPUState *env, int mode)
526
{
527
    int old_mode;
528
    int i;
529

    
530
    old_mode = env->uncached_cpsr & CPSR_M;
531
    if (mode == old_mode)
532
        return;
533

    
534
    if (old_mode == ARM_CPU_MODE_FIQ) {
535
        memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
536
        memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
537
    } else if (mode == ARM_CPU_MODE_FIQ) {
538
        memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
539
        memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
540
    }
541

    
542
    i = bank_number(old_mode);
543
    env->banked_r13[i] = env->regs[13];
544
    env->banked_r14[i] = env->regs[14];
545
    env->banked_spsr[i] = env->spsr;
546

    
547
    i = bank_number(mode);
548
    env->regs[13] = env->banked_r13[i];
549
    env->regs[14] = env->banked_r14[i];
550
    env->spsr = env->banked_spsr[i];
551
}
552

    
553
static void v7m_push(CPUARMState *env, uint32_t val)
554
{
555
    env->regs[13] -= 4;
556
    stl_phys(env->regs[13], val);
557
}
558

    
559
static uint32_t v7m_pop(CPUARMState *env)
560
{
561
    uint32_t val;
562
    val = ldl_phys(env->regs[13]);
563
    env->regs[13] += 4;
564
    return val;
565
}
566

    
567
/* Switch to V7M main or process stack pointer.  */
568
static void switch_v7m_sp(CPUARMState *env, int process)
569
{
570
    uint32_t tmp;
571
    if (env->v7m.current_sp != process) {
572
        tmp = env->v7m.other_sp;
573
        env->v7m.other_sp = env->regs[13];
574
        env->regs[13] = tmp;
575
        env->v7m.current_sp = process;
576
    }
577
}
578

    
579
static void do_v7m_exception_exit(CPUARMState *env)
580
{
581
    uint32_t type;
582
    uint32_t xpsr;
583

    
584
    type = env->regs[15];
585
    if (env->v7m.exception != 0)
586
        armv7m_nvic_complete_irq(env->v7m.nvic, env->v7m.exception);
587

    
588
    /* Switch to the target stack.  */
589
    switch_v7m_sp(env, (type & 4) != 0);
590
    /* Pop registers.  */
591
    env->regs[0] = v7m_pop(env);
592
    env->regs[1] = v7m_pop(env);
593
    env->regs[2] = v7m_pop(env);
594
    env->regs[3] = v7m_pop(env);
595
    env->regs[12] = v7m_pop(env);
596
    env->regs[14] = v7m_pop(env);
597
    env->regs[15] = v7m_pop(env);
598
    xpsr = v7m_pop(env);
599
    xpsr_write(env, xpsr, 0xfffffdff);
600
    /* Undo stack alignment.  */
601
    if (xpsr & 0x200)
602
        env->regs[13] |= 4;
603
    /* ??? The exception return type specifies Thread/Handler mode.  However
604
       this is also implied by the xPSR value. Not sure what to do
605
       if there is a mismatch.  */
606
    /* ??? Likewise for mismatches between the CONTROL register and the stack
607
       pointer.  */
608
}
609

    
610
void do_interrupt_v7m(CPUARMState *env)
611
{
612
    uint32_t xpsr = xpsr_read(env);
613
    uint32_t lr;
614
    uint32_t addr;
615

    
616
    lr = 0xfffffff1;
617
    if (env->v7m.current_sp)
618
        lr |= 4;
619
    if (env->v7m.exception == 0)
620
        lr |= 8;
621

    
622
    /* For exceptions we just mark as pending on the NVIC, and let that
623
       handle it.  */
624
    /* TODO: Need to escalate if the current priority is higher than the
625
       one we're raising.  */
626
    switch (env->exception_index) {
627
    case EXCP_UDEF:
628
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_USAGE);
629
        return;
630
    case EXCP_SWI:
631
        env->regs[15] += 2;
632
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_SVC);
633
        return;
634
    case EXCP_PREFETCH_ABORT:
635
    case EXCP_DATA_ABORT:
636
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_MEM);
637
        return;
638
    case EXCP_BKPT:
639
        if (semihosting_enabled) {
640
            int nr;
641
            nr = lduw_code(env->regs[15]) & 0xff;
642
            if (nr == 0xab) {
643
                env->regs[15] += 2;
644
                env->regs[0] = do_arm_semihosting(env);
645
                return;
646
            }
647
        }
648
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_DEBUG);
649
        return;
650
    case EXCP_IRQ:
651
        env->v7m.exception = armv7m_nvic_acknowledge_irq(env->v7m.nvic);
652
        break;
653
    case EXCP_EXCEPTION_EXIT:
654
        do_v7m_exception_exit(env);
655
        return;
656
    default:
657
        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
658
        return; /* Never happens.  Keep compiler happy.  */
659
    }
660

    
661
    /* Align stack pointer.  */
662
    /* ??? Should only do this if Configuration Control Register
663
       STACKALIGN bit is set.  */
664
    if (env->regs[13] & 4) {
665
        env->regs[13] += 4;
666
        xpsr |= 0x200;
667
    }
668
    /* Switch to the hander mode.  */
669
    v7m_push(env, xpsr);
670
    v7m_push(env, env->regs[15]);
671
    v7m_push(env, env->regs[14]);
672
    v7m_push(env, env->regs[12]);
673
    v7m_push(env, env->regs[3]);
674
    v7m_push(env, env->regs[2]);
675
    v7m_push(env, env->regs[1]);
676
    v7m_push(env, env->regs[0]);
677
    switch_v7m_sp(env, 0);
678
    env->uncached_cpsr &= ~CPSR_IT;
679
    env->regs[14] = lr;
680
    addr = ldl_phys(env->v7m.vecbase + env->v7m.exception * 4);
681
    env->regs[15] = addr & 0xfffffffe;
682
    env->thumb = addr & 1;
683
}
684

    
685
/* Handle a CPU exception.  */
686
void do_interrupt(CPUARMState *env)
687
{
688
    uint32_t addr;
689
    uint32_t mask;
690
    int new_mode;
691
    uint32_t offset;
692

    
693
    if (IS_M(env)) {
694
        do_interrupt_v7m(env);
695
        return;
696
    }
697
    /* TODO: Vectored interrupt controller.  */
698
    switch (env->exception_index) {
699
    case EXCP_UDEF:
700
        new_mode = ARM_CPU_MODE_UND;
701
        addr = 0x04;
702
        mask = CPSR_I;
703
        if (env->thumb)
704
            offset = 2;
705
        else
706
            offset = 4;
707
        break;
708
    case EXCP_SWI:
709
        if (semihosting_enabled) {
710
            /* Check for semihosting interrupt.  */
711
            if (env->thumb) {
712
                mask = lduw_code(env->regs[15] - 2) & 0xff;
713
            } else {
714
                mask = ldl_code(env->regs[15] - 4) & 0xffffff;
715
            }
716
            /* Only intercept calls from privileged modes, to provide some
717
               semblance of security.  */
718
            if (((mask == 0x123456 && !env->thumb)
719
                    || (mask == 0xab && env->thumb))
720
                  && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
721
                env->regs[0] = do_arm_semihosting(env);
722
                return;
723
            }
724
        }
725
        new_mode = ARM_CPU_MODE_SVC;
726
        addr = 0x08;
727
        mask = CPSR_I;
728
        /* The PC already points to the next instructon.  */
729
        offset = 0;
730
        break;
731
    case EXCP_BKPT:
732
        /* See if this is a semihosting syscall.  */
733
        if (env->thumb && semihosting_enabled) {
734
            mask = lduw_code(env->regs[15]) & 0xff;
735
            if (mask == 0xab
736
                  && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
737
                env->regs[15] += 2;
738
                env->regs[0] = do_arm_semihosting(env);
739
                return;
740
            }
741
        }
742
        /* Fall through to prefetch abort.  */
743
    case EXCP_PREFETCH_ABORT:
744
        new_mode = ARM_CPU_MODE_ABT;
745
        addr = 0x0c;
746
        mask = CPSR_A | CPSR_I;
747
        offset = 4;
748
        break;
749
    case EXCP_DATA_ABORT:
750
        new_mode = ARM_CPU_MODE_ABT;
751
        addr = 0x10;
752
        mask = CPSR_A | CPSR_I;
753
        offset = 8;
754
        break;
755
    case EXCP_IRQ:
756
        new_mode = ARM_CPU_MODE_IRQ;
757
        addr = 0x18;
758
        /* Disable IRQ and imprecise data aborts.  */
759
        mask = CPSR_A | CPSR_I;
760
        offset = 4;
761
        break;
762
    case EXCP_FIQ:
763
        new_mode = ARM_CPU_MODE_FIQ;
764
        addr = 0x1c;
765
        /* Disable FIQ, IRQ and imprecise data aborts.  */
766
        mask = CPSR_A | CPSR_I | CPSR_F;
767
        offset = 4;
768
        break;
769
    default:
770
        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
771
        return; /* Never happens.  Keep compiler happy.  */
772
    }
773
    /* High vectors.  */
774
    if (env->cp15.c1_sys & (1 << 13)) {
775
        addr += 0xffff0000;
776
    }
777
    switch_mode (env, new_mode);
778
    env->spsr = cpsr_read(env);
779
    /* Clear IT bits.  */
780
    env->condexec_bits = 0;
781
    /* Switch to the new mode, and switch to Arm mode.  */
782
    /* ??? Thumb interrupt handlers not implemented.  */
783
    env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
784
    env->uncached_cpsr |= mask;
785
    env->thumb = 0;
786
    env->regs[14] = env->regs[15] + offset;
787
    env->regs[15] = addr;
788
    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
789
}
790

    
791
/* Check section/page access permissions.
792
   Returns the page protection flags, or zero if the access is not
793
   permitted.  */
794
static inline int check_ap(CPUState *env, int ap, int domain, int access_type,
795
                           int is_user)
796
{
797
  int prot_ro;
798

    
799
  if (domain == 3)
800
    return PAGE_READ | PAGE_WRITE;
801

    
802
  if (access_type == 1)
803
      prot_ro = 0;
804
  else
805
      prot_ro = PAGE_READ;
806

    
807
  switch (ap) {
808
  case 0:
809
      if (access_type == 1)
810
          return 0;
811
      switch ((env->cp15.c1_sys >> 8) & 3) {
812
      case 1:
813
          return is_user ? 0 : PAGE_READ;
814
      case 2:
815
          return PAGE_READ;
816
      default:
817
          return 0;
818
      }
819
  case 1:
820
      return is_user ? 0 : PAGE_READ | PAGE_WRITE;
821
  case 2:
822
      if (is_user)
823
          return prot_ro;
824
      else
825
          return PAGE_READ | PAGE_WRITE;
826
  case 3:
827
      return PAGE_READ | PAGE_WRITE;
828
  case 4: case 7: /* Reserved.  */
829
      return 0;
830
  case 5:
831
      return is_user ? 0 : prot_ro;
832
  case 6:
833
      return prot_ro;
834
  default:
835
      abort();
836
  }
837
}
838

    
839
static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
840
                            int is_user, uint32_t *phys_ptr, int *prot)
841
{
842
    int code;
843
    uint32_t table;
844
    uint32_t desc;
845
    int type;
846
    int ap;
847
    int domain;
848
    uint32_t phys_addr;
849

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

    
930
static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
931
                            int is_user, uint32_t *phys_ptr, int *prot)
932
{
933
    int code;
934
    uint32_t table;
935
    uint32_t desc;
936
    uint32_t xn;
937
    int type;
938
    int ap;
939
    int domain;
940
    uint32_t phys_addr;
941

    
942
    /* Pagetable walk.  */
943
    /* Lookup l1 descriptor.  */
944
    if (address & env->cp15.c2_mask)
945
        table = env->cp15.c2_base1;
946
    else
947
        table = env->cp15.c2_base0;
948
    table = (table & 0xffffc000) | ((address >> 18) & 0x3ffc);
949
    desc = ldl_phys(table);
950
    type = (desc & 3);
951
    if (type == 0) {
952
        /* Secton translation fault.  */
953
        code = 5;
954
        domain = 0;
955
        goto do_fault;
956
    } else if (type == 2 && (desc & (1 << 18))) {
957
        /* Supersection.  */
958
        domain = 0;
959
    } else {
960
        /* Section or page.  */
961
        domain = (desc >> 4) & 0x1e;
962
    }
963
    domain = (env->cp15.c3 >> domain) & 3;
964
    if (domain == 0 || domain == 2) {
965
        if (type == 2)
966
            code = 9; /* Section domain fault.  */
967
        else
968
            code = 11; /* Page domain fault.  */
969
        goto do_fault;
970
    }
971
    if (type == 2) {
972
        if (desc & (1 << 18)) {
973
            /* Supersection.  */
974
            phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
975
        } else {
976
            /* Section.  */
977
            phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
978
        }
979
        ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
980
        xn = desc & (1 << 4);
981
        code = 13;
982
    } else {
983
        /* Lookup l2 entry.  */
984
        table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
985
        desc = ldl_phys(table);
986
        ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
987
        switch (desc & 3) {
988
        case 0: /* Page translation fault.  */
989
            code = 7;
990
            goto do_fault;
991
        case 1: /* 64k page.  */
992
            phys_addr = (desc & 0xffff0000) | (address & 0xffff);
993
            xn = desc & (1 << 15);
994
            break;
995
        case 2: case 3: /* 4k page.  */
996
            phys_addr = (desc & 0xfffff000) | (address & 0xfff);
997
            xn = desc & 1;
998
            break;
999
        default:
1000
            /* Never happens, but compiler isn't smart enough to tell.  */
1001
            abort();
1002
        }
1003
        code = 15;
1004
    }
1005
    if (xn && access_type == 2)
1006
        goto do_fault;
1007

    
1008
    *prot = check_ap(env, ap, domain, access_type, is_user);
1009
    if (!*prot) {
1010
        /* Access permission fault.  */
1011
        goto do_fault;
1012
    }
1013
    *phys_ptr = phys_addr;
1014
    return 0;
1015
do_fault:
1016
    return code | (domain << 4);
1017
}
1018

    
1019
static int get_phys_addr_mpu(CPUState *env, uint32_t address, int access_type,
1020
                             int is_user, uint32_t *phys_ptr, int *prot)
1021
{
1022
    int n;
1023
    uint32_t mask;
1024
    uint32_t base;
1025

    
1026
    *phys_ptr = address;
1027
    for (n = 7; n >= 0; n--) {
1028
        base = env->cp15.c6_region[n];
1029
        if ((base & 1) == 0)
1030
            continue;
1031
        mask = 1 << ((base >> 1) & 0x1f);
1032
        /* Keep this shift separate from the above to avoid an
1033
           (undefined) << 32.  */
1034
        mask = (mask << 1) - 1;
1035
        if (((base ^ address) & ~mask) == 0)
1036
            break;
1037
    }
1038
    if (n < 0)
1039
        return 2;
1040

    
1041
    if (access_type == 2) {
1042
        mask = env->cp15.c5_insn;
1043
    } else {
1044
        mask = env->cp15.c5_data;
1045
    }
1046
    mask = (mask >> (n * 4)) & 0xf;
1047
    switch (mask) {
1048
    case 0:
1049
        return 1;
1050
    case 1:
1051
        if (is_user)
1052
          return 1;
1053
        *prot = PAGE_READ | PAGE_WRITE;
1054
        break;
1055
    case 2:
1056
        *prot = PAGE_READ;
1057
        if (!is_user)
1058
            *prot |= PAGE_WRITE;
1059
        break;
1060
    case 3:
1061
        *prot = PAGE_READ | PAGE_WRITE;
1062
        break;
1063
    case 5:
1064
        if (is_user)
1065
            return 1;
1066
        *prot = PAGE_READ;
1067
        break;
1068
    case 6:
1069
        *prot = PAGE_READ;
1070
        break;
1071
    default:
1072
        /* Bad permission.  */
1073
        return 1;
1074
    }
1075
    return 0;
1076
}
1077

    
1078
static inline int get_phys_addr(CPUState *env, uint32_t address,
1079
                                int access_type, int is_user,
1080
                                uint32_t *phys_ptr, int *prot)
1081
{
1082
    /* Fast Context Switch Extension.  */
1083
    if (address < 0x02000000)
1084
        address += env->cp15.c13_fcse;
1085

    
1086
    if ((env->cp15.c1_sys & 1) == 0) {
1087
        /* MMU/MPU disabled.  */
1088
        *phys_ptr = address;
1089
        *prot = PAGE_READ | PAGE_WRITE;
1090
        return 0;
1091
    } else if (arm_feature(env, ARM_FEATURE_MPU)) {
1092
        return get_phys_addr_mpu(env, address, access_type, is_user, phys_ptr,
1093
                                 prot);
1094
    } else if (env->cp15.c1_sys & (1 << 23)) {
1095
        return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,
1096
                                prot);
1097
    } else {
1098
        return get_phys_addr_v5(env, address, access_type, is_user, phys_ptr,
1099
                                prot);
1100
    }
1101
}
1102

    
1103
int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
1104
                              int access_type, int mmu_idx, int is_softmmu)
1105
{
1106
    uint32_t phys_addr;
1107
    int prot;
1108
    int ret, is_user;
1109

    
1110
    is_user = mmu_idx == MMU_USER_IDX;
1111
    ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot);
1112
    if (ret == 0) {
1113
        /* Map a single [sub]page.  */
1114
        phys_addr &= ~(uint32_t)0x3ff;
1115
        address &= ~(uint32_t)0x3ff;
1116
        return tlb_set_page (env, address, phys_addr, prot, mmu_idx,
1117
                             is_softmmu);
1118
    }
1119

    
1120
    if (access_type == 2) {
1121
        env->cp15.c5_insn = ret;
1122
        env->cp15.c6_insn = address;
1123
        env->exception_index = EXCP_PREFETCH_ABORT;
1124
    } else {
1125
        env->cp15.c5_data = ret;
1126
        if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6))
1127
            env->cp15.c5_data |= (1 << 11);
1128
        env->cp15.c6_data = address;
1129
        env->exception_index = EXCP_DATA_ABORT;
1130
    }
1131
    return 1;
1132
}
1133

    
1134
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1135
{
1136
    uint32_t phys_addr;
1137
    int prot;
1138
    int ret;
1139

    
1140
    ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot);
1141

    
1142
    if (ret != 0)
1143
        return -1;
1144

    
1145
    return phys_addr;
1146
}
1147

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

    
1151
void helper_mark_exclusive(CPUState *env, uint32_t addr)
1152
{
1153
    env->mmon_addr = addr;
1154
}
1155

    
1156
int helper_test_exclusive(CPUState *env, uint32_t addr)
1157
{
1158
    return (env->mmon_addr != addr);
1159
}
1160

    
1161
void helper_clrex(CPUState *env)
1162
{
1163
    env->mmon_addr = -1;
1164
}
1165

    
1166
void helper_set_cp(CPUState *env, uint32_t insn, uint32_t val)
1167
{
1168
    int cp_num = (insn >> 8) & 0xf;
1169
    int cp_info = (insn >> 5) & 7;
1170
    int src = (insn >> 16) & 0xf;
1171
    int operand = insn & 0xf;
1172

    
1173
    if (env->cp[cp_num].cp_write)
1174
        env->cp[cp_num].cp_write(env->cp[cp_num].opaque,
1175
                                 cp_info, src, operand, val);
1176
}
1177

    
1178
uint32_t helper_get_cp(CPUState *env, uint32_t insn)
1179
{
1180
    int cp_num = (insn >> 8) & 0xf;
1181
    int cp_info = (insn >> 5) & 7;
1182
    int dest = (insn >> 16) & 0xf;
1183
    int operand = insn & 0xf;
1184

    
1185
    if (env->cp[cp_num].cp_read)
1186
        return env->cp[cp_num].cp_read(env->cp[cp_num].opaque,
1187
                                       cp_info, dest, operand);
1188
    return 0;
1189
}
1190

    
1191
/* Return basic MPU access permission bits.  */
1192
static uint32_t simple_mpu_ap_bits(uint32_t val)
1193
{
1194
    uint32_t ret;
1195
    uint32_t mask;
1196
    int i;
1197
    ret = 0;
1198
    mask = 3;
1199
    for (i = 0; i < 16; i += 2) {
1200
        ret |= (val >> i) & mask;
1201
        mask <<= 2;
1202
    }
1203
    return ret;
1204
}
1205

    
1206
/* Pad basic MPU access permission bits to extended format.  */
1207
static uint32_t extended_mpu_ap_bits(uint32_t val)
1208
{
1209
    uint32_t ret;
1210
    uint32_t mask;
1211
    int i;
1212
    ret = 0;
1213
    mask = 3;
1214
    for (i = 0; i < 16; i += 2) {
1215
        ret |= (val & mask) << i;
1216
        mask <<= 2;
1217
    }
1218
    return ret;
1219
}
1220

    
1221
void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val)
1222
{
1223
    int op1;
1224
    int op2;
1225
    int crm;
1226

    
1227
    op1 = (insn >> 21) & 7;
1228
    op2 = (insn >> 5) & 7;
1229
    crm = insn & 0xf;
1230
    switch ((insn >> 16) & 0xf) {
1231
    case 0:
1232
        if (((insn >> 21) & 7) == 2) {
1233
            /* ??? Select cache level.  Ignore.  */
1234
            return;
1235
        }
1236
        /* ID codes.  */
1237
        if (arm_feature(env, ARM_FEATURE_XSCALE))
1238
            break;
1239
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1240
            break;
1241
        goto bad_reg;
1242
    case 1: /* System configuration.  */
1243
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1244
            op2 = 0;
1245
        switch (op2) {
1246
        case 0:
1247
            if (!arm_feature(env, ARM_FEATURE_XSCALE) || crm == 0)
1248
                env->cp15.c1_sys = val;
1249
            /* ??? Lots of these bits are not implemented.  */
1250
            /* This may enable/disable the MMU, so do a TLB flush.  */
1251
            tlb_flush(env, 1);
1252
            break;
1253
        case 1: /* Auxiliary cotrol register.  */
1254
            if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1255
                env->cp15.c1_xscaleauxcr = val;
1256
                break;
1257
            }
1258
            /* Not implemented.  */
1259
            break;
1260
        case 2:
1261
            if (arm_feature(env, ARM_FEATURE_XSCALE))
1262
                goto bad_reg;
1263
            env->cp15.c1_coproc = val;
1264
            /* ??? Is this safe when called from within a TB?  */
1265
            tb_flush(env);
1266
            break;
1267
        default:
1268
            goto bad_reg;
1269
        }
1270
        break;
1271
    case 2: /* MMU Page table control / MPU cache control.  */
1272
        if (arm_feature(env, ARM_FEATURE_MPU)) {
1273
            switch (op2) {
1274
            case 0:
1275
                env->cp15.c2_data = val;
1276
                break;
1277
            case 1:
1278
                env->cp15.c2_insn = val;
1279
                break;
1280
            default:
1281
                goto bad_reg;
1282
            }
1283
        } else {
1284
            switch (op2) {
1285
            case 0:
1286
                env->cp15.c2_base0 = val;
1287
                break;
1288
            case 1:
1289
                env->cp15.c2_base1 = val;
1290
                break;
1291
            case 2:
1292
                env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val);
1293
                break;
1294
            default:
1295
                goto bad_reg;
1296
            }
1297
        }
1298
        break;
1299
    case 3: /* MMU Domain access control / MPU write buffer control.  */
1300
        env->cp15.c3 = val;
1301
        tlb_flush(env, 1); /* Flush TLB as domain not tracked in TLB */
1302
        break;
1303
    case 4: /* Reserved.  */
1304
        goto bad_reg;
1305
    case 5: /* MMU Fault status / MPU access permission.  */
1306
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1307
            op2 = 0;
1308
        switch (op2) {
1309
        case 0:
1310
            if (arm_feature(env, ARM_FEATURE_MPU))
1311
                val = extended_mpu_ap_bits(val);
1312
            env->cp15.c5_data = val;
1313
            break;
1314
        case 1:
1315
            if (arm_feature(env, ARM_FEATURE_MPU))
1316
                val = extended_mpu_ap_bits(val);
1317
            env->cp15.c5_insn = val;
1318
            break;
1319
        case 2:
1320
            if (!arm_feature(env, ARM_FEATURE_MPU))
1321
                goto bad_reg;
1322
            env->cp15.c5_data = val;
1323
            break;
1324
        case 3:
1325
            if (!arm_feature(env, ARM_FEATURE_MPU))
1326
                goto bad_reg;
1327
            env->cp15.c5_insn = val;
1328
            break;
1329
        default:
1330
            goto bad_reg;
1331
        }
1332
        break;
1333
    case 6: /* MMU Fault address / MPU base/size.  */
1334
        if (arm_feature(env, ARM_FEATURE_MPU)) {
1335
            if (crm >= 8)
1336
                goto bad_reg;
1337
            env->cp15.c6_region[crm] = val;
1338
        } else {
1339
            if (arm_feature(env, ARM_FEATURE_OMAPCP))
1340
                op2 = 0;
1341
            switch (op2) {
1342
            case 0:
1343
                env->cp15.c6_data = val;
1344
                break;
1345
            case 1: /* ??? This is WFAR on armv6 */
1346
            case 2:
1347
                env->cp15.c6_insn = val;
1348
                break;
1349
            default:
1350
                goto bad_reg;
1351
            }
1352
        }
1353
        break;
1354
    case 7: /* Cache control.  */
1355
        env->cp15.c15_i_max = 0x000;
1356
        env->cp15.c15_i_min = 0xff0;
1357
        /* No cache, so nothing to do.  */
1358
        /* ??? MPCore has VA to PA translation functions.  */
1359
        break;
1360
    case 8: /* MMU TLB control.  */
1361
        switch (op2) {
1362
        case 0: /* Invalidate all.  */
1363
            tlb_flush(env, 0);
1364
            break;
1365
        case 1: /* Invalidate single TLB entry.  */
1366
#if 0
1367
            /* ??? This is wrong for large pages and sections.  */
1368
            /* As an ugly hack to make linux work we always flush a 4K
1369
               pages.  */
1370
            val &= 0xfffff000;
1371
            tlb_flush_page(env, val);
1372
            tlb_flush_page(env, val + 0x400);
1373
            tlb_flush_page(env, val + 0x800);
1374
            tlb_flush_page(env, val + 0xc00);
1375
#else
1376
            tlb_flush(env, 1);
1377
#endif
1378
            break;
1379
        case 2: /* Invalidate on ASID.  */
1380
            tlb_flush(env, val == 0);
1381
            break;
1382
        case 3: /* Invalidate single entry on MVA.  */
1383
            /* ??? This is like case 1, but ignores ASID.  */
1384
            tlb_flush(env, 1);
1385
            break;
1386
        default:
1387
            goto bad_reg;
1388
        }
1389
        break;
1390
    case 9:
1391
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1392
            break;
1393
        switch (crm) {
1394
        case 0: /* Cache lockdown.  */
1395
            switch (op1) {
1396
            case 0: /* L1 cache.  */
1397
                switch (op2) {
1398
                case 0:
1399
                    env->cp15.c9_data = val;
1400
                    break;
1401
                case 1:
1402
                    env->cp15.c9_insn = val;
1403
                    break;
1404
                default:
1405
                    goto bad_reg;
1406
                }
1407
                break;
1408
            case 1: /* L2 cache.  */
1409
                /* Ignore writes to L2 lockdown/auxiliary registers.  */
1410
                break;
1411
            default:
1412
                goto bad_reg;
1413
            }
1414
            break;
1415
        case 1: /* TCM memory region registers.  */
1416
            /* Not implemented.  */
1417
            goto bad_reg;
1418
        default:
1419
            goto bad_reg;
1420
        }
1421
        break;
1422
    case 10: /* MMU TLB lockdown.  */
1423
        /* ??? TLB lockdown not implemented.  */
1424
        break;
1425
    case 12: /* Reserved.  */
1426
        goto bad_reg;
1427
    case 13: /* Process ID.  */
1428
        switch (op2) {
1429
        case 0:
1430
            /* Unlike real hardware the qemu TLB uses virtual addresses,
1431
               not modified virtual addresses, so this causes a TLB flush.
1432
             */
1433
            if (env->cp15.c13_fcse != val)
1434
              tlb_flush(env, 1);
1435
            env->cp15.c13_fcse = val;
1436
            break;
1437
        case 1:
1438
            /* This changes the ASID, so do a TLB flush.  */
1439
            if (env->cp15.c13_context != val
1440
                && !arm_feature(env, ARM_FEATURE_MPU))
1441
              tlb_flush(env, 0);
1442
            env->cp15.c13_context = val;
1443
            break;
1444
        case 2:
1445
            env->cp15.c13_tls1 = val;
1446
            break;
1447
        case 3:
1448
            env->cp15.c13_tls2 = val;
1449
            break;
1450
        case 4:
1451
            env->cp15.c13_tls3 = val;
1452
            break;
1453
        default:
1454
            goto bad_reg;
1455
        }
1456
        break;
1457
    case 14: /* Reserved.  */
1458
        goto bad_reg;
1459
    case 15: /* Implementation specific.  */
1460
        if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1461
            if (op2 == 0 && crm == 1) {
1462
                if (env->cp15.c15_cpar != (val & 0x3fff)) {
1463
                    /* Changes cp0 to cp13 behavior, so needs a TB flush.  */
1464
                    tb_flush(env);
1465
                    env->cp15.c15_cpar = val & 0x3fff;
1466
                }
1467
                break;
1468
            }
1469
            goto bad_reg;
1470
        }
1471
        if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
1472
            switch (crm) {
1473
            case 0:
1474
                break;
1475
            case 1: /* Set TI925T configuration.  */
1476
                env->cp15.c15_ticonfig = val & 0xe7;
1477
                env->cp15.c0_cpuid = (val & (1 << 5)) ? /* OS_TYPE bit */
1478
                        ARM_CPUID_TI915T : ARM_CPUID_TI925T;
1479
                break;
1480
            case 2: /* Set I_max.  */
1481
                env->cp15.c15_i_max = val;
1482
                break;
1483
            case 3: /* Set I_min.  */
1484
                env->cp15.c15_i_min = val;
1485
                break;
1486
            case 4: /* Set thread-ID.  */
1487
                env->cp15.c15_threadid = val & 0xffff;
1488
                break;
1489
            case 8: /* Wait-for-interrupt (deprecated).  */
1490
                cpu_interrupt(env, CPU_INTERRUPT_HALT);
1491
                break;
1492
            default:
1493
                goto bad_reg;
1494
            }
1495
        }
1496
        break;
1497
    }
1498
    return;
1499
bad_reg:
1500
    /* ??? For debugging only.  Should raise illegal instruction exception.  */
1501
    cpu_abort(env, "Unimplemented cp15 register write (c%d, c%d, {%d, %d})\n",
1502
              (insn >> 16) & 0xf, crm, op1, op2);
1503
}
1504

    
1505
uint32_t helper_get_cp15(CPUState *env, uint32_t insn)
1506
{
1507
    int op1;
1508
    int op2;
1509
    int crm;
1510

    
1511
    op1 = (insn >> 21) & 7;
1512
    op2 = (insn >> 5) & 7;
1513
    crm = insn & 0xf;
1514
    switch ((insn >> 16) & 0xf) {
1515
    case 0: /* ID codes.  */
1516
        switch (op1) {
1517
        case 0:
1518
            switch (crm) {
1519
            case 0:
1520
                switch (op2) {
1521
                case 0: /* Device ID.  */
1522
                    return env->cp15.c0_cpuid;
1523
                case 1: /* Cache Type.  */
1524
                    return env->cp15.c0_cachetype;
1525
                case 2: /* TCM status.  */
1526
                    return 0;
1527
                case 3: /* TLB type register.  */
1528
                    return 0; /* No lockable TLB entries.  */
1529
                case 5: /* CPU ID */
1530
                    return env->cpu_index;
1531
                default:
1532
                    goto bad_reg;
1533
                }
1534
            case 1:
1535
                if (!arm_feature(env, ARM_FEATURE_V6))
1536
                    goto bad_reg;
1537
                return env->cp15.c0_c1[op2];
1538
            case 2:
1539
                if (!arm_feature(env, ARM_FEATURE_V6))
1540
                    goto bad_reg;
1541
                return env->cp15.c0_c2[op2];
1542
            case 3: case 4: case 5: case 6: case 7:
1543
                return 0;
1544
            default:
1545
                goto bad_reg;
1546
            }
1547
        case 1:
1548
            /* These registers aren't documented on arm11 cores.  However
1549
               Linux looks at them anyway.  */
1550
            if (!arm_feature(env, ARM_FEATURE_V6))
1551
                goto bad_reg;
1552
            if (crm != 0)
1553
                goto bad_reg;
1554
            if (arm_feature(env, ARM_FEATURE_XSCALE))
1555
                goto bad_reg;
1556
            return 0;
1557
        default:
1558
            goto bad_reg;
1559
        }
1560
    case 1: /* System configuration.  */
1561
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1562
            op2 = 0;
1563
        switch (op2) {
1564
        case 0: /* Control register.  */
1565
            return env->cp15.c1_sys;
1566
        case 1: /* Auxiliary control register.  */
1567
            if (arm_feature(env, ARM_FEATURE_XSCALE))
1568
                return env->cp15.c1_xscaleauxcr;
1569
            if (!arm_feature(env, ARM_FEATURE_AUXCR))
1570
                goto bad_reg;
1571
            switch (ARM_CPUID(env)) {
1572
            case ARM_CPUID_ARM1026:
1573
                return 1;
1574
            case ARM_CPUID_ARM1136:
1575
                return 7;
1576
            case ARM_CPUID_ARM11MPCORE:
1577
                return 1;
1578
            case ARM_CPUID_CORTEXA8:
1579
                return 0;
1580
            default:
1581
                goto bad_reg;
1582
            }
1583
        case 2: /* Coprocessor access register.  */
1584
            if (arm_feature(env, ARM_FEATURE_XSCALE))
1585
                goto bad_reg;
1586
            return env->cp15.c1_coproc;
1587
        default:
1588
            goto bad_reg;
1589
        }
1590
    case 2: /* MMU Page table control / MPU cache control.  */
1591
        if (arm_feature(env, ARM_FEATURE_MPU)) {
1592
            switch (op2) {
1593
            case 0:
1594
                return env->cp15.c2_data;
1595
                break;
1596
            case 1:
1597
                return env->cp15.c2_insn;
1598
                break;
1599
            default:
1600
                goto bad_reg;
1601
            }
1602
        } else {
1603
            switch (op2) {
1604
            case 0:
1605
                return env->cp15.c2_base0;
1606
            case 1:
1607
                return env->cp15.c2_base1;
1608
            case 2:
1609
                {
1610
                    int n;
1611
                    uint32_t mask;
1612
                    n = 0;
1613
                    mask = env->cp15.c2_mask;
1614
                    while (mask) {
1615
                        n++;
1616
                        mask <<= 1;
1617
                    }
1618
                    return n;
1619
                }
1620
            default:
1621
                goto bad_reg;
1622
            }
1623
        }
1624
    case 3: /* MMU Domain access control / MPU write buffer control.  */
1625
        return env->cp15.c3;
1626
    case 4: /* Reserved.  */
1627
        goto bad_reg;
1628
    case 5: /* MMU Fault status / MPU access permission.  */
1629
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1630
            op2 = 0;
1631
        switch (op2) {
1632
        case 0:
1633
            if (arm_feature(env, ARM_FEATURE_MPU))
1634
                return simple_mpu_ap_bits(env->cp15.c5_data);
1635
            return env->cp15.c5_data;
1636
        case 1:
1637
            if (arm_feature(env, ARM_FEATURE_MPU))
1638
                return simple_mpu_ap_bits(env->cp15.c5_data);
1639
            return env->cp15.c5_insn;
1640
        case 2:
1641
            if (!arm_feature(env, ARM_FEATURE_MPU))
1642
                goto bad_reg;
1643
            return env->cp15.c5_data;
1644
        case 3:
1645
            if (!arm_feature(env, ARM_FEATURE_MPU))
1646
                goto bad_reg;
1647
            return env->cp15.c5_insn;
1648
        default:
1649
            goto bad_reg;
1650
        }
1651
    case 6: /* MMU Fault address.  */
1652
        if (arm_feature(env, ARM_FEATURE_MPU)) {
1653
            if (crm >= 8)
1654
                goto bad_reg;
1655
            return env->cp15.c6_region[crm];
1656
        } else {
1657
            if (arm_feature(env, ARM_FEATURE_OMAPCP))
1658
                op2 = 0;
1659
            switch (op2) {
1660
            case 0:
1661
                return env->cp15.c6_data;
1662
            case 1:
1663
                if (arm_feature(env, ARM_FEATURE_V6)) {
1664
                    /* Watchpoint Fault Adrress.  */
1665
                    return 0; /* Not implemented.  */
1666
                } else {
1667
                    /* Instruction Fault Adrress.  */
1668
                    /* Arm9 doesn't have an IFAR, but implementing it anyway
1669
                       shouldn't do any harm.  */
1670
                    return env->cp15.c6_insn;
1671
                }
1672
            case 2:
1673
                if (arm_feature(env, ARM_FEATURE_V6)) {
1674
                    /* Instruction Fault Adrress.  */
1675
                    return env->cp15.c6_insn;
1676
                } else {
1677
                    goto bad_reg;
1678
                }
1679
            default:
1680
                goto bad_reg;
1681
            }
1682
        }
1683
    case 7: /* Cache control.  */
1684
        /* ??? This is for test, clean and invaidate operations that set the
1685
           Z flag.  We can't represent N = Z = 1, so it also clears
1686
           the N flag.  Oh well.  */
1687
        env->NZF = 0;
1688
        return 0;
1689
    case 8: /* MMU TLB control.  */
1690
        goto bad_reg;
1691
    case 9: /* Cache lockdown.  */
1692
        switch (op1) {
1693
        case 0: /* L1 cache.  */
1694
            if (arm_feature(env, ARM_FEATURE_OMAPCP))
1695
                return 0;
1696
            switch (op2) {
1697
            case 0:
1698
                return env->cp15.c9_data;
1699
            case 1:
1700
                return env->cp15.c9_insn;
1701
            default:
1702
                goto bad_reg;
1703
            }
1704
        case 1: /* L2 cache */
1705
            if (crm != 0)
1706
                goto bad_reg;
1707
            /* L2 Lockdown and Auxiliary control.  */
1708
            return 0;
1709
        default:
1710
            goto bad_reg;
1711
        }
1712
    case 10: /* MMU TLB lockdown.  */
1713
        /* ??? TLB lockdown not implemented.  */
1714
        return 0;
1715
    case 11: /* TCM DMA control.  */
1716
    case 12: /* Reserved.  */
1717
        goto bad_reg;
1718
    case 13: /* Process ID.  */
1719
        switch (op2) {
1720
        case 0:
1721
            return env->cp15.c13_fcse;
1722
        case 1:
1723
            return env->cp15.c13_context;
1724
        case 2:
1725
            return env->cp15.c13_tls1;
1726
        case 3:
1727
            return env->cp15.c13_tls2;
1728
        case 4:
1729
            return env->cp15.c13_tls3;
1730
        default:
1731
            goto bad_reg;
1732
        }
1733
    case 14: /* Reserved.  */
1734
        goto bad_reg;
1735
    case 15: /* Implementation specific.  */
1736
        if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1737
            if (op2 == 0 && crm == 1)
1738
                return env->cp15.c15_cpar;
1739

    
1740
            goto bad_reg;
1741
        }
1742
        if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
1743
            switch (crm) {
1744
            case 0:
1745
                return 0;
1746
            case 1: /* Read TI925T configuration.  */
1747
                return env->cp15.c15_ticonfig;
1748
            case 2: /* Read I_max.  */
1749
                return env->cp15.c15_i_max;
1750
            case 3: /* Read I_min.  */
1751
                return env->cp15.c15_i_min;
1752
            case 4: /* Read thread-ID.  */
1753
                return env->cp15.c15_threadid;
1754
            case 8: /* TI925T_status */
1755
                return 0;
1756
            }
1757
            goto bad_reg;
1758
        }
1759
        return 0;
1760
    }
1761
bad_reg:
1762
    /* ??? For debugging only.  Should raise illegal instruction exception.  */
1763
    cpu_abort(env, "Unimplemented cp15 register read (c%d, c%d, {%d, %d})\n",
1764
              (insn >> 16) & 0xf, crm, op1, op2);
1765
    return 0;
1766
}
1767

    
1768
void helper_set_r13_banked(CPUState *env, int mode, uint32_t val)
1769
{
1770
    env->banked_r13[bank_number(mode)] = val;
1771
}
1772

    
1773
uint32_t helper_get_r13_banked(CPUState *env, int mode)
1774
{
1775
    return env->banked_r13[bank_number(mode)];
1776
}
1777

    
1778
uint32_t helper_v7m_mrs(CPUState *env, int reg)
1779
{
1780
    switch (reg) {
1781
    case 0: /* APSR */
1782
        return xpsr_read(env) & 0xf8000000;
1783
    case 1: /* IAPSR */
1784
        return xpsr_read(env) & 0xf80001ff;
1785
    case 2: /* EAPSR */
1786
        return xpsr_read(env) & 0xff00fc00;
1787
    case 3: /* xPSR */
1788
        return xpsr_read(env) & 0xff00fdff;
1789
    case 5: /* IPSR */
1790
        return xpsr_read(env) & 0x000001ff;
1791
    case 6: /* EPSR */
1792
        return xpsr_read(env) & 0x0700fc00;
1793
    case 7: /* IEPSR */
1794
        return xpsr_read(env) & 0x0700edff;
1795
    case 8: /* MSP */
1796
        return env->v7m.current_sp ? env->v7m.other_sp : env->regs[13];
1797
    case 9: /* PSP */
1798
        return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp;
1799
    case 16: /* PRIMASK */
1800
        return (env->uncached_cpsr & CPSR_I) != 0;
1801
    case 17: /* FAULTMASK */
1802
        return (env->uncached_cpsr & CPSR_F) != 0;
1803
    case 18: /* BASEPRI */
1804
    case 19: /* BASEPRI_MAX */
1805
        return env->v7m.basepri;
1806
    case 20: /* CONTROL */
1807
        return env->v7m.control;
1808
    default:
1809
        /* ??? For debugging only.  */
1810
        cpu_abort(env, "Unimplemented system register read (%d)\n", reg);
1811
        return 0;
1812
    }
1813
}
1814

    
1815
void helper_v7m_msr(CPUState *env, int reg, uint32_t val)
1816
{
1817
    switch (reg) {
1818
    case 0: /* APSR */
1819
        xpsr_write(env, val, 0xf8000000);
1820
        break;
1821
    case 1: /* IAPSR */
1822
        xpsr_write(env, val, 0xf8000000);
1823
        break;
1824
    case 2: /* EAPSR */
1825
        xpsr_write(env, val, 0xfe00fc00);
1826
        break;
1827
    case 3: /* xPSR */
1828
        xpsr_write(env, val, 0xfe00fc00);
1829
        break;
1830
    case 5: /* IPSR */
1831
        /* IPSR bits are readonly.  */
1832
        break;
1833
    case 6: /* EPSR */
1834
        xpsr_write(env, val, 0x0600fc00);
1835
        break;
1836
    case 7: /* IEPSR */
1837
        xpsr_write(env, val, 0x0600fc00);
1838
        break;
1839
    case 8: /* MSP */
1840
        if (env->v7m.current_sp)
1841
            env->v7m.other_sp = val;
1842
        else
1843
            env->regs[13] = val;
1844
        break;
1845
    case 9: /* PSP */
1846
        if (env->v7m.current_sp)
1847
            env->regs[13] = val;
1848
        else
1849
            env->v7m.other_sp = val;
1850
        break;
1851
    case 16: /* PRIMASK */
1852
        if (val & 1)
1853
            env->uncached_cpsr |= CPSR_I;
1854
        else
1855
            env->uncached_cpsr &= ~CPSR_I;
1856
        break;
1857
    case 17: /* FAULTMASK */
1858
        if (val & 1)
1859
            env->uncached_cpsr |= CPSR_F;
1860
        else
1861
            env->uncached_cpsr &= ~CPSR_F;
1862
        break;
1863
    case 18: /* BASEPRI */
1864
        env->v7m.basepri = val & 0xff;
1865
        break;
1866
    case 19: /* BASEPRI_MAX */
1867
        val &= 0xff;
1868
        if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0))
1869
            env->v7m.basepri = val;
1870
        break;
1871
    case 20: /* CONTROL */
1872
        env->v7m.control = val & 3;
1873
        switch_v7m_sp(env, (val & 2) != 0);
1874
        break;
1875
    default:
1876
        /* ??? For debugging only.  */
1877
        cpu_abort(env, "Unimplemented system register write (%d)\n", reg);
1878
        return;
1879
    }
1880
}
1881

    
1882
void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
1883
                ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
1884
                void *opaque)
1885
{
1886
    if (cpnum < 0 || cpnum > 14) {
1887
        cpu_abort(env, "Bad coprocessor number: %i\n", cpnum);
1888
        return;
1889
    }
1890

    
1891
    env->cp[cpnum].cp_read = cp_read;
1892
    env->cp[cpnum].cp_write = cp_write;
1893
    env->cp[cpnum].opaque = opaque;
1894
}
1895

    
1896
#endif
1897