diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-04-27 21:34:46 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-04-27 21:34:46 +0100 |
commit | 9ec34ecc97bcd5df04b0f67a774d79ffcd6b0a11 (patch) | |
tree | 6cf993ec0d442d43c116a42e69e3382a9f797b5a /target/ppc/mmu-hash32.c | |
parent | db7f1c3fafa8e1d23ecb212454f9d83ac59e411b (diff) | |
parent | aaef873b130f4f9c78f8e97b69c235c81b8b8b88 (diff) |
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.1-20190426' into staging
ppc patch queue 2019-04-26
Here's the first ppc target pull request for qemu-4.1. This has a
number of things that have accumulated while qemu-4.0 was frozen.
* A number of emulated MMU improvements from Ben Herrenschmidt
* Assorted cleanups fro Greg Kurz
* A large set of mostly mechanical cleanups from me to make target/ppc
much closer to compliant with the modern coding style
* Support for passthrough of NVIDIA GPUs using NVLink2
As well as some other assorted fixes.
# gpg: Signature made Fri 26 Apr 2019 07:02:19 BST
# gpg: using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full]
# gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full]
# gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full]
# gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown]
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392
* remotes/dgibson/tags/ppc-for-4.1-20190426: (36 commits)
target/ppc: improve performance of large BAT invalidations
ppc/hash32: Rework R and C bit updates
ppc/hash64: Rework R and C bit updates
ppc/spapr: Use proper HPTE accessors for H_READ
target/ppc: Don't check UPRT in radix mode when in HV real mode
target/ppc/kvm: Convert DPRINTF to traces
target/ppc/trace-events: Fix trivial typo
spapr: Drop duplicate PCI swizzle code
spapr_pci: Get rid of duplicate code for node name creation
target/ppc: Style fixes for translate/spe-impl.inc.c
target/ppc: Style fixes for translate/vmx-impl.inc.c
target/ppc: Style fixes for translate/vsx-impl.inc.c
target/ppc: Style fixes for translate/fp-impl.inc.c
target/ppc: Style fixes for translate.c
target/ppc: Style fixes for translate_init.inc.c
target/ppc: Style fixes for monitor.c
target/ppc: Style fixes for mmu_helper.c
target/ppc: Style fixes for mmu-hash64.[ch]
target/ppc: Style fixes for mmu-hash32.[ch]
target/ppc: Style fixes for misc_helper.c
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/ppc/mmu-hash32.c')
-rw-r--r-- | target/ppc/mmu-hash32.c | 59 |
1 files changed, 41 insertions, 18 deletions
diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c index e8562a7c87..55cf156a0b 100644 --- a/target/ppc/mmu-hash32.c +++ b/target/ppc/mmu-hash32.c @@ -27,7 +27,7 @@ #include "mmu-hash32.h" #include "exec/log.h" -//#define DEBUG_BAT +/* #define DEBUG_BAT */ #ifdef DEBUG_BATS # define LOG_BATS(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__) @@ -228,8 +228,10 @@ static int ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr, qemu_log_mask(CPU_LOG_MMU, "direct store...\n"); if ((sr & 0x1FF00000) >> 20 == 0x07f) { - /* Memory-forced I/O controller interface access */ - /* If T=1 and BUID=x'07F', the 601 performs a memory access + /* + * Memory-forced I/O controller interface access + * + * If T=1 and BUID=x'07F', the 601 performs a memory access * to SR[28-31] LA[4-31], bypassing all protection mechanisms. */ *raddr = ((sr & 0xF) << 28) | (eaddr & 0x0FFFFFFF); @@ -265,9 +267,11 @@ static int ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr, } return 1; case ACCESS_CACHE: - /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */ - /* Should make the instruction do no-op. - * As it already do no-op, it's quite easy :-) + /* + * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi + * + * Should make the instruction do no-op. As it already do + * no-op, it's quite easy :-) */ *raddr = eaddr; return 0; @@ -341,6 +345,24 @@ static hwaddr ppc_hash32_pteg_search(PowerPCCPU *cpu, hwaddr pteg_off, return -1; } +static void ppc_hash32_set_r(PowerPCCPU *cpu, hwaddr pte_offset, uint32_t pte1) +{ + target_ulong base = ppc_hash32_hpt_base(cpu); + hwaddr offset = pte_offset + 6; + + /* The HW performs a non-atomic byte update */ + stb_phys(CPU(cpu)->as, base + offset, ((pte1 >> 8) & 0xff) | 0x01); +} + +static void ppc_hash32_set_c(PowerPCCPU *cpu, hwaddr pte_offset, uint64_t pte1) +{ + target_ulong base = ppc_hash32_hpt_base(cpu); + hwaddr offset = pte_offset + 7; + + /* The HW performs a non-atomic byte update */ + stb_phys(CPU(cpu)->as, base + offset, (pte1 & 0xff) | 0x80); +} + static hwaddr ppc_hash32_htab_lookup(PowerPCCPU *cpu, target_ulong sr, target_ulong eaddr, ppc_hash_pte32_t *pte) @@ -399,7 +421,6 @@ int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx, hwaddr pte_offset; ppc_hash_pte32_t pte; int prot; - uint32_t new_pte1; const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC}; hwaddr raddr; @@ -515,18 +536,20 @@ int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx, /* 8. Update PTE referenced and changed bits if necessary */ - new_pte1 = pte.pte1 | HPTE32_R_R; /* set referenced bit */ - if (rwx == 1) { - new_pte1 |= HPTE32_R_C; /* set changed (dirty) bit */ - } else { - /* Treat the page as read-only for now, so that a later write - * will pass through this function again to set the C bit */ - prot &= ~PAGE_WRITE; - } - - if (new_pte1 != pte.pte1) { - ppc_hash32_store_hpte1(cpu, pte_offset, new_pte1); + if (!(pte.pte1 & HPTE32_R_R)) { + ppc_hash32_set_r(cpu, pte_offset, pte.pte1); } + if (!(pte.pte1 & HPTE32_R_C)) { + if (rwx == 1) { + ppc_hash32_set_c(cpu, pte_offset, pte.pte1); + } else { + /* + * Treat the page as read-only for now, so that a later write + * will pass through this function again to set the C bit + */ + prot &= ~PAGE_WRITE; + } + } /* 9. Determine the real address from the PTE */ |