Skip to content
This repository was archived by the owner on Sep 1, 2024. It is now read-only.

Commit 667f833

Browse files
committed
Single Processor Works with new Serial Logger
1 parent 4216e4a commit 667f833

File tree

3 files changed

+51
-58
lines changed

3 files changed

+51
-58
lines changed

driver/src/main.rs

+20-20
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@
55

66
extern crate alloc;
77

8+
use core::ffi::c_void;
89
use {
9-
crate::{processor::MpManager, virtualize::virtualize_system},
10+
crate::{
11+
processor::MpManager,
12+
virtualize::{switch_stack_and_virtualize_core, zap_relocations},
13+
},
1014
hypervisor::{
1115
global::GlobalState,
1216
intel::capture::{capture_registers, GuestRegisters},
13-
logger::init_uart_logger,
17+
logger,
1418
},
1519
log::*,
1620
uefi::prelude::*,
@@ -41,12 +45,9 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {
4145
#[entry]
4246
fn main(_image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
4347
// Initialize the COM2 port logger with level filter set to Info.
44-
// init_uart_logger();
48+
logger::init(LevelFilter::Trace);
4549

46-
com_logger::builder()
47-
.base(0x2f8)
48-
.filter(LevelFilter::Trace)
49-
.setup();
50+
//com_logger::builder().base(0x2f8).filter(LevelFilter::Trace).setup();
5051

5152
uefi_services::init(&mut system_table).unwrap();
5253

@@ -67,6 +68,8 @@ fn main(_image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
6768
info!("Total processors: {}", processor_count.total);
6869
info!("Enabled processors: {}", processor_count.enabled);
6970

71+
zap_relocations(&system_table);
72+
7073
// Capture the register values to be used as an initial state of the VM.
7174
let mut guest_registers = GuestRegisters::default();
7275
unsafe { capture_registers(&mut guest_registers) }
@@ -81,20 +84,17 @@ fn main(_image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
8184

8285
if processor_count.enabled == 1 {
8386
info!("Found only one processor, virtualizing it");
84-
virtualize_system(&mut global_state, &system_table);
85-
}
86-
/*
87-
else {
88-
info!("Found multiple processors, virtualizing all of them");
89-
match mp_manager.start_virtualization_on_all_processors(
90-
switch_stack_and_virtualize_core,
91-
&mut global_state as *mut _ as *mut c_void,
92-
) {
93-
Ok(_) => debug!("Virtualization started on all processors"),
94-
Err(e) => panic!("Failed to start virtualization on all processors: {:?}", e),
95-
}
87+
switch_stack_and_virtualize_core(&mut global_state as *mut _ as *mut c_void);
88+
} else {
89+
info!("Found multiple processors, virtualizing all of them");
90+
match mp_manager.start_virtualization_on_all_processors(
91+
switch_stack_and_virtualize_core,
92+
&mut global_state as *mut _ as *mut c_void,
93+
) {
94+
Ok(_) => debug!("Virtualization started on all processors"),
95+
Err(e) => panic!("Failed to start virtualization on all processors: {:?}", e),
9696
}
97-
*/
97+
}
9898
}
9999

100100
info!("The hypervisor has been installed successfully!");

driver/src/virtualize.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use core::ffi::c_void;
12
use {
23
alloc::alloc::{alloc_zeroed, handle_alloc_error},
34
core::{alloc::Layout, arch::global_asm},
@@ -9,7 +10,7 @@ use {
910
},
1011
};
1112

12-
pub fn virtualize_system(global_state: &mut GlobalState, system_table: &SystemTable<Boot>) -> ! {
13+
pub fn zap_relocations(system_table: &SystemTable<Boot>) {
1314
let boot_service = system_table.boot_services();
1415

1516
// Open the loaded image protocol to get the current image base and image size.
@@ -37,7 +38,9 @@ pub fn virtualize_system(global_state: &mut GlobalState, system_table: &SystemTa
3738
*((image_base + 0x128) as *mut u32) = 0;
3839
*((image_base + 0x12c) as *mut u32) = 0;
3940
}
41+
}
4042

43+
pub fn allocate_stack() -> u64 {
4144
// Allocate separate stack space. This is never freed.
4245
let layout = Layout::array::<Page>(0x10).unwrap();
4346

@@ -50,6 +53,13 @@ pub fn virtualize_system(global_state: &mut GlobalState, system_table: &SystemTa
5053
let stack_base = stack as u64 + layout.size() as u64 - 0x10;
5154
debug!("Stack range: {:#x?}", stack_base..stack as u64);
5255

56+
stack_base
57+
}
58+
59+
pub extern "efiapi" fn switch_stack_and_virtualize_core(procedure_argument: *mut c_void) {
60+
let global_state = unsafe { &mut *(procedure_argument as *mut GlobalState) };
61+
let stack_base = allocate_stack();
62+
5363
unsafe { switch_stack(global_state, start_hypervisor as usize, stack_base) };
5464
}
5565

hypervisor/src/logger.rs

+20-37
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
//! The module containing the UART (serial port) logger implementation.
2-
// Inspired by:
3-
// https://github.com/iankronquist/rustyvisor/blob/83b53ac104d85073858ba83326a28a6e08d1af12/pcuart/src/lib.rs
4-
// Credits: https://github.com/tandasat/Hello-VT-rp/blob/main/hypervisor/src/logger.rs
1+
//! The module containing the serial port logger implementation.
52
63
use {
74
crate::intel::support::{inb, outb},
@@ -10,25 +7,27 @@ use {
107
};
118

129
/// Initializes the logger instance.
13-
pub fn init_uart_logger(level: log::LevelFilter) -> Result<(), log::SetLoggerError> {
14-
log::set_logger(&UART_LOGGER).map(|()| log::set_max_level(level))
10+
pub fn init(level: log::LevelFilter) {
11+
log::set_logger(&SERIAL_LOGGER)
12+
.map(|()| log::set_max_level(level))
13+
.unwrap();
1514
}
1615

17-
struct UartLogger {
18-
port: Mutex<Uart>,
16+
struct SerialLogger {
17+
port: Mutex<Serial>,
1918
}
20-
impl UartLogger {
21-
const fn new(port: UartComPort) -> Self {
19+
impl SerialLogger {
20+
const fn new() -> Self {
2221
Self {
23-
port: Mutex::new(Uart::new(port)),
22+
port: Mutex::new(Serial {}),
2423
}
2524
}
2625

27-
fn lock(&self) -> spin::MutexGuard<'_, Uart> {
26+
fn lock(&self) -> spin::MutexGuard<'_, Serial> {
2827
self.port.lock()
2928
}
3029
}
31-
impl log::Log for UartLogger {
30+
impl log::Log for SerialLogger {
3231
fn enabled(&self, metadata: &log::Metadata<'_>) -> bool {
3332
metadata.level() <= log::Level::Trace
3433
}
@@ -42,38 +41,22 @@ impl log::Log for UartLogger {
4241
fn flush(&self) {}
4342
}
4443

45-
#[derive(Default)]
46-
struct Uart {
47-
io_port_base: u16,
48-
}
49-
impl Uart {
50-
const fn new(port: UartComPort) -> Self {
51-
Self {
52-
io_port_base: port as u16,
53-
}
54-
}
55-
}
56-
impl Write for Uart {
44+
struct Serial;
45+
46+
impl Write for Serial {
5747
// Writes bytes `string` to the serial port.
5848
fn write_str(&mut self, string: &str) -> Result<(), fmt::Error> {
49+
//const UART_COM1: u16 = 0x3f8;
50+
const UART_COM2: u16 = 0x2f8;
5951
const UART_OFFSET_TRANSMITTER_HOLDING_BUFFER: u16 = 0;
6052
const UART_OFFSET_LINE_STATUS: u16 = 5;
6153

6254
for byte in string.bytes() {
63-
while (inb(self.io_port_base + UART_OFFSET_LINE_STATUS) & 0x20) == 0 {}
64-
outb(
65-
self.io_port_base + UART_OFFSET_TRANSMITTER_HOLDING_BUFFER,
66-
byte,
67-
);
55+
while (inb(UART_COM2 + UART_OFFSET_LINE_STATUS) & 0x20) == 0 {}
56+
outb(UART_COM2 + UART_OFFSET_TRANSMITTER_HOLDING_BUFFER, byte);
6857
}
6958
Ok(())
7059
}
7160
}
7261

73-
#[derive(Clone, Copy)]
74-
#[repr(u16)]
75-
enum UartComPort {
76-
Com1 = 0x3f8,
77-
}
78-
79-
static UART_LOGGER: UartLogger = UartLogger::new(UartComPort::Com1);
62+
static SERIAL_LOGGER: SerialLogger = SerialLogger::new();

0 commit comments

Comments
 (0)