1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-23 00:16:17 +04:00

Fix VGA driver, now screen lightens on malta!

Signed-off-by: Harry Chen <i@harrychen.xyz>
This commit is contained in:
Harry Chen 2019-04-08 20:53:00 +08:00
parent 2baf15acac
commit 39a4dd2ff0
7 changed files with 105 additions and 36 deletions

View File

@ -1,6 +1,7 @@
use once::*; use once::*;
use alloc::string::String; use alloc::string::String;
use mips::registers::cp0; use mips::registers::cp0;
use crate::drivers::bus::pci;
#[path = "../../../../drivers/serial/ti_16c550c.rs"] #[path = "../../../../drivers/serial/ti_16c550c.rs"]
pub mod serial; pub mod serial;
@ -31,7 +32,9 @@ pub fn init_serial_early() {
/// Initialize other board drivers /// Initialize other board drivers
pub fn init_driver() { pub fn init_driver() {
// TODO: add possibly more drivers // TODO: add possibly more drivers
vga::init(0xb8000000, 0xb2050000, 800, 600); vga::init(0xbbe00000, 0xb2050000, 800, 600);
// pci::init();
fb::init();
} }
pub fn probe_fb_info(_width: u32, _height: u32, _depth: u32) -> fb::FramebufferResult { pub fn probe_fb_info(_width: u32, _height: u32, _depth: u32) -> fb::FramebufferResult {

View File

@ -23,8 +23,3 @@ pub fn putfmt(fmt: Arguments) {
console.write_fmt(fmt).unwrap(); console.write_fmt(fmt).unwrap();
} }
} }
pub fn putchar(c: u8) {
unsafe { SERIAL_PORT.force_unlock() }
SERIAL_PORT.lock().putchar(c);
}

View File

@ -51,15 +51,15 @@ pub extern fn rust_main() -> ! {
unsafe { memory::clear_bss(); } unsafe { memory::clear_bss(); }
board::init_serial_early(); board::init_serial_early();
driver::init(); crate::logging::init();
println!("Hello MIPS 32 from CPU {}, dtb @ {:#x}", cpu_id, dtb_start);
interrupt::init(); interrupt::init();
memory::init(); memory::init();
timer::init(); timer::init();
driver::init();
println!("Hello MIPS 32 from CPU {}, dtb @ {:#x}", cpu_id, dtb_start);
crate::logging::init();
crate::drivers::init(dtb_start); crate::drivers::init(dtb_start);
crate::process::init(); crate::process::init();

View File

@ -1,3 +1,3 @@
#[cfg(target_arch = "x86_64")] #[cfg(any(target_arch = "x86_64", target_arch = "mips"))]
pub mod pci; pub mod pci;
pub mod virtio_mmio; pub mod virtio_mmio;

View File

@ -10,7 +10,6 @@ use core::cmp::Ordering;
use pci::*; use pci::*;
use rcore_memory::{paging::PageTable, PAGE_SIZE}; use rcore_memory::{paging::PageTable, PAGE_SIZE};
use spin::Mutex; use spin::Mutex;
use x86_64::instructions::port::Port;
const PCI_COMMAND: u16 = 0x04; const PCI_COMMAND: u16 = 0x04;
const PCI_CAP_PTR: u16 = 0x34; const PCI_CAP_PTR: u16 = 0x34;
@ -26,7 +25,12 @@ const PCI_CAP_ID_MSI: u8 = 0x05;
struct PortOpsImpl; struct PortOpsImpl;
#[cfg(target_arch = "x86_64")]
use x86_64::instructions::port::Port;
#[cfg(target_arch = "x86_64")]
impl PortOps for PortOpsImpl { impl PortOps for PortOpsImpl {
unsafe fn read8(&self, port: u16) -> u8 { unsafe fn read8(&self, port: u16) -> u8 {
Port::new(port).read() Port::new(port).read()
} }
@ -47,6 +51,35 @@ impl PortOps for PortOpsImpl {
} }
} }
#[cfg(target_arch = "mips")]
use crate::util::{read, write};
#[cfg(feature = "board_malta")]
const PCI_BASE: usize = 0xbbe00000;
#[cfg(target_arch = "mips")]
impl PortOps for PortOpsImpl {
unsafe fn read8(&self, port: u16) -> u8 {
read(PCI_BASE + port as usize)
}
unsafe fn read16(&self, port: u16) -> u16 {
read(PCI_BASE + port as usize)
}
unsafe fn read32(&self, port: u16) -> u32 {
read(PCI_BASE + port as usize)
}
unsafe fn write8(&self, port: u16, val: u8) {
write(PCI_BASE + port as usize, val);
}
unsafe fn write16(&self, port: u16, val: u16) {
write(PCI_BASE + port as usize, val);
}
unsafe fn write32(&self, port: u16, val: u32) {
write(PCI_BASE + port as usize, val);
}
}
/// Enable the pci device and its interrupt /// Enable the pci device and its interrupt
/// Return assigned MSI interrupt number when applicable /// Return assigned MSI interrupt number when applicable
unsafe fn enable(loc: Location) -> Option<u32> { unsafe fn enable(loc: Location) -> Option<u32> {

View File

@ -2,49 +2,71 @@
use crate::util::{read, write}; use crate::util::{read, write};
const VGA_MMIO_OFFSET: usize = 0x400 - 0x3c0; const VGA_MMIO_OFFSET: usize = 0x400 - 0x3C0;
const VBE_MMIO_OFFSET: usize = 0x500; const VBE_MMIO_OFFSET: usize = 0x500;
const VGA_AR_ADDR: u16 = 0x3C0; const VGA_AR_ADDR : u16 = 0x3C0;
const VBE_DISPI_INDEX_XRES: u16 = 0x01; const VBE_DISPI_INDEX_XRES : u16 = 0x1;
const VBE_DISPI_INDEX_YRES: u16 = 0x02; const VBE_DISPI_INDEX_YRES : u16 = 0x2;
const VBE_DISPI_INDEX_BPP: u16 = 0x03; const VBE_DISPI_INDEX_BPP : u16 = 0x3;
const VBE_DISPI_INDEX_ENABLE: u16 = 0x04; const VBE_DISPI_INDEX_ENABLE : u16 = 0x4;
const VBE_DISPI_INDEX_BANK : u16 = 0x5;
const VBE_DISPI_INDEX_VIRT_WIDTH : u16 = 0x6;
const VBE_DISPI_INDEX_VIRT_HEIGHT : u16 = 0x7;
const VBE_DISPI_INDEX_X_OFFSET : u16 = 0x8;
const VBE_DISPI_INDEX_Y_OFFSET : u16 = 0x9;
const VBE_DISPI_INDEX_VIDEO_MEMORY_64K : u16 = 0xa;
const VGA_AR_PAS: u8 = 0x20; const VGA_AR_PAS : u8 = 0x20;
const VBE_DISPI_ENABLED: u16 = 0x01; const VBE_DISPI_ENABLED : u16 = 0x01;
const VBE_DISPI_LFB_ENABLED : u16 = 0x40;
const PCI_COMMAND: u8 = 0x04;
const PCI_COMMAND_IO: u32 = 0x1;
const PCI_COMMAND_MEMORY: u32 = 0x2;
const PCI_COMMAND_MASTER: u32 = 0x4;
const PCI_COMMAND_SPECIAL: u32 = 0x8;
const PCI_COMMAND_SERR: u32 = 0x100;
const PCIR_COMMAND: u8 = 0x04;
const PCIM_CMD_PORTEN: u32 = 0x0001;
const PCIM_CMD_MEMEN: u32 = 0x0002;
fn pci_read_config(pci_base: usize, bus: u8, slot: u8, func: u8, offset: u8) -> u32 { fn pci_read_config(pci_base: usize, bus: u8, slot: u8, func: u8, offset: u8) -> u32 {
// write config address // write config address
let address = (1 << 31) | ((bus as u32) << 16) | ((slot as u32) << 11) | ((func as u32) << 8) | (offset as u32); let address = (1 << 31) | ((bus as u32) << 16) | ((slot as u32) << 11) | ((func as u32) << 8) | (offset as u32);
println!("Address: {:08x}", address);
write(pci_base + 0xcf8, address); write(pci_base + 0xcf8, address);
// do the actual work // do the actual work
read(pci_base + 0xcfc) let value = read(pci_base + 0xcfc);
debug!("Read {:08x} from PCI address: {:02x}:{:02x}.{:02x} @ 0x{:02x}", value, bus, slot, func, offset);
value
} }
fn pci_write_config(pci_base: usize, bus: u8, slot: u8, func: u8, offset: u8, value: u32) { fn pci_write_config(pci_base: usize, bus: u8, slot: u8, func: u8, offset: u8, value: u32) {
// write config address // write config address
let address = (1 << 31) | ((bus as u32) << 16) | ((slot as u32) << 11) | ((func as u32) << 8) | (offset as u32); let address = (1 << 31) | ((bus as u32) << 16) | ((slot as u32) << 11) | ((func as u32) << 8) | (offset as u32);
debug!("Write {:08x} to PCI address: {:02x}:{:02x}.{:02x} @ 0x{:02x}", value, bus, slot, func, offset);
write(pci_base + 0xcf8, address); write(pci_base + 0xcf8, address);
// do the actual work // do the actual work
write(pci_base + 0xcfc, value) write(pci_base + 0xcfc, value)
} }
pub fn init(pci_base: usize, vga_base: usize, x_res: u16, y_res: u16) { pub fn init(pci_base: usize, vga_base: usize, x_res: u16, y_res: u16) {
debug!("PCI Controller Base: {:08x}", pci_read_config(pci_base, 0x00, 0x00, 0x00, 0x20));
let controller = pci_read_config(pci_base, 0x00, 0x00, 0x00, PCI_COMMAND);
pci_write_config(pci_base, 0x00, 0x00, 0x00, PCI_COMMAND, controller | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SERR);
// enable PCI MMIO
let pci_vendor = pci_read_config(pci_base, 0x00, 0x12, 0x00, 0x0); let pci_vendor = pci_read_config(pci_base, 0x00, 0x12, 0x00, 0x0);
println!("PCI Device ID: {:08x}", pci_vendor); debug!("VGA PCI Device ID: {:08x}", pci_vendor);
let pci_state = pci_read_config(pci_base, 0x00, 0x12, 0x00, PCIR_COMMAND); // enable port and MMIO for vga card
println!("PCI Config Status: {:08x}", pci_state); pci_write_config(pci_base, 0x00, 0x12, 0x00, PCI_COMMAND, pci_read_config(pci_base, 0x00, 0x12, 0x00, PCI_COMMAND) | PCI_COMMAND_MEMORY);
pci_write_config(pci_base, 0x00, 0x12, 0x00, PCIR_COMMAND, pci_state | PCIM_CMD_PORTEN | PCIM_CMD_MEMEN); // bar 0
pci_write_config(pci_base, 0x00, 0x12, 0x00, 0x10, 0x10000000);
debug!("VGA PCI BAR 0: {:08x}", pci_read_config(pci_base, 0x00, 0x12, 0x00, 0x10));
// bar 2
pci_write_config(pci_base, 0x00, 0x12, 0x00, 0x18, 0x12050000);
debug!("VGA PCI BAR 2: {:08x}", pci_read_config(pci_base, 0x00, 0x12, 0x00, 0x18));
// vga operations // vga operations
@ -52,6 +74,10 @@ pub fn init(pci_base: usize, vga_base: usize, x_res: u16, y_res: u16) {
write(vga_base + VGA_MMIO_OFFSET + (offset as usize), value); write(vga_base + VGA_MMIO_OFFSET + (offset as usize), value);
}; };
let vga_read_io = |offset: u16| -> u8 {
read(vga_base + VGA_MMIO_OFFSET + (offset as usize))
};
let vga_write_vbe = |offset: u16, value: u16| { let vga_write_vbe = |offset: u16, value: u16| {
write(vga_base + VBE_MMIO_OFFSET + (offset as usize) * 2, value); write(vga_base + VBE_MMIO_OFFSET + (offset as usize) * 2, value);
}; };
@ -60,17 +86,29 @@ pub fn init(pci_base: usize, vga_base: usize, x_res: u16, y_res: u16) {
read(vga_base + VBE_MMIO_OFFSET + (offset as usize) * 2) read(vga_base + VBE_MMIO_OFFSET + (offset as usize) * 2)
}; };
// enable palette access debug!("VGA Endianess: {:x}", read::<u32>(vga_base + 0x604));
// unblank vga output
vga_read_io(0x3DA);
vga_write_io(VGA_AR_ADDR, VGA_AR_PAS); vga_write_io(VGA_AR_ADDR, VGA_AR_PAS);
debug!("VGA AR: {}", vga_read_io(VGA_AR_ADDR));
// set resolution and color depth // set resolution and color depth
vga_write_vbe(VBE_DISPI_INDEX_XRES, x_res); vga_write_vbe(VBE_DISPI_INDEX_XRES, x_res);
vga_write_vbe(VBE_DISPI_INDEX_YRES, y_res); vga_write_vbe(VBE_DISPI_INDEX_YRES, y_res);
vga_write_vbe(VBE_DISPI_INDEX_VIRT_WIDTH, x_res);
vga_write_vbe(VBE_DISPI_INDEX_VIRT_HEIGHT, y_res);
vga_write_vbe(VBE_DISPI_INDEX_BANK, 0);
vga_write_vbe(VBE_DISPI_INDEX_X_OFFSET, 0);
vga_write_vbe(VBE_DISPI_INDEX_Y_OFFSET, 0);
vga_write_vbe(VBE_DISPI_INDEX_BPP, 8); vga_write_vbe(VBE_DISPI_INDEX_BPP, 8);
debug!("VGA Resolution: {}*{}@{}bit", vga_read_vbe(VBE_DISPI_INDEX_XRES), vga_read_vbe(VBE_DISPI_INDEX_YRES), vga_read_vbe(VBE_DISPI_INDEX_BPP));
// enable vbe // enable vbe
let vbe_enable = vga_read_vbe(VBE_DISPI_INDEX_ENABLE); let vbe_enable = vga_read_vbe(VBE_DISPI_INDEX_ENABLE);
println!("VBE Status: {:04x}", vbe_enable); vga_write_vbe(VBE_DISPI_INDEX_ENABLE, vbe_enable | VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
vga_write_vbe(VBE_DISPI_INDEX_ENABLE, vbe_enable | VBE_DISPI_ENABLED); debug!("VBE Status: {:04x}", vga_read_vbe(VBE_DISPI_INDEX_ENABLE));
println!("QEMU STDVGA driver initialized @ {:x}", vga_base); info!("QEMU STDVGA driver initialized @ {:x}", vga_base);
} }

View File

@ -348,8 +348,8 @@ pub fn e1000_init(name: String, irq: Option<u32>, header: usize, size: usize) {
let recv_page = unsafe { let recv_page = unsafe {
HEAP_ALLOCATOR.alloc_zeroed(Layout::from_size_align(PAGE_SIZE, PAGE_SIZE).unwrap()) HEAP_ALLOCATOR.alloc_zeroed(Layout::from_size_align(PAGE_SIZE, PAGE_SIZE).unwrap())
} as usize; } as usize;
let send_page_pa = active_table().get_entry(send_page).unwrap().target(); let send_page_pa = active_table().get_entry(send_page).unwrap().target() as u64;
let recv_page_pa = active_table().get_entry(recv_page).unwrap().target(); let recv_page_pa = active_table().get_entry(recv_page).unwrap().target() as u64;
let send_queue_size = PAGE_SIZE / size_of::<E1000SendDesc>(); let send_queue_size = PAGE_SIZE / size_of::<E1000SendDesc>();
let recv_queue_size = PAGE_SIZE / size_of::<E1000RecvDesc>(); let recv_queue_size = PAGE_SIZE / size_of::<E1000RecvDesc>();
let mut send_queue = let mut send_queue =