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