1#include "mem/tests/test_internal.h"
2#include <mem/address_range.h>
3
4ADDRESS_RANGE_DECLARE(vas_test_map, .flags = ADDRESS_RANGE_DYNAMIC,
5 .size = PAGE_2MB, .align = PAGE_SIZE);
6
7TEST_DECLARE_SMOKE(vas, reserve_query_free) {
8 const vaddr_t base = 0x700000000000ULL;
9 struct vas *vas = vas_create(base, limit: base + PAGE_1GB);
10 TEST_ASSERT_NONNULL(vas);
11
12 size_t sizes[] = {PAGE_SIZE, 64 * 1024, PAGE_2MB};
13 vaddr_t addresses[TEST_ARRAY_LEN(sizes)];
14 for (size_t i = 0; i < TEST_ARRAY_LEN(sizes); i++) {
15 addresses[i] = vas_alloc(vas, size: sizes[i], PAGE_SIZE);
16 TEST_ASSERT_NE(addresses[i], 0);
17 TEST_ASSERT(vas_vaddr_is_allocated(vas, addresses[i]));
18 TEST_ASSERT(vas_vaddr_is_allocated(vas, addresses[i] + sizes[i] - 1));
19 }
20
21 for (size_t i = 0; i < TEST_ARRAY_LEN(sizes); i++) {
22 vas_free(vas, addr: addresses[i], size: sizes[i]);
23 TEST_ASSERT_FALSE(vas_vaddr_is_allocated(vas, addresses[i]));
24 }
25
26 TEST_ASSERT(vas_destroy(vas));
27 return TEST_SUCCESS;
28}
29
30TEST_DECLARE_SMOKE(vas, map_unaligned_physical_address) {
31 struct vas *vas = vas_from(ar: &ADDRESS_RANGE(vas_test_map));
32 TEST_ASSERT_NONNULL(vas);
33 paddr_t phys = pmm_alloc_pages(2);
34 TEST_ASSERT_NE(phys, 0);
35 void *mapped =
36 vas_map(vas, paddr: phys + 37, PAGE_SIZE, PAGE_WRITE, vflags: VMM_FLAG_NONE);
37
38 TEST_ASSERT_NONNULL(mapped);
39 vaddr_t base = (vaddr_t) mapped - 37;
40
41 TEST_ASSERT_EQ(base & (PAGE_SIZE - 1), 0);
42 TEST_ASSERT_EQ(vmm_get_phys((vaddr_t) mapped, VMM_FLAG_NONE), phys + 37);
43 TEST_ASSERT(vas_vaddr_is_allocated(vas, base + 2 * PAGE_SIZE - 1));
44
45 ((uint8_t *) mapped)[PAGE_SIZE - 1] = 0x57;
46 TEST_ASSERT_EQ(((uint8_t *) hhdm_paddr_to_ptr(phys))[PAGE_SIZE + 36], 0x57);
47 vaddr_t next = vas_alloc(vas, PAGE_SIZE, PAGE_SIZE);
48
49 TEST_ASSERT_EQ(next, base + 2 * PAGE_SIZE);
50 vas_unmap(vas, vaddr: mapped, PAGE_SIZE);
51
52 TEST_ASSERT_FALSE(vas_vaddr_is_allocated(vas, base));
53 TEST_ASSERT_EQ(vmm_get_phys(base, VMM_FLAG_NONE), PADDR_MAX);
54 TEST_ASSERT_EQ(vmm_get_phys(base + PAGE_SIZE, VMM_FLAG_NONE), PADDR_MAX);
55 vas_free(vas, addr: next, PAGE_SIZE);
56 pmm_free_pages(addr: phys, count: 2);
57 TEST_ASSERT(vas_destroy(vas));
58
59 return TEST_SUCCESS;
60}
61