Revision 9ee6e8bb target-arm/helper.c

b/target-arm/helper.c
4 4

  
5 5
#include "cpu.h"
6 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 };
7 26

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

  
......
34 53
        env->cp15.c0_cachetype = 0x1dd20d2;
35 54
        env->cp15.c1_sys = 0x00090078;
36 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;
37 112
    case ARM_CPUID_TI915T:
38 113
    case ARM_CPUID_TI925T:
39 114
        set_feature(env, ARM_FEATURE_OMAPCP);
......
85 160
#else
86 161
    /* SVC mode with interrupts disabled.  */
87 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;
88 167
    env->vfp.xregs[ARM_VFP_FPEXC] = 0;
89 168
#endif
90 169
    env->regs[15] = 0;
......
117 196
    { ARM_CPUID_ARM926, "arm926"},
118 197
    { ARM_CPUID_ARM946, "arm946"},
119 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"},
120 203
    { ARM_CPUID_TI925T, "ti925t" },
121 204
    { ARM_CPUID_PXA250, "pxa250" },
122 205
    { ARM_CPUID_PXA255, "pxa255" },
......
130 213
    { ARM_CPUID_PXA270_B1, "pxa270-b1" },
131 214
    { ARM_CPUID_PXA270_C0, "pxa270-c0" },
132 215
    { ARM_CPUID_PXA270_C5, "pxa270-c5" },
216
    { ARM_CPUID_ANY, "any"},
133 217
    { 0, NULL}
134 218
};
135 219

  
......
164 248
    free(env);
165 249
}
166 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

  
167 275
#if defined(CONFIG_USER_ONLY)
168 276

  
169 277
void do_interrupt (CPUState *env)
......
171 279
    env->exception_index = -1;
172 280
}
173 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

  
174 292
int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
175 293
                              int mmu_idx, int is_softmmu)
176 294
{
......
184 302
    return 1;
185 303
}
186 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

  
187 363
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
188 364
{
189 365
    return addr;
......
215 391
    return 0;
216 392
}
217 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

  
218 406
void switch_mode(CPUState *env, int mode)
219 407
{
220 408
    if (mode != ARM_CPU_MODE_USR)
221 409
        cpu_abort(env, "Tried to switch out of user mode\n");
222 410
}
223 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

  
224 423
#else
225 424

  
226 425
extern int semihosting_enabled;
......
275 474
    env->spsr = env->banked_spsr[i];
276 475
}
277 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

  
278 600
/* Handle a CPU exception.  */
279 601
void do_interrupt(CPUARMState *env)
280 602
{
......
283 605
    int new_mode;
284 606
    uint32_t offset;
285 607

  
608
    if (IS_M(env)) {
609
        do_interrupt_v7m(env);
610
        return;
611
    }
286 612
    /* TODO: Vectored interrupt controller.  */
287 613
    switch (env->exception_index) {
288 614
    case EXCP_UDEF:
......
317 643
        /* The PC already points to the next instructon.  */
318 644
        offset = 0;
319 645
        break;
320
    case EXCP_PREFETCH_ABORT:
321 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:
322 659
        new_mode = ARM_CPU_MODE_ABT;
323 660
        addr = 0x0c;
324 661
        mask = CPSR_A | CPSR_I;
......
354 691
    }
355 692
    switch_mode (env, new_mode);
356 693
    env->spsr = cpsr_read(env);
694
    /* Clear IT bits.  */
695
    env->condexec_bits = 0;
357 696
    /* Switch to the new mode, and switch to Arm mode.  */
358 697
    /* ??? Thumb interrupt handlers not implemented.  */
359 698
    env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
......
370 709
static inline int check_ap(CPUState *env, int ap, int domain, int access_type,
371 710
                           int is_user)
372 711
{
712
  int prot_ro;
713

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

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

  
376 722
  switch (ap) {
377 723
  case 0:
378 724
      if (access_type == 1)
......
389 735
      return is_user ? 0 : PAGE_READ | PAGE_WRITE;
390 736
  case 2:
391 737
      if (is_user)
392
          return (access_type == 1) ? 0 : PAGE_READ;
738
          return prot_ro;
393 739
      else
394 740
          return PAGE_READ | PAGE_WRITE;
395 741
  case 3:
396 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;
397 749
  default:
398 750
      abort();
399 751
  }
400 752
}
401 753

  
402
static int get_phys_addr(CPUState *env, uint32_t address, int access_type,
403
                         int is_user, uint32_t *phys_ptr, int *prot)
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)
404 756
{
405 757
    int code;
406 758
    uint32_t table;
......
410 762
    int domain;
411 763
    uint32_t phys_addr;
412 764

  
413
    /* Fast Context Switch Extension.  */
414
    if (address < 0x02000000)
415
        address += env->cp15.c13_fcse;
416

  
417
    if ((env->cp15.c1_sys & 1) == 0) {
418
        /* MMU/MPU disabled.  */
419
        *phys_ptr = address;
420
        *prot = PAGE_READ | PAGE_WRITE;
421
    } else if (arm_feature(env, ARM_FEATURE_MPU)) {
422
        int n;
423
        uint32_t mask;
424
        uint32_t base;
425

  
426
        *phys_ptr = address;
427
        for (n = 7; n >= 0; n--) {
428
            base = env->cp15.c6_region[n];
429
            if ((base & 1) == 0)
430
                continue;
431
            mask = 1 << ((base >> 1) & 0x1f);
432
            /* Keep this shift separate from the above to avoid an
433
               (undefined) << 32.  */
434
            mask = (mask << 1) - 1;
435
            if (((base ^ address) & ~mask) == 0)
436
                break;
437
        }
438
        if (n < 0)
439
            return 2;
440

  
441
        if (access_type == 2) {
442
            mask = env->cp15.c5_insn;
443
        } else {
444
            mask = env->cp15.c5_data;
445
        }
446
        mask = (mask >> (n * 4)) & 0xf;
447
        switch (mask) {
448
        case 0:
449
            return 1;
450
        case 1:
451
            if (is_user)
452
              return 1;
453
            *prot = PAGE_READ | PAGE_WRITE;
454
            break;
455
        case 2:
456
            *prot = PAGE_READ;
457
            if (!is_user)
458
                *prot |= PAGE_WRITE;
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;
459 809
            break;
460
        case 3:
461
            *prot = PAGE_READ | PAGE_WRITE;
810
        case 2: /* 4k page.  */
811
            phys_addr = (desc & 0xfffff000) | (address & 0xfff);
812
            ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
462 813
            break;
463
        case 5:
464
            if (is_user)
465
                return 1;
466
            *prot = PAGE_READ;
467
            break;
468
        case 6:
469
            *prot = PAGE_READ;
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;
470 827
            break;
471 828
        default:
472
            /* Bad permission.  */
473
            return 1;
829
            /* Never happens, but compiler isn't smart enough to tell.  */
830
            abort();
474 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;
475 874
    } else {
476
        /* Pagetable walk.  */
477
        /* Lookup l1 descriptor.  */
478
        table = (env->cp15.c2_base & 0xffffc000) | ((address >> 18) & 0x3ffc);
479
        desc = ldl_phys(table);
480
        type = (desc & 3);
481
        domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3;
482
        if (type == 0) {
483
            /* Secton translation fault.  */
484
            code = 5;
485
            goto do_fault;
486
        }
487
        if (domain == 0 || domain == 2) {
488
            if (type == 2)
489
                code = 9; /* Section domain fault.  */
490
            else
491
                code = 11; /* Page domain fault.  */
492
            goto do_fault;
493
        }
494
        if (type == 2) {
495
            /* 1Mb section.  */
496
            phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
497
            ap = (desc >> 10) & 3;
498
            code = 13;
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);
499 890
        } else {
500
            /* Lookup l2 entry.  */
501
            if (type == 1) {
502
                /* Coarse pagetable.  */
503
                table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
504
            } else {
505
                /* Fine pagetable.  */
506
                table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
507
            }
508
            desc = ldl_phys(table);
509
            switch (desc & 3) {
510
            case 0: /* Page translation fault.  */
511
                code = 7;
512
                goto do_fault;
513
            case 1: /* 64k page.  */
514
                phys_addr = (desc & 0xffff0000) | (address & 0xffff);
515
                ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
516
                break;
517
            case 2: /* 4k page.  */
518
                phys_addr = (desc & 0xfffff000) | (address & 0xfff);
519
                ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
520
                break;
521
            case 3: /* 1k page.  */
522
                if (type == 1) {
523
                    if (arm_feature(env, ARM_FEATURE_XSCALE))
524
                        phys_addr = (desc & 0xfffff000) | (address & 0xfff);
525
                    else {
526
                        /* Page translation fault.  */
527
                        code = 7;
528
                        goto do_fault;
529
                    }
530
                } else
531
                    phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
532
                ap = (desc >> 4) & 3;
533
                break;
534
            default:
535
                /* Never happens, but compiler isn't smart enough to tell.  */
536
                abort();
537
            }
538
            code = 15;
891
            /* Section.  */
892
            phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
539 893
        }
540
        *prot = check_ap(env, ap, domain, access_type, is_user);
541
        if (!*prot) {
542
            /* Access permission fault.  */
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;
543 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();
544 917
        }
545
        *phys_ptr = phys_addr;
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;
546 927
    }
928
    *phys_ptr = phys_addr;
547 929
    return 0;
548 930
do_fault:
549 931
    return code | (domain << 4);
550 932
}
551 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

  
552 1018
int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
553 1019
                              int access_type, int mmu_idx, int is_softmmu)
554 1020
{
......
572 1038
        env->exception_index = EXCP_PREFETCH_ABORT;
573 1039
    } else {
574 1040
        env->cp15.c5_data = ret;
1041
        if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6))
1042
            env->cp15.c5_data |= (1 << 11);
575 1043
        env->cp15.c6_data = address;
576 1044
        env->exception_index = EXCP_DATA_ABORT;
577 1045
    }
......
592 1060
    return phys_addr;
593 1061
}
594 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

  
595 1081
void helper_set_cp(CPUState *env, uint32_t insn, uint32_t val)
596 1082
{
597 1083
    int cp_num = (insn >> 8) & 0xf;
......
649 1135

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

  
1142
    op1 = (insn >> 21) & 7;
655 1143
    op2 = (insn >> 5) & 7;
656 1144
    crm = insn & 0xf;
657 1145
    switch ((insn >> 16) & 0xf) {
658
    case 0: /* ID codes.  */
1146
    case 0:
1147
        if (((insn >> 21) & 7) == 2) {
1148
            /* ??? Select cache level.  Ignore.  */
1149
            return;
1150
        }
1151
        /* ID codes.  */
659 1152
        if (arm_feature(env, ARM_FEATURE_XSCALE))
660 1153
            break;
661 1154
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
......
672 1165
            /* This may enable/disable the MMU, so do a TLB flush.  */
673 1166
            tlb_flush(env, 1);
674 1167
            break;
675
        case 1:
1168
        case 1: /* Auxiliary cotrol register.  */
676 1169
            if (arm_feature(env, ARM_FEATURE_XSCALE)) {
677 1170
                env->cp15.c1_xscaleauxcr = val;
678 1171
                break;
679 1172
            }
680
            goto bad_reg;
1173
            /* Not implemented.  */
1174
            break;
681 1175
        case 2:
682 1176
            if (arm_feature(env, ARM_FEATURE_XSCALE))
683 1177
                goto bad_reg;
......
702 1196
                goto bad_reg;
703 1197
            }
704 1198
        } else {
705
            env->cp15.c2_base = val;
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
	    }
706 1212
        }
707 1213
        break;
708 1214
    case 3: /* MMU Domain access control / MPU write buffer control.  */
......
751 1257
            case 0:
752 1258
                env->cp15.c6_data = val;
753 1259
                break;
754
            case 1:
1260
            case 1: /* ??? This is WFAR on armv6 */
1261
            case 2:
755 1262
                env->cp15.c6_insn = val;
756 1263
                break;
757 1264
            default:
......
763 1270
        env->cp15.c15_i_max = 0x000;
764 1271
        env->cp15.c15_i_min = 0xff0;
765 1272
        /* No cache, so nothing to do.  */
1273
        /* ??? MPCore has VA to PA translation functions.  */
766 1274
        break;
767 1275
    case 8: /* MMU TLB control.  */
768 1276
        switch (op2) {
......
783 1291
            tlb_flush(env, 1);
784 1292
#endif
785 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;
786 1301
        default:
787 1302
            goto bad_reg;
788 1303
        }
......
792 1307
            break;
793 1308
        switch (crm) {
794 1309
        case 0: /* Cache lockdown.  */
795
            switch (op2) {
796
            case 0:
797
                env->cp15.c9_data = val;
798
                break;
799
            case 1:
800
                env->cp15.c9_insn = val;
801
                break;
802
            default:
803
                goto bad_reg;
804
            }
805
            break;
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;
806 1330
        case 1: /* TCM memory region registers.  */
807 1331
            /* Not implemented.  */
808 1332
            goto bad_reg;
......
832 1356
              tlb_flush(env, 0);
833 1357
            env->cp15.c13_context = val;
834 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;
835 1368
        default:
836 1369
            goto bad_reg;
837 1370
        }
......
880 1413
    return;
881 1414
bad_reg:
882 1415
    /* ??? For debugging only.  Should raise illegal instruction exception.  */
883
    cpu_abort(env, "Unimplemented cp15 register write\n");
1416
    cpu_abort(env, "Unimplemented cp15 register write (c%d, c%d, {%d, %d})\n",
1417
              (insn >> 16) & 0xf, crm, op1, op2);
884 1418
}
885 1419

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

  
1426
    op1 = (insn >> 21) & 7;
891 1427
    op2 = (insn >> 5) & 7;
892 1428
    crm = insn & 0xf;
893 1429
    switch ((insn >> 16) & 0xf) {
894 1430
    case 0: /* ID codes.  */
895
        switch (op2) {
896
        default: /* Device ID.  */
897
            return env->cp15.c0_cpuid;
898
        case 1: /* Cache Type.  */
899
            return env->cp15.c0_cachetype;
900
        case 2: /* TCM status.  */
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;
901 1469
            if (arm_feature(env, ARM_FEATURE_XSCALE))
902 1470
                goto bad_reg;
903 1471
            return 0;
1472
        default:
1473
            goto bad_reg;
904 1474
        }
905 1475
    case 1: /* System configuration.  */
906 1476
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
......
909 1479
        case 0: /* Control register.  */
910 1480
            return env->cp15.c1_sys;
911 1481
        case 1: /* Auxiliary control register.  */
912
            if (arm_feature(env, ARM_FEATURE_AUXCR))
913
                return 1;
914 1482
            if (arm_feature(env, ARM_FEATURE_XSCALE))
915 1483
                return env->cp15.c1_xscaleauxcr;
916
            goto bad_reg;
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
            }
917 1498
        case 2: /* Coprocessor access register.  */
918 1499
            if (arm_feature(env, ARM_FEATURE_XSCALE))
919 1500
                goto bad_reg;
......
934 1515
                goto bad_reg;
935 1516
            }
936 1517
        } else {
937
            return env->cp15.c2_base;
938
        }
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
	}
939 1539
    case 3: /* MMU Domain access control / MPU write buffer control.  */
940 1540
        return env->cp15.c3;
941 1541
    case 4: /* Reserved.  */
......
963 1563
        default:
964 1564
            goto bad_reg;
965 1565
        }
966
    case 6: /* MMU Fault address / MPU base/size.  */
1566
    case 6: /* MMU Fault address.  */
967 1567
        if (arm_feature(env, ARM_FEATURE_MPU)) {
968
            int n;
969
            n = (insn & 0xf);
970
            if (n >= 8)
1568
            if (crm >= 8)
971 1569
                goto bad_reg;
972
            return env->cp15.c6_region[n];
1570
            return env->cp15.c6_region[crm];
973 1571
        } else {
974 1572
            if (arm_feature(env, ARM_FEATURE_OMAPCP))
975 1573
                op2 = 0;
976
            switch (op2) {
977
            case 0:
978
                return env->cp15.c6_data;
979
            case 1:
980
                /* Arm9 doesn't have an IFAR, but implementing it anyway
981
                   shouldn't do any harm.  */
982
                return env->cp15.c6_insn;
983
            default:
984
                goto bad_reg;
985
            }
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
	    }
986 1597
        }
987 1598
    case 7: /* Cache control.  */
988 1599
        /* ??? This is for test, clean and invaidate operations that set the
......
993 1604
    case 8: /* MMU TLB control.  */
994 1605
        goto bad_reg;
995 1606
    case 9: /* Cache lockdown.  */
996
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
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.  */
997 1623
            return 0;
998
        switch (op2) {
999
        case 0:
1000
            return env->cp15.c9_data;
1001
        case 1:
1002
            return env->cp15.c9_insn;
1003 1624
        default:
1004 1625
            goto bad_reg;
1005 1626
        }
......
1015 1636
            return env->cp15.c13_fcse;
1016 1637
        case 1:
1017 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;
1018 1645
        default:
1019 1646
            goto bad_reg;
1020 1647
        }
......
1048 1675
    }
1049 1676
bad_reg:
1050 1677
    /* ??? For debugging only.  Should raise illegal instruction exception.  */
1051
    cpu_abort(env, "Unimplemented cp15 register read\n");
1678
    cpu_abort(env, "Unimplemented cp15 register read (c%d, c%d, {%d, %d})\n",
1679
              (insn >> 16) & 0xf, crm, op1, op2);
1052 1680
    return 0;
1053 1681
}
1054 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

  
1055 1797
void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
1056 1798
                ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
1057 1799
                void *opaque)

Also available in: Unified diff