1#include "mem/tests/test_internal.h"
2#include <mem/address_range.h>
3
4ADDRESS_RANGE_DEFINE(vas_test_map, .flags = ADDRESS_RANGE_DYNAMIC,
5 .size = PAGE_2MB, .align = PAGE_SIZE);
6
7TEST_DEFINE_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, KIB(64), 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_DEFINE_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 = vas_map(vas, phys + 37, PAGE_SIZE, .page_flags = PAGE_WRITE);
36
37 TEST_ASSERT_NONNULL(mapped);
38 vaddr_t base = (vaddr_t) mapped - 37;
39
40 TEST_ASSERT_EQ(base & (PAGE_SIZE - 1), 0);
41 TEST_ASSERT_EQ(vmm_get_phys((vaddr_t) mapped), phys + 37);
42 TEST_ASSERT(vas_vaddr_is_allocated(vas, base + 2 * PAGE_SIZE - 1));
43
44 ((uint8_t *) mapped)[PAGE_SIZE - 1] = 0x57;
45 TEST_ASSERT_EQ(((uint8_t *) hhdm_paddr_to_ptr(phys))[PAGE_SIZE + 36], 0x57);
46 vaddr_t next = vas_alloc(vas, PAGE_SIZE, PAGE_SIZE);
47
48 TEST_ASSERT_EQ(next, base + 2 * PAGE_SIZE);
49 vas_unmap(vas, vaddr: mapped, PAGE_SIZE);
50
51 TEST_ASSERT_FALSE(vas_vaddr_is_allocated(vas, base));
52 TEST_ASSERT_EQ(vmm_get_phys(base), PADDR_MAX);
53 TEST_ASSERT_EQ(vmm_get_phys(base + PAGE_SIZE), PADDR_MAX);
54 vas_free(vas, addr: next, PAGE_SIZE);
55 pmm_free_pages(addr: phys, count: 2);
56 TEST_ASSERT(vas_destroy(vas));
57
58 return TEST_SUCCESS;
59}
60