1 // Copyright 2017 The Fuchsia Authors
2 //
3 // Use of this source code is governed by a MIT-style
4 // license that can be found in the LICENSE file or at
5 // https://opensource.org/licenses/MIT
6 
7 #pragma once
8 
9 #include <arch/mmu.h>
10 #include <fbl/macros.h>
11 #include <sys/types.h>
12 #include <zircon/types.h>
13 
14 // Flags
15 const uint ARCH_MMU_FLAG_CACHED = (0u << 0);
16 const uint ARCH_MMU_FLAG_UNCACHED = (1u << 0);
17 const uint ARCH_MMU_FLAG_UNCACHED_DEVICE = (2u << 0); // Only exists on some arches, otherwise UNCACHED
18 const uint ARCH_MMU_FLAG_WRITE_COMBINING = (3u << 0); // Only exists on some arches, otherwise UNCACHED
19 const uint ARCH_MMU_FLAG_CACHE_MASK = (3u << 0);
20 const uint ARCH_MMU_FLAG_PERM_USER = (1u << 2);
21 const uint ARCH_MMU_FLAG_PERM_READ = (1u << 3);
22 const uint ARCH_MMU_FLAG_PERM_WRITE = (1u << 4);
23 const uint ARCH_MMU_FLAG_PERM_EXECUTE = (1u << 5);
24 const uint ARCH_MMU_FLAG_PERM_RWX_MASK = (ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE |
25                                           ARCH_MMU_FLAG_PERM_EXECUTE);
26 const uint ARCH_MMU_FLAG_NS = (1u << 6);      // NON-SECURE
27 const uint ARCH_MMU_FLAG_INVALID = (1u << 7); // Indicates that flags are not specified
28 
29 const uint ARCH_ASPACE_FLAG_KERNEL = (1u << 0);
30 const uint ARCH_ASPACE_FLAG_GUEST = (1u << 1);
31 
32 // per arch base class api to encapsulate the mmu routines on an aspace
33 class ArchVmAspaceInterface {
34 public:
~ArchVmAspaceInterface()35     virtual ~ArchVmAspaceInterface() {}
36 
37     virtual zx_status_t Init(vaddr_t base, size_t size, uint mmu_flags) = 0;
38 
39     virtual zx_status_t Destroy() = 0;
40 
41     // main methods
42 
43     // Map a physically contiguous region into the virtual address space
44     virtual zx_status_t MapContiguous(vaddr_t vaddr, paddr_t paddr, size_t count,
45                                       uint mmu_flags, size_t* mapped) = 0;
46     // Map the given array of pages into the virtual address space starting at
47     // |vaddr|, in the order they appear in |phys|.
48     // If any address in the range [vaddr, vaddr + count * PAGE_SIZE) is already
49     // mapped when this is called, this returns ZX_ERR_ALREADY_EXISTS.
50     virtual zx_status_t Map(vaddr_t vaddr, paddr_t* phys, size_t count,
51                             uint mmu_flags, size_t* mapped) = 0;
52 
53     // Unmap the given virtual address range
54     virtual zx_status_t Unmap(vaddr_t vaddr, size_t count, size_t* unmapped) = 0;
55 
56     // Change the page protections on the given virtual address range
57     virtual zx_status_t Protect(vaddr_t vaddr, size_t count, uint mmu_flags) = 0;
58 
59     virtual zx_status_t Query(vaddr_t vaddr, paddr_t* paddr, uint* mmu_flags) = 0;
60 
61     virtual vaddr_t PickSpot(vaddr_t base, uint prev_region_mmu_flags,
62                              vaddr_t end, uint next_region_mmu_flags,
63                              vaddr_t align, size_t size, uint mmu_flags) = 0;
64 
65     // Physical address of the backing data structure used for translation.
66     //
67     // This should be treated as an opaque value outside of
68     // architecture-specific components.
69     virtual paddr_t arch_table_phys() const = 0;
70 };
71