add: Added io.rs and cpu.rs
This commit is contained in:
parent
9566eec501
commit
3177749dbe
@ -10,7 +10,7 @@ memory: guest=1024, host=1024
|
||||
|
||||
clock: sync=realtime, time0=utc, rtc_sync=1
|
||||
|
||||
log: bochsout.txt
|
||||
# log: bochsout.txt
|
||||
magic_break: enabled=1
|
||||
panic: action=ask
|
||||
|
||||
@ -34,4 +34,4 @@ mouse: enabled=0
|
||||
display_library: x
|
||||
|
||||
# -- 除錯 --
|
||||
debugger_log: none
|
||||
# debugger_log: none
|
||||
|
||||
256
bochsout.txt
256
bochsout.txt
@ -1,256 +0,0 @@
|
||||
00000000000i[ ] Bochs x86 Emulator 2.8
|
||||
00000000000i[ ] Built from GitHub snapshot on March 10, 2024
|
||||
00000000000i[ ] Timestamp: Sun Mar 10 08:00:00 CET 2024
|
||||
00000000000i[ ] System configuration
|
||||
00000000000i[ ] processors: 1 (cores=1, HT threads=1)
|
||||
00000000000i[ ] A20 line support: yes
|
||||
00000000000i[ ] IPS is set to 4000000
|
||||
00000000000i[ ] CPU configuration
|
||||
00000000000i[ ] SMP support: yes, quantum=16
|
||||
00000000000i[ ] level: 6
|
||||
00000000000i[ ] APIC support: xapic
|
||||
00000000000i[ ] FPU support: yes
|
||||
00000000000i[ ] MMX support: yes
|
||||
00000000000i[ ] 3dnow! support: yes
|
||||
00000000000i[ ] SEP support: yes
|
||||
00000000000i[ ] SIMD support: sse2
|
||||
00000000000i[ ] XSAVE support: no
|
||||
00000000000i[ ] AES support: no
|
||||
00000000000i[ ] SHA support: no
|
||||
00000000000i[ ] MOVBE support: no
|
||||
00000000000i[ ] ADX support: no
|
||||
00000000000i[ ] x86-64 support: yes
|
||||
00000000000i[ ] 1G paging support: no
|
||||
00000000000i[ ] MWAIT support: yes
|
||||
00000000000i[ ] VMX support: 1
|
||||
00000000000i[ ] Optimization configuration
|
||||
00000000000i[ ] RepeatSpeedups support: yes
|
||||
00000000000i[ ] Fast function calls: yes
|
||||
00000000000i[ ] Handlers Chaining speedups: no
|
||||
00000000000i[ ] Devices configuration
|
||||
00000000000i[ ] PCI support: i440FX i430FX i440BX
|
||||
00000000000i[ ] Networking: no
|
||||
00000000000i[ ] Sound support: no
|
||||
00000000000i[ ] USB support: no
|
||||
00000000000i[ ] VGA extension support: vbe
|
||||
00000000000i[IMG ] Disk image modules
|
||||
00000000000i[IMG ] flat concat sparse dll growing undoable volatile vmware3
|
||||
00000000000i[IMG ] vmware4 vbox vpc vvfat
|
||||
00000000000i[MEM0 ] allocated memory at 0x7f063c694010. after alignment, vector=0x7f063c695000, block_size = 128K
|
||||
00000000000i[MEM0 ] 1024.00MB
|
||||
00000000000i[MEM0 ] mem block size = 0x00020000, blocks=8192
|
||||
00000000000i[MEM0 ] rom at 0xfffe0000/131072 ('/usr/local/share/bochs/BIOS-bochs-latest')
|
||||
00000000000i[CPU0 ] WARNING: 3DNow! is not implemented yet !
|
||||
00000000000i[DEV ] will paste characters every 100 iodev timer ticks
|
||||
00000000000i[PLUGIN] init_dev of 'pci' plugin device by virtual method
|
||||
00000000000i[DEV ] i440FX PMC present at device 0, function 0
|
||||
00000000000i[PLUGIN] init_dev of 'pci2isa' plugin device by virtual method
|
||||
00000000000i[DEV ] PIIX3 PCI-to-ISA bridge present at device 1, function 0
|
||||
00000000000i[PLUGIN] init_dev of 'cmos' plugin device by virtual method
|
||||
00000000000i[CMOS ] CMOS RTC using realtime synchronisation method
|
||||
00000000000i[CMOS ] Using utc time for initial clock
|
||||
00000000000i[CMOS ] Setting initial clock to: Mon May 5 6:27:55 2025 tz=utc (time0=1746426475)
|
||||
00000000000i[PLUGIN] init_dev of 'dma' plugin device by virtual method
|
||||
00000000000i[DMA ] channel 4 used by cascade
|
||||
00000000000i[PLUGIN] init_dev of 'pic' plugin device by virtual method
|
||||
00000000000i[PLUGIN] init_dev of 'pit' plugin device by virtual method
|
||||
00000000000i[PIT ] PIT using realtime synchronisation method
|
||||
00000000000i[PLUGIN] init_dev of 'vga' plugin device by virtual method
|
||||
00000000000i[MEM0 ] Register memory access handlers: 0x0000000a0000 - 0x0000000bffff
|
||||
00000000000i[VGA ] interval=100000, mode=realtime
|
||||
00000000000i[VGA ] Setting VGA update interval to 100000 (10.0 Hz)
|
||||
00000000000i[VGA ] VSYNC using realtime mode
|
||||
00000000000i[MEM0 ] Register memory access handlers: 0x0000e0000000 - 0x0000e0ffffff
|
||||
00000000000i[BXVGA ] VBE Bochs Display Extension Enabled
|
||||
00000000000i[XGUI ] test_alloc_colors: 16 colors available out of 16 colors tried
|
||||
00000000000i[XGUI ] font 8 wide x 16 high, display depth = 24
|
||||
00000000000i[XGUI ] maximum host resolution: x=1920 y=1030
|
||||
00000000000i[MEM0 ] rom at 0xc0000/36352 ('/usr/local/share/bochs/VGABIOS-lgpl-latest')
|
||||
00000000000i[PLUGIN] init_dev of 'floppy' plugin device by virtual method
|
||||
00000000000i[DMA ] channel 2 used by Floppy Drive
|
||||
00000000000i[FLOPPY] Using boot sequence cdrom, none, none
|
||||
00000000000i[FLOPPY] Floppy boot signature check is enabled
|
||||
00000000000i[PLUGIN] init_dev of 'acpi' plugin device by virtual method
|
||||
00000000000i[DEV ] ACPI Controller present at device 1, function 3
|
||||
00000000000i[PLUGIN] init_dev of 'hpet' plugin device by virtual method
|
||||
00000000000i[HPET ] initializing HPET
|
||||
00000000000i[MEM0 ] Register memory access handlers: 0x0000fed00000 - 0x0000fed003ff
|
||||
00000000000i[PLUGIN] init_dev of 'ioapic' plugin device by virtual method
|
||||
00000000000i[IOAPIC] initializing I/O APIC
|
||||
00000000000i[MEM0 ] Register memory access handlers: 0x0000fec00000 - 0x0000fec00fff
|
||||
00000000000i[IOAPIC] IOAPIC enabled (base address = 0xfec00000)
|
||||
00000000000i[PLUGIN] init_dev of 'keyboard' plugin device by virtual method
|
||||
00000000000i[PLUGIN] init_dev of 'harddrv' plugin device by virtual method
|
||||
00000000000i[HD ] CD on ata0-0: 'build/cure.iso'
|
||||
00000000000i[CD1 ] load cdrom with path='build/cure.iso'
|
||||
00000000000i[CD1 ] Opening image file as a cd.
|
||||
00000000000i[HD ] Media present in CD-ROM drive
|
||||
00000000000i[HD ] Capacity is 2495 sectors (4.87 MB)
|
||||
00000000000i[PLUGIN] init_dev of 'pci_ide' plugin device by virtual method
|
||||
00000000000i[DEV ] PIIX3 PCI IDE controller present at device 1, function 1
|
||||
00000000000i[PLUGIN] init_dev of 'unmapped' plugin device by virtual method
|
||||
00000000000i[PLUGIN] init_dev of 'biosdev' plugin device by virtual method
|
||||
00000000000i[PLUGIN] init_dev of 'speaker' plugin device by virtual method
|
||||
00000000000e[PCSPK ] Failed to open /dev/console: Permission denied
|
||||
00000000000e[PCSPK ] Deactivating beep on console
|
||||
00000000000i[PLUGIN] init_dev of 'extfpuirq' plugin device by virtual method
|
||||
00000000000i[PLUGIN] init_dev of 'parallel' plugin device by virtual method
|
||||
00000000000i[PAR ] parallel port 1 at 0x0378 irq 7
|
||||
00000000000i[PLUGIN] init_dev of 'serial' plugin device by virtual method
|
||||
00000000000i[SER ] com1 at 0x03f8 irq 4 (mode: null)
|
||||
00000000000i[PLUGIN] init_dev of 'iodebug' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'pci' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'pci2isa' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'cmos' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'dma' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'pic' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'pit' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'vga' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'floppy' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'unmapped' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'biosdev' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'speaker' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'extfpuirq' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'parallel' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'serial' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'iodebug' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'acpi' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'hpet' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'ioapic' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'keyboard' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'harddrv' plugin device by virtual method
|
||||
00000000000i[PLUGIN] register state of 'pci_ide' plugin device by virtual method
|
||||
00000000000i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
|
||||
00000000000i[CPU0 ] cpu hardware reset
|
||||
00000000000i[APIC0 ] allocate APIC id=0 (MMIO enabled) to 0x0000fee00000
|
||||
00000000000i[CPU0 ] CPU[0] is the bootstrap processor
|
||||
00000000000i[CPU0 ] CPUID[0x00000000]: 00000005 68747541 444d4163 69746e65
|
||||
00000000000i[CPU0 ] CPUID[0x00000001]: 00000633 00010800 00002008 078bfbff
|
||||
00000000000i[CPU0 ] CPUID[0x00000002]: 00000000 00000000 00000000 00000000
|
||||
00000000000i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000
|
||||
00000000000i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000
|
||||
00000000000i[CPU0 ] CPUID[0x00000005]: 00000040 00000040 00000003 00000020
|
||||
00000000000i[CPU0 ] CPUID[0x80000000]: 80000008 68747541 444d4163 69746e65
|
||||
00000000000i[CPU0 ] CPUID[0x80000001]: 00000633 00000000 00000101 ebd3f3ff
|
||||
00000000000i[CPU0 ] CPUID[0x80000002]: 20444d41 6c687441 74286e6f 7020296d
|
||||
00000000000i[CPU0 ] CPUID[0x80000003]: 65636f72 726f7373 00000000 00000000
|
||||
00000000000i[CPU0 ] CPUID[0x80000004]: 00000000 00000000 00000000 00000000
|
||||
00000000000i[CPU0 ] CPUID[0x80000005]: 01ff01ff 01ff01ff 40020140 40020140
|
||||
00000000000i[CPU0 ] CPUID[0x80000006]: 00000000 42004200 02008140 00000000
|
||||
00000000000i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000000
|
||||
00000000000i[CPU0 ] CPUID[0x80000008]: 00003028 00000200 00000000 00000000
|
||||
00000000000i[CPU0 ] CPU Features supported:
|
||||
00000000000i[CPU0 ] "x87"
|
||||
00000000000i[CPU0 ] "486ni"
|
||||
00000000000i[CPU0 ] "pentium_ni"
|
||||
00000000000i[CPU0 ] "p6ni"
|
||||
00000000000i[CPU0 ] "mmx"
|
||||
00000000000i[CPU0 ] "3dnow"
|
||||
00000000000i[CPU0 ] "debugext"
|
||||
00000000000i[CPU0 ] "vme"
|
||||
00000000000i[CPU0 ] "pse"
|
||||
00000000000i[CPU0 ] "pae"
|
||||
00000000000i[CPU0 ] "pge"
|
||||
00000000000i[CPU0 ] "pse36"
|
||||
00000000000i[CPU0 ] "mtrr"
|
||||
00000000000i[CPU0 ] "pat"
|
||||
00000000000i[CPU0 ] "sysenter_sysexit"
|
||||
00000000000i[CPU0 ] "clflush"
|
||||
00000000000i[CPU0 ] "sse"
|
||||
00000000000i[CPU0 ] "sse2"
|
||||
00000000000i[CPU0 ] "mwait"
|
||||
00000000000i[CPU0 ] "vmx"
|
||||
00000000000i[CPU0 ] "longmode"
|
||||
00000000000i[CPU0 ] "lm_lahf_sahf"
|
||||
00000000000i[CPU0 ] "nx"
|
||||
00000000000i[CPU0 ] "cmpxhg16b"
|
||||
00000000000i[CPU0 ] "rdtscp"
|
||||
00000000000i[CPU0 ] "ffxsr"
|
||||
00000000000i[CPU0 ] "xapic"
|
||||
00000000000i[PLUGIN] reset of 'pci' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'pci2isa' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'cmos' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'dma' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'pic' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'pit' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'vga' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'floppy' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'acpi' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'hpet' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'ioapic' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'keyboard' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'harddrv' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'pci_ide' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'unmapped' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'biosdev' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'speaker' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'extfpuirq' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'parallel' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'serial' plugin device by virtual method
|
||||
00000000000i[PLUGIN] reset of 'iodebug' plugin device by virtual method
|
||||
00000000000i[ ] Using debugger log file none
|
||||
00000000000i[ ] set SIGINT handler to bx_debug_ctrlc_handler
|
||||
00000001740i[BIOS ] BIOS BUILD DATE: 03/10/24
|
||||
00000314450i[KBD ] reset-disable command received
|
||||
00000316434i[BIOS ] Starting rombios32
|
||||
00000316872i[BIOS ] Shutdown flag 0
|
||||
00000317480i[BIOS ] ram_size=0x40000000
|
||||
00000317958i[BIOS ] ram_end=1024MB
|
||||
00000330227i[BIOS ] Found 1 cpu(s)
|
||||
00000344165i[BIOS ] bios_table_addr: 0x000fa128 end=0x000fcc00
|
||||
00000671981i[PCI ] i440FX PMC write to PAM register 59 (TLB Flush)
|
||||
00000999916i[P2ISA ] PCI IRQ routing: PIRQA# set to 0x0b
|
||||
00000999940i[P2ISA ] PCI IRQ routing: PIRQB# set to 0x09
|
||||
00000999964i[P2ISA ] PCI IRQ routing: PIRQC# set to 0x0b
|
||||
00000999988i[P2ISA ] PCI IRQ routing: PIRQD# set to 0x09
|
||||
00000999998i[P2ISA ] write: ELCR2 = 0x0a
|
||||
00001000767i[BIOS ] PIIX3/PIIX4 init: elcr=00 0a
|
||||
00001014389i[BIOS ] PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237 class=0x0600
|
||||
00001016733i[BIOS ] PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000 class=0x0601
|
||||
00001018916i[BIOS ] PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010 class=0x0101
|
||||
00001019151i[PIDE ] BAR #4: i/o base address = 0xc000
|
||||
00001019767i[BIOS ] region 4: 0x0000c000
|
||||
00001021825i[BIOS ] PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113 class=0x0680
|
||||
00001022101i[ACPI ] new IRQ line = 11
|
||||
00001022115i[ACPI ] new IRQ line = 9
|
||||
00001022143i[ACPI ] new PM base address: 0xb000
|
||||
00001022157i[ACPI ] new SM base address: 0xb100
|
||||
00001022185i[PCI ] setting SMRAM control register to 0x4a
|
||||
00001186320i[CPU0 ] Enter to System Management Mode
|
||||
00001186320i[CPU0 ] enter_system_management_mode: temporary disable VMX while in SMM mode
|
||||
00001186330i[CPU0 ] RSM: Resuming from System Management Mode
|
||||
00001350386i[PCI ] setting SMRAM control register to 0x0a
|
||||
00001377002i[BIOS ] MP table addr=0x000fa200 MPC table addr=0x000fa130 size=0xc8
|
||||
00001378709i[BIOS ] SMBIOS table addr=0x000fa210
|
||||
00001380808i[BIOS ] ACPI tables: RSDP addr=0x000fa330 ACPI DATA addr=0x3fff0000 size=0xff8
|
||||
00001383815i[BIOS ] Firmware waking vector 0x3fff00cc
|
||||
00001386069i[PCI ] i440FX PMC write to PAM register 59 (TLB Flush)
|
||||
00001386799i[BIOS ] bios_table_cur_addr: 0x000fa354
|
||||
00001497506i[VBIOS ] VGABios ID: vgabios.c 2024-03-03
|
||||
00001497577i[BXVGA ] VBE known Display Interface b0c0
|
||||
00001497609i[BXVGA ] VBE known Display Interface b0c5
|
||||
00001499030i[VBIOS ] VBE Bios ID: vbe.c 2024-03-03
|
||||
00005107043i[BIOS ] IDE time out
|
||||
01706430294i[BIOS ] Booting from 07c0:0000
|
||||
01773625838i[CPU0 ] WARNING: HLT instruction with IF=0!
|
||||
03648260000p[XGUI ] >>PANIC<< POWER button turned off.
|
||||
03648260000i[CPU0 ] CPU is in protected mode (halted)
|
||||
03648260000i[CPU0 ] CS.mode = 32 bit
|
||||
03648260000i[CPU0 ] SS.mode = 32 bit
|
||||
03648260000i[CPU0 ] EFER = 0x00000000
|
||||
03648260000i[CPU0 ] | EAX=00010000 EBX=00010000 ECX=00000000 EDX=00000000
|
||||
03648260000i[CPU0 ] | ESP=00108fb0 EBP=00000000 ESI=00000000 EDI=00000000
|
||||
03648260000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af pf cf
|
||||
03648260000i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
|
||||
03648260000i[CPU0 ] | CS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||
03648260000i[CPU0 ] | DS:0018( 0003| 0| 0) 00000000 ffffffff 1 1
|
||||
03648260000i[CPU0 ] | SS:0018( 0003| 0| 0) 00000000 ffffffff 1 1
|
||||
03648260000i[CPU0 ] | ES:0018( 0003| 0| 0) 00000000 ffffffff 1 1
|
||||
03648260000i[CPU0 ] | FS:0018( 0003| 0| 0) 00000000 ffffffff 1 1
|
||||
03648260000i[CPU0 ] | GS:0018( 0003| 0| 0) 00000000 ffffffff 1 1
|
||||
03648260000i[CPU0 ] | EIP=00100038 (00100038)
|
||||
03648260000i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
|
||||
03648260000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
|
||||
03648260000i[CMOS ] Last time: 1746426482 tz=utc (Mon May 5 6:28:02 2025)
|
||||
03648260000i[XGUI ] Exit
|
||||
03648260000i[SIM ] quit_sim called with exit code 1
|
||||
5
none
5
none
@ -1,5 +0,0 @@
|
||||
Bochs internal debugger, type 'help' for help or 'c' to continue
|
||||
Switching to CPU0
|
||||
Next at t=0
|
||||
(0) [0x0000fffffff0] f000:fff0 (unk. ctxt): jmpf 0xf000:e05b ; ea5be000f0
|
||||
<bochs:1> c
|
||||
241
src/hal/cpu.rs
241
src/hal/cpu.rs
@ -0,0 +1,241 @@
|
||||
// src/hal/cpu.rs
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
/// 32 位元暫存器類型
|
||||
pub type Reg32 = u32;
|
||||
/// 16 位元暫存器類型
|
||||
pub type Reg16 = u16;
|
||||
|
||||
/// 通用目的暫存器結構
|
||||
#[repr(C, packed)]
|
||||
pub struct GpRegs {
|
||||
pub eax: Reg32,
|
||||
pub ebx: Reg32,
|
||||
pub ecx: Reg32,
|
||||
pub edx: Reg32,
|
||||
pub edi: Reg32,
|
||||
pub ebp: Reg32,
|
||||
pub esi: Reg32,
|
||||
pub esp: Reg32,
|
||||
}
|
||||
|
||||
/// 段暫存器結構
|
||||
#[repr(C, packed)]
|
||||
pub struct SgReg {
|
||||
pub ss: Reg16,
|
||||
pub es: Reg16,
|
||||
pub ds: Reg16,
|
||||
pub fs: Reg16,
|
||||
pub gs: Reg16,
|
||||
pub cs: Reg16,
|
||||
}
|
||||
|
||||
/// 讀取 CR0 暫存器
|
||||
#[inline]
|
||||
pub fn cpu_r_cr0() -> Reg32 {
|
||||
let val: Reg32;
|
||||
unsafe {
|
||||
asm!("mov %cr0, {}", out(reg) val);
|
||||
}
|
||||
val
|
||||
}
|
||||
|
||||
/// 讀取 CR2 暫存器
|
||||
#[inline]
|
||||
pub fn cpu_r_cr2() -> Reg32 {
|
||||
let val: Reg32;
|
||||
unsafe {
|
||||
asm!("mov %cr2, {}", out(reg) val);
|
||||
}
|
||||
val
|
||||
}
|
||||
|
||||
/// 讀取 CR3 暫存器
|
||||
#[inline]
|
||||
pub fn cpu_r_cr3() -> Reg32 {
|
||||
let val: Reg32;
|
||||
unsafe {
|
||||
asm!("mov %cr3, {}", out(reg) val);
|
||||
}
|
||||
val
|
||||
}
|
||||
|
||||
/// 寫入 CR0 暫存器
|
||||
#[inline]
|
||||
pub fn cpu_w_cr0(val: Reg32) {
|
||||
unsafe {
|
||||
asm!("mov {}, %cr0", in(reg) val);
|
||||
}
|
||||
}
|
||||
|
||||
/// 寫入 CR2 暫存器
|
||||
#[inline]
|
||||
pub fn cpu_w_cr2(val: Reg32) {
|
||||
unsafe {
|
||||
asm!("mov {}, %cr2", in(reg) val);
|
||||
}
|
||||
}
|
||||
|
||||
/// 寫入 CR3 暫存器
|
||||
#[inline]
|
||||
pub fn cpu_w_cr3(val: Reg32) {
|
||||
unsafe {
|
||||
asm!("mov {}, %cr3", in(reg) val);
|
||||
}
|
||||
}
|
||||
|
||||
/// 獲取 CPU 型號
|
||||
///
|
||||
/// # 參數
|
||||
/// * `model_out` - 輸出緩衝區,至少需要 13 bytes
|
||||
pub fn cpu_get_model(model_out: &mut [u8]) {
|
||||
let out: &mut [u32] = unsafe {
|
||||
core::slice::from_raw_parts_mut(model_out.as_mut_ptr() as *mut u32, 3)
|
||||
};
|
||||
|
||||
let mut eax: u32 = 0;
|
||||
let mut ebx: u32;
|
||||
let mut ecx: u32;
|
||||
let mut edx: u32;
|
||||
|
||||
unsafe {
|
||||
asm!("cpuid",
|
||||
inout("eax") eax,
|
||||
out("ebx") ebx,
|
||||
out("ecx") ecx,
|
||||
out("edx") edx
|
||||
);
|
||||
}
|
||||
|
||||
out[0] = ebx;
|
||||
out[1] = edx;
|
||||
out[2] = ecx;
|
||||
|
||||
// 確保以 null 結尾
|
||||
if model_out.len() > 12 {
|
||||
model_out[12] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const BRAND_LEAF: u32 = 0x80000000;
|
||||
|
||||
/// 檢查是否支持品牌字串
|
||||
pub fn cpu_brand_string_supported() -> bool {
|
||||
let mut eax: u32 = BRAND_LEAF;
|
||||
let mut ebx: u32;
|
||||
let mut ecx: u32;
|
||||
let mut edx: u32;
|
||||
|
||||
unsafe {
|
||||
asm!("cpuid",
|
||||
inout("eax") eax,
|
||||
out("ebx") ebx,
|
||||
out("ecx") ecx,
|
||||
out("edx") edx
|
||||
);
|
||||
}
|
||||
|
||||
eax >= 0x80000004
|
||||
}
|
||||
|
||||
/// 獲取 CPU 品牌字串
|
||||
///
|
||||
/// # 參數
|
||||
/// * `brand_out` - 輸出緩衝區,至少需要 49 bytes
|
||||
pub fn cpu_get_brand(brand_out: &mut [u8]) {
|
||||
if !cpu_brand_string_supported() {
|
||||
brand_out[0] = b'?';
|
||||
if brand_out.len() > 1 {
|
||||
brand_out[1] = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let out: &mut [u32] = unsafe {
|
||||
core::slice::from_raw_parts_mut(brand_out.as_mut_ptr() as *mut u32, 12)
|
||||
};
|
||||
|
||||
for i in 0..3u32 {
|
||||
let mut eax: u32 = BRAND_LEAF + i + 2;
|
||||
let mut ebx: u32;
|
||||
let mut ecx: u32;
|
||||
let mut edx: u32;
|
||||
|
||||
unsafe {
|
||||
asm!("cpuid",
|
||||
inout("eax") eax,
|
||||
out("ebx") ebx,
|
||||
out("ecx") ecx,
|
||||
out("edx") edx
|
||||
);
|
||||
}
|
||||
|
||||
let j = (i * 4) as usize;
|
||||
out[j] = eax;
|
||||
out[j + 1] = ebx;
|
||||
out[j + 2] = ecx;
|
||||
out[j + 3] = edx;
|
||||
}
|
||||
|
||||
// 確保以 null 結尾
|
||||
if brand_out.len() > 48 {
|
||||
brand_out[48] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// 讀取 CPU 時間戳計數器 (TSC)
|
||||
///
|
||||
/// # 返回
|
||||
/// 時間戳計數值
|
||||
#[inline]
|
||||
pub fn cpu_rdtsc() -> u64 {
|
||||
let low: u32;
|
||||
let high: u32;
|
||||
unsafe {
|
||||
asm!("rdtsc", out("eax") low, out("edx") high);
|
||||
}
|
||||
((high as u64) << 32) | (low as u64)
|
||||
}
|
||||
|
||||
/// 執行 CPU 暫停指令
|
||||
///
|
||||
/// 在等待時減少 CPU 功耗
|
||||
#[inline]
|
||||
pub fn cpu_pause() {
|
||||
unsafe {
|
||||
asm!("pause");
|
||||
}
|
||||
}
|
||||
|
||||
/// 停止 CPU 執行,直到下一個中斷發生
|
||||
#[inline]
|
||||
pub fn cpu_halt() {
|
||||
unsafe {
|
||||
asm!("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
/// 停止 CPU 並進入低功耗模式
|
||||
#[inline]
|
||||
pub fn cpu_idle() {
|
||||
unsafe {
|
||||
asm!("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
/// 啟用中斷
|
||||
#[inline]
|
||||
pub fn cpu_enable_interrupts() {
|
||||
unsafe {
|
||||
asm!("sti");
|
||||
}
|
||||
}
|
||||
|
||||
/// 禁用中斷
|
||||
#[inline]
|
||||
pub fn cpu_disable_interrupts() {
|
||||
unsafe {
|
||||
asm!("cli");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
// src/hal/io.rs
|
||||
|
||||
// :e - 32 位寄存器(如 eax, edx 等)
|
||||
// :x - 16 位寄存器(如 ax, dx 等)
|
||||
// :l - 8 位低位寄存器(如 al, dl 等)
|
||||
// :h - 8 位高位寄存器(如 ah, dh 等)
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
/// 向 I/O 端口寫入一個字節
|
||||
///
|
||||
/// # 參數
|
||||
/// * `port` - 端口號
|
||||
/// * `value` - 要寫入的值
|
||||
#[inline]
|
||||
pub fn io_port_wb(port: u8, value: u8) {
|
||||
unsafe {
|
||||
asm!(
|
||||
"movb {0}, %al",
|
||||
"movw {1:x}, %dx",
|
||||
"outb %al, %dx",
|
||||
in(reg_byte) value,
|
||||
in(reg) port as u16,
|
||||
out("al") _,
|
||||
out("dx") _
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 向 I/O 端口寫入一個雙字
|
||||
///
|
||||
/// # 參數
|
||||
/// * `port` - 端口號
|
||||
/// * `value` - 要寫入的值
|
||||
#[inline]
|
||||
pub fn io_port_wl(port: u8, value: u32) {
|
||||
unsafe {
|
||||
asm!(
|
||||
"movl {0}, %eax",
|
||||
"movw {1:x}, %dx",
|
||||
"outl %eax, %dx",
|
||||
in(reg) value,
|
||||
in(reg) port as u16,
|
||||
out("eax") _,
|
||||
out("dx") _
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 從 I/O 端口讀取一個字節
|
||||
///
|
||||
/// # 參數
|
||||
/// * `port` - 端口號
|
||||
/// # 返回
|
||||
/// 讀取到的值
|
||||
#[inline]
|
||||
pub fn io_port_rb(port: u8) -> u8 {
|
||||
let value: u8;
|
||||
unsafe {
|
||||
asm!(
|
||||
"movw {1:x}, %dx",
|
||||
"inb %dx, %al",
|
||||
"movb %al, {0}",
|
||||
out(reg_byte) value,
|
||||
in(reg) port as u16,
|
||||
out("al") _,
|
||||
out("dx") _
|
||||
);
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
/// 從 I/O 端口讀取一個雙字
|
||||
///
|
||||
/// # 參數
|
||||
/// * `port` - 端口號
|
||||
/// # 返回
|
||||
/// 讀取到的值
|
||||
#[inline]
|
||||
pub fn io_port_rl(port: u8) -> u32 {
|
||||
let value: u32;
|
||||
unsafe {
|
||||
asm!(
|
||||
"movw {1:x}, %dx",
|
||||
"inl %dx, %eax",
|
||||
"movl %eax, {0}",
|
||||
out(reg) value,
|
||||
in(reg) port as u16,
|
||||
out("eax") _,
|
||||
out("dx") _
|
||||
);
|
||||
}
|
||||
value
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user