xref: /openbmc/u-boot/test/dm/pci.c (revision 4c0411eb)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2015 Google, Inc
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <asm/io.h>
9 #include <asm/test.h>
10 #include <dm/test.h>
11 #include <test/ut.h>
12 
13 /* Test that sandbox PCI works correctly */
14 static int dm_test_pci_base(struct unit_test_state *uts)
15 {
16 	struct udevice *bus;
17 
18 	ut_assertok(uclass_get_device(UCLASS_PCI, 0, &bus));
19 
20 	return 0;
21 }
22 DM_TEST(dm_test_pci_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
23 
24 /* Test that sandbox PCI bus numbering and device works correctly */
25 static int dm_test_pci_busdev(struct unit_test_state *uts)
26 {
27 	struct udevice *bus;
28 	struct udevice *swap;
29 	u16 vendor, device;
30 
31 	/* Test bus#0 and its devices */
32 	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 0, &bus));
33 
34 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x00, 0), &swap));
35 	vendor = 0;
36 	ut_assertok(dm_pci_read_config16(swap, PCI_VENDOR_ID, &vendor));
37 	ut_asserteq(SANDBOX_PCI_VENDOR_ID, vendor);
38 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap));
39 	device = 0;
40 	ut_assertok(dm_pci_read_config16(swap, PCI_DEVICE_ID, &device));
41 	ut_asserteq(SANDBOX_PCI_DEVICE_ID, device);
42 
43 	/* Test bus#1 and its devices */
44 	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 1, &bus));
45 
46 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &swap));
47 	vendor = 0;
48 	ut_assertok(dm_pci_read_config16(swap, PCI_VENDOR_ID, &vendor));
49 	ut_asserteq(SANDBOX_PCI_VENDOR_ID, vendor);
50 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x0c, 0), &swap));
51 	device = 0;
52 	ut_assertok(dm_pci_read_config16(swap, PCI_DEVICE_ID, &device));
53 	ut_asserteq(SANDBOX_PCI_DEVICE_ID, device);
54 
55 	return 0;
56 }
57 DM_TEST(dm_test_pci_busdev, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
58 
59 /* Test that we can use the swapcase device correctly */
60 static int dm_test_pci_swapcase(struct unit_test_state *uts)
61 {
62 	struct udevice *swap;
63 	ulong io_addr, mem_addr;
64 	char *ptr;
65 
66 	/* Check that asking for the device 0 automatically fires up PCI */
67 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x00, 0), &swap));
68 
69 	/* First test I/O */
70 	io_addr = dm_pci_read_bar32(swap, 0);
71 	outb(2, io_addr);
72 	ut_asserteq(2, inb(io_addr));
73 
74 	/*
75 	 * Now test memory mapping - note we must unmap and remap to cause
76 	 * the swapcase emulation to see our data and response.
77 	 */
78 	mem_addr = dm_pci_read_bar32(swap, 1);
79 	ptr = map_sysmem(mem_addr, 20);
80 	strcpy(ptr, "This is a TesT");
81 	unmap_sysmem(ptr);
82 
83 	ptr = map_sysmem(mem_addr, 20);
84 	ut_asserteq_str("tHIS IS A tESt", ptr);
85 	unmap_sysmem(ptr);
86 
87 	/* Check that asking for the device 1 automatically fires up PCI */
88 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap));
89 
90 	/* First test I/O */
91 	io_addr = dm_pci_read_bar32(swap, 0);
92 	outb(2, io_addr);
93 	ut_asserteq(2, inb(io_addr));
94 
95 	/*
96 	 * Now test memory mapping - note we must unmap and remap to cause
97 	 * the swapcase emulation to see our data and response.
98 	 */
99 	mem_addr = dm_pci_read_bar32(swap, 1);
100 	ptr = map_sysmem(mem_addr, 20);
101 	strcpy(ptr, "This is a TesT");
102 	unmap_sysmem(ptr);
103 
104 	ptr = map_sysmem(mem_addr, 20);
105 	ut_asserteq_str("tHIS IS A tESt", ptr);
106 	unmap_sysmem(ptr);
107 
108 	return 0;
109 }
110 DM_TEST(dm_test_pci_swapcase, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
111 
112 /* Test that we can dynamically bind the device driver correctly */
113 static int dm_test_pci_drvdata(struct unit_test_state *uts)
114 {
115 	struct udevice *bus, *swap;
116 
117 	/* Check that asking for the device automatically fires up PCI */
118 	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 1, &bus));
119 
120 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &swap));
121 	ut_asserteq(SWAP_CASE_DRV_DATA, swap->driver_data);
122 	ut_assertok(dev_of_valid(swap));
123 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x0c, 0), &swap));
124 	ut_asserteq(SWAP_CASE_DRV_DATA, swap->driver_data);
125 	ut_assertok(dev_of_valid(swap));
126 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x10, 0), &swap));
127 	ut_asserteq(SWAP_CASE_DRV_DATA, swap->driver_data);
128 	ut_assertok(!dev_of_valid(swap));
129 
130 	return 0;
131 }
132 DM_TEST(dm_test_pci_drvdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
133 
134 /* Test that devices on PCI bus#2 can be accessed correctly */
135 static int dm_test_pci_mixed(struct unit_test_state *uts)
136 {
137 	/* PCI bus#2 has both statically and dynamic declared devices */
138 	struct udevice *bus, *swap;
139 	u16 vendor, device;
140 	ulong io_addr, mem_addr;
141 	char *ptr;
142 
143 	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 2, &bus));
144 
145 	/* Test the dynamic device */
146 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(2, 0x08, 0), &swap));
147 	vendor = 0;
148 	ut_assertok(dm_pci_read_config16(swap, PCI_VENDOR_ID, &vendor));
149 	ut_asserteq(SANDBOX_PCI_VENDOR_ID, vendor);
150 
151 	/* First test I/O */
152 	io_addr = dm_pci_read_bar32(swap, 0);
153 	outb(2, io_addr);
154 	ut_asserteq(2, inb(io_addr));
155 
156 	/*
157 	 * Now test memory mapping - note we must unmap and remap to cause
158 	 * the swapcase emulation to see our data and response.
159 	 */
160 	mem_addr = dm_pci_read_bar32(swap, 1);
161 	ptr = map_sysmem(mem_addr, 30);
162 	strcpy(ptr, "This is a TesT oN dYNAMIc");
163 	unmap_sysmem(ptr);
164 
165 	ptr = map_sysmem(mem_addr, 30);
166 	ut_asserteq_str("tHIS IS A tESt On DynamiC", ptr);
167 	unmap_sysmem(ptr);
168 
169 	/* Test the static device */
170 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(2, 0x1f, 0), &swap));
171 	device = 0;
172 	ut_assertok(dm_pci_read_config16(swap, PCI_DEVICE_ID, &device));
173 	ut_asserteq(SANDBOX_PCI_DEVICE_ID, device);
174 
175 	/* First test I/O */
176 	io_addr = dm_pci_read_bar32(swap, 0);
177 	outb(2, io_addr);
178 	ut_asserteq(2, inb(io_addr));
179 
180 	/*
181 	 * Now test memory mapping - note we must unmap and remap to cause
182 	 * the swapcase emulation to see our data and response.
183 	 */
184 	mem_addr = dm_pci_read_bar32(swap, 1);
185 	ptr = map_sysmem(mem_addr, 30);
186 	strcpy(ptr, "This is a TesT oN sTATIc");
187 	unmap_sysmem(ptr);
188 
189 	ptr = map_sysmem(mem_addr, 30);
190 	ut_asserteq_str("tHIS IS A tESt On StatiC", ptr);
191 	unmap_sysmem(ptr);
192 
193 	return 0;
194 }
195 DM_TEST(dm_test_pci_mixed, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
196 
197 /* Test looking up PCI capability and extended capability */
198 static int dm_test_pci_cap(struct unit_test_state *uts)
199 {
200 	struct udevice *bus, *swap;
201 	int cap;
202 
203 	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 0, &bus));
204 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap));
205 
206 	/* look up PCI_CAP_ID_EXP */
207 	cap = dm_pci_find_capability(swap, PCI_CAP_ID_EXP);
208 	ut_asserteq(PCI_CAP_ID_EXP_OFFSET, cap);
209 
210 	/* look up PCI_CAP_ID_PCIX */
211 	cap = dm_pci_find_capability(swap, PCI_CAP_ID_PCIX);
212 	ut_asserteq(0, cap);
213 
214 	/* look up PCI_CAP_ID_MSIX starting from PCI_CAP_ID_PM_OFFSET */
215 	cap = dm_pci_find_next_capability(swap, PCI_CAP_ID_PM_OFFSET,
216 					  PCI_CAP_ID_MSIX);
217 	ut_asserteq(PCI_CAP_ID_MSIX_OFFSET, cap);
218 
219 	/* look up PCI_CAP_ID_VNDR starting from PCI_CAP_ID_EXP_OFFSET */
220 	cap = dm_pci_find_next_capability(swap, PCI_CAP_ID_EXP_OFFSET,
221 					  PCI_CAP_ID_VNDR);
222 	ut_asserteq(0, cap);
223 
224 	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 1, &bus));
225 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &swap));
226 
227 	/* look up PCI_EXT_CAP_ID_DSN */
228 	cap = dm_pci_find_ext_capability(swap, PCI_EXT_CAP_ID_DSN);
229 	ut_asserteq(PCI_EXT_CAP_ID_DSN_OFFSET, cap);
230 
231 	/* look up PCI_EXT_CAP_ID_SRIOV */
232 	cap = dm_pci_find_ext_capability(swap, PCI_EXT_CAP_ID_SRIOV);
233 	ut_asserteq(0, cap);
234 
235 	/* look up PCI_EXT_CAP_ID_DSN starting from PCI_EXT_CAP_ID_ERR_OFFSET */
236 	cap = dm_pci_find_next_ext_capability(swap, PCI_EXT_CAP_ID_ERR_OFFSET,
237 					      PCI_EXT_CAP_ID_DSN);
238 	ut_asserteq(PCI_EXT_CAP_ID_DSN_OFFSET, cap);
239 
240 	/* look up PCI_EXT_CAP_ID_RCRB starting from PCI_EXT_CAP_ID_VC_OFFSET */
241 	cap = dm_pci_find_next_ext_capability(swap, PCI_EXT_CAP_ID_VC_OFFSET,
242 					      PCI_EXT_CAP_ID_RCRB);
243 	ut_asserteq(0, cap);
244 
245 	return 0;
246 }
247 DM_TEST(dm_test_pci_cap, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
248