GDT enumeration
This commit is contained in:
parent
a2eb0c8a25
commit
629ba0f6ce
@ -1,6 +1,20 @@
|
|||||||
// Copyright (c) 2025 shibedrill
|
// Copyright (c) 2025 shibedrill
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
use core::arch::asm;
|
||||||
|
|
||||||
|
use intbits::Bits;
|
||||||
|
|
||||||
pub fn nop() {
|
pub fn nop() {
|
||||||
::x86_64::instructions::nop();
|
::x86_64::instructions::nop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn long_mode() -> bool {
|
||||||
|
let mut output: u32;
|
||||||
|
unsafe { asm!(
|
||||||
|
"mov eax, 0x80000001",
|
||||||
|
"cpuid",
|
||||||
|
out("edx") output,
|
||||||
|
) }
|
||||||
|
output.bit(29)
|
||||||
|
}
|
||||||
@ -5,8 +5,13 @@ use core::arch::asm;
|
|||||||
use core::ptr::addr_of_mut;
|
use core::ptr::addr_of_mut;
|
||||||
|
|
||||||
use intbits::Bits;
|
use intbits::Bits;
|
||||||
|
use x86_64::structures::gdt;
|
||||||
use x86_64::structures::gdt::*;
|
use x86_64::structures::gdt::*;
|
||||||
|
|
||||||
|
use crate::log_info;
|
||||||
|
use crate::log::*;
|
||||||
|
use crate::memory::alloc::format;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub trait GdtEntryRead {
|
pub trait GdtEntryRead {
|
||||||
fn base(&self) -> usize;
|
fn base(&self) -> usize;
|
||||||
@ -48,3 +53,64 @@ pub fn read_gdt() -> GlobalDescriptorTable {
|
|||||||
unsafe { core::slice::from_raw_parts(base as *const u64, (limit / 8) - 1) };
|
unsafe { core::slice::from_raw_parts(base as *const u64, (limit / 8) - 1) };
|
||||||
GlobalDescriptorTable::from_raw_entries(gdt_raw)
|
GlobalDescriptorTable::from_raw_entries(gdt_raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dump_gdt() {
|
||||||
|
let gdt = crate::arch::x86_64::gdt::read_gdt();
|
||||||
|
log_info!("GDT length: {}", gdt.limit() + 1);
|
||||||
|
for entry in gdt.entries() {
|
||||||
|
let flags = x86_64::structures::gdt::DescriptorFlags::from_bits_retain(entry.raw());
|
||||||
|
let seg_type = SegmentType::try_from(entry);
|
||||||
|
log_info!(
|
||||||
|
"GDT entry: type: {:?}, size: {}, raw flags: 0b{:04b}, access: 0b{:08b}",
|
||||||
|
seg_type.unwrap(),
|
||||||
|
if flags.contains(gdt::DescriptorFlags::DEFAULT_SIZE) {
|
||||||
|
"32-bit"
|
||||||
|
} else if flags.contains(gdt::DescriptorFlags::LONG_MODE) {
|
||||||
|
"64-bit"
|
||||||
|
} else {
|
||||||
|
"16-bit"
|
||||||
|
},
|
||||||
|
entry.raw().bits(52..=55),
|
||||||
|
entry.access()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum SegmentType {
|
||||||
|
Null,
|
||||||
|
Code,
|
||||||
|
Data,
|
||||||
|
Ldt,
|
||||||
|
Tss16Avail,
|
||||||
|
Tss16Busy,
|
||||||
|
Tss32Avail,
|
||||||
|
Tss32Busy,
|
||||||
|
Tss64Avail,
|
||||||
|
Tss64Busy,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&gdt::Entry> for SegmentType {
|
||||||
|
type Error = ();
|
||||||
|
fn try_from(value: &gdt::Entry) -> Result<Self, ()> {
|
||||||
|
let flags = x86_64::structures::gdt::DescriptorFlags::from_bits_retain(value.raw());
|
||||||
|
if value.access().bit(4) {
|
||||||
|
if value.access().bit(3) {
|
||||||
|
Ok(SegmentType::Code)
|
||||||
|
} else {
|
||||||
|
Ok(SegmentType::Data)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match value.access().bits(0..=3) {
|
||||||
|
0b0000 => Ok(SegmentType::Null),
|
||||||
|
0b0001 => Ok(SegmentType::Tss16Avail),
|
||||||
|
0b0010 => Ok(SegmentType::Ldt),
|
||||||
|
0b0011 => Ok(SegmentType::Tss16Busy),
|
||||||
|
0b1001 => {if flags.contains(gdt::DescriptorFlags::LONG_MODE) { Ok(SegmentType::Tss64Avail) } else { Ok(SegmentType::Tss32Avail) }},
|
||||||
|
0b1011 => {if flags.contains(gdt::DescriptorFlags::LONG_MODE) { Ok(SegmentType::Tss64Busy) } else { Ok(SegmentType::Tss32Busy) }},
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -29,11 +29,9 @@ use limine::firmware_type::FirmwareType;
|
|||||||
use spin::mutex::Mutex;
|
use spin::mutex::Mutex;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::x86_64::{
|
arch::{asm, x86_64::{
|
||||||
cpuid::{CPUID, virt_supported},
|
cpuid::{CPUID, virt_supported}, gdt::dump_gdt,
|
||||||
gdt::GdtEntryRead,
|
}}, memory::HHDM_RESPONSE,
|
||||||
},
|
|
||||||
memory::HHDM_RESPONSE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@ -165,16 +163,8 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
);
|
);
|
||||||
|
|
||||||
//iter_table(4, &PML4);
|
//iter_table(4, &PML4);
|
||||||
|
log_info!("Long mode: {}", asm::long_mode());
|
||||||
let gdt = crate::arch::x86_64::gdt::read_gdt();
|
dump_gdt();
|
||||||
log_info!("GDT length: {}", gdt.limit() + 1);
|
|
||||||
for entry in gdt.entries() {
|
|
||||||
log_info!(
|
|
||||||
"GDT entry: Flags 0b{:b}, Access 0b{:b}",
|
|
||||||
entry.flags(),
|
|
||||||
entry.access()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
panic!("Finished boot, but cannot start init because processes not implemented!");
|
panic!("Finished boot, but cannot start init because processes not implemented!");
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user