1e7324a48SNicholas Piggin /* 2e7324a48SNicholas Piggin * Test sPAPR "Per Virtual Processor Area" and H_REGISTER_VPA hypervisor call 3e7324a48SNicholas Piggin * (also known as VPA, also known as lppaca in the Linux pseries kernel). 4e7324a48SNicholas Piggin * 5e7324a48SNicholas Piggin * This work is licensed under the terms of the GNU LGPL, version 2. 6e7324a48SNicholas Piggin */ 7e7324a48SNicholas Piggin #include <libcflat.h> 8e7324a48SNicholas Piggin #include <libfdt/libfdt.h> 9e7324a48SNicholas Piggin #include <devicetree.h> 10e7324a48SNicholas Piggin #include <util.h> 11e7324a48SNicholas Piggin #include <alloc.h> 12e7324a48SNicholas Piggin #include <asm/processor.h> 13*8b10d4faSNicholas Piggin #include <asm/time.h> 14e7324a48SNicholas Piggin #include <asm/setup.h> 15e7324a48SNicholas Piggin #include <asm/hcall.h> 16e7324a48SNicholas Piggin #include <asm/vpa.h> 17e7324a48SNicholas Piggin #include <asm/io.h> /* for endian accessors */ 18e7324a48SNicholas Piggin 19e7324a48SNicholas Piggin static int verbose; 20e7324a48SNicholas Piggin 21e7324a48SNicholas Piggin static void print_vpa(struct vpa *vpa) 22e7324a48SNicholas Piggin { 23e7324a48SNicholas Piggin printf("VPA\n"); 24e7324a48SNicholas Piggin printf("descriptor: 0x%08x\n", be32_to_cpu(vpa->descriptor)); 25e7324a48SNicholas Piggin printf("size: 0x%04x\n", be16_to_cpu(vpa->size)); 26e7324a48SNicholas Piggin printf("status: 0x%02x\n", vpa->status); 27e7324a48SNicholas Piggin printf("fru_node_id: 0x%08x\n", be32_to_cpu(vpa->fru_node_id)); 28e7324a48SNicholas Piggin printf("fru_proc_id: 0x%08x\n", be32_to_cpu(vpa->fru_proc_id)); 29e7324a48SNicholas Piggin printf("vhpn_change_counters: 0x%02x %02x %02x %02x %02x %02x %02x %02x\n", vpa->vhpn_change_counters[0], vpa->vhpn_change_counters[1], vpa->vhpn_change_counters[2], vpa->vhpn_change_counters[3], vpa->vhpn_change_counters[4], vpa->vhpn_change_counters[5], vpa->vhpn_change_counters[6], vpa->vhpn_change_counters[7]); 30e7324a48SNicholas Piggin printf("vp_dispatch_count: 0x%08x\n", be32_to_cpu(vpa->vp_dispatch_count)); 31e7324a48SNicholas Piggin printf("vp_dispatch_dispersion: 0x%08x\n", be32_to_cpu(vpa->vp_dispatch_dispersion)); 32e7324a48SNicholas Piggin printf("vp_fault_count: 0x%08lx\n", be64_to_cpu(vpa->vp_fault_count)); 33e7324a48SNicholas Piggin printf("vp_fault_tb: 0x%08lx\n", be64_to_cpu(vpa->vp_fault_tb)); 34e7324a48SNicholas Piggin printf("purr_exprop_idle: 0x%08lx\n", be64_to_cpu(vpa->purr_exprop_idle)); 35e7324a48SNicholas Piggin printf("spurr_exprop_idle: 0x%08lx\n", be64_to_cpu(vpa->spurr_exprop_idle)); 36e7324a48SNicholas Piggin printf("purr_exprop_busy: 0x%08lx\n", be64_to_cpu(vpa->purr_exprop_busy)); 37e7324a48SNicholas Piggin printf("spurr_exprop_busy: 0x%08lx\n", be64_to_cpu(vpa->spurr_exprop_busy)); 38e7324a48SNicholas Piggin printf("purr_donate_idle: 0x%08lx\n", be64_to_cpu(vpa->purr_donate_idle)); 39e7324a48SNicholas Piggin printf("spurr_donate_idle: 0x%08lx\n", be64_to_cpu(vpa->spurr_donate_idle)); 40e7324a48SNicholas Piggin printf("purr_donate_busy: 0x%08lx\n", be64_to_cpu(vpa->purr_donate_busy)); 41e7324a48SNicholas Piggin printf("spurr_donate_busy: 0x%08lx\n", be64_to_cpu(vpa->spurr_donate_busy)); 42e7324a48SNicholas Piggin printf("vp_wait3_tb: 0x%08lx\n", be64_to_cpu(vpa->vp_wait3_tb)); 43e7324a48SNicholas Piggin printf("vp_wait2_tb: 0x%08lx\n", be64_to_cpu(vpa->vp_wait2_tb)); 44e7324a48SNicholas Piggin printf("vp_wait1_tb: 0x%08lx\n", be64_to_cpu(vpa->vp_wait1_tb)); 45e7324a48SNicholas Piggin printf("purr_exprop_adjunct_busy: 0x%08lx\n", be64_to_cpu(vpa->purr_exprop_adjunct_busy)); 46e7324a48SNicholas Piggin printf("spurr_exprop_adjunct_busy: 0x%08lx\n", be64_to_cpu(vpa->spurr_exprop_adjunct_busy)); 47e7324a48SNicholas Piggin printf("purr_exprop_adjunct_idle: 0x%08lx\n", be64_to_cpu(vpa->purr_exprop_adjunct_idle)); 48e7324a48SNicholas Piggin printf("spurr_exprop_adjunct_idle: 0x%08lx\n", be64_to_cpu(vpa->spurr_exprop_adjunct_idle)); 49e7324a48SNicholas Piggin printf("adjunct_insns_executed: 0x%08lx\n", be64_to_cpu(vpa->adjunct_insns_executed)); 50e7324a48SNicholas Piggin printf("dtl_index: 0x%08lx\n", be64_to_cpu(vpa->dtl_index)); 51e7324a48SNicholas Piggin } 52e7324a48SNicholas Piggin 53e7324a48SNicholas Piggin #define SUBFUNC_RESERVED (0ULL << 45) 54e7324a48SNicholas Piggin #define SUBFUNC_REGISTER (1ULL << 45) 55e7324a48SNicholas Piggin #define SUBFUNC_DEREGISTER (5ULL << 45) 56e7324a48SNicholas Piggin 5762cdf7a5SNico Boehr /* 58e7324a48SNicholas Piggin * Test the H_REGISTER_VPA h-call register/deregister calls. 59e7324a48SNicholas Piggin */ 60e7324a48SNicholas Piggin static void test_register_vpa(void) 61e7324a48SNicholas Piggin { 62e7324a48SNicholas Piggin struct vpa *vpa; 63e7324a48SNicholas Piggin uint32_t cpuid = fdt_boot_cpuid_phys(dt_fdt()); 64e7324a48SNicholas Piggin int rc; 65e7324a48SNicholas Piggin 66e7324a48SNicholas Piggin report_prefix_push("H_REGISTER_VPA"); 67e7324a48SNicholas Piggin 68e7324a48SNicholas Piggin vpa = memalign(4096, sizeof(*vpa)); 69e7324a48SNicholas Piggin 70e7324a48SNicholas Piggin memset(vpa, 0, sizeof(*vpa)); 71e7324a48SNicholas Piggin 72e7324a48SNicholas Piggin vpa->size = cpu_to_be16(sizeof(*vpa)); 73e7324a48SNicholas Piggin 74e7324a48SNicholas Piggin rc = hcall(H_REGISTER_VPA, SUBFUNC_RESERVED, cpuid, vpa); 75e7324a48SNicholas Piggin report(rc == H_PARAMETER, "Reserved sub-function fails with H_PARAMETER"); 76e7324a48SNicholas Piggin 77e7324a48SNicholas Piggin rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, 0xbadbad, vpa); 78e7324a48SNicholas Piggin report(rc == H_PARAMETER, "Register with invalid proc-no fails"); 79e7324a48SNicholas Piggin 80e7324a48SNicholas Piggin rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, (void *)vpa + 8); 81e7324a48SNicholas Piggin report(rc == H_PARAMETER, "Register with VPA not cacheline aligned fails"); 82e7324a48SNicholas Piggin 83e7324a48SNicholas Piggin 84e7324a48SNicholas Piggin rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, (void *)vpa + 4096 - 128); 85e7324a48SNicholas Piggin report(rc == H_PARAMETER, "Register with VPA spanning 4096 bytes fails"); 86e7324a48SNicholas Piggin 87e7324a48SNicholas Piggin vpa->size = cpu_to_be16(632); 88e7324a48SNicholas Piggin rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, (void *)vpa); 89e7324a48SNicholas Piggin report(rc == H_PARAMETER, "Register with VPA size < 640 bytes fails"); 90e7324a48SNicholas Piggin vpa->size = cpu_to_be16(sizeof(*vpa)); 91e7324a48SNicholas Piggin 92e7324a48SNicholas Piggin rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, PHYSICAL_END); 93e7324a48SNicholas Piggin report(rc == H_PARAMETER, "Register with VPA outside guest real memory fails"); 94e7324a48SNicholas Piggin 95e7324a48SNicholas Piggin 96e7324a48SNicholas Piggin rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, vpa); 97e7324a48SNicholas Piggin report(rc == H_SUCCESS, "VPA registered"); 98e7324a48SNicholas Piggin 99e7324a48SNicholas Piggin rc = hcall(H_REGISTER_VPA, SUBFUNC_DEREGISTER, cpuid, NULL); 100e7324a48SNicholas Piggin report(rc == H_SUCCESS, "VPA deregistered"); 101e7324a48SNicholas Piggin 102e7324a48SNicholas Piggin /* 103e7324a48SNicholas Piggin * From PAPR: "note no check is made that a valid VPA registration 104e7324a48SNicholas Piggin * exists". 105e7324a48SNicholas Piggin */ 106e7324a48SNicholas Piggin rc = hcall(H_REGISTER_VPA, SUBFUNC_DEREGISTER, cpuid, NULL); 107e7324a48SNicholas Piggin report(rc == H_SUCCESS, "Deregister succeeds with no VPA registered"); 108e7324a48SNicholas Piggin 109e7324a48SNicholas Piggin rc = hcall(H_REGISTER_VPA, SUBFUNC_DEREGISTER, 0xbadbad, NULL); 110e7324a48SNicholas Piggin report(rc == H_PARAMETER, "Deregister with invalid proc-no fails"); 111e7324a48SNicholas Piggin 112e7324a48SNicholas Piggin report_prefix_pop(); 113e7324a48SNicholas Piggin } 114e7324a48SNicholas Piggin 11562cdf7a5SNico Boehr /* 116e7324a48SNicholas Piggin * Test some VPA fields. 117e7324a48SNicholas Piggin */ 118e7324a48SNicholas Piggin static void test_vpa(void) 119e7324a48SNicholas Piggin { 120e7324a48SNicholas Piggin struct vpa *vpa; 121e7324a48SNicholas Piggin uint32_t cpuid = fdt_boot_cpuid_phys(dt_fdt()); 122e7324a48SNicholas Piggin int disp_count1, disp_count2; 123e7324a48SNicholas Piggin int rc; 124e7324a48SNicholas Piggin 125e7324a48SNicholas Piggin report_prefix_push("VPA"); 126e7324a48SNicholas Piggin 127e7324a48SNicholas Piggin vpa = memalign(4096, sizeof(*vpa)); 128e7324a48SNicholas Piggin 129e7324a48SNicholas Piggin memset(vpa, 0, sizeof(*vpa)); 130e7324a48SNicholas Piggin 131e7324a48SNicholas Piggin vpa->size = cpu_to_be16(sizeof(*vpa)); 132e7324a48SNicholas Piggin 133e7324a48SNicholas Piggin rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, vpa); 134e7324a48SNicholas Piggin if (rc != H_SUCCESS) { 135e7324a48SNicholas Piggin report_skip("VPA could not be registered"); 136e7324a48SNicholas Piggin return; 137e7324a48SNicholas Piggin } 138e7324a48SNicholas Piggin 139e7324a48SNicholas Piggin if (verbose) 140e7324a48SNicholas Piggin print_vpa(vpa); 141e7324a48SNicholas Piggin 142e7324a48SNicholas Piggin disp_count1 = be32_to_cpu(vpa->vp_dispatch_count); 143e7324a48SNicholas Piggin report(disp_count1 % 2 == 0, "Dispatch count is even while running"); 144e7324a48SNicholas Piggin msleep(100); 145e7324a48SNicholas Piggin disp_count2 = be32_to_cpu(vpa->vp_dispatch_count); 146e7324a48SNicholas Piggin report(disp_count1 != disp_count2, "Dispatch count increments over H_CEDE"); 147e7324a48SNicholas Piggin 148e7324a48SNicholas Piggin rc = hcall(H_REGISTER_VPA, SUBFUNC_DEREGISTER, cpuid, vpa); 149e7324a48SNicholas Piggin if (rc != H_SUCCESS) 150e7324a48SNicholas Piggin report_fail("Could not deregister after registration"); 151e7324a48SNicholas Piggin 152e7324a48SNicholas Piggin disp_count1 = be32_to_cpu(vpa->vp_dispatch_count); 153e7324a48SNicholas Piggin report(disp_count1 % 2 == 1, "Dispatch count is odd after deregister"); 154e7324a48SNicholas Piggin 155e7324a48SNicholas Piggin report_prefix_pop(); 156e7324a48SNicholas Piggin } 157e7324a48SNicholas Piggin 158e7324a48SNicholas Piggin int main(int argc, char *argv[]) 159e7324a48SNicholas Piggin { 160e7324a48SNicholas Piggin int i; 161e7324a48SNicholas Piggin 162e7324a48SNicholas Piggin for (i = 1; i < argc; i++) { 163e7324a48SNicholas Piggin if (strcmp(argv[i], "-v") == 0) { 164e7324a48SNicholas Piggin verbose = 1; 165e7324a48SNicholas Piggin } 166e7324a48SNicholas Piggin } 167e7324a48SNicholas Piggin 168e7324a48SNicholas Piggin test_register_vpa(); 169e7324a48SNicholas Piggin 170e7324a48SNicholas Piggin test_vpa(); 171e7324a48SNicholas Piggin 172e7324a48SNicholas Piggin return report_summary(); 173e7324a48SNicholas Piggin } 174