1 // Copyright 2016 The Fuchsia Authors
2 // Copyright (c) 2014 Travis Geiselbrecht
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 #pragma once
9 
10 #include <arch.h>
11 #include <assert.h>
12 #include <list.h>
13 #include <stdint.h>
14 #include <stdlib.h>
15 #include <sys/types.h>
16 #include <zircon/compiler.h>
17 
18 #define PAGE_ALIGN(x) ALIGN((x), PAGE_SIZE)
19 #define ROUNDUP_PAGE_SIZE(x) ROUNDUP((x), PAGE_SIZE)
20 #define IS_PAGE_ALIGNED(x) IS_ALIGNED((x), PAGE_SIZE)
21 
22 // kernel address space
23 static_assert(KERNEL_ASPACE_BASE + (KERNEL_ASPACE_SIZE - 1) > KERNEL_ASPACE_BASE, "");
24 
is_kernel_address(vaddr_t va)25 static inline bool is_kernel_address(vaddr_t va) {
26     return (va >= (vaddr_t)KERNEL_ASPACE_BASE &&
27             va - (vaddr_t)KERNEL_ASPACE_BASE < (vaddr_t)KERNEL_ASPACE_SIZE);
28 }
29 
30 // user address space, defaults to below kernel space with a 16MB guard gap on either side
31 static_assert(USER_ASPACE_BASE + (USER_ASPACE_SIZE - 1) > USER_ASPACE_BASE, "");
32 
is_user_address(vaddr_t va)33 static inline bool is_user_address(vaddr_t va) {
34     return (va >= USER_ASPACE_BASE && va <= (USER_ASPACE_BASE + (USER_ASPACE_SIZE - 1)));
35 }
36 
is_user_address_range(vaddr_t va,size_t len)37 static inline bool is_user_address_range(vaddr_t va, size_t len) {
38     return va + len >= va &&
39            is_user_address(va) &&
40            (len == 0 || is_user_address(va + len - 1));
41 }
42 
43 // linker script provided variables for various virtual kernel addresses
44 extern char __code_start[];
45 extern char __code_end[];
46 extern char __rodata_start[];
47 extern char __rodata_end[];
48 extern char __data_start[];
49 extern char __data_end[];
50 extern char __bss_start[];
51 extern char _end[];
52 
53 // return the physical address corresponding to _start
get_kernel_base_phys(void)54 static inline paddr_t get_kernel_base_phys(void) {
55     extern paddr_t kernel_base_phys;
56 
57     return kernel_base_phys;
58 }
59 
get_kernel_size(void)60 static size_t get_kernel_size(void) {
61     return _end - __code_start;
62 }
63 
64 __BEGIN_CDECLS
65 
66 // C friendly opaque handle to the internals of the VMM.
67 // Never defined, just used as a handle for C apis.
68 typedef struct vmm_aspace vmm_aspace_t;
69 
70 // internal kernel routines below, do not call directly
71 
72 // internal routine by the scheduler to swap mmu contexts
73 void vmm_context_switch(vmm_aspace_t* oldspace, vmm_aspace_t* newaspace);
74 
75 // set the current user aspace as active on the current thread.
76 // NULL is a valid argument, which unmaps the current user address space
77 void vmm_set_active_aspace(vmm_aspace_t* aspace);
78 
79 __END_CDECLS
80