mycelium_kernel/arch/x86_64/
shell.rs1use crate::shell::{Command, NumberFormat};
2use hal_x86_64::control_regs;
3use mycelium_util::fmt;
4
5pub const DUMP_ARCH: Command = Command::new("arch")
6 .with_help("dump architecture-specific structures")
7 .with_subcommands(&[
8 Command::new("gdt")
9 .with_help("print the global descriptor table (GDT)")
10 .with_fn(|_| {
11 let gdt = super::interrupt::GDT.get();
12 tracing::info!(GDT = ?gdt);
13 Ok(())
14 }),
15 Command::new("idt")
16 .with_help("print the interrupt descriptor table (IDT)")
17 .with_fn(|_| {
18 let idt = super::interrupt::Controller::idt();
19 tracing::info!(IDT = ?idt);
20 Ok(())
21 }),
22 Command::new("msr")
23 .with_help(
24 "print the value of the specified model-specific register (MSR)\n \
25 MSR_NUM: the MSR number in hexadecimal or binary\n \
26 -f, --fmt <hex|bin|dec>: format the value of the MSR in hexadecimal, \
27 decimal, or binary.",
28 )
29 .with_usage("[-f|--fmt] <MSR_NUM>")
30 .with_fn(|mut ctx| {
31 let fmt = ctx
32 .parse_optional_flag::<NumberFormat>(&["-f", "--fmt"])?
33 .unwrap_or(NumberFormat::Hex);
34 let num = ctx.parse_u32_hex_or_dec("<MSR_NUM>")?;
35
36 let msr = hal_x86_64::cpu::msr::Msr::try_new(num).ok_or_else(|| {
37 ctx.other_error(
38 "CPU does not support model-specific registers (must be pre-pentium...)",
39 )
40 })?;
41
42 let val = msr.read_raw();
43 match fmt {
44 NumberFormat::Binary => tracing::info!("MSR {num:#x} = {val:#b}"),
45 NumberFormat::Decimal => tracing::info!("MSR {num:#x} = {val}"),
46 NumberFormat::Hex => tracing::info!("MSR {num:#x} = {val:#x}"),
47 }
48 Ok(())
49 }),
50 Command::new("cpuid")
51 .with_help(
52 "print the value of the specified CPUID leaf (and subleaf)\n \
53 LEAF: the CPUID leaf number in hexadecimal or binary\n \
54 SUBLEAF: the CPUID subleaf number in hexadecimal or binary\n \
55 -f, --fmt <hex|bin|dec>: format the values of the CPUID registers in hexadecimal, \
56 decimal, or binary.",
57 )
58 .with_usage("[-f|--fmt] <LEAF> [SUBLEAF]")
59 .with_fn(|mut ctx| {
60 use core::arch::x86_64::{CpuidResult, __cpuid_count};
61 let fmt = ctx
62 .parse_optional_flag::<NumberFormat>(&["-f", "--fmt"])?
63 .unwrap_or(NumberFormat::Hex);
64 let leaf = ctx.parse_u32_hex_or_dec("<LEAF>")?;
65 let subleaf = ctx.parse_optional_u32_hex_or_dec("[SUBLEAF]")?.unwrap_or(0);
66
67 let CpuidResult { eax, ebx, ecx, edx } = unsafe { __cpuid_count(leaf, subleaf) };
68 match fmt {
69 NumberFormat::Binary => tracing::info!(
70 target: "shell",
71 eax = fmt::bin(eax),
72 ebx = fmt::bin(ebx),
73 ecx = fmt::bin(ecx),
74 edx = fmt::bin(edx),
75 "CPUID {leaf:#x}:{subleaf:x}",
76 ),
77 NumberFormat::Decimal => tracing::info!(
78 target: "shell", eax, ebx, ecx, edx,
79 "CPUID {leaf:#x}:{subleaf:x}",
80 ),
81 NumberFormat::Hex => tracing::info!(
82 target: "shell",
83 eax = fmt::hex(eax),
84 ebx = fmt::hex(ebx),
85 ecx = fmt::hex(ecx),
86 edx = fmt::hex(edx),
87 "CPUID {leaf:#x}:{subleaf:x}",
88 ),
89 }
90 Ok(())
91 }),
92 Command::new("cr0")
93 .with_help("print the value of control register CR0")
94 .with_fn(|_| {
95 tracing::info!(
96 target: "shell",
97 "CR0:\n{}",
98 control_regs::Cr0::read(),
99 );
100 Ok(())
101 }),
102 Command::new("cr2")
103 .with_help("print the value of control register CR2")
104 .with_fn(|_| {
105 tracing::info!(
106 target: "shell",
107 cr2 = ?control_regs::Cr2::read(),
108 "CR2",
109 );
110 Ok(())
111 }),
112 Command::new("cr3")
113 .with_help("print the value of control register CR3")
114 .with_fn(|_| {
115 let (page, flags) = control_regs::cr3::read();
116 tracing::info!(target: "shell", ?page, ?flags, "CR3");
117 Ok(())
118 }),
119 Command::new("cr4")
120 .with_help("print the value of control register CR4")
121 .with_fn(|_| {
122 tracing::info!(
123 target: "shell",
124 "CR4\n{}",
125 control_regs::Cr4::read(),
126 );
127 Ok(())
128 }),
129 ]);