* [Qemu-devel] [PATCH v2 1/4] kvm: update linux-headers
2011-08-18 20:38 [Qemu-devel] [PATCH v2 0/4] ppc: booke206: KVM MMU API and info tlb Scott Wood
@ 2011-08-18 20:38 ` Scott Wood
2011-08-18 20:38 ` [Qemu-devel] [PATCH v2 2/4] kvm: ppc: booke206: use MMU API Scott Wood
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Scott Wood @ 2011-08-18 20:38 UTC (permalink / raw)
To: agraf; +Cc: qemu-devel
Needed for PPC MMU API support.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
v2: new to v2
| 54 ++++++++++++++++++++++++++++++++++++-
| 14 ++++++++++
| 41 +++++++++++++++++++++++-----
| 1 +
4 files changed, 100 insertions(+), 10 deletions(-)
--git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
index 777d307..874f23d 100644
--- a/linux-headers/asm-powerpc/kvm.h
+++ b/linux-headers/asm-powerpc/kvm.h
@@ -22,6 +22,10 @@
#include <linux/types.h>
+/* Select powerpc specific features in <linux/kvm.h> */
+#define __KVM_HAVE_SPAPR_TCE
+#define __KVM_HAVE_PPC_SMT
+
struct kvm_regs {
__u64 pc;
__u64 cr;
@@ -166,8 +170,8 @@ struct kvm_sregs {
} ppc64;
struct {
__u32 sr[16];
- __u64 ibat[8];
- __u64 dbat[8];
+ __u64 ibat[8];
+ __u64 dbat[8];
} ppc32;
} s;
struct {
@@ -272,4 +276,50 @@ struct kvm_guest_debug_arch {
#define KVM_INTERRUPT_UNSET -2U
#define KVM_INTERRUPT_SET_LEVEL -3U
+/* for KVM_CAP_SPAPR_TCE */
+struct kvm_create_spapr_tce {
+ __u64 liobn;
+ __u32 window_size;
+};
+
+/* for KVM_ALLOCATE_RMA */
+struct kvm_allocate_rma {
+ __u64 rma_size;
+};
+
+struct kvm_book3e_206_tlb_entry {
+ __u32 mas8;
+ __u32 mas1;
+ __u64 mas2;
+ __u64 mas7_3;
+};
+
+struct kvm_book3e_206_tlb_params {
+ /*
+ * For mmu types KVM_MMU_FSL_BOOKE_NOHV and KVM_MMU_FSL_BOOKE_HV:
+ *
+ * - The number of ways of TLB0 must be a power of two between 2 and
+ * 16.
+ * - TLB1 must be fully associative.
+ * - The size of TLB0 must be a multiple of the number of ways, and
+ * the number of sets must be a power of two.
+ * - The size of TLB1 may not exceed 64 entries.
+ * - TLB0 supports 4 KiB pages.
+ * - The page sizes supported by TLB1 are as indicated by
+ * TLB1CFG (if MMUCFG[MAVN] = 0) or TLB1PS (if MMUCFG[MAVN] = 1)
+ * as returned by KVM_GET_SREGS.
+ * - TLB2 and TLB3 are reserved, and their entries in tlb_sizes[]
+ * and tlb_ways[] must be zero.
+ *
+ * tlb_ways[n] = tlb_sizes[n] means the array is fully associative.
+ *
+ * KVM will adjust TLBnCFG based on the sizes configured here,
+ * though arrays greater than 2048 entries will have TLBnCFG[NENTRY]
+ * set to zero.
+ */
+ __u32 tlb_sizes[4];
+ __u32 tlb_ways[4];
+ __u32 reserved[8];
+};
+
#endif /* __LINUX_KVM_POWERPC_H */
--git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h
index 834d71e..f2ac46a 100644
--- a/linux-headers/asm-x86/kvm_para.h
+++ b/linux-headers/asm-x86/kvm_para.h
@@ -21,6 +21,7 @@
*/
#define KVM_FEATURE_CLOCKSOURCE2 3
#define KVM_FEATURE_ASYNC_PF 4
+#define KVM_FEATURE_STEAL_TIME 5
/* The last 8 bits are used to indicate how to interpret the flags field
* in pvclock structure. If no bits are set, all flags are ignored.
@@ -30,10 +31,23 @@
#define MSR_KVM_WALL_CLOCK 0x11
#define MSR_KVM_SYSTEM_TIME 0x12
+#define KVM_MSR_ENABLED 1
/* Custom MSRs falls in the range 0x4b564d00-0x4b564dff */
#define MSR_KVM_WALL_CLOCK_NEW 0x4b564d00
#define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01
#define MSR_KVM_ASYNC_PF_EN 0x4b564d02
+#define MSR_KVM_STEAL_TIME 0x4b564d03
+
+struct kvm_steal_time {
+ __u64 steal;
+ __u32 version;
+ __u32 flags;
+ __u32 pad[12];
+};
+
+#define KVM_STEAL_ALIGNMENT_BITS 5
+#define KVM_STEAL_VALID_BITS ((-1ULL << (KVM_STEAL_ALIGNMENT_BITS + 1)))
+#define KVM_STEAL_RESERVED_MASK (((1 << KVM_STEAL_ALIGNMENT_BITS) - 1 ) << 1)
#define KVM_MAX_MMU_OP_BATCH 32
--git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index fc63b73..7d8a7f6 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -161,6 +161,7 @@ struct kvm_pit_config {
#define KVM_EXIT_NMI 16
#define KVM_EXIT_INTERNAL_ERROR 17
#define KVM_EXIT_OSI 18
+#define KVM_EXIT_PAPR_HCALL 19
/* For KVM_EXIT_INTERNAL_ERROR */
#define KVM_INTERNAL_ERROR_EMULATION 1
@@ -264,6 +265,11 @@ struct kvm_run {
struct {
__u64 gprs[32];
} osi;
+ struct {
+ __u64 nr;
+ __u64 ret;
+ __u64 args[9];
+ } papr_hcall;
/* Fix the size of the union. */
char padding[256];
};
@@ -457,7 +463,7 @@ struct kvm_ppc_pvinfo {
#define KVM_CAP_VAPIC 6
#define KVM_CAP_EXT_CPUID 7
#define KVM_CAP_CLOCKSOURCE 8
-#define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */
+#define KVM_CAP_NR_VCPUS 9 /* returns recommended max vcpus per vm */
#define KVM_CAP_NR_MEMSLOTS 10 /* returns max memory slots per vm */
#define KVM_CAP_PIT 11
#define KVM_CAP_NOP_IO_DELAY 12
@@ -544,6 +550,11 @@ struct kvm_ppc_pvinfo {
#define KVM_CAP_TSC_CONTROL 60
#define KVM_CAP_GET_TSC_KHZ 61
#define KVM_CAP_PPC_BOOKE_SREGS 62
+#define KVM_CAP_SPAPR_TCE 63
+#define KVM_CAP_PPC_SMT 64
+#define KVM_CAP_PPC_RMA 65
+#define KVM_CAP_MAX_VCPUS 66 /* returns max vcpus per vm */
+#define KVM_CAP_SW_TLB 67
#ifdef KVM_CAP_IRQ_ROUTING
@@ -623,6 +634,21 @@ struct kvm_clock_data {
__u32 pad[9];
};
+#define KVM_MMU_FSL_BOOKE_NOHV 0
+#define KVM_MMU_FSL_BOOKE_HV 1
+
+struct kvm_config_tlb {
+ __u64 params;
+ __u64 array;
+ __u32 mmu_type;
+ __u32 array_len;
+};
+
+struct kvm_dirty_tlb {
+ __u64 bitmap;
+ __u32 num_dirty;
+};
+
/*
* ioctls for VM fds
*/
@@ -746,6 +772,11 @@ struct kvm_clock_data {
/* Available with KVM_CAP_XCRS */
#define KVM_GET_XCRS _IOR(KVMIO, 0xa6, struct kvm_xcrs)
#define KVM_SET_XCRS _IOW(KVMIO, 0xa7, struct kvm_xcrs)
+#define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce)
+/* Available with KVM_CAP_RMA */
+#define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma)
+/* Available with KVM_CAP_SW_TLB */
+#define KVM_DIRTY_TLB _IOW(KVMIO, 0xaa, struct kvm_dirty_tlb)
#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
@@ -773,20 +804,14 @@ struct kvm_assigned_pci_dev {
struct kvm_assigned_irq {
__u32 assigned_dev_id;
- __u32 host_irq;
+ __u32 host_irq; /* ignored (legacy field) */
__u32 guest_irq;
__u32 flags;
union {
- struct {
- __u32 addr_lo;
- __u32 addr_hi;
- __u32 data;
- } guest_msi;
__u32 reserved[12];
};
};
-
struct kvm_assigned_msix_nr {
__u32 assigned_dev_id;
__u16 entry_nr;
--git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h
index 7bdcf93..b315e27 100644
--- a/linux-headers/linux/kvm_para.h
+++ b/linux-headers/linux/kvm_para.h
@@ -26,3 +26,4 @@
#include <asm/kvm_para.h>
#endif /* __LINUX_KVM_PARA_H */
+
--
1.7.6
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH v2 2/4] kvm: ppc: booke206: use MMU API
2011-08-18 20:38 [Qemu-devel] [PATCH v2 0/4] ppc: booke206: KVM MMU API and info tlb Scott Wood
2011-08-18 20:38 ` [Qemu-devel] [PATCH v2 1/4] kvm: update linux-headers Scott Wood
@ 2011-08-18 20:38 ` Scott Wood
2011-08-31 13:55 ` Alexander Graf
2011-08-18 20:38 ` [Qemu-devel] [PATCH v2 3/4] ppc: booke206: use MAV=2.0 TSIZE definition, fix 4G pages Scott Wood
2011-08-18 20:38 ` [Qemu-devel] [PATCH v2 4/4] ppc: booke206: add "info tlb" support Scott Wood
3 siblings, 1 reply; 6+ messages in thread
From: Scott Wood @ 2011-08-18 20:38 UTC (permalink / raw)
To: agraf; +Cc: qemu-devel
Share the TLB array with KVM. This allows us to set the initial TLB
both on initial boot and reset, is useful for debugging, and could
eventually be used to support migration.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
v2 (was 1/3 in v1):
updated for kernel API change, removed kernel header ifdefs,
minor changes as requested
hw/ppce500_mpc8544ds.c | 2 +
target-ppc/cpu.h | 2 +
target-ppc/kvm.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 91 insertions(+), 0 deletions(-)
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index b739ce2..3626e26 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -202,6 +202,8 @@ static void mmubooke_create_initial_mapping(CPUState *env,
tlb->mas2 = va & TARGET_PAGE_MASK;
tlb->mas7_3 = pa & TARGET_PAGE_MASK;
tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX;
+
+ env->tlb_dirty = true;
}
static void mpc8544ds_cpu_reset(void *opaque)
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 024eb6f..0e38d4f 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -919,6 +919,8 @@ struct CPUPPCState {
ppc_tlb_t tlb; /* TLB is optional. Allocate them only if needed */
/* 403 dedicated access protection registers */
target_ulong pb[4];
+ bool tlb_dirty; /* Set to non-zero when modifying TLB */
+ bool kvm_sw_tlb; /* non-zero if KVM SW TLB API is active */
#endif
/* Other registers */
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 21f35af7..1e1e5db 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -105,6 +105,54 @@ static int kvm_arch_sync_sregs(CPUState *cenv)
return kvm_vcpu_ioctl(cenv, KVM_SET_SREGS, &sregs);
}
+/* Set up a shared TLB array with KVM */
+static int kvm_booke206_tlb_init(CPUState *env)
+{
+ struct kvm_book3e_206_tlb_params params = {};
+ struct kvm_config_tlb cfg = {};
+ struct kvm_enable_cap encap = {};
+ size_t array_len;
+ unsigned int entries = 0;
+ int ret, i;
+
+ if (!kvm_enabled() ||
+ !kvm_check_extension(env->kvm_state, KVM_CAP_SW_TLB)) {
+ return 0;
+ }
+
+ assert(ARRAY_SIZE(params.tlb_sizes) == BOOKE206_MAX_TLBN);
+
+ for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
+ params.tlb_sizes[i] = booke206_tlb_size(env, i);
+ params.tlb_ways[i] = booke206_tlb_ways(env, i);
+ entries += params.tlb_sizes[i];
+ }
+
+ assert(entries == env->nb_tlb);
+ assert(sizeof(struct kvm_book3e_206_tlb_entry) == sizeof(ppcmas_tlb_t));
+
+ array_len = sizeof(ppcmas_tlb_t) * entries;
+ env->tlb_dirty = true;
+
+ cfg.array = (uintptr_t)env->tlb.tlbm;
+ cfg.array_len = sizeof(ppcmas_tlb_t) * entries;
+ cfg.params = (uintptr_t)¶ms;
+ cfg.mmu_type = KVM_MMU_FSL_BOOKE_NOHV;
+
+ encap.cap = KVM_CAP_SW_TLB;
+ encap.args[0] = (uintptr_t)&cfg;
+
+ ret = kvm_vcpu_ioctl(env, KVM_ENABLE_CAP, &encap);
+ if (ret < 0) {
+ fprintf(stderr, "%s: couldn't enable KVM_CAP_SW_TLB: %s\n",
+ __func__, strerror(-ret));
+ return ret;
+ }
+
+ env->kvm_sw_tlb = true;
+ return 0;
+}
+
int kvm_arch_init_vcpu(CPUState *cenv)
{
int ret;
@@ -116,6 +164,15 @@ int kvm_arch_init_vcpu(CPUState *cenv)
idle_timer = qemu_new_timer_ns(vm_clock, kvm_kick_env, cenv);
+ /* Some targets support access to KVM's guest TLB. */
+ switch (cenv->mmu_model) {
+ case POWERPC_MMU_BOOKE206:
+ ret = kvm_booke206_tlb_init(cenv);
+ break;
+ default:
+ break;
+ }
+
return ret;
}
@@ -123,6 +180,31 @@ void kvm_arch_reset_vcpu(CPUState *env)
{
}
+static void kvm_sw_tlb_put(CPUState *env)
+{
+ struct kvm_dirty_tlb dirty_tlb;
+ unsigned char *bitmap;
+ int ret;
+
+ if (!env->kvm_sw_tlb) {
+ return;
+ }
+
+ bitmap = qemu_malloc((env->nb_tlb + 7) / 8);
+ memset(bitmap, 0xFF, (env->nb_tlb + 7) / 8);
+
+ dirty_tlb.bitmap = (uintptr_t)bitmap;
+ dirty_tlb.num_dirty = env->nb_tlb;
+
+ ret = kvm_vcpu_ioctl(env, KVM_DIRTY_TLB, &dirty_tlb);
+ if (ret) {
+ fprintf(stderr, "%s: KVM_DIRTY_TLB: %s\n",
+ __func__, strerror(-ret));
+ }
+
+ qemu_free(bitmap);
+}
+
int kvm_arch_put_registers(CPUState *env, int level)
{
struct kvm_regs regs;
@@ -160,6 +242,11 @@ int kvm_arch_put_registers(CPUState *env, int level)
if (ret < 0)
return ret;
+ if (env->tlb_dirty) {
+ kvm_sw_tlb_put(env);
+ env->tlb_dirty = false;
+ }
+
return ret;
}
--
1.7.6
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH v2 2/4] kvm: ppc: booke206: use MMU API
2011-08-18 20:38 ` [Qemu-devel] [PATCH v2 2/4] kvm: ppc: booke206: use MMU API Scott Wood
@ 2011-08-31 13:55 ` Alexander Graf
0 siblings, 0 replies; 6+ messages in thread
From: Alexander Graf @ 2011-08-31 13:55 UTC (permalink / raw)
To: Scott Wood; +Cc: qemu-devel
On 18.08.2011, at 22:38, Scott Wood wrote:
> Share the TLB array with KVM. This allows us to set the initial TLB
> both on initial boot and reset, is useful for debugging, and could
> eventually be used to support migration.
>
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> v2 (was 1/3 in v1):
> updated for kernel API change, removed kernel header ifdefs,
> minor changes as requested
>
> hw/ppce500_mpc8544ds.c | 2 +
> target-ppc/cpu.h | 2 +
> target-ppc/kvm.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 91 insertions(+), 0 deletions(-)
>
> diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
> index b739ce2..3626e26 100644
> --- a/hw/ppce500_mpc8544ds.c
> +++ b/hw/ppce500_mpc8544ds.c
> @@ -202,6 +202,8 @@ static void mmubooke_create_initial_mapping(CPUState *env,
> tlb->mas2 = va & TARGET_PAGE_MASK;
> tlb->mas7_3 = pa & TARGET_PAGE_MASK;
> tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX;
> +
> + env->tlb_dirty = true;
> }
>
> static void mpc8544ds_cpu_reset(void *opaque)
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index 024eb6f..0e38d4f 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -919,6 +919,8 @@ struct CPUPPCState {
> ppc_tlb_t tlb; /* TLB is optional. Allocate them only if needed */
> /* 403 dedicated access protection registers */
> target_ulong pb[4];
> + bool tlb_dirty; /* Set to non-zero when modifying TLB */
> + bool kvm_sw_tlb; /* non-zero if KVM SW TLB API is active */
> #endif
>
> /* Other registers */
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index 21f35af7..1e1e5db 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -105,6 +105,54 @@ static int kvm_arch_sync_sregs(CPUState *cenv)
> return kvm_vcpu_ioctl(cenv, KVM_SET_SREGS, &sregs);
> }
>
> +/* Set up a shared TLB array with KVM */
> +static int kvm_booke206_tlb_init(CPUState *env)
> +{
> + struct kvm_book3e_206_tlb_params params = {};
> + struct kvm_config_tlb cfg = {};
> + struct kvm_enable_cap encap = {};
> + size_t array_len;
> + unsigned int entries = 0;
> + int ret, i;
> +
> + if (!kvm_enabled() ||
> + !kvm_check_extension(env->kvm_state, KVM_CAP_SW_TLB)) {
> + return 0;
> + }
> +
> + assert(ARRAY_SIZE(params.tlb_sizes) == BOOKE206_MAX_TLBN);
> +
> + for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
> + params.tlb_sizes[i] = booke206_tlb_size(env, i);
> + params.tlb_ways[i] = booke206_tlb_ways(env, i);
> + entries += params.tlb_sizes[i];
> + }
> +
> + assert(entries == env->nb_tlb);
> + assert(sizeof(struct kvm_book3e_206_tlb_entry) == sizeof(ppcmas_tlb_t));
> +
> + array_len = sizeof(ppcmas_tlb_t) * entries;
/dev/shm/qemu/target-ppc/kvm.c: In function 'kvm_booke206_tlb_init':
/dev/shm/qemu/target-ppc/kvm.c:121:12: warning: variable 'array_len' set but not used [-Wunused-but-set-variable]
Alex
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH v2 3/4] ppc: booke206: use MAV=2.0 TSIZE definition, fix 4G pages
2011-08-18 20:38 [Qemu-devel] [PATCH v2 0/4] ppc: booke206: KVM MMU API and info tlb Scott Wood
2011-08-18 20:38 ` [Qemu-devel] [PATCH v2 1/4] kvm: update linux-headers Scott Wood
2011-08-18 20:38 ` [Qemu-devel] [PATCH v2 2/4] kvm: ppc: booke206: use MMU API Scott Wood
@ 2011-08-18 20:38 ` Scott Wood
2011-08-18 20:38 ` [Qemu-devel] [PATCH v2 4/4] ppc: booke206: add "info tlb" support Scott Wood
3 siblings, 0 replies; 6+ messages in thread
From: Scott Wood @ 2011-08-18 20:38 UTC (permalink / raw)
To: agraf; +Cc: qemu-devel
This definition is backward compatible with MAV=1.0 as long as
the guest does not set reserved bits in MAS1/MAS4.
Also, fix the shift in booke206_tlb_to_page_size -- it's the base
that should be able to hold a 4G page size, not the shift count.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
v2 (was 2/3 in v1): no change
hw/ppce500_mpc8544ds.c | 2 +-
target-ppc/cpu.h | 4 ++--
target-ppc/helper.c | 5 +++--
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 3626e26..1aed612 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -187,7 +187,7 @@ out:
/* Create -kernel TLB entries for BookE, linearly spanning 256MB. */
static inline target_phys_addr_t booke206_page_size_to_tlb(uint64_t size)
{
- return (ffs(size >> 10) - 1) >> 1;
+ return ffs(size >> 10) - 1;
}
static void mmubooke_create_initial_mapping(CPUState *env,
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 0e38d4f..06d78ca 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -652,8 +652,8 @@ enum {
#define MAS0_ATSEL_TLB 0
#define MAS0_ATSEL_LRAT MAS0_ATSEL
-#define MAS1_TSIZE_SHIFT 8
-#define MAS1_TSIZE_MASK (0xf << MAS1_TSIZE_SHIFT)
+#define MAS1_TSIZE_SHIFT 7
+#define MAS1_TSIZE_MASK (0x1f << MAS1_TSIZE_SHIFT)
#define MAS1_TS_SHIFT 12
#define MAS1_TS (1 << MAS1_TS_SHIFT)
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 789e6aa..d9a3855 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -1293,7 +1293,7 @@ target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t *tlb)
{
uint32_t tlbncfg;
int tlbn = booke206_tlbm_to_tlbn(env, tlb);
- target_phys_addr_t tlbm_size;
+ int tlbm_size;
tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn];
@@ -1301,9 +1301,10 @@ target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t *tlb)
tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
} else {
tlbm_size = (tlbncfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
+ tlbm_size <<= 1;
}
- return (1 << (tlbm_size << 1)) << 10;
+ return 1024ULL << tlbm_size;
}
/* TLB check function for MAS based SoftTLBs */
--
1.7.6
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH v2 4/4] ppc: booke206: add "info tlb" support
2011-08-18 20:38 [Qemu-devel] [PATCH v2 0/4] ppc: booke206: KVM MMU API and info tlb Scott Wood
` (2 preceding siblings ...)
2011-08-18 20:38 ` [Qemu-devel] [PATCH v2 3/4] ppc: booke206: use MAV=2.0 TSIZE definition, fix 4G pages Scott Wood
@ 2011-08-18 20:38 ` Scott Wood
3 siblings, 0 replies; 6+ messages in thread
From: Scott Wood @ 2011-08-18 20:38 UTC (permalink / raw)
To: agraf; +Cc: qemu-devel
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
v2 (was 3/3 in v1): no change
hmp-commands.hx | 2 +-
monitor.c | 5 ++-
target-ppc/cpu.h | 2 +
target-ppc/helper.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 94 insertions(+), 3 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 0ccfb28..589c1ef 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1306,7 +1306,7 @@ show i8259 (PIC) state
@item info pci
show emulated PCI device info
@item info tlb
-show virtual to physical memory mappings (i386, SH4 and SPARC only)
+show virtual to physical memory mappings (i386, SH4, SPARC, and PPC only)
@item info mem
show the active virtual memory mappings (i386 only)
@item info jit
diff --git a/monitor.c b/monitor.c
index 1b8ba2c..a59aefd 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2442,7 +2442,7 @@ static void tlb_info(Monitor *mon)
#endif
-#if defined(TARGET_SPARC)
+#if defined(TARGET_SPARC) || defined(TARGET_PPC)
static void tlb_info(Monitor *mon)
{
CPUState *env1 = mon_get_cpu();
@@ -2935,7 +2935,8 @@ static const mon_cmd_t info_cmds[] = {
.user_print = do_pci_info_print,
.mhandler.info_new = do_pci_info,
},
-#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC)
+#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) || \
+ defined(TARGET_PPC)
{
.name = "tlb",
.args_type = "",
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 06d78ca..dd5e021 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -2030,4 +2030,6 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
env->nip = tb->pc;
}
+void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env);
+
#endif /* !defined (__CPU_PPC_H__) */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index d9a3855..1c77ed7 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -1466,6 +1466,94 @@ found_tlb:
return ret;
}
+static const char *book3e_tsize_to_str[32] = {
+ "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
+ "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
+ "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
+ "1T", "2T"
+};
+
+static void mmubooke206_dump_one_tlb(FILE *f, fprintf_function cpu_fprintf,
+ CPUState *env, int tlbn, int offset,
+ int tlbsize)
+{
+ ppcmas_tlb_t *entry;
+ int i;
+
+ cpu_fprintf(f, "\nTLB%d:\n", tlbn);
+ cpu_fprintf(f, "Effective Physical Size TID TS SRWX URWX WIMGE U0123\n");
+
+ entry = &env->tlb.tlbm[offset];
+ for (i = 0; i < tlbsize; i++, entry++) {
+ target_phys_addr_t ea, pa, size;
+ int tsize;
+
+ if (!(entry->mas1 & MAS1_VALID)) {
+ continue;
+ }
+
+ tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
+ size = 1024ULL << tsize;
+ ea = entry->mas2 & ~(size - 1);
+ pa = entry->mas7_3 & ~(size - 1);
+
+ cpu_fprintf(f, "0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u S%c%c%c U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
+ (uint64_t)ea, (uint64_t)pa,
+ book3e_tsize_to_str[tsize],
+ (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT,
+ (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT,
+ entry->mas7_3 & MAS3_SR ? 'R' : '-',
+ entry->mas7_3 & MAS3_SW ? 'W' : '-',
+ entry->mas7_3 & MAS3_SX ? 'X' : '-',
+ entry->mas7_3 & MAS3_UR ? 'R' : '-',
+ entry->mas7_3 & MAS3_UW ? 'W' : '-',
+ entry->mas7_3 & MAS3_UX ? 'X' : '-',
+ entry->mas2 & MAS2_W ? 'W' : '-',
+ entry->mas2 & MAS2_I ? 'I' : '-',
+ entry->mas2 & MAS2_M ? 'M' : '-',
+ entry->mas2 & MAS2_G ? 'G' : '-',
+ entry->mas2 & MAS2_E ? 'E' : '-',
+ entry->mas7_3 & MAS3_U0 ? '0' : '-',
+ entry->mas7_3 & MAS3_U1 ? '1' : '-',
+ entry->mas7_3 & MAS3_U2 ? '2' : '-',
+ entry->mas7_3 & MAS3_U3 ? '3' : '-');
+ }
+}
+
+static void mmubooke206_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
+ CPUState *env)
+{
+ int offset = 0;
+ int i;
+
+ if (kvm_enabled() && !env->kvm_sw_tlb) {
+ cpu_fprintf(f, "Cannot access KVM TLB\n");
+ return;
+ }
+
+ for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
+ int size = booke206_tlb_size(env, i);
+
+ if (size == 0) {
+ continue;
+ }
+
+ mmubooke206_dump_one_tlb(f, cpu_fprintf, env, i, offset, size);
+ offset += size;
+ }
+}
+
+void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env)
+{
+ switch (env->mmu_model) {
+ case POWERPC_MMU_BOOKE206:
+ mmubooke206_dump_mmu(f, cpu_fprintf, env);
+ break;
+ default:
+ cpu_fprintf(f, "%s: unimplemented\n", __func__);
+ }
+}
+
static inline int check_physical(CPUState *env, mmu_ctx_t *ctx,
target_ulong eaddr, int rw)
{
--
1.7.6
^ permalink raw reply related [flat|nested] 6+ messages in thread