|
7 | 7 | #include <linux/ioport.h>
|
8 | 8 | #include <linux/kernel.h>
|
9 | 9 | #include <linux/string.h>
|
| 10 | +#include <linux/sizes.h> |
| 11 | +#include <linux/mm.h> |
10 | 12 |
|
11 | 13 | #define R0_START 0x0000
|
12 | 14 | #define R0_END 0xffff
|
@@ -137,9 +139,150 @@ static void resource_test_intersection(struct kunit *test)
|
137 | 139 | } while (++i < ARRAY_SIZE(results_for_intersection));
|
138 | 140 | }
|
139 | 141 |
|
| 142 | +/* |
| 143 | + * The test resource tree for region_intersects() test: |
| 144 | + * |
| 145 | + * BASE-BASE+1M-1 : Test System RAM 0 |
| 146 | + * # hole 0 (BASE+1M-BASE+2M) |
| 147 | + * BASE+2M-BASE+3M-1 : Test CXL Window 0 |
| 148 | + * BASE+3M-BASE+4M-1 : Test System RAM 1 |
| 149 | + * BASE+4M-BASE+7M-1 : Test CXL Window 1 |
| 150 | + * BASE+4M-BASE+5M-1 : Test System RAM 2 |
| 151 | + * BASE+4M+128K-BASE+4M+256K-1: Test Code |
| 152 | + * BASE+5M-BASE+6M-1 : Test System RAM 3 |
| 153 | + */ |
| 154 | +#define RES_TEST_RAM0_OFFSET 0 |
| 155 | +#define RES_TEST_RAM0_SIZE SZ_1M |
| 156 | +#define RES_TEST_HOLE0_OFFSET (RES_TEST_RAM0_OFFSET + RES_TEST_RAM0_SIZE) |
| 157 | +#define RES_TEST_HOLE0_SIZE SZ_1M |
| 158 | +#define RES_TEST_WIN0_OFFSET (RES_TEST_HOLE0_OFFSET + RES_TEST_HOLE0_SIZE) |
| 159 | +#define RES_TEST_WIN0_SIZE SZ_1M |
| 160 | +#define RES_TEST_RAM1_OFFSET (RES_TEST_WIN0_OFFSET + RES_TEST_WIN0_SIZE) |
| 161 | +#define RES_TEST_RAM1_SIZE SZ_1M |
| 162 | +#define RES_TEST_WIN1_OFFSET (RES_TEST_RAM1_OFFSET + RES_TEST_RAM1_SIZE) |
| 163 | +#define RES_TEST_WIN1_SIZE (SZ_1M * 3) |
| 164 | +#define RES_TEST_RAM2_OFFSET RES_TEST_WIN1_OFFSET |
| 165 | +#define RES_TEST_RAM2_SIZE SZ_1M |
| 166 | +#define RES_TEST_CODE_OFFSET (RES_TEST_RAM2_OFFSET + SZ_128K) |
| 167 | +#define RES_TEST_CODE_SIZE SZ_128K |
| 168 | +#define RES_TEST_RAM3_OFFSET (RES_TEST_RAM2_OFFSET + RES_TEST_RAM2_SIZE) |
| 169 | +#define RES_TEST_RAM3_SIZE SZ_1M |
| 170 | +#define RES_TEST_TOTAL_SIZE ((RES_TEST_WIN1_OFFSET + RES_TEST_WIN1_SIZE)) |
| 171 | + |
| 172 | +static void remove_free_resource(void *ctx) |
| 173 | +{ |
| 174 | + struct resource *res = (struct resource *)ctx; |
| 175 | + |
| 176 | + remove_resource(res); |
| 177 | + kfree(res); |
| 178 | +} |
| 179 | + |
| 180 | +static void resource_test_request_region(struct kunit *test, struct resource *parent, |
| 181 | + resource_size_t start, resource_size_t size, |
| 182 | + const char *name, unsigned long flags) |
| 183 | +{ |
| 184 | + struct resource *res; |
| 185 | + |
| 186 | + res = __request_region(parent, start, size, name, flags); |
| 187 | + KUNIT_ASSERT_NOT_NULL(test, res); |
| 188 | + kunit_add_action_or_reset(test, remove_free_resource, res); |
| 189 | +} |
| 190 | + |
| 191 | +static void resource_test_insert_resource(struct kunit *test, struct resource *parent, |
| 192 | + resource_size_t start, resource_size_t size, |
| 193 | + const char *name, unsigned long flags) |
| 194 | +{ |
| 195 | + struct resource *res; |
| 196 | + |
| 197 | + res = kzalloc(sizeof(*res), GFP_KERNEL); |
| 198 | + KUNIT_ASSERT_NOT_NULL(test, res); |
| 199 | + |
| 200 | + res->name = name; |
| 201 | + res->start = start; |
| 202 | + res->end = start + size - 1; |
| 203 | + res->flags = flags; |
| 204 | + if (insert_resource(parent, res)) { |
| 205 | + kfree(res); |
| 206 | + KUNIT_FAIL_AND_ABORT(test, "Fail to insert resource %pR\n", res); |
| 207 | + } |
| 208 | + |
| 209 | + kunit_add_action_or_reset(test, remove_free_resource, res); |
| 210 | +} |
| 211 | + |
| 212 | +static void resource_test_region_intersects(struct kunit *test) |
| 213 | +{ |
| 214 | + unsigned long flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; |
| 215 | + struct resource *parent; |
| 216 | + resource_size_t start; |
| 217 | + |
| 218 | + /* Find an iomem_resource hole to hold test resources */ |
| 219 | + parent = alloc_free_mem_region(&iomem_resource, RES_TEST_TOTAL_SIZE, SZ_1M, |
| 220 | + "test resources"); |
| 221 | + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent); |
| 222 | + start = parent->start; |
| 223 | + kunit_add_action_or_reset(test, remove_free_resource, parent); |
| 224 | + |
| 225 | + resource_test_request_region(test, parent, start + RES_TEST_RAM0_OFFSET, |
| 226 | + RES_TEST_RAM0_SIZE, "Test System RAM 0", flags); |
| 227 | + resource_test_insert_resource(test, parent, start + RES_TEST_WIN0_OFFSET, |
| 228 | + RES_TEST_WIN0_SIZE, "Test CXL Window 0", |
| 229 | + IORESOURCE_MEM); |
| 230 | + resource_test_request_region(test, parent, start + RES_TEST_RAM1_OFFSET, |
| 231 | + RES_TEST_RAM1_SIZE, "Test System RAM 1", flags); |
| 232 | + resource_test_insert_resource(test, parent, start + RES_TEST_WIN1_OFFSET, |
| 233 | + RES_TEST_WIN1_SIZE, "Test CXL Window 1", |
| 234 | + IORESOURCE_MEM); |
| 235 | + resource_test_request_region(test, parent, start + RES_TEST_RAM2_OFFSET, |
| 236 | + RES_TEST_RAM2_SIZE, "Test System RAM 2", flags); |
| 237 | + resource_test_insert_resource(test, parent, start + RES_TEST_CODE_OFFSET, |
| 238 | + RES_TEST_CODE_SIZE, "Test Code", flags); |
| 239 | + resource_test_request_region(test, parent, start + RES_TEST_RAM3_OFFSET, |
| 240 | + RES_TEST_RAM3_SIZE, "Test System RAM 3", flags); |
| 241 | + kunit_release_action(test, remove_free_resource, parent); |
| 242 | + |
| 243 | + KUNIT_EXPECT_EQ(test, REGION_INTERSECTS, |
| 244 | + region_intersects(start + RES_TEST_RAM0_OFFSET, PAGE_SIZE, |
| 245 | + IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)); |
| 246 | + KUNIT_EXPECT_EQ(test, REGION_INTERSECTS, |
| 247 | + region_intersects(start + RES_TEST_RAM0_OFFSET + |
| 248 | + RES_TEST_RAM0_SIZE - PAGE_SIZE, 2 * PAGE_SIZE, |
| 249 | + IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)); |
| 250 | + KUNIT_EXPECT_EQ(test, REGION_DISJOINT, |
| 251 | + region_intersects(start + RES_TEST_HOLE0_OFFSET, PAGE_SIZE, |
| 252 | + IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)); |
| 253 | + KUNIT_EXPECT_EQ(test, REGION_DISJOINT, |
| 254 | + region_intersects(start + RES_TEST_HOLE0_OFFSET + |
| 255 | + RES_TEST_HOLE0_SIZE - PAGE_SIZE, 2 * PAGE_SIZE, |
| 256 | + IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)); |
| 257 | + KUNIT_EXPECT_EQ(test, REGION_MIXED, |
| 258 | + region_intersects(start + RES_TEST_WIN0_OFFSET + |
| 259 | + RES_TEST_WIN0_SIZE - PAGE_SIZE, 2 * PAGE_SIZE, |
| 260 | + IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)); |
| 261 | + KUNIT_EXPECT_EQ(test, REGION_INTERSECTS, |
| 262 | + region_intersects(start + RES_TEST_RAM1_OFFSET + |
| 263 | + RES_TEST_RAM1_SIZE - PAGE_SIZE, 2 * PAGE_SIZE, |
| 264 | + IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)); |
| 265 | + KUNIT_EXPECT_EQ(test, REGION_INTERSECTS, |
| 266 | + region_intersects(start + RES_TEST_RAM2_OFFSET + |
| 267 | + RES_TEST_RAM2_SIZE - PAGE_SIZE, 2 * PAGE_SIZE, |
| 268 | + IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)); |
| 269 | + KUNIT_EXPECT_EQ(test, REGION_INTERSECTS, |
| 270 | + region_intersects(start + RES_TEST_CODE_OFFSET, PAGE_SIZE, |
| 271 | + IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)); |
| 272 | + KUNIT_EXPECT_EQ(test, REGION_INTERSECTS, |
| 273 | + region_intersects(start + RES_TEST_RAM2_OFFSET, |
| 274 | + RES_TEST_RAM2_SIZE + PAGE_SIZE, |
| 275 | + IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)); |
| 276 | + KUNIT_EXPECT_EQ(test, REGION_MIXED, |
| 277 | + region_intersects(start + RES_TEST_RAM3_OFFSET, |
| 278 | + RES_TEST_RAM3_SIZE + PAGE_SIZE, |
| 279 | + IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)); |
| 280 | +} |
| 281 | + |
140 | 282 | static struct kunit_case resource_test_cases[] = {
|
141 | 283 | KUNIT_CASE(resource_test_union),
|
142 | 284 | KUNIT_CASE(resource_test_intersection),
|
| 285 | + KUNIT_CASE(resource_test_region_intersects), |
143 | 286 | {}
|
144 | 287 | };
|
145 | 288 |
|
|
0 commit comments