183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2d3b7ff14SSimon Glass /* 3d3b7ff14SSimon Glass * Copyright (C) 2015 Google, Inc 4d3b7ff14SSimon Glass */ 5d3b7ff14SSimon Glass 6d3b7ff14SSimon Glass #include <common.h> 7d3b7ff14SSimon Glass #include <dm.h> 8d3b7ff14SSimon Glass #include <asm/io.h> 93839b4e8SBin Meng #include <asm/test.h> 10d3b7ff14SSimon Glass #include <dm/test.h> 11e721b882SJoe Hershberger #include <test/ut.h> 12d3b7ff14SSimon Glass 13d3b7ff14SSimon Glass /* Test that sandbox PCI works correctly */ 14e721b882SJoe Hershberger static int dm_test_pci_base(struct unit_test_state *uts) 15d3b7ff14SSimon Glass { 16d3b7ff14SSimon Glass struct udevice *bus; 17d3b7ff14SSimon Glass 18d3b7ff14SSimon Glass ut_assertok(uclass_get_device(UCLASS_PCI, 0, &bus)); 19d3b7ff14SSimon Glass 20d3b7ff14SSimon Glass return 0; 21d3b7ff14SSimon Glass } 22d3b7ff14SSimon Glass DM_TEST(dm_test_pci_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 23d3b7ff14SSimon Glass 242db7f2b7SBin Meng /* Test that sandbox PCI bus numbering and device works correctly */ 252db7f2b7SBin Meng static int dm_test_pci_busdev(struct unit_test_state *uts) 262bb02e4fSSimon Glass { 272bb02e4fSSimon Glass struct udevice *bus; 283839b4e8SBin Meng struct udevice *swap; 293839b4e8SBin Meng u16 vendor, device; 302bb02e4fSSimon Glass 31dee4d752SBin Meng /* Test bus#0 and its devices */ 322bb02e4fSSimon Glass ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 0, &bus)); 332bb02e4fSSimon Glass 342db7f2b7SBin Meng ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x00, 0), &swap)); 353839b4e8SBin Meng vendor = 0; 363839b4e8SBin Meng ut_assertok(dm_pci_read_config16(swap, PCI_VENDOR_ID, &vendor)); 373839b4e8SBin Meng ut_asserteq(SANDBOX_PCI_VENDOR_ID, vendor); 382db7f2b7SBin Meng ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap)); 393839b4e8SBin Meng device = 0; 403839b4e8SBin Meng ut_assertok(dm_pci_read_config16(swap, PCI_DEVICE_ID, &device)); 413839b4e8SBin Meng ut_asserteq(SANDBOX_PCI_DEVICE_ID, device); 422db7f2b7SBin Meng 43dee4d752SBin Meng /* Test bus#1 and its devices */ 44dee4d752SBin Meng ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 1, &bus)); 45dee4d752SBin Meng 46dee4d752SBin Meng ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &swap)); 473839b4e8SBin Meng vendor = 0; 483839b4e8SBin Meng ut_assertok(dm_pci_read_config16(swap, PCI_VENDOR_ID, &vendor)); 493839b4e8SBin Meng ut_asserteq(SANDBOX_PCI_VENDOR_ID, vendor); 50dee4d752SBin Meng ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x0c, 0), &swap)); 513839b4e8SBin Meng device = 0; 523839b4e8SBin Meng ut_assertok(dm_pci_read_config16(swap, PCI_DEVICE_ID, &device)); 533839b4e8SBin Meng ut_asserteq(SANDBOX_PCI_DEVICE_ID, device); 54dee4d752SBin Meng 552bb02e4fSSimon Glass return 0; 562bb02e4fSSimon Glass } 572db7f2b7SBin Meng DM_TEST(dm_test_pci_busdev, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 582bb02e4fSSimon Glass 59d3b7ff14SSimon Glass /* Test that we can use the swapcase device correctly */ 60e721b882SJoe Hershberger static int dm_test_pci_swapcase(struct unit_test_state *uts) 61d3b7ff14SSimon Glass { 62dd4808f9SBin Meng struct udevice *swap; 63d3b7ff14SSimon Glass ulong io_addr, mem_addr; 64d3b7ff14SSimon Glass char *ptr; 65d3b7ff14SSimon Glass 662db7f2b7SBin Meng /* Check that asking for the device 0 automatically fires up PCI */ 672db7f2b7SBin Meng ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x00, 0), &swap)); 682db7f2b7SBin Meng 692db7f2b7SBin Meng /* First test I/O */ 702db7f2b7SBin Meng io_addr = dm_pci_read_bar32(swap, 0); 712db7f2b7SBin Meng outb(2, io_addr); 722db7f2b7SBin Meng ut_asserteq(2, inb(io_addr)); 732db7f2b7SBin Meng 742db7f2b7SBin Meng /* 752db7f2b7SBin Meng * Now test memory mapping - note we must unmap and remap to cause 762db7f2b7SBin Meng * the swapcase emulation to see our data and response. 772db7f2b7SBin Meng */ 782db7f2b7SBin Meng mem_addr = dm_pci_read_bar32(swap, 1); 792db7f2b7SBin Meng ptr = map_sysmem(mem_addr, 20); 802db7f2b7SBin Meng strcpy(ptr, "This is a TesT"); 812db7f2b7SBin Meng unmap_sysmem(ptr); 822db7f2b7SBin Meng 832db7f2b7SBin Meng ptr = map_sysmem(mem_addr, 20); 842db7f2b7SBin Meng ut_asserteq_str("tHIS IS A tESt", ptr); 852db7f2b7SBin Meng unmap_sysmem(ptr); 862db7f2b7SBin Meng 872db7f2b7SBin Meng /* Check that asking for the device 1 automatically fires up PCI */ 88c0322412SSimon Glass ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap)); 89d3b7ff14SSimon Glass 90d3b7ff14SSimon Glass /* First test I/O */ 91c0322412SSimon Glass io_addr = dm_pci_read_bar32(swap, 0); 92d3b7ff14SSimon Glass outb(2, io_addr); 93d3b7ff14SSimon Glass ut_asserteq(2, inb(io_addr)); 94d3b7ff14SSimon Glass 95d3b7ff14SSimon Glass /* 96d3b7ff14SSimon Glass * Now test memory mapping - note we must unmap and remap to cause 97d3b7ff14SSimon Glass * the swapcase emulation to see our data and response. 98d3b7ff14SSimon Glass */ 99c0322412SSimon Glass mem_addr = dm_pci_read_bar32(swap, 1); 100d3b7ff14SSimon Glass ptr = map_sysmem(mem_addr, 20); 101d3b7ff14SSimon Glass strcpy(ptr, "This is a TesT"); 102d3b7ff14SSimon Glass unmap_sysmem(ptr); 103d3b7ff14SSimon Glass 104d3b7ff14SSimon Glass ptr = map_sysmem(mem_addr, 20); 105d3b7ff14SSimon Glass ut_asserteq_str("tHIS IS A tESt", ptr); 106d3b7ff14SSimon Glass unmap_sysmem(ptr); 107d3b7ff14SSimon Glass 108d3b7ff14SSimon Glass return 0; 109d3b7ff14SSimon Glass } 110d3b7ff14SSimon Glass DM_TEST(dm_test_pci_swapcase, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 11182b31043SBin Meng 11282b31043SBin Meng /* Test that we can dynamically bind the device driver correctly */ 11382b31043SBin Meng static int dm_test_pci_drvdata(struct unit_test_state *uts) 11482b31043SBin Meng { 11582b31043SBin Meng struct udevice *bus, *swap; 11682b31043SBin Meng 11782b31043SBin Meng /* Check that asking for the device automatically fires up PCI */ 11882b31043SBin Meng ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 1, &bus)); 11982b31043SBin Meng 12082b31043SBin Meng ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &swap)); 12182b31043SBin Meng ut_asserteq(SWAP_CASE_DRV_DATA, swap->driver_data); 12282b31043SBin Meng ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x0c, 0), &swap)); 12382b31043SBin Meng ut_asserteq(SWAP_CASE_DRV_DATA, swap->driver_data); 12482b31043SBin Meng 12582b31043SBin Meng return 0; 12682b31043SBin Meng } 12782b31043SBin Meng DM_TEST(dm_test_pci_drvdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 1283ed214acSBin Meng 1293ed214acSBin Meng /* Test that devices on PCI bus#2 can be accessed correctly */ 1303ed214acSBin Meng static int dm_test_pci_mixed(struct unit_test_state *uts) 1313ed214acSBin Meng { 1323ed214acSBin Meng /* PCI bus#2 has both statically and dynamic declared devices */ 1333ed214acSBin Meng struct udevice *bus, *swap; 1343ed214acSBin Meng u16 vendor, device; 1353ed214acSBin Meng ulong io_addr, mem_addr; 1363ed214acSBin Meng char *ptr; 1373ed214acSBin Meng 1383ed214acSBin Meng ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 2, &bus)); 1393ed214acSBin Meng 1403ed214acSBin Meng /* Test the dynamic device */ 1413ed214acSBin Meng ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(2, 0x08, 0), &swap)); 1423ed214acSBin Meng vendor = 0; 1433ed214acSBin Meng ut_assertok(dm_pci_read_config16(swap, PCI_VENDOR_ID, &vendor)); 1443ed214acSBin Meng ut_asserteq(SANDBOX_PCI_VENDOR_ID, vendor); 1453ed214acSBin Meng 1463ed214acSBin Meng /* First test I/O */ 1473ed214acSBin Meng io_addr = dm_pci_read_bar32(swap, 0); 1483ed214acSBin Meng outb(2, io_addr); 1493ed214acSBin Meng ut_asserteq(2, inb(io_addr)); 1503ed214acSBin Meng 1513ed214acSBin Meng /* 1523ed214acSBin Meng * Now test memory mapping - note we must unmap and remap to cause 1533ed214acSBin Meng * the swapcase emulation to see our data and response. 1543ed214acSBin Meng */ 1553ed214acSBin Meng mem_addr = dm_pci_read_bar32(swap, 1); 1563ed214acSBin Meng ptr = map_sysmem(mem_addr, 30); 1573ed214acSBin Meng strcpy(ptr, "This is a TesT oN dYNAMIc"); 1583ed214acSBin Meng unmap_sysmem(ptr); 1593ed214acSBin Meng 1603ed214acSBin Meng ptr = map_sysmem(mem_addr, 30); 1613ed214acSBin Meng ut_asserteq_str("tHIS IS A tESt On DynamiC", ptr); 1623ed214acSBin Meng unmap_sysmem(ptr); 1633ed214acSBin Meng 1643ed214acSBin Meng /* Test the static device */ 1653ed214acSBin Meng ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(2, 0x1f, 0), &swap)); 1663ed214acSBin Meng device = 0; 1673ed214acSBin Meng ut_assertok(dm_pci_read_config16(swap, PCI_DEVICE_ID, &device)); 1683ed214acSBin Meng ut_asserteq(SANDBOX_PCI_DEVICE_ID, device); 1693ed214acSBin Meng 1703ed214acSBin Meng /* First test I/O */ 1713ed214acSBin Meng io_addr = dm_pci_read_bar32(swap, 0); 1723ed214acSBin Meng outb(2, io_addr); 1733ed214acSBin Meng ut_asserteq(2, inb(io_addr)); 1743ed214acSBin Meng 1753ed214acSBin Meng /* 1763ed214acSBin Meng * Now test memory mapping - note we must unmap and remap to cause 1773ed214acSBin Meng * the swapcase emulation to see our data and response. 1783ed214acSBin Meng */ 1793ed214acSBin Meng mem_addr = dm_pci_read_bar32(swap, 1); 1803ed214acSBin Meng ptr = map_sysmem(mem_addr, 30); 1813ed214acSBin Meng strcpy(ptr, "This is a TesT oN sTATIc"); 1823ed214acSBin Meng unmap_sysmem(ptr); 1833ed214acSBin Meng 1843ed214acSBin Meng ptr = map_sysmem(mem_addr, 30); 1853ed214acSBin Meng ut_asserteq_str("tHIS IS A tESt On StatiC", ptr); 1863ed214acSBin Meng unmap_sysmem(ptr); 1873ed214acSBin Meng 1883ed214acSBin Meng return 0; 1893ed214acSBin Meng } 1903ed214acSBin Meng DM_TEST(dm_test_pci_mixed, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 191*95e11069SBin Meng 192*95e11069SBin Meng /* Test looking up PCI capability and extended capability */ 193*95e11069SBin Meng static int dm_test_pci_cap(struct unit_test_state *uts) 194*95e11069SBin Meng { 195*95e11069SBin Meng struct udevice *bus, *swap; 196*95e11069SBin Meng int cap; 197*95e11069SBin Meng 198*95e11069SBin Meng ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 0, &bus)); 199*95e11069SBin Meng ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap)); 200*95e11069SBin Meng 201*95e11069SBin Meng /* look up PCI_CAP_ID_EXP */ 202*95e11069SBin Meng cap = dm_pci_find_capability(swap, PCI_CAP_ID_EXP); 203*95e11069SBin Meng ut_asserteq(PCI_CAP_ID_EXP_OFFSET, cap); 204*95e11069SBin Meng 205*95e11069SBin Meng /* look up PCI_CAP_ID_PCIX */ 206*95e11069SBin Meng cap = dm_pci_find_capability(swap, PCI_CAP_ID_PCIX); 207*95e11069SBin Meng ut_asserteq(0, cap); 208*95e11069SBin Meng 209*95e11069SBin Meng ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 1, &bus)); 210*95e11069SBin Meng ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &swap)); 211*95e11069SBin Meng 212*95e11069SBin Meng /* look up PCI_EXT_CAP_ID_DSN */ 213*95e11069SBin Meng cap = dm_pci_find_ext_capability(swap, PCI_EXT_CAP_ID_DSN); 214*95e11069SBin Meng ut_asserteq(PCI_EXT_CAP_ID_DSN_OFFSET, cap); 215*95e11069SBin Meng 216*95e11069SBin Meng /* look up PCI_EXT_CAP_ID_SRIOV */ 217*95e11069SBin Meng cap = dm_pci_find_ext_capability(swap, PCI_EXT_CAP_ID_SRIOV); 218*95e11069SBin Meng ut_asserteq(0, cap); 219*95e11069SBin Meng 220*95e11069SBin Meng return 0; 221*95e11069SBin Meng } 222*95e11069SBin Meng DM_TEST(dm_test_pci_cap, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 223