GDT enumeration
This commit is contained in:
parent
a2eb0c8a25
commit
629ba0f6ce
@ -1,6 +1,20 @@
|
||||
// Copyright (c) 2025 shibedrill
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
use intbits::Bits;
|
||||
|
||||
pub fn 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 intbits::Bits;
|
||||
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)]
|
||||
pub trait GdtEntryRead {
|
||||
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) };
|
||||
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 crate::{
|
||||
arch::x86_64::{
|
||||
cpuid::{CPUID, virt_supported},
|
||||
gdt::GdtEntryRead,
|
||||
},
|
||||
memory::HHDM_RESPONSE,
|
||||
arch::{asm, x86_64::{
|
||||
cpuid::{CPUID, virt_supported}, gdt::dump_gdt,
|
||||
}}, memory::HHDM_RESPONSE,
|
||||
};
|
||||
|
||||
lazy_static! {
|
||||
@ -165,16 +163,8 @@ unsafe extern "C" fn main() -> ! {
|
||||
);
|
||||
|
||||
//iter_table(4, &PML4);
|
||||
|
||||
let gdt = crate::arch::x86_64::gdt::read_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()
|
||||
);
|
||||
}
|
||||
log_info!("Long mode: {}", asm::long_mode());
|
||||
dump_gdt();
|
||||
|
||||
panic!("Finished boot, but cannot start init because processes not implemented!");
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user