From 76330ae67db88350e2938b31d72f57b13f7234d3 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Fri, 3 Aug 2018 01:14:40 -0700 Subject: pci: sandbox: swap_case: Preserve space indicator bit in BAR registers With the newly added testing of more than one device, we get: => ut dm pci_swapcase Test: dm_test_pci_swapcase: pci.c test/dm/pci.c:88, dm_test_pci_swapcase(): "tHIS IS A tESt" = ptr: Expected "tHIS IS A tESt", got "this is a test" Test: dm_test_pci_swapcase: pci.c (flat tree) test/dm/pci.c:88, dm_test_pci_swapcase(): "tHIS IS A tESt" = ptr: Expected "tHIS IS A tESt", got "this is a test" Failures: 2 The failure only happens on the 2nd swap_case device on the PCI bus. The case passes on the 1st device. It turns out the swap_case driver does not emulate bit#0 in BAR registers as a read-only bit. This corrects the implementation. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- drivers/misc/swap_case.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/misc/swap_case.c') diff --git a/drivers/misc/swap_case.c b/drivers/misc/swap_case.c index b777404c09..80ccb9f383 100644 --- a/drivers/misc/swap_case.c +++ b/drivers/misc/swap_case.c @@ -142,6 +142,8 @@ static int sandbox_swap_case_write_config(struct udevice *emul, uint offset, debug("w bar %d=%lx\n", barnum, value); *bar = value; + /* space indicator (bit#0) is read-only */ + *bar |= barinfo[barnum].type; break; } } @@ -157,11 +159,11 @@ static int sandbox_swap_case_find_bar(struct udevice *emul, unsigned int addr, for (barnum = 0; barnum < ARRAY_SIZE(barinfo); barnum++) { unsigned int size = barinfo[barnum].size; + u32 base = plat->bar[barnum] & ~PCI_BASE_ADDRESS_SPACE; - if (addr >= plat->bar[barnum] && - addr < plat->bar[barnum] + size) { + if (addr >= base && addr < base + size) { *barnump = barnum; - *offsetp = addr - plat->bar[barnum]; + *offsetp = addr - base; return 0; } } -- cgit v1.2.3 From 59a160e8b93950244155c34ec6eb11e101ce49db Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Fri, 3 Aug 2018 01:14:46 -0700 Subject: pci: sandbox: swap_case: Declare dynamic driver matching This adds a U_BOOT_PCI_DEVICE() declaration to the swap_case driver. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- arch/sandbox/include/asm/test.h | 4 ++++ drivers/misc/swap_case.c | 7 +++++++ 2 files changed, 11 insertions(+) (limited to 'drivers/misc/swap_case.c') diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 08863bf3a9..57aeca8402 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -16,6 +16,10 @@ #define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM #define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL +/* Useful for PCI_VDEVICE() macro */ +#define PCI_VENDOR_ID_SANDBOX SANDBOX_PCI_VENDOR_ID +#define SWAP_CASE_DRV_DATA 0x55aa + #define SANDBOX_CLK_RATE 32768 /* System controller driver data */ diff --git a/drivers/misc/swap_case.c b/drivers/misc/swap_case.c index 80ccb9f383..790bb0c4bd 100644 --- a/drivers/misc/swap_case.c +++ b/drivers/misc/swap_case.c @@ -285,3 +285,10 @@ U_BOOT_DRIVER(sandbox_swap_case_emul) = { .priv_auto_alloc_size = sizeof(struct swap_case_priv), .platdata_auto_alloc_size = sizeof(struct swap_case_platdata), }; + +static struct pci_device_id sandbox_swap_case_supported[] = { + { PCI_VDEVICE(SANDBOX, SANDBOX_PCI_DEVICE_ID), SWAP_CASE_DRV_DATA }, + {}, +}; + +U_BOOT_PCI_DEVICE(sandbox_swap_case_emul, sandbox_swap_case_supported); -- cgit v1.2.3 From 95e11069b5e10c38cc966a2ff9c16748d017df52 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Fri, 3 Aug 2018 01:14:53 -0700 Subject: test: dm: pci: Add cases for finding PCI capability APIs Add several PCI capability and extended capability ID registers in the swap_case driver, so that we can add test case for dm_pci_find_capability() and dm_pci_find_ext_capability(). Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- arch/sandbox/include/asm/test.h | 8 ++++++++ drivers/misc/swap_case.c | 21 +++++++++++++++++++++ test/dm/pci.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) (limited to 'drivers/misc/swap_case.c') diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 57aeca8402..c8ae52b248 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -16,6 +16,14 @@ #define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM #define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL +#define PCI_CAP_ID_PM_OFFSET 0x50 +#define PCI_CAP_ID_EXP_OFFSET 0x60 +#define PCI_CAP_ID_MSIX_OFFSET 0x70 + +#define PCI_EXT_CAP_ID_ERR_OFFSET 0x100 +#define PCI_EXT_CAP_ID_VC_OFFSET 0x200 +#define PCI_EXT_CAP_ID_DSN_OFFSET 0x300 + /* Useful for PCI_VDEVICE() macro */ #define PCI_VENDOR_ID_SANDBOX SANDBOX_PCI_VENDOR_ID #define SWAP_CASE_DRV_DATA 0x55aa diff --git a/drivers/misc/swap_case.c b/drivers/misc/swap_case.c index 790bb0c4bd..bffb809f14 100644 --- a/drivers/misc/swap_case.c +++ b/drivers/misc/swap_case.c @@ -118,6 +118,27 @@ static int sandbox_swap_case_read_config(struct udevice *emul, uint offset, *valuep = result; break; } + case PCI_CAPABILITY_LIST: + *valuep = PCI_CAP_ID_PM_OFFSET; + break; + case PCI_CAP_ID_PM_OFFSET: + *valuep = (PCI_CAP_ID_EXP_OFFSET << 8) | PCI_CAP_ID_PM; + break; + case PCI_CAP_ID_EXP_OFFSET: + *valuep = (PCI_CAP_ID_MSIX_OFFSET << 8) | PCI_CAP_ID_EXP; + break; + case PCI_CAP_ID_MSIX_OFFSET: + *valuep = PCI_CAP_ID_MSIX; + break; + case PCI_EXT_CAP_ID_ERR_OFFSET: + *valuep = (PCI_EXT_CAP_ID_VC_OFFSET << 20) | PCI_EXT_CAP_ID_ERR; + break; + case PCI_EXT_CAP_ID_VC_OFFSET: + *valuep = (PCI_EXT_CAP_ID_DSN_OFFSET << 20) | PCI_EXT_CAP_ID_VC; + break; + case PCI_EXT_CAP_ID_DSN_OFFSET: + *valuep = PCI_EXT_CAP_ID_DSN; + break; } return 0; diff --git a/test/dm/pci.c b/test/dm/pci.c index e03f6ba671..869970072d 100644 --- a/test/dm/pci.c +++ b/test/dm/pci.c @@ -188,3 +188,35 @@ static int dm_test_pci_mixed(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_pci_mixed, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test looking up PCI capability and extended capability */ +static int dm_test_pci_cap(struct unit_test_state *uts) +{ + struct udevice *bus, *swap; + int cap; + + ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 0, &bus)); + ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap)); + + /* look up PCI_CAP_ID_EXP */ + cap = dm_pci_find_capability(swap, PCI_CAP_ID_EXP); + ut_asserteq(PCI_CAP_ID_EXP_OFFSET, cap); + + /* look up PCI_CAP_ID_PCIX */ + cap = dm_pci_find_capability(swap, PCI_CAP_ID_PCIX); + ut_asserteq(0, cap); + + ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 1, &bus)); + ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &swap)); + + /* look up PCI_EXT_CAP_ID_DSN */ + cap = dm_pci_find_ext_capability(swap, PCI_EXT_CAP_ID_DSN); + ut_asserteq(PCI_EXT_CAP_ID_DSN_OFFSET, cap); + + /* look up PCI_EXT_CAP_ID_SRIOV */ + cap = dm_pci_find_ext_capability(swap, PCI_EXT_CAP_ID_SRIOV); + ut_asserteq(0, cap); + + return 0; +} +DM_TEST(dm_test_pci_cap, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -- cgit v1.2.3