qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.9-20170303' into staging

ppc patch queuye for 2017-03-03

This will probably be my last pull request before the hard freeze. It
has some new work, but that has all been posted in draft before the
soft freeze, so I think it's reasonable to include in qemu-2.9.

This batch has:
* A substantial amount of POWER9 work
* Implements the legacy (hash) MMU for POWER9
* Some more preliminaries for implementing the POWER9 radix
MMU
* POWER9 has_work
* Basic POWER9 compatibility mode handling
* Removal of some premature tests
* Some cleanups and fixes to the existing MMU code to make the
POWER9 work simpler
* A bugfix for TCG multiply adds on power
* Allow pseries guests to access PCIe extended config space

This also includes a code-motion not strictly in ppc code - moving
getrampagesize() from ppc code to exec.c. This will make some future
VFIO improvements easier, Paolo said it was ok to merge via my tree.

# gpg: Signature made Fri 03 Mar 2017 03:20:36 GMT
# gpg: using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-2.9-20170303:
target/ppc: rewrite f[n]m[add,sub] using float64_muladd
spapr: Small cleanup of PPC MMU enums
spapr_pci: Advertise access to PCIe extended config space
target/ppc: Rework hash mmu page fault code and add defines for clarity
target/ppc: Move no-execute and guarded page checking into new function
target/ppc: Add execute permission checking to access authority check
target/ppc: Add Instruction Authority Mask Register Check
hw/ppc/spapr: Add POWER9 to pseries cpu models
target/ppc/POWER9: Add cpu_has_work function for POWER9
target/ppc/POWER9: Add POWER9 pa-features definition
target/ppc/POWER9: Add POWER9 mmu fault handler
target/ppc: Don't gen an SDR1 on POWER9 and rework register creation
target/ppc: Add patb_entry to sPAPRMachineState
target/ppc/POWER9: Add POWERPC_MMU_V3 bit
powernv: Don't test POWER9 CPU yet
exec, kvm, target-ppc: Move getrampagesize() to common code
target/ppc: Add POWER9/ISAv3.00 to compat_table

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+734 -494
+82
exec.c
··· 42 42 #include "exec/memory.h" 43 43 #include "exec/ioport.h" 44 44 #include "sysemu/dma.h" 45 + #include "sysemu/numa.h" 45 46 #include "exec/address-spaces.h" 46 47 #include "sysemu/xen-mapcache.h" 47 48 #include "trace-root.h" ··· 1255 1256 { 1256 1257 qemu_mutex_unlock(&ram_list.mutex); 1257 1258 } 1259 + 1260 + #ifdef __linux__ 1261 + /* 1262 + * FIXME TOCTTOU: this iterates over memory backends' mem-path, which 1263 + * may or may not name the same files / on the same filesystem now as 1264 + * when we actually open and map them. Iterate over the file 1265 + * descriptors instead, and use qemu_fd_getpagesize(). 1266 + */ 1267 + static int find_max_supported_pagesize(Object *obj, void *opaque) 1268 + { 1269 + char *mem_path; 1270 + long *hpsize_min = opaque; 1271 + 1272 + if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) { 1273 + mem_path = object_property_get_str(obj, "mem-path", NULL); 1274 + if (mem_path) { 1275 + long hpsize = qemu_mempath_getpagesize(mem_path); 1276 + if (hpsize < *hpsize_min) { 1277 + *hpsize_min = hpsize; 1278 + } 1279 + } else { 1280 + *hpsize_min = getpagesize(); 1281 + } 1282 + } 1283 + 1284 + return 0; 1285 + } 1286 + 1287 + long qemu_getrampagesize(void) 1288 + { 1289 + long hpsize = LONG_MAX; 1290 + long mainrampagesize; 1291 + Object *memdev_root; 1292 + 1293 + if (mem_path) { 1294 + mainrampagesize = qemu_mempath_getpagesize(mem_path); 1295 + } else { 1296 + mainrampagesize = getpagesize(); 1297 + } 1298 + 1299 + /* it's possible we have memory-backend objects with 1300 + * hugepage-backed RAM. these may get mapped into system 1301 + * address space via -numa parameters or memory hotplug 1302 + * hooks. we want to take these into account, but we 1303 + * also want to make sure these supported hugepage 1304 + * sizes are applicable across the entire range of memory 1305 + * we may boot from, so we take the min across all 1306 + * backends, and assume normal pages in cases where a 1307 + * backend isn't backed by hugepages. 1308 + */ 1309 + memdev_root = object_resolve_path("/objects", NULL); 1310 + if (memdev_root) { 1311 + object_child_foreach(memdev_root, find_max_supported_pagesize, &hpsize); 1312 + } 1313 + if (hpsize == LONG_MAX) { 1314 + /* No additional memory regions found ==> Report main RAM page size */ 1315 + return mainrampagesize; 1316 + } 1317 + 1318 + /* If NUMA is disabled or the NUMA nodes are not backed with a 1319 + * memory-backend, then there is at least one node using "normal" RAM, 1320 + * so if its page size is smaller we have got to report that size instead. 1321 + */ 1322 + if (hpsize > mainrampagesize && 1323 + (nb_numa_nodes == 0 || numa_info[0].node_memdev == NULL)) { 1324 + static bool warned; 1325 + if (!warned) { 1326 + error_report("Huge page support disabled (n/a for main memory)."); 1327 + warned = true; 1328 + } 1329 + return mainrampagesize; 1330 + } 1331 + 1332 + return hpsize; 1333 + } 1334 + #else 1335 + long qemu_getrampagesize(void) 1336 + { 1337 + return getpagesize(); 1338 + } 1339 + #endif 1258 1340 1259 1341 #ifdef __linux__ 1260 1342 static int64_t get_file_size(int fd)
+50 -5
hw/ppc/spapr.c
··· 390 390 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 391 391 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 392 392 0x80, 0x00, 0x80, 0x00, 0x00, 0x00 }; 393 + /* Currently we don't advertise any of the "new" ISAv3.00 functionality */ 394 + uint8_t pa_features_300[] = { 64, 0, 395 + 0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0, /* 0 - 5 */ 396 + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */ 397 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */ 398 + 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */ 399 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 24 - 29 */ 400 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 35 */ 401 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 36 - 41 */ 402 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 42 - 47 */ 403 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 48 - 53 */ 404 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 54 - 59 */ 405 + 0x00, 0x00, 0x00, 0x00 }; /* 60 - 63 */ 406 + 393 407 uint8_t *pa_features; 394 408 size_t pa_size; 395 409 396 - switch (env->mmu_model) { 397 - case POWERPC_MMU_2_06: 398 - case POWERPC_MMU_2_06a: 410 + switch (POWERPC_MMU_VER(env->mmu_model)) { 411 + case POWERPC_MMU_VER_2_06: 399 412 pa_features = pa_features_206; 400 413 pa_size = sizeof(pa_features_206); 401 414 break; 402 - case POWERPC_MMU_2_07: 403 - case POWERPC_MMU_2_07a: 415 + case POWERPC_MMU_VER_2_07: 404 416 pa_features = pa_features_207; 405 417 pa_size = sizeof(pa_features_207); 418 + break; 419 + case POWERPC_MMU_VER_3_00: 420 + pa_features = pa_features_300; 421 + pa_size = sizeof(pa_features_300); 406 422 break; 407 423 default: 408 424 return; ··· 1055 1071 } 1056 1072 } 1057 1073 1074 + static uint64_t spapr_get_patbe(PPCVirtualHypervisor *vhyp) 1075 + { 1076 + sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp); 1077 + 1078 + return spapr->patb_entry; 1079 + } 1080 + 1058 1081 #define HPTE(_table, _i) (void *)(((uint64_t *)(_table)) + ((_i) * 2)) 1059 1082 #define HPTE_VALID(_hpte) (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_VALID) 1060 1083 #define HPTE_DIRTY(_hpte) (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_HPTE_DIRTY) ··· 1233 1256 1234 1257 /* Check for unknown sysbus devices */ 1235 1258 foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL); 1259 + 1260 + spapr->patb_entry = 0; 1236 1261 1237 1262 /* Allocate and/or reset the hash page table */ 1238 1263 spapr_reallocate_hpt(spapr, ··· 1427 1452 }, 1428 1453 }; 1429 1454 1455 + static bool spapr_patb_entry_needed(void *opaque) 1456 + { 1457 + sPAPRMachineState *spapr = opaque; 1458 + 1459 + return !!spapr->patb_entry; 1460 + } 1461 + 1462 + static const VMStateDescription vmstate_spapr_patb_entry = { 1463 + .name = "spapr_patb_entry", 1464 + .version_id = 1, 1465 + .minimum_version_id = 1, 1466 + .needed = spapr_patb_entry_needed, 1467 + .fields = (VMStateField[]) { 1468 + VMSTATE_UINT64(patb_entry, sPAPRMachineState), 1469 + VMSTATE_END_OF_LIST() 1470 + }, 1471 + }; 1472 + 1430 1473 static const VMStateDescription vmstate_spapr = { 1431 1474 .name = "spapr", 1432 1475 .version_id = 3, ··· 1444 1487 }, 1445 1488 .subsections = (const VMStateDescription*[]) { 1446 1489 &vmstate_spapr_ov5_cas, 1490 + &vmstate_spapr_patb_entry, 1447 1491 NULL 1448 1492 } 1449 1493 }; ··· 3049 3093 vhc->map_hptes = spapr_map_hptes; 3050 3094 vhc->unmap_hptes = spapr_unmap_hptes; 3051 3095 vhc->store_hpte = spapr_store_hpte; 3096 + vhc->get_patbe = spapr_get_patbe; 3052 3097 xic->ics_get = spapr_ics_get; 3053 3098 xic->ics_resend = spapr_ics_resend; 3054 3099 xic->icp_get = spapr_icp_get;
+3
hw/ppc/spapr_cpu_core.c
··· 238 238 239 239 /* POWER8NVL */ 240 240 "POWER8NVL_v1.0", 241 + 242 + /* POWER9 */ 243 + "POWER9_v1.0", 241 244 }; 242 245 243 246 void spapr_cpu_core_class_init(ObjectClass *oc, void *data)
+4
hw/ppc/spapr_pci.c
··· 1321 1321 _FDT(fdt_setprop(fdt, offset, "assigned-addresses", 1322 1322 (uint8_t *)rp.assigned, rp.assigned_len)); 1323 1323 1324 + if (pci_is_express(dev)) { 1325 + _FDT(fdt_setprop_cell(fdt, offset, "ibm,pci-config-space-type", 0x1)); 1326 + } 1327 + 1324 1328 return 0; 1325 1329 } 1326 1330
+1
include/exec/ram_addr.h
··· 52 52 return (char *)block->host + offset; 53 53 } 54 54 55 + long qemu_getrampagesize(void); 55 56 ram_addr_t last_ram_offset(void); 56 57 RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, 57 58 bool share, const char *mem_path,
+1
include/hw/ppc/spapr.h
··· 62 62 63 63 void *htab; 64 64 uint32_t htab_shift; 65 + uint64_t patb_entry; /* Process tbl registed in H_REGISTER_PROCESS_TABLE */ 65 66 hwaddr rma_size; 66 67 int vrma_adjust; 67 68 ssize_t rtas_size;
+2
include/qemu/mmap-alloc.h
··· 5 5 6 6 size_t qemu_fd_getpagesize(int fd); 7 7 8 + size_t qemu_mempath_getpagesize(const char *mem_path); 9 + 8 10 void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared); 9 11 10 12 void qemu_ram_munmap(void *ptr, size_t size);
+1 -1
target/ppc/Makefile.objs
··· 3 3 obj-y += translate.o 4 4 ifeq ($(CONFIG_SOFTMMU),y) 5 5 obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o arch_dump.o 6 - obj-$(TARGET_PPC64) += mmu-hash64.o compat.o 6 + obj-$(TARGET_PPC64) += mmu-hash64.o mmu-book3s-v3.o compat.o 7 7 endif 8 8 obj-$(CONFIG_KVM) += kvm.o 9 9 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
+11 -5
target/ppc/compat.c
··· 39 39 */ 40 40 { /* POWER6, ISA2.05 */ 41 41 .pvr = CPU_POWERPC_LOGICAL_2_05, 42 - .pcr = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05 43 - | PCR_TM_DIS | PCR_VSX_DIS, 42 + .pcr = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | 43 + PCR_COMPAT_2_05 | PCR_TM_DIS | PCR_VSX_DIS, 44 44 .pcr_level = PCR_COMPAT_2_05, 45 45 .max_threads = 2, 46 46 }, 47 47 { /* POWER7, ISA2.06 */ 48 48 .pvr = CPU_POWERPC_LOGICAL_2_06, 49 - .pcr = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_TM_DIS, 49 + .pcr = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_TM_DIS, 50 50 .pcr_level = PCR_COMPAT_2_06, 51 51 .max_threads = 4, 52 52 }, 53 53 { 54 54 .pvr = CPU_POWERPC_LOGICAL_2_06_PLUS, 55 - .pcr = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_TM_DIS, 55 + .pcr = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_TM_DIS, 56 56 .pcr_level = PCR_COMPAT_2_06, 57 57 .max_threads = 4, 58 58 }, 59 59 { /* POWER8, ISA2.07 */ 60 60 .pvr = CPU_POWERPC_LOGICAL_2_07, 61 - .pcr = PCR_COMPAT_2_07, 61 + .pcr = PCR_COMPAT_3_00 | PCR_COMPAT_2_07, 62 62 .pcr_level = PCR_COMPAT_2_07, 63 63 .max_threads = 8, 64 + }, 65 + { /* POWER9, ISA3.00 */ 66 + .pvr = CPU_POWERPC_LOGICAL_3_00, 67 + .pcr = PCR_COMPAT_3_00, 68 + .pcr_level = PCR_COMPAT_3_00, 69 + .max_threads = 4, 64 70 }, 65 71 }; 66 72
+9 -7
target/ppc/cpu-qom.h
··· 71 71 #define POWERPC_MMU_1TSEG 0x00020000 72 72 #define POWERPC_MMU_AMR 0x00040000 73 73 #define POWERPC_MMU_64K 0x00080000 74 + #define POWERPC_MMU_V3 0x00100000 /* ISA V3.00 MMU Support */ 74 75 /* 64 bits PowerPC MMU */ 75 76 POWERPC_MMU_64B = POWERPC_MMU_64 | 0x00000001, 76 77 /* Architecture 2.03 and later (has LPCR) */ ··· 79 80 POWERPC_MMU_2_06 = POWERPC_MMU_64 | POWERPC_MMU_1TSEG 80 81 | POWERPC_MMU_64K 81 82 | POWERPC_MMU_AMR | 0x00000003, 82 - /* Architecture 2.06 "degraded" (no 1T segments) */ 83 - POWERPC_MMU_2_06a = POWERPC_MMU_64 | POWERPC_MMU_AMR 84 - | 0x00000003, 85 83 /* Architecture 2.07 variant */ 86 84 POWERPC_MMU_2_07 = POWERPC_MMU_64 | POWERPC_MMU_1TSEG 87 85 | POWERPC_MMU_64K 88 86 | POWERPC_MMU_AMR | 0x00000004, 89 - /* Architecture 2.07 "degraded" (no 1T segments) */ 90 - POWERPC_MMU_2_07a = POWERPC_MMU_64 | POWERPC_MMU_AMR 91 - | 0x00000004, 92 87 /* Architecture 3.00 variant */ 93 88 POWERPC_MMU_3_00 = POWERPC_MMU_64 | POWERPC_MMU_1TSEG 94 89 | POWERPC_MMU_64K 95 - | POWERPC_MMU_AMR | 0x00000005, 90 + | POWERPC_MMU_AMR | POWERPC_MMU_V3 91 + | 0x00000005, 96 92 }; 93 + #define POWERPC_MMU_VER(x) ((x) & (POWERPC_MMU_64 | 0xFFFF)) 94 + #define POWERPC_MMU_VER_64B POWERPC_MMU_VER(POWERPC_MMU_64B) 95 + #define POWERPC_MMU_VER_2_03 POWERPC_MMU_VER(POWERPC_MMU_2_03) 96 + #define POWERPC_MMU_VER_2_06 POWERPC_MMU_VER(POWERPC_MMU_2_06) 97 + #define POWERPC_MMU_VER_2_07 POWERPC_MMU_VER(POWERPC_MMU_2_07) 98 + #define POWERPC_MMU_VER_3_00 POWERPC_MMU_VER(POWERPC_MMU_3_00) 97 99 98 100 /*****************************************************************************/ 99 101 /* Exception model */
+17
target/ppc/cpu.h
··· 473 473 #endif 474 474 #endif 475 475 476 + /* DSISR */ 477 + #define DSISR_NOPTE 0x40000000 478 + /* Not permitted by access authority of encoded access authority */ 479 + #define DSISR_PROTFAULT 0x08000000 480 + #define DSISR_ISSTORE 0x02000000 481 + /* Not permitted by virtual page class key protection */ 482 + #define DSISR_AMR 0x00200000 483 + 484 + /* SRR1 error code fields */ 485 + 486 + #define SRR1_NOPTE DSISR_NOPTE 487 + /* Not permitted due to no-execute or guard bit set */ 488 + #define SRR1_NOEXEC_GUARD 0x10000000 489 + #define SRR1_PROTFAULT DSISR_PROTFAULT 490 + #define SRR1_IAMR DSISR_AMR 491 + 476 492 /* Facility Status and Control (FSCR) bits */ 477 493 #define FSCR_EBB (63 - 56) /* Event-Based Branch Facility */ 478 494 #define FSCR_TAR (63 - 55) /* Target Address Register */ ··· 1216 1232 hwaddr ptex, int n); 1217 1233 void (*store_hpte)(PPCVirtualHypervisor *vhyp, hwaddr ptex, 1218 1234 uint64_t pte0, uint64_t pte1); 1235 + uint64_t (*get_patbe)(PPCVirtualHypervisor *vhyp); 1219 1236 }; 1220 1237 1221 1238 #define TYPE_PPC_VIRTUAL_HYPERVISOR "ppc-virtual-hypervisor"
+45 -166
target/ppc/fpu_helper.c
··· 743 743 return do_fri(env, arg, float_round_down); 744 744 } 745 745 746 - /* fmadd - fmadd. */ 747 - uint64_t helper_fmadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2, 748 - uint64_t arg3) 746 + static void float64_maddsub_update_excp(CPUPPCState *env, float64 arg1, 747 + float64 arg2, float64 arg3, 748 + unsigned int madd_flags) 749 749 { 750 - CPU_DoubleU farg1, farg2, farg3; 751 - 752 - farg1.ll = arg1; 753 - farg2.ll = arg2; 754 - farg3.ll = arg3; 755 - 756 - if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) || 757 - (float64_is_zero(farg1.d) && float64_is_infinity(farg2.d)))) { 750 + if (unlikely((float64_is_infinity(arg1) && float64_is_zero(arg2)) || 751 + (float64_is_zero(arg1) && float64_is_infinity(arg2)))) { 758 752 /* Multiplication of zero by infinity */ 759 - farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1); 760 - } else { 761 - if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) || 762 - float64_is_signaling_nan(farg2.d, &env->fp_status) || 763 - float64_is_signaling_nan(farg3.d, &env->fp_status))) { 764 - /* sNaN operation */ 765 - float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); 766 - } 767 - /* This is the way the PowerPC specification defines it */ 768 - float128 ft0_128, ft1_128; 753 + arg1 = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1); 754 + } else if (unlikely(float64_is_signaling_nan(arg1, &env->fp_status) || 755 + float64_is_signaling_nan(arg2, &env->fp_status) || 756 + float64_is_signaling_nan(arg3, &env->fp_status))) { 757 + /* sNaN operation */ 758 + float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); 759 + } else if ((float64_is_infinity(arg1) || float64_is_infinity(arg2)) && 760 + float64_is_infinity(arg3)) { 761 + uint8_t aSign, bSign, cSign; 769 762 770 - ft0_128 = float64_to_float128(farg1.d, &env->fp_status); 771 - ft1_128 = float64_to_float128(farg2.d, &env->fp_status); 772 - ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status); 773 - if (unlikely(float128_is_infinity(ft0_128) && 774 - float64_is_infinity(farg3.d) && 775 - float128_is_neg(ft0_128) != float64_is_neg(farg3.d))) { 776 - /* Magnitude subtraction of infinities */ 777 - farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1); 778 - } else { 779 - ft1_128 = float64_to_float128(farg3.d, &env->fp_status); 780 - ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status); 781 - farg1.d = float128_to_float64(ft0_128, &env->fp_status); 763 + aSign = float64_is_neg(arg1); 764 + bSign = float64_is_neg(arg2); 765 + cSign = float64_is_neg(arg3); 766 + if (madd_flags & float_muladd_negate_c) { 767 + cSign ^= 1; 782 768 } 783 - } 784 - 785 - return farg1.ll; 786 - } 787 - 788 - /* fmsub - fmsub. */ 789 - uint64_t helper_fmsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2, 790 - uint64_t arg3) 791 - { 792 - CPU_DoubleU farg1, farg2, farg3; 793 - 794 - farg1.ll = arg1; 795 - farg2.ll = arg2; 796 - farg3.ll = arg3; 797 - 798 - if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) || 799 - (float64_is_zero(farg1.d) && 800 - float64_is_infinity(farg2.d)))) { 801 - /* Multiplication of zero by infinity */ 802 - farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1); 803 - } else { 804 - if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) || 805 - float64_is_signaling_nan(farg2.d, &env->fp_status) || 806 - float64_is_signaling_nan(farg3.d, &env->fp_status))) { 807 - /* sNaN operation */ 808 - float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); 809 - } 810 - /* This is the way the PowerPC specification defines it */ 811 - float128 ft0_128, ft1_128; 812 - 813 - ft0_128 = float64_to_float128(farg1.d, &env->fp_status); 814 - ft1_128 = float64_to_float128(farg2.d, &env->fp_status); 815 - ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status); 816 - if (unlikely(float128_is_infinity(ft0_128) && 817 - float64_is_infinity(farg3.d) && 818 - float128_is_neg(ft0_128) == float64_is_neg(farg3.d))) { 819 - /* Magnitude subtraction of infinities */ 820 - farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1); 821 - } else { 822 - ft1_128 = float64_to_float128(farg3.d, &env->fp_status); 823 - ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status); 824 - farg1.d = float128_to_float64(ft0_128, &env->fp_status); 769 + if (aSign ^ bSign ^ cSign) { 770 + float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1); 825 771 } 826 772 } 827 - return farg1.ll; 828 773 } 829 774 830 - /* fnmadd - fnmadd. */ 831 - uint64_t helper_fnmadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2, 832 - uint64_t arg3) 833 - { 834 - CPU_DoubleU farg1, farg2, farg3; 835 - 836 - farg1.ll = arg1; 837 - farg2.ll = arg2; 838 - farg3.ll = arg3; 839 - 840 - if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) || 841 - (float64_is_zero(farg1.d) && float64_is_infinity(farg2.d)))) { 842 - /* Multiplication of zero by infinity */ 843 - farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1); 844 - } else { 845 - if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) || 846 - float64_is_signaling_nan(farg2.d, &env->fp_status) || 847 - float64_is_signaling_nan(farg3.d, &env->fp_status))) { 848 - /* sNaN operation */ 849 - float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); 850 - } 851 - /* This is the way the PowerPC specification defines it */ 852 - float128 ft0_128, ft1_128; 853 - 854 - ft0_128 = float64_to_float128(farg1.d, &env->fp_status); 855 - ft1_128 = float64_to_float128(farg2.d, &env->fp_status); 856 - ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status); 857 - if (unlikely(float128_is_infinity(ft0_128) && 858 - float64_is_infinity(farg3.d) && 859 - float128_is_neg(ft0_128) != float64_is_neg(farg3.d))) { 860 - /* Magnitude subtraction of infinities */ 861 - farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1); 862 - } else { 863 - ft1_128 = float64_to_float128(farg3.d, &env->fp_status); 864 - ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status); 865 - farg1.d = float128_to_float64(ft0_128, &env->fp_status); 866 - } 867 - if (likely(!float64_is_any_nan(farg1.d))) { 868 - farg1.d = float64_chs(farg1.d); 869 - } 870 - } 871 - return farg1.ll; 775 + #define FPU_FMADD(op, madd_flags) \ 776 + uint64_t helper_##op(CPUPPCState *env, uint64_t arg1, \ 777 + uint64_t arg2, uint64_t arg3) \ 778 + { \ 779 + uint32_t flags; \ 780 + float64 ret = float64_muladd(arg1, arg2, arg3, madd_flags, \ 781 + &env->fp_status); \ 782 + flags = get_float_exception_flags(&env->fp_status); \ 783 + if (flags) { \ 784 + if (flags & float_flag_invalid) { \ 785 + float64_maddsub_update_excp(env, arg1, arg2, arg3, \ 786 + madd_flags); \ 787 + } \ 788 + float_check_status(env); \ 789 + } \ 790 + return ret; \ 872 791 } 873 792 874 - /* fnmsub - fnmsub. */ 875 - uint64_t helper_fnmsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2, 876 - uint64_t arg3) 877 - { 878 - CPU_DoubleU farg1, farg2, farg3; 879 - 880 - farg1.ll = arg1; 881 - farg2.ll = arg2; 882 - farg3.ll = arg3; 793 + #define MADD_FLGS 0 794 + #define MSUB_FLGS float_muladd_negate_c 795 + #define NMADD_FLGS float_muladd_negate_result 796 + #define NMSUB_FLGS (float_muladd_negate_c | float_muladd_negate_result) 883 797 884 - if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) || 885 - (float64_is_zero(farg1.d) && 886 - float64_is_infinity(farg2.d)))) { 887 - /* Multiplication of zero by infinity */ 888 - farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1); 889 - } else { 890 - if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) || 891 - float64_is_signaling_nan(farg2.d, &env->fp_status) || 892 - float64_is_signaling_nan(farg3.d, &env->fp_status))) { 893 - /* sNaN operation */ 894 - float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); 895 - } 896 - /* This is the way the PowerPC specification defines it */ 897 - float128 ft0_128, ft1_128; 898 - 899 - ft0_128 = float64_to_float128(farg1.d, &env->fp_status); 900 - ft1_128 = float64_to_float128(farg2.d, &env->fp_status); 901 - ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status); 902 - if (unlikely(float128_is_infinity(ft0_128) && 903 - float64_is_infinity(farg3.d) && 904 - float128_is_neg(ft0_128) == float64_is_neg(farg3.d))) { 905 - /* Magnitude subtraction of infinities */ 906 - farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1); 907 - } else { 908 - ft1_128 = float64_to_float128(farg3.d, &env->fp_status); 909 - ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status); 910 - farg1.d = float128_to_float64(ft0_128, &env->fp_status); 911 - } 912 - if (likely(!float64_is_any_nan(farg1.d))) { 913 - farg1.d = float64_chs(farg1.d); 914 - } 915 - } 916 - return farg1.ll; 917 - } 798 + FPU_FMADD(fmadd, MADD_FLGS) 799 + FPU_FMADD(fnmadd, NMADD_FLGS) 800 + FPU_FMADD(fmsub, MSUB_FLGS) 801 + FPU_FMADD(fnmsub, NMSUB_FLGS) 918 802 919 803 /* frsp - frsp. */ 920 804 uint64_t helper_frsp(CPUPPCState *env, uint64_t arg) ··· 2383 2267 putVSR(xT(opcode), &xt_out, env); \ 2384 2268 float_check_status(env); \ 2385 2269 } 2386 - 2387 - #define MADD_FLGS 0 2388 - #define MSUB_FLGS float_muladd_negate_c 2389 - #define NMADD_FLGS float_muladd_negate_result 2390 - #define NMSUB_FLGS (float_muladd_negate_c | float_muladd_negate_result) 2391 2270 2392 2271 VSX_MADD(xsmaddadp, 1, float64, VsrD(0), MADD_FLGS, 1, 1, 0) 2393 2272 VSX_MADD(xsmaddmdp, 1, float64, VsrD(0), MADD_FLGS, 0, 1, 0)
+9 -108
target/ppc/kvm.c
··· 28 28 #include "qemu/timer.h" 29 29 #include "sysemu/sysemu.h" 30 30 #include "sysemu/hw_accel.h" 31 - #include "sysemu/numa.h" 32 31 #include "kvm_ppc.h" 33 32 #include "sysemu/cpus.h" 34 33 #include "sysemu/device_tree.h" ··· 43 42 #include "trace.h" 44 43 #include "exec/gdbstub.h" 45 44 #include "exec/memattrs.h" 45 + #include "exec/ram_addr.h" 46 46 #include "sysemu/hostmem.h" 47 47 #include "qemu/cutils.h" 48 + #include "qemu/mmap-alloc.h" 48 49 #if defined(TARGET_PPC64) 49 50 #include "hw/ppc/spapr_cpu_core.h" 50 51 #endif ··· 282 283 info->flags |= KVM_PPC_1T_SEGMENTS; 283 284 } 284 285 285 - if (env->mmu_model == POWERPC_MMU_2_06 || 286 - env->mmu_model == POWERPC_MMU_2_07) { 286 + if (POWERPC_MMU_VER(env->mmu_model) == POWERPC_MMU_VER_2_06 || 287 + POWERPC_MMU_VER(env->mmu_model) == POWERPC_MMU_VER_2_07) { 287 288 info->slb_size = 32; 288 289 } else { 289 290 info->slb_size = 64; ··· 297 298 i++; 298 299 299 300 /* 64K on MMU 2.06 and later */ 300 - if (env->mmu_model == POWERPC_MMU_2_06 || 301 - env->mmu_model == POWERPC_MMU_2_07) { 301 + if (POWERPC_MMU_VER(env->mmu_model) == POWERPC_MMU_VER_2_06 || 302 + POWERPC_MMU_VER(env->mmu_model) == POWERPC_MMU_VER_2_07) { 302 303 info->sps[i].page_shift = 16; 303 304 info->sps[i].slb_enc = 0x110; 304 305 info->sps[i].enc[0].page_shift = 16; ··· 329 330 kvm_get_fallback_smmu_info(cpu, info); 330 331 } 331 332 332 - static long gethugepagesize(const char *mem_path) 333 - { 334 - struct statfs fs; 335 - int ret; 336 - 337 - do { 338 - ret = statfs(mem_path, &fs); 339 - } while (ret != 0 && errno == EINTR); 340 - 341 - if (ret != 0) { 342 - fprintf(stderr, "Couldn't statfs() memory path: %s\n", 343 - strerror(errno)); 344 - exit(1); 345 - } 346 - 347 - #define HUGETLBFS_MAGIC 0x958458f6 348 - 349 - if (fs.f_type != HUGETLBFS_MAGIC) { 350 - /* Explicit mempath, but it's ordinary pages */ 351 - return getpagesize(); 352 - } 353 - 354 - /* It's hugepage, return the huge page size */ 355 - return fs.f_bsize; 356 - } 357 - 358 - /* 359 - * FIXME TOCTTOU: this iterates over memory backends' mem-path, which 360 - * may or may not name the same files / on the same filesystem now as 361 - * when we actually open and map them. Iterate over the file 362 - * descriptors instead, and use qemu_fd_getpagesize(). 363 - */ 364 - static int find_max_supported_pagesize(Object *obj, void *opaque) 365 - { 366 - char *mem_path; 367 - long *hpsize_min = opaque; 368 - 369 - if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) { 370 - mem_path = object_property_get_str(obj, "mem-path", NULL); 371 - if (mem_path) { 372 - long hpsize = gethugepagesize(mem_path); 373 - if (hpsize < *hpsize_min) { 374 - *hpsize_min = hpsize; 375 - } 376 - } else { 377 - *hpsize_min = getpagesize(); 378 - } 379 - } 380 - 381 - return 0; 382 - } 383 - 384 - static long getrampagesize(void) 385 - { 386 - long hpsize = LONG_MAX; 387 - long mainrampagesize; 388 - Object *memdev_root; 389 - 390 - if (mem_path) { 391 - mainrampagesize = gethugepagesize(mem_path); 392 - } else { 393 - mainrampagesize = getpagesize(); 394 - } 395 - 396 - /* it's possible we have memory-backend objects with 397 - * hugepage-backed RAM. these may get mapped into system 398 - * address space via -numa parameters or memory hotplug 399 - * hooks. we want to take these into account, but we 400 - * also want to make sure these supported hugepage 401 - * sizes are applicable across the entire range of memory 402 - * we may boot from, so we take the min across all 403 - * backends, and assume normal pages in cases where a 404 - * backend isn't backed by hugepages. 405 - */ 406 - memdev_root = object_resolve_path("/objects", NULL); 407 - if (memdev_root) { 408 - object_child_foreach(memdev_root, find_max_supported_pagesize, &hpsize); 409 - } 410 - if (hpsize == LONG_MAX) { 411 - /* No additional memory regions found ==> Report main RAM page size */ 412 - return mainrampagesize; 413 - } 414 - 415 - /* If NUMA is disabled or the NUMA nodes are not backed with a 416 - * memory-backend, then there is at least one node using "normal" RAM, 417 - * so if its page size is smaller we have got to report that size instead. 418 - */ 419 - if (hpsize > mainrampagesize && 420 - (nb_numa_nodes == 0 || numa_info[0].node_memdev == NULL)) { 421 - static bool warned; 422 - if (!warned) { 423 - error_report("Huge page support disabled (n/a for main memory)."); 424 - warned = true; 425 - } 426 - return mainrampagesize; 427 - } 428 - 429 - return hpsize; 430 - } 431 - 432 333 static bool kvm_valid_page_size(uint32_t flags, long rampgsize, uint32_t shift) 433 334 { 434 335 if (!(flags & KVM_PPC_PAGE_SIZES_REAL)) { ··· 460 361 } 461 362 462 363 if (!max_cpu_page_size) { 463 - max_cpu_page_size = getrampagesize(); 364 + max_cpu_page_size = qemu_getrampagesize(); 464 365 } 465 366 466 367 /* Convert to QEMU form */ ··· 521 422 long pagesize; 522 423 523 424 if (mempath) { 524 - pagesize = gethugepagesize(mempath); 425 + pagesize = qemu_mempath_getpagesize(mempath); 525 426 } else { 526 427 pagesize = getpagesize(); 527 428 } ··· 2205 2106 /* Find the largest hardware supported page size that's less than 2206 2107 * or equal to the (logical) backing page size of guest RAM */ 2207 2108 kvm_get_smmu_info(POWERPC_CPU(first_cpu), &info); 2208 - rampagesize = getrampagesize(); 2109 + rampagesize = qemu_getrampagesize(); 2209 2110 best_page_shift = 0; 2210 2111 2211 2112 for (i = 0; i < KVM_PPC_PAGE_SIZES_MAX_SZ; i++) {
+37
target/ppc/mmu-book3s-v3.c
··· 1 + /* 2 + * PowerPC ISAV3 BookS emulation generic mmu helpers for qemu. 3 + * 4 + * Copyright (c) 2017 Suraj Jitindar Singh, IBM Corporation 5 + * 6 + * This library is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU Lesser General Public 8 + * License as published by the Free Software Foundation; either 9 + * version 2 of the License, or (at your option) any later version. 10 + * 11 + * This library is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 + * Lesser General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU Lesser General Public 17 + * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include "qemu/osdep.h" 21 + #include "qapi/error.h" 22 + #include "cpu.h" 23 + #include "mmu-hash64.h" 24 + #include "mmu-book3s-v3.h" 25 + #include "qemu/error-report.h" 26 + 27 + int ppc64_v3_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx, 28 + int mmu_idx) 29 + { 30 + if (ppc64_radix_guest(cpu)) { /* Guest uses radix */ 31 + /* TODO - Unsupported */ 32 + error_report("Guest Radix Support Unimplemented"); 33 + exit(1); 34 + } else { /* Guest uses hash */ 35 + return ppc_hash64_handle_mmu_fault(cpu, eaddr, rwx, mmu_idx); 36 + } 37 + }
+50
target/ppc/mmu-book3s-v3.h
··· 1 + /* 2 + * PowerPC ISAV3 BookS emulation generic mmu definitions for qemu. 3 + * 4 + * Copyright (c) 2017 Suraj Jitindar Singh, IBM Corporation 5 + * 6 + * This library is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU Lesser General Public 8 + * License as published by the Free Software Foundation; either 9 + * version 2 of the License, or (at your option) any later version. 10 + * 11 + * This library is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 + * Lesser General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU Lesser General Public 17 + * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #ifndef MMU_H 21 + #define MMU_H 22 + 23 + #ifndef CONFIG_USER_ONLY 24 + 25 + /* Partition Table Entry Fields */ 26 + #define PATBE1_GR 0x8000000000000000 27 + 28 + #ifdef TARGET_PPC64 29 + 30 + static inline bool ppc64_use_proc_tbl(PowerPCCPU *cpu) 31 + { 32 + return !!(cpu->env.spr[SPR_LPCR] & LPCR_UPRT); 33 + } 34 + 35 + static inline bool ppc64_radix_guest(PowerPCCPU *cpu) 36 + { 37 + PPCVirtualHypervisorClass *vhc = 38 + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 39 + 40 + return !!(vhc->get_patbe(cpu->vhyp) & PATBE1_GR); 41 + } 42 + 43 + int ppc64_v3_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx, 44 + int mmu_idx); 45 + 46 + #endif /* TARGET_PPC64 */ 47 + 48 + #endif /* CONFIG_USER_ONLY */ 49 + 50 + #endif /* MMU_H */
+85 -32
target/ppc/mmu-hash64.c
··· 28 28 #include "mmu-hash64.h" 29 29 #include "exec/log.h" 30 30 #include "hw/hw.h" 31 + #include "mmu-book3s-v3.h" 31 32 32 33 //#define DEBUG_SLB 33 34 ··· 289 290 return rt; 290 291 } 291 292 293 + /* Check No-Execute or Guarded Storage */ 294 + static inline int ppc_hash64_pte_noexec_guard(PowerPCCPU *cpu, 295 + ppc_hash_pte64_t pte) 296 + { 297 + /* Exec permissions CANNOT take away read or write permissions */ 298 + return (pte.pte1 & HPTE64_R_N) || (pte.pte1 & HPTE64_R_G) ? 299 + PAGE_READ | PAGE_WRITE : PAGE_READ | PAGE_WRITE | PAGE_EXEC; 300 + } 301 + 302 + /* Check Basic Storage Protection */ 292 303 static int ppc_hash64_pte_prot(PowerPCCPU *cpu, 293 304 ppc_slb_t *slb, ppc_hash_pte64_t pte) 294 305 { ··· 307 318 case 0x0: 308 319 case 0x1: 309 320 case 0x2: 310 - prot = PAGE_READ | PAGE_WRITE; 321 + prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 311 322 break; 312 323 313 324 case 0x3: 314 325 case 0x6: 315 - prot = PAGE_READ; 326 + prot = PAGE_READ | PAGE_EXEC; 316 327 break; 317 328 } 318 329 } else { 319 330 switch (pp) { 320 331 case 0x0: 321 332 case 0x6: 322 - prot = 0; 323 333 break; 324 334 325 335 case 0x1: 326 336 case 0x3: 327 - prot = PAGE_READ; 337 + prot = PAGE_READ | PAGE_EXEC; 328 338 break; 329 339 330 340 case 0x2: 331 - prot = PAGE_READ | PAGE_WRITE; 341 + prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 332 342 break; 333 343 } 334 344 } 335 345 336 - /* No execute if either noexec or guarded bits set */ 337 - if (!(pte.pte1 & HPTE64_R_N) || (pte.pte1 & HPTE64_R_G) 338 - || (slb->vsid & SLB_VSID_N)) { 339 - prot |= PAGE_EXEC; 340 - } 346 + return prot; 347 + } 348 + 349 + /* Check the instruction access permissions specified in the IAMR */ 350 + static int ppc_hash64_iamr_prot(PowerPCCPU *cpu, int key) 351 + { 352 + CPUPPCState *env = &cpu->env; 353 + int iamr_bits = (env->spr[SPR_IAMR] >> 2 * (31 - key)) & 0x3; 341 354 342 - return prot; 355 + /* 356 + * An instruction fetch is permitted if the IAMR bit is 0. 357 + * If the bit is set, return PAGE_READ | PAGE_WRITE because this bit 358 + * can only take away EXEC permissions not READ or WRITE permissions. 359 + * If bit is cleared return PAGE_READ | PAGE_WRITE | PAGE_EXEC since 360 + * EXEC permissions are allowed. 361 + */ 362 + return (iamr_bits & 0x1) ? PAGE_READ | PAGE_WRITE : 363 + PAGE_READ | PAGE_WRITE | PAGE_EXEC; 343 364 } 344 365 345 366 static int ppc_hash64_amr_prot(PowerPCCPU *cpu, ppc_hash_pte64_t pte) ··· 372 393 */ 373 394 if (amrbits & 0x1) { 374 395 prot &= ~PAGE_READ; 396 + } 397 + 398 + switch (env->mmu_model) { 399 + /* 400 + * MMU version 2.07 and later support IAMR 401 + * Check if the IAMR allows the instruction access - it will return 402 + * PAGE_EXEC if it doesn't (and thus that bit will be cleared) or 0 403 + * if it does (and prot will be unchanged indicating execution support). 404 + */ 405 + case POWERPC_MMU_2_07: 406 + case POWERPC_MMU_3_00: 407 + prot &= ppc_hash64_iamr_prot(cpu, key); 408 + break; 409 + default: 410 + break; 375 411 } 376 412 377 413 return prot; ··· 664 700 unsigned apshift; 665 701 hwaddr ptex; 666 702 ppc_hash_pte64_t pte; 667 - int pp_prot, amr_prot, prot; 668 - uint64_t new_pte1, dsisr; 703 + int exec_prot, pp_prot, amr_prot, prot; 704 + uint64_t new_pte1; 669 705 const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC}; 670 706 hwaddr raddr; 671 707 ··· 706 742 } else { 707 743 /* The access failed, generate the approriate interrupt */ 708 744 if (rwx == 2) { 709 - ppc_hash64_set_isi(cs, env, 0x08000000); 745 + ppc_hash64_set_isi(cs, env, SRR1_PROTFAULT); 710 746 } else { 711 - dsisr = 0x08000000; 747 + int dsisr = DSISR_PROTFAULT; 712 748 if (rwx == 1) { 713 - dsisr |= 0x02000000; 749 + dsisr |= DSISR_ISSTORE; 714 750 } 715 751 ppc_hash64_set_dsi(cs, env, eaddr, dsisr); 716 752 } ··· 726 762 /* 2. Translation is on, so look up the SLB */ 727 763 slb = slb_lookup(cpu, eaddr); 728 764 if (!slb) { 765 + /* No entry found, check if in-memory segment tables are in use */ 766 + if ((env->mmu_model & POWERPC_MMU_V3) && ppc64_use_proc_tbl(cpu)) { 767 + /* TODO - Unsupported */ 768 + error_report("Segment Table Support Unimplemented"); 769 + exit(1); 770 + } 771 + /* Segment still not found, generate the appropriate interrupt */ 729 772 if (rwx == 2) { 730 773 cs->exception_index = POWERPC_EXCP_ISEG; 731 774 env->error_code = 0; ··· 741 784 742 785 /* 3. Check for segment level no-execute violation */ 743 786 if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) { 744 - ppc_hash64_set_isi(cs, env, 0x10000000); 787 + ppc_hash64_set_isi(cs, env, SRR1_NOEXEC_GUARD); 745 788 return 1; 746 789 } 747 790 748 791 /* 4. Locate the PTE in the hash table */ 749 792 ptex = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte, &apshift); 750 793 if (ptex == -1) { 751 - dsisr = 0x40000000; 752 794 if (rwx == 2) { 753 - ppc_hash64_set_isi(cs, env, dsisr); 795 + ppc_hash64_set_isi(cs, env, SRR1_NOPTE); 754 796 } else { 797 + int dsisr = DSISR_NOPTE; 755 798 if (rwx == 1) { 756 - dsisr |= 0x02000000; 799 + dsisr |= DSISR_ISSTORE; 757 800 } 758 801 ppc_hash64_set_dsi(cs, env, eaddr, dsisr); 759 802 } ··· 764 807 765 808 /* 5. Check access permissions */ 766 809 810 + exec_prot = ppc_hash64_pte_noexec_guard(cpu, pte); 767 811 pp_prot = ppc_hash64_pte_prot(cpu, slb, pte); 768 812 amr_prot = ppc_hash64_amr_prot(cpu, pte); 769 - prot = pp_prot & amr_prot; 813 + prot = exec_prot & pp_prot & amr_prot; 770 814 771 815 if ((need_prot[rwx] & ~prot) != 0) { 772 816 /* Access right violation */ 773 817 qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n"); 774 818 if (rwx == 2) { 775 - ppc_hash64_set_isi(cs, env, 0x08000000); 819 + int srr1 = 0; 820 + if (PAGE_EXEC & ~exec_prot) { 821 + srr1 |= SRR1_NOEXEC_GUARD; /* Access violates noexec or guard */ 822 + } else if (PAGE_EXEC & ~pp_prot) { 823 + srr1 |= SRR1_PROTFAULT; /* Access violates access authority */ 824 + } 825 + if (PAGE_EXEC & ~amr_prot) { 826 + srr1 |= SRR1_IAMR; /* Access violates virt pg class key prot */ 827 + } 828 + ppc_hash64_set_isi(cs, env, srr1); 776 829 } else { 777 - dsisr = 0; 830 + int dsisr = 0; 778 831 if (need_prot[rwx] & ~pp_prot) { 779 - dsisr |= 0x08000000; 832 + dsisr |= DSISR_PROTFAULT; 780 833 } 781 834 if (rwx == 1) { 782 - dsisr |= 0x02000000; 835 + dsisr |= DSISR_ISSTORE; 783 836 } 784 837 if (need_prot[rwx] & ~amr_prot) { 785 - dsisr |= 0x00200000; 838 + dsisr |= DSISR_AMR; 786 839 } 787 840 ppc_hash64_set_dsi(cs, env, eaddr, dsisr); 788 841 } ··· 979 1032 uint64_t lpcr = 0; 980 1033 981 1034 /* Filter out bits */ 982 - switch (env->mmu_model) { 983 - case POWERPC_MMU_64B: /* 970 */ 1035 + switch (POWERPC_MMU_VER(env->mmu_model)) { 1036 + case POWERPC_MMU_VER_64B: /* 970 */ 984 1037 if (val & 0x40) { 985 1038 lpcr |= LPCR_LPES0; 986 1039 } ··· 1006 1059 * to dig HRMOR out of HID5 1007 1060 */ 1008 1061 break; 1009 - case POWERPC_MMU_2_03: /* P5p */ 1062 + case POWERPC_MMU_VER_2_03: /* P5p */ 1010 1063 lpcr = val & (LPCR_RMLS | LPCR_ILE | 1011 1064 LPCR_LPES0 | LPCR_LPES1 | 1012 1065 LPCR_RMI | LPCR_HDICE); 1013 1066 break; 1014 - case POWERPC_MMU_2_06: /* P7 */ 1067 + case POWERPC_MMU_VER_2_06: /* P7 */ 1015 1068 lpcr = val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD | 1016 1069 LPCR_VRMASD | LPCR_RMLS | LPCR_ILE | 1017 1070 LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 | 1018 1071 LPCR_MER | LPCR_TC | 1019 1072 LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE); 1020 1073 break; 1021 - case POWERPC_MMU_2_07: /* P8 */ 1074 + case POWERPC_MMU_VER_2_07: /* P8 */ 1022 1075 lpcr = val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV | 1023 1076 LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE | 1024 1077 LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 | 1025 1078 LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 | 1026 1079 LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE); 1027 1080 break; 1028 - case POWERPC_MMU_3_00: /* P9 */ 1081 + case POWERPC_MMU_VER_3_00: /* P9 */ 1029 1082 lpcr = val & (LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD | 1030 1083 (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL | 1031 1084 LPCR_UPRT | LPCR_EVIRT | LPCR_ONL |
+42 -40
target/ppc/mmu_helper.c
··· 29 29 #include "exec/log.h" 30 30 #include "helper_regs.h" 31 31 #include "qemu/error-report.h" 32 + #include "mmu-book3s-v3.h" 32 33 33 34 //#define DEBUG_MMU 34 35 //#define DEBUG_BATS ··· 1265 1266 1266 1267 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env) 1267 1268 { 1268 - switch (env->mmu_model) { 1269 + switch (POWERPC_MMU_VER(env->mmu_model)) { 1269 1270 case POWERPC_MMU_BOOKE: 1270 1271 mmubooke_dump_mmu(f, cpu_fprintf, env); 1271 1272 break; ··· 1277 1278 mmu6xx_dump_mmu(f, cpu_fprintf, env); 1278 1279 break; 1279 1280 #if defined(TARGET_PPC64) 1280 - case POWERPC_MMU_64B: 1281 - case POWERPC_MMU_2_03: 1282 - case POWERPC_MMU_2_06: 1283 - case POWERPC_MMU_2_06a: 1284 - case POWERPC_MMU_2_07: 1285 - case POWERPC_MMU_2_07a: 1281 + case POWERPC_MMU_VER_64B: 1282 + case POWERPC_MMU_VER_2_03: 1283 + case POWERPC_MMU_VER_2_06: 1284 + case POWERPC_MMU_VER_2_07: 1286 1285 dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env)); 1287 1286 break; 1287 + case POWERPC_MMU_VER_3_00: 1288 + if (ppc64_radix_guest(ppc_env_get_cpu(env))) { 1289 + /* TODO - Unsupported */ 1290 + } else { 1291 + dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env)); 1292 + break; 1293 + } 1288 1294 #endif 1289 1295 default: 1290 1296 qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__); ··· 1417 1423 CPUPPCState *env = &cpu->env; 1418 1424 mmu_ctx_t ctx; 1419 1425 1420 - switch (env->mmu_model) { 1426 + switch (POWERPC_MMU_VER(env->mmu_model)) { 1421 1427 #if defined(TARGET_PPC64) 1422 - case POWERPC_MMU_64B: 1423 - case POWERPC_MMU_2_03: 1424 - case POWERPC_MMU_2_06: 1425 - case POWERPC_MMU_2_06a: 1426 - case POWERPC_MMU_2_07: 1427 - case POWERPC_MMU_2_07a: 1428 + case POWERPC_MMU_VER_64B: 1429 + case POWERPC_MMU_VER_2_03: 1430 + case POWERPC_MMU_VER_2_06: 1431 + case POWERPC_MMU_VER_2_07: 1428 1432 return ppc_hash64_get_phys_page_debug(cpu, addr); 1433 + case POWERPC_MMU_VER_3_00: 1434 + if (ppc64_radix_guest(ppc_env_get_cpu(env))) { 1435 + /* TODO - Unsupported */ 1436 + } else { 1437 + return ppc_hash64_get_phys_page_debug(cpu, addr); 1438 + } 1439 + break; 1429 1440 #endif 1430 1441 1431 1442 case POWERPC_MMU_32B: ··· 1909 1920 { 1910 1921 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1911 1922 1923 + #if defined(TARGET_PPC64) 1924 + if (env->mmu_model & POWERPC_MMU_64) { 1925 + env->tlb_need_flush = 0; 1926 + tlb_flush(CPU(cpu)); 1927 + } else 1928 + #endif /* defined(TARGET_PPC64) */ 1912 1929 switch (env->mmu_model) { 1913 1930 case POWERPC_MMU_SOFT_6xx: 1914 1931 case POWERPC_MMU_SOFT_74xx: ··· 1933 1950 break; 1934 1951 case POWERPC_MMU_32B: 1935 1952 case POWERPC_MMU_601: 1936 - #if defined(TARGET_PPC64) 1937 - case POWERPC_MMU_64B: 1938 - case POWERPC_MMU_2_03: 1939 - case POWERPC_MMU_2_06: 1940 - case POWERPC_MMU_2_06a: 1941 - case POWERPC_MMU_2_07: 1942 - case POWERPC_MMU_2_07a: 1943 - case POWERPC_MMU_3_00: 1944 - #endif /* defined(TARGET_PPC64) */ 1945 1953 env->tlb_need_flush = 0; 1946 1954 tlb_flush(CPU(cpu)); 1947 1955 break; 1948 1956 default: 1949 1957 /* XXX: TODO */ 1950 - cpu_abort(CPU(cpu), "Unknown MMU model %d\n", env->mmu_model); 1958 + cpu_abort(CPU(cpu), "Unknown MMU model %x\n", env->mmu_model); 1951 1959 break; 1952 1960 } 1953 1961 } ··· 1956 1964 { 1957 1965 #if !defined(FLUSH_ALL_TLBS) 1958 1966 addr &= TARGET_PAGE_MASK; 1967 + #if defined(TARGET_PPC64) 1968 + if (env->mmu_model & POWERPC_MMU_64) { 1969 + /* tlbie invalidate TLBs for all segments */ 1970 + /* XXX: given the fact that there are too many segments to invalidate, 1971 + * and we still don't have a tlb_flush_mask(env, n, mask) in QEMU, 1972 + * we just invalidate all TLBs 1973 + */ 1974 + env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH; 1975 + } else 1976 + #endif /* defined(TARGET_PPC64) */ 1959 1977 switch (env->mmu_model) { 1960 1978 case POWERPC_MMU_SOFT_6xx: 1961 1979 case POWERPC_MMU_SOFT_74xx: ··· 1973 1991 */ 1974 1992 env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH; 1975 1993 break; 1976 - #if defined(TARGET_PPC64) 1977 - case POWERPC_MMU_64B: 1978 - case POWERPC_MMU_2_03: 1979 - case POWERPC_MMU_2_06: 1980 - case POWERPC_MMU_2_06a: 1981 - case POWERPC_MMU_2_07: 1982 - case POWERPC_MMU_2_07a: 1983 - case POWERPC_MMU_3_00: 1984 - /* tlbie invalidate TLBs for all segments */ 1985 - /* XXX: given the fact that there are too many segments to invalidate, 1986 - * and we still don't have a tlb_flush_mask(env, n, mask) in QEMU, 1987 - * we just invalidate all TLBs 1988 - */ 1989 - env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH; 1990 - break; 1991 - #endif /* defined(TARGET_PPC64) */ 1992 1994 default: 1993 1995 /* Should never reach here with other MMU models */ 1994 1996 assert(0);
+10 -9
target/ppc/translate.c
··· 7078 7078 if (env->spr_cb[SPR_LPCR].name) 7079 7079 cpu_fprintf(f, " LPCR " TARGET_FMT_lx "\n", env->spr[SPR_LPCR]); 7080 7080 7081 - switch (env->mmu_model) { 7081 + switch (POWERPC_MMU_VER(env->mmu_model)) { 7082 7082 case POWERPC_MMU_32B: 7083 7083 case POWERPC_MMU_601: 7084 7084 case POWERPC_MMU_SOFT_6xx: 7085 7085 case POWERPC_MMU_SOFT_74xx: 7086 7086 #if defined(TARGET_PPC64) 7087 - case POWERPC_MMU_64B: 7088 - case POWERPC_MMU_2_03: 7089 - case POWERPC_MMU_2_06: 7090 - case POWERPC_MMU_2_06a: 7091 - case POWERPC_MMU_2_07: 7092 - case POWERPC_MMU_2_07a: 7087 + case POWERPC_MMU_VER_64B: 7088 + case POWERPC_MMU_VER_2_03: 7089 + case POWERPC_MMU_VER_2_06: 7090 + case POWERPC_MMU_VER_2_07: 7091 + case POWERPC_MMU_VER_3_00: 7093 7092 #endif 7094 - cpu_fprintf(f, " SDR1 " TARGET_FMT_lx " DAR " TARGET_FMT_lx 7095 - " DSISR " TARGET_FMT_lx "\n", env->spr[SPR_SDR1], 7093 + if (env->spr_cb[SPR_SDR1].name) { /* SDR1 Exists */ 7094 + cpu_fprintf(f, " SDR1 " TARGET_FMT_lx " ", env->spr[SPR_SDR1]); 7095 + } 7096 + cpu_fprintf(f, " DAR " TARGET_FMT_lx " DSISR " TARGET_FMT_lx "\n", 7096 7097 env->spr[SPR_DAR], env->spr[SPR_DSISR]); 7097 7098 break; 7098 7099 case POWERPC_MMU_BOOKE206:
+245 -119
target/ppc/translate_init.c
··· 32 32 #include "qapi/visitor.h" 33 33 #include "hw/qdev-properties.h" 34 34 #include "hw/ppc/ppc.h" 35 + #include "mmu-book3s-v3.h" 35 36 36 37 //#define PPC_DUMP_CPU 37 38 //#define PPC_DEBUG_SPR ··· 723 724 } 724 725 725 726 /* SPR common to all non-embedded PowerPC, including 601 */ 726 - static void gen_spr_ne_601 (CPUPPCState *env) 727 + static void gen_spr_ne_601(CPUPPCState *env) 727 728 { 728 729 /* Exception processing */ 729 730 spr_register_kvm(env, SPR_DSISR, "DSISR", ··· 739 740 SPR_NOACCESS, SPR_NOACCESS, 740 741 &spr_read_decr, &spr_write_decr, 741 742 0x00000000); 742 - /* Memory management */ 743 + } 744 + 745 + /* Storage Description Register 1 */ 746 + static void gen_spr_sdr1(CPUPPCState *env) 747 + { 743 748 #ifndef CONFIG_USER_ONLY 744 749 if (env->has_hv_mode) { 745 750 /* SDR1 is a hypervisor resource on CPUs which have a ··· 1180 1185 } 1181 1186 #endif /* CONFIG_USER_ONLY */ 1182 1187 1183 - static void gen_spr_amr(CPUPPCState *env, bool has_iamr) 1188 + static void gen_spr_amr(CPUPPCState *env) 1184 1189 { 1185 1190 #ifndef CONFIG_USER_ONLY 1186 1191 /* Virtual Page Class Key protection */ ··· 1206 1211 SPR_NOACCESS, SPR_NOACCESS, 1207 1212 &spr_read_generic, &spr_write_generic, 1208 1213 0); 1209 - if (has_iamr) { 1210 - spr_register_kvm_hv(env, SPR_IAMR, "IAMR", 1211 - SPR_NOACCESS, SPR_NOACCESS, 1212 - &spr_read_generic, &spr_write_iamr, 1213 - &spr_read_generic, &spr_write_generic, 1214 - KVM_REG_PPC_IAMR, 0); 1215 - } 1214 + #endif /* !CONFIG_USER_ONLY */ 1215 + } 1216 + 1217 + static void gen_spr_iamr(CPUPPCState *env) 1218 + { 1219 + #ifndef CONFIG_USER_ONLY 1220 + spr_register_kvm_hv(env, SPR_IAMR, "IAMR", 1221 + SPR_NOACCESS, SPR_NOACCESS, 1222 + &spr_read_generic, &spr_write_iamr, 1223 + &spr_read_generic, &spr_write_generic, 1224 + KVM_REG_PPC_IAMR, 0); 1216 1225 #endif /* !CONFIG_USER_ONLY */ 1217 1226 } 1218 1227 #endif /* TARGET_PPC64 */ ··· 4422 4431 static void init_proc_G2 (CPUPPCState *env) 4423 4432 { 4424 4433 gen_spr_ne_601(env); 4434 + gen_spr_sdr1(env); 4425 4435 gen_spr_G2_755(env); 4426 4436 gen_spr_G2(env); 4427 4437 /* Time base */ ··· 4500 4510 static void init_proc_G2LE (CPUPPCState *env) 4501 4511 { 4502 4512 gen_spr_ne_601(env); 4513 + gen_spr_sdr1(env); 4503 4514 gen_spr_G2_755(env); 4504 4515 gen_spr_G2(env); 4505 4516 /* Time base */ ··· 4735 4746 static void init_proc_e300 (CPUPPCState *env) 4736 4747 { 4737 4748 gen_spr_ne_601(env); 4749 + gen_spr_sdr1(env); 4738 4750 gen_spr_603(env); 4739 4751 /* Time base */ 4740 4752 gen_tbl(env); ··· 5234 5246 static void init_proc_601 (CPUPPCState *env) 5235 5247 { 5236 5248 gen_spr_ne_601(env); 5249 + gen_spr_sdr1(env); 5237 5250 gen_spr_601(env); 5238 5251 /* Hardware implementation registers */ 5239 5252 /* XXX : not implemented */ ··· 5348 5361 static void init_proc_602 (CPUPPCState *env) 5349 5362 { 5350 5363 gen_spr_ne_601(env); 5364 + gen_spr_sdr1(env); 5351 5365 gen_spr_602(env); 5352 5366 /* Time base */ 5353 5367 gen_tbl(env); ··· 5417 5431 static void init_proc_603 (CPUPPCState *env) 5418 5432 { 5419 5433 gen_spr_ne_601(env); 5434 + gen_spr_sdr1(env); 5420 5435 gen_spr_603(env); 5421 5436 /* Time base */ 5422 5437 gen_tbl(env); ··· 5483 5498 static void init_proc_603E (CPUPPCState *env) 5484 5499 { 5485 5500 gen_spr_ne_601(env); 5501 + gen_spr_sdr1(env); 5486 5502 gen_spr_603(env); 5487 5503 /* Time base */ 5488 5504 gen_tbl(env); ··· 5549 5565 static void init_proc_604 (CPUPPCState *env) 5550 5566 { 5551 5567 gen_spr_ne_601(env); 5568 + gen_spr_sdr1(env); 5552 5569 gen_spr_604(env); 5553 5570 /* Time base */ 5554 5571 gen_tbl(env); ··· 5612 5629 static void init_proc_604E (CPUPPCState *env) 5613 5630 { 5614 5631 gen_spr_ne_601(env); 5632 + gen_spr_sdr1(env); 5615 5633 gen_spr_604(env); 5616 5634 /* XXX : not implemented */ 5617 5635 spr_register(env, SPR_7XX_MMCR1, "MMCR1", ··· 5695 5713 static void init_proc_740 (CPUPPCState *env) 5696 5714 { 5697 5715 gen_spr_ne_601(env); 5716 + gen_spr_sdr1(env); 5698 5717 gen_spr_7xx(env); 5699 5718 /* Time base */ 5700 5719 gen_tbl(env); ··· 5765 5784 static void init_proc_750 (CPUPPCState *env) 5766 5785 { 5767 5786 gen_spr_ne_601(env); 5787 + gen_spr_sdr1(env); 5768 5788 gen_spr_7xx(env); 5769 5789 /* XXX : not implemented */ 5770 5790 spr_register(env, SPR_L2CR, "L2CR", ··· 5843 5863 static void init_proc_750cl (CPUPPCState *env) 5844 5864 { 5845 5865 gen_spr_ne_601(env); 5866 + gen_spr_sdr1(env); 5846 5867 gen_spr_7xx(env); 5847 5868 /* XXX : not implemented */ 5848 5869 spr_register(env, SPR_L2CR, "L2CR", ··· 6044 6065 static void init_proc_750cx (CPUPPCState *env) 6045 6066 { 6046 6067 gen_spr_ne_601(env); 6068 + gen_spr_sdr1(env); 6047 6069 gen_spr_7xx(env); 6048 6070 /* XXX : not implemented */ 6049 6071 spr_register(env, SPR_L2CR, "L2CR", ··· 6126 6148 static void init_proc_750fx (CPUPPCState *env) 6127 6149 { 6128 6150 gen_spr_ne_601(env); 6151 + gen_spr_sdr1(env); 6129 6152 gen_spr_7xx(env); 6130 6153 /* XXX : not implemented */ 6131 6154 spr_register(env, SPR_L2CR, "L2CR", ··· 6213 6236 static void init_proc_750gx (CPUPPCState *env) 6214 6237 { 6215 6238 gen_spr_ne_601(env); 6239 + gen_spr_sdr1(env); 6216 6240 gen_spr_7xx(env); 6217 6241 /* XXX : not implemented (XXX: different from 750fx) */ 6218 6242 spr_register(env, SPR_L2CR, "L2CR", ··· 6300 6324 static void init_proc_745 (CPUPPCState *env) 6301 6325 { 6302 6326 gen_spr_ne_601(env); 6327 + gen_spr_sdr1(env); 6303 6328 gen_spr_7xx(env); 6304 6329 gen_spr_G2_755(env); 6305 6330 /* Time base */ ··· 6375 6400 static void init_proc_755 (CPUPPCState *env) 6376 6401 { 6377 6402 gen_spr_ne_601(env); 6403 + gen_spr_sdr1(env); 6378 6404 gen_spr_7xx(env); 6379 6405 gen_spr_G2_755(env); 6380 6406 /* Time base */ ··· 6461 6487 static void init_proc_7400 (CPUPPCState *env) 6462 6488 { 6463 6489 gen_spr_ne_601(env); 6490 + gen_spr_sdr1(env); 6464 6491 gen_spr_7xx(env); 6465 6492 /* Time base */ 6466 6493 gen_tbl(env); ··· 6539 6566 static void init_proc_7410 (CPUPPCState *env) 6540 6567 { 6541 6568 gen_spr_ne_601(env); 6569 + gen_spr_sdr1(env); 6542 6570 gen_spr_7xx(env); 6543 6571 /* Time base */ 6544 6572 gen_tbl(env); ··· 6623 6651 static void init_proc_7440 (CPUPPCState *env) 6624 6652 { 6625 6653 gen_spr_ne_601(env); 6654 + gen_spr_sdr1(env); 6626 6655 gen_spr_7xx(env); 6627 6656 /* Time base */ 6628 6657 gen_tbl(env); ··· 6730 6759 static void init_proc_7450 (CPUPPCState *env) 6731 6760 { 6732 6761 gen_spr_ne_601(env); 6762 + gen_spr_sdr1(env); 6733 6763 gen_spr_7xx(env); 6734 6764 /* Time base */ 6735 6765 gen_tbl(env); ··· 6863 6893 static void init_proc_7445 (CPUPPCState *env) 6864 6894 { 6865 6895 gen_spr_ne_601(env); 6896 + gen_spr_sdr1(env); 6866 6897 gen_spr_7xx(env); 6867 6898 /* Time base */ 6868 6899 gen_tbl(env); ··· 6999 7030 static void init_proc_7455 (CPUPPCState *env) 7000 7031 { 7001 7032 gen_spr_ne_601(env); 7033 + gen_spr_sdr1(env); 7002 7034 gen_spr_7xx(env); 7003 7035 /* Time base */ 7004 7036 gen_tbl(env); ··· 7137 7169 static void init_proc_7457 (CPUPPCState *env) 7138 7170 { 7139 7171 gen_spr_ne_601(env); 7172 + gen_spr_sdr1(env); 7140 7173 gen_spr_7xx(env); 7141 7174 /* Time base */ 7142 7175 gen_tbl(env); ··· 7299 7332 static void init_proc_e600 (CPUPPCState *env) 7300 7333 { 7301 7334 gen_spr_ne_601(env); 7335 + gen_spr_sdr1(env); 7302 7336 gen_spr_7xx(env); 7303 7337 /* Time base */ 7304 7338 gen_tbl(env); ··· 7444 7478 #define POWERPC970_HID5_INIT 0x00000000 7445 7479 #endif 7446 7480 7447 - enum BOOK3S_CPU_TYPE { 7448 - BOOK3S_CPU_970, 7449 - BOOK3S_CPU_POWER5PLUS, 7450 - BOOK3S_CPU_POWER6, 7451 - BOOK3S_CPU_POWER7, 7452 - BOOK3S_CPU_POWER8, 7453 - BOOK3S_CPU_POWER9 7454 - }; 7455 - 7456 7481 static void gen_fscr_facility_check(DisasContext *ctx, int facility_sprn, 7457 7482 int bit, int sprn, int cause) 7458 7483 { ··· 7540 7565 0x00000000); 7541 7566 } 7542 7567 7543 - static void gen_spr_book3s_common(CPUPPCState *env) 7568 + static void gen_spr_book3s_ctrl(CPUPPCState *env) 7544 7569 { 7545 7570 spr_register(env, SPR_CTRL, "SPR_CTRL", 7546 7571 SPR_NOACCESS, SPR_NOACCESS, ··· 8210 8235 #endif 8211 8236 } 8212 8237 8213 - static void init_proc_book3s_64(CPUPPCState *env, int version) 8238 + static void init_proc_book3s_common(CPUPPCState *env) 8214 8239 { 8215 8240 gen_spr_ne_601(env); 8216 8241 gen_tbl(env); 8217 8242 gen_spr_book3s_altivec(env); 8218 8243 gen_spr_book3s_pmu_sup(env); 8219 8244 gen_spr_book3s_pmu_user(env); 8220 - gen_spr_book3s_common(env); 8245 + gen_spr_book3s_ctrl(env); 8246 + } 8221 8247 8222 - switch (version) { 8223 - case BOOK3S_CPU_970: 8224 - case BOOK3S_CPU_POWER5PLUS: 8225 - gen_spr_970_hid(env); 8226 - gen_spr_970_hior(env); 8227 - gen_low_BATs(env); 8228 - gen_spr_970_pmu_sup(env); 8229 - gen_spr_970_pmu_user(env); 8230 - break; 8231 - case BOOK3S_CPU_POWER7: 8232 - case BOOK3S_CPU_POWER8: 8233 - case BOOK3S_CPU_POWER9: 8234 - gen_spr_book3s_ids(env); 8235 - gen_spr_amr(env, version >= BOOK3S_CPU_POWER8); 8236 - gen_spr_book3s_purr(env); 8237 - env->ci_large_pages = true; 8238 - break; 8239 - default: 8240 - g_assert_not_reached(); 8241 - } 8242 - if (version >= BOOK3S_CPU_POWER5PLUS) { 8243 - gen_spr_power5p_common(env); 8244 - gen_spr_power5p_lpar(env); 8245 - gen_spr_power5p_ear(env); 8246 - } else { 8247 - gen_spr_970_lpar(env); 8248 - } 8249 - if (version == BOOK3S_CPU_970) { 8250 - gen_spr_970_dbg(env); 8251 - } 8252 - if (version >= BOOK3S_CPU_POWER6) { 8253 - gen_spr_power6_common(env); 8254 - gen_spr_power6_dbg(env); 8255 - } 8256 - if (version == BOOK3S_CPU_POWER7) { 8257 - gen_spr_power7_book4(env); 8258 - } 8259 - if (version >= BOOK3S_CPU_POWER8) { 8260 - gen_spr_power8_tce_address_control(env); 8261 - gen_spr_power8_ids(env); 8262 - gen_spr_power8_ebb(env); 8263 - gen_spr_power8_fscr(env); 8264 - gen_spr_power8_pmu_sup(env); 8265 - gen_spr_power8_pmu_user(env); 8266 - gen_spr_power8_tm(env); 8267 - gen_spr_power8_pspb(env); 8268 - gen_spr_vtb(env); 8269 - gen_spr_power8_ic(env); 8270 - gen_spr_power8_book4(env); 8271 - gen_spr_power8_rpr(env); 8272 - } 8273 - if (version < BOOK3S_CPU_POWER8) { 8274 - gen_spr_book3s_dbg(env); 8275 - } else { 8276 - gen_spr_book3s_207_dbg(env); 8277 - } 8248 + static void init_proc_970(CPUPPCState *env) 8249 + { 8250 + /* Common Registers */ 8251 + init_proc_book3s_common(env); 8252 + gen_spr_sdr1(env); 8253 + gen_spr_book3s_dbg(env); 8254 + 8255 + /* 970 Specific Registers */ 8256 + gen_spr_970_hid(env); 8257 + gen_spr_970_hior(env); 8258 + gen_low_BATs(env); 8259 + gen_spr_970_pmu_sup(env); 8260 + gen_spr_970_pmu_user(env); 8261 + gen_spr_970_lpar(env); 8262 + gen_spr_970_dbg(env); 8263 + 8264 + /* env variables */ 8278 8265 #if !defined(CONFIG_USER_ONLY) 8279 - switch (version) { 8280 - case BOOK3S_CPU_970: 8281 - case BOOK3S_CPU_POWER5PLUS: 8282 - env->slb_nr = 64; 8283 - break; 8284 - case BOOK3S_CPU_POWER7: 8285 - case BOOK3S_CPU_POWER8: 8286 - case BOOK3S_CPU_POWER9: 8287 - default: 8288 - env->slb_nr = 32; 8289 - break; 8290 - } 8266 + env->slb_nr = 64; 8291 8267 #endif 8292 - /* Allocate hardware IRQ controller */ 8293 - switch (version) { 8294 - case BOOK3S_CPU_970: 8295 - case BOOK3S_CPU_POWER5PLUS: 8296 - init_excp_970(env); 8297 - ppc970_irq_init(ppc_env_get_cpu(env)); 8298 - break; 8299 - case BOOK3S_CPU_POWER7: 8300 - init_excp_POWER7(env); 8301 - ppcPOWER7_irq_init(ppc_env_get_cpu(env)); 8302 - break; 8303 - case BOOK3S_CPU_POWER8: 8304 - case BOOK3S_CPU_POWER9: 8305 - init_excp_POWER8(env); 8306 - ppcPOWER7_irq_init(ppc_env_get_cpu(env)); 8307 - break; 8308 - default: 8309 - g_assert_not_reached(); 8310 - } 8311 - 8312 8268 env->dcache_line_size = 128; 8313 8269 env->icache_line_size = 128; 8314 - } 8315 8270 8316 - static void init_proc_970(CPUPPCState *env) 8317 - { 8318 - init_proc_book3s_64(env, BOOK3S_CPU_970); 8271 + /* Allocate hardware IRQ controller */ 8272 + init_excp_970(env); 8273 + ppc970_irq_init(ppc_env_get_cpu(env)); 8319 8274 } 8320 8275 8321 8276 POWERPC_FAMILY(970)(ObjectClass *oc, void *data) ··· 8367 8322 8368 8323 static void init_proc_power5plus(CPUPPCState *env) 8369 8324 { 8370 - init_proc_book3s_64(env, BOOK3S_CPU_POWER5PLUS); 8325 + /* Common Registers */ 8326 + init_proc_book3s_common(env); 8327 + gen_spr_sdr1(env); 8328 + gen_spr_book3s_dbg(env); 8329 + 8330 + /* POWER5+ Specific Registers */ 8331 + gen_spr_970_hid(env); 8332 + gen_spr_970_hior(env); 8333 + gen_low_BATs(env); 8334 + gen_spr_970_pmu_sup(env); 8335 + gen_spr_970_pmu_user(env); 8336 + gen_spr_power5p_common(env); 8337 + gen_spr_power5p_lpar(env); 8338 + gen_spr_power5p_ear(env); 8339 + 8340 + /* env variables */ 8341 + #if !defined(CONFIG_USER_ONLY) 8342 + env->slb_nr = 64; 8343 + #endif 8344 + env->dcache_line_size = 128; 8345 + env->icache_line_size = 128; 8346 + 8347 + /* Allocate hardware IRQ controller */ 8348 + init_excp_970(env); 8349 + ppc970_irq_init(ppc_env_get_cpu(env)); 8371 8350 } 8372 8351 8373 8352 POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data) ··· 8520 8499 8521 8500 static void init_proc_POWER7 (CPUPPCState *env) 8522 8501 { 8523 - init_proc_book3s_64(env, BOOK3S_CPU_POWER7); 8502 + /* Common Registers */ 8503 + init_proc_book3s_common(env); 8504 + gen_spr_sdr1(env); 8505 + gen_spr_book3s_dbg(env); 8506 + 8507 + /* POWER7 Specific Registers */ 8508 + gen_spr_book3s_ids(env); 8509 + gen_spr_amr(env); 8510 + gen_spr_book3s_purr(env); 8511 + gen_spr_power5p_common(env); 8512 + gen_spr_power5p_lpar(env); 8513 + gen_spr_power5p_ear(env); 8514 + gen_spr_power6_common(env); 8515 + gen_spr_power6_dbg(env); 8516 + gen_spr_power7_book4(env); 8517 + 8518 + /* env variables */ 8519 + #if !defined(CONFIG_USER_ONLY) 8520 + env->slb_nr = 32; 8521 + #endif 8522 + env->ci_large_pages = true; 8523 + env->dcache_line_size = 128; 8524 + env->icache_line_size = 128; 8525 + 8526 + /* Allocate hardware IRQ controller */ 8527 + init_excp_POWER7(env); 8528 + ppcPOWER7_irq_init(ppc_env_get_cpu(env)); 8524 8529 } 8525 8530 8526 8531 static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr) ··· 8636 8641 8637 8642 static void init_proc_POWER8(CPUPPCState *env) 8638 8643 { 8639 - init_proc_book3s_64(env, BOOK3S_CPU_POWER8); 8644 + /* Common Registers */ 8645 + init_proc_book3s_common(env); 8646 + gen_spr_sdr1(env); 8647 + gen_spr_book3s_207_dbg(env); 8648 + 8649 + /* POWER8 Specific Registers */ 8650 + gen_spr_book3s_ids(env); 8651 + gen_spr_amr(env); 8652 + gen_spr_iamr(env); 8653 + gen_spr_book3s_purr(env); 8654 + gen_spr_power5p_common(env); 8655 + gen_spr_power5p_lpar(env); 8656 + gen_spr_power5p_ear(env); 8657 + gen_spr_power6_common(env); 8658 + gen_spr_power6_dbg(env); 8659 + gen_spr_power8_tce_address_control(env); 8660 + gen_spr_power8_ids(env); 8661 + gen_spr_power8_ebb(env); 8662 + gen_spr_power8_fscr(env); 8663 + gen_spr_power8_pmu_sup(env); 8664 + gen_spr_power8_pmu_user(env); 8665 + gen_spr_power8_tm(env); 8666 + gen_spr_power8_pspb(env); 8667 + gen_spr_vtb(env); 8668 + gen_spr_power8_ic(env); 8669 + gen_spr_power8_book4(env); 8670 + gen_spr_power8_rpr(env); 8671 + 8672 + /* env variables */ 8673 + #if !defined(CONFIG_USER_ONLY) 8674 + env->slb_nr = 32; 8675 + #endif 8676 + env->ci_large_pages = true; 8677 + env->dcache_line_size = 128; 8678 + env->icache_line_size = 128; 8679 + 8680 + /* Allocate hardware IRQ controller */ 8681 + init_excp_POWER8(env); 8682 + ppcPOWER7_irq_init(ppc_env_get_cpu(env)); 8640 8683 } 8641 8684 8642 8685 static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr) ··· 8764 8807 pcc->l1_icache_size = 0x8000; 8765 8808 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr; 8766 8809 } 8810 + 8767 8811 static void init_proc_POWER9(CPUPPCState *env) 8768 8812 { 8769 - init_proc_book3s_64(env, BOOK3S_CPU_POWER9); 8813 + /* Common Registers */ 8814 + init_proc_book3s_common(env); 8815 + gen_spr_book3s_207_dbg(env); 8816 + 8817 + /* POWER8 Specific Registers */ 8818 + gen_spr_book3s_ids(env); 8819 + gen_spr_amr(env); 8820 + gen_spr_iamr(env); 8821 + gen_spr_book3s_purr(env); 8822 + gen_spr_power5p_common(env); 8823 + gen_spr_power5p_lpar(env); 8824 + gen_spr_power5p_ear(env); 8825 + gen_spr_power6_common(env); 8826 + gen_spr_power6_dbg(env); 8827 + gen_spr_power8_tce_address_control(env); 8828 + gen_spr_power8_ids(env); 8829 + gen_spr_power8_ebb(env); 8830 + gen_spr_power8_fscr(env); 8831 + gen_spr_power8_pmu_sup(env); 8832 + gen_spr_power8_pmu_user(env); 8833 + gen_spr_power8_tm(env); 8834 + gen_spr_power8_pspb(env); 8835 + gen_spr_vtb(env); 8836 + gen_spr_power8_ic(env); 8837 + gen_spr_power8_book4(env); 8838 + gen_spr_power8_rpr(env); 8839 + 8840 + /* env variables */ 8841 + #if !defined(CONFIG_USER_ONLY) 8842 + env->slb_nr = 32; 8843 + #endif 8844 + env->ci_large_pages = true; 8845 + env->dcache_line_size = 128; 8846 + env->icache_line_size = 128; 8847 + 8848 + /* Allocate hardware IRQ controller */ 8849 + init_excp_POWER8(env); 8850 + ppcPOWER7_irq_init(ppc_env_get_cpu(env)); 8770 8851 } 8771 8852 8772 8853 static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr) ··· 8777 8858 return false; 8778 8859 } 8779 8860 8861 + static bool cpu_has_work_POWER9(CPUState *cs) 8862 + { 8863 + PowerPCCPU *cpu = POWERPC_CPU(cs); 8864 + CPUPPCState *env = &cpu->env; 8865 + 8866 + if (cs->halted) { 8867 + if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { 8868 + return false; 8869 + } 8870 + /* External Exception */ 8871 + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && 8872 + (env->spr[SPR_LPCR] & LPCR_EEE)) { 8873 + return true; 8874 + } 8875 + /* Decrementer Exception */ 8876 + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && 8877 + (env->spr[SPR_LPCR] & LPCR_DEE)) { 8878 + return true; 8879 + } 8880 + /* Machine Check or Hypervisor Maintenance Exception */ 8881 + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK | 8882 + 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) { 8883 + return true; 8884 + } 8885 + /* Privileged Doorbell Exception */ 8886 + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) && 8887 + (env->spr[SPR_LPCR] & LPCR_PDEE)) { 8888 + return true; 8889 + } 8890 + /* Hypervisor Doorbell Exception */ 8891 + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) && 8892 + (env->spr[SPR_LPCR] & LPCR_HDEE)) { 8893 + return true; 8894 + } 8895 + if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { 8896 + return true; 8897 + } 8898 + return false; 8899 + } else { 8900 + return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD); 8901 + } 8902 + } 8903 + 8780 8904 POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) 8781 8905 { 8782 8906 DeviceClass *dc = DEVICE_CLASS(oc); 8783 8907 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); 8908 + CPUClass *cc = CPU_CLASS(oc); 8784 8909 8785 8910 dc->fw_name = "PowerPC,POWER9"; 8786 8911 dc->desc = "POWER9"; ··· 8791 8916 PCR_COMPAT_2_05; 8792 8917 pcc->init_proc = init_proc_POWER9; 8793 8918 pcc->check_pow = check_pow_nocheck; 8919 + cc->has_work = cpu_has_work_POWER9; 8794 8920 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | 8795 8921 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | 8796 8922 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | ··· 8830 8956 (1ull << MSR_LE); 8831 8957 pcc->mmu_model = POWERPC_MMU_3_00; 8832 8958 #if defined(CONFIG_SOFTMMU) 8833 - pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; 8959 + pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault; 8834 8960 /* segment page size remain the same */ 8835 8961 pcc->sps = &POWER7_POWER8_sps; 8836 8962 #endif
+1 -1
tests/boot-serial-test.c
··· 29 29 { "ppc64", "ppce500", "", "U-Boot" }, 30 30 { "ppc64", "prep", "", "Open Hack'Ware BIOS" }, 31 31 { "ppc64", "pseries", "", "Open Firmware" }, 32 - { "ppc64", "powernv", "-cpu POWER9", "SkiBoot" }, 32 + { "ppc64", "powernv", "-cpu POWER8", "SkiBoot" }, 33 33 { "i386", "isapc", "-cpu qemu32 -device sga", "SGABIOS" }, 34 34 { "i386", "pc", "-device sga", "SGABIOS" }, 35 35 { "i386", "q35", "-device sga", "SGABIOS" },
+4 -1
tests/pnv-xscom-test.c
··· 41 41 .xscom_core_base = 0x10000000ull, 42 42 .cfam_id = 0x120d304980000000ull, 43 43 .first_core = 0x1, 44 - }, { 44 + }, 45 + #if 0 /* POWER9 support is not ready yet */ 46 + { 45 47 .chip_type = PNV_CHIP_POWER9, 46 48 .cpu_model = "POWER9", 47 49 .xscom_base = 0x000603fc00000000ull, ··· 49 51 .cfam_id = 0x100d104980000000ull, 50 52 .first_core = 0x20, 51 53 }, 54 + #endif 52 55 }; 53 56 54 57 static uint64_t pnv_xscom_addr(const PnvChip *chip, uint32_t pcba)
+25
util/mmap-alloc.c
··· 40 40 return getpagesize(); 41 41 } 42 42 43 + size_t qemu_mempath_getpagesize(const char *mem_path) 44 + { 45 + #ifdef CONFIG_LINUX 46 + struct statfs fs; 47 + int ret; 48 + 49 + do { 50 + ret = statfs(mem_path, &fs); 51 + } while (ret != 0 && errno == EINTR); 52 + 53 + if (ret != 0) { 54 + fprintf(stderr, "Couldn't statfs() memory path: %s\n", 55 + strerror(errno)); 56 + exit(1); 57 + } 58 + 59 + if (fs.f_type == HUGETLBFS_MAGIC) { 60 + /* It's hugepage, return the huge page size */ 61 + return fs.f_bsize; 62 + } 63 + #endif 64 + 65 + return getpagesize(); 66 + } 67 + 43 68 void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) 44 69 { 45 70 /*