blob: b21a3f02a278ddf7ea8899586d69e1f95d8f6b0d [file] [log] [blame]
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +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//! Low-level allocation and tracking of main memory.
16
Andrew Walbran848decf2022-12-15 14:39:38 +000017#![deny(unsafe_op_in_unsafe_fn)]
18
Alice Wang4be4dd02023-06-07 07:50:40 +000019use crate::helpers::PVMFW_PAGE_SIZE;
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000020use aarch64_paging::MapError;
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +000021use core::result;
Alice Wang93ee98a2023-06-08 08:20:39 +000022use log::error;
Pierre-Clément Tosi3d4c5c32023-05-31 16:57:06 +000023use vmbase::{
Alice Wang93ee98a2023-06-08 08:20:39 +000024 layout,
25 memory::{MemoryRange, PageTable, SIZE_2MB, SIZE_4KB},
26 util::align_up,
Pierre-Clément Tosi3d4c5c32023-05-31 16:57:06 +000027};
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +000028
Jiyong Park0ee65392023-03-27 20:52:45 +090029/// First address that can't be translated by a level 1 TTBR0_EL1.
30pub const MAX_ADDR: usize = 1 << 40;
31
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000032/// Returns memory range reserved for the appended payload.
Alice Wang446146a2023-06-07 08:18:46 +000033pub fn appended_payload_range() -> MemoryRange {
Alice Wangeacb7382023-06-05 12:53:54 +000034 let start = align_up(layout::binary_end(), SIZE_4KB).unwrap();
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000035 // pvmfw is contained in a 2MiB region so the payload can't be larger than the 2MiB alignment.
Alice Wangeacb7382023-06-05 12:53:54 +000036 let end = align_up(start, SIZE_2MB).unwrap();
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000037 start..end
38}
39
40/// Region allocated for the stack.
Alice Wang446146a2023-06-07 08:18:46 +000041pub fn stack_range() -> MemoryRange {
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000042 const STACK_PAGES: usize = 8;
43
44 layout::stack_range(STACK_PAGES * PVMFW_PAGE_SIZE)
45}
46
47pub fn init_page_table() -> result::Result<PageTable, MapError> {
Alice Wangee5b1802023-06-07 07:41:54 +000048 let mut page_table = PageTable::default();
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000049
50 // Stack and scratch ranges are explicitly zeroed and flushed before jumping to payload,
51 // so dirty state management can be omitted.
52 page_table.map_data(&layout::scratch_range())?;
53 page_table.map_data(&stack_range())?;
54 page_table.map_code(&layout::text_range())?;
55 page_table.map_rodata(&layout::rodata_range())?;
56 page_table.map_data_dbm(&appended_payload_range())?;
Alice Wang807fa592023-06-02 09:54:43 +000057 if let Err(e) = page_table.map_device(&layout::console_uart_range()) {
58 error!("Failed to remap the UART as a dynamic page table entry: {e}");
59 return Err(e);
60 }
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000061 Ok(page_table)
62}