From 8754a6eb15847c3e5354d5e696eb03cd75a4cb12 Mon Sep 17 00:00:00 2001 From: Harry Chen Date: Mon, 8 Apr 2019 03:03:35 +0800 Subject: [PATCH] Add PCI initialization in QEMU stdvga Signed-off-by: Harry Chen --- kernel/src/arch/mipsel/board/malta/mod.rs | 2 +- kernel/src/drivers/gpu/qemu_stdvga.rs | 38 +++++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/kernel/src/arch/mipsel/board/malta/mod.rs b/kernel/src/arch/mipsel/board/malta/mod.rs index c0c2cfa..2c34e4c 100644 --- a/kernel/src/arch/mipsel/board/malta/mod.rs +++ b/kernel/src/arch/mipsel/board/malta/mod.rs @@ -31,7 +31,7 @@ pub fn init_serial_early() { /// Initialize other board drivers pub fn init_driver() { // TODO: add possibly more drivers - vga::init(0x92050000, 800, 600); + vga::init(0xb8000000, 0x92050000, 800, 600); } pub fn probe_fb_info(_width: u32, _height: u32, _depth: u32) -> fb::FramebufferResult { diff --git a/kernel/src/drivers/gpu/qemu_stdvga.rs b/kernel/src/drivers/gpu/qemu_stdvga.rs index 415d01b..bf9663f 100644 --- a/kernel/src/drivers/gpu/qemu_stdvga.rs +++ b/kernel/src/drivers/gpu/qemu_stdvga.rs @@ -14,8 +14,40 @@ const VBE_DISPI_INDEX_ENABLE: u16 = 0x04; const VGA_AR_PAS: u8 = 0x20; const VBE_DISPI_ENABLED: u16 = 0x01; -pub fn init(vga_base: usize, x_res: u16, y_res: u16) { +const PCIR_COMMAND: u8 = 0x04; +const PCIM_CMD_PORTEN: u16 = 0x0001; +const PCIM_CMD_MEMEN: u16 = 0x0002; + +fn pci_read_config(pci_base: usize, bus: u8, slot: u8, func: u8, offset: u8) -> u16 { + // enable access mechanism + let data = 0xF0 | (func << 1); + write(pci_base + 0xcf8, data); + write(pci_base + 0xcfa, bus); + // calculate port address + let addr: u16 = (0xC000 | ((slot as u16) << 8) | (offset as u16)) & 0xFFFC; + // do the actual work + read(pci_base + addr as usize) +} + +fn pci_write_config(pci_base: usize, bus: u8, slot: u8, func: u8, offset: u8, value: u16) { + // enable access mechanism + let data = 0xF0 | (func << 1); + write(pci_base + 0xcf8, data); + write(pci_base + 0xcfa, bus); + // calculate port address + let addr: u16 = (0xC000 | ((slot as u16) << 8) | (offset as u16)) & 0xFFFC; + // do the actual work + write(pci_base + addr as usize, value); +} + +pub fn init(pci_base: usize, vga_base: usize, x_res: u16, y_res: u16) { + + // enable PCI MMIO + let pci_state = pci_read_config(pci_base, 0x00, 0x12, 0x00, PCIR_COMMAND); + pci_write_config(pci_base, 0x00, 0x12, 0x00, PCIR_COMMAND, pci_state | PCIM_CMD_PORTEN | PCIM_CMD_MEMEN); + + // vga operations let vga_write_io = |offset: u16, value: u8| { write(vga_base + VGA_MMIO_OFFSET + (offset as usize), value); }; @@ -38,4 +70,6 @@ pub fn init(vga_base: usize, x_res: u16, y_res: u16) { let vbe_enable = vga_read_vbe(VBE_DISPI_INDEX_ENABLE) | VBE_DISPI_ENABLED; vga_write_vbe(VBE_DISPI_INDEX_ENABLE, vbe_enable); -} \ No newline at end of file + println!("QEMU STDVGA driver initialized @ {:x}", vga_base); + +}