From 7dd87644096d11f9466f66046d8d6f4ccfa4a75d Mon Sep 17 00:00:00 2001 From: Julien CLEMENT Date: Mon, 12 Dec 2022 01:08:16 +0100 Subject: [PATCH] add send scsi packet Signed-off-by: Julien CLEMENT --- Cargo.lock | 153 ++++++++++++++++++++++++++++++++++++++- Cargo.toml | 3 + src/drivers/atapi/mod.rs | 68 ++++++++++++++++- 3 files changed, 218 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e956402..12e097b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "atomic-polyfill" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" +dependencies = [ + "critical-section", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -26,12 +35,24 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + [[package]] name = "conquer-once" version = "0.2.1" @@ -47,6 +68,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "654fb2472cc369d311c547103a1fa81d467bef370ae7a0680f65939895b1182a" +[[package]] +name = "critical-section" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" + [[package]] name = "crossbeam-queue" version = "0.2.3" @@ -92,6 +119,29 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "heapless" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "serde", + "spin 0.9.4", + "stable_deref_trait", +] + [[package]] name = "julios" version = "0.1.0" @@ -99,12 +149,15 @@ dependencies = [ "conquer-once", "crossbeam-queue", "futures-util", + "heapless", "lazy_static", "linked_list_allocator", "multiboot2", "pc-keyboard", "pic8259", - "spin", + "postcard", + "serde", + "spin 0.5.2", "volatile 0.2.7", "x86_64", ] @@ -115,7 +168,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "spin", + "spin 0.5.2", ] [[package]] @@ -178,6 +231,44 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "postcard" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c2b180dc0bade59f03fd005cb967d3f1e5f69b13922dad0cd6e047cb8af2363" +dependencies = [ + "cobs", + "heapless", + "serde", +] + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "rustversion" version = "1.0.6" @@ -190,12 +281,47 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "semver" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" + +[[package]] +name = "serde" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +dependencies = [ + "lock_api", +] + [[package]] name = "spinning_top" version = "0.2.4" @@ -205,6 +331,29 @@ dependencies = [ "lock_api", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "syn" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + [[package]] name = "volatile" version = "0.2.7" diff --git a/Cargo.toml b/Cargo.toml index 29604dc..79569e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,9 @@ pic8259 = "0.10.1" pc-keyboard = "0.5.0" multiboot2 = "0.1.0" linked_list_allocator = "0.9.0" +postcard = "1.0.0" +serde = { version = "1.0", default-features = false, features = ["alloc"] } +heapless = "0.7.16" [dependencies.lazy_static] version = "1.0" diff --git a/src/drivers/atapi/mod.rs b/src/drivers/atapi/mod.rs index 21a717c..5cc2f64 100644 --- a/src/drivers/atapi/mod.rs +++ b/src/drivers/atapi/mod.rs @@ -1,7 +1,12 @@ use crate::serial_println; use crate::println; +use core::convert::TryInto; + use lazy_static::lazy_static; +use serde::{Serialize, Deserialize}; +use spin::Mutex; +use postcard::{to_vec}; use x86_64::instructions::port::Port; const CD_SECTOR_SIZE: usize = 2048; @@ -14,6 +19,9 @@ const ATA_BUS_SECONDARY: u16 = 0x170; const ATA_DRIVE_MASTER: u8 = 0xa0; const ATA_DRIVE_SLAVE: u8 = 0xb0; +// ATA Commands +const ATA_CMD_PACKET: u8 = 0xa0; + // Status bits const ATA_ERR: u8 = 1 << 0; const ATA_DRQ: u8 = 1 << 3; @@ -40,14 +48,14 @@ static ATAPI_SIG: [u8; 4] = [ ]; lazy_static! { - static ref DRIVE: Option = { - ATABus::discover_atapi_drive() + static ref DRIVE: Mutex> = { + Mutex::new(ATABus::discover_atapi_drive()) }; } pub fn init() { println!("Detecting drives"); - match DRIVE.as_ref() { + match DRIVE.lock().as_ref() { None => println!("No drive detected :("), Some(drive) => { let drive_type = match drive.current_drive { @@ -64,6 +72,9 @@ pub fn init() { serial_println!("Detected drive: {:?}", drive); } } + + // TODO : remove + DRIVE.lock().as_mut().unwrap().send_packet(SCSIPacket::new()); } #[derive(Debug)] @@ -71,7 +82,7 @@ struct ATABus { base_port: u16, // IO ports - data: Port, + data: Port, features: Port, // write error: Port, // read sector_count: Port, @@ -164,6 +175,29 @@ impl ATABus { ATAPI_SIG == sig } + fn send_packet(&mut self, packet: SCSIPacket) { + let raw_packet = packet.serialize(); + self.wait_busy(); + + unsafe { + self.features.write(0); + self.sector_count.write(0); + self.address2.write((CD_SECTOR_SIZE & 0xff) as u8); + self.address3.write(((CD_SECTOR_SIZE >> 8) & 0xff) as u8); + self.command.write(ATA_CMD_PACKET); + } + + self.wait_packet_request(); + + for i in (0..raw_packet.len()).step_by(2) { + let word = u16::from_be_bytes(raw_packet[i..i+2].try_into().unwrap()); + unsafe { + self.data.write(word); + } + } + // TODO: Wait packet data transmit + } + fn wait_busy(&mut self) { let mut status = ATA_BSY; while (status & ATA_BSY) != 0 { @@ -192,3 +226,29 @@ impl ATABus { } } +#[derive(Default, Serialize, Deserialize, Debug, Eq, PartialEq)] +#[repr(C, packed)] +struct SCSIPacket { + op_code: u8, + flags_lo: u8, + lba_hi: u8, + lba_mihi: u8, + lba_midlo: u8, + lba_lo: u8, + transfer_length_hi: u8, + transfer_length_mihi: u8, + transfer_length_milo: u8, + transfer_length_lo: u8, + flags_hi: u8, + control: u8 +} + +impl SCSIPacket { + fn new() -> Self { + SCSIPacket::default() + } + + fn serialize(&self) -> heapless::Vec { + to_vec(&self).unwrap() + } +} \ No newline at end of file