1 /*
2  * Copyright (c) 2014-2016 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 #if ARCH_HAS_MMU
11 
12 #include <arch.h>
13 #include <lk/compiler.h>
14 #include <stdbool.h>
15 #include <sys/types.h>
16 
17 /* to bring in definition of arch_aspace */
18 #include <arch/aspace.h>
19 
20 __BEGIN_CDECLS
21 
22 /* flags to pass to the arch_mmu_map and arch_mmu_query routines */
23 #define ARCH_MMU_FLAG_CACHED            (0U<<0)
24 #define ARCH_MMU_FLAG_UNCACHED          (1U<<0)
25 #define ARCH_MMU_FLAG_UNCACHED_DEVICE   (2U<<0) /* only exists on some arches, otherwise UNCACHED */
26 #define ARCH_MMU_FLAG_CACHE_MASK        (3U<<0)
27 
28 #define ARCH_MMU_FLAG_PERM_USER         (1U<<2)
29 #define ARCH_MMU_FLAG_PERM_RO           (1U<<3)
30 #define ARCH_MMU_FLAG_PERM_NO_EXECUTE   (1U<<4) /* supported on most, but not all arches */
31 #define ARCH_MMU_FLAG_NS                (1U<<5) /* supported on some arches */
32 #define ARCH_MMU_FLAG_INVALID           (1U<<6) /* indicates that flags are not specified */
33 
34 /* arch level query of some features at the mapping/query level */
35 bool arch_mmu_supports_nx_mappings(void);
36 bool arch_mmu_supports_ns_mappings(void);
37 bool arch_mmu_supports_user_aspaces(void);
38 
39 /* forward declare the per-address space arch-specific context object */
40 typedef struct arch_aspace arch_aspace_t;
41 
42 #define ARCH_ASPACE_FLAG_KERNEL         (1U<<0)
43 
44 /* initialize per address space */
45 status_t arch_mmu_init_aspace(arch_aspace_t *aspace, vaddr_t base, size_t size, uint flags) __NONNULL((1));
46 status_t arch_mmu_destroy_aspace(arch_aspace_t *aspace) __NONNULL((1));
47 
48 /* routines to map/unmap/query mappings per address space */
49 int arch_mmu_map(arch_aspace_t *aspace, vaddr_t vaddr, paddr_t paddr, uint count, uint flags) __NONNULL((1));
50 int arch_mmu_unmap(arch_aspace_t *aspace, vaddr_t vaddr, uint count) __NONNULL((1));
51 status_t arch_mmu_query(arch_aspace_t *aspace, vaddr_t vaddr, paddr_t *paddr, uint *flags) __NONNULL((1));
52 
53 vaddr_t arch_mmu_pick_spot(arch_aspace_t *aspace,
54                            vaddr_t base, uint prev_region_arch_mmu_flags,
55                            vaddr_t end,  uint next_region_arch_mmu_flags,
56                            vaddr_t align, size_t size, uint arch_mmu_flags) __NONNULL((1));
57 
58 /*
59  * load a new user address space context.
60  * aspace argument NULL should unload user space.
61  */
62 void arch_mmu_context_switch(arch_aspace_t *aspace);
63 
64 __END_CDECLS
65 
66 #endif
67 
68