From 7ae998ce3b592953fbca69e264998bc5b861d3db Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 5 Jan 2017 11:22:36 -0700 Subject: [PATCH] Move drivers to submodule --- .gitmodules | 3 + drivers | 1 + drivers/ahcid/Cargo.toml | 10 - drivers/ahcid/src/ahci/disk.rs | 108 ------- drivers/ahcid/src/ahci/fis.rs | 155 ----------- drivers/ahcid/src/ahci/hba.rs | 417 ---------------------------- drivers/ahcid/src/ahci/mod.rs | 35 --- drivers/ahcid/src/main.rs | 86 ------ drivers/ahcid/src/scheme.rs | 166 ----------- drivers/bgad/Cargo.toml | 3 - drivers/bgad/src/main.rs | 13 - drivers/e1000d/Cargo.toml | 11 - drivers/e1000d/src/device.rs | 346 ----------------------- drivers/e1000d/src/main.rs | 136 --------- drivers/pcid/Cargo.toml | 8 - drivers/pcid/src/config.rs | 14 - drivers/pcid/src/main.rs | 160 ----------- drivers/pcid/src/pci/bar.rs | 18 -- drivers/pcid/src/pci/bus.rs | 46 --- drivers/pcid/src/pci/class.rs | 50 ---- drivers/pcid/src/pci/dev.rs | 46 --- drivers/pcid/src/pci/func.rs | 30 -- drivers/pcid/src/pci/header.rs | 43 --- drivers/pcid/src/pci/mod.rs | 78 ------ drivers/ps2d/Cargo.toml | 10 - drivers/ps2d/src/controller.rs | 233 ---------------- drivers/ps2d/src/keymap.rs | 148 ---------- drivers/ps2d/src/main.rs | 193 ------------- drivers/rtl8168d/Cargo.toml | 11 - drivers/rtl8168d/src/device.rs | 300 -------------------- drivers/rtl8168d/src/main.rs | 141 ---------- drivers/vesad/Cargo.toml | 12 - drivers/vesad/src/display.rs | 246 ---------------- drivers/vesad/src/main.rs | 109 -------- drivers/vesad/src/mode_info.rs | 37 --- drivers/vesad/src/primitive.rs | 47 ---- drivers/vesad/src/scheme.rs | 190 ------------- drivers/vesad/src/screen/graphic.rs | 126 --------- drivers/vesad/src/screen/mod.rs | 32 --- drivers/vesad/src/screen/text.rs | 233 ---------------- 40 files changed, 4 insertions(+), 4047 deletions(-) create mode 160000 drivers delete mode 100644 drivers/ahcid/Cargo.toml delete mode 100644 drivers/ahcid/src/ahci/disk.rs delete mode 100644 drivers/ahcid/src/ahci/fis.rs delete mode 100644 drivers/ahcid/src/ahci/hba.rs delete mode 100644 drivers/ahcid/src/ahci/mod.rs delete mode 100644 drivers/ahcid/src/main.rs delete mode 100644 drivers/ahcid/src/scheme.rs delete mode 100644 drivers/bgad/Cargo.toml delete mode 100644 drivers/bgad/src/main.rs delete mode 100644 drivers/e1000d/Cargo.toml delete mode 100644 drivers/e1000d/src/device.rs delete mode 100644 drivers/e1000d/src/main.rs delete mode 100644 drivers/pcid/Cargo.toml delete mode 100644 drivers/pcid/src/config.rs delete mode 100644 drivers/pcid/src/main.rs delete mode 100644 drivers/pcid/src/pci/bar.rs delete mode 100644 drivers/pcid/src/pci/bus.rs delete mode 100644 drivers/pcid/src/pci/class.rs delete mode 100644 drivers/pcid/src/pci/dev.rs delete mode 100644 drivers/pcid/src/pci/func.rs delete mode 100644 drivers/pcid/src/pci/header.rs delete mode 100644 drivers/pcid/src/pci/mod.rs delete mode 100644 drivers/ps2d/Cargo.toml delete mode 100644 drivers/ps2d/src/controller.rs delete mode 100644 drivers/ps2d/src/keymap.rs delete mode 100644 drivers/ps2d/src/main.rs delete mode 100644 drivers/rtl8168d/Cargo.toml delete mode 100644 drivers/rtl8168d/src/device.rs delete mode 100644 drivers/rtl8168d/src/main.rs delete mode 100644 drivers/vesad/Cargo.toml delete mode 100644 drivers/vesad/src/display.rs delete mode 100644 drivers/vesad/src/main.rs delete mode 100644 drivers/vesad/src/mode_info.rs delete mode 100644 drivers/vesad/src/primitive.rs delete mode 100644 drivers/vesad/src/scheme.rs delete mode 100644 drivers/vesad/src/screen/graphic.rs delete mode 100644 drivers/vesad/src/screen/mod.rs delete mode 100644 drivers/vesad/src/screen/text.rs diff --git a/.gitmodules b/.gitmodules index 02f5947..c5a24df 100644 --- a/.gitmodules +++ b/.gitmodules @@ -61,3 +61,6 @@ [submodule "kernel"] path = kernel url = https://github.com/redox-os/kernel.git +[submodule "drivers"] + path = drivers + url = https://github.com/redox-os/drivers.git diff --git a/drivers b/drivers new file mode 160000 index 0000000..9eeade8 --- /dev/null +++ b/drivers @@ -0,0 +1 @@ +Subproject commit 9eeade88606095a03ee3c285972b45d1c499a971 diff --git a/drivers/ahcid/Cargo.toml b/drivers/ahcid/Cargo.toml deleted file mode 100644 index f718331..0000000 --- a/drivers/ahcid/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "ahcid" -version = "0.1.0" - -[dependencies] -bitflags = "*" -dma = { path = "../../crates/dma/" } -io = { path = "../../crates/io/" } -spin = "*" -redox_syscall = { path = "../../syscall/" } diff --git a/drivers/ahcid/src/ahci/disk.rs b/drivers/ahcid/src/ahci/disk.rs deleted file mode 100644 index 4389425..0000000 --- a/drivers/ahcid/src/ahci/disk.rs +++ /dev/null @@ -1,108 +0,0 @@ -use std::ptr; - -use dma::Dma; -use syscall::error::Result; - -use super::hba::{HbaPort, HbaCmdTable, HbaCmdHeader}; - -pub struct Disk { - id: usize, - port: &'static mut HbaPort, - size: u64, - clb: Dma<[HbaCmdHeader; 32]>, - ctbas: [Dma; 32], - _fb: Dma<[u8; 256]>, - buf: Dma<[u8; 256 * 512]> -} - -impl Disk { - pub fn new(id: usize, port: &'static mut HbaPort) -> Result { - let mut clb = Dma::zeroed()?; - let mut ctbas = [ - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - ]; - let mut fb = Dma::zeroed()?; - let buf = Dma::zeroed()?; - - port.init(&mut clb, &mut ctbas, &mut fb); - - let size = unsafe { port.identify(&mut clb, &mut ctbas).unwrap_or(0) }; - - Ok(Disk { - id: id, - port: port, - size: size, - clb: clb, - ctbas: ctbas, - _fb: fb, - buf: buf - }) - } - - pub fn id(&self) -> usize { - self.id - } - - pub fn size(&self) -> u64 { - self.size - } - - pub fn read(&mut self, block: u64, buffer: &mut [u8]) -> Result { - let sectors = buffer.len()/512; - - let mut sector: usize = 0; - while sectors - sector >= 255 { - if let Err(err) = self.port.ata_dma(block + sector as u64, 255, false, &mut self.clb, &mut self.ctbas, &mut self.buf) { - return Err(err); - } - - unsafe { ptr::copy(self.buf.as_ptr(), buffer.as_mut_ptr().offset(sector as isize * 512), 255 * 512); } - - sector += 255; - } - if sector < sectors { - if let Err(err) = self.port.ata_dma(block + sector as u64, sectors - sector, false, &mut self.clb, &mut self.ctbas, &mut self.buf) { - return Err(err); - } - - unsafe { ptr::copy(self.buf.as_ptr(), buffer.as_mut_ptr().offset(sector as isize * 512), (sectors - sector) * 512); } - - sector += sectors - sector; - } - - Ok(sector * 512) - } - - pub fn write(&mut self, block: u64, buffer: &[u8]) -> Result { - let sectors = buffer.len()/512; - - let mut sector: usize = 0; - while sectors - sector >= 255 { - unsafe { ptr::copy(buffer.as_ptr().offset(sector as isize * 512), self.buf.as_mut_ptr(), 255 * 512); } - - if let Err(err) = self.port.ata_dma(block + sector as u64, 255, true, &mut self.clb, &mut self.ctbas, &mut self.buf) { - return Err(err); - } - - sector += 255; - } - if sector < sectors { - unsafe { ptr::copy(buffer.as_ptr().offset(sector as isize * 512), self.buf.as_mut_ptr(), (sectors - sector) * 512); } - - if let Err(err) = self.port.ata_dma(block + sector as u64, sectors - sector, true, &mut self.clb, &mut self.ctbas, &mut self.buf) { - return Err(err); - } - - sector += sectors - sector; - } - - Ok(sector * 512) - } -} diff --git a/drivers/ahcid/src/ahci/fis.rs b/drivers/ahcid/src/ahci/fis.rs deleted file mode 100644 index 7dbe33c..0000000 --- a/drivers/ahcid/src/ahci/fis.rs +++ /dev/null @@ -1,155 +0,0 @@ -use io::Mmio; - -#[repr(u8)] -pub enum FisType { - /// Register FIS - host to device - RegH2D = 0x27, - /// Register FIS - device to host - RegD2H = 0x34, - /// DMA activate FIS - device to host - DmaAct = 0x39, - /// DMA setup FIS - bidirectional - DmaSetup = 0x41, - /// Data FIS - bidirectional - Data = 0x46, - /// BIST activate FIS - bidirectional - Bist = 0x58, - /// PIO setup FIS - device to host - PioSetup = 0x5F, - /// Set device bits FIS - device to host - DevBits = 0xA1 -} - -#[repr(packed)] -pub struct FisRegH2D { - // DWORD 0 - pub fis_type: Mmio, // FIS_TYPE_REG_H2D - - pub pm: Mmio, // Port multiplier, 1: Command, 0: Control - - pub command: Mmio, // Command register - pub featurel: Mmio, // Feature register, 7:0 - - // DWORD 1 - pub lba0: Mmio, // LBA low register, 7:0 - pub lba1: Mmio, // LBA mid register, 15:8 - pub lba2: Mmio, // LBA high register, 23:16 - pub device: Mmio, // Device register - - // DWORD 2 - pub lba3: Mmio, // LBA register, 31:24 - pub lba4: Mmio, // LBA register, 39:32 - pub lba5: Mmio, // LBA register, 47:40 - pub featureh: Mmio, // Feature register, 15:8 - - // DWORD 3 - pub countl: Mmio, // Count register, 7:0 - pub counth: Mmio, // Count register, 15:8 - pub icc: Mmio, // Isochronous command completion - pub control: Mmio, // Control register - - // DWORD 4 - pub rsv1: [Mmio; 4], // Reserved -} - -#[repr(packed)] -pub struct FisRegD2H { - // DWORD 0 - pub fis_type: Mmio, // FIS_TYPE_REG_D2H - - pub pm: Mmio, // Port multiplier, Interrupt bit: 2 - - pub status: Mmio, // Status register - pub error: Mmio, // Error register - - // DWORD 1 - pub lba0: Mmio, // LBA low register, 7:0 - pub lba1: Mmio, // LBA mid register, 15:8 - pub lba2: Mmio, // LBA high register, 23:16 - pub device: Mmio, // Device register - - // DWORD 2 - pub lba3: Mmio, // LBA register, 31:24 - pub lba4: Mmio, // LBA register, 39:32 - pub lba5: Mmio, // LBA register, 47:40 - pub rsv2: Mmio, // Reserved - - // DWORD 3 - pub countl: Mmio, // Count register, 7:0 - pub counth: Mmio, // Count register, 15:8 - pub rsv3: [Mmio; 2], // Reserved - - // DWORD 4 - pub rsv4: [Mmio; 4], // Reserved -} - -#[repr(packed)] -pub struct FisData { - // DWORD 0 - pub fis_type: Mmio, // FIS_TYPE_DATA - - pub pm: Mmio, // Port multiplier - - pub rsv1: [Mmio; 2], // Reserved - - // DWORD 1 ~ N - pub data: [Mmio; 252], // Payload -} - -#[repr(packed)] -pub struct FisPioSetup { - // DWORD 0 - pub fis_type: Mmio, // FIS_TYPE_PIO_SETUP - - pub pm: Mmio, // Port multiplier, direction: 4 - device to host, interrupt: 2 - - pub status: Mmio, // Status register - pub error: Mmio, // Error register - - // DWORD 1 - pub lba0: Mmio, // LBA low register, 7:0 - pub lba1: Mmio, // LBA mid register, 15:8 - pub lba2: Mmio, // LBA high register, 23:16 - pub device: Mmio, // Device register - - // DWORD 2 - pub lba3: Mmio, // LBA register, 31:24 - pub lba4: Mmio, // LBA register, 39:32 - pub lba5: Mmio, // LBA register, 47:40 - pub rsv2: Mmio, // Reserved - - // DWORD 3 - pub countl: Mmio, // Count register, 7:0 - pub counth: Mmio, // Count register, 15:8 - pub rsv3: Mmio, // Reserved - pub e_status: Mmio, // New value of status register - - // DWORD 4 - pub tc: Mmio, // Transfer count - pub rsv4: [Mmio; 2], // Reserved -} - -#[repr(packed)] -pub struct FisDmaSetup { - // DWORD 0 - pub fis_type: Mmio, // FIS_TYPE_DMA_SETUP - - pub pm: Mmio, // Port multiplier, direction: 4 - device to host, interrupt: 2, auto-activate: 1 - - pub rsv1: [Mmio; 2], // Reserved - - // DWORD 1&2 - pub dma_buffer_id: Mmio, /* DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work. */ - - // DWORD 3 - pub rsv3: Mmio, // More reserved - - // DWORD 4 - pub dma_buffer_offset: Mmio, // Byte offset into buffer. First 2 bits must be 0 - - // DWORD 5 - pub transfer_count: Mmio, // Number of bytes to transfer. Bit 0 must be 0 - - // DWORD 6 - pub rsv6: Mmio, // Reserved -} diff --git a/drivers/ahcid/src/ahci/hba.rs b/drivers/ahcid/src/ahci/hba.rs deleted file mode 100644 index d22b706..0000000 --- a/drivers/ahcid/src/ahci/hba.rs +++ /dev/null @@ -1,417 +0,0 @@ -use std::mem::size_of; -use std::ops::DerefMut; -use std::{ptr, u32}; - -use dma::Dma; -use io::{Io, Mmio}; -use syscall::error::{Error, Result, EIO}; - -use super::fis::{FisType, FisRegH2D}; - -const ATA_CMD_READ_DMA_EXT: u8 = 0x25; -const ATA_CMD_WRITE_DMA_EXT: u8 = 0x35; -const ATA_CMD_IDENTIFY: u8 = 0xEC; -const ATA_DEV_BUSY: u8 = 0x80; -const ATA_DEV_DRQ: u8 = 0x08; - -const HBA_PORT_CMD_CR: u32 = 1 << 15; -const HBA_PORT_CMD_FR: u32 = 1 << 14; -const HBA_PORT_CMD_FRE: u32 = 1 << 4; -const HBA_PORT_CMD_ST: u32 = 1; -const HBA_PORT_IS_ERR: u32 = 1 << 30 | 1 << 29 | 1 << 28 | 1 << 27; -const HBA_SSTS_PRESENT: u32 = 0x3; -const HBA_SIG_ATA: u32 = 0x00000101; -const HBA_SIG_ATAPI: u32 = 0xEB140101; -const HBA_SIG_PM: u32 = 0x96690101; -const HBA_SIG_SEMB: u32 = 0xC33C0101; - -fn pause() { - unsafe { asm!("pause" : : : "memory" : "intel", "volatile"); } -} - -#[derive(Debug)] -pub enum HbaPortType { - None, - Unknown(u32), - SATA, - SATAPI, - PM, - SEMB, -} - -#[repr(packed)] -pub struct HbaPort { - pub clb: [Mmio; 2], // 0x00, command list base address, 1K-byte aligned - pub fb: [Mmio; 2], // 0x08, FIS base address, 256-byte aligned - pub is: Mmio, // 0x10, interrupt status - pub ie: Mmio, // 0x14, interrupt enable - pub cmd: Mmio, // 0x18, command and status - pub _rsv0: Mmio, // 0x1C, Reserved - pub tfd: Mmio, // 0x20, task file data - pub sig: Mmio, // 0x24, signature - pub ssts: Mmio, // 0x28, SATA status (SCR0:SStatus) - pub sctl: Mmio, // 0x2C, SATA control (SCR2:SControl) - pub serr: Mmio, // 0x30, SATA error (SCR1:SError) - pub sact: Mmio, // 0x34, SATA active (SCR3:SActive) - pub ci: Mmio, // 0x38, command issue - pub sntf: Mmio, // 0x3C, SATA notification (SCR4:SNotification) - pub fbs: Mmio, // 0x40, FIS-based switch control - pub _rsv1: [Mmio; 11], // 0x44 ~ 0x6F, Reserved - pub vendor: [Mmio; 4], // 0x70 ~ 0x7F, vendor specific -} - -impl HbaPort { - pub fn probe(&self) -> HbaPortType { - if self.ssts.readf(HBA_SSTS_PRESENT) { - let sig = self.sig.read(); - match sig { - HBA_SIG_ATA => HbaPortType::SATA, - HBA_SIG_ATAPI => HbaPortType::SATAPI, - HBA_SIG_PM => HbaPortType::PM, - HBA_SIG_SEMB => HbaPortType::SEMB, - _ => HbaPortType::Unknown(sig), - } - } else { - HbaPortType::None - } - } - - pub fn start(&mut self) { - while self.cmd.readf(HBA_PORT_CMD_CR) { - pause(); - } - - self.cmd.writef(HBA_PORT_CMD_FRE | HBA_PORT_CMD_ST, true); - } - - pub fn stop(&mut self) { - self.cmd.writef(HBA_PORT_CMD_ST, false); - - while self.cmd.readf(HBA_PORT_CMD_FR | HBA_PORT_CMD_CR) { - pause(); - } - - self.cmd.writef(HBA_PORT_CMD_FRE, false); - } - - pub fn slot(&self) -> Option { - let slots = self.sact.read() | self.ci.read(); - for i in 0..32 { - if slots & 1 << i == 0 { - return Some(i); - } - } - None - } - - pub fn init(&mut self, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32], fb: &mut Dma<[u8; 256]>) { - self.stop(); - - for i in 0..32 { - let cmdheader = &mut clb[i]; - cmdheader.ctba.write(ctbas[i].physical() as u64); - cmdheader.prdtl.write(0); - } - - self.clb[0].write(clb.physical() as u32); - self.clb[1].write((clb.physical() >> 32) as u32); - self.fb[0].write(fb.physical() as u32); - self.fb[1].write((fb.physical() >> 32) as u32); - let is = self.is.read(); - self.is.write(is); - self.ie.write(0); - let serr = self.serr.read(); - self.serr.write(serr); - - // Disable power management - let sctl = self.sctl.read() ; - self.sctl.write(sctl | 7 << 8); - - // Power on and spin up device - self.cmd.writef(1 << 2 | 1 << 1, true); - - print!("{}", format!(" - AHCI init {:X}\n", self.cmd.read())); - } - - pub unsafe fn identify(&mut self, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32]) -> Option { - self.is.write(u32::MAX); - - let dest: Dma<[u16; 256]> = Dma::new([0; 256]).unwrap(); - - if let Some(slot) = self.slot() { - let cmdheader = &mut clb[slot as usize]; - cmdheader.cfl.write(((size_of::() / size_of::()) as u8)); - cmdheader.prdtl.write(1); - - { - let cmdtbl = &mut ctbas[slot as usize]; - ptr::write_bytes(cmdtbl.deref_mut() as *mut HbaCmdTable as *mut u8, 0, size_of::()); - - let prdt_entry = &mut cmdtbl.prdt_entry[0]; - prdt_entry.dba.write(dest.physical() as u64); - prdt_entry.dbc.write(512 | 1); - } - - { - let cmdfis = &mut *(ctbas[slot as usize].cfis.as_mut_ptr() as *mut FisRegH2D); - - cmdfis.fis_type.write(FisType::RegH2D as u8); - cmdfis.pm.write(1 << 7); - cmdfis.command.write(ATA_CMD_IDENTIFY); - cmdfis.device.write(0); - cmdfis.countl.write(1); - cmdfis.counth.write(0); - } - - while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) { - pause(); - } - - self.ci.writef(1 << slot, true); - - self.start(); - - while (self.ci.readf(1 << slot) || self.tfd.readf(0x80)) && self.is.read() & HBA_PORT_IS_ERR == 0 { - pause(); - } - - self.stop(); - - if self.is.read() & HBA_PORT_IS_ERR != 0 { - print!("{}", format!("ERROR IS {:X} TFD {:X} SERR {:X}\n", self.is.read(), self.tfd.read(), self.serr.read())); - return None; - } - - let mut serial = String::new(); - for word in 10..20 { - let d = dest[word]; - let a = ((d >> 8) as u8) as char; - if a != '\0' { - serial.push(a); - } - let b = (d as u8) as char; - if b != '\0' { - serial.push(b); - } - } - - let mut firmware = String::new(); - for word in 23..27 { - let d = dest[word]; - let a = ((d >> 8) as u8) as char; - if a != '\0' { - firmware.push(a); - } - let b = (d as u8) as char; - if b != '\0' { - firmware.push(b); - } - } - - let mut model = String::new(); - for word in 27..47 { - let d = dest[word]; - let a = ((d >> 8) as u8) as char; - if a != '\0' { - model.push(a); - } - let b = (d as u8) as char; - if b != '\0' { - model.push(b); - } - } - - let mut sectors = (dest[100] as u64) | - ((dest[101] as u64) << 16) | - ((dest[102] as u64) << 32) | - ((dest[103] as u64) << 48); - - let lba_bits = if sectors == 0 { - sectors = (dest[60] as u64) | ((dest[61] as u64) << 16); - 28 - } else { - 48 - }; - - print!("{}", format!(" + Serial: {} Firmware: {} Model: {} {}-bit LBA Size: {} MB\n", - serial.trim(), firmware.trim(), model.trim(), lba_bits, sectors / 2048)); - - Some(sectors * 512) - } else { - None - } - } - - pub fn ata_dma(&mut self, block: u64, sectors: usize, write: bool, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32], buf: &mut Dma<[u8; 256 * 512]>) -> Result { - if write { - //print!("{}", format!("AHCI {:X} DMA BLOCK: {:X} SECTORS: {} WRITE: {}\n", (self as *mut HbaPort) as usize, block, sectors, write)); - } - - assert!(sectors > 0 && sectors < 256); - - self.is.write(u32::MAX); - - if let Some(slot) = self.slot() { - if write { - //print!("{}", format!("SLOT {}\n", slot)); - } - - let cmdheader = &mut clb[slot as usize]; - - cmdheader.cfl.write(((size_of::() / size_of::()) as u8) | if write { 1 << 7 | 1 << 6 } else { 0 }); - - cmdheader.prdtl.write(1); - - { - let cmdtbl = &mut ctbas[slot as usize]; - unsafe { ptr::write_bytes(cmdtbl.deref_mut() as *mut HbaCmdTable as *mut u8, 0, size_of::()) }; - - let prdt_entry = &mut cmdtbl.prdt_entry[0]; - prdt_entry.dba.write(buf.physical() as u64); - prdt_entry.dbc.write(((sectors * 512) as u32) | 1); - } - - { - let cmdfis = unsafe { &mut *(ctbas[slot as usize].cfis.as_mut_ptr() as *mut FisRegH2D) }; - - cmdfis.fis_type.write(FisType::RegH2D as u8); - cmdfis.pm.write(1 << 7); - if write { - cmdfis.command.write(ATA_CMD_WRITE_DMA_EXT); - } else { - cmdfis.command.write(ATA_CMD_READ_DMA_EXT); - } - - cmdfis.lba0.write(block as u8); - cmdfis.lba1.write((block >> 8) as u8); - cmdfis.lba2.write((block >> 16) as u8); - - cmdfis.device.write(1 << 6); - - cmdfis.lba3.write((block >> 24) as u8); - cmdfis.lba4.write((block >> 32) as u8); - cmdfis.lba5.write((block >> 40) as u8); - - cmdfis.countl.write(sectors as u8); - cmdfis.counth.write((sectors >> 8) as u8); - } - - if write { - //print!("WAIT ATA_DEV_BUSY | ATA_DEV_DRQ\n"); - } - while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) { - pause(); - } - - if write { - //print!("{}", format!("WRITE CI {:X} in {:X}\n", 1 << slot, self.ci.read())); - } - self.ci.writef(1 << slot, true); - - self.start(); - - if write { - //print!("{}", format!("WAIT CI {:X} in {:X}\n", 1 << slot, self.ci.read())); - } - while (self.ci.readf(1 << slot) || self.tfd.readf(0x80)) && self.is.read() & HBA_PORT_IS_ERR == 0 { - pause(); - if write { - //print!("{}", format!("WAIT CI {:X} TFD {:X} IS {:X} CMD {:X} SERR {:X}\n", self.ci.read(), self.tfd.read(), self.is.read(), self.cmd.read(), self.serr.read())); - } - } - - self.stop(); - - if self.is.read() & HBA_PORT_IS_ERR != 0 { - print!("{}", format!("ERROR IS {:X} IE {:X} CMD {:X} TFD {:X}\nSSTS {:X} SCTL {:X} SERR {:X} SACT {:X}\nCI {:X} SNTF {:X} FBS {:X}\n", - self.is.read(), self.ie.read(), self.cmd.read(), self.tfd.read(), - self.ssts.read(), self.sctl.read(), self.serr.read(), self.sact.read(), - self.ci.read(), self.sntf.read(), self.fbs.read())); - self.is.write(u32::MAX); - return Err(Error::new(EIO)); - } - - if write { - //print!("{}", format!("SUCCESS {}\n", sectors)); - } - Ok(sectors * 512) - } else { - print!("No Command Slots\n"); - Err(Error::new(EIO)) - } - } -} - -#[repr(packed)] -pub struct HbaMem { - pub cap: Mmio, // 0x00, Host capability - pub ghc: Mmio, // 0x04, Global host control - pub is: Mmio, // 0x08, Interrupt status - pub pi: Mmio, // 0x0C, Port implemented - pub vs: Mmio, // 0x10, Version - pub ccc_ctl: Mmio, // 0x14, Command completion coalescing control - pub ccc_pts: Mmio, // 0x18, Command completion coalescing ports - pub em_loc: Mmio, // 0x1C, Enclosure management location - pub em_ctl: Mmio, // 0x20, Enclosure management control - pub cap2: Mmio, // 0x24, Host capabilities extended - pub bohc: Mmio, // 0x28, BIOS/OS handoff control and status - pub _rsv: [Mmio; 116], // 0x2C - 0x9F, Reserved - pub vendor: [Mmio; 96], // 0xA0 - 0xFF, Vendor specific registers - pub ports: [HbaPort; 32], // 0x100 - 0x10FF, Port control registers -} - -impl HbaMem { - pub fn init(&mut self) { - /* - self.ghc.writef(1, true); - while self.ghc.readf(1) { - pause(); - } - */ - self.ghc.write(1 << 31 | 1 << 1); - - print!("{}", format!(" - AHCI CAP {:X} GHC {:X} IS {:X} PI {:X} VS {:X} CAP2 {:X} BOHC {:X}", - self.cap.read(), self.ghc.read(), self.is.read(), self.pi.read(), - self.vs.read(), self.cap2.read(), self.bohc.read())); - } -} - -#[repr(packed)] -pub struct HbaPrdtEntry { - dba: Mmio, // Data base address - _rsv0: Mmio, // Reserved - dbc: Mmio, // Byte count, 4M max, interrupt = 1 -} - -#[repr(packed)] -pub struct HbaCmdTable { - // 0x00 - cfis: [Mmio; 64], // Command FIS - - // 0x40 - _acmd: [Mmio; 16], // ATAPI command, 12 or 16 bytes - - // 0x50 - _rsv: [Mmio; 48], // Reserved - - // 0x80 - prdt_entry: [HbaPrdtEntry; 65536], // Physical region descriptor table entries, 0 ~ 65535 -} - -#[repr(packed)] -pub struct HbaCmdHeader { - // DW0 - cfl: Mmio, /* Command FIS length in DWORDS, 2 ~ 16, atapi: 4, write - host to device: 2, prefetchable: 1 */ - _pm: Mmio, // Reset - 0x80, bist: 0x40, clear busy on ok: 0x20, port multiplier - - prdtl: Mmio, // Physical region descriptor table length in entries - - // DW1 - _prdbc: Mmio, // Physical region descriptor byte count transferred - - // DW2, 3 - ctba: Mmio, // Command table descriptor base address - - // DW4 - 7 - _rsv1: [Mmio; 4], // Reserved -} diff --git a/drivers/ahcid/src/ahci/mod.rs b/drivers/ahcid/src/ahci/mod.rs deleted file mode 100644 index fec9e00..0000000 --- a/drivers/ahcid/src/ahci/mod.rs +++ /dev/null @@ -1,35 +0,0 @@ -use io::Io; - -use self::disk::Disk; -use self::hba::{HbaMem, HbaPortType}; - -pub mod disk; -pub mod fis; -pub mod hba; - -pub fn disks(base: usize, name: &str) -> Vec { - unsafe { &mut *(base as *mut HbaMem) }.init(); - let pi = unsafe { &mut *(base as *mut HbaMem) }.pi.read(); - let ret: Vec = (0..32) - .filter(|&i| pi & 1 << i as i32 == 1 << i as i32) - .filter_map(|i| { - let port = &mut unsafe { &mut *(base as *mut HbaMem) }.ports[i]; - let port_type = port.probe(); - print!("{}", format!("{}-{}: {:?}\n", name, i, port_type)); - match port_type { - HbaPortType::SATA => { - match Disk::new(i, port) { - Ok(disk) => Some(disk), - Err(err) => { - print!("{}", format!("{}: {}\n", i, err)); - None - } - } - } - _ => None, - } - }) - .collect(); - - ret -} diff --git a/drivers/ahcid/src/main.rs b/drivers/ahcid/src/main.rs deleted file mode 100644 index 4e8cbc9..0000000 --- a/drivers/ahcid/src/main.rs +++ /dev/null @@ -1,86 +0,0 @@ -#![feature(asm)] - -#[macro_use] -extern crate bitflags; -extern crate dma; -extern crate io; -extern crate spin; -extern crate syscall; - -use std::{env, usize}; -use std::fs::File; -use std::io::{Read, Write}; -use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; -use syscall::{EVENT_READ, MAP_WRITE, Event, Packet, Result, Scheme}; - -use scheme::DiskScheme; - -pub mod ahci; -pub mod scheme; - -fn create_scheme_fallback<'a>(name: &'a str, fallback: &'a str) -> Result<(&'a str, RawFd)> { - if let Ok(fd) = syscall::open(&format!(":{}", name), syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK) { - Ok((name, fd)) - } else { - syscall::open(&format!(":{}", fallback), syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK) - .map(|fd| (fallback, fd)) - } -} - -fn main() { - let mut args = env::args().skip(1); - - let mut name = args.next().expect("ahcid: no name provided"); - name.push_str("_ahci"); - - let bar_str = args.next().expect("ahcid: no address provided"); - let bar = usize::from_str_radix(&bar_str, 16).expect("ahcid: failed to parse address"); - - let irq_str = args.next().expect("ahcid: no irq provided"); - let irq = irq_str.parse::().expect("ahcid: failed to parse irq"); - - print!("{}", format!(" + AHCI {} on: {:X} IRQ: {}\n", name, bar, irq)); - - // Daemonize - if unsafe { syscall::clone(0).unwrap() } == 0 { - let address = unsafe { syscall::physmap(bar, 4096, MAP_WRITE).expect("ahcid: failed to map address") }; - { - let (_scheme_name, socket_fd) = create_scheme_fallback("disk", &name).expect("ahcid: failed to create disk scheme"); - let mut socket = unsafe { File::from_raw_fd(socket_fd) }; - syscall::fevent(socket_fd, EVENT_READ).expect("ahcid: failed to fevent disk scheme"); - - let mut irq_file = File::open(&format!("irq:{}", irq)).expect("ahcid: failed to open irq file"); - let irq_fd = irq_file.as_raw_fd(); - syscall::fevent(irq_fd, EVENT_READ).expect("ahcid: failed to fevent irq file"); - - let mut event_file = File::open("event:").expect("ahcid: failed to open event file"); - - let scheme = DiskScheme::new(ahci::disks(address, &name)); - loop { - let mut event = Event::default(); - if event_file.read(&mut event).expect("ahcid: failed to read event file") == 0 { - break; - } - if event.id == socket_fd { - loop { - let mut packet = Packet::default(); - if socket.read(&mut packet).expect("ahcid: failed to read disk scheme") == 0 { - break; - } - scheme.handle(&mut packet); - socket.write(&mut packet).expect("ahcid: failed to write disk scheme"); - } - } else if event.id == irq_fd { - let mut irq = [0; 8]; - if irq_file.read(&mut irq).expect("ahcid: failed to read irq file") >= irq.len() { - //TODO : Test for IRQ - //irq_file.write(&irq).expect("ahcid: failed to write irq file"); - } - } else { - println!("Unknown event {}", event.id); - } - } - } - unsafe { let _ = syscall::physunmap(address); } - } -} diff --git a/drivers/ahcid/src/scheme.rs b/drivers/ahcid/src/scheme.rs deleted file mode 100644 index cd35d76..0000000 --- a/drivers/ahcid/src/scheme.rs +++ /dev/null @@ -1,166 +0,0 @@ -use std::collections::BTreeMap; -use std::{cmp, str}; -use std::fmt::Write; -use std::io::Read; -use std::sync::Arc; -use std::sync::atomic::{AtomicUsize, Ordering}; -use spin::Mutex; -use syscall::{Error, EACCES, EBADF, EINVAL, EISDIR, ENOENT, Result, Scheme, Stat, MODE_DIR, MODE_FILE, O_DIRECTORY, O_STAT, SEEK_CUR, SEEK_END, SEEK_SET}; - -use ahci::disk::Disk; - -#[derive(Clone)] -enum Handle { - //TODO: Make these enum variants normal tuples (), not nested tuples (()) - List((Vec, usize)), - Disk((Arc>, usize)) -} - -pub struct DiskScheme { - disks: Box<[Arc>]>, - handles: Mutex>, - next_id: AtomicUsize -} - -impl DiskScheme { - pub fn new(disks: Vec) -> DiskScheme { - let mut disk_arcs = vec![]; - for disk in disks { - disk_arcs.push(Arc::new(Mutex::new(disk))); - } - - DiskScheme { - disks: disk_arcs.into_boxed_slice(), - handles: Mutex::new(BTreeMap::new()), - next_id: AtomicUsize::new(0) - } - } -} - -impl Scheme for DiskScheme { - fn open(&self, path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result { - if uid == 0 { - let path_str = str::from_utf8(path).or(Err(Error::new(ENOENT)))?.trim_matches('/'); - if path_str.is_empty() { - if flags & O_DIRECTORY == O_DIRECTORY || flags & O_STAT == O_STAT { - let mut list = String::new(); - - for i in 0..self.disks.len() { - write!(list, "{}\n", i).unwrap(); - } - - let id = self.next_id.fetch_add(1, Ordering::SeqCst); - self.handles.lock().insert(id, Handle::List((list.into_bytes(), 0))); - Ok(id) - } else { - Err(Error::new(EISDIR)) - } - } else { - let i = path_str.parse::().or(Err(Error::new(ENOENT)))?; - - if let Some(disk) = self.disks.get(i) { - let id = self.next_id.fetch_add(1, Ordering::SeqCst); - self.handles.lock().insert(id, Handle::Disk((disk.clone(), 0))); - Ok(id) - } else { - Err(Error::new(ENOENT)) - } - } - } else { - Err(Error::new(EACCES)) - } - } - - fn dup(&self, id: usize, _buf: &[u8]) -> Result { - let mut handles = self.handles.lock(); - let new_handle = { - let handle = handles.get(&id).ok_or(Error::new(EBADF))?; - handle.clone() - }; - - let new_id = self.next_id.fetch_add(1, Ordering::SeqCst); - handles.insert(new_id, new_handle); - Ok(new_id) - } - - fn fstat(&self, id: usize, stat: &mut Stat) -> Result { - let handles = self.handles.lock(); - match *handles.get(&id).ok_or(Error::new(EBADF))? { - Handle::List(ref handle) => { - stat.st_mode = MODE_DIR; - stat.st_size = handle.0.len() as u64; - Ok(0) - }, - Handle::Disk(ref handle) => { - stat.st_mode = MODE_FILE; - stat.st_size = handle.0.lock().size(); - Ok(0) - } - } - } - - fn read(&self, id: usize, buf: &mut [u8]) -> Result { - let mut handles = self.handles.lock(); - match *handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(ref mut handle) => { - let count = (&handle.0[handle.1..]).read(buf).unwrap(); - handle.1 += count; - Ok(count) - }, - Handle::Disk(ref mut handle) => { - let mut disk = handle.0.lock(); - let count = disk.read((handle.1 as u64)/512, buf)?; - handle.1 += count; - Ok(count) - } - } - } - - fn write(&self, id: usize, buf: &[u8]) -> Result { - let mut handles = self.handles.lock(); - match *handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(_) => { - Err(Error::new(EBADF)) - }, - Handle::Disk(ref mut handle) => { - let mut disk = handle.0.lock(); - let count = disk.write((handle.1 as u64)/512, buf)?; - handle.1 += count; - Ok(count) - } - } - } - - fn seek(&self, id: usize, pos: usize, whence: usize) -> Result { - let mut handles = self.handles.lock(); - match *handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(ref mut handle) => { - let len = handle.0.len() as usize; - handle.1 = match whence { - SEEK_SET => cmp::min(len, pos), - SEEK_CUR => cmp::max(0, cmp::min(len as isize, handle.1 as isize + pos as isize)) as usize, - SEEK_END => cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize, - _ => return Err(Error::new(EINVAL)) - }; - - Ok(handle.1) - }, - Handle::Disk(ref mut handle) => { - let len = handle.0.lock().size() as usize; - handle.1 = match whence { - SEEK_SET => cmp::min(len, pos), - SEEK_CUR => cmp::max(0, cmp::min(len as isize, handle.1 as isize + pos as isize)) as usize, - SEEK_END => cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize, - _ => return Err(Error::new(EINVAL)) - }; - - Ok(handle.1) - } - } - } - - fn close(&self, id: usize) -> Result { - let mut handles = self.handles.lock(); - handles.remove(&id).ok_or(Error::new(EBADF)).and(Ok(0)) - } -} diff --git a/drivers/bgad/Cargo.toml b/drivers/bgad/Cargo.toml deleted file mode 100644 index c763e32..0000000 --- a/drivers/bgad/Cargo.toml +++ /dev/null @@ -1,3 +0,0 @@ -[package] -name = "bgad" -version = "0.1.0" diff --git a/drivers/bgad/src/main.rs b/drivers/bgad/src/main.rs deleted file mode 100644 index 48d75d7..0000000 --- a/drivers/bgad/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -use std::env; - -fn main() { - let mut args = env::args().skip(1); - - let mut name = args.next().expect("bgad: no name provided"); - name.push_str("_bga"); - - let bar_str = args.next().expect("bgad: no address provided"); - let bar = usize::from_str_radix(&bar_str, 16).expect("bgad: failed to parse address"); - - print!("{}", format!(" + BGA {} on: {:X}\n", name, bar)); -} diff --git a/drivers/e1000d/Cargo.toml b/drivers/e1000d/Cargo.toml deleted file mode 100644 index ec8c45e..0000000 --- a/drivers/e1000d/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "e1000d" -version = "0.1.0" - -[dependencies] -bitflags = "*" -dma = { path = "../../crates/dma/" } -event = { path = "../../crates/event/" } -io = { path = "../../crates/io/" } -netutils = { path = "../../programs/netutils/" } -redox_syscall = { path = "../../syscall/" } diff --git a/drivers/e1000d/src/device.rs b/drivers/e1000d/src/device.rs deleted file mode 100644 index 8cb46f3..0000000 --- a/drivers/e1000d/src/device.rs +++ /dev/null @@ -1,346 +0,0 @@ -use std::{cmp, mem, ptr, slice}; - -use dma::Dma; -use netutils::setcfg; -use syscall::error::{Error, EACCES, EWOULDBLOCK, Result}; -use syscall::flag::O_NONBLOCK; -use syscall::scheme::Scheme; - -const CTRL: u32 = 0x00; -const CTRL_LRST: u32 = 1 << 3; -const CTRL_ASDE: u32 = 1 << 5; -const CTRL_SLU: u32 = 1 << 6; -const CTRL_ILOS: u32 = 1 << 7; -const CTRL_VME: u32 = 1 << 30; -const CTRL_PHY_RST: u32 = 1 << 31; - -const STATUS: u32 = 0x08; - -const FCAL: u32 = 0x28; -const FCAH: u32 = 0x2C; -const FCT: u32 = 0x30; -const FCTTV: u32 = 0x170; - -const ICR: u32 = 0xC0; - -const IMS: u32 = 0xD0; -const IMS_TXDW: u32 = 1; -const IMS_TXQE: u32 = 1 << 1; -const IMS_LSC: u32 = 1 << 2; -const IMS_RXSEQ: u32 = 1 << 3; -const IMS_RXDMT: u32 = 1 << 4; -const IMS_RX: u32 = 1 << 6; -const IMS_RXT: u32 = 1 << 7; - -const RCTL: u32 = 0x100; -const RCTL_EN: u32 = 1 << 1; -const RCTL_UPE: u32 = 1 << 3; -const RCTL_MPE: u32 = 1 << 4; -const RCTL_LPE: u32 = 1 << 5; -const RCTL_LBM: u32 = 1 << 6 | 1 << 7; -const RCTL_BAM: u32 = 1 << 15; -const RCTL_BSIZE1: u32 = 1 << 16; -const RCTL_BSIZE2: u32 = 1 << 17; -const RCTL_BSEX: u32 = 1 << 25; -const RCTL_SECRC: u32 = 1 << 26; - -const RDBAL: u32 = 0x2800; -const RDBAH: u32 = 0x2804; -const RDLEN: u32 = 0x2808; -const RDH: u32 = 0x2810; -const RDT: u32 = 0x2818; - -const RAL0: u32 = 0x5400; -const RAH0: u32 = 0x5404; - -#[derive(Debug)] -#[repr(packed)] -struct Rd { - buffer: u64, - length: u16, - checksum: u16, - status: u8, - error: u8, - special: u16, -} -const RD_DD: u8 = 1; -const RD_EOP: u8 = 1 << 1; - -const TCTL: u32 = 0x400; -const TCTL_EN: u32 = 1 << 1; -const TCTL_PSP: u32 = 1 << 3; - -const TDBAL: u32 = 0x3800; -const TDBAH: u32 = 0x3804; -const TDLEN: u32 = 0x3808; -const TDH: u32 = 0x3810; -const TDT: u32 = 0x3818; - -#[derive(Debug)] -#[repr(packed)] -struct Td { - buffer: u64, - length: u16, - cso: u8, - command: u8, - status: u8, - css: u8, - special: u16, -} -const TD_CMD_EOP: u8 = 1; -const TD_CMD_IFCS: u8 = 1 << 1; -const TD_CMD_RS: u8 = 1 << 3; -const TD_DD: u8 = 1; - -pub struct Intel8254x { - base: usize, - receive_buffer: [Dma<[u8; 16384]>; 16], - receive_ring: Dma<[Rd; 16]>, - transmit_buffer: [Dma<[u8; 16384]>; 16], - transmit_ring: Dma<[Td; 16]> -} - -impl Scheme for Intel8254x { - fn open(&self, _path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result { - if uid == 0 { - Ok(flags) - } else { - Err(Error::new(EACCES)) - } - } - - fn dup(&self, id: usize, _buf: &[u8]) -> Result { - Ok(id) - } - - fn read(&self, id: usize, buf: &mut [u8]) -> Result { - let head = unsafe { self.read(RDH) }; - let mut tail = unsafe { self.read(RDT) }; - - tail += 1; - if tail >= self.receive_ring.len() as u32 { - tail = 0; - } - - if tail != head { - let rd = unsafe { &mut * (self.receive_ring.as_ptr().offset(tail as isize) as *mut Rd) }; - if rd.status & RD_DD == RD_DD { - rd.status = 0; - - let data = &self.receive_buffer[tail as usize][.. rd.length as usize]; - - let mut i = 0; - while i < buf.len() && i < data.len() { - buf[i] = data[i]; - i += 1; - } - - unsafe { self.write(RDT, tail) }; - - return Ok(i); - } - } - - if id & O_NONBLOCK == O_NONBLOCK { - Ok(0) - } else { - Err(Error::new(EWOULDBLOCK)) - } - } - - fn write(&self, _id: usize, buf: &[u8]) -> Result { - loop { - let head = unsafe { self.read(TDH) }; - let mut tail = unsafe { self.read(TDT) }; - let old_tail = tail; - - tail += 1; - if tail >= self.transmit_ring.len() as u32 { - tail = 0; - } - - if tail != head { - let td = unsafe { &mut * (self.transmit_ring.as_ptr().offset(old_tail as isize) as *mut Td) }; - - td.cso = 0; - td.command = TD_CMD_EOP | TD_CMD_IFCS | TD_CMD_RS; - td.status = 0; - td.css = 0; - td.special = 0; - - td.length = (cmp::min(buf.len(), 0x3FFF)) as u16; - - let mut data = unsafe { slice::from_raw_parts_mut(self.transmit_buffer[old_tail as usize].as_ptr() as *mut u8, td.length as usize) }; - - let mut i = 0; - while i < buf.len() && i < data.len() { - data[i] = buf[i]; - i += 1; - } - - unsafe { self.write(TDT, tail) }; - - while td.status == 0 { - unsafe { asm!("pause" : : : "memory" : "intel", "volatile"); } - } - - return Ok(i); - } - - unsafe { asm!("pause" : : : "memory" : "intel", "volatile"); } - } - } - - fn fevent(&self, _id: usize, _flags: usize) -> Result { - Ok(0) - } - - fn fsync(&self, _id: usize) -> Result { - Ok(0) - } - - fn close(&self, _id: usize) -> Result { - Ok(0) - } -} - -impl Intel8254x { - pub unsafe fn new(base: usize) -> Result { - let mut module = Intel8254x { - base: base, - receive_buffer: [Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?], - receive_ring: Dma::zeroed()?, - transmit_buffer: [Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?], - transmit_ring: Dma::zeroed()? - }; - - module.init(); - - Ok(module) - } - - pub unsafe fn irq(&self) -> bool { - let icr = self.read(ICR); - icr != 0 - } - - pub fn next_read(&self) -> usize { - let head = unsafe { self.read(RDH) }; - let mut tail = unsafe { self.read(RDT) }; - - tail += 1; - if tail >= self.receive_ring.len() as u32 { - tail = 0; - } - - if tail != head { - let rd = unsafe { &* (self.receive_ring.as_ptr().offset(tail as isize) as *const Rd) }; - if rd.status & RD_DD == RD_DD { - return rd.length as usize; - } - } - - 0 - } - - pub unsafe fn read(&self, register: u32) -> u32 { - ptr::read_volatile((self.base + register as usize) as *mut u32) - } - - pub unsafe fn write(&self, register: u32, data: u32) -> u32 { - ptr::write_volatile((self.base + register as usize) as *mut u32, data); - ptr::read_volatile((self.base + register as usize) as *mut u32) - } - - pub unsafe fn flag(&self, register: u32, flag: u32, value: bool) { - if value { - self.write(register, self.read(register) | flag); - } else { - self.write(register, self.read(register) & (0xFFFFFFFF - flag)); - } - } - - pub unsafe fn init(&mut self) { - // Enable auto negotiate, link, clear reset, do not Invert Loss-Of Signal - self.flag(CTRL, CTRL_ASDE | CTRL_SLU, true); - self.flag(CTRL, CTRL_LRST, false); - self.flag(CTRL, CTRL_PHY_RST, false); - self.flag(CTRL, CTRL_ILOS, false); - - // No flow control - self.write(FCAH, 0); - self.write(FCAL, 0); - self.write(FCT, 0); - self.write(FCTTV, 0); - - // Do not use VLANs - self.flag(CTRL, CTRL_VME, false); - - // TODO: Clear statistical counters - - let mac_low = self.read(RAL0); - let mac_high = self.read(RAH0); - let mac = [mac_low as u8, - (mac_low >> 8) as u8, - (mac_low >> 16) as u8, - (mac_low >> 24) as u8, - mac_high as u8, - (mac_high >> 8) as u8]; - print!("{}", format!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); - let _ = setcfg("mac", &format!("{:>02X}.{:>02X}.{:>02X}.{:>02X}.{:>02X}.{:>02X}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); - - // - // MTA => 0; - // - - // Receive Buffer - for i in 0..self.receive_ring.len() { - self.receive_ring[i].buffer = self.receive_buffer[i].physical() as u64; - } - - self.write(RDBAH, (self.receive_ring.physical() >> 32) as u32); - self.write(RDBAL, self.receive_ring.physical() as u32); - self.write(RDLEN, (self.receive_ring.len() * mem::size_of::()) as u32); - self.write(RDH, 0); - self.write(RDT, self.receive_ring.len() as u32 - 1); - - // Transmit Buffer - for i in 0..self.transmit_ring.len() { - self.transmit_ring[i].buffer = self.transmit_buffer[i].physical() as u64; - } - - self.write(TDBAH, (self.transmit_ring.physical() >> 32) as u32); - self.write(TDBAL, self.transmit_ring.physical() as u32); - self.write(TDLEN, (self.transmit_ring.len() * mem::size_of::()) as u32); - self.write(TDH, 0); - self.write(TDT, 0); - - self.write(IMS, IMS_RXT | IMS_RX | IMS_RXDMT | IMS_RXSEQ); // | IMS_LSC | IMS_TXQE | IMS_TXDW - - self.flag(RCTL, RCTL_EN, true); - self.flag(RCTL, RCTL_UPE, true); - // self.flag(RCTL, RCTL_MPE, true); - self.flag(RCTL, RCTL_LPE, true); - self.flag(RCTL, RCTL_LBM, false); - // RCTL.RDMTS = Minimum threshold size ??? - // RCTL.MO = Multicast offset - self.flag(RCTL, RCTL_BAM, true); - self.flag(RCTL, RCTL_BSIZE1, true); - self.flag(RCTL, RCTL_BSIZE2, false); - self.flag(RCTL, RCTL_BSEX, true); - self.flag(RCTL, RCTL_SECRC, true); - - self.flag(TCTL, TCTL_EN, true); - self.flag(TCTL, TCTL_PSP, true); - // TCTL.CT = Collision threshold - // TCTL.COLD = Collision distance - // TIPG Packet Gap - // TODO ... - } -} diff --git a/drivers/e1000d/src/main.rs b/drivers/e1000d/src/main.rs deleted file mode 100644 index b690029..0000000 --- a/drivers/e1000d/src/main.rs +++ /dev/null @@ -1,136 +0,0 @@ -#![feature(asm)] - -extern crate dma; -extern crate event; -extern crate netutils; -extern crate syscall; - -use std::cell::RefCell; -use std::env; -use std::fs::File; -use std::io::{Read, Write, Result}; -use std::os::unix::io::{AsRawFd, FromRawFd}; -use std::sync::Arc; - -use event::EventQueue; -use syscall::{Packet, Scheme, MAP_WRITE}; -use syscall::error::EWOULDBLOCK; - -pub mod device; - -fn main() { - let mut args = env::args().skip(1); - - let mut name = args.next().expect("e1000d: no name provided"); - name.push_str("_e1000"); - - let bar_str = args.next().expect("e1000d: no address provided"); - let bar = usize::from_str_radix(&bar_str, 16).expect("e1000d: failed to parse address"); - - let irq_str = args.next().expect("e1000d: no irq provided"); - let irq = irq_str.parse::().expect("e1000d: failed to parse irq"); - - print!("{}", format!(" + E1000 {} on: {:X}, IRQ: {}\n", name, bar, irq)); - - // Daemonize - if unsafe { syscall::clone(0).unwrap() } == 0 { - let socket_fd = syscall::open(":network", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK).expect("e1000d: failed to create network scheme"); - let socket = Arc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd) })); - - let address = unsafe { syscall::physmap(bar, 128*1024, MAP_WRITE).expect("e1000d: failed to map address") }; - { - let device = Arc::new(unsafe { device::Intel8254x::new(address).expect("e1000d: failed to allocate device") }); - - let mut event_queue = EventQueue::::new().expect("e1000d: failed to create event queue"); - - let todo = Arc::new(RefCell::new(Vec::::new())); - - let device_irq = device.clone(); - let socket_irq = socket.clone(); - let todo_irq = todo.clone(); - let mut irq_file = File::open(format!("irq:{}", irq)).expect("e1000d: failed to open IRQ file"); - event_queue.add(irq_file.as_raw_fd(), move |_count: usize| -> Result> { - let mut irq = [0; 8]; - irq_file.read(&mut irq)?; - if unsafe { device_irq.irq() } { - irq_file.write(&mut irq)?; - - let mut todo = todo_irq.borrow_mut(); - let mut i = 0; - while i < todo.len() { - let a = todo[i].a; - device_irq.handle(&mut todo[i]); - if todo[i].a == (-EWOULDBLOCK) as usize { - todo[i].a = a; - i += 1; - } else { - socket_irq.borrow_mut().write(&mut todo[i])?; - todo.remove(i); - } - } - - let next_read = device_irq.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - } - Ok(None) - }).expect("e1000d: failed to catch events on IRQ file"); - - let socket_packet = socket.clone(); - event_queue.add(socket_fd, move |_count: usize| -> Result> { - loop { - let mut packet = Packet::default(); - if socket_packet.borrow_mut().read(&mut packet)? == 0 { - break; - } - - let a = packet.a; - device.handle(&mut packet); - if packet.a == (-EWOULDBLOCK) as usize { - packet.a = a; - todo.borrow_mut().push(packet); - } else { - socket_packet.borrow_mut().write(&mut packet)?; - } - } - - let next_read = device.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - - Ok(None) - }).expect("e1000d: failed to catch events on IRQ file"); - - for event_count in event_queue.trigger_all(0).expect("e1000d: failed to trigger events") { - socket.borrow_mut().write(&Packet { - id: 0, - pid: 0, - uid: 0, - gid: 0, - a: syscall::number::SYS_FEVENT, - b: 0, - c: syscall::flag::EVENT_READ, - d: event_count - }).expect("e1000d: failed to write event"); - } - - loop { - let event_count = event_queue.run().expect("e1000d: failed to handle events"); - - socket.borrow_mut().write(&Packet { - id: 0, - pid: 0, - uid: 0, - gid: 0, - a: syscall::number::SYS_FEVENT, - b: 0, - c: syscall::flag::EVENT_READ, - d: event_count - }).expect("e1000d: failed to write event"); - } - } - unsafe { let _ = syscall::physunmap(address); } - } -} diff --git a/drivers/pcid/Cargo.toml b/drivers/pcid/Cargo.toml deleted file mode 100644 index f09b85a..0000000 --- a/drivers/pcid/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "pcid" -version = "0.1.0" - -[dependencies] -redox_syscall = { path = "../../syscall/" } -rustc-serialize = "0.3" -toml = "0.2" diff --git a/drivers/pcid/src/config.rs b/drivers/pcid/src/config.rs deleted file mode 100644 index 3bc4dba..0000000 --- a/drivers/pcid/src/config.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[derive(Debug, Default, RustcDecodable)] -pub struct Config { - pub drivers: Vec -} - -#[derive(Debug, Default, RustcDecodable)] -pub struct DriverConfig { - pub name: Option, - pub class: Option, - pub subclass: Option, - pub vendor: Option, - pub device: Option, - pub command: Option> -} diff --git a/drivers/pcid/src/main.rs b/drivers/pcid/src/main.rs deleted file mode 100644 index 8202d6f..0000000 --- a/drivers/pcid/src/main.rs +++ /dev/null @@ -1,160 +0,0 @@ -#![feature(asm)] - -extern crate rustc_serialize; -extern crate syscall; -extern crate toml; - -use std::env; -use std::fs::File; -use std::io::Read; -use std::process::Command; -use syscall::iopl; - -use config::Config; -use pci::{Pci, PciBar, PciClass}; - -mod config; -mod pci; - -fn main() { - let mut config = Config::default(); - - let mut args = env::args().skip(1); - if let Some(config_path) = args.next() { - if let Ok(mut config_file) = File::open(&config_path) { - let mut config_data = String::new(); - if let Ok(_) = config_file.read_to_string(&mut config_data) { - config = toml::decode_str(&config_data).unwrap_or(Config::default()); - } - } - } - - unsafe { iopl(3).unwrap() }; - - print!("PCI BS/DV/FN VEND:DEVI CL.SC.IN.RV\n"); - - let pci = Pci::new(); - for bus in pci.buses() { - for dev in bus.devs() { - for func in dev.funcs() { - if let Some(header) = func.header() { - let pci_class = PciClass::from(header.class); - - let mut string = format!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X} {:?}", - bus.num, dev.num, func.num, - header.vendor_id, header.device_id, - header.class, header.subclass, header.interface, header.revision, - pci_class); - - match pci_class { - PciClass::Storage => match header.subclass { - 0x01 => { - string.push_str(" IDE"); - }, - 0x06 => { - string.push_str(" SATA"); - }, - _ => () - }, - PciClass::SerialBus => match header.subclass { - 0x03 => match header.interface { - 0x00 => { - string.push_str(" UHCI"); - }, - 0x10 => { - string.push_str(" OHCI"); - }, - 0x20 => { - string.push_str(" EHCI"); - }, - 0x30 => { - string.push_str(" XHCI"); - }, - _ => () - }, - _ => () - }, - _ => () - } - - for i in 0..header.bars.len() { - match PciBar::from(header.bars[i]) { - PciBar::None => (), - PciBar::Memory(address) => string.push_str(&format!(" {}={:>08X}", i, address)), - PciBar::Port(address) => string.push_str(&format!(" {}={:>04X}", i, address)) - } - } - - string.push('\n'); - - print!("{}", string); - - for driver in config.drivers.iter() { - if let Some(class) = driver.class { - if class != header.class { continue; } - } - - if let Some(subclass) = driver.subclass { - if subclass != header.subclass { continue; } - } - - if let Some(vendor) = driver.vendor { - if vendor != header.vendor_id { continue; } - } - - if let Some(device) = driver.device { - if device != header.device_id { continue; } - } - - if let Some(ref args) = driver.command { - // Enable bus mastering - unsafe { - let cmd = pci.read(bus.num, dev.num, func.num, 0x04); - pci.write(bus.num, dev.num, func.num, 0x04, cmd | 4); - } - - let mut args = args.iter(); - if let Some(program) = args.next() { - let mut command = Command::new(program); - for arg in args { - let bar_arg = |i| -> String { - match PciBar::from(header.bars[i]) { - PciBar::None => String::new(), - PciBar::Memory(address) => format!("{:>08X}", address), - PciBar::Port(address) => format!("{:>04X}", address) - } - }; - let arg = match arg.as_str() { - "$BUS" => format!("{:>02X}", bus.num), - "$DEV" => format!("{:>02X}", dev.num), - "$FUNC" => format!("{:>02X}", func.num), - "$NAME" => format!("pci-{:>02X}.{:>02X}.{:>02X}", bus.num, dev.num, func.num), - "$BAR0" => bar_arg(0), - "$BAR1" => bar_arg(1), - "$BAR2" => bar_arg(2), - "$BAR3" => bar_arg(3), - "$BAR4" => bar_arg(4), - "$BAR5" => bar_arg(5), - "$IRQ" => format!("{}", header.interrupt_line), - _ => arg.clone() - }; - command.arg(&arg); - } - - println!("PCID SPAWN {:?}", command); - - match command.spawn() { - Ok(mut child) => match child.wait() { - Ok(_status) => (), //println!("pcid: waited for {}: {:?}", line, status.code()), - Err(err) => println!("pcid: failed to wait for {:?}: {}", command, err) - }, - Err(err) => println!("pcid: failed to execute {:?}: {}", command, err) - } - } - } - } - } - } - } - } -} diff --git a/drivers/pcid/src/pci/bar.rs b/drivers/pcid/src/pci/bar.rs deleted file mode 100644 index 190fa05..0000000 --- a/drivers/pcid/src/pci/bar.rs +++ /dev/null @@ -1,18 +0,0 @@ -#[derive(Debug)] -pub enum PciBar { - None, - Memory(u32), - Port(u16) -} - -impl From for PciBar { - fn from(bar: u32) -> Self { - if bar & 0xFFFFFFFC == 0 { - PciBar::None - } else if bar & 1 == 0 { - PciBar::Memory(bar & 0xFFFFFFF0) - } else { - PciBar::Port((bar & 0xFFFC) as u16) - } - } -} diff --git a/drivers/pcid/src/pci/bus.rs b/drivers/pcid/src/pci/bus.rs deleted file mode 100644 index 120fa45..0000000 --- a/drivers/pcid/src/pci/bus.rs +++ /dev/null @@ -1,46 +0,0 @@ -use super::{Pci, PciDev}; - -pub struct PciBus<'pci> { - pub pci: &'pci Pci, - pub num: u8 -} - -impl<'pci> PciBus<'pci> { - pub fn devs(&'pci self) -> PciBusIter<'pci> { - PciBusIter::new(self) - } - - pub unsafe fn read(&self, dev: u8, func: u8, offset: u8) -> u32 { - self.pci.read(self.num, dev, func, offset) - } -} - -pub struct PciBusIter<'pci> { - bus: &'pci PciBus<'pci>, - num: u32 -} - -impl<'pci> PciBusIter<'pci> { - pub fn new(bus: &'pci PciBus<'pci>) -> Self { - PciBusIter { - bus: bus, - num: 0 - } - } -} - -impl<'pci> Iterator for PciBusIter<'pci> { - type Item = PciDev<'pci>; - fn next(&mut self) -> Option { - if self.num < 32 { - let dev = PciDev { - bus: self.bus, - num: self.num as u8 - }; - self.num += 1; - Some(dev) - } else { - None - } - } -} diff --git a/drivers/pcid/src/pci/class.rs b/drivers/pcid/src/pci/class.rs deleted file mode 100644 index 21f7f69..0000000 --- a/drivers/pcid/src/pci/class.rs +++ /dev/null @@ -1,50 +0,0 @@ -#[derive(Debug)] -pub enum PciClass { - Legacy, - Storage, - Network, - Display, - Multimedia, - Memory, - Bridge, - SimpleComms, - Peripheral, - Input, - Docking, - Processor, - SerialBus, - Wireless, - IntelligentIo, - SatelliteComms, - Cryptography, - SignalProc, - Reserved(u8), - Unknown -} - -impl From for PciClass { - fn from(class: u8) -> PciClass { - match class { - 0x00 => PciClass::Legacy, - 0x01 => PciClass::Storage, - 0x02 => PciClass::Network, - 0x03 => PciClass::Display, - 0x04 => PciClass::Multimedia, - 0x05 => PciClass::Memory, - 0x06 => PciClass::Bridge, - 0x07 => PciClass::SimpleComms, - 0x08 => PciClass::Peripheral, - 0x09 => PciClass::Input, - 0x0A => PciClass::Docking, - 0x0B => PciClass::Processor, - 0x0C => PciClass::SerialBus, - 0x0D => PciClass::Wireless, - 0x0E => PciClass::IntelligentIo, - 0x0F => PciClass::SatelliteComms, - 0x10 => PciClass::Cryptography, - 0x11 => PciClass::SignalProc, - 0xFF => PciClass::Unknown, - reserved => PciClass::Reserved(reserved) - } - } -} diff --git a/drivers/pcid/src/pci/dev.rs b/drivers/pcid/src/pci/dev.rs deleted file mode 100644 index 0508888..0000000 --- a/drivers/pcid/src/pci/dev.rs +++ /dev/null @@ -1,46 +0,0 @@ -use super::{PciBus, PciFunc}; - -pub struct PciDev<'pci> { - pub bus: &'pci PciBus<'pci>, - pub num: u8 -} - -impl<'pci> PciDev<'pci> { - pub fn funcs(&'pci self) -> PciDevIter<'pci> { - PciDevIter::new(self) - } - - pub unsafe fn read(&self, func: u8, offset: u8) -> u32 { - self.bus.read(self.num, func, offset) - } -} - -pub struct PciDevIter<'pci> { - dev: &'pci PciDev<'pci>, - num: u32 -} - -impl<'pci> PciDevIter<'pci> { - pub fn new(dev: &'pci PciDev<'pci>) -> Self { - PciDevIter { - dev: dev, - num: 0 - } - } -} - -impl<'pci> Iterator for PciDevIter<'pci> { - type Item = PciFunc<'pci>; - fn next(&mut self) -> Option { - if self.num < 8 { - let func = PciFunc { - dev: self.dev, - num: self.num as u8 - }; - self.num += 1; - Some(func) - } else { - None - } - } -} diff --git a/drivers/pcid/src/pci/func.rs b/drivers/pcid/src/pci/func.rs deleted file mode 100644 index 578e5c6..0000000 --- a/drivers/pcid/src/pci/func.rs +++ /dev/null @@ -1,30 +0,0 @@ -use std::ops::DerefMut; - -use super::{PciDev, PciHeader}; - -pub struct PciFunc<'pci> { - pub dev: &'pci PciDev<'pci>, - pub num: u8 -} - -impl<'pci> PciFunc<'pci> { - pub fn header(&self) -> Option { - if unsafe { self.read(0) } != 0xFFFFFFFF { - let mut header = PciHeader::default(); - { - let dwords = header.deref_mut(); - dwords.iter_mut().fold(0usize, |offset, dword| { - *dword = unsafe { self.read(offset as u8) }; - offset + 4 - }); - } - Some(header) - } else { - None - } - } - - pub unsafe fn read(&self, offset: u8) -> u32 { - self.dev.read(self.num, offset) - } -} diff --git a/drivers/pcid/src/pci/header.rs b/drivers/pcid/src/pci/header.rs deleted file mode 100644 index 2cc335e..0000000 --- a/drivers/pcid/src/pci/header.rs +++ /dev/null @@ -1,43 +0,0 @@ -use std::ops::{Deref, DerefMut}; -use std::{slice, mem}; - -#[derive(Debug, Default)] -#[repr(packed)] -pub struct PciHeader { - pub vendor_id: u16, - pub device_id: u16, - pub command: u16, - pub status: u16, - pub revision: u8, - pub interface: u8, - pub subclass: u8, - pub class: u8, - pub cache_line_size: u8, - pub latency_timer: u8, - pub header_type: u8, - pub bist: u8, - pub bars: [u32; 6], - pub cardbus_cis_ptr: u32, - pub subsystem_vendor_id: u16, - pub subsystem_id: u16, - pub expansion_rom_bar: u32, - pub capabilities: u8, - pub reserved: [u8; 7], - pub interrupt_line: u8, - pub interrupt_pin: u8, - pub min_grant: u8, - pub max_latency: u8 -} - -impl Deref for PciHeader { - type Target = [u32]; - fn deref(&self) -> &[u32] { - unsafe { slice::from_raw_parts(self as *const PciHeader as *const u32, mem::size_of::()/4) as &[u32] } - } -} - -impl DerefMut for PciHeader { - fn deref_mut(&mut self) -> &mut [u32] { - unsafe { slice::from_raw_parts_mut(self as *mut PciHeader as *mut u32, mem::size_of::()/4) as &mut [u32] } - } -} diff --git a/drivers/pcid/src/pci/mod.rs b/drivers/pcid/src/pci/mod.rs deleted file mode 100644 index d2a8e89..0000000 --- a/drivers/pcid/src/pci/mod.rs +++ /dev/null @@ -1,78 +0,0 @@ -pub use self::bar::PciBar; -pub use self::bus::{PciBus, PciBusIter}; -pub use self::class::PciClass; -pub use self::dev::{PciDev, PciDevIter}; -pub use self::func::PciFunc; -pub use self::header::PciHeader; - -mod bar; -mod bus; -mod class; -mod dev; -mod func; -mod header; - -pub struct Pci; - -impl Pci { - pub fn new() -> Self { - Pci - } - - pub fn buses<'pci>(&'pci self) -> PciIter<'pci> { - PciIter::new(self) - } - - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] - pub unsafe fn read(&self, bus: u8, dev: u8, func: u8, offset: u8) -> u32 { - let address = 0x80000000 | ((bus as u32) << 16) | ((dev as u32) << 11) | ((func as u32) << 8) | ((offset as u32) & 0xFC); - let value: u32; - asm!("mov dx, 0xCF8 - out dx, eax - mov dx, 0xCFC - in eax, dx" - : "={eax}"(value) : "{eax}"(address) : "dx" : "intel", "volatile"); - value - } - - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] - pub unsafe fn write(&self, bus: u8, dev: u8, func: u8, offset: u8, value: u32) { - let address = 0x80000000 | ((bus as u32) << 16) | ((dev as u32) << 11) | ((func as u32) << 8) | ((offset as u32) & 0xFC); - asm!("mov dx, 0xCF8 - out dx, eax" - : : "{eax}"(address) : "dx" : "intel", "volatile"); - asm!("mov dx, 0xCFC - out dx, eax" - : : "{eax}"(value) : "dx" : "intel", "volatile"); - } -} - -pub struct PciIter<'pci> { - pci: &'pci Pci, - num: u32 -} - -impl<'pci> PciIter<'pci> { - pub fn new(pci: &'pci Pci) -> Self { - PciIter { - pci: pci, - num: 0 - } - } -} - -impl<'pci> Iterator for PciIter<'pci> { - type Item = PciBus<'pci>; - fn next(&mut self) -> Option { - if self.num < 256 { - let bus = PciBus { - pci: self.pci, - num: self.num as u8 - }; - self.num += 1; - Some(bus) - } else { - None - } - } -} diff --git a/drivers/ps2d/Cargo.toml b/drivers/ps2d/Cargo.toml deleted file mode 100644 index 22863b9..0000000 --- a/drivers/ps2d/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "ps2d" -version = "0.1.0" - -[dependencies] -bitflags = "*" -event = { path = "../../crates/event/" } -io = { path = "../../crates/io/" } -orbclient = "0.2" -redox_syscall = { path = "../../syscall/" } diff --git a/drivers/ps2d/src/controller.rs b/drivers/ps2d/src/controller.rs deleted file mode 100644 index e68d4f1..0000000 --- a/drivers/ps2d/src/controller.rs +++ /dev/null @@ -1,233 +0,0 @@ -use io::{Io, Pio, ReadOnly, WriteOnly}; - -bitflags! { - flags StatusFlags: u8 { - const OUTPUT_FULL = 1, - const INPUT_FULL = 1 << 1, - const SYSTEM = 1 << 2, - const COMMAND = 1 << 3, - // Chipset specific - const KEYBOARD_LOCK = 1 << 4, - // Chipset specific - const SECOND_OUTPUT_FULL = 1 << 5, - const TIME_OUT = 1 << 6, - const PARITY = 1 << 7 - } -} - -bitflags! { - flags ConfigFlags: u8 { - const FIRST_INTERRUPT = 1, - const SECOND_INTERRUPT = 1 << 1, - const POST_PASSED = 1 << 2, - // 1 << 3 should be zero - const CONFIG_RESERVED_3 = 1 << 3, - const FIRST_DISABLED = 1 << 4, - const SECOND_DISABLED = 1 << 5, - const FIRST_TRANSLATE = 1 << 6, - // 1 << 7 should be zero - const CONFIG_RESERVED_7 = 1 << 7, - } -} - -#[repr(u8)] -#[allow(dead_code)] -enum Command { - ReadConfig = 0x20, - WriteConfig = 0x60, - DisableSecond = 0xA7, - EnableSecond = 0xA8, - TestSecond = 0xA9, - TestController = 0xAA, - TestFirst = 0xAB, - Diagnostic = 0xAC, - DisableFirst = 0xAD, - EnableFirst = 0xAE, - WriteSecond = 0xD4 -} - -#[repr(u8)] -#[allow(dead_code)] -enum KeyboardCommand { - EnableReporting = 0xF4, - SetDefaults = 0xF6, - Reset = 0xFF -} - -#[repr(u8)] -enum KeyboardCommandData { - ScancodeSet = 0xF0 -} - -#[repr(u8)] -#[allow(dead_code)] -enum MouseCommand { - GetDeviceId = 0xF2, - EnableReporting = 0xF4, - SetDefaults = 0xF6, - Reset = 0xFF -} - -#[repr(u8)] -enum MouseCommandData { - SetSampleRate = 0xF3, -} - -pub struct Ps2 { - data: Pio, - status: ReadOnly>, - command: WriteOnly> -} - -impl Ps2 { - pub fn new() -> Self { - Ps2 { - data: Pio::new(0x60), - status: ReadOnly::new(Pio::new(0x64)), - command: WriteOnly::new(Pio::new(0x64)), - } - } - - fn status(&mut self) -> StatusFlags { - StatusFlags::from_bits_truncate(self.status.read()) - } - - fn wait_write(&mut self) { - while self.status().contains(INPUT_FULL) {} - } - - fn wait_read(&mut self) { - while ! self.status().contains(OUTPUT_FULL) {} - } - - fn flush_read(&mut self) { - while self.status().contains(OUTPUT_FULL) { - print!("FLUSH: {:X}\n", self.data.read()); - } - } - - fn command(&mut self, command: Command) { - self.wait_write(); - self.command.write(command as u8); - } - - fn read(&mut self) -> u8 { - self.wait_read(); - self.data.read() - } - - fn write(&mut self, data: u8) { - self.wait_write(); - self.data.write(data); - } - - fn config(&mut self) -> ConfigFlags { - self.command(Command::ReadConfig); - ConfigFlags::from_bits_truncate(self.read()) - } - - fn set_config(&mut self, config: ConfigFlags) { - self.command(Command::WriteConfig); - self.write(config.bits()); - } - - fn keyboard_command(&mut self, command: KeyboardCommand) -> u8 { - self.write(command as u8); - self.read() - } - - fn keyboard_command_data(&mut self, command: KeyboardCommandData, data: u8) -> u8 { - self.write(command as u8); - assert_eq!(self.read(), 0xFA); - self.write(data as u8); - self.read() - } - - fn mouse_command(&mut self, command: MouseCommand) -> u8 { - self.command(Command::WriteSecond); - self.write(command as u8); - self.read() - } - - fn mouse_command_data(&mut self, command: MouseCommandData, data: u8) -> u8 { - self.command(Command::WriteSecond); - self.write(command as u8); - assert_eq!(self.read(), 0xFA); - self.command(Command::WriteSecond); - self.write(data as u8); - self.read() - } - - pub fn init(&mut self) -> bool { - // Disable devices - self.command(Command::DisableFirst); - self.command(Command::DisableSecond); - - // Clear remaining data - self.flush_read(); - - // Disable clocks, disable interrupts, and disable translate - { - let mut config = self.config(); - config.insert(FIRST_DISABLED); - config.insert(SECOND_DISABLED); - config.remove(FIRST_TRANSLATE); - config.remove(FIRST_INTERRUPT); - config.remove(SECOND_INTERRUPT); - self.set_config(config); - } - - // Perform the self test - self.command(Command::TestController); - assert_eq!(self.read(), 0x55); - - // Enable devices - self.command(Command::EnableFirst); - self.command(Command::EnableSecond); - - // Reset keyboard - assert_eq!(self.keyboard_command(KeyboardCommand::Reset), 0xFA); - assert_eq!(self.read(), 0xAA); - self.flush_read(); - - // Set scancode set to 2 - assert_eq!(self.keyboard_command_data(KeyboardCommandData::ScancodeSet, 2), 0xFA); - - // Reset mouse and set up scroll - // TODO: Check for ack - assert_eq!(self.mouse_command(MouseCommand::Reset), 0xFA); - assert_eq!(self.read(), 0xAA); - assert_eq!(self.read(), 0x00); - self.flush_read(); - - // Enable extra packet on mouse - assert_eq!(self.mouse_command_data(MouseCommandData::SetSampleRate, 200), 0xFA); - assert_eq!(self.mouse_command_data(MouseCommandData::SetSampleRate, 100), 0xFA); - assert_eq!(self.mouse_command_data(MouseCommandData::SetSampleRate, 80), 0xFA); - assert_eq!(self.mouse_command(MouseCommand::GetDeviceId), 0xFA); - let mouse_id = self.read(); - let mouse_extra = mouse_id == 3; - - // Set sample rate to maximum - assert_eq!(self.mouse_command_data(MouseCommandData::SetSampleRate, 200), 0xFA); - - // Enable data reporting - assert_eq!(self.keyboard_command(KeyboardCommand::EnableReporting), 0xFA); - assert_eq!(self.mouse_command(MouseCommand::EnableReporting), 0xFA); - - // Enable clocks and interrupts - { - let mut config = self.config(); - config.remove(FIRST_DISABLED); - config.remove(SECOND_DISABLED); - config.insert(FIRST_TRANSLATE); - config.insert(FIRST_INTERRUPT); - config.insert(SECOND_INTERRUPT); - self.set_config(config); - } - - self.flush_read(); - - mouse_extra - } -} diff --git a/drivers/ps2d/src/keymap.rs b/drivers/ps2d/src/keymap.rs deleted file mode 100644 index 5697e52..0000000 --- a/drivers/ps2d/src/keymap.rs +++ /dev/null @@ -1,148 +0,0 @@ -pub mod english { - static ENGLISH: [[char; 2]; 58] = [ - ['\0', '\0'], - ['\x1B', '\x1B'], - ['1', '!'], - ['2', '@'], - ['3', '#'], - ['4', '$'], - ['5', '%'], - ['6', '^'], - ['7', '&'], - ['8', '*'], - ['9', '('], - ['0', ')'], - ['-', '_'], - ['=', '+'], - ['\x7F', '\x7F'], - ['\t', '\t'], - ['q', 'Q'], - ['w', 'W'], - ['e', 'E'], - ['r', 'R'], - ['t', 'T'], - ['y', 'Y'], - ['u', 'U'], - ['i', 'I'], - ['o', 'O'], - ['p', 'P'], - ['[', '{'], - [']', '}'], - ['\n', '\n'], - ['\0', '\0'], - ['a', 'A'], - ['s', 'S'], - ['d', 'D'], - ['f', 'F'], - ['g', 'G'], - ['h', 'H'], - ['j', 'J'], - ['k', 'K'], - ['l', 'L'], - [';', ':'], - ['\'', '"'], - ['`', '~'], - ['\0', '\0'], - ['\\', '|'], - ['z', 'Z'], - ['x', 'X'], - ['c', 'C'], - ['v', 'V'], - ['b', 'B'], - ['n', 'N'], - ['m', 'M'], - [',', '<'], - ['.', '>'], - ['/', '?'], - ['\0', '\0'], - ['\0', '\0'], - ['\0', '\0'], - [' ', ' '] - ]; - - pub fn get_char(scancode: u8, shift: bool) -> char { - if let Some(c) = ENGLISH.get(scancode as usize) { - if shift { - c[1] - } else { - c[0] - } - } else { - '\0' - } - } -} -pub mod dvorak { - static DVORAK: [[char; 2]; 58] = [ - ['\0', '\0'], - ['\x1B', '\x1B'], - ['1', '!'], - ['2', '@'], - ['3', '#'], - ['4', '$'], - ['5', '%'], - ['6', '^'], - ['7', '&'], - ['8', '*'], - ['9', '('], - ['0', ')'], - ['[', '{'], - [']', '}'], - ['\x7F', '\x7F'], - ['\t', '\t'], - ['\'', '"'], - [',', '<'], - ['.', '>'], - ['p', 'P'], - ['y', 'Y'], - ['f', 'F'], - ['g', 'G'], - ['c', 'C'], - ['r', 'R'], - ['l', 'L'], - ['/', '?'], - ['=', '+'], - ['\n', '\n'], - ['\0', '\0'], - ['a', 'A'], - ['o', 'O'], - ['e', 'E'], - ['u', 'U'], - ['i', 'I'], - ['d', 'D'], - ['h', 'H'], - ['t', 'T'], - ['n', 'N'], - ['s', 'S'], - ['-', '_'], - ['`', '~'], - ['\0', '\0'], - ['\\', '|'], - [';', ':'], - ['q', 'Q'], - ['j', 'J'], - ['k', 'K'], - ['x', 'X'], - ['b', 'B'], - ['m', 'M'], - ['w', 'W'], - ['v', 'V'], - ['z', 'Z'], - ['\0', '\0'], - ['\0', '\0'], - ['\0', '\0'], - [' ', ' '] - ]; - - pub fn get_char(scancode: u8, shift: bool) -> char { - if let Some(c) = DVORAK.get(scancode as usize) { - if shift { - c[1] - } else { - c[0] - } - } else { - '\0' - } - } -} diff --git a/drivers/ps2d/src/main.rs b/drivers/ps2d/src/main.rs deleted file mode 100644 index 7c67bd3..0000000 --- a/drivers/ps2d/src/main.rs +++ /dev/null @@ -1,193 +0,0 @@ -#![feature(asm)] - -#[macro_use] -extern crate bitflags; -extern crate event; -extern crate io; -extern crate orbclient; -extern crate syscall; - -use std::env; -use std::fs::File; -use std::io::{Read, Write, Result}; -use std::os::unix::io::AsRawFd; -use std::mem; - -use event::EventQueue; -use orbclient::{KeyEvent, MouseEvent}; -use syscall::iopl; - -mod controller; -mod keymap; - -bitflags! { - flags MousePacketFlags: u8 { - const LEFT_BUTTON = 1, - const RIGHT_BUTTON = 1 << 1, - const MIDDLE_BUTTON = 1 << 2, - const ALWAYS_ON = 1 << 3, - const X_SIGN = 1 << 4, - const Y_SIGN = 1 << 5, - const X_OVERFLOW = 1 << 6, - const Y_OVERFLOW = 1 << 7 - } -} - -struct Ps2d<'a> { - input: File, - lshift: bool, - rshift: bool, - packets: [u8; 4], - packet_i: usize, - extra_packet: bool, - //Keymap function - get_char: &'a Fn(u8,bool) -> char -} - -impl<'a> Ps2d<'a> { - fn new(input: File, extra_packet: bool, keymap: &'a Fn(u8,bool) -> char) -> Self { - Ps2d { - input: input, - lshift: false, - rshift: false, - packets: [0; 4], - packet_i: 0, - extra_packet: extra_packet, - get_char: keymap - } - } - - fn handle(&mut self, keyboard: bool, data: u8) { - if keyboard { - let (scancode, pressed) = if data >= 0x80 { - (data - 0x80, false) - } else { - (data, true) - }; - - if scancode == 0x2A { - self.lshift = pressed; - } else if scancode == 0x36 { - self.rshift = pressed; - } - - self.input.write(&KeyEvent { - character: (self.get_char)(scancode, self.lshift || self.rshift), - scancode: scancode, - pressed: pressed - }.to_event()).expect("ps2d: failed to write key event"); - } else { - self.packets[self.packet_i] = data; - self.packet_i += 1; - - let flags = MousePacketFlags::from_bits_truncate(self.packets[0]); - if ! flags.contains(ALWAYS_ON) { - println!("MOUSE MISALIGN {:X}", self.packets[0]); - - self.packets = [0; 4]; - self.packet_i = 0; - } else if self.packet_i >= self.packets.len() || (!self.extra_packet && self.packet_i >= 3) { - if ! flags.contains(X_OVERFLOW) && ! flags.contains(Y_OVERFLOW) { - let mut dx = self.packets[1] as i32; - if flags.contains(X_SIGN) { - dx -= 0x100; - } - - let mut dy = -(self.packets[2] as i32); - if flags.contains(Y_SIGN) { - dy += 0x100; - } - - let _extra = if self.extra_packet { - self.packets[3] - } else { - 0 - }; - - self.input.write(&MouseEvent { - x: dx, - y: dy, - left_button: flags.contains(LEFT_BUTTON), - middle_button: flags.contains(MIDDLE_BUTTON), - right_button: flags.contains(RIGHT_BUTTON) - }.to_event()).expect("ps2d: failed to write mouse event"); - } else { - println!("ps2d: overflow {:X} {:X} {:X} {:X}", self.packets[0], self.packets[1], self.packets[2], self.packets[3]); - } - - self.packets = [0; 4]; - self.packet_i = 0; - } - } - } -} - -fn main() { - // Daemonize - if unsafe { syscall::clone(0).unwrap() } == 0 { - unsafe { - iopl(3).expect("ps2d: failed to get I/O permission"); - asm!("cli" : : : : "intel", "volatile"); - } - - let input = File::open("display:input").expect("ps2d: failed to open display:input"); - - let extra_packet = controller::Ps2::new().init(); - let keymap = match env::args().skip(1).next() { - Some(k) => match k.to_lowercase().as_ref() { - "dvorak" => (keymap::dvorak::get_char), - "english" => (keymap::english::get_char), - &_ => (keymap::english::get_char) - }, - None => (keymap::english::get_char) - }; - let mut ps2d = Ps2d::new(input, extra_packet,&keymap); - - let mut event_queue = EventQueue::<(bool, u8)>::new().expect("ps2d: failed to create event queue"); - - let mut key_irq = File::open("irq:1").expect("ps2d: failed to open irq:1"); - - event_queue.add(key_irq.as_raw_fd(), move |_count: usize| -> Result> { - let mut irq = [0; 8]; - if key_irq.read(&mut irq)? >= mem::size_of::() { - let data: u8; - unsafe { - asm!("in al, dx" : "={al}"(data) : "{dx}"(0x60) : : "intel", "volatile"); - } - - key_irq.write(&irq)?; - - Ok(Some((true, data))) - } else { - Ok(None) - } - }).expect("ps2d: failed to poll irq:1"); - - let mut mouse_irq = File::open("irq:12").expect("ps2d: failed to open irq:12"); - - event_queue.add(mouse_irq.as_raw_fd(), move |_count: usize| -> Result> { - let mut irq = [0; 8]; - if mouse_irq.read(&mut irq)? >= mem::size_of::() { - let data: u8; - unsafe { - asm!("in al, dx" : "={al}"(data) : "{dx}"(0x60) : : "intel", "volatile"); - } - - mouse_irq.write(&irq)?; - - Ok(Some((false, data))) - } else { - Ok(None) - } - }).expect("ps2d: failed to poll irq:12"); - - for (keyboard, data) in event_queue.trigger_all(0).expect("ps2d: failed to trigger events") { - ps2d.handle(keyboard, data); - } - - loop { - let (keyboard, data) = event_queue.run().expect("ps2d: failed to handle events"); - ps2d.handle(keyboard, data); - } - } -} diff --git a/drivers/rtl8168d/Cargo.toml b/drivers/rtl8168d/Cargo.toml deleted file mode 100644 index e72a130..0000000 --- a/drivers/rtl8168d/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "rtl8168d" -version = "0.1.0" - -[dependencies] -bitflags = "*" -dma = { path = "../../crates/dma/" } -event = { path = "../../crates/event/" } -io = { path = "../../crates/io/" } -netutils = { path = "../../programs/netutils/" } -redox_syscall = { path = "../../syscall/" } diff --git a/drivers/rtl8168d/src/device.rs b/drivers/rtl8168d/src/device.rs deleted file mode 100644 index 7ed7d59..0000000 --- a/drivers/rtl8168d/src/device.rs +++ /dev/null @@ -1,300 +0,0 @@ -use std::mem; - -use dma::Dma; -use io::{Mmio, Io, ReadOnly}; -use netutils::setcfg; -use syscall::error::{Error, EACCES, EWOULDBLOCK, Result}; -use syscall::flag::O_NONBLOCK; -use syscall::scheme::SchemeMut; - -#[repr(packed)] -struct Regs { - mac: [Mmio; 2], - _mar: [Mmio; 2], - _dtccr: [Mmio; 2], - _rsv0: [Mmio; 2], - tnpds: [Mmio; 2], - thpds: [Mmio; 2], - _rsv1: [Mmio; 7], - cmd: Mmio, - tppoll: Mmio, - _rsv2: [Mmio; 3], - imr: Mmio, - isr: Mmio, - tcr: Mmio, - rcr: Mmio, - _tctr: Mmio, - _rsv3: Mmio, - cmd_9346: Mmio, - _config: [Mmio; 6], - _rsv4: Mmio, - timer_int: Mmio, - _rsv5: Mmio, - _phys_ar: Mmio, - _rsv6: [Mmio; 2], - phys_sts: ReadOnly>, - _rsv7: [Mmio; 23], - _wakeup: [Mmio; 16], - _crc: [Mmio; 5], - _rsv8: [Mmio; 12], - rms: Mmio, - _rsv9: Mmio, - _c_plus_cr: Mmio, - _rsv10: Mmio, - rdsar: [Mmio; 2], - mtps: Mmio, - _rsv11: [Mmio; 19], -} - -const OWN: u32 = 1 << 31; -const EOR: u32 = 1 << 30; -const FS: u32 = 1 << 29; -const LS: u32 = 1 << 28; - -#[repr(packed)] -struct Rd { - ctrl: Mmio, - _vlan: Mmio, - buffer: Mmio -} - -#[repr(packed)] -struct Td { - ctrl: Mmio, - _vlan: Mmio, - buffer: Mmio -} - -pub struct Rtl8168 { - regs: &'static mut Regs, - receive_buffer: [Dma<[Mmio; 0x1FF8]>; 16], - receive_ring: Dma<[Rd; 16]>, - transmit_buffer: [Dma<[Mmio; 7552]>; 16], - transmit_ring: Dma<[Td; 16]>, - transmit_buffer_h: [Dma<[Mmio; 7552]>; 1], - transmit_ring_h: Dma<[Td; 1]> -} - -impl SchemeMut for Rtl8168 { - fn open(&mut self, _path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result { - if uid == 0 { - Ok(flags) - } else { - Err(Error::new(EACCES)) - } - } - - fn dup(&mut self, id: usize, _buf: &[u8]) -> Result { - Ok(id) - } - - fn read(&mut self, id: usize, buf: &mut [u8]) -> Result { - for (rd_i, rd) in self.receive_ring.iter_mut().enumerate() { - if ! rd.ctrl.readf(OWN) { - let rd_len = rd.ctrl.read() & 0x3FFF; - - let data = &self.receive_buffer[rd_i as usize]; - - let mut i = 0; - while i < buf.len() && i < rd_len as usize { - buf[i] = data[i].read(); - i += 1; - } - - let eor = rd.ctrl.read() & EOR; - rd.ctrl.write(OWN | eor | data.len() as u32); - - return Ok(i); - } - } - - if id & O_NONBLOCK == O_NONBLOCK { - Ok(0) - } else { - Err(Error::new(EWOULDBLOCK)) - } - } - - fn write(&mut self, _id: usize, buf: &[u8]) -> Result { - loop { - for (td_i, td) in self.transmit_ring.iter_mut().enumerate() { - if ! td.ctrl.readf(OWN) { - - let mut data = &mut self.transmit_buffer[td_i as usize]; - - let mut i = 0; - while i < buf.len() && i < data.len() { - data[i].write(buf[i]); - i += 1; - } - - let eor = td.ctrl.read() & EOR; - td.ctrl.write(OWN | eor | FS | LS | i as u32); - - self.regs.tppoll.writef(1 << 6, true); //Notify of normal priority packet - - while self.regs.tppoll.readf(1 << 6) { - unsafe { asm!("pause" : : : "memory" : "intel", "volatile"); } - } - - return Ok(i); - } - } - - unsafe { asm!("pause" : : : "memory" : "intel", "volatile"); } - } - } - - fn fevent(&mut self, _id: usize, _flags: usize) -> Result { - Ok(0) - } - - fn fsync(&mut self, _id: usize) -> Result { - Ok(0) - } - - fn close(&mut self, _id: usize) -> Result { - Ok(0) - } -} - -impl Rtl8168 { - pub unsafe fn new(base: usize) -> Result { - assert_eq!(mem::size_of::(), 256); - - let regs = &mut *(base as *mut Regs); - assert_eq!(®s.tnpds as *const _ as usize - base, 0x20); - assert_eq!(®s.cmd as *const _ as usize - base, 0x37); - assert_eq!(®s.tcr as *const _ as usize - base, 0x40); - assert_eq!(®s.rcr as *const _ as usize - base, 0x44); - assert_eq!(®s.cmd_9346 as *const _ as usize - base, 0x50); - assert_eq!(®s.phys_sts as *const _ as usize - base, 0x6C); - assert_eq!(®s.rms as *const _ as usize - base, 0xDA); - assert_eq!(®s.rdsar as *const _ as usize - base, 0xE4); - assert_eq!(®s.mtps as *const _ as usize - base, 0xEC); - - let mut module = Rtl8168 { - regs: regs, - receive_buffer: [Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?], - receive_ring: Dma::zeroed()?, - transmit_buffer: [Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, - Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?], - transmit_ring: Dma::zeroed()?, - transmit_buffer_h: [Dma::zeroed()?], - transmit_ring_h: Dma::zeroed()? - }; - - module.init(); - - Ok(module) - } - - pub unsafe fn irq(&mut self) -> u16 { - // Read and then clear the ISR - let isr = self.regs.isr.read(); - self.regs.isr.write(isr); - let imr = self.regs.imr.read(); - isr & imr - } - - pub fn next_read(&self) -> usize { - for rd in self.receive_ring.iter() { - if ! rd.ctrl.readf(OWN) { - return rd.ctrl.read() as usize & 0x3FFF; - } - } - 0 - } - - pub unsafe fn init(&mut self) { - let mac_low = self.regs.mac[0].read(); - let mac_high = self.regs.mac[1].read(); - let mac = [mac_low as u8, - (mac_low >> 8) as u8, - (mac_low >> 16) as u8, - (mac_low >> 24) as u8, - mac_high as u8, - (mac_high >> 8) as u8]; - print!("{}", format!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); - let _ = setcfg("mac", &format!("{:>02X}.{:>02X}.{:>02X}.{:>02X}.{:>02X}.{:>02X}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); - - // Reset - this will disable tx and rx, reinitialize FIFOs, and set the system buffer pointer to the initial value - self.regs.cmd.writef(1 << 4, true); - while self.regs.cmd.readf(1 << 4) {} - - // Set up rx buffers - for i in 0..self.receive_ring.len() { - let rd = &mut self.receive_ring[i]; - let data = &mut self.receive_buffer[i]; - rd.buffer.write(data.physical() as u64); - rd.ctrl.write(OWN | data.len() as u32); - } - if let Some(mut rd) = self.receive_ring.last_mut() { - rd.ctrl.writef(EOR, true); - } - - // Set up normal priority tx buffers - for i in 0..self.transmit_ring.len() { - self.transmit_ring[i].buffer.write(self.transmit_buffer[i].physical() as u64); - } - if let Some(mut td) = self.transmit_ring.last_mut() { - td.ctrl.writef(EOR, true); - } - - // Set up high priority tx buffers - for i in 0..self.transmit_ring_h.len() { - self.transmit_ring_h[i].buffer.write(self.transmit_buffer_h[i].physical() as u64); - } - if let Some(mut td) = self.transmit_ring_h.last_mut() { - td.ctrl.writef(EOR, true); - } - - // Unlock config - self.regs.cmd_9346.write(1 << 7 | 1 << 6); - - // Enable rx (bit 3) and tx (bit 2) - self.regs.cmd.writef(1 << 3 | 1 << 2, true); - - // Max RX packet size - self.regs.rms.write(0x1FF8); - - // Max TX packet size - self.regs.mtps.write(0x3B); - - // Set tx low priority buffer address - self.regs.tnpds[0].write(self.transmit_ring.physical() as u32); - self.regs.tnpds[1].write((self.transmit_ring.physical() >> 32) as u32); - - // Set tx high priority buffer address - self.regs.thpds[0].write(self.transmit_ring_h.physical() as u32); - self.regs.thpds[1].write((self.transmit_ring_h.physical() >> 32) as u32); - - // Set rx buffer address - self.regs.rdsar[0].write(self.receive_ring.physical() as u32); - self.regs.rdsar[1].write((self.receive_ring.physical() >> 32) as u32); - - // Disable timer interrupt - self.regs.timer_int.write(0); - - //Clear ISR - let isr = self.regs.isr.read(); - self.regs.isr.write(isr); - - // Interrupt on tx error (bit 3), tx ok (bit 2), rx error(bit 1), and rx ok (bit 0) - self.regs.imr.write(1 << 15 | 1 << 14 | 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1); - - // Set TX config - self.regs.tcr.write(0b11 << 24 | 0b111 << 8); - - // Set RX config - Accept broadcast (bit 3), multicast (bit 2), and unicast (bit 1) - self.regs.rcr.write(0xE70E); - - // Lock config - self.regs.cmd_9346.write(0); - } -} diff --git a/drivers/rtl8168d/src/main.rs b/drivers/rtl8168d/src/main.rs deleted file mode 100644 index 46a1b86..0000000 --- a/drivers/rtl8168d/src/main.rs +++ /dev/null @@ -1,141 +0,0 @@ -#![feature(asm)] - -extern crate dma; -extern crate event; -extern crate io; -extern crate netutils; -extern crate syscall; - -use std::cell::RefCell; -use std::env; -use std::fs::File; -use std::io::{Read, Write, Result}; -use std::os::unix::io::{AsRawFd, FromRawFd}; -use std::sync::Arc; - -use event::EventQueue; -use syscall::{Packet, SchemeMut, MAP_WRITE}; -use syscall::error::EWOULDBLOCK; - -pub mod device; - -fn main() { - let mut args = env::args().skip(1); - - let mut name = args.next().expect("rtl8168d: no name provided"); - name.push_str("_rtl8168"); - - let bar_str = args.next().expect("rtl8168d: no address provided"); - let bar = usize::from_str_radix(&bar_str, 16).expect("rtl8168d: failed to parse address"); - - let irq_str = args.next().expect("rtl8168d: no irq provided"); - let irq = irq_str.parse::().expect("rtl8168d: failed to parse irq"); - - print!("{}", format!(" + RTL8168 {} on: {:X}, IRQ: {}\n", name, bar, irq)); - - // Daemonize - if unsafe { syscall::clone(0).unwrap() } == 0 { - let socket_fd = syscall::open(":network", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK).expect("rtl8168d: failed to create network scheme"); - let socket = Arc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd) })); - - let mut irq_file = File::open(format!("irq:{}", irq)).expect("rtl8168d: failed to open IRQ file"); - - let address = unsafe { syscall::physmap(bar, 256, MAP_WRITE).expect("rtl8168d: failed to map address") }; - { - let device = Arc::new(RefCell::new(unsafe { device::Rtl8168::new(address).expect("rtl8168d: failed to allocate device") })); - - let mut event_queue = EventQueue::::new().expect("rtl8168d: failed to create event queue"); - - let todo = Arc::new(RefCell::new(Vec::::new())); - - let device_irq = device.clone(); - let socket_irq = socket.clone(); - let todo_irq = todo.clone(); - event_queue.add(irq_file.as_raw_fd(), move |_count: usize| -> Result> { - let mut irq = [0; 8]; - irq_file.read(&mut irq)?; - - let isr = unsafe { device_irq.borrow_mut().irq() }; - if isr != 0 { - irq_file.write(&mut irq)?; - - let mut todo = todo_irq.borrow_mut(); - let mut i = 0; - while i < todo.len() { - let a = todo[i].a; - device_irq.borrow_mut().handle(&mut todo[i]); - if todo[i].a == (-EWOULDBLOCK) as usize { - todo[i].a = a; - i += 1; - } else { - socket_irq.borrow_mut().write(&mut todo[i])?; - todo.remove(i); - } - } - - let next_read = device_irq.borrow().next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - } - Ok(None) - }).expect("rtl8168d: failed to catch events on IRQ file"); - - let socket_fd = socket.borrow().as_raw_fd(); - let socket_packet = socket.clone(); - event_queue.add(socket_fd, move |_count: usize| -> Result> { - loop { - let mut packet = Packet::default(); - if socket_packet.borrow_mut().read(&mut packet)? == 0 { - break; - } - - let a = packet.a; - device.borrow_mut().handle(&mut packet); - if packet.a == (-EWOULDBLOCK) as usize { - packet.a = a; - todo.borrow_mut().push(packet); - } else { - socket_packet.borrow_mut().write(&mut packet)?; - } - } - - let next_read = device.borrow().next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - - Ok(None) - }).expect("rtl8168d: failed to catch events on IRQ file"); - - for event_count in event_queue.trigger_all(0).expect("rtl8168d: failed to trigger events") { - socket.borrow_mut().write(&Packet { - id: 0, - pid: 0, - uid: 0, - gid: 0, - a: syscall::number::SYS_FEVENT, - b: 0, - c: syscall::flag::EVENT_READ, - d: event_count - }).expect("rtl8168d: failed to write event"); - } - - loop { - let event_count = event_queue.run().expect("rtl8168d: failed to handle events"); - - socket.borrow_mut().write(&Packet { - id: 0, - pid: 0, - uid: 0, - gid: 0, - a: syscall::number::SYS_FEVENT, - b: 0, - c: syscall::flag::EVENT_READ, - d: event_count - }).expect("rtl8168d: failed to write event"); - } - } - unsafe { let _ = syscall::physunmap(address); } - } -} diff --git a/drivers/vesad/Cargo.toml b/drivers/vesad/Cargo.toml deleted file mode 100644 index a70dbf0..0000000 --- a/drivers/vesad/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "vesad" -version = "0.1.0" - -[dependencies] -orbclient = "0.2" -ransid = "0.2" -rusttype = { version = "0.2", optional = true } -redox_syscall = { path = "../../syscall" } - -[features] -default = [] diff --git a/drivers/vesad/src/display.rs b/drivers/vesad/src/display.rs deleted file mode 100644 index 829d6ba..0000000 --- a/drivers/vesad/src/display.rs +++ /dev/null @@ -1,246 +0,0 @@ -#[cfg(feature="rusttype")] -extern crate rusttype; - -use alloc::heap; -use std::{cmp, slice}; - -use primitive::{fast_set32, fast_set64, fast_copy, fast_copy64}; - -#[cfg(feature="rusttype")] -use self::rusttype::{Font, FontCollection, Scale, point}; - -#[cfg(not(feature="rusttype"))] -static FONT: &'static [u8] = include_bytes!("../../../res/fonts/unifont.font"); - -#[cfg(feature="rusttype")] -static FONT: &'static [u8] = include_bytes!("../../../res/fonts/DejaVuSansMono.ttf"); -#[cfg(feature="rusttype")] -static FONT_BOLD: &'static [u8] = include_bytes!("../../../res/fonts/DejaVuSansMono-Bold.ttf"); -#[cfg(feature="rusttype")] -static FONT_BOLD_ITALIC: &'static [u8] = include_bytes!("../../../res/fonts/DejaVuSansMono-BoldOblique.ttf"); -#[cfg(feature="rusttype")] -static FONT_ITALIC: &'static [u8] = include_bytes!("../../../res/fonts/DejaVuSansMono-Oblique.ttf"); - -/// A display -pub struct Display { - pub width: usize, - pub height: usize, - pub onscreen: &'static mut [u32], - pub offscreen: &'static mut [u32], - #[cfg(feature="rusttype")] - pub font: Font<'static>, - #[cfg(feature="rusttype")] - pub font_bold: Font<'static>, - #[cfg(feature="rusttype")] - pub font_bold_italic: Font<'static>, - #[cfg(feature="rusttype")] - pub font_italic: Font<'static> -} - -impl Display { - #[cfg(not(feature="rusttype"))] - pub fn new(width: usize, height: usize, onscreen: usize) -> Display { - let size = width * height; - let offscreen = unsafe { heap::allocate(size * 4, 4096) }; - unsafe { fast_set64(offscreen as *mut u64, 0, size/2) }; - Display { - width: width, - height: height, - onscreen: unsafe { slice::from_raw_parts_mut(onscreen as *mut u32, size) }, - offscreen: unsafe { slice::from_raw_parts_mut(offscreen as *mut u32, size) } - } - } - - #[cfg(feature="rusttype")] - pub fn new(width: usize, height: usize, onscreen: usize) -> Display { - let size = width * height; - let offscreen = unsafe { heap::allocate(size * 4, 4096) }; - unsafe { fast_set64(offscreen as *mut u64, 0, size/2) }; - Display { - width: width, - height: height, - onscreen: unsafe { slice::from_raw_parts_mut(onscreen as *mut u32, size) }, - offscreen: unsafe { slice::from_raw_parts_mut(offscreen as *mut u32, size) }, - font: FontCollection::from_bytes(FONT).into_font().unwrap(), - font_bold: FontCollection::from_bytes(FONT_BOLD).into_font().unwrap(), - font_bold_italic: FontCollection::from_bytes(FONT_BOLD_ITALIC).into_font().unwrap(), - font_italic: FontCollection::from_bytes(FONT_ITALIC).into_font().unwrap() - } - } - - /// Draw a rectangle - pub fn rect(&mut self, x: usize, y: usize, w: usize, h: usize, color: u32) { - let start_y = cmp::min(self.height - 1, y); - let end_y = cmp::min(self.height, y + h); - - let start_x = cmp::min(self.width - 1, x); - let len = cmp::min(self.width, x + w) - start_x; - - let mut offscreen_ptr = self.offscreen.as_mut_ptr() as usize; - - let stride = self.width * 4; - - let offset = y * stride + start_x * 4; - offscreen_ptr += offset; - - let mut rows = end_y - start_y; - while rows > 0 { - unsafe { - fast_set32(offscreen_ptr as *mut u32, color, len); - } - offscreen_ptr += stride; - rows -= 1; - } - } - - /// Invert a rectangle - pub fn invert(&mut self, x: usize, y: usize, w: usize, h: usize) { - let start_y = cmp::min(self.height - 1, y); - let end_y = cmp::min(self.height, y + h); - - let start_x = cmp::min(self.width - 1, x); - let len = cmp::min(self.width, x + w) - start_x; - - let mut offscreen_ptr = self.offscreen.as_mut_ptr() as usize; - - let stride = self.width * 4; - - let offset = y * stride + start_x * 4; - offscreen_ptr += offset; - - let mut rows = end_y - start_y; - while rows > 0 { - let mut row_ptr = offscreen_ptr; - let mut cols = len; - while cols > 0 { - unsafe { - let color = *(row_ptr as *mut u32); - *(row_ptr as *mut u32) = !color; - } - row_ptr += 4; - cols -= 1; - } - offscreen_ptr += stride; - rows -= 1; - } - } - - /// Draw a character - #[cfg(not(feature="rusttype"))] - pub fn char(&mut self, x: usize, y: usize, character: char, color: u32, _bold: bool, _italic: bool) { - if x + 8 <= self.width && y + 16 <= self.height { - let mut dst = self.offscreen.as_mut_ptr() as usize + (y * self.width + x) * 4; - - let font_i = 16 * (character as usize); - if font_i + 16 <= FONT.len() { - for row in 0..16 { - let row_data = FONT[font_i + row]; - for col in 0..8 { - if (row_data >> (7 - col)) & 1 == 1 { - unsafe { *((dst + col * 4) as *mut u32) = color; } - } - } - dst += self.width * 4; - } - } - } - } - - /// Draw a character - #[cfg(feature="rusttype")] - pub fn char(&mut self, x: usize, y: usize, character: char, color: u32, bold: bool, italic: bool) { - let width = self.width; - let height = self.height; - let offscreen = self.offscreen.as_mut_ptr() as usize; - - let font = if bold && italic { - &self.font_bold_italic - } else if bold { - &self.font_bold - } else if italic { - &self.font_italic - } else { - &self.font - }; - - if let Some(glyph) = font.glyph(character){ - let scale = Scale::uniform(16.0); - let v_metrics = font.v_metrics(scale); - let point = point(0.0, v_metrics.ascent); - let glyph = glyph.scaled(scale).positioned(point); - if let Some(bb) = glyph.pixel_bounding_box() { - glyph.draw(|off_x, off_y, v| { - let off_x = x + (off_x as i32 + bb.min.x) as usize; - let off_y = y + (off_y as i32 + bb.min.y) as usize; - // There's still a possibility that the glyph clips the boundaries of the bitmap - if off_x < width && off_y < height { - if v > 0.0 { - let f_a = (v * 255.0) as u32; - let f_r = (((color >> 16) & 0xFF) * f_a)/255; - let f_g = (((color >> 8) & 0xFF) * f_a)/255; - let f_b = ((color & 0xFF) * f_a)/255; - - let offscreen_ptr = (offscreen + (off_y * width + off_x) * 4) as *mut u32; - - let bg = unsafe { *offscreen_ptr }; - - let b_a = 255 - f_a; - let b_r = (((bg >> 16) & 0xFF) * b_a)/255; - let b_g = (((bg >> 8) & 0xFF) * b_a)/255; - let b_b = ((bg & 0xFF) * b_a)/255; - - let c = ((f_r + b_r) << 16) | ((f_g + b_g) << 8) | (f_b + b_b); - - unsafe { *offscreen_ptr = c; } - } - } - }); - } - } - } - - /// Scroll display - pub fn scroll(&mut self, rows: usize, color: u32) { - let data = (color as u64) << 32 | color as u64; - - let width = self.width/2; - let height = self.height; - if rows > 0 && rows < height { - let off1 = rows * width; - let off2 = height * width - off1; - unsafe { - let data_ptr = self.offscreen.as_mut_ptr() as *mut u64; - fast_copy64(data_ptr, data_ptr.offset(off1 as isize), off2); - fast_set64(data_ptr.offset(off2 as isize), data, off1); - } - } - } - - /// Copy from offscreen to onscreen - pub fn sync(&mut self, x: usize, y: usize, w: usize, h: usize) { - let start_y = cmp::min(self.height - 1, y); - let end_y = cmp::min(self.height, y + h); - - let start_x = cmp::min(self.width - 1, x); - let len = (cmp::min(self.width, x + w) - start_x) * 4; - - let mut offscreen_ptr = self.offscreen.as_mut_ptr() as usize; - let mut onscreen_ptr = self.onscreen.as_mut_ptr() as usize; - - let stride = self.width * 4; - - let offset = y * stride + start_x * 4; - offscreen_ptr += offset; - onscreen_ptr += offset; - - let mut rows = end_y - start_y; - while rows > 0 { - unsafe { - fast_copy(onscreen_ptr as *mut u8, offscreen_ptr as *const u8, len); - } - offscreen_ptr += stride; - onscreen_ptr += stride; - rows -= 1; - } - } -} diff --git a/drivers/vesad/src/main.rs b/drivers/vesad/src/main.rs deleted file mode 100644 index 7f4347a..0000000 --- a/drivers/vesad/src/main.rs +++ /dev/null @@ -1,109 +0,0 @@ -#![feature(alloc)] -#![feature(asm)] -#![feature(heap_api)] - -extern crate alloc; -extern crate orbclient; -extern crate syscall; - -use std::{env, mem}; -use std::fs::File; -use std::io::{Read, Write}; -use syscall::{physmap, physunmap, Packet, SchemeMut, EVENT_READ, MAP_WRITE, MAP_WRITE_COMBINE}; - -use mode_info::VBEModeInfo; -use primitive::fast_set64; -use scheme::DisplayScheme; - -pub mod display; -pub mod mode_info; -pub mod primitive; -pub mod scheme; -pub mod screen; - -fn main() { - let mut spec = Vec::new(); - - for arg in env::args().skip(1) { - if arg == "T" { - spec.push(false); - } else if arg == "G" { - spec.push(true); - } else { - println!("vesad: unknown screen type: {}", arg); - } - } - - let width; - let height; - let physbaseptr; - - { - let mode_info = unsafe { &*(physmap(0x5200, 4096, 0).expect("vesad: failed to map VBE info") as *const VBEModeInfo) }; - - width = mode_info.xresolution as usize; - height = mode_info.yresolution as usize; - physbaseptr = mode_info.physbaseptr as usize; - - unsafe { let _ = physunmap(mode_info as *const _ as usize); } - } - - if physbaseptr > 0 { - // Daemonize - if unsafe { syscall::clone(0).unwrap() } == 0 { - let mut socket = File::create(":display").expect("vesad: failed to create display scheme"); - - let size = width * height; - - let onscreen = unsafe { physmap(physbaseptr, size * 4, MAP_WRITE | MAP_WRITE_COMBINE).expect("vesad: failed to map VBE LFB") }; - unsafe { fast_set64(onscreen as *mut u64, 0, size/2) }; - - let mut scheme = DisplayScheme::new(width, height, onscreen, &spec); - - let mut blocked = Vec::new(); - loop { - let mut packet = Packet::default(); - socket.read(&mut packet).expect("vesad: failed to read display scheme"); - - // If it is a read packet, and there is no data, block it. Otherwise, handle packet - if packet.a == syscall::number::SYS_READ && packet.d > 0 && scheme.will_block(packet.b) { - blocked.push(packet); - } else { - scheme.handle(&mut packet); - socket.write(&packet).expect("vesad: failed to write display scheme"); - } - - // If there are blocked readers, and data is available, handle them - { - let mut i = 0; - while i < blocked.len() { - if ! scheme.will_block(blocked[i].b) { - let mut packet = blocked.remove(i); - scheme.handle(&mut packet); - socket.write(&packet).expect("vesad: failed to write display scheme"); - } else { - i += 1; - } - } - } - - for (screen_id, screen) in scheme.screens.iter() { - if ! screen.will_block() { - let event_packet = Packet { - id: 0, - pid: 0, - uid: 0, - gid: 0, - a: syscall::number::SYS_FEVENT, - b: *screen_id, - c: EVENT_READ, - d: mem::size_of::() - }; - - socket.write(&event_packet).expect("vesad: failed to write display event"); - } - } - } - } - } -} diff --git a/drivers/vesad/src/mode_info.rs b/drivers/vesad/src/mode_info.rs deleted file mode 100644 index 7d59af6..0000000 --- a/drivers/vesad/src/mode_info.rs +++ /dev/null @@ -1,37 +0,0 @@ -/// The info of the VBE mode -#[derive(Copy, Clone, Default, Debug)] -#[repr(packed)] -pub struct VBEModeInfo { - attributes: u16, - win_a: u8, - win_b: u8, - granularity: u16, - winsize: u16, - segment_a: u16, - segment_b: u16, - winfuncptr: u32, - bytesperscanline: u16, - pub xresolution: u16, - pub yresolution: u16, - xcharsize: u8, - ycharsize: u8, - numberofplanes: u8, - bitsperpixel: u8, - numberofbanks: u8, - memorymodel: u8, - banksize: u8, - numberofimagepages: u8, - unused: u8, - redmasksize: u8, - redfieldposition: u8, - greenmasksize: u8, - greenfieldposition: u8, - bluemasksize: u8, - bluefieldposition: u8, - rsvdmasksize: u8, - rsvdfieldposition: u8, - directcolormodeinfo: u8, - pub physbaseptr: u32, - offscreenmemoryoffset: u32, - offscreenmemsize: u16, -} diff --git a/drivers/vesad/src/primitive.rs b/drivers/vesad/src/primitive.rs deleted file mode 100644 index 16c2536..0000000 --- a/drivers/vesad/src/primitive.rs +++ /dev/null @@ -1,47 +0,0 @@ -#[cfg(target_arch = "x86_64")] -#[inline(always)] -#[cold] -pub unsafe fn fast_copy(dst: *mut u8, src: *const u8, len: usize) { - asm!("cld - rep movsb" - : - : "{rdi}"(dst as usize), "{rsi}"(src as usize), "{rcx}"(len) - : "cc", "memory", "rdi", "rsi", "rcx" - : "intel", "volatile"); -} - -#[cfg(target_arch = "x86_64")] -#[inline(always)] -#[cold] -pub unsafe fn fast_copy64(dst: *mut u64, src: *const u64, len: usize) { - asm!("cld - rep movsq" - : - : "{rdi}"(dst as usize), "{rsi}"(src as usize), "{rcx}"(len) - : "cc", "memory", "rdi", "rsi", "rcx" - : "intel", "volatile"); -} - -#[cfg(target_arch = "x86_64")] -#[inline(always)] -#[cold] -pub unsafe fn fast_set32(dst: *mut u32, src: u32, len: usize) { - asm!("cld - rep stosd" - : - : "{rdi}"(dst as usize), "{eax}"(src), "{rcx}"(len) - : "cc", "memory", "rdi", "rcx" - : "intel", "volatile"); -} - -#[cfg(target_arch = "x86_64")] -#[inline(always)] -#[cold] -pub unsafe fn fast_set64(dst: *mut u64, src: u64, len: usize) { - asm!("cld - rep stosq" - : - : "{rdi}"(dst as usize), "{rax}"(src), "{rcx}"(len) - : "cc", "memory", "rdi", "rcx" - : "intel", "volatile"); -} diff --git a/drivers/vesad/src/scheme.rs b/drivers/vesad/src/scheme.rs deleted file mode 100644 index e376bf7..0000000 --- a/drivers/vesad/src/scheme.rs +++ /dev/null @@ -1,190 +0,0 @@ -use std::collections::BTreeMap; -use std::{mem, slice, str}; - -use orbclient::{Event, EventOption}; -use syscall::{Result, Error, EACCES, EBADF, ENOENT, SchemeMut}; - -use display::Display; -use screen::{Screen, GraphicScreen, TextScreen}; - -pub struct DisplayScheme { - active: usize, - pub screens: BTreeMap> -} - -impl DisplayScheme { - pub fn new(width: usize, height: usize, onscreen: usize, spec: &[bool]) -> DisplayScheme { - let mut screens: BTreeMap> = BTreeMap::new(); - - let mut screen_i = 1; - for &screen_type in spec.iter() { - if screen_type { - screens.insert(screen_i, Box::new(GraphicScreen::new(Display::new(width, height, onscreen)))); - } else { - screens.insert(screen_i, Box::new(TextScreen::new(Display::new(width, height, onscreen)))); - } - screen_i += 1; - } - - DisplayScheme { - active: 1, - screens: screens - } - } - - pub fn will_block(&self, id: usize) -> bool { - if let Some(screen) = self.screens.get(&id) { - screen.will_block() - } else { - false - } - } -} - -impl SchemeMut for DisplayScheme { - fn open(&mut self, path: &[u8], _flags: usize, uid: u32, _gid: u32) -> Result { - if path == b"input" { - if uid == 0 { - Ok(0) - } else { - Err(Error::new(EACCES)) - } - } else { - let path_str = str::from_utf8(path).unwrap_or("").trim_matches('/'); - let mut parts = path_str.split('/'); - let id = parts.next().unwrap_or("").parse::().unwrap_or(0); - if self.screens.contains_key(&id) { - for cmd in parts { - if cmd == "activate" { - self.active = id; - } - } - Ok(id) - } else { - Err(Error::new(ENOENT)) - } - } - } - - fn dup(&mut self, id: usize, _buf: &[u8]) -> Result { - Ok(id) - } - - fn fevent(&mut self, id: usize, flags: usize) -> Result { - if let Some(mut screen) = self.screens.get_mut(&id) { - screen.event(flags).and(Ok(id)) - } else { - Err(Error::new(EBADF)) - } - } - - fn fmap(&mut self, id: usize, offset: usize, size: usize) -> Result { - if let Some(screen) = self.screens.get(&id) { - screen.map(offset, size) - } else { - Err(Error::new(EBADF)) - } - } - - fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result { - let path_str = if id == 0 { - format!("display:input") - } else if let Some(screen) = self.screens.get(&id) { - format!("display:{}/{}/{}", id, screen.width(), screen.height()) - } else { - return Err(Error::new(EBADF)); - }; - - let path = path_str.as_bytes(); - - let mut i = 0; - while i < buf.len() && i < path.len() { - buf[i] = path[i]; - i += 1; - } - - Ok(i) - } - - fn fsync(&mut self, id: usize) -> Result { - if let Some(mut screen) = self.screens.get_mut(&id) { - if id == self.active { - screen.sync(); - } - Ok(0) - } else { - Err(Error::new(EBADF)) - } - } - - fn read(&mut self, id: usize, buf: &mut [u8]) -> Result { - if let Some(mut screen) = self.screens.get_mut(&id) { - screen.read(buf) - } else { - Err(Error::new(EBADF)) - } - } - - fn write(&mut self, id: usize, buf: &[u8]) -> Result { - if id == 0 { - if buf.len() == 1 && buf[0] >= 0xF4 { - let new_active = (buf[0] - 0xF4) as usize + 1; - if let Some(mut screen) = self.screens.get_mut(&new_active) { - self.active = new_active; - screen.redraw(); - } - Ok(1) - } else { - let events = unsafe { slice::from_raw_parts(buf.as_ptr() as *const Event, buf.len()/mem::size_of::()) }; - - for event in events.iter() { - let new_active_opt = if let EventOption::Key(key_event) = event.to_option() { - match key_event.scancode { - f @ 0x3B ... 0x44 => { // F1 through F10 - Some((f - 0x3A) as usize) - }, - 0x57 => { // F11 - Some(11) - }, - 0x58 => { // F12 - Some(12) - }, - _ => None - } - } else { - None - }; - - if let Some(new_active) = new_active_opt { - if let Some(mut screen) = self.screens.get_mut(&new_active) { - self.active = new_active; - screen.redraw(); - } - } else { - if let Some(mut screen) = self.screens.get_mut(&self.active) { - screen.input(event); - } - } - } - - Ok(events.len() * mem::size_of::()) - } - } else if let Some(mut screen) = self.screens.get_mut(&id) { - screen.write(buf, id == self.active) - } else { - Err(Error::new(EBADF)) - } - } - - fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result { - if let Some(mut screen) = self.screens.get_mut(&id) { - screen.seek(pos, whence) - } else { - Err(Error::new(EBADF)) - } - } - - fn close(&mut self, _id: usize) -> Result { - Ok(0) - } -} diff --git a/drivers/vesad/src/screen/graphic.rs b/drivers/vesad/src/screen/graphic.rs deleted file mode 100644 index b911922..0000000 --- a/drivers/vesad/src/screen/graphic.rs +++ /dev/null @@ -1,126 +0,0 @@ -use std::collections::VecDeque; -use std::{cmp, mem, slice}; - -use orbclient::{Event, EventOption}; -use syscall::error::*; -use syscall::flag::{SEEK_SET, SEEK_CUR, SEEK_END}; - -use display::Display; -use primitive::fast_copy; -use screen::Screen; - -pub struct GraphicScreen { - pub display: Display, - pub seek: usize, - pub mouse_x: i32, - pub mouse_y: i32, - pub input: VecDeque, - pub requested: usize -} - -impl GraphicScreen { - pub fn new(display: Display) -> GraphicScreen { - GraphicScreen { - display: display, - seek: 0, - mouse_x: 0, - mouse_y: 0, - input: VecDeque::new(), - requested: 0 - } - } -} - -impl Screen for GraphicScreen { - fn width(&self) -> usize { - self.display.width - } - - fn height(&self) -> usize { - self.display.height - } - - fn event(&mut self, flags: usize) -> Result { - self.requested = flags; - Ok(0) - } - - fn map(&self, offset: usize, size: usize) -> Result { - if offset + size <= self.display.offscreen.len() * 4 { - Ok(self.display.offscreen.as_ptr() as usize + offset) - } else { - Err(Error::new(EINVAL)) - } - } - - fn input(&mut self, event: &Event) { - if let EventOption::Mouse(mut mouse_event) = event.to_option() { - let x = cmp::max(0, cmp::min(self.display.width as i32, self.mouse_x + mouse_event.x)); - let y = cmp::max(0, cmp::min(self.display.height as i32, self.mouse_y + mouse_event.y)); - - mouse_event.x = x; - self.mouse_x = x; - mouse_event.y = y; - self.mouse_y = y; - - self.input.push_back(mouse_event.to_event()); - } else { - self.input.push_back(*event); - } - } - - fn read(&mut self, buf: &mut [u8]) -> Result { - let mut i = 0; - - let event_buf = unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut Event, buf.len()/mem::size_of::()) }; - - while i < event_buf.len() && ! self.input.is_empty() { - event_buf[i] = self.input.pop_front().unwrap(); - i += 1; - } - - Ok(i * mem::size_of::()) - } - - fn will_block(&self) -> bool { - self.input.is_empty() - } - - fn write(&mut self, buf: &[u8], sync: bool) -> Result { - let size = cmp::max(0, cmp::min(self.display.offscreen.len() as isize - self.seek as isize, (buf.len()/4) as isize)) as usize; - - if size > 0 { - unsafe { - fast_copy(self.display.offscreen.as_mut_ptr().offset(self.seek as isize) as *mut u8, buf.as_ptr(), size * 4); - if sync { - fast_copy(self.display.onscreen.as_mut_ptr().offset(self.seek as isize) as *mut u8, buf.as_ptr(), size * 4); - } - } - } - - Ok(size * 4) - } - - fn seek(&mut self, pos: usize, whence: usize) -> Result { - let size = self.display.offscreen.len(); - - self.seek = match whence { - SEEK_SET => cmp::min(size, (pos/4)), - SEEK_CUR => cmp::max(0, cmp::min(size as isize, self.seek as isize + (pos/4) as isize)) as usize, - SEEK_END => cmp::max(0, cmp::min(size as isize, size as isize + (pos/4) as isize)) as usize, - _ => return Err(Error::new(EINVAL)) - }; - - Ok(self.seek * 4) - } - - fn sync(&mut self) { - self.redraw(); - } - - fn redraw(&mut self) { - let width = self.display.width; - let height = self.display.height; - self.display.sync(0, 0, width, height); - } -} diff --git a/drivers/vesad/src/screen/mod.rs b/drivers/vesad/src/screen/mod.rs deleted file mode 100644 index 9909694..0000000 --- a/drivers/vesad/src/screen/mod.rs +++ /dev/null @@ -1,32 +0,0 @@ -pub use self::graphic::GraphicScreen; -pub use self::text::TextScreen; - -use orbclient::Event; -use syscall::Result; - -mod graphic; -mod text; - -pub trait Screen { - fn width(&self) -> usize; - - fn height(&self) -> usize; - - fn event(&mut self, flags: usize) -> Result; - - fn map(&self, offset: usize, size: usize) -> Result; - - fn input(&mut self, event: &Event); - - fn read(&mut self, buf: &mut [u8]) -> Result; - - fn will_block(&self) -> bool; - - fn write(&mut self, buf: &[u8], sync: bool) -> Result; - - fn seek(&mut self, pos: usize, whence: usize) -> Result; - - fn sync(&mut self); - - fn redraw(&mut self); -} diff --git a/drivers/vesad/src/screen/text.rs b/drivers/vesad/src/screen/text.rs deleted file mode 100644 index ccc259d..0000000 --- a/drivers/vesad/src/screen/text.rs +++ /dev/null @@ -1,233 +0,0 @@ -extern crate ransid; - -use std::collections::{BTreeSet, VecDeque}; - -use orbclient::{Event, EventOption}; -use syscall::error::*; - -use display::Display; -use screen::Screen; - -pub struct TextScreen { - pub console: ransid::Console, - pub display: Display, - pub changed: BTreeSet, - pub ctrl: bool, - pub input: VecDeque, - pub end_of_input: bool, - pub cooked: VecDeque, - pub requested: usize -} - -impl TextScreen { - pub fn new(display: Display) -> TextScreen { - TextScreen { - console: ransid::Console::new(display.width/8, display.height/16), - display: display, - changed: BTreeSet::new(), - ctrl: false, - input: VecDeque::new(), - end_of_input: false, - cooked: VecDeque::new(), - requested: 0 - } - } -} - -impl Screen for TextScreen { - fn width(&self) -> usize { - self.console.w - } - - fn height(&self) -> usize { - self.console.h - } - - fn event(&mut self, flags: usize) -> Result { - self.requested = flags; - Ok(0) - } - - fn map(&self, offset: usize, size: usize) -> Result { - Err(Error::new(EBADF)) - } - - fn input(&mut self, event: &Event) { - let mut buf = vec![]; - - match event.to_option() { - EventOption::Key(key_event) => { - if key_event.scancode == 0x1D { - self.ctrl = key_event.pressed; - } else if key_event.pressed { - match key_event.scancode { - 0x0E => { // Backspace - buf.extend_from_slice(b"\x7F"); - }, - 0x47 => { // Home - buf.extend_from_slice(b"\x1B[H"); - }, - 0x48 => { // Up - buf.extend_from_slice(b"\x1B[A"); - }, - 0x49 => { // Page up - buf.extend_from_slice(b"\x1B[5~"); - }, - 0x4B => { // Left - buf.extend_from_slice(b"\x1B[D"); - }, - 0x4D => { // Right - buf.extend_from_slice(b"\x1B[C"); - }, - 0x4F => { // End - buf.extend_from_slice(b"\x1B[F"); - }, - 0x50 => { // Down - buf.extend_from_slice(b"\x1B[B"); - }, - 0x51 => { // Page down - buf.extend_from_slice(b"\x1B[6~"); - }, - 0x52 => { // Insert - buf.extend_from_slice(b"\x1B[2~"); - }, - 0x53 => { // Delete - buf.extend_from_slice(b"\x1B[3~"); - }, - _ => { - let c = match key_event.character { - c @ 'A' ... 'Z' if self.ctrl => ((c as u8 - b'A') + b'\x01') as char, - c @ 'a' ... 'z' if self.ctrl => ((c as u8 - b'a') + b'\x01') as char, - c => c - }; - - if c != '\0' { - buf.extend_from_slice(&[c as u8]); - } - } - } - } - }, - _ => () //TODO: Mouse in terminal - } - - if self.console.raw_mode { - for &b in buf.iter() { - self.input.push_back(b); - } - } else { - for &b in buf.iter() { - match b { - b'\x03' => { - self.end_of_input = true; - let _ = self.write(b"^C\n", true); - }, - b'\x08' | b'\x7F' => { - if let Some(_c) = self.cooked.pop_back() { - let _ = self.write(b"\x08", true); - } - }, - b'\x1B' => { - let _ = self.write(b"^[", true); - }, - b'\n' | b'\r' => { - self.cooked.push_back(b); - while let Some(c) = self.cooked.pop_front() { - self.input.push_back(c); - } - let _ = self.write(b"\n", true); - }, - _ => { - self.cooked.push_back(b); - let _ = self.write(&[b], true); - } - } - } - } - } - - fn read(&mut self, buf: &mut [u8]) -> Result { - let mut i = 0; - - while i < buf.len() && ! self.input.is_empty() { - buf[i] = self.input.pop_front().unwrap(); - i += 1; - } - - if i == 0 { - self.end_of_input = false; - } - - Ok(i) - } - - fn will_block(&self) -> bool { - self.input.is_empty() && ! self.end_of_input - } - - fn write(&mut self, buf: &[u8], sync: bool) -> Result { - if self.console.cursor && self.console.x < self.console.w && self.console.y < self.console.h { - let x = self.console.x; - let y = self.console.y; - self.display.invert(x * 8, y * 16, 8, 16); - self.changed.insert(y); - } - - { - let display = &mut self.display; - let changed = &mut self.changed; - self.console.write(buf, |event| { - match event { - ransid::Event::Char { x, y, c, color, bold, .. } => { - display.char(x * 8, y * 16, c, color.data, bold, false); - changed.insert(y); - }, - ransid::Event::Rect { x, y, w, h, color } => { - display.rect(x * 8, y * 16, w * 8, h * 16, color.data); - for y2 in y..y + h { - changed.insert(y2); - } - }, - ransid::Event::Scroll { rows, color } => { - display.scroll(rows * 16, color.data); - for y in 0..display.height/16 { - changed.insert(y); - } - } - } - }); - } - - if self.console.cursor && self.console.x < self.console.w && self.console.y < self.console.h { - let x = self.console.x; - let y = self.console.y; - self.display.invert(x * 8, y * 16, 8, 16); - self.changed.insert(y); - } - - if ! self.console.raw_mode && sync { - self.sync(); - } - - Ok(buf.len()) - } - - fn seek(&mut self, _pos: usize, _whence: usize) -> Result { - Ok(0) - } - - fn sync(&mut self) { - let width = self.display.width; - for change in self.changed.iter() { - self.display.sync(0, change * 16, width, 16); - } - self.changed.clear(); - } - - fn redraw(&mut self) { - let width = self.display.width; - let height = self.display.height; - self.display.sync(0, 0, width, height); - self.changed.clear(); - } -}