Use x86_64 crate for asm
This commit is contained in:
parent
4097ae0b53
commit
f48426c59c
@ -1,125 +1,6 @@
|
|||||||
// Copyright (c) 2025 shibedrill
|
// Copyright (c) 2025 shibedrill
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#![allow(clippy::missing_safety_doc)]
|
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use core::arch::asm;
|
|
||||||
|
|
||||||
pub fn read_cr0() -> u64 {
|
|
||||||
let cr0: u64;
|
|
||||||
unsafe { asm!("mov {0:r}, cr0", out(reg) cr0) }
|
|
||||||
cr0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_cr2() -> usize {
|
|
||||||
let cr2: usize;
|
|
||||||
unsafe { asm!("mov {0:r}, cr2", out(reg) cr2) }
|
|
||||||
cr2
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_cr3() -> u64 {
|
|
||||||
let cr3: u64;
|
|
||||||
unsafe { asm!("mov {0:r}, cr3", out(reg) cr3) }
|
|
||||||
cr3
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_cr3(val: u64) {
|
|
||||||
unsafe { asm!("mov cr3, {0:r}", in(reg) val) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_cr4() -> u64 {
|
|
||||||
let cr4: u64;
|
|
||||||
unsafe { asm!("mov {0:r}, cr4", out(reg) cr4) }
|
|
||||||
cr4
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn interrupt_disable() {
|
|
||||||
unsafe {
|
|
||||||
asm!("cli");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn interrupt_enable() {
|
|
||||||
unsafe {
|
|
||||||
asm!("sti");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn halt() {
|
|
||||||
unsafe {
|
|
||||||
asm!("hlt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn nop() {
|
pub fn nop() {
|
||||||
unsafe {
|
::x86_64::instructions::nop();
|
||||||
asm!("nop");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn port_read_u8(port: u16) -> u8 {
|
|
||||||
let result: u8;
|
|
||||||
unsafe {
|
|
||||||
asm! {
|
|
||||||
"in al dx",
|
|
||||||
in("dx") port,
|
|
||||||
out("al") result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn port_read_u16(port: u16) -> u16 {
|
|
||||||
let result: u16;
|
|
||||||
unsafe {
|
|
||||||
asm! {
|
|
||||||
"in ax dx",
|
|
||||||
in("dx") port,
|
|
||||||
out("ax") result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn port_read_u32(port: u16) -> u32 {
|
|
||||||
let result: u32;
|
|
||||||
unsafe {
|
|
||||||
asm! {
|
|
||||||
"in eax dx",
|
|
||||||
in("dx") port,
|
|
||||||
out("eax") result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn port_write_u8(port: u16, data: u8) {
|
|
||||||
unsafe {
|
|
||||||
asm! {
|
|
||||||
"out dx, al",
|
|
||||||
in("dx") port,
|
|
||||||
in("al") data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn port_write_u16(port: u16, data: u16) {
|
|
||||||
unsafe {
|
|
||||||
asm! {
|
|
||||||
"out dx, ax",
|
|
||||||
in("dx") port,
|
|
||||||
in("ax") data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn port_write_u32(port: u16, data: u32) {
|
|
||||||
unsafe {
|
|
||||||
asm! {
|
|
||||||
"out dx eax",
|
|
||||||
in("dx") port,
|
|
||||||
in("eax") data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
use crate::LogLevel;
|
use crate::LogLevel;
|
||||||
use crate::{LOGGER, arch::asm::read_cr2, format, log_trace};
|
use crate::{LOGGER, format, log_trace};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use x86_64::structures::idt::*;
|
use x86_64::structures::idt::*;
|
||||||
|
|
||||||
@ -26,10 +26,13 @@ extern "x86-interrupt" fn double_fault(info: InterruptStackFrame, _: u64) -> ! {
|
|||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
extern "x86-interrupt" fn page_fault(info: InterruptStackFrame, errcode: PageFaultErrorCode) {
|
extern "x86-interrupt" fn page_fault(info: InterruptStackFrame, errcode: PageFaultErrorCode) {
|
||||||
let addr = read_cr2();
|
let addr = x86_64::registers::control::Cr2::read();
|
||||||
log_trace!(
|
log_trace!(
|
||||||
"Fault: Page fault with address 0x{:x}, error code 0b{:b}",
|
"Fault: Page fault with {}, error code 0b{:b}",
|
||||||
addr,
|
match addr {
|
||||||
|
Ok(addr_inner) => format!("address 0x{:x}", addr_inner),
|
||||||
|
Err(_) => "invalid virtual address".into(),
|
||||||
|
},
|
||||||
errcode
|
errcode
|
||||||
);
|
);
|
||||||
if errcode.contains(PageFaultErrorCode::USER_MODE) {
|
if errcode.contains(PageFaultErrorCode::USER_MODE) {
|
||||||
@ -43,7 +46,7 @@ extern "x86-interrupt" fn page_fault(info: InterruptStackFrame, errcode: PageFau
|
|||||||
| errcode.contains(PageFaultErrorCode::MALFORMED_TABLE)
|
| errcode.contains(PageFaultErrorCode::MALFORMED_TABLE)
|
||||||
{
|
{
|
||||||
let info_formatted = format!("{info:#?}");
|
let info_formatted = format!("{info:#?}");
|
||||||
crate::interrupt::page_fault(addr, info_formatted)
|
crate::interrupt::page_fault(addr.unwrap().as_u64() as usize, info_formatted)
|
||||||
} else {
|
} else {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use crate::arch;
|
use crate::{LOGGER, LogLevel, format, log_info};
|
||||||
use crate::memory::HHDM_RESPONSE;
|
use x86_64::registers::control::*;
|
||||||
use crate::{LOGGER, LogLevel, format, log_info, log_trace};
|
|
||||||
use intbits::Bits;
|
|
||||||
use x86_64::structures::paging::PageTableFlags;
|
|
||||||
use x86_64::structures::paging::page_table::PageTable;
|
|
||||||
|
|
||||||
pub fn get_mappings() {
|
pub fn get_mappings() {
|
||||||
log_info!("HHDM offset: 0x{:X}", HHDM_RESPONSE.offset());
|
log_info!("Paging: {}", Cr0::read().contains(Cr0Flags::PAGING));
|
||||||
|
log_info!(
|
||||||
log_info!("Paging: {}", arch::asm::read_cr0().bit(31));
|
"Protection: {}",
|
||||||
log_info!("Protection: {}", arch::asm::read_cr0().bit(0));
|
Cr0::read().contains(Cr0Flags::PROTECTED_MODE_ENABLE)
|
||||||
|
);
|
||||||
log_info!(
|
log_info!(
|
||||||
"Physical Address Extensions: {}",
|
"Physical Address Extensions: {}",
|
||||||
arch::asm::read_cr4().bit(5)
|
x86_64::registers::control::Cr4::read().contains(Cr4Flags::PHYSICAL_ADDRESS_EXTENSION)
|
||||||
|
);
|
||||||
|
log_info!(
|
||||||
|
"Page Size Extensions: {}",
|
||||||
|
Cr4::read().contains(Cr4Flags::PAGE_SIZE_EXTENSION)
|
||||||
);
|
);
|
||||||
log_info!("Page Size Extensions: {}", arch::asm::read_cr4().bit(4));
|
|
||||||
log_info!(
|
log_info!(
|
||||||
"Paging mode: {}",
|
"Paging mode: {}",
|
||||||
match crate::memory::PAGING_REQUEST.get_response().unwrap().mode() {
|
match crate::memory::PAGING_REQUEST.get_response().unwrap().mode() {
|
||||||
@ -25,14 +25,14 @@ pub fn get_mappings() {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
log_info!("CR3 Value: 0b{:064b}", arch::asm::read_cr3());
|
let pml4_addr = Cr3::read_raw().0.start_address();
|
||||||
// Physical address of Page Map Level 4 Table
|
log_info!("Page Map Level 4 Address: 0x{:X}", pml4_addr.as_u64());
|
||||||
let pml4_ptr: *const PageTable =
|
log_info!(
|
||||||
((arch::asm::read_cr3().bits(12..=63) << 12) + HHDM_RESPONSE.offset()) as *const PageTable;
|
"Page-Level Write-Through: {}",
|
||||||
let pagemap_lvl4 = unsafe { &*pml4_ptr };
|
Cr3::read().1.contains(Cr3Flags::PAGE_LEVEL_WRITETHROUGH)
|
||||||
for entry in pagemap_lvl4.iter() {
|
);
|
||||||
if entry.flags().contains(PageTableFlags::PRESENT) {
|
log_info!(
|
||||||
log_trace!("Page Table Level 4 Entry: 0x{:X}", entry.addr());
|
"Page-Level Cache Disable: {}",
|
||||||
}
|
Cr3::read().1.contains(Cr3Flags::PAGE_LEVEL_CACHE_DISABLE)
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,13 @@
|
|||||||
// Copyright (c) 2025 shibedrill
|
// Copyright (c) 2025 shibedrill
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
use crate::arch::asm::*;
|
|
||||||
use crate::log::LogSubscriber;
|
use crate::log::LogSubscriber;
|
||||||
|
use x86_64::instructions::port::Port;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
impl LogSubscriber for Port<u8> {
|
||||||
pub struct Serialport {
|
fn log_write(&mut self, msg: &str) {
|
||||||
port: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LogSubscriber for Serialport {
|
|
||||||
fn write(&self, msg: &str) {
|
|
||||||
for c in msg.chars() {
|
for c in msg.chars() {
|
||||||
port_write_u8(self.port, c as u8);
|
unsafe { self.write(c as u8) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialport {
|
|
||||||
pub fn new(port: u16) -> Self {
|
|
||||||
Serialport { port }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -80,7 +80,7 @@ pub struct LoggerInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait LogSubscriber: Send + Sync {
|
pub trait LogSubscriber: Send + Sync {
|
||||||
fn write(&self, msg: &str);
|
fn log_write(&mut self, msg: &str);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LoggerInner {
|
impl Default for LoggerInner {
|
||||||
@ -112,7 +112,7 @@ impl LoggerInner {
|
|||||||
"[{level_string}] {file}:{line},{column} - {msg}"
|
"[{level_string}] {file}:{line},{column} - {msg}"
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
sub.lock().write(&message);
|
sub.lock().log_write(&message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,6 @@ mod process;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
use arch::x86_64::serial::Serialport;
|
|
||||||
|
|
||||||
use boot::{BASE_REVISION, params, *};
|
use boot::{BASE_REVISION, params, *};
|
||||||
use constants::*;
|
use constants::*;
|
||||||
use limine::firmware_type::FirmwareType;
|
use limine::firmware_type::FirmwareType;
|
||||||
@ -44,6 +41,9 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
// Ensure IDT exists
|
// Ensure IDT exists
|
||||||
IDT.load();
|
IDT.load();
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
let serial: x86_64::instructions::port::Port<u8> = x86_64::instructions::port::Port::new(0x3f8);
|
||||||
|
|
||||||
// Set up logging level from params
|
// Set up logging level from params
|
||||||
// Nothing we can do here if this fails since no log subscribers are initialized yet
|
// Nothing we can do here if this fails since no log subscribers are initialized yet
|
||||||
if let Some(level) = PARAMS.get("-loglevel")
|
if let Some(level) = PARAMS.get("-loglevel")
|
||||||
@ -60,7 +60,7 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
if log_device_list.contains(&"serial") {
|
if log_device_list.contains(&"serial") {
|
||||||
// TODO: Set up device discovery
|
// TODO: Set up device discovery
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
LOGGER.add_subscriber(Serialport::new(0x3f8));
|
LOGGER.add_subscriber(serial);
|
||||||
}
|
}
|
||||||
log_trace!("Configured kernel logging devices");
|
log_trace!("Configured kernel logging devices");
|
||||||
}
|
}
|
||||||
@ -120,6 +120,7 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
boot::modules::log_modules();
|
boot::modules::log_modules();
|
||||||
|
|
||||||
memory::log_memory();
|
memory::log_memory();
|
||||||
|
memory::log_address();
|
||||||
|
|
||||||
arch::x86_64::paging::get_mappings();
|
arch::x86_64::paging::get_mappings();
|
||||||
|
|
||||||
|
@ -86,6 +86,22 @@ pub fn log_memory() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn log_address() {
|
||||||
|
if let Some(resp) = ADDRESS_REQUEST.get_response() {
|
||||||
|
log_info!(
|
||||||
|
"Kernel physical start address: 0x{:X}",
|
||||||
|
resp.physical_base()
|
||||||
|
);
|
||||||
|
log_info!("Kernel virtual start address: 0x{:X}", resp.virtual_base());
|
||||||
|
} else {
|
||||||
|
log_warning!("No kernel address response provided.");
|
||||||
|
}
|
||||||
|
log_info!(
|
||||||
|
"Higher Half direct map offset: 0x{:X}",
|
||||||
|
HHDM_RESPONSE.offset()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[used]
|
#[used]
|
||||||
#[unsafe(link_section = ".requests")]
|
#[unsafe(link_section = ".requests")]
|
||||||
pub static PAGING_REQUEST: PagingModeRequest = limine::request::PagingModeRequest::new();
|
pub static PAGING_REQUEST: PagingModeRequest = limine::request::PagingModeRequest::new();
|
||||||
|
Loading…
Reference in New Issue
Block a user