blob: 27ab71965ec1f5cdf909d44223732d4aa86978b6 [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;
Alice Wanga3931aa2023-07-05 12:52:09 +000020use aarch64_paging::paging::VirtualAddress;
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000021use aarch64_paging::MapError;
Alice Wanga3931aa2023-07-05 12:52:09 +000022use core::ops::Range;
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +000023use core::result;
Alice Wang93ee98a2023-06-08 08:20:39 +000024use log::error;
Pierre-Clément Tosi3d4c5c32023-05-31 16:57:06 +000025use vmbase::{
Alice Wang93ee98a2023-06-08 08:20:39 +000026 layout,
Alice Wanga3931aa2023-07-05 12:52:09 +000027 memory::{PageTable, SIZE_2MB, SIZE_4KB},
Alice Wang93ee98a2023-06-08 08:20:39 +000028 util::align_up,
Pierre-Clément Tosi3d4c5c32023-05-31 16:57:06 +000029};
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +000030
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000031/// Returns memory range reserved for the appended payload.
Alice Wanga3931aa2023-07-05 12:52:09 +000032pub fn appended_payload_range() -> Range<VirtualAddress> {
Alice Wang8b097042023-07-06 14:56:58 +000033 let start = align_up(layout::binary_end().0, SIZE_4KB).unwrap();
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000034 // 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 +000035 let end = align_up(start, SIZE_2MB).unwrap();
Alice Wanga3931aa2023-07-05 12:52:09 +000036 VirtualAddress(start)..VirtualAddress(end)
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000037}
38
39/// Region allocated for the stack.
Alice Wanga3931aa2023-07-05 12:52:09 +000040pub fn stack_range() -> Range<VirtualAddress> {
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000041 const STACK_PAGES: usize = 8;
42
43 layout::stack_range(STACK_PAGES * PVMFW_PAGE_SIZE)
44}
45
46pub fn init_page_table() -> result::Result<PageTable, MapError> {
Alice Wangee5b1802023-06-07 07:41:54 +000047 let mut page_table = PageTable::default();
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000048
49 // Stack and scratch ranges are explicitly zeroed and flushed before jumping to payload,
50 // so dirty state management can be omitted.
Alice Wanga3931aa2023-07-05 12:52:09 +000051 page_table.map_data(&layout::scratch_range().into())?;
52 page_table.map_data(&stack_range().into())?;
53 page_table.map_code(&layout::text_range().into())?;
54 page_table.map_rodata(&layout::rodata_range().into())?;
55 page_table.map_data_dbm(&appended_payload_range().into())?;
56 if let Err(e) = page_table.map_device(&layout::console_uart_range().into()) {
Alice Wang807fa592023-06-02 09:54:43 +000057 error!("Failed to remap the UART as a dynamic page table entry: {e}");
58 return Err(e);
59 }
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000060 Ok(page_table)
61}