Skip to content

Commit 2b3de08

Browse files
misc(kernel): bump bitflags to 2.4.2
Signed-off-by: Anhad Singh <[email protected]>
1 parent 27d18d6 commit 2b3de08

File tree

14 files changed

+192
-107
lines changed

14 files changed

+192
-107
lines changed

src/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/aero_kernel/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ spin = { version = "0.9.8", default-features = false, features = [
2626
"rwlock",
2727
"once",
2828
] }
29-
bitflags = "1.2.1"
29+
bitflags = "2.4.2"
3030
bit_field = "0.10.2"
3131
log = "0.4.20"
3232
xmas-elf = "0.9.1"

src/aero_kernel/src/arch/x86_64/controlregs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ bitflags::bitflags! {
184184
}
185185

186186
bitflags::bitflags! {
187+
#[derive(Debug)]
187188
pub struct MxCsr: u32 {
188189
const INVALID_OPERATION = 1 << 0;
189190
const DENORMAL = 1 << 1;

src/aero_kernel/src/arch/x86_64/gdt.rs

Lines changed: 97 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -30,32 +30,24 @@ use core::ptr::addr_of;
3030

3131
use alloc::alloc::alloc_zeroed;
3232

33-
bitflags::bitflags! {
34-
/// Specifies which element to load into a segment from
35-
/// descriptor tables (i.e., is a index to LDT or GDT table
36-
/// with some additional flags).
37-
pub struct SegmentSelector: u16 {
38-
const RPL_0 = 0b00;
39-
const RPL_1 = 0b01;
40-
const RPL_2 = 0b10;
41-
const RPL_3 = 0b11;
42-
const TI_GDT = 0 << 2;
43-
const TI_LDT = 1 << 2;
44-
}
45-
}
46-
4733
bitflags::bitflags! {
4834
struct GdtEntryFlags: u8 {
49-
const NULL = 0;
5035
const PROTECTED_MODE = 1 << 6;
5136
const LONG_MODE = 1 << 5;
5237
}
5338
}
5439

55-
#[derive(Debug, Clone, Copy, PartialEq)]
56-
pub enum Ring {
57-
Ring0 = 0b00,
58-
Ring3 = 0b11,
40+
#[derive(Debug, Copy, Clone, PartialEq)]
41+
#[repr(u8)]
42+
pub enum PrivilegeLevel {
43+
Ring0 = 0,
44+
Ring3 = 3,
45+
}
46+
47+
impl PrivilegeLevel {
48+
pub fn is_user(&self) -> bool {
49+
matches!(self, Self::Ring3)
50+
}
5951
}
6052

6153
const BOOT_GDT_ENTRY_COUNT: usize = 4;
@@ -155,7 +147,7 @@ static GDT: [GdtEntry; GDT_ENTRY_COUNT] = [
155147
// GDT TSS descriptor.
156148
GdtEntry::new(
157149
GdtAccessFlags::PRESENT | GdtAccessFlags::RING_3 | GdtAccessFlags::TSS_AVAIL,
158-
GdtEntryFlags::NULL,
150+
GdtEntryFlags::empty(),
159151
),
160152
// GDT null descriptor as the TSS should be 16 bytes long
161153
// and twice the normal size.
@@ -175,10 +167,10 @@ impl GdtAccessFlags {
175167
const TSS_AVAIL: u8 = 9;
176168
}
177169

178-
pub struct GdtEntryType;
170+
pub struct GdtEntryIndex;
179171

180172
#[rustfmt::skip]
181-
impl GdtEntryType {
173+
impl GdtEntryIndex {
182174
pub const KERNEL_CODE: u16 = 1;
183175
pub const KERNEL_DATA: u16 = 2;
184176
pub const KERNEL_TLS: u16 = 3;
@@ -188,10 +180,32 @@ impl GdtEntryType {
188180
pub const TSS_HI: u16 = 9;
189181
}
190182

183+
#[derive(Debug, Copy, Clone)]
184+
#[repr(transparent)]
185+
pub struct SegmentSelector(u16);
186+
191187
impl SegmentSelector {
192-
const fn new(index: u16, rpl: Ring) -> Self {
193-
Self {
194-
bits: index << 3 | (rpl as u16),
188+
pub const fn empty() -> Self {
189+
Self(0)
190+
}
191+
192+
pub const fn new(index: u16, privilege_level: PrivilegeLevel) -> Self {
193+
Self(index << 3 | (privilege_level as u16))
194+
}
195+
196+
pub const fn bits(&self) -> u16 {
197+
self.0
198+
}
199+
200+
pub const fn from_bits(value: u16) -> Self {
201+
Self(value)
202+
}
203+
204+
pub const fn privilege_level(&self) -> PrivilegeLevel {
205+
match self.bits() & 0b11 {
206+
0 => PrivilegeLevel::Ring0,
207+
3 => PrivilegeLevel::Ring3,
208+
_ => unreachable!(),
195209
}
196210
}
197211
}
@@ -230,7 +244,7 @@ pub(super) struct GdtEntry {
230244
}
231245

232246
impl GdtEntry {
233-
const NULL: Self = Self::new(GdtAccessFlags::NULL, GdtEntryFlags::NULL);
247+
const NULL: Self = Self::new(GdtAccessFlags::NULL, GdtEntryFlags::empty());
234248

235249
const fn new(access_flags: u8, entry_flags: GdtEntryFlags) -> Self {
236250
Self {
@@ -311,19 +325,45 @@ pub fn init_boot() {
311325

312326
// Load the GDT segments.
313327
unsafe {
314-
load_cs(SegmentSelector::new(GdtEntryType::KERNEL_CODE, Ring::Ring0));
315-
load_ds(SegmentSelector::new(GdtEntryType::KERNEL_DATA, Ring::Ring0));
316-
load_es(SegmentSelector::new(GdtEntryType::KERNEL_DATA, Ring::Ring0));
317-
load_fs(SegmentSelector::new(GdtEntryType::KERNEL_DATA, Ring::Ring0));
318-
load_gs(SegmentSelector::new(GdtEntryType::KERNEL_TLS, Ring::Ring0));
319-
load_ss(SegmentSelector::new(GdtEntryType::KERNEL_DATA, Ring::Ring0));
328+
load_cs(SegmentSelector::new(
329+
GdtEntryIndex::KERNEL_CODE,
330+
PrivilegeLevel::Ring0,
331+
));
332+
333+
load_ds(SegmentSelector::new(
334+
GdtEntryIndex::KERNEL_DATA,
335+
PrivilegeLevel::Ring0,
336+
));
337+
338+
load_es(SegmentSelector::new(
339+
GdtEntryIndex::KERNEL_DATA,
340+
PrivilegeLevel::Ring0,
341+
));
342+
343+
load_fs(SegmentSelector::new(
344+
GdtEntryIndex::KERNEL_DATA,
345+
PrivilegeLevel::Ring0,
346+
));
347+
348+
load_gs(SegmentSelector::new(
349+
GdtEntryIndex::KERNEL_TLS,
350+
PrivilegeLevel::Ring0,
351+
));
352+
353+
load_ss(SegmentSelector::new(
354+
GdtEntryIndex::KERNEL_DATA,
355+
PrivilegeLevel::Ring0,
356+
));
320357
}
321358
}
322359

323360
static STK: [u8; 4096 * 16] = [0; 4096 * 16];
324361

325-
pub const USER_SS: SegmentSelector = SegmentSelector::new(GdtEntryType::USER_DATA, Ring::Ring3);
326-
pub const USER_CS: SegmentSelector = SegmentSelector::new(GdtEntryType::USER_CODE, Ring::Ring3);
362+
pub const USER_SS: SegmentSelector =
363+
SegmentSelector::new(GdtEntryIndex::USER_DATA, PrivilegeLevel::Ring3);
364+
365+
pub const USER_CS: SegmentSelector =
366+
SegmentSelector::new(GdtEntryIndex::USER_CODE, PrivilegeLevel::Ring3);
327367

328368
/// Initialize the *actual* GDT stored in TLS.
329369
///
@@ -347,9 +387,9 @@ pub fn init() {
347387
unsafe {
348388
let tss_ptr = TSS.addr().as_mut_ptr::<Tss>();
349389

350-
gdt[GdtEntryType::TSS as usize].set_offset(tss_ptr as u32);
351-
gdt[GdtEntryType::TSS as usize].set_limit(mem::size_of::<Tss>() as u32);
352-
gdt[GdtEntryType::TSS_HI as usize].set_raw((tss_ptr as u64) >> 32);
390+
gdt[GdtEntryIndex::TSS as usize].set_offset(tss_ptr as u32);
391+
gdt[GdtEntryIndex::TSS as usize].set_limit(mem::size_of::<Tss>() as u32);
392+
gdt[GdtEntryIndex::TSS_HI as usize].set_raw((tss_ptr as u64) >> 32);
353393

354394
TSS.rsp[0] = STK.as_ptr().offset(4096 * 16) as u64;
355395

@@ -361,13 +401,28 @@ pub fn init() {
361401
load_gdt(&gdt_descriptor);
362402

363403
// Reload the GDT segments.
364-
load_cs(SegmentSelector::new(GdtEntryType::KERNEL_CODE, Ring::Ring0));
365-
load_ds(SegmentSelector::new(GdtEntryType::KERNEL_DATA, Ring::Ring0));
366-
load_es(SegmentSelector::new(GdtEntryType::KERNEL_DATA, Ring::Ring0));
367-
load_ss(SegmentSelector::new(GdtEntryType::KERNEL_DATA, Ring::Ring0));
404+
load_cs(SegmentSelector::new(
405+
GdtEntryIndex::KERNEL_CODE,
406+
PrivilegeLevel::Ring0,
407+
));
408+
load_ds(SegmentSelector::new(
409+
GdtEntryIndex::KERNEL_DATA,
410+
PrivilegeLevel::Ring0,
411+
));
412+
load_es(SegmentSelector::new(
413+
GdtEntryIndex::KERNEL_DATA,
414+
PrivilegeLevel::Ring0,
415+
));
416+
load_ss(SegmentSelector::new(
417+
GdtEntryIndex::KERNEL_DATA,
418+
PrivilegeLevel::Ring0,
419+
));
368420

369421
// Load the Task State Segment.
370-
load_tss(SegmentSelector::new(GdtEntryType::TSS, Ring::Ring0));
422+
load_tss(SegmentSelector::new(
423+
GdtEntryIndex::TSS,
424+
PrivilegeLevel::Ring0,
425+
));
371426
}
372427

373428
// // Now we update the per-cpu storage to store a reference

src/aero_kernel/src/arch/x86_64/interrupts/idt.rs

Lines changed: 62 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,15 @@
2121
2222
const IDT_ENTRIES: usize = 256;
2323

24-
pub(super) static mut IDT: [IdtEntry; IDT_ENTRIES] = [IdtEntry::NULL; IDT_ENTRIES];
24+
pub(super) static mut IDT: [IdtEntry; IDT_ENTRIES] = [IdtEntry::EMPTY; IDT_ENTRIES];
2525

2626
use core::mem::size_of;
2727
use core::ptr::addr_of;
2828

29-
use crate::arch::gdt::SegmentSelector;
30-
use crate::utils::sync::Mutex;
29+
use bit_field::BitField;
3130

32-
bitflags::bitflags! {
33-
pub struct IDTFlags: u8 {
34-
const PRESENT = 1 << 7;
35-
const RING_0 = 0 << 5;
36-
const RING_1 = 1 << 5;
37-
const RING_2 = 2 << 5;
38-
const RING_3 = 3 << 5;
39-
const SS = 1 << 4;
40-
const INTERRUPT = 0xE;
41-
const TRAP = 0xF;
42-
}
43-
}
31+
use crate::arch::gdt::{GdtEntryIndex, PrivilegeLevel, SegmentSelector};
32+
use crate::utils::sync::Mutex;
4433

4534
#[repr(C, packed)]
4635
struct IdtDescriptor {
@@ -56,47 +45,72 @@ impl IdtDescriptor {
5645
}
5746
}
5847

48+
#[derive(Debug, Copy, Clone)]
49+
#[repr(C)]
50+
struct EntryOptions {
51+
cs: SegmentSelector,
52+
bits: u16,
53+
}
54+
55+
impl EntryOptions {
56+
#[inline]
57+
const fn default() -> Self {
58+
Self {
59+
cs: SegmentSelector::empty(),
60+
// bits 11:8 specify the gate-descriptor type, default to 64-bit interrupt gate (0xe).
61+
bits: 0b1110_0000_0000,
62+
}
63+
}
64+
65+
#[inline]
66+
fn set_privilege_level(&mut self, dpl: PrivilegeLevel) {
67+
self.bits.set_bits(13..15, dpl as u16);
68+
}
69+
70+
#[inline]
71+
fn set_code_segment(&mut self, cs: SegmentSelector) {
72+
self.cs = cs;
73+
}
74+
75+
#[inline]
76+
fn set_present(&mut self, present: bool) {
77+
self.bits.set_bit(15, present);
78+
}
79+
}
80+
5981
#[derive(Copy, Clone)]
60-
#[repr(C, packed)]
82+
#[repr(C)]
6183
pub(super) struct IdtEntry {
62-
offset_low: u16,
63-
selector: u16,
64-
ist: u8,
65-
type_attr: u8,
66-
offset_middle: u16,
67-
offset_hi: u32,
84+
ptr_low: u16,
85+
options: EntryOptions,
86+
ptr_middle: u16,
87+
ptr_high: u32,
6888
ignore: u32,
6989
}
7090

7191
impl IdtEntry {
72-
/// IDT entry with all values defaulted to 0, ie `null`.
73-
const NULL: Self = Self {
74-
offset_low: 0x00,
75-
selector: 0x00,
76-
ist: 0x00,
77-
type_attr: 0x00,
78-
offset_middle: 0x00,
79-
offset_hi: 0x00,
80-
ignore: 0x00,
92+
const EMPTY: Self = Self {
93+
ptr_low: 0,
94+
options: EntryOptions::default(),
95+
ptr_middle: 0,
96+
ptr_high: 0,
97+
ignore: 0,
8198
};
8299

83-
/// Set the IDT entry flags.
84-
fn set_flags(&mut self, flags: IDTFlags) {
85-
self.type_attr = flags.bits;
86-
}
100+
pub(crate) fn set_function(&mut self, ptr: *const u8) {
101+
self.options.set_privilege_level(PrivilegeLevel::Ring0);
102+
self.options.set_code_segment(SegmentSelector::new(
103+
GdtEntryIndex::KERNEL_CODE,
104+
PrivilegeLevel::Ring0,
105+
));
87106

88-
/// Set the IDT entry offset.
89-
fn set_offset(&mut self, selector: u16, base: usize) {
90-
self.selector = selector;
91-
self.offset_low = base as u16;
92-
self.offset_middle = (base >> 16) as u16;
93-
self.offset_hi = (base >> 32) as u32;
94-
}
107+
let addr = ptr.addr();
108+
109+
self.ptr_low = addr as u16;
110+
self.ptr_middle = (addr >> 16) as u16;
111+
self.ptr_high = (addr >> 32) as u32;
95112

96-
/// Set the handler function of the IDT entry.
97-
pub(crate) fn set_function(&mut self, handler: *const u8) {
98-
self.set_flags(IDTFlags::PRESENT | IDTFlags::RING_0 | IDTFlags::INTERRUPT);
99-
self.set_offset(8, handler as usize);
113+
self.options.set_present(true);
100114
}
101115
}
102116

@@ -137,7 +151,8 @@ pub struct IretRegisters {
137151

138152
impl IretRegisters {
139153
pub fn is_user(&self) -> bool {
140-
SegmentSelector::from_bits_truncate(self.cs as u16).contains(SegmentSelector::RPL_3)
154+
let selector = SegmentSelector::from_bits(self.cs as u16);
155+
selector.privilege_level().is_user()
141156
}
142157
}
143158

0 commit comments

Comments
 (0)