aboutsummaryrefslogtreecommitdiff
path: root/target/ppc
diff options
context:
space:
mode:
authorSuraj Jitindar Singh <sjitindarsingh@gmail.com>2019-03-01 13:43:15 +1100
committerDavid Gibson <david@gibson.dropbear.id.au>2019-03-12 12:07:49 +1100
commita8dafa525181e57405b7ef4bf7c212bf5f6d8ca1 (patch)
tree53fcc83a2b381812d4838a57a9fda15322f80bb4 /target/ppc
parentc982f5cf9ab9e60a8255f9cc72362c932c252471 (diff)
downloadqemu-a8dafa525181e57405b7ef4bf7c212bf5f6d8ca1.zip
qemu-a8dafa525181e57405b7ef4bf7c212bf5f6d8ca1.tar.gz
qemu-a8dafa525181e57405b7ef4bf7c212bf5f6d8ca1.tar.bz2
target/ppc: Implement large decrementer support for TCG
Prior to POWER9 the decrementer was a 32-bit register which decremented with each tick of the timebase. From POWER9 onwards the decrementer can be set to operate in a mode called large decrementer where it acts as a n-bit decrementing register which is visible as a 64-bit register, that is the value of the decrementer is sign extended to 64 bits (where n is implementation dependant). The mode in which the decrementer operates is controlled by the LPCR_LD bit in the logical paritition control register (LPCR). >From POWER9 onwards the HDEC (hypervisor decrementer) was enlarged to h-bits, also sign extended to 64 bits (where h is implementation dependant). Note this isn't configurable and is always enabled. On POWER9 the large decrementer and hdec are both 56 bits, as represented by the lrg_decr_bits cpu class property. Since they are the same size we only add one property for now, which could be extended in the case they ever differ in the future. We also add the lrg_decr_bits property for POWER5+/7/8 since it is used to determine the size of the hdec, which is only generated on the POWER5+ processor and later. On these processors it is 32 bits. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20190301024317.22137-2-sjitindarsingh@gmail.com> [dwg: Small style fixes] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target/ppc')
-rw-r--r--target/ppc/cpu-qom.h1
-rw-r--r--target/ppc/cpu.h8
-rw-r--r--target/ppc/mmu-hash64.c2
-rw-r--r--target/ppc/translate.c2
-rw-r--r--target/ppc/translate_init.inc.c4
5 files changed, 11 insertions, 6 deletions
diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
index ae51fe7..be9b4c3 100644
--- a/target/ppc/cpu-qom.h
+++ b/target/ppc/cpu-qom.h
@@ -190,6 +190,7 @@ typedef struct PowerPCCPUClass {
#endif
const PPCHash64Options *hash64_opts;
struct ppc_radix_page_info *radix_page_info;
+ uint32_t lrg_decr_bits;
void (*init_proc)(CPUPPCState *env);
int (*check_pow)(CPUPPCState *env);
int (*handle_mmu_fault)(PowerPCCPU *cpu, vaddr eaddr, int rwx, int mmu_idx);
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 26604dd..21e418d 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1321,10 +1321,10 @@ uint32_t cpu_ppc_load_atbu (CPUPPCState *env);
void cpu_ppc_store_atbl (CPUPPCState *env, uint32_t value);
void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value);
bool ppc_decr_clear_on_delivery(CPUPPCState *env);
-uint32_t cpu_ppc_load_decr (CPUPPCState *env);
-void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
-uint32_t cpu_ppc_load_hdecr (CPUPPCState *env);
-void cpu_ppc_store_hdecr (CPUPPCState *env, uint32_t value);
+target_ulong cpu_ppc_load_decr(CPUPPCState *env);
+void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value);
+target_ulong cpu_ppc_load_hdecr(CPUPPCState *env);
+void cpu_ppc_store_hdecr(CPUPPCState *env, target_ulong value);
uint64_t cpu_ppc_load_purr (CPUPPCState *env);
uint32_t cpu_ppc601_load_rtcl (CPUPPCState *env);
uint32_t cpu_ppc601_load_rtcu (CPUPPCState *env);
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index c431303..a2b1ec5 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -1109,7 +1109,7 @@ void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val)
case POWERPC_MMU_3_00: /* P9 */
lpcr = val & (LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
(LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
- LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR |
+ LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
(LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
LPCR_DEE | LPCR_OEE)) | LPCR_MER | LPCR_GTSE | LPCR_TC |
LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE);
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 819221f..b156be4 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7417,7 +7417,7 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
#if !defined(NO_TIMER_DUMP)
cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
#if !defined(CONFIG_USER_ONLY)
- " DECR %08" PRIu32
+ " DECR " TARGET_FMT_lu
#endif
"\n",
cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 58542c0..af70a3b 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -8376,6 +8376,7 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
#if defined(CONFIG_SOFTMMU)
pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
pcc->hash64_opts = &ppc_hash64_opts_basic;
+ pcc->lrg_decr_bits = 32;
#endif
pcc->excp_model = POWERPC_EXCP_970;
pcc->bus_model = PPC_FLAGS_INPUT_970;
@@ -8550,6 +8551,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
#if defined(CONFIG_SOFTMMU)
pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
pcc->hash64_opts = &ppc_hash64_opts_POWER7;
+ pcc->lrg_decr_bits = 32;
#endif
pcc->excp_model = POWERPC_EXCP_POWER7;
pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
@@ -8718,6 +8720,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
#if defined(CONFIG_SOFTMMU)
pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
pcc->hash64_opts = &ppc_hash64_opts_POWER7;
+ pcc->lrg_decr_bits = 32;
#endif
pcc->excp_model = POWERPC_EXCP_POWER8;
pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
@@ -8926,6 +8929,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
/* segment page size remain the same */
pcc->hash64_opts = &ppc_hash64_opts_POWER7;
pcc->radix_page_info = &POWER9_radix_page_info;
+ pcc->lrg_decr_bits = 56;
#endif
pcc->excp_model = POWERPC_EXCP_POWER9;
pcc->bus_model = PPC_FLAGS_INPUT_POWER9;