blob: 8d12b57ce8344c457982bbcb0fc7d7abe580dae1 [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
Alice Wang4be4dd02023-06-07 07:50:40 +000017use crate::helpers::PVMFW_PAGE_SIZE;
Alice Wanga3931aa2023-07-05 12:52:09 +000018use aarch64_paging::paging::VirtualAddress;
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000019use aarch64_paging::MapError;
Alice Wanga3931aa2023-07-05 12:52:09 +000020use core::ops::Range;
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,
Alice Wanga3931aa2023-07-05 12:52:09 +000025 memory::{PageTable, SIZE_2MB, SIZE_4KB},
Alice Wang93ee98a2023-06-08 08:20:39 +000026 util::align_up,
Pierre-Clément Tosi3d4c5c32023-05-31 16:57:06 +000027};
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +000028
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000029/// Returns memory range reserved for the appended payload.
Alice Wanga3931aa2023-07-05 12:52:09 +000030pub fn appended_payload_range() -> Range<VirtualAddress> {
Alice Wang8b097042023-07-06 14:56:58 +000031 let start = align_up(layout::binary_end().0, SIZE_4KB).unwrap();
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000032 // 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 +000033 let end = align_up(start, SIZE_2MB).unwrap();
Alice Wanga3931aa2023-07-05 12:52:09 +000034 VirtualAddress(start)..VirtualAddress(end)
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000035}
36
37/// Region allocated for the stack.
Alice Wanga3931aa2023-07-05 12:52:09 +000038pub fn stack_range() -> Range<VirtualAddress> {
Pierre-Clément Tosi9ddfab52024-04-24 23:03:46 +010039 const STACK_PAGES: usize = 12;
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000040
41 layout::stack_range(STACK_PAGES * PVMFW_PAGE_SIZE)
42}
43
44pub fn init_page_table() -> result::Result<PageTable, MapError> {
Alice Wangee5b1802023-06-07 07:41:54 +000045 let mut page_table = PageTable::default();
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000046
47 // Stack and scratch ranges are explicitly zeroed and flushed before jumping to payload,
48 // so dirty state management can be omitted.
Alice Wanga3931aa2023-07-05 12:52:09 +000049 page_table.map_data(&layout::scratch_range().into())?;
50 page_table.map_data(&stack_range().into())?;
51 page_table.map_code(&layout::text_range().into())?;
52 page_table.map_rodata(&layout::rodata_range().into())?;
53 page_table.map_data_dbm(&appended_payload_range().into())?;
Pierre-Clément Tosi38a36212024-06-06 11:30:39 +010054 if let Err(e) = page_table.map_device(&layout::console_uart_page().into()) {
Alice Wang807fa592023-06-02 09:54:43 +000055 error!("Failed to remap the UART as a dynamic page table entry: {e}");
56 return Err(e);
57 }
Pierre-Clément Tosiad1fc752023-05-31 16:56:56 +000058 Ok(page_table)
59}