blob: d68e3898391400093ba6d035462ad65fdd64e749 [file] [log] [blame]
Pierre-Clément Tosia8a4a202022-11-03 14:16:46 +00001// Copyright 2022, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Memory management.
16
17use aarch64_paging::idmap::IdMap;
18use aarch64_paging::paging::Attributes;
19use aarch64_paging::paging::MemoryRegion;
20use aarch64_paging::MapError;
21use core::ops::Range;
22use vmbase::layout;
23
24// We assume that:
25// - MAIR_EL1.Attr0 = "Device-nGnRE memory" (0b0000_0100)
26// - MAIR_EL1.Attr1 = "Normal memory, Outer & Inner WB Non-transient, R/W-Allocate" (0b1111_1111)
27const MEMORY: Attributes = Attributes::NORMAL.union(Attributes::NON_GLOBAL);
28const DEVICE: Attributes = Attributes::DEVICE_NGNRE.union(Attributes::EXECUTE_NEVER);
29const CODE: Attributes = MEMORY.union(Attributes::READ_ONLY);
30const DATA: Attributes = MEMORY.union(Attributes::EXECUTE_NEVER);
31const RODATA: Attributes = DATA.union(Attributes::READ_ONLY);
32
33/// High-level API for managing MMU mappings.
34pub struct PageTable {
35 idmap: IdMap,
36}
37
38impl PageTable {
39 const ASID: usize = 1;
40 const ROOT_LEVEL: usize = 1;
41
42 /// Creates an instance pre-populated with pvmfw's binary layout.
43 pub fn from_static_layout() -> Result<Self, MapError> {
44 let mut page_table = Self { idmap: IdMap::new(Self::ASID, Self::ROOT_LEVEL) };
45
46 page_table.map_code(&layout::text_range())?;
47 page_table.map_data(&layout::writable_region())?;
48 page_table.map_rodata(&layout::rodata_range())?;
49
50 Ok(page_table)
51 }
52
53 pub unsafe fn activate(&mut self) {
54 self.idmap.activate()
55 }
56
57 pub fn map_device(&mut self, range: &Range<usize>) -> Result<(), MapError> {
58 self.map_range(range, DEVICE)
59 }
60
61 pub fn map_data(&mut self, range: &Range<usize>) -> Result<(), MapError> {
62 self.map_range(range, DATA)
63 }
64
65 pub fn map_code(&mut self, range: &Range<usize>) -> Result<(), MapError> {
66 self.map_range(range, CODE)
67 }
68
69 pub fn map_rodata(&mut self, range: &Range<usize>) -> Result<(), MapError> {
70 self.map_range(range, RODATA)
71 }
72
73 fn map_range(&mut self, range: &Range<usize>, attr: Attributes) -> Result<(), MapError> {
74 self.idmap.map_range(&MemoryRegion::new(range.start, range.end), attr)
75 }
76}