blob: 1fadf229261f0ab345210a18aea4f977bddaa9f1 [file] [log] [blame]
Andrew Walbran68a8c162022-03-07 15:38:42 +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//! pVM firmware.
16
17#![no_main]
18#![no_std]
19
Pierre-Clément Tosi5bbfca52022-10-21 12:14:35 +010020mod entry;
Andrew Walbrandfb73372022-04-21 10:52:27 +000021mod exceptions;
Pierre-Clément Tosida4440a2022-08-22 18:06:32 +010022mod helpers;
23mod smccc;
Andrew Walbran68a8c162022-03-07 15:38:42 +000024
Pierre-Clément Tosi263ffd52022-10-05 20:27:50 +010025use core::fmt;
Pierre-Clément Tosida4440a2022-08-22 18:06:32 +010026use helpers::checked_page_of;
Pierre-Clément Tosi5bbfca52022-10-21 12:14:35 +010027use log::{debug, info};
28use vmbase::console;
Andrew Walbran68a8c162022-03-07 15:38:42 +000029
Pierre-Clément Tosi263ffd52022-10-05 20:27:50 +010030#[derive(Debug, Clone)]
Pierre-Clément Tosida4440a2022-08-22 18:06:32 +010031enum Error {
32 /// Failed to configure the UART; no logs available.
33 FailedUartSetup,
34}
Pierre-Clément Tosi263ffd52022-10-05 20:27:50 +010035
36impl fmt::Display for Error {
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Pierre-Clément Tosi263ffd52022-10-05 20:27:50 +010038 let msg = match self {
Pierre-Clément Tosida4440a2022-08-22 18:06:32 +010039 Self::FailedUartSetup => "Failed to configure the UART",
Pierre-Clément Tosi263ffd52022-10-05 20:27:50 +010040 };
41 write!(f, "{}", msg)
42 }
43}
44
Pierre-Clément Tosi5bbfca52022-10-21 12:14:35 +010045fn main(fdt: &mut [u8], payload: &[u8]) -> Result<(), Error> {
Pierre-Clément Tosida4440a2022-08-22 18:06:32 +010046 // We need to inform the hypervisor that the MMIO page containing the UART may be shared back.
Pierre-Clément Tosida4440a2022-08-22 18:06:32 +010047 let mmio_granule = smccc::mmio_guard_info().map_err(|_| Error::FailedUartSetup)?;
Pierre-Clément Tosi446136e2022-10-19 10:10:42 +010048 let uart_page = checked_page_of(console::BASE_ADDRESS, mmio_granule as usize)
49 .ok_or(Error::FailedUartSetup)?;
50 smccc::mmio_guard_map(uart_page as u64).map_err(|_| Error::FailedUartSetup)?;
Pierre-Clément Tosida4440a2022-08-22 18:06:32 +010051
Pierre-Clément Tosi37105a62022-10-18 12:21:48 +010052 info!("pVM firmware");
53 debug!(
Pierre-Clément Tosi5bbfca52022-10-21 12:14:35 +010054 "fdt_address={:#018x}, payload_start={:#018x}, payload_size={:#018x}",
55 fdt.as_ptr() as usize,
56 payload.as_ptr() as usize,
57 payload.len(),
Andrew Walbrane03395a2022-04-29 15:15:49 +000058 );
Andrew Walbran5db32352022-05-06 13:58:11 +000059
Pierre-Clément Tosi37105a62022-10-18 12:21:48 +010060 info!("Starting payload...");
Pierre-Clément Tosi263ffd52022-10-05 20:27:50 +010061
62 Ok(())
63}
64
Pierre-Clément Tosi263ffd52022-10-05 20:27:50 +010065fn jump_to_payload(fdt_address: u64, payload_start: u64) {
Andrew Walbran5db32352022-05-06 13:58:11 +000066 // Safe because this is a function we have implemented in assembly that matches its signature
67 // here.
68 unsafe {
69 start_payload(fdt_address, payload_start);
70 }
71}
72
73extern "C" {
74 fn start_payload(fdt_address: u64, payload_start: u64) -> !;
Andrew Walbran68a8c162022-03-07 15:38:42 +000075}