17d36db35SAvi Kivity #include "libcflat.h" 27d36db35SAvi Kivity #include "smp.h" 3850479e3SJason Wang #include "processor.h" 47d641cc5SAvi Kivity #include "atomic.h" 5456c55bcSAndrew Jones #include "pci.h" 65292dbf7SMichael S. Tsirkin #include "x86/vm.h" 75292dbf7SMichael S. Tsirkin #include "x86/desc.h" 8a5d12b9fSPaolo Bonzini #include "x86/acpi.h" 9f22a66a1SAndrew Jones #include "x86/io.h" 107d36db35SAvi Kivity 115292dbf7SMichael S. Tsirkin struct test { 125292dbf7SMichael S. Tsirkin void (*func)(void); 135292dbf7SMichael S. Tsirkin const char *name; 145292dbf7SMichael S. Tsirkin int (*valid)(void); 155292dbf7SMichael S. Tsirkin int parallel; 165292dbf7SMichael S. Tsirkin bool (*next)(struct test *); 175292dbf7SMichael S. Tsirkin }; 185292dbf7SMichael S. Tsirkin 197d36db35SAvi Kivity #define GOAL (1ull << 30) 207d36db35SAvi Kivity 21eda71b28SAvi Kivity static int nr_cpus; 22eda71b28SAvi Kivity 23850479e3SJason Wang static void cpuid_test(void) 247d36db35SAvi Kivity { 257d36db35SAvi Kivity asm volatile ("push %%"R "bx; cpuid; pop %%"R "bx" 267d36db35SAvi Kivity : : : "eax", "ecx", "edx"); 277d36db35SAvi Kivity } 287d36db35SAvi Kivity 297d36db35SAvi Kivity static void vmcall(void) 307d36db35SAvi Kivity { 317d36db35SAvi Kivity unsigned long a = 0, b, c, d; 327d36db35SAvi Kivity 337d36db35SAvi Kivity asm volatile ("vmcall" : "+a"(a), "=b"(b), "=c"(c), "=d"(d)); 347d36db35SAvi Kivity } 357d36db35SAvi Kivity 365fecf5d8SWill Auld #define MSR_TSC_ADJUST 0x3b 377d36db35SAvi Kivity #define MSR_EFER 0xc0000080 387d36db35SAvi Kivity #define EFER_NX_MASK (1ull << 11) 397d36db35SAvi Kivity 405ada505aSJason Wang #ifdef __x86_64__ 417d36db35SAvi Kivity static void mov_from_cr8(void) 427d36db35SAvi Kivity { 437d36db35SAvi Kivity unsigned long cr8; 447d36db35SAvi Kivity 457d36db35SAvi Kivity asm volatile ("mov %%cr8, %0" : "=r"(cr8)); 467d36db35SAvi Kivity } 477d36db35SAvi Kivity 487d36db35SAvi Kivity static void mov_to_cr8(void) 497d36db35SAvi Kivity { 507d36db35SAvi Kivity unsigned long cr8 = 0; 517d36db35SAvi Kivity 527d36db35SAvi Kivity asm volatile ("mov %0, %%cr8" : : "r"(cr8)); 537d36db35SAvi Kivity } 545ada505aSJason Wang #endif 557d36db35SAvi Kivity 567d36db35SAvi Kivity static int is_smp(void) 577d36db35SAvi Kivity { 587d36db35SAvi Kivity return cpu_count() > 1; 597d36db35SAvi Kivity } 607d36db35SAvi Kivity 617d36db35SAvi Kivity static void nop(void *junk) 627d36db35SAvi Kivity { 637d36db35SAvi Kivity } 647d36db35SAvi Kivity 657d36db35SAvi Kivity static void ipi(void) 667d36db35SAvi Kivity { 677d36db35SAvi Kivity on_cpu(1, nop, 0); 687d36db35SAvi Kivity } 697d36db35SAvi Kivity 707d36db35SAvi Kivity static void ipi_halt(void) 717d36db35SAvi Kivity { 727d36db35SAvi Kivity unsigned long long t; 737d36db35SAvi Kivity 747d36db35SAvi Kivity on_cpu(1, nop, 0); 757d36db35SAvi Kivity t = rdtsc() + 2000; 767d36db35SAvi Kivity while (rdtsc() < t) 777d36db35SAvi Kivity ; 787d36db35SAvi Kivity } 797d36db35SAvi Kivity 80a5d12b9fSPaolo Bonzini int pm_tmr_blk; 817d36db35SAvi Kivity static void inl_pmtimer(void) 827d36db35SAvi Kivity { 83a5d12b9fSPaolo Bonzini inl(pm_tmr_blk); 847d36db35SAvi Kivity } 857d36db35SAvi Kivity 8600bfecaaSPaolo Bonzini static void inl_nop_qemu(void) 8700bfecaaSPaolo Bonzini { 8800bfecaaSPaolo Bonzini inl(0x1234); 8900bfecaaSPaolo Bonzini } 9000bfecaaSPaolo Bonzini 9100bfecaaSPaolo Bonzini static void inl_nop_kernel(void) 9200bfecaaSPaolo Bonzini { 9300bfecaaSPaolo Bonzini inb(0x4d0); 9400bfecaaSPaolo Bonzini } 9500bfecaaSPaolo Bonzini 9600bfecaaSPaolo Bonzini static void outl_elcr_kernel(void) 9700bfecaaSPaolo Bonzini { 98f22a66a1SAndrew Jones outb(0, 0x4d0); 9900bfecaaSPaolo Bonzini } 10000bfecaaSPaolo Bonzini 1018a544409SPaolo Bonzini static void mov_dr(void) 1028a544409SPaolo Bonzini { 1038a544409SPaolo Bonzini asm volatile("mov %0, %%dr7" : : "r" (0x400L)); 1048a544409SPaolo Bonzini } 1058a544409SPaolo Bonzini 106eda71b28SAvi Kivity static void ple_round_robin(void) 107eda71b28SAvi Kivity { 108eda71b28SAvi Kivity struct counter { 109eda71b28SAvi Kivity volatile int n1; 110eda71b28SAvi Kivity int n2; 111eda71b28SAvi Kivity } __attribute__((aligned(64))); 112eda71b28SAvi Kivity static struct counter counters[64] = { { -1, 0 } }; 113eda71b28SAvi Kivity int me = smp_id(); 114eda71b28SAvi Kivity int you; 115eda71b28SAvi Kivity volatile struct counter *p = &counters[me]; 116eda71b28SAvi Kivity 117eda71b28SAvi Kivity while (p->n1 == p->n2) 118eda71b28SAvi Kivity asm volatile ("pause"); 119eda71b28SAvi Kivity 120eda71b28SAvi Kivity p->n2 = p->n1; 121eda71b28SAvi Kivity you = me + 1; 122eda71b28SAvi Kivity if (you == nr_cpus) 123eda71b28SAvi Kivity you = 0; 124eda71b28SAvi Kivity ++counters[you].n1; 125eda71b28SAvi Kivity } 126eda71b28SAvi Kivity 1275fecf5d8SWill Auld static void rd_tsc_adjust_msr(void) 1285fecf5d8SWill Auld { 1295fecf5d8SWill Auld rdmsr(MSR_TSC_ADJUST); 1305fecf5d8SWill Auld } 1315fecf5d8SWill Auld 1325fecf5d8SWill Auld static void wr_tsc_adjust_msr(void) 1335fecf5d8SWill Auld { 1345fecf5d8SWill Auld wrmsr(MSR_TSC_ADJUST, 0x0); 1355fecf5d8SWill Auld } 1365fecf5d8SWill Auld 1375292dbf7SMichael S. Tsirkin static struct pci_test { 1385292dbf7SMichael S. Tsirkin unsigned iobar; 1395292dbf7SMichael S. Tsirkin unsigned ioport; 1405292dbf7SMichael S. Tsirkin volatile void *memaddr; 1415292dbf7SMichael S. Tsirkin volatile void *mem; 1425292dbf7SMichael S. Tsirkin int test_idx; 1435292dbf7SMichael S. Tsirkin uint32_t data; 1445292dbf7SMichael S. Tsirkin uint32_t offset; 1455292dbf7SMichael S. Tsirkin } pci_test = { 1465292dbf7SMichael S. Tsirkin .test_idx = -1 1475292dbf7SMichael S. Tsirkin }; 1485292dbf7SMichael S. Tsirkin 1495292dbf7SMichael S. Tsirkin static void pci_mem_testb(void) 1505292dbf7SMichael S. Tsirkin { 1515292dbf7SMichael S. Tsirkin *(volatile uint8_t *)pci_test.mem = pci_test.data; 1525292dbf7SMichael S. Tsirkin } 1535292dbf7SMichael S. Tsirkin 1545292dbf7SMichael S. Tsirkin static void pci_mem_testw(void) 1555292dbf7SMichael S. Tsirkin { 1565292dbf7SMichael S. Tsirkin *(volatile uint16_t *)pci_test.mem = pci_test.data; 1575292dbf7SMichael S. Tsirkin } 1585292dbf7SMichael S. Tsirkin 1595292dbf7SMichael S. Tsirkin static void pci_mem_testl(void) 1605292dbf7SMichael S. Tsirkin { 1615292dbf7SMichael S. Tsirkin *(volatile uint32_t *)pci_test.mem = pci_test.data; 1625292dbf7SMichael S. Tsirkin } 1635292dbf7SMichael S. Tsirkin 1645292dbf7SMichael S. Tsirkin static void pci_io_testb(void) 1655292dbf7SMichael S. Tsirkin { 166f22a66a1SAndrew Jones outb(pci_test.data, pci_test.ioport); 1675292dbf7SMichael S. Tsirkin } 1685292dbf7SMichael S. Tsirkin 1695292dbf7SMichael S. Tsirkin static void pci_io_testw(void) 1705292dbf7SMichael S. Tsirkin { 171f22a66a1SAndrew Jones outw(pci_test.data, pci_test.ioport); 1725292dbf7SMichael S. Tsirkin } 1735292dbf7SMichael S. Tsirkin 1745292dbf7SMichael S. Tsirkin static void pci_io_testl(void) 1755292dbf7SMichael S. Tsirkin { 176f22a66a1SAndrew Jones outl(pci_test.data, pci_test.ioport); 1775292dbf7SMichael S. Tsirkin } 1785292dbf7SMichael S. Tsirkin 1795292dbf7SMichael S. Tsirkin static uint8_t ioreadb(unsigned long addr, bool io) 1805292dbf7SMichael S. Tsirkin { 1815292dbf7SMichael S. Tsirkin if (io) { 1825292dbf7SMichael S. Tsirkin return inb(addr); 1835292dbf7SMichael S. Tsirkin } else { 1845292dbf7SMichael S. Tsirkin return *(volatile uint8_t *)addr; 1855292dbf7SMichael S. Tsirkin } 1865292dbf7SMichael S. Tsirkin } 1875292dbf7SMichael S. Tsirkin 1885292dbf7SMichael S. Tsirkin static uint32_t ioreadl(unsigned long addr, bool io) 1895292dbf7SMichael S. Tsirkin { 1905292dbf7SMichael S. Tsirkin /* Note: assumes little endian */ 1915292dbf7SMichael S. Tsirkin if (io) { 1925292dbf7SMichael S. Tsirkin return inl(addr); 1935292dbf7SMichael S. Tsirkin } else { 1945292dbf7SMichael S. Tsirkin return *(volatile uint32_t *)addr; 1955292dbf7SMichael S. Tsirkin } 1965292dbf7SMichael S. Tsirkin } 1975292dbf7SMichael S. Tsirkin 1985292dbf7SMichael S. Tsirkin static void iowriteb(unsigned long addr, uint8_t data, bool io) 1995292dbf7SMichael S. Tsirkin { 2005292dbf7SMichael S. Tsirkin if (io) { 201f22a66a1SAndrew Jones outb(data, addr); 2025292dbf7SMichael S. Tsirkin } else { 2035292dbf7SMichael S. Tsirkin *(volatile uint8_t *)addr = data; 2045292dbf7SMichael S. Tsirkin } 2055292dbf7SMichael S. Tsirkin } 2065292dbf7SMichael S. Tsirkin 2075292dbf7SMichael S. Tsirkin static bool pci_next(struct test *test, unsigned long addr, bool io) 2085292dbf7SMichael S. Tsirkin { 2095292dbf7SMichael S. Tsirkin int i; 2105292dbf7SMichael S. Tsirkin uint8_t width; 2115292dbf7SMichael S. Tsirkin 2125292dbf7SMichael S. Tsirkin if (!pci_test.memaddr) { 2135292dbf7SMichael S. Tsirkin test->func = NULL; 2145292dbf7SMichael S. Tsirkin return true; 2155292dbf7SMichael S. Tsirkin } 2165292dbf7SMichael S. Tsirkin pci_test.test_idx++; 2175292dbf7SMichael S. Tsirkin iowriteb(addr + offsetof(struct pci_test_dev_hdr, test), 2185292dbf7SMichael S. Tsirkin pci_test.test_idx, io); 2195292dbf7SMichael S. Tsirkin width = ioreadb(addr + offsetof(struct pci_test_dev_hdr, width), 2205292dbf7SMichael S. Tsirkin io); 2215292dbf7SMichael S. Tsirkin switch (width) { 2225292dbf7SMichael S. Tsirkin case 1: 2235292dbf7SMichael S. Tsirkin test->func = io ? pci_io_testb : pci_mem_testb; 2245292dbf7SMichael S. Tsirkin break; 2255292dbf7SMichael S. Tsirkin case 2: 2265292dbf7SMichael S. Tsirkin test->func = io ? pci_io_testw : pci_mem_testw; 2275292dbf7SMichael S. Tsirkin break; 2285292dbf7SMichael S. Tsirkin case 4: 2295292dbf7SMichael S. Tsirkin test->func = io ? pci_io_testl : pci_mem_testl; 2305292dbf7SMichael S. Tsirkin break; 2315292dbf7SMichael S. Tsirkin default: 2325292dbf7SMichael S. Tsirkin /* Reset index for purposes of the next test */ 2335292dbf7SMichael S. Tsirkin pci_test.test_idx = -1; 2345292dbf7SMichael S. Tsirkin test->func = NULL; 2355292dbf7SMichael S. Tsirkin return false; 2365292dbf7SMichael S. Tsirkin } 2375292dbf7SMichael S. Tsirkin pci_test.data = ioreadl(addr + offsetof(struct pci_test_dev_hdr, data), 2385292dbf7SMichael S. Tsirkin io); 2395292dbf7SMichael S. Tsirkin pci_test.offset = ioreadl(addr + offsetof(struct pci_test_dev_hdr, 2405292dbf7SMichael S. Tsirkin offset), io); 2415292dbf7SMichael S. Tsirkin for (i = 0; i < pci_test.offset; ++i) { 2425292dbf7SMichael S. Tsirkin char c = ioreadb(addr + offsetof(struct pci_test_dev_hdr, 2435292dbf7SMichael S. Tsirkin name) + i, io); 2445292dbf7SMichael S. Tsirkin if (!c) { 2455292dbf7SMichael S. Tsirkin break; 2465292dbf7SMichael S. Tsirkin } 2475292dbf7SMichael S. Tsirkin printf("%c",c); 2485292dbf7SMichael S. Tsirkin } 2495292dbf7SMichael S. Tsirkin printf(":"); 2505292dbf7SMichael S. Tsirkin return true; 2515292dbf7SMichael S. Tsirkin } 2525292dbf7SMichael S. Tsirkin 2535292dbf7SMichael S. Tsirkin static bool pci_mem_next(struct test *test) 2545292dbf7SMichael S. Tsirkin { 2555292dbf7SMichael S. Tsirkin bool ret; 2565292dbf7SMichael S. Tsirkin ret = pci_next(test, ((unsigned long)pci_test.memaddr), false); 2575292dbf7SMichael S. Tsirkin if (ret) { 2585292dbf7SMichael S. Tsirkin pci_test.mem = pci_test.memaddr + pci_test.offset; 2595292dbf7SMichael S. Tsirkin } 2605292dbf7SMichael S. Tsirkin return ret; 2615292dbf7SMichael S. Tsirkin } 2625292dbf7SMichael S. Tsirkin 2635292dbf7SMichael S. Tsirkin static bool pci_io_next(struct test *test) 2645292dbf7SMichael S. Tsirkin { 2655292dbf7SMichael S. Tsirkin bool ret; 2665292dbf7SMichael S. Tsirkin ret = pci_next(test, ((unsigned long)pci_test.iobar), true); 2675292dbf7SMichael S. Tsirkin if (ret) { 2685292dbf7SMichael S. Tsirkin pci_test.ioport = pci_test.iobar + pci_test.offset; 2695292dbf7SMichael S. Tsirkin } 2705292dbf7SMichael S. Tsirkin return ret; 2715292dbf7SMichael S. Tsirkin } 2725292dbf7SMichael S. Tsirkin 2735292dbf7SMichael S. Tsirkin static struct test tests[] = { 274850479e3SJason Wang { cpuid_test, "cpuid", .parallel = 1, }, 2757d36db35SAvi Kivity { vmcall, "vmcall", .parallel = 1, }, 2765ada505aSJason Wang #ifdef __x86_64__ 2777d36db35SAvi Kivity { mov_from_cr8, "mov_from_cr8", .parallel = 1, }, 2787d36db35SAvi Kivity { mov_to_cr8, "mov_to_cr8" , .parallel = 1, }, 2795ada505aSJason Wang #endif 2807d36db35SAvi Kivity { inl_pmtimer, "inl_from_pmtimer", .parallel = 1, }, 28100bfecaaSPaolo Bonzini { inl_nop_qemu, "inl_from_qemu", .parallel = 1 }, 28200bfecaaSPaolo Bonzini { inl_nop_kernel, "inl_from_kernel", .parallel = 1 }, 28300bfecaaSPaolo Bonzini { outl_elcr_kernel, "outl_to_kernel", .parallel = 1 }, 2848a544409SPaolo Bonzini { mov_dr, "mov_dr", .parallel = 1 }, 2857d36db35SAvi Kivity { ipi, "ipi", is_smp, .parallel = 0, }, 2867d36db35SAvi Kivity { ipi_halt, "ipi+halt", is_smp, .parallel = 0, }, 287eda71b28SAvi Kivity { ple_round_robin, "ple-round-robin", .parallel = 1 }, 2885fecf5d8SWill Auld { wr_tsc_adjust_msr, "wr_tsc_adjust_msr", .parallel = 1 }, 2895fecf5d8SWill Auld { rd_tsc_adjust_msr, "rd_tsc_adjust_msr", .parallel = 1 }, 2905292dbf7SMichael S. Tsirkin { NULL, "pci-mem", .parallel = 0, .next = pci_mem_next }, 2915292dbf7SMichael S. Tsirkin { NULL, "pci-io", .parallel = 0, .next = pci_io_next }, 2927d36db35SAvi Kivity }; 2937d36db35SAvi Kivity 2947d36db35SAvi Kivity unsigned iterations; 2957d641cc5SAvi Kivity static atomic_t nr_cpus_done; 2967d36db35SAvi Kivity 2977d36db35SAvi Kivity static void run_test(void *_func) 2987d36db35SAvi Kivity { 2997d36db35SAvi Kivity int i; 3007d36db35SAvi Kivity void (*func)(void) = _func; 3017d36db35SAvi Kivity 3027d36db35SAvi Kivity for (i = 0; i < iterations; ++i) 3037d36db35SAvi Kivity func(); 3047d36db35SAvi Kivity 3057d641cc5SAvi Kivity atomic_inc(&nr_cpus_done); 3067d36db35SAvi Kivity } 3077d36db35SAvi Kivity 3085292dbf7SMichael S. Tsirkin static bool do_test(struct test *test) 3097d36db35SAvi Kivity { 3107d36db35SAvi Kivity int i; 3117d36db35SAvi Kivity unsigned long long t1, t2; 3125292dbf7SMichael S. Tsirkin void (*func)(void); 3137d36db35SAvi Kivity 3147d36db35SAvi Kivity iterations = 32; 3157d36db35SAvi Kivity 3167d36db35SAvi Kivity if (test->valid && !test->valid()) { 3177d36db35SAvi Kivity printf("%s (skipped)\n", test->name); 3185292dbf7SMichael S. Tsirkin return false; 3195292dbf7SMichael S. Tsirkin } 3205292dbf7SMichael S. Tsirkin 3215292dbf7SMichael S. Tsirkin if (test->next && !test->next(test)) { 3225292dbf7SMichael S. Tsirkin return false; 3235292dbf7SMichael S. Tsirkin } 3245292dbf7SMichael S. Tsirkin 3255292dbf7SMichael S. Tsirkin func = test->func; 3265292dbf7SMichael S. Tsirkin if (!func) { 3275292dbf7SMichael S. Tsirkin printf("%s (skipped)\n", test->name); 3285292dbf7SMichael S. Tsirkin return false; 3297d36db35SAvi Kivity } 3307d36db35SAvi Kivity 3317d36db35SAvi Kivity do { 3327d36db35SAvi Kivity iterations *= 2; 3337d36db35SAvi Kivity t1 = rdtsc(); 3347d36db35SAvi Kivity 3357d36db35SAvi Kivity if (!test->parallel) { 3367d36db35SAvi Kivity for (i = 0; i < iterations; ++i) 3377d36db35SAvi Kivity func(); 3387d36db35SAvi Kivity } else { 3397d641cc5SAvi Kivity atomic_set(&nr_cpus_done, 0); 3407d36db35SAvi Kivity for (i = cpu_count(); i > 0; i--) 3417d36db35SAvi Kivity on_cpu_async(i-1, run_test, func); 3427d641cc5SAvi Kivity while (atomic_read(&nr_cpus_done) < cpu_count()) 3437d36db35SAvi Kivity ; 3447d36db35SAvi Kivity } 3457d36db35SAvi Kivity t2 = rdtsc(); 3467d36db35SAvi Kivity } while ((t2 - t1) < GOAL); 3477d36db35SAvi Kivity printf("%s %d\n", test->name, (int)((t2 - t1) / iterations)); 3485292dbf7SMichael S. Tsirkin return test->next; 3497d36db35SAvi Kivity } 3507d36db35SAvi Kivity 3517d36db35SAvi Kivity static void enable_nx(void *junk) 3527d36db35SAvi Kivity { 353e46b32aaSAvi Kivity if (cpuid(0x80000001).d & (1 << 20)) 3547d36db35SAvi Kivity wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NX_MASK); 3557d36db35SAvi Kivity } 3567d36db35SAvi Kivity 3570b267183SAvi Kivity bool test_wanted(struct test *test, char *wanted[], int nwanted) 3580b267183SAvi Kivity { 3590b267183SAvi Kivity int i; 3600b267183SAvi Kivity 3610b267183SAvi Kivity if (!nwanted) 3620b267183SAvi Kivity return true; 3630b267183SAvi Kivity 3640b267183SAvi Kivity for (i = 0; i < nwanted; ++i) 3650b267183SAvi Kivity if (strcmp(wanted[i], test->name) == 0) 3660b267183SAvi Kivity return true; 3670b267183SAvi Kivity 3680b267183SAvi Kivity return false; 3690b267183SAvi Kivity } 3700b267183SAvi Kivity 3710b267183SAvi Kivity int main(int ac, char **av) 3727d36db35SAvi Kivity { 373a5d12b9fSPaolo Bonzini struct fadt_descriptor_rev1 *fadt; 3747d36db35SAvi Kivity int i; 3755292dbf7SMichael S. Tsirkin unsigned long membar = 0, base, offset; 3765292dbf7SMichael S. Tsirkin void *m; 3775292dbf7SMichael S. Tsirkin pcidevaddr_t pcidev; 3787d36db35SAvi Kivity 3797d36db35SAvi Kivity smp_init(); 3805292dbf7SMichael S. Tsirkin setup_vm(); 381eda71b28SAvi Kivity nr_cpus = cpu_count(); 3827d36db35SAvi Kivity 3837d36db35SAvi Kivity for (i = cpu_count(); i > 0; i--) 3847d36db35SAvi Kivity on_cpu(i-1, enable_nx, 0); 3857d36db35SAvi Kivity 386a5d12b9fSPaolo Bonzini fadt = find_acpi_table_addr(FACP_SIGNATURE); 387a5d12b9fSPaolo Bonzini pm_tmr_blk = fadt->pm_tmr_blk; 388a5d12b9fSPaolo Bonzini printf("PM timer port is %x\n", pm_tmr_blk); 389a5d12b9fSPaolo Bonzini 390289ebf8fSAndrew Jones pcidev = pci_find_dev(PCI_VENDOR_ID_REDHAT, PCI_DEVICE_ID_REDHAT_TEST); 391*d3a8ad49SAndrew Jones if (pcidev != PCIDEVADDR_INVALID) { 392289ebf8fSAndrew Jones for (i = 0; i < PCI_TESTDEV_NUM_BARS; i++) { 3935292dbf7SMichael S. Tsirkin if (!pci_bar_is_valid(pcidev, i)) { 3945292dbf7SMichael S. Tsirkin continue; 3955292dbf7SMichael S. Tsirkin } 3965292dbf7SMichael S. Tsirkin if (pci_bar_is_memory(pcidev, i)) { 3975292dbf7SMichael S. Tsirkin membar = pci_bar_addr(pcidev, i); 3985292dbf7SMichael S. Tsirkin base = membar & ~4095; 3995292dbf7SMichael S. Tsirkin offset = membar - base; 4005292dbf7SMichael S. Tsirkin m = alloc_vpages(1); 4015292dbf7SMichael S. Tsirkin 4025292dbf7SMichael S. Tsirkin install_page((void *)read_cr3(), base, m); 4035292dbf7SMichael S. Tsirkin pci_test.memaddr = m + offset; 4045292dbf7SMichael S. Tsirkin } else { 4055292dbf7SMichael S. Tsirkin pci_test.iobar = pci_bar_addr(pcidev, i); 4065292dbf7SMichael S. Tsirkin } 4075292dbf7SMichael S. Tsirkin } 4085292dbf7SMichael S. Tsirkin printf("pci-testdev at 0x%x membar %lx iobar %x\n", 4095292dbf7SMichael S. Tsirkin pcidev, membar, pci_test.iobar); 4105292dbf7SMichael S. Tsirkin } 4115292dbf7SMichael S. Tsirkin 4127d36db35SAvi Kivity for (i = 0; i < ARRAY_SIZE(tests); ++i) 4130b267183SAvi Kivity if (test_wanted(&tests[i], av + 1, ac - 1)) 4145292dbf7SMichael S. Tsirkin while (do_test(&tests[i])) {} 4157d36db35SAvi Kivity 4167d36db35SAvi Kivity return 0; 4177d36db35SAvi Kivity } 418