Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'ppc-for-upstream' of git://github.com/agraf/qemu

* 'ppc-for-upstream' of git://github.com/agraf/qemu: (58 commits)
  target-ppc: Use NARROW_MODE macro for tlbie
  target-ppc: Use NARROW_MODE macro for addresses
  target-ppc: Use NARROW_MODE macro for comparisons
  target-ppc: Use NARROW_MODE macro for branches
  target-ppc: Fix add and subf carry generation in narrow mode
  target-ppc: Use QOM method dispatch for MMU fault handling
  target-ppc: Move ppc tlb_fill implementation into mmu_helper.c
  target-ppc: Split user only code out of mmu_helper.c
  mmu-hash64: Implement Virtual Page Class Key Protection
  mmu-hash*: Merge translate and fault handling functions
  mmu-hash*: Don't use full ppc_hash{32, 64}_translate() path for get_phys_page_debug()
  mmu-hash*: Correctly mask RPN from hash PTE
  mmu-hash*: Clean up real address calculation
  mmu-hash*: Clean up PTE flags update
  mmu-hash64: Factor SLB N bit into permissions bits
  mmu-hash*: Clean up permission checking
  mmu-hash32: Remove nx from context structure
  mmu-hash*: Don't update PTE flags when permission is denied
  mmu-hash32: Don't look up page tables on BAT permission error
  mmu-hash32: Cleanup BAT lookup
  ...
  • Loading branch information...
commit d76bb73549fcac07524aea5135280ea533a94fd6 2 parents 52ae646 + 9ca3f7f
aurel32 aurel32 authored
3  gdbstub.c
@@ -781,7 +781,8 @@ static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n)
781 781 /* fpscr */
782 782 if (gdb_has_xml)
783 783 return 0;
784   - return 4;
  784 + store_fpscr(env, ldtul_p(mem_buf), 0xffffffff);
  785 + return sizeof(target_ulong);
785 786 }
786 787 }
787 788 return 0;
16 hw/ppc/spapr.c
@@ -629,7 +629,7 @@ static void ppc_spapr_reset(void)
629 629 spapr->rtas_size);
630 630
631 631 /* Set up the entry state */
632   - first_cpu_cpu = CPU(first_cpu);
  632 + first_cpu_cpu = ENV_GET_CPU(first_cpu);
633 633 first_cpu->gpr[3] = spapr->fdt_addr;
634 634 first_cpu->gpr[5] = 0;
635 635 first_cpu_cpu->halted = 0;
@@ -779,6 +779,11 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
779 779 spapr->htab_shift++;
780 780 }
781 781
  782 + /* Set up Interrupt Controller before we create the VCPUs */
  783 + spapr->icp = xics_system_init(smp_cpus * kvmppc_smt_threads() / smp_threads,
  784 + XICS_IRQS);
  785 + spapr->next_irq = XICS_IRQ_BASE;
  786 +
782 787 /* init CPUs */
783 788 if (cpu_model == NULL) {
784 789 cpu_model = kvm_enabled() ? "host" : "POWER7";
@@ -791,6 +796,8 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
791 796 }
792 797 env = &cpu->env;
793 798
  799 + xics_cpu_setup(spapr->icp, cpu);
  800 +
794 801 /* Set time-base frequency to 512 MHz */
795 802 cpu_ppc_tb_init(env, TIMEBASE_FREQ);
796 803
@@ -830,11 +837,6 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
830 837 }
831 838 g_free(filename);
832 839
833   -
834   - /* Set up Interrupt Controller */
835   - spapr->icp = xics_system_init(XICS_IRQS);
836   - spapr->next_irq = XICS_IRQ_BASE;
837   -
838 840 /* Set up EPOW events infrastructure */
839 841 spapr_events_init(spapr);
840 842
@@ -856,7 +858,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
856 858 /* Set up PCI */
857 859 spapr_pci_rtas_init();
858 860
859   - phb = spapr_create_phb(spapr, 0, "pci");
  861 + phb = spapr_create_phb(spapr, 0);
860 862
861 863 for (i = 0; i < nb_nics; i++) {
862 864 NICInfo *nd = &nd_table[i];
102 hw/ppc/spapr_hcall.c
@@ -3,39 +3,7 @@
3 3 #include "sysemu/sysemu.h"
4 4 #include "helper_regs.h"
5 5 #include "hw/spapr.h"
6   -
7   -#define HPTES_PER_GROUP 8
8   -
9   -#define HPTE_V_SSIZE_SHIFT 62
10   -#define HPTE_V_AVPN_SHIFT 7
11   -#define HPTE_V_AVPN 0x3fffffffffffff80ULL
12   -#define HPTE_V_AVPN_VAL(x) (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT)
13   -#define HPTE_V_COMPARE(x, y) (!(((x) ^ (y)) & 0xffffffffffffff80UL))
14   -#define HPTE_V_BOLTED 0x0000000000000010ULL
15   -#define HPTE_V_LOCK 0x0000000000000008ULL
16   -#define HPTE_V_LARGE 0x0000000000000004ULL
17   -#define HPTE_V_SECONDARY 0x0000000000000002ULL
18   -#define HPTE_V_VALID 0x0000000000000001ULL
19   -
20   -#define HPTE_R_PP0 0x8000000000000000ULL
21   -#define HPTE_R_TS 0x4000000000000000ULL
22   -#define HPTE_R_KEY_HI 0x3000000000000000ULL
23   -#define HPTE_R_RPN_SHIFT 12
24   -#define HPTE_R_RPN 0x3ffffffffffff000ULL
25   -#define HPTE_R_FLAGS 0x00000000000003ffULL
26   -#define HPTE_R_PP 0x0000000000000003ULL
27   -#define HPTE_R_N 0x0000000000000004ULL
28   -#define HPTE_R_G 0x0000000000000008ULL
29   -#define HPTE_R_M 0x0000000000000010ULL
30   -#define HPTE_R_I 0x0000000000000020ULL
31   -#define HPTE_R_W 0x0000000000000040ULL
32   -#define HPTE_R_WIMG 0x0000000000000078ULL
33   -#define HPTE_R_C 0x0000000000000080ULL
34   -#define HPTE_R_R 0x0000000000000100ULL
35   -#define HPTE_R_KEY_LO 0x0000000000000e00ULL
36   -
37   -#define HPTE_V_1TB_SEG 0x4000000000000000ULL
38   -#define HPTE_V_VRMA_MASK 0x4001ffffff000000ULL
  6 +#include "mmu-hash64.h"
39 7
40 8 static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r,
41 9 target_ulong pte_index)
@@ -44,17 +12,17 @@ static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r,
44 12
45 13 rb = (v & ~0x7fULL) << 16; /* AVA field */
46 14 va_low = pte_index >> 3;
47   - if (v & HPTE_V_SECONDARY) {
  15 + if (v & HPTE64_V_SECONDARY) {
48 16 va_low = ~va_low;
49 17 }
50 18 /* xor vsid from AVA */
51   - if (!(v & HPTE_V_1TB_SEG)) {
  19 + if (!(v & HPTE64_V_1TB_SEG)) {
52 20 va_low ^= v >> 12;
53 21 } else {
54 22 va_low ^= v >> 24;
55 23 }
56 24 va_low &= 0x7ff;
57   - if (v & HPTE_V_LARGE) {
  25 + if (v & HPTE64_V_LARGE) {
58 26 rb |= 1; /* L field */
59 27 #if 0 /* Disable that P7 specific bit for now */
60 28 if (r & 0xff000) {
@@ -84,10 +52,10 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
84 52 target_ulong page_shift = 12;
85 53 target_ulong raddr;
86 54 target_ulong i;
87   - uint8_t *hpte;
  55 + hwaddr hpte;
88 56
89 57 /* only handle 4k and 16M pages for now */
90   - if (pteh & HPTE_V_LARGE) {
  58 + if (pteh & HPTE64_V_LARGE) {
91 59 #if 0 /* We don't support 64k pages yet */
92 60 if ((ptel & 0xf000) == 0x1000) {
93 61 /* 64k page */
@@ -105,11 +73,11 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
105 73 }
106 74 }
107 75
108   - raddr = (ptel & HPTE_R_RPN) & ~((1ULL << page_shift) - 1);
  76 + raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << page_shift) - 1);
109 77
110 78 if (raddr < spapr->ram_limit) {
111 79 /* Regular RAM - should have WIMG=0010 */
112   - if ((ptel & HPTE_R_WIMG) != HPTE_R_M) {
  80 + if ((ptel & HPTE64_R_WIMG) != HPTE64_R_M) {
113 81 return H_PARAMETER;
114 82 }
115 83 } else {
@@ -117,7 +85,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
117 85 /* FIXME: What WIMG combinations could be sensible for IO?
118 86 * For now we allow WIMG=010x, but are there others? */
119 87 /* FIXME: Should we check against registered IO addresses? */
120   - if ((ptel & (HPTE_R_W | HPTE_R_I | HPTE_R_M)) != HPTE_R_I) {
  88 + if ((ptel & (HPTE64_R_W | HPTE64_R_I | HPTE64_R_M)) != HPTE64_R_I) {
121 89 return H_PARAMETER;
122 90 }
123 91 }
@@ -129,26 +97,26 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
129 97 }
130 98 if (likely((flags & H_EXACT) == 0)) {
131 99 pte_index &= ~7ULL;
132   - hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
  100 + hpte = pte_index * HASH_PTE_SIZE_64;
133 101 for (i = 0; ; ++i) {
134 102 if (i == 8) {
135 103 return H_PTEG_FULL;
136 104 }
137   - if ((ldq_p(hpte) & HPTE_V_VALID) == 0) {
  105 + if ((ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) == 0) {
138 106 break;
139 107 }
140 108 hpte += HASH_PTE_SIZE_64;
141 109 }
142 110 } else {
143 111 i = 0;
144   - hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
145   - if (ldq_p(hpte) & HPTE_V_VALID) {
  112 + hpte = pte_index * HASH_PTE_SIZE_64;
  113 + if (ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) {
146 114 return H_PTEG_FULL;
147 115 }
148 116 }
149   - stq_p(hpte + (HASH_PTE_SIZE_64/2), ptel);
  117 + ppc_hash64_store_hpte1(env, hpte, ptel);
150 118 /* eieio(); FIXME: need some sort of barrier for smp? */
151   - stq_p(hpte, pteh);
  119 + ppc_hash64_store_hpte0(env, hpte, pteh);
152 120
153 121 args[0] = pte_index + i;
154 122 return H_SUCCESS;
@@ -166,26 +134,26 @@ static target_ulong remove_hpte(CPUPPCState *env, target_ulong ptex,
166 134 target_ulong flags,
167 135 target_ulong *vp, target_ulong *rp)
168 136 {
169   - uint8_t *hpte;
  137 + hwaddr hpte;
170 138 target_ulong v, r, rb;
171 139
172 140 if ((ptex * HASH_PTE_SIZE_64) & ~env->htab_mask) {
173 141 return REMOVE_PARM;
174 142 }
175 143
176   - hpte = env->external_htab + (ptex * HASH_PTE_SIZE_64);
  144 + hpte = ptex * HASH_PTE_SIZE_64;
177 145
178   - v = ldq_p(hpte);
179   - r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));
  146 + v = ppc_hash64_load_hpte0(env, hpte);
  147 + r = ppc_hash64_load_hpte1(env, hpte);
180 148
181   - if ((v & HPTE_V_VALID) == 0 ||
  149 + if ((v & HPTE64_V_VALID) == 0 ||
182 150 ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) ||
183 151 ((flags & H_ANDCOND) && (v & avpn) != 0)) {
184 152 return REMOVE_NOT_FOUND;
185 153 }
186 154 *vp = v;
187 155 *rp = r;
188   - stq_p(hpte, 0);
  156 + ppc_hash64_store_hpte0(env, hpte, 0);
189 157 rb = compute_tlbie_rb(v, r, ptex);
190 158 ppc_tlb_invalidate_one(env, rb);
191 159 return REMOVE_SUCCESS;
@@ -271,7 +239,7 @@ static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPREnvironment *spapr,
271 239
272 240 switch (ret) {
273 241 case REMOVE_SUCCESS:
274   - *tsh |= (r & (HPTE_R_C | HPTE_R_R)) << 43;
  242 + *tsh |= (r & (HPTE64_R_C | HPTE64_R_R)) << 43;
275 243 break;
276 244
277 245 case REMOVE_PARM:
@@ -292,34 +260,34 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,
292 260 target_ulong flags = args[0];
293 261 target_ulong pte_index = args[1];
294 262 target_ulong avpn = args[2];
295   - uint8_t *hpte;
  263 + hwaddr hpte;
296 264 target_ulong v, r, rb;
297 265
298 266 if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
299 267 return H_PARAMETER;
300 268 }
301 269
302   - hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
  270 + hpte = pte_index * HASH_PTE_SIZE_64;
303 271
304   - v = ldq_p(hpte);
305   - r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));
  272 + v = ppc_hash64_load_hpte0(env, hpte);
  273 + r = ppc_hash64_load_hpte1(env, hpte);
306 274
307   - if ((v & HPTE_V_VALID) == 0 ||
  275 + if ((v & HPTE64_V_VALID) == 0 ||
308 276 ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {
309 277 return H_NOT_FOUND;
310 278 }
311 279
312   - r &= ~(HPTE_R_PP0 | HPTE_R_PP | HPTE_R_N |
313   - HPTE_R_KEY_HI | HPTE_R_KEY_LO);
314   - r |= (flags << 55) & HPTE_R_PP0;
315   - r |= (flags << 48) & HPTE_R_KEY_HI;
316   - r |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO);
  280 + r &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
  281 + HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
  282 + r |= (flags << 55) & HPTE64_R_PP0;
  283 + r |= (flags << 48) & HPTE64_R_KEY_HI;
  284 + r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
317 285 rb = compute_tlbie_rb(v, r, pte_index);
318   - stq_p(hpte, v & ~HPTE_V_VALID);
  286 + ppc_hash64_store_hpte0(env, hpte, v & ~HPTE64_V_VALID);
319 287 ppc_tlb_invalidate_one(env, rb);
320   - stq_p(hpte + (HASH_PTE_SIZE_64/2), r);
  288 + ppc_hash64_store_hpte1(env, hpte, r);
321 289 /* Don't need a memory barrier, due to qemu's global lock */
322   - stq_p(hpte, v);
  290 + ppc_hash64_store_hpte0(env, hpte, v);
323 291 return H_SUCCESS;
324 292 }
325 293
57 hw/ppc/xics.c
@@ -521,45 +521,38 @@ static void xics_reset(void *opaque)
521 521 }
522 522 }
523 523
524   -struct icp_state *xics_system_init(int nr_irqs)
  524 +void xics_cpu_setup(struct icp_state *icp, PowerPCCPU *cpu)
525 525 {
526   - CPUPPCState *env;
527   - CPUState *cpu;
528   - int max_server_num;
529   - struct icp_state *icp;
530   - struct ics_state *ics;
  526 + CPUState *cs = CPU(cpu);
  527 + CPUPPCState *env = &cpu->env;
  528 + struct icp_server_state *ss = &icp->ss[cs->cpu_index];
531 529
532   - max_server_num = -1;
533   - for (env = first_cpu; env != NULL; env = env->next_cpu) {
534   - cpu = CPU(ppc_env_get_cpu(env));
535   - if (cpu->cpu_index > max_server_num) {
536   - max_server_num = cpu->cpu_index;
537   - }
538   - }
  530 + assert(cs->cpu_index < icp->nr_servers);
539 531
540   - icp = g_malloc0(sizeof(*icp));
541   - icp->nr_servers = max_server_num + 1;
542   - icp->ss = g_malloc0(icp->nr_servers*sizeof(struct icp_server_state));
  532 + switch (PPC_INPUT(env)) {
  533 + case PPC_FLAGS_INPUT_POWER7:
  534 + ss->output = env->irq_inputs[POWER7_INPUT_INT];
  535 + break;
543 536
544   - for (env = first_cpu; env != NULL; env = env->next_cpu) {
545   - cpu = CPU(ppc_env_get_cpu(env));
546   - struct icp_server_state *ss = &icp->ss[cpu->cpu_index];
  537 + case PPC_FLAGS_INPUT_970:
  538 + ss->output = env->irq_inputs[PPC970_INPUT_INT];
  539 + break;
547 540
548   - switch (PPC_INPUT(env)) {
549   - case PPC_FLAGS_INPUT_POWER7:
550   - ss->output = env->irq_inputs[POWER7_INPUT_INT];
551   - break;
  541 + default:
  542 + fprintf(stderr, "XICS interrupt controller does not support this CPU "
  543 + "bus model\n");
  544 + abort();
  545 + }
  546 +}
552 547
553   - case PPC_FLAGS_INPUT_970:
554   - ss->output = env->irq_inputs[PPC970_INPUT_INT];
555   - break;
  548 +struct icp_state *xics_system_init(int nr_servers, int nr_irqs)
  549 +{
  550 + struct icp_state *icp;
  551 + struct ics_state *ics;
556 552
557   - default:
558   - hw_error("XICS interrupt model does not support this CPU bus "
559   - "model\n");
560   - exit(1);
561   - }
562   - }
  553 + icp = g_malloc0(sizeof(*icp));
  554 + icp->nr_servers = nr_servers;
  555 + icp->ss = g_malloc0(icp->nr_servers*sizeof(struct icp_server_state));
563 556
564 557 ics = g_malloc0(sizeof(*ics));
565 558 ics->nr_irqs = nr_irqs;
30 hw/spapr_pci.c
@@ -518,6 +518,7 @@ static int spapr_phb_init(SysBusDevice *s)
518 518 {
519 519 sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
520 520 PCIHostState *phb = PCI_HOST_BRIDGE(s);
  521 + const char *busname;
521 522 char *namebuf;
522 523 int i;
523 524 PCIBus *bus;
@@ -575,9 +576,6 @@ static int spapr_phb_init(SysBusDevice *s)
575 576 }
576 577
577 578 sphb->dtbusname = g_strdup_printf("pci@%" PRIx64, sphb->buid);
578   - if (!sphb->busname) {
579   - sphb->busname = sphb->dtbusname;
580   - }
581 579
582 580 namebuf = alloca(strlen(sphb->dtbusname) + 32);
583 581
@@ -621,7 +619,26 @@ static int spapr_phb_init(SysBusDevice *s)
621 619 &sphb->msiwindow);
622 620 }
623 621
624   - bus = pci_register_bus(DEVICE(s), sphb->busname,
  622 + /*
  623 + * Selecting a busname is more complex than you'd think, due to
  624 + * interacting constraints. If the user has specified an id
  625 + * explicitly for the phb , then we want to use the qdev default
  626 + * of naming the bus based on the bridge device (so the user can
  627 + * then assign devices to it in the way they expect). For the
  628 + * first / default PCI bus (index=0) we want to use just "pci"
  629 + * because libvirt expects there to be a bus called, simply,
  630 + * "pci". Otherwise, we use the same name as in the device tree,
  631 + * since it's unique by construction, and makes the guest visible
  632 + * BUID clear.
  633 + */
  634 + if (s->qdev.id) {
  635 + busname = NULL;
  636 + } else if (sphb->index == 0) {
  637 + busname = "pci";
  638 + } else {
  639 + busname = sphb->dtbusname;
  640 + }
  641 + bus = pci_register_bus(DEVICE(s), busname,
625 642 pci_spapr_set_irq, pci_spapr_map_irq, sphb,
626 643 &sphb->memspace, &sphb->iospace,
627 644 PCI_DEVFN(0, 0), PCI_NUM_PINS);
@@ -663,7 +680,6 @@ static void spapr_phb_reset(DeviceState *qdev)
663 680 }
664 681
665 682 static Property spapr_phb_properties[] = {
666   - DEFINE_PROP_STRING("busname", sPAPRPHBState, busname),
667 683 DEFINE_PROP_INT32("index", sPAPRPHBState, index, -1),
668 684 DEFINE_PROP_HEX64("buid", sPAPRPHBState, buid, -1),
669 685 DEFINE_PROP_HEX32("liobn", sPAPRPHBState, dma_liobn, -1),
@@ -694,14 +710,12 @@ static const TypeInfo spapr_phb_info = {
694 710 .class_init = spapr_phb_class_init,
695 711 };
696 712
697   -PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index,
698   - const char *busname)
  713 +PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index)
699 714 {
700 715 DeviceState *dev;
701 716
702 717 dev = qdev_create(NULL, TYPE_SPAPR_PCI_HOST_BRIDGE);
703 718 qdev_prop_set_uint32(dev, "index", index);
704   - qdev_prop_set_string(dev, "busname", busname);
705 719 qdev_init_nofail(dev);
706 720
707 721 return PCI_HOST_BRIDGE(dev);
4 hw/spapr_pci.h
@@ -39,7 +39,6 @@ typedef struct sPAPRPHBState {
39 39
40 40 int32_t index;
41 41 uint64_t buid;
42   - char *busname;
43 42 char *dtbusname;
44 43
45 44 MemoryRegion memspace, iospace;
@@ -82,8 +81,7 @@ static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin)
82 81 return xics_get_qirq(spapr->icp, phb->lsi_table[pin].irq);
83 82 }
84 83
85   -PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index,
86   - const char *busname);
  84 +PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index);
87 85
88 86 int spapr_populate_pci_dt(sPAPRPHBState *phb,
89 87 uint32_t xics_phandle,
3  hw/xics.h
@@ -35,6 +35,7 @@ struct icp_state;
35 35 qemu_irq xics_get_qirq(struct icp_state *icp, int irq);
36 36 void xics_set_irq_type(struct icp_state *icp, int irq, bool lsi);
37 37
38   -struct icp_state *xics_system_init(int nr_irqs);
  38 +struct icp_state *xics_system_init(int nr_servers, int nr_irqs);
  39 +void xics_cpu_setup(struct icp_state *icp, PowerPCCPU *cpu);
39 40
40 41 #endif /* __XICS_H__ */
4 monitor.c
@@ -2960,10 +2960,6 @@ static const MonitorDef monitor_defs[] = {
2960 2960 { "xer", 0, &monitor_get_xer, },
2961 2961 { "tbu", 0, &monitor_get_tbu, },
2962 2962 { "tbl", 0, &monitor_get_tbl, },
2963   -#if defined(TARGET_PPC64)
2964   - /* Address space register */
2965   - { "asr", offsetof(CPUPPCState, asr) },
2966   -#endif
2967 2963 /* Segment registers */
2968 2964 { "sdr1", offsetof(CPUPPCState, spr[SPR_SDR1]) },
2969 2965 { "sr0", offsetof(CPUPPCState, sr[0]) },
7 target-ppc/Makefile.objs
... ... @@ -1,11 +1,14 @@
1 1 obj-y += cpu-models.o
2 2 obj-y += translate.o
3   -obj-$(CONFIG_SOFTMMU) += machine.o
  3 +ifeq ($(CONFIG_SOFTMMU),y)
  4 +obj-y += machine.o mmu_helper.o mmu-hash32.o
  5 +obj-$(TARGET_PPC64) += mmu-hash64.o
  6 +endif
4 7 obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o
5 8 obj-y += excp_helper.o
6 9 obj-y += fpu_helper.o
7 10 obj-y += int_helper.o
8   -obj-y += mmu_helper.o
9 11 obj-y += timebase_helper.o
10 12 obj-y += misc_helper.o
11 13 obj-y += mem_helper.o
  14 +obj-$(CONFIG_USER_ONLY) += user_only_helper.o
2  target-ppc/cpu-models.c
@@ -1101,9 +1101,9 @@
1101 1101 "PowerPC 7457A v1.2 (G4)")
1102 1102 /* 64 bits PowerPC */
1103 1103 #if defined (TARGET_PPC64)
  1104 +#if defined(TODO)
1104 1105 POWERPC_DEF("620", CPU_POWERPC_620, 620,
1105 1106 "PowerPC 620")
1106   -#if defined(TODO)
1107 1107 POWERPC_DEF("630", CPU_POWERPC_630, 630,
1108 1108 "PowerPC 630 (POWER3)")
1109 1109 #endif
4 target-ppc/cpu-qom.h
@@ -68,6 +68,10 @@ typedef struct PowerPCCPUClass {
68 68 #endif
69 69 void (*init_proc)(CPUPPCState *env);
70 70 int (*check_pow)(CPUPPCState *env);
  71 +#if defined(CONFIG_SOFTMMU)
  72 + int (*handle_mmu_fault)(CPUPPCState *env, target_ulong eaddr, int rwx,
  73 + int mmu_idx);
  74 +#endif
71 75 } PowerPCCPUClass;
72 76
73 77 /**
91 target-ppc/cpu.h
@@ -113,13 +113,13 @@ enum powerpc_mmu_t {
113 113 #if defined(TARGET_PPC64)
114 114 #define POWERPC_MMU_64 0x00010000
115 115 #define POWERPC_MMU_1TSEG 0x00020000
  116 +#define POWERPC_MMU_AMR 0x00040000
116 117 /* 64 bits PowerPC MMU */
117 118 POWERPC_MMU_64B = POWERPC_MMU_64 | 0x00000001,
118   - /* 620 variant (no segment exceptions) */
119   - POWERPC_MMU_620 = POWERPC_MMU_64 | 0x00000002,
120 119 /* Architecture 2.06 variant */
121   - POWERPC_MMU_2_06 = POWERPC_MMU_64 | POWERPC_MMU_1TSEG | 0x00000003,
122   - /* Architecture 2.06 "degraded" (no 1T segments) */
  120 + POWERPC_MMU_2_06 = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
  121 + | POWERPC_MMU_AMR | 0x00000003,
  122 + /* Architecture 2.06 "degraded" (no 1T segments or AMR) */
123 123 POWERPC_MMU_2_06d = POWERPC_MMU_64 | 0x00000003,
124 124 #endif /* defined(TARGET_PPC64) */
125 125 };
@@ -396,36 +396,12 @@ union ppc_tlb_t {
396 396 #define SDR_64_HTABSIZE 0x000000000000001FULL
397 397 #endif /* defined(TARGET_PPC64 */
398 398
399   -#define HASH_PTE_SIZE_32 8
400   -#define HASH_PTE_SIZE_64 16
401   -
402 399 typedef struct ppc_slb_t ppc_slb_t;
403 400 struct ppc_slb_t {
404 401 uint64_t esid;
405 402 uint64_t vsid;
406 403 };
407 404
408   -/* Bits in the SLB ESID word */
409   -#define SLB_ESID_ESID 0xFFFFFFFFF0000000ULL
410   -#define SLB_ESID_V 0x0000000008000000ULL /* valid */
411   -
412   -/* Bits in the SLB VSID word */
413   -#define SLB_VSID_SHIFT 12
414   -#define SLB_VSID_SHIFT_1T 24
415   -#define SLB_VSID_SSIZE_SHIFT 62
416   -#define SLB_VSID_B 0xc000000000000000ULL
417   -#define SLB_VSID_B_256M 0x0000000000000000ULL
418   -#define SLB_VSID_B_1T 0x4000000000000000ULL
419   -#define SLB_VSID_VSID 0x3FFFFFFFFFFFF000ULL
420   -#define SLB_VSID_PTEM (SLB_VSID_B | SLB_VSID_VSID)
421   -#define SLB_VSID_KS 0x0000000000000800ULL
422   -#define SLB_VSID_KP 0x0000000000000400ULL
423   -#define SLB_VSID_N 0x0000000000000200ULL /* no-execute */
424   -#define SLB_VSID_L 0x0000000000000100ULL
425   -#define SLB_VSID_C 0x0000000000000080ULL /* class */
426   -#define SLB_VSID_LP 0x0000000000000030ULL
427   -#define SLB_VSID_ATTR 0x0000000000000FFFULL
428   -
429 405 #define SEGMENT_SHIFT_256M 28
430 406 #define SEGMENT_MASK_256M (~((1ULL << SEGMENT_SHIFT_256M) - 1))
431 407
@@ -965,8 +941,6 @@ struct CPUPPCState {
965 941 /* MMU context - only relevant for full system emulation */
966 942 #if !defined(CONFIG_USER_ONLY)
967 943 #if defined(TARGET_PPC64)
968   - /* Address space register */
969   - target_ulong asr;
970 944 /* PowerPC 64 SLB area */
971 945 ppc_slb_t slb[64];
972 946 int slb_nr;
@@ -1105,20 +1079,6 @@ do { \
1105 1079 env->wdt_period[3] = (d_); \
1106 1080 } while (0)
1107 1081
1108   -#if !defined(CONFIG_USER_ONLY)
1109   -/* Context used internally during MMU translations */
1110   -typedef struct mmu_ctx_t mmu_ctx_t;
1111   -struct mmu_ctx_t {
1112   - hwaddr raddr; /* Real address */
1113   - hwaddr eaddr; /* Effective address */
1114   - int prot; /* Protection bits */
1115   - hwaddr hash[2]; /* Pagetable hash values */
1116   - target_ulong ptem; /* Virtual segment ID | API */
1117   - int key; /* Access key */
1118   - int nx; /* Non-execute area */
1119   -};
1120   -#endif
1121   -
1122 1082 #include "cpu-qom.h"
1123 1083
1124 1084 /*****************************************************************************/
@@ -1130,17 +1090,14 @@ int cpu_ppc_exec (CPUPPCState *s);
1130 1090 is returned if the signal was handled by the virtual CPU. */
1131 1091 int cpu_ppc_signal_handler (int host_signum, void *pinfo,
1132 1092 void *puc);
1133   -int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw,
1134   - int mmu_idx);
1135   -#define cpu_handle_mmu_fault cpu_ppc_handle_mmu_fault
1136 1093 void ppc_hw_interrupt (CPUPPCState *env);
  1094 +#if defined(CONFIG_USER_ONLY)
  1095 +int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
  1096 + int mmu_idx);
  1097 +#endif
1137 1098
1138 1099 #if !defined(CONFIG_USER_ONLY)
1139 1100 void ppc_store_sdr1 (CPUPPCState *env, target_ulong value);
1140   -#if defined(TARGET_PPC64)
1141   -void ppc_store_asr (CPUPPCState *env, target_ulong value);
1142   -int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs);
1143   -#endif /* defined(TARGET_PPC64) */
1144 1101 #endif /* !defined(CONFIG_USER_ONLY) */
1145 1102 void ppc_store_msr (CPUPPCState *env, target_ulong value);
1146 1103
@@ -1172,14 +1129,13 @@ void store_40x_dbcr0 (CPUPPCState *env, uint32_t val);
1172 1129 void store_40x_sler (CPUPPCState *env, uint32_t val);
1173 1130 void store_booke_tcr (CPUPPCState *env, target_ulong val);
1174 1131 void store_booke_tsr (CPUPPCState *env, target_ulong val);
1175   -int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb,
1176   - hwaddr *raddrp, target_ulong address,
1177   - uint32_t pid);
1178 1132 void ppc_tlb_invalidate_all (CPUPPCState *env);
1179 1133 void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr);
1180 1134 #endif
1181 1135 #endif
1182 1136
  1137 +void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask);
  1138 +
1183 1139 static inline uint64_t ppc_dump_gpr(CPUPPCState *env, int gprn)
1184 1140 {
1185 1141 uint64_t gprv;
@@ -1270,6 +1226,7 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
1270 1226 #define SPR_601_UDECR (0x006)
1271 1227 #define SPR_LR (0x008)
1272 1228 #define SPR_CTR (0x009)
  1229 +#define SPR_UAMR (0x00C)
1273 1230 #define SPR_DSCR (0x011)
1274 1231 #define SPR_DSISR (0x012)
1275 1232 #define SPR_DAR (0x013) /* DAE for PowerPC 601 */
@@ -1307,6 +1264,7 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
1307 1264 #define SPR_MPC_CMPH (0x09B)
1308 1265 #define SPR_MPC_LCTRL1 (0x09C)
1309 1266 #define SPR_MPC_LCTRL2 (0x09D)
  1267 +#define SPR_UAMOR (0x09D)
1310 1268 #define SPR_MPC_ICTRL (0x09E)
1311 1269 #define SPR_MPC_BAR (0x09F)
1312 1270 #define SPR_VRSAVE (0x100)
@@ -1489,11 +1447,9 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
1489 1447 #define SPR_RCPU_MI_RBA2 (0x302)
1490 1448 #define SPR_MPC_MI_AP (0x302)
1491 1449 #define SPR_PERF3 (0x303)
1492   -#define SPR_620_PMC1R (0x303)
1493 1450 #define SPR_RCPU_MI_RBA3 (0x303)
1494 1451 #define SPR_MPC_MI_EPN (0x303)
1495 1452 #define SPR_PERF4 (0x304)
1496   -#define SPR_620_PMC2R (0x304)
1497 1453 #define SPR_PERF5 (0x305)
1498 1454 #define SPR_MPC_MI_TWC (0x305)
1499 1455 #define SPR_PERF6 (0x306)
@@ -1509,7 +1465,6 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
1509 1465 #define SPR_RCPU_L2U_RBA2 (0x30A)
1510 1466 #define SPR_MPC_MD_AP (0x30A)
1511 1467 #define SPR_PERFB (0x30B)
1512   -#define SPR_620_MMCR0R (0x30B)
1513 1468 #define SPR_RCPU_L2U_RBA3 (0x30B)
1514 1469 #define SPR_MPC_MD_EPN (0x30B)
1515 1470 #define SPR_PERFC (0x30C)
@@ -1524,9 +1479,7 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
1524 1479 #define SPR_UPERF1 (0x311)
1525 1480 #define SPR_UPERF2 (0x312)
1526 1481 #define SPR_UPERF3 (0x313)
1527   -#define SPR_620_PMC1W (0x313)
1528 1482 #define SPR_UPERF4 (0x314)
1529   -#define SPR_620_PMC2W (0x314)
1530 1483 #define SPR_UPERF5 (0x315)
1531 1484 #define SPR_UPERF6 (0x316)
1532 1485 #define SPR_UPERF7 (0x317)
@@ -1534,7 +1487,6 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
1534 1487 #define SPR_UPERF9 (0x319)
1535 1488 #define SPR_UPERFA (0x31A)
1536 1489 #define SPR_UPERFB (0x31B)
1537   -#define SPR_620_MMCR0W (0x31B)
1538 1490 #define SPR_UPERFC (0x31C)
1539 1491 #define SPR_UPERFD (0x31D)
1540 1492 #define SPR_UPERFE (0x31E)
@@ -1606,49 +1558,33 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
1606 1558 #define SPR_USDA (0x3AF)
1607 1559 #define SPR_40x_ZPR (0x3B0)
1608 1560 #define SPR_BOOKE_MAS7 (0x3B0)
1609   -#define SPR_620_PMR0 (0x3B0)
1610 1561 #define SPR_MMCR2 (0x3B0)
1611 1562 #define SPR_PMC5 (0x3B1)
1612 1563 #define SPR_40x_PID (0x3B1)
1613   -#define SPR_620_PMR1 (0x3B1)
1614 1564 #define SPR_PMC6 (0x3B2)
1615 1565 #define SPR_440_MMUCR (0x3B2)
1616   -#define SPR_620_PMR2 (0x3B2)
1617 1566 #define SPR_4xx_CCR0 (0x3B3)
1618 1567 #define SPR_BOOKE_EPLC (0x3B3)
1619   -#define SPR_620_PMR3 (0x3B3)
1620 1568 #define SPR_405_IAC3 (0x3B4)
1621 1569 #define SPR_BOOKE_EPSC (0x3B4)
1622   -#define SPR_620_PMR4 (0x3B4)
1623 1570 #define SPR_405_IAC4 (0x3B5)
1624   -#define SPR_620_PMR5 (0x3B5)
1625 1571 #define SPR_405_DVC1 (0x3B6)
1626   -#define SPR_620_PMR6 (0x3B6)
1627 1572 #define SPR_405_DVC2 (0x3B7)
1628   -#define SPR_620_PMR7 (0x3B7)
1629 1573 #define SPR_BAMR (0x3B7)
1630 1574 #define SPR_MMCR0 (0x3B8)
1631   -#define SPR_620_PMR8 (0x3B8)
1632 1575 #define SPR_PMC1 (0x3B9)
1633 1576 #define SPR_40x_SGR (0x3B9)
1634   -#define SPR_620_PMR9 (0x3B9)
1635 1577 #define SPR_PMC2 (0x3BA)
1636 1578 #define SPR_40x_DCWR (0x3BA)
1637   -#define SPR_620_PMRA (0x3BA)
1638 1579 #define SPR_SIAR (0x3BB)
1639 1580 #define SPR_405_SLER (0x3BB)
1640   -#define SPR_620_PMRB (0x3BB)
1641 1581 #define SPR_MMCR1 (0x3BC)
1642 1582 #define SPR_405_SU0R (0x3BC)
1643   -#define SPR_620_PMRC (0x3BC)
1644 1583 #define SPR_401_SKR (0x3BC)
1645 1584 #define SPR_PMC3 (0x3BD)
1646 1585 #define SPR_405_DBCR1 (0x3BD)
1647   -#define SPR_620_PMRD (0x3BD)
1648 1586 #define SPR_PMC4 (0x3BE)
1649   -#define SPR_620_PMRE (0x3BE)
1650 1587 #define SPR_SDA (0x3BF)
1651   -#define SPR_620_PMRF (0x3BF)
1652 1588 #define SPR_403_VTBL (0x3CC)
1653 1589 #define SPR_403_VTBU (0x3CD)
1654 1590 #define SPR_DMISS (0x3D0)
@@ -1716,15 +1652,12 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
1716 1652 #define SPR_LDSTCR (0x3F8)
1717 1653 #define SPR_L2PMCR (0x3F8)
1718 1654 #define SPR_750FX_HID2 (0x3F8)
1719   -#define SPR_620_BUSCSR (0x3F8)
1720 1655 #define SPR_Exxx_L1FINV0 (0x3F8)
1721 1656 #define SPR_L2CR (0x3F9)
1722   -#define SPR_620_L2CR (0x3F9)
1723 1657 #define SPR_L3CR (0x3FA)
1724 1658 #define SPR_750_TDCH (0x3FA)
1725 1659 #define SPR_IABR2 (0x3FA)
1726 1660 #define SPR_40x_DCCR (0x3FA)
1727   -#define SPR_620_L2SR (0x3FA)
1728 1661 #define SPR_ICTC (0x3FB)
1729 1662 #define SPR_40x_ICCR (0x3FB)
1730 1663 #define SPR_THRM1 (0x3FC)
5 target-ppc/fpu_helper.c
@@ -463,6 +463,11 @@ void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
463 463 fpscr_set_rounding_mode(env);
464 464 }
465 465
  466 +void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
  467 +{
  468 + helper_store_fpscr(env, arg, mask);
  469 +}
  470 +
466 471 void helper_float_check_status(CPUPPCState *env)
467 472 {
468 473 if (env->exception_index == POWERPC_EXCP_PROGRAM &&
1  target-ppc/helper.h
@@ -382,7 +382,6 @@ DEF_HELPER_1(load_601_rtcl, tl, env)
382 382 DEF_HELPER_1(load_601_rtcu, tl, env)
383 383 #if !defined(CONFIG_USER_ONLY)
384 384 #if defined(TARGET_PPC64)
385   -DEF_HELPER_2(store_asr, void, env, tl)
386 385 DEF_HELPER_1(load_purr, tl, env)
387 386 #endif
388 387 DEF_HELPER_2(store_sdr1, void, env, tl)
3  target-ppc/kvm.c
@@ -32,6 +32,7 @@
32 32 #include "sysemu/device_tree.h"
33 33 #include "hw/sysbus.h"
34 34 #include "hw/spapr.h"
  35 +#include "mmu-hash64.h"
35 36
36 37 #include "hw/sysbus.h"
37 38 #include "hw/spapr.h"
@@ -1077,7 +1078,7 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
1077 1078 dprintf("handle halt\n");
1078 1079 ret = kvmppc_handle_halt(cpu);
1079 1080 break;
1080   -#ifdef CONFIG_PSERIES
  1081 +#if defined(TARGET_PPC64)
1081 1082 case KVM_EXIT_PAPR_HCALL:
1082 1083 dprintf("handle PAPR hypercall\n");
1083 1084 run->papr_hcall.ret = spapr_hypercall(cpu,
4 target-ppc/machine.c
@@ -37,7 +37,7 @@ void cpu_save(QEMUFile *f, void *opaque)
37 37 qemu_put_be32s(f, &fpscr);
38 38 qemu_put_sbe32s(f, &env->access_type);
39 39 #if defined(TARGET_PPC64)
40   - qemu_put_betls(f, &env->asr);
  40 + qemu_put_betls(f, &env->spr[SPR_ASR]);
41 41 qemu_put_sbe32s(f, &env->slb_nr);
42 42 #endif
43 43 qemu_put_betls(f, &env->spr[SPR_SDR1]);
@@ -125,7 +125,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
125 125 env->fpscr = fpscr;
126 126 qemu_get_sbe32s(f, &env->access_type);
127 127 #if defined(TARGET_PPC64)
128   - qemu_get_betls(f, &env->asr);
  128 + qemu_get_betls(f, &env->spr[SPR_ASR]);
129 129 qemu_get_sbe32s(f, &env->slb_nr);
130 130 #endif
131 131 qemu_get_betls(f, &sdr1);
38 target-ppc/mem_helper.c
@@ -252,41 +252,3 @@ STVE(stvewx, cpu_stl_data, bswap32, u32)
252 252
253 253 #undef HI_IDX
254 254 #undef LO_IDX
255   -
256   -/*****************************************************************************/
257   -/* Softmmu support */
258   -#if !defined(CONFIG_USER_ONLY)
259   -
260   -#define MMUSUFFIX _mmu
261   -
262   -#define SHIFT 0
263   -#include "exec/softmmu_template.h"
264   -
265   -#define SHIFT 1
266   -#include "exec/softmmu_template.h"
267   -
268   -#define SHIFT 2
269   -#include "exec/softmmu_template.h"
270   -
271   -#define SHIFT 3
272   -#include "exec/softmmu_template.h"
273   -
274   -/* try to fill the TLB and return an exception if error. If retaddr is
275   - NULL, it means that the function was called in C code (i.e. not
276   - from generated code or from helper.c) */
277   -/* XXX: fix it to restore all registers */
278   -void tlb_fill(CPUPPCState *env, target_ulong addr, int is_write, int mmu_idx,
279   - uintptr_t retaddr)
280   -{
281   - int ret;
282   -
283   - ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx);
284   - if (unlikely(ret != 0)) {
285   - if (likely(retaddr)) {
286   - /* now we have a real cpu fault */
287   - cpu_restore_state(env, retaddr);
288   - }
289   - helper_raise_exception_err(env, env->exception_index, env->error_code);
290   - }
291   -}
292   -#endif /* !CONFIG_USER_ONLY */
6 target-ppc/misc_helper.c
@@ -35,12 +35,6 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn)
35 35 env->spr[sprn]);
36 36 }
37 37 #if !defined(CONFIG_USER_ONLY)
38   -#if defined(TARGET_PPC64)
39   -void helper_store_asr(CPUPPCState *env, target_ulong val)
40   -{
41   - ppc_store_asr(env, val);
42   -}
43   -#endif
44 38
45 39 void helper_store_sdr1(CPUPPCState *env, target_ulong val)
46 40 {
560 target-ppc/mmu-hash32.c
... ... @@ -0,0 +1,560 @@
  1 +/*
  2 + * PowerPC MMU, TLB and BAT emulation helpers for QEMU.
  3 + *
  4 + * Copyright (c) 2003-2007 Jocelyn Mayer
  5 + * Copyright (c) 2013 David Gibson, IBM Corporation
  6 + *
  7 + * This library is free software; you can redistribute it and/or
  8 + * modify it under the terms of the GNU Lesser General Public
  9 + * License as published by the Free Software Foundation; either
  10 + * version 2 of the License, or (at your option) any later version.
  11 + *
  12 + * This library is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  19 + */
  20 +
  21 +#include "cpu.h"
  22 +#include "helper.h"
  23 +#include "sysemu/kvm.h"
  24 +#include "kvm_ppc.h"
  25 +#include "mmu-hash32.h"
  26 +
  27 +//#define DEBUG_MMU
  28 +//#define DEBUG_BAT
  29 +
  30 +#ifdef DEBUG_MMU
  31 +# define LOG_MMU(...) qemu_log(__VA_ARGS__)
  32 +# define LOG_MMU_STATE(env) log_cpu_state((env), 0)
  33 +#else
  34 +# define LOG_MMU(...) do { } while (0)
  35 +# define LOG_MMU_STATE(...) do { } while (0)
  36 +#endif
  37 +
  38 +#ifdef DEBUG_BATS
  39 +# define LOG_BATS(...) qemu_log(__VA_ARGS__)
  40 +#else
  41 +# define LOG_BATS(...) do { } while (0)
  42 +#endif
  43 +
  44 +struct mmu_ctx_hash32 {
  45 + hwaddr raddr; /* Real address */
  46 + int prot; /* Protection bits */
  47 + int key; /* Access key */
  48 +};
  49 +
  50 +static int ppc_hash32_pp_prot(int key, int pp, int nx)
  51 +{
  52 + int prot;
  53 +
  54 + if (key == 0) {
  55 + switch (pp) {
  56 + case 0x0:
  57 + case 0x1:
  58 + case 0x2:
  59 + prot = PAGE_READ | PAGE_WRITE;
  60 + break;
  61 +
  62 + case 0x3:
  63 + prot = PAGE_READ;
  64 + break;
  65 +
  66 + default:
  67 + abort();
  68 + }
  69 + } else {
  70 + switch (pp) {
  71 + case 0x0:
  72 + prot = 0;
  73 + break;
  74 +
  75 + case 0x1:
  76 + case 0x3:
  77 + prot = PAGE_READ;
  78 + break;
  79 +
  80 + case 0x2:
  81 + prot = PAGE_READ | PAGE_WRITE;
  82 + break;
  83 +
  84 + default:
  85 + abort();
  86 + }
  87 + }
  88 + if (nx == 0) {
  89 + prot |= PAGE_EXEC;
  90 + }
  91 +
  92 + return prot;
  93 +}
  94 +
  95 +static int ppc_hash32_pte_prot(CPUPPCState *env,
  96 + target_ulong sr, ppc_hash_pte32_t pte)
  97 +{
  98 + unsigned pp, key;
  99 +
  100 + key = !!(msr_pr ? (sr & SR32_KP) : (sr & SR32_KS));
  101 + pp = pte.pte1 & HPTE32_R_PP;
  102 +
  103 + return ppc_hash32_pp_prot(key, pp, !!(sr & SR32_NX));
  104 +}
  105 +
  106 +static target_ulong hash32_bat_size(CPUPPCState *env,
  107 + target_ulong batu, target_ulong batl)
  108 +{
  109 + if ((msr_pr && !(batu & BATU32_VP))
  110 + || (!msr_pr && !(batu & BATU32_VS))) {
  111 + return 0;
  112 + }
  113 +
  114 + return BATU32_BEPI & ~((batu & BATU32_BL) << 15);
  115 +}
  116 +
  117 +static int hash32_bat_prot(CPUPPCState *env,
  118 + target_ulong batu, target_ulong batl)
  119 +{
  120 + int pp, prot;
  121 +
  122 + prot = 0;
  123 + pp = batl & BATL32_PP;
  124 + if (pp != 0) {
  125 + prot = PAGE_READ | PAGE_EXEC;
  126 + if (pp == 0x2) {
  127 + prot |= PAGE_WRITE;
  128 + }
  129 + }
  130 + return prot;
  131 +}
  132 +
  133 +static target_ulong hash32_bat_601_size(CPUPPCState *env,
  134 + target_ulong batu, target_ulong batl)
  135 +{
  136 + if (!(batl & BATL32_601_V)) {
  137 + return 0;
  138 + }
  139 +
  140 + return BATU32_BEPI & ~((batl & BATL32_601_BL) << 17);
  141 +}
  142 +
  143 +static int hash32_bat_601_prot(CPUPPCState *env,
  144 + target_ulong batu, target_ulong batl)
  145 +{
  146 + int key, pp;
  147 +
  148 + pp = batu & BATU32_601_PP;
  149 + if (msr_pr == 0) {
  150 + key = !!(batu & BATU32_601_KS);
  151 + } else {
  152 + key = !!(batu & BATU32_601_KP);
  153 + }
  154 + return ppc_hash32_pp_prot(key, pp, 0);
  155 +}
  156 +
  157 +static hwaddr ppc_hash32_bat_lookup(CPUPPCState *env, target_ulong ea, int rwx,
  158 + int *prot)
  159 +{
  160 + target_ulong *BATlt, *BATut;
  161 + int i;
  162 +
  163 + LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
  164 + rwx == 2 ? 'I' : 'D', ea);
  165 + if (rwx == 2) {
  166 + BATlt = env->IBAT[1];
  167 + BATut = env->IBAT[0];
  168 + } else {
  169 + BATlt = env->DBAT[1];
  170 + BATut = env->DBAT[0];
  171 + }
  172 + for (i = 0; i < env->nb_BATs; i++) {
  173 + target_ulong batu = BATut[i];
  174 + target_ulong batl = BATlt[i];
  175 + target_ulong mask;
  176 +
  177 + if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
  178 + mask = hash32_bat_601_size(env, batu, batl);
  179 + } else {
  180 + mask = hash32_bat_size(env, batu, batl);
  181 + }
  182 + LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
  183 + " BATl " TARGET_FMT_lx "\n", __func__,
  184 + type == ACCESS_CODE ? 'I' : 'D', i, ea, batu, batl);
  185 +
  186 + if (mask && ((ea & mask) == (batu & BATU32_BEPI))) {
  187 + hwaddr raddr = (batl & mask) | (ea & ~mask);
  188 +
  189 + if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
  190 + *prot = hash32_bat_601_prot(env, batu, batl);
  191 + } else {
  192 + *prot = hash32_bat_prot(env, batu, batl);
  193 + }
  194 +
  195 + return raddr & TARGET_PAGE_MASK;
  196 + }
  197 + }
  198 +
  199 + /* No hit */
  200 +#if defined(DEBUG_BATS)
  201 + if (qemu_log_enabled()) {
  202 + LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", ea);
  203 + for (i = 0; i < 4; i++) {
  204 + BATu = &BATut[i];
  205 + BATl = &BATlt[i];
  206 + BEPIu = *BATu & BATU32_BEPIU;
  207 + BEPIl = *BATu & BATU32_BEPIL;
  208 + bl = (*BATu & 0x00001FFC) << 15;
  209 + LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
  210 + " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
  211 + TARGET_FMT_lx " " TARGET_FMT_lx "\n",
  212 + __func__, type == ACCESS_CODE ? 'I' : 'D', i, ea,
  213 + *BATu, *BATl, BEPIu, BEPIl, bl);
  214 + }
  215 + }
  216 +#endif
  217 +
  218 + return -1;
  219 +}
  220 +
  221 +static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
  222 + target_ulong eaddr, int rwx,
  223 + hwaddr *raddr, int *prot)
  224 +{
  225 + int key = !!(msr_pr ? (sr & SR32_KP) : (sr & SR32_KS));
  226 +
  227 + LOG_MMU("direct store...\n");
  228 +
  229 + if ((sr & 0x1FF00000) >> 20 == 0x07f) {
  230 + /* Memory-forced I/O controller interface access */
  231 + /* If T=1 and BUID=x'07F', the 601 performs a memory access
  232 + * to SR[28-31] LA[4-31], bypassing all protection mechanisms.
  233 + */
  234 + *raddr = ((sr & 0xF) << 28) | (eaddr & 0x0FFFFFFF);
  235 + *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
  236 + return 0;
  237 + }
  238 +
  239 + if (rwx == 2) {
  240 + /* No code fetch is allowed in direct-store areas */
  241 + env->exception_index = POWERPC_EXCP_ISI;
  242 + env->error_code = 0x10000000;
  243 + return 1;
  244 + }
  245 +
  246 + switch (env->access_type) {
  247 + case ACCESS_INT:
  248 + /* Integer load/store : only access allowed */
  249 + break;
  250 + case ACCESS_FLOAT:
  251 + /* Floating point load/store */
  252 + env->exception_index = POWERPC_EXCP_ALIGN;
  253 + env->error_code = POWERPC_EXCP_ALIGN_FP;
  254 + env->spr[SPR_DAR] = eaddr;
  255 + return 1;
  256 + case ACCESS_RES:
  257 + /* lwarx, ldarx or srwcx. */
  258 + env->error_code = 0;
  259 + env->spr[SPR_DAR] = eaddr;
  260 + if (rwx == 1) {
  261 + env->spr[SPR_DSISR] = 0x06000000;
  262 + } else {
  263 + env->spr[SPR_DSISR] = 0x04000000;
  264 + }
  265 + return 1;
  266 + case ACCESS_CACHE:
  267 + /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
  268 + /* Should make the instruction do no-op.
  269 + * As it already do no-op, it's quite easy :-)
  270 + */
  271 + *raddr = eaddr;
  272 + return 0;
  273 + case ACCESS_EXT:
  274 + /* eciwx or ecowx */
  275 + env->exception_index = POWERPC_EXCP_DSI;
  276 + env->error_code = 0;
  277 + env->spr[SPR_DAR] = eaddr;
  278 + if (rwx == 1) {
  279 + env->spr[SPR_DSISR] = 0x06100000;
  280 + } else {
  281 + env->spr[SPR_DSISR] = 0x04100000;
  282 + }
  283 + return 1;
  284 + default:
  285 + qemu_log("ERROR: instruction should not need "
  286 + "address translation\n");
  287 + abort();
  288 + }
  289 + if ((rwx == 1 || key != 1) && (rwx == 0 || key != 0)) {
  290 + *raddr = eaddr;
  291 + return 0;
  292 + } else {
  293 + env->exception_index = POWERPC_EXCP_DSI;
  294 + env->error_code = 0;
  295 + env->spr[SPR_DAR] = eaddr;
  296 + if (rwx == 1) {
  297 + env->spr[SPR_DSISR] = 0x0a000000;
  298 + } else {