1 /*
2 * Copyright (c) 2015 Google, Inc. All rights reserved
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8
9 #include <lib/page_alloc.h>
10
11 #include <lk/debug.h>
12 #include <assert.h>
13 #include <string.h>
14 #include <lk/trace.h>
15 #include <lk/console_cmd.h>
16 #if WITH_KERNEL_VM
17 #include <kernel/vm.h>
18 #else
19 #include <kernel/novm.h>
20 #endif
21
22 /* A simple page-aligned wrapper around the pmm or novm implementation of
23 * the underlying physical page allocator. Used by system heaps or any
24 * other user that wants pages of memory but doesn't want to use LK
25 * specific apis.
26 */
27 #define LOCAL_TRACE 0
28
29 #if WITH_STATIC_HEAP
30
31 #error "fix static heap post page allocator and novm stuff"
32
33 #if !defined(HEAP_START) || !defined(HEAP_LEN)
34 #error WITH_STATIC_HEAP set but no HEAP_START or HEAP_LEN defined
35 #endif
36
37 #endif
38
page_alloc(size_t pages,int arena)39 void *page_alloc(size_t pages, int arena) {
40 #if WITH_KERNEL_VM
41 void *result = pmm_alloc_kpages(pages, NULL);
42 return result;
43 #else
44 void *result = novm_alloc_pages(pages, arena);
45 return result;
46 #endif
47 }
48
page_free(void * ptr,size_t pages)49 void page_free(void *ptr, size_t pages) {
50 #if WITH_KERNEL_VM
51 DEBUG_ASSERT(IS_PAGE_ALIGNED((uintptr_t)ptr));
52
53 pmm_free_kpages(ptr, pages);
54 #else
55 novm_free_pages(ptr, pages);
56 #endif
57 }
58
page_get_arenas(struct page_range * ranges,int number_of_ranges)59 int page_get_arenas(struct page_range *ranges, int number_of_ranges) {
60 #if WITH_KERNEL_VM
61 ranges[0].address = kvaddr_get_range(&ranges[0].size);
62 return 1;
63 #else
64 return novm_get_arenas(ranges, number_of_ranges);
65 #endif // WITH_KERNEL_VM
66 }
67
page_first_alloc(size_t * size_return)68 void *page_first_alloc(size_t *size_return) {
69 #if WITH_KERNEL_VM
70 *size_return = PAGE_SIZE;
71 return page_alloc(1, PAGE_ALLOC_ANY_ARENA);
72 #else
73 return novm_alloc_unaligned(size_return);
74 #endif
75 }
76
77 #if LK_DEBUGLEVEL > 1
78
79 static int cmd_page_alloc(int argc, const console_cmd_args *argv);
80 static void page_alloc_dump(void);
81
82 STATIC_COMMAND_START
83 STATIC_COMMAND("page_alloc", "page allocator debug commands", &cmd_page_alloc)
84 STATIC_COMMAND_END(page_alloc);
85
cmd_page_alloc(int argc,const console_cmd_args * argv)86 static int cmd_page_alloc(int argc, const console_cmd_args *argv) {
87 if (argc != 2) {
88 notenoughargs:
89 printf("not enough arguments\n");
90 usage:
91 printf("usage:\n");
92 printf("\t%s info\n", argv[0].str);
93 return -1;
94 }
95
96 if (strcmp(argv[1].str, "info") == 0) {
97 page_alloc_dump();
98 } else {
99 printf("unrecognized command\n");
100 goto usage;
101 }
102
103 return 0;
104 }
105
page_alloc_dump(void)106 static void page_alloc_dump(void) {
107 #ifdef WITH_KERNEL_VM
108 dprintf(INFO, "Page allocator is based on pmm\n");
109 #else
110 dprintf(INFO, "Page allocator is based on novm\n");
111 #endif
112 }
113
114 #endif
115