From a4e044c30e0044947fd0d69b1888d916f96bba6b Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 14 Mar 2013 17:59:29 +0000 Subject: pseries: Fix breakage in CPU QOM conversion Commit 259186a7d2f7184efc96ae99bc5658e6159f53ad "cpu: Move halted and interrupt_request fields to CPUState" broke the pseries machine. That's because it uses CPU() instead of ENV_GET_CPU() to convert from the global first_cpu pointer (still a CPUArchState) to a CPUState. This patch fixes the breakage. Signed-off-by: David Gibson Signed-off-by: Alexander Graf --- hw/ppc/spapr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index f355a9b..d45098d 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -629,7 +629,7 @@ static void ppc_spapr_reset(void) spapr->rtas_size); /* Set up the entry state */ - first_cpu_cpu = CPU(first_cpu); + first_cpu_cpu = ENV_GET_CPU(first_cpu); first_cpu->gpr[3] = spapr->fdt_addr; first_cpu->gpr[5] = 0; first_cpu_cpu->halted = 0; -- cgit v1.1 From 89dfd6e1b3c0b31ef700203808be2a9a71947d1d Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 13 Mar 2013 15:53:25 +0000 Subject: pseries: Remove "busname" property for PCI host bridge Currently the "spapr-pci-host-bridge" device has a "busname" property which can be used to override the default assignment of qbus names for the bus subordinate to the PHB. We use that for the default primary PCI bus, to make libvirt happy, which expects there to be a bus named simply "pci". The default qdev core logic would name the bus "pci.0", and the pseries code would otherwise name it "pci@800000020000000" which is the name it is given in the device tree based on its BUID. The "busname" property is rather clunky though, so this patch simplifies things by just using a special case hack for the default PHB, setting busname to "pci" when index=0. Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson Signed-off-by: Alexander Graf --- hw/ppc/spapr.c | 2 +- hw/spapr_pci.c | 30 ++++++++++++++++++++++-------- hw/spapr_pci.h | 4 +--- 3 files changed, 24 insertions(+), 12 deletions(-) (limited to 'hw') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index d45098d..74ae83b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -856,7 +856,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) /* Set up PCI */ spapr_pci_rtas_init(); - phb = spapr_create_phb(spapr, 0, "pci"); + phb = spapr_create_phb(spapr, 0); for (i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 36adbc5..42c8b61 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -518,6 +518,7 @@ static int spapr_phb_init(SysBusDevice *s) { sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s); PCIHostState *phb = PCI_HOST_BRIDGE(s); + const char *busname; char *namebuf; int i; PCIBus *bus; @@ -575,9 +576,6 @@ static int spapr_phb_init(SysBusDevice *s) } sphb->dtbusname = g_strdup_printf("pci@%" PRIx64, sphb->buid); - if (!sphb->busname) { - sphb->busname = sphb->dtbusname; - } namebuf = alloca(strlen(sphb->dtbusname) + 32); @@ -621,7 +619,26 @@ static int spapr_phb_init(SysBusDevice *s) &sphb->msiwindow); } - bus = pci_register_bus(DEVICE(s), sphb->busname, + /* + * Selecting a busname is more complex than you'd think, due to + * interacting constraints. If the user has specified an id + * explicitly for the phb , then we want to use the qdev default + * of naming the bus based on the bridge device (so the user can + * then assign devices to it in the way they expect). For the + * first / default PCI bus (index=0) we want to use just "pci" + * because libvirt expects there to be a bus called, simply, + * "pci". Otherwise, we use the same name as in the device tree, + * since it's unique by construction, and makes the guest visible + * BUID clear. + */ + if (s->qdev.id) { + busname = NULL; + } else if (sphb->index == 0) { + busname = "pci"; + } else { + busname = sphb->dtbusname; + } + bus = pci_register_bus(DEVICE(s), busname, pci_spapr_set_irq, pci_spapr_map_irq, sphb, &sphb->memspace, &sphb->iospace, PCI_DEVFN(0, 0), PCI_NUM_PINS); @@ -663,7 +680,6 @@ static void spapr_phb_reset(DeviceState *qdev) } static Property spapr_phb_properties[] = { - DEFINE_PROP_STRING("busname", sPAPRPHBState, busname), DEFINE_PROP_INT32("index", sPAPRPHBState, index, -1), DEFINE_PROP_HEX64("buid", sPAPRPHBState, buid, -1), DEFINE_PROP_HEX32("liobn", sPAPRPHBState, dma_liobn, -1), @@ -694,14 +710,12 @@ static const TypeInfo spapr_phb_info = { .class_init = spapr_phb_class_init, }; -PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index, - const char *busname) +PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index) { DeviceState *dev; dev = qdev_create(NULL, TYPE_SPAPR_PCI_HOST_BRIDGE); qdev_prop_set_uint32(dev, "index", index); - qdev_prop_set_string(dev, "busname", busname); qdev_init_nofail(dev); return PCI_HOST_BRIDGE(dev); diff --git a/hw/spapr_pci.h b/hw/spapr_pci.h index 8bb3c62..8bd8a66 100644 --- a/hw/spapr_pci.h +++ b/hw/spapr_pci.h @@ -39,7 +39,6 @@ typedef struct sPAPRPHBState { int32_t index; uint64_t buid; - char *busname; char *dtbusname; MemoryRegion memspace, iospace; @@ -82,8 +81,7 @@ static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin) return xics_get_qirq(spapr->icp, phb->lsi_table[pin].irq); } -PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index, - const char *busname); +PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index); int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, -- cgit v1.1 From 7b5651605836fd29572fd4c8769af5378d351712 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 13 Mar 2013 15:53:28 +0000 Subject: pseries: Move XICS initialization before cpu initialization Currently, the pseries machine initializes the cpus, then the XICS interrupt controller. However, to support the upcoming in-kernel XICS implementation we will need to initialize the irq controller before the vcpus. This patch makes the necesssary rearrangement. This means the xics init code can no longer auto-detect the number of cpus ("interrupt servers" in XICS terminology) and so we must pass that in explicitly from the platform code. Signed-off-by: Michael Ellerman Signed-off-by: Ben Herrenschmidt Signed-off-by: David Gibson Signed-off-by: Alexander Graf --- hw/ppc/spapr.c | 12 +++++++----- hw/ppc/xics.c | 57 +++++++++++++++++++++++++-------------------------------- hw/xics.h | 3 ++- 3 files changed, 34 insertions(+), 38 deletions(-) (limited to 'hw') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 74ae83b..7b2a11f 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -779,6 +779,11 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) spapr->htab_shift++; } + /* Set up Interrupt Controller before we create the VCPUs */ + spapr->icp = xics_system_init(smp_cpus * kvmppc_smt_threads() / smp_threads, + XICS_IRQS); + spapr->next_irq = XICS_IRQ_BASE; + /* init CPUs */ if (cpu_model == NULL) { cpu_model = kvm_enabled() ? "host" : "POWER7"; @@ -791,6 +796,8 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) } env = &cpu->env; + xics_cpu_setup(spapr->icp, cpu); + /* Set time-base frequency to 512 MHz */ cpu_ppc_tb_init(env, TIMEBASE_FREQ); @@ -830,11 +837,6 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) } g_free(filename); - - /* Set up Interrupt Controller */ - spapr->icp = xics_system_init(XICS_IRQS); - spapr->next_irq = XICS_IRQ_BASE; - /* Set up EPOW events infrastructure */ spapr_events_init(spapr); diff --git a/hw/ppc/xics.c b/hw/ppc/xics.c index c3ef12f..374da5b 100644 --- a/hw/ppc/xics.c +++ b/hw/ppc/xics.c @@ -521,45 +521,38 @@ static void xics_reset(void *opaque) } } -struct icp_state *xics_system_init(int nr_irqs) +void xics_cpu_setup(struct icp_state *icp, PowerPCCPU *cpu) { - CPUPPCState *env; - CPUState *cpu; - int max_server_num; - struct icp_state *icp; - struct ics_state *ics; + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + struct icp_server_state *ss = &icp->ss[cs->cpu_index]; - max_server_num = -1; - for (env = first_cpu; env != NULL; env = env->next_cpu) { - cpu = CPU(ppc_env_get_cpu(env)); - if (cpu->cpu_index > max_server_num) { - max_server_num = cpu->cpu_index; - } - } + assert(cs->cpu_index < icp->nr_servers); - icp = g_malloc0(sizeof(*icp)); - icp->nr_servers = max_server_num + 1; - icp->ss = g_malloc0(icp->nr_servers*sizeof(struct icp_server_state)); + switch (PPC_INPUT(env)) { + case PPC_FLAGS_INPUT_POWER7: + ss->output = env->irq_inputs[POWER7_INPUT_INT]; + break; - for (env = first_cpu; env != NULL; env = env->next_cpu) { - cpu = CPU(ppc_env_get_cpu(env)); - struct icp_server_state *ss = &icp->ss[cpu->cpu_index]; + case PPC_FLAGS_INPUT_970: + ss->output = env->irq_inputs[PPC970_INPUT_INT]; + break; - switch (PPC_INPUT(env)) { - case PPC_FLAGS_INPUT_POWER7: - ss->output = env->irq_inputs[POWER7_INPUT_INT]; - break; + default: + fprintf(stderr, "XICS interrupt controller does not support this CPU " + "bus model\n"); + abort(); + } +} - case PPC_FLAGS_INPUT_970: - ss->output = env->irq_inputs[PPC970_INPUT_INT]; - break; +struct icp_state *xics_system_init(int nr_servers, int nr_irqs) +{ + struct icp_state *icp; + struct ics_state *ics; - default: - hw_error("XICS interrupt model does not support this CPU bus " - "model\n"); - exit(1); - } - } + icp = g_malloc0(sizeof(*icp)); + icp->nr_servers = nr_servers; + icp->ss = g_malloc0(icp->nr_servers*sizeof(struct icp_server_state)); ics = g_malloc0(sizeof(*ics)); ics->nr_irqs = nr_irqs; diff --git a/hw/xics.h b/hw/xics.h index c3bf008..6bce042 100644 --- a/hw/xics.h +++ b/hw/xics.h @@ -35,6 +35,7 @@ struct icp_state; qemu_irq xics_get_qirq(struct icp_state *icp, int irq); void xics_set_irq_type(struct icp_state *icp, int irq, bool lsi); -struct icp_state *xics_system_init(int nr_irqs); +struct icp_state *xics_system_init(int nr_servers, int nr_irqs); +void xics_cpu_setup(struct icp_state *icp, PowerPCCPU *cpu); #endif /* __XICS_H__ */ -- cgit v1.1 From d5aea6f367d25b630a952a5a0c8289add774a8e8 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 12 Mar 2013 00:31:18 +0000 Subject: mmu-hash*: Add header file for definitions Currently cpu.h contains a number of definitions relating to the 64-bit hash MMU. Some are used in the MMU emulation code, but some are only used in the spapr MMU management hcall implementations. This patch moves these definitions (except for a few that are needed more widely) into mmu-hash64.h header, shared between the MMU emulation code and the spapr hcall code. The MMU emulation code is also updated to actually use a number of those definitions in place of hard coded constants. Similarly, we add new analogous definitions to mmu-hash32.h and use those in place of many hard-coded constants in mmu-hash32.c Signed-off-by: David Gibson [agraf: fix 32-bit hosts] Signed-off-by: Alexander Graf --- hw/ppc/spapr_hcall.c | 70 ++++++++++++++-------------------------------------- 1 file changed, 19 insertions(+), 51 deletions(-) (limited to 'hw') diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index dd72743..7be743c 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -3,39 +3,7 @@ #include "sysemu/sysemu.h" #include "helper_regs.h" #include "hw/spapr.h" - -#define HPTES_PER_GROUP 8 - -#define HPTE_V_SSIZE_SHIFT 62 -#define HPTE_V_AVPN_SHIFT 7 -#define HPTE_V_AVPN 0x3fffffffffffff80ULL -#define HPTE_V_AVPN_VAL(x) (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT) -#define HPTE_V_COMPARE(x, y) (!(((x) ^ (y)) & 0xffffffffffffff80UL)) -#define HPTE_V_BOLTED 0x0000000000000010ULL -#define HPTE_V_LOCK 0x0000000000000008ULL -#define HPTE_V_LARGE 0x0000000000000004ULL -#define HPTE_V_SECONDARY 0x0000000000000002ULL -#define HPTE_V_VALID 0x0000000000000001ULL - -#define HPTE_R_PP0 0x8000000000000000ULL -#define HPTE_R_TS 0x4000000000000000ULL -#define HPTE_R_KEY_HI 0x3000000000000000ULL -#define HPTE_R_RPN_SHIFT 12 -#define HPTE_R_RPN 0x3ffffffffffff000ULL -#define HPTE_R_FLAGS 0x00000000000003ffULL -#define HPTE_R_PP 0x0000000000000003ULL -#define HPTE_R_N 0x0000000000000004ULL -#define HPTE_R_G 0x0000000000000008ULL -#define HPTE_R_M 0x0000000000000010ULL -#define HPTE_R_I 0x0000000000000020ULL -#define HPTE_R_W 0x0000000000000040ULL -#define HPTE_R_WIMG 0x0000000000000078ULL -#define HPTE_R_C 0x0000000000000080ULL -#define HPTE_R_R 0x0000000000000100ULL -#define HPTE_R_KEY_LO 0x0000000000000e00ULL - -#define HPTE_V_1TB_SEG 0x4000000000000000ULL -#define HPTE_V_VRMA_MASK 0x4001ffffff000000ULL +#include "mmu-hash64.h" static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r, target_ulong pte_index) @@ -44,17 +12,17 @@ static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r, rb = (v & ~0x7fULL) << 16; /* AVA field */ va_low = pte_index >> 3; - if (v & HPTE_V_SECONDARY) { + if (v & HPTE64_V_SECONDARY) { va_low = ~va_low; } /* xor vsid from AVA */ - if (!(v & HPTE_V_1TB_SEG)) { + if (!(v & HPTE64_V_1TB_SEG)) { va_low ^= v >> 12; } else { va_low ^= v >> 24; } va_low &= 0x7ff; - if (v & HPTE_V_LARGE) { + if (v & HPTE64_V_LARGE) { rb |= 1; /* L field */ #if 0 /* Disable that P7 specific bit for now */ if (r & 0xff000) { @@ -87,7 +55,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, uint8_t *hpte; /* only handle 4k and 16M pages for now */ - if (pteh & HPTE_V_LARGE) { + if (pteh & HPTE64_V_LARGE) { #if 0 /* We don't support 64k pages yet */ if ((ptel & 0xf000) == 0x1000) { /* 64k page */ @@ -105,11 +73,11 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, } } - raddr = (ptel & HPTE_R_RPN) & ~((1ULL << page_shift) - 1); + raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << page_shift) - 1); if (raddr < spapr->ram_limit) { /* Regular RAM - should have WIMG=0010 */ - if ((ptel & HPTE_R_WIMG) != HPTE_R_M) { + if ((ptel & HPTE64_R_WIMG) != HPTE64_R_M) { return H_PARAMETER; } } else { @@ -117,7 +85,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, /* FIXME: What WIMG combinations could be sensible for IO? * For now we allow WIMG=010x, but are there others? */ /* FIXME: Should we check against registered IO addresses? */ - if ((ptel & (HPTE_R_W | HPTE_R_I | HPTE_R_M)) != HPTE_R_I) { + if ((ptel & (HPTE64_R_W | HPTE64_R_I | HPTE64_R_M)) != HPTE64_R_I) { return H_PARAMETER; } } @@ -134,7 +102,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, if (i == 8) { return H_PTEG_FULL; } - if ((ldq_p(hpte) & HPTE_V_VALID) == 0) { + if ((ldq_p(hpte) & HPTE64_V_VALID) == 0) { break; } hpte += HASH_PTE_SIZE_64; @@ -142,7 +110,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, } else { i = 0; hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64); - if (ldq_p(hpte) & HPTE_V_VALID) { + if (ldq_p(hpte) & HPTE64_V_VALID) { return H_PTEG_FULL; } } @@ -178,7 +146,7 @@ static target_ulong remove_hpte(CPUPPCState *env, target_ulong ptex, v = ldq_p(hpte); r = ldq_p(hpte + (HASH_PTE_SIZE_64/2)); - if ((v & HPTE_V_VALID) == 0 || + if ((v & HPTE64_V_VALID) == 0 || ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) || ((flags & H_ANDCOND) && (v & avpn) != 0)) { return REMOVE_NOT_FOUND; @@ -271,7 +239,7 @@ static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPREnvironment *spapr, switch (ret) { case REMOVE_SUCCESS: - *tsh |= (r & (HPTE_R_C | HPTE_R_R)) << 43; + *tsh |= (r & (HPTE64_R_C | HPTE64_R_R)) << 43; break; case REMOVE_PARM: @@ -304,18 +272,18 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr, v = ldq_p(hpte); r = ldq_p(hpte + (HASH_PTE_SIZE_64/2)); - if ((v & HPTE_V_VALID) == 0 || + if ((v & HPTE64_V_VALID) == 0 || ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) { return H_NOT_FOUND; } - r &= ~(HPTE_R_PP0 | HPTE_R_PP | HPTE_R_N | - HPTE_R_KEY_HI | HPTE_R_KEY_LO); - r |= (flags << 55) & HPTE_R_PP0; - r |= (flags << 48) & HPTE_R_KEY_HI; - r |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO); + r &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N | + HPTE64_R_KEY_HI | HPTE64_R_KEY_LO); + r |= (flags << 55) & HPTE64_R_PP0; + r |= (flags << 48) & HPTE64_R_KEY_HI; + r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO); rb = compute_tlbie_rb(v, r, pte_index); - stq_p(hpte, v & ~HPTE_V_VALID); + stq_p(hpte, v & ~HPTE64_V_VALID); ppc_tlb_invalidate_one(env, rb); stq_p(hpte + (HASH_PTE_SIZE_64/2), r); /* Don't need a memory barrier, due to qemu's global lock */ -- cgit v1.1 From dffdaf6162d20b992e34c4708969ed4de0353417 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 12 Mar 2013 00:31:19 +0000 Subject: mmu-hash*: Add hash pte load/store helpers On real hardware the ppc hash page table is stored in memory; accordingly our mmu emulation code can read a hash page table in guest memory. But, when paravirtualized under PAPR, the real hash page table is in host memory, accessible to the guest only via hypercalls. We model this by also allowing the MMU emulation code to access a specially allocated hash page table outside the guest's memory image. At present these two options are implemented with some ugly conditionals at each access point in the mmu emulation code. In the implementation of the PAPR hypercalls, we assume the external hash table. This patch cleans things up by adding helpers to load and store from the hash table for both 32-bit and 64-bit hash mmus. The 64-bit versions handle both the in-guest-memory and outside guest memory cases. The 32-bit versions only handle the in-guest-memory case since no 32-bit systems can have an external hash table at present. Signed-off-by: David Gibson Signed-off-by: Alexander Graf --- hw/ppc/spapr_hcall.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'hw') diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 7be743c..22cfb7e 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -52,7 +52,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, target_ulong page_shift = 12; target_ulong raddr; target_ulong i; - uint8_t *hpte; + hwaddr hpte; /* only handle 4k and 16M pages for now */ if (pteh & HPTE64_V_LARGE) { @@ -97,26 +97,26 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, } if (likely((flags & H_EXACT) == 0)) { pte_index &= ~7ULL; - hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64); + hpte = pte_index * HASH_PTE_SIZE_64; for (i = 0; ; ++i) { if (i == 8) { return H_PTEG_FULL; } - if ((ldq_p(hpte) & HPTE64_V_VALID) == 0) { + if ((ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) == 0) { break; } hpte += HASH_PTE_SIZE_64; } } else { i = 0; - hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64); - if (ldq_p(hpte) & HPTE64_V_VALID) { + hpte = pte_index * HASH_PTE_SIZE_64; + if (ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) { return H_PTEG_FULL; } } - stq_p(hpte + (HASH_PTE_SIZE_64/2), ptel); + ppc_hash64_store_hpte1(env, hpte, ptel); /* eieio(); FIXME: need some sort of barrier for smp? */ - stq_p(hpte, pteh); + ppc_hash64_store_hpte0(env, hpte, pteh); args[0] = pte_index + i; return H_SUCCESS; @@ -134,17 +134,17 @@ static target_ulong remove_hpte(CPUPPCState *env, target_ulong ptex, target_ulong flags, target_ulong *vp, target_ulong *rp) { - uint8_t *hpte; + hwaddr hpte; target_ulong v, r, rb; if ((ptex * HASH_PTE_SIZE_64) & ~env->htab_mask) { return REMOVE_PARM; } - hpte = env->external_htab + (ptex * HASH_PTE_SIZE_64); + hpte = ptex * HASH_PTE_SIZE_64; - v = ldq_p(hpte); - r = ldq_p(hpte + (HASH_PTE_SIZE_64/2)); + v = ppc_hash64_load_hpte0(env, hpte); + r = ppc_hash64_load_hpte1(env, hpte); if ((v & HPTE64_V_VALID) == 0 || ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) || @@ -153,7 +153,7 @@ static target_ulong remove_hpte(CPUPPCState *env, target_ulong ptex, } *vp = v; *rp = r; - stq_p(hpte, 0); + ppc_hash64_store_hpte0(env, hpte, 0); rb = compute_tlbie_rb(v, r, ptex); ppc_tlb_invalidate_one(env, rb); return REMOVE_SUCCESS; @@ -260,17 +260,17 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr, target_ulong flags = args[0]; target_ulong pte_index = args[1]; target_ulong avpn = args[2]; - uint8_t *hpte; + hwaddr hpte; target_ulong v, r, rb; if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) { return H_PARAMETER; } - hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64); + hpte = pte_index * HASH_PTE_SIZE_64; - v = ldq_p(hpte); - r = ldq_p(hpte + (HASH_PTE_SIZE_64/2)); + v = ppc_hash64_load_hpte0(env, hpte); + r = ppc_hash64_load_hpte1(env, hpte); if ((v & HPTE64_V_VALID) == 0 || ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) { @@ -283,11 +283,11 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr, r |= (flags << 48) & HPTE64_R_KEY_HI; r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO); rb = compute_tlbie_rb(v, r, pte_index); - stq_p(hpte, v & ~HPTE64_V_VALID); + ppc_hash64_store_hpte0(env, hpte, v & ~HPTE64_V_VALID); ppc_tlb_invalidate_one(env, rb); - stq_p(hpte + (HASH_PTE_SIZE_64/2), r); + ppc_hash64_store_hpte1(env, hpte, r); /* Don't need a memory barrier, due to qemu's global lock */ - stq_p(hpte, v); + ppc_hash64_store_hpte0(env, hpte, v); return H_SUCCESS; } -- cgit v1.1