From ad14a44670ce0727aa532fd0f225f658836b9d54 Mon Sep 17 00:00:00 2001 From: Andy-Python-Programmer Date: Fri, 10 Feb 2023 19:49:56 +1100 Subject: [PATCH 1/6] e1000: init Signed-off-by: Andy-Python-Programmer --- src/aero_kernel/src/drivers/e1000.rs | 308 +++++++++++++++++++++++++++ src/aero_kernel/src/drivers/mod.rs | 1 + 2 files changed, 309 insertions(+) create mode 100644 src/aero_kernel/src/drivers/e1000.rs diff --git a/src/aero_kernel/src/drivers/e1000.rs b/src/aero_kernel/src/drivers/e1000.rs new file mode 100644 index 00000000000..e7354acfe5b --- /dev/null +++ b/src/aero_kernel/src/drivers/e1000.rs @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2021-2023 The Aero Project Developers. + * + * This file is part of The Aero Project. + * + * Aero is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Aero is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Aero. If not, see . + */ + +use alloc::sync::Arc; + +use crate::drivers::pci::*; +use crate::mem::paging::*; + +const TX_DESC_NUM: usize = 32; +const TX_DESC_SIZE: usize = TX_DESC_NUM * core::mem::size_of::(); + +const RX_QUEUE_SIZE: usize = 32; + +#[derive(Copy, Clone, Debug)] +enum Error { + UnknownBar, + NoEeprom, + OutOfMemory, + NotSupported, +} + +#[derive(Copy, Clone)] +#[repr(usize)] +enum Register { + Control = 0x00, + Eeprom = 0x14, + + TCtrl = 0x400, + /// Lower bits of the 64 bit descriptor base address. + TxDesLo = 0x3800, + /// Upper 32 bits of the 64 bit descriptor base address. + TxDesHi = 0x3804, + /// Descriptor length and must be 128B aligned. + TxDescLen = 0x3808, + /// Head pointer for the transmit descriptor ring. + TxDescHead = 0x3810, + /// Tail pointer for the transmit descriptor ring. + TxDescTail = 0x3818, + /// Controls the IPG (Inter Packet Gap) timer. + Tipg = 0x410, +} + +bitflags::bitflags! { + struct ControlFlags: u32 { + const LRST = 1 << 3; + const ASDE = 1 << 5; + const SLU = 1 << 6; + const ILOS = 1 << 7; + const RST = 1 << 26; + const VME = 1 << 30; + const PHY_RST = 1 << 31; + } +} + +bitflags::bitflags! { + pub struct TStatus: u8 { + const DD = 1 << 0; // Descriptor Done + const EC = 1 << 1; // Excess Collisions + const LC = 1 << 2; // Late Collision + const TU = 1 << 3; // Transmit Underrun + } +} + +bitflags::bitflags! { + pub struct TCtl: u32 { + const EN = 1 << 1; // Transmit Enable + const PSP = 1 << 3; // Pad Short Packets + const SWXOFF = 1 << 22; // Software XOFF Transmission + const RTLC = 1 << 24; // Re-transmit on Late Collision + } +} + +impl TCtl { + /// Sets the number of attempts at retransmission prior to giving + /// up on the packet (not including the first transmission attempt). + pub fn set_collision_threshold(&mut self, value: u8) { + self.bits |= (value as u32) << 4; + } + + /// Sets the minimum number of byte times which must elapse for + /// proper CSMA/CD operation. + pub fn set_collision_distance(&mut self, value: u8) { + self.bits |= (value as u32) << 12; + } +} + +#[repr(C, packed)] +pub struct TxDescriptor { + pub addr: u64, + pub length: u16, + pub cso: u8, + pub cmd: u8, + pub status: TStatus, + pub css: u8, + pub special: u16, +} + +struct Eeprom<'a> { + e1000: &'a E1000, +} + +impl<'a> Eeprom<'a> { + fn new(e1000: &'a E1000) -> Self { + Self { e1000 } + } + + fn read(&self, addr: u8) -> u32 { + self.e1000.write(Register::Eeprom, 1 | ((addr as u32) << 8)); + + loop { + let res = self.e1000.read(Register::Eeprom); + + if res & (1 << 4) > 0 { + return (res >> 16) & 0xffff; + } + } + } +} + +struct E1000 { + base: VirtAddr, +} + +impl E1000 { + fn new(header: &PciHeader) -> Result<(), Error> { + header.enable_bus_mastering(); + header.enable_mmio(); + + let bar0 = header.get_bar(0).ok_or(Error::UnknownBar)?; + + let registers_addr = match bar0 { + Bar::Memory64 { address, .. } => PhysAddr::new(address), + Bar::Memory32 { address, .. } => PhysAddr::new(address as u64), + _ => return Err(Error::UnknownBar), + }; + + let this = Self { + base: registers_addr.as_hhdm_virt(), + }; + + this.reset(); + + if !this.detect_eeprom() { + return Err(Error::NoEeprom); + } + + let eeprom = Eeprom::new(&this); + + let mut mac = [0u8; 6]; + + // Get the MAC address + for i in 0..3 { + let x = eeprom.read(i) as u16; + mac[i as usize * 2] = (x & 0xff) as u8; + mac[i as usize * 2 + 1] = (x >> 8) as u8; + } + + log::trace!( + "e1000: MAC address {:x}:{:x}:{:x}:{:x}:{:x}:{:x}", + mac[0], + mac[1], + mac[2], + mac[3], + mac[4], + mac[5] + ); + + this.init_tx()?; + this.init_rx()?; + + log::trace!("e1000: successfully initialized"); + Ok(()) + } + + fn init_tx(&self) -> Result<(), Error> { + assert!(core::mem::size_of::() * TX_DESC_NUM < Size4KiB::SIZE as usize); + + let frame: PhysFrame = + FRAME_ALLOCATOR.allocate_frame().ok_or(Error::OutOfMemory)?; + + let addr = frame.start_address().as_hhdm_virt(); + let descriptors = addr + .read_mut::<[TxDescriptor; TX_DESC_NUM]>() + .ok_or(Error::NotSupported)?; + + for desc in descriptors { + desc.status = TStatus::DD; + } + + let phys = frame.start_address(); + + self.write(Register::TxDesLo, phys.as_u64() as _); + self.write(Register::TxDesHi, (phys.as_u64() >> 32) as _); + self.write(Register::TxDescLen, TX_DESC_SIZE as _); + self.write(Register::TxDescHead, 0); + self.write(Register::TxDescTail, 0); + + let mut flags = TCtl::EN | TCtl::PSP | TCtl::RTLC; + flags.set_collision_distance(64); + flags.set_collision_threshold(15); + + self.write(Register::TCtrl, flags.bits()); + + // TODO: Set the default values for the Tx Inter Packet + // Gap Timer. + // self.write(Register::Tipg, 0x??????) + + Ok(()) + } + + fn init_rx(&self) -> Result<(), Error> { + Ok(()) + } + + fn detect_eeprom(&self) -> bool { + self.write(Register::Eeprom, 1); + + for _ in 0..1000 { + let value = self.read(Register::Eeprom); + + if value & (1 << 4) > 0 { + return true; + } + } + + false + } + + fn reset(&self) { + self.insert_flags(Register::Control, ControlFlags::RST.bits()); + + while ControlFlags::from_bits_truncate(self.read(Register::Control)) + .contains(ControlFlags::RST) + { + core::hint::spin_loop(); + } + + // Do not use VLANs, clear reset and do not invert loss-of-signal. + self.remove_flags( + Register::Control, + (ControlFlags::LRST | ControlFlags::PHY_RST | ControlFlags::VME).bits(), + ); + } + + fn remove_flags(&self, register: Register, flag: u32) { + self.write(register, self.read(register) & !flag); + } + + fn insert_flags(&self, register: Register, flag: u32) { + self.write(register, self.read(register) | flag); + } + + fn write(&self, register: Register, value: u32) { + unsafe { + let register = self.base.as_mut_ptr::().add(register as usize); + core::ptr::write_volatile(register as *mut u32, value); + } + } + + fn read(&self, register: Register) -> u32 { + unsafe { self.read_raw(register as u32) } + } + + unsafe fn read_raw(&self, register: u32) -> u32 { + let register = self.base.as_ptr::().add(register as usize); + core::ptr::read_volatile(register as *const u32) + } +} + +struct Handler; + +impl Handler { + fn new() -> Arc { + Arc::new(Self {}) + } +} + +impl PciDeviceHandle for Handler { + fn handles(&self, vendor_id: Vendor, device_id: DeviceType) -> bool { + vendor_id == Vendor::Intel && device_id == DeviceType::EthernetController + } + + fn start(&self, header: &PciHeader, _offset_table: &mut OffsetPageTable) { + E1000::new(header).unwrap() + } +} + +fn init() { + register_device_driver(Handler::new()) +} + +crate::module_init!(init, ModuleType::Block); diff --git a/src/aero_kernel/src/drivers/mod.rs b/src/aero_kernel/src/drivers/mod.rs index 1446a709334..ba761134561 100644 --- a/src/aero_kernel/src/drivers/mod.rs +++ b/src/aero_kernel/src/drivers/mod.rs @@ -28,6 +28,7 @@ pub mod keyboard; #[cfg(target_arch = "x86_64")] pub mod lai; // FIXME: aarch64 port +pub mod e1000; pub mod mouse; #[cfg(target_arch = "x86_64")] pub mod pci; From d7bc6a9debe5dc001bd0ffe7a12d81e37e484f55 Mon Sep 17 00:00:00 2001 From: Andy-Python-Programmer Date: Sat, 11 Feb 2023 13:05:37 +1100 Subject: [PATCH 2/6] e1000: init rx Signed-off-by: Andy-Python-Programmer --- src/aero_kernel/src/drivers/e1000.rs | 122 ++++++++++++++++++++++++--- 1 file changed, 108 insertions(+), 14 deletions(-) diff --git a/src/aero_kernel/src/drivers/e1000.rs b/src/aero_kernel/src/drivers/e1000.rs index e7354acfe5b..bcb8c5669cf 100644 --- a/src/aero_kernel/src/drivers/e1000.rs +++ b/src/aero_kernel/src/drivers/e1000.rs @@ -22,10 +22,11 @@ use alloc::sync::Arc; use crate::drivers::pci::*; use crate::mem::paging::*; -const TX_DESC_NUM: usize = 32; -const TX_DESC_SIZE: usize = TX_DESC_NUM * core::mem::size_of::(); +const TX_DESC_NUM: u32 = 32; +const TX_DESC_SIZE: u32 = TX_DESC_NUM * core::mem::size_of::() as u32; -const RX_QUEUE_SIZE: usize = 32; +const RX_DESC_NUM: u32 = 32; +const RX_DESC_SIZE: u32 = RX_DESC_NUM * core::mem::size_of::() as u32; #[derive(Copy, Clone, Debug)] enum Error { @@ -41,6 +42,18 @@ enum Register { Control = 0x00, Eeprom = 0x14, + RCtrl = 0x0100, + /// Lower bits of the 64 bit descriptor base address. + RxDescLo = 0x2800, + /// Upper 32 bits of the 64 bit descriptor base address. + RxDescHi = 0x2804, + /// Descriptor length and must be 128B aligned. + RxDescLen = 0x2808, + /// Head pointer for the receive descriptor buffer. + RxDescHead = 0x2810, + /// Tail pointer for the receive descriptor buffer. + RxDescTail = 0x2818, + TCtrl = 0x400, /// Lower bits of the 64 bit descriptor base address. TxDesLo = 0x3800, @@ -69,7 +82,7 @@ bitflags::bitflags! { } bitflags::bitflags! { - pub struct TStatus: u8 { + struct TStatus: u8 { const DD = 1 << 0; // Descriptor Done const EC = 1 << 1; // Excess Collisions const LC = 1 << 2; // Late Collision @@ -78,7 +91,7 @@ bitflags::bitflags! { } bitflags::bitflags! { - pub struct TCtl: u32 { + struct TCtl: u32 { const EN = 1 << 1; // Transmit Enable const PSP = 1 << 3; // Pad Short Packets const SWXOFF = 1 << 22; // Software XOFF Transmission @@ -89,19 +102,54 @@ bitflags::bitflags! { impl TCtl { /// Sets the number of attempts at retransmission prior to giving /// up on the packet (not including the first transmission attempt). - pub fn set_collision_threshold(&mut self, value: u8) { + fn set_collision_threshold(&mut self, value: u8) { self.bits |= (value as u32) << 4; } /// Sets the minimum number of byte times which must elapse for /// proper CSMA/CD operation. - pub fn set_collision_distance(&mut self, value: u8) { + fn set_collision_distance(&mut self, value: u8) { self.bits |= (value as u32) << 12; } } +bitflags::bitflags! { + struct RCtl: u32 { + const EN = 1 << 1; // Receiver Enable + const SBP = 1 << 2; // Store Bad Packets + const UPE = 1 << 3; // Unicast Promiscuous Enabled + const MPE = 1 << 4; // Multicast Promiscuous Enabled + const LPE = 1 << 5; // Long Packet Reception Enable + const LBM_NONE = 0 << 6; // No Loopback + const LBM_PHY = 3 << 6; // PHY or external SerDesc loopback + const RDMTS_HALF = 0 << 8; // Free Buffer Threshold is 1/2 of RDLEN + const RDMTS_QUARTER = 1 << 8; // Free Buffer Threshold is 1/4 of RDLEN + const RDMTS_EIGHTH = 2 << 8; // Free Buffer Threshold is 1/8 of RDLEN + const MO_36 = 0 << 12; // Multicast Offset - bits 47:36 + const MO_35 = 1 << 12; // Multicast Offset - bits 46:35 + const MO_34 = 2 << 12; // Multicast Offset - bits 45:34 + const MO_32 = 3 << 12; // Multicast Offset - bits 43:32 + const BAM = 1 << 15; // Broadcast Accept Mode + const VFE = 1 << 18; // VLAN Filter Enable + const CFIEN = 1 << 19; // Canonical Form Indicator Enable + const CFI = 1 << 20; // Canonical Form Indicator Bit Value + const DPF = 1 << 22; // Discard Pause Frames + const PMCF = 1 << 23; // Pass MAC Control Frames + const SECRC = 1 << 26; // Strip Ethernet CRC + + // Receive Buffer Size - bits 17:16 + const BSIZE_256 = 3 << 16; + const BSIZE_512 = 2 << 16; + const BSIZE_1024 = 1 << 16; + const BSIZE_2048 = 0 << 16; + const BSIZE_4096 = (3 << 16) | (1 << 25); + const BSIZE_8192 = (2 << 16) | (1 << 25); + const BSIZE_16384 = (1 << 16) | (1 << 25); + } +} + #[repr(C, packed)] -pub struct TxDescriptor { +struct TxDescriptor { pub addr: u64, pub length: u16, pub cso: u8, @@ -111,6 +159,16 @@ pub struct TxDescriptor { pub special: u16, } +#[repr(C, packed)] +struct RxDescriptor { + pub addr: u64, + pub length: u16, + pub checksum: u16, + pub status: u8, + pub errors: u8, + pub special: u16, +} + struct Eeprom<'a> { e1000: &'a E1000, } @@ -189,25 +247,25 @@ impl E1000 { } fn init_tx(&self) -> Result<(), Error> { - assert!(core::mem::size_of::() * TX_DESC_NUM < Size4KiB::SIZE as usize); + assert!(TX_DESC_SIZE < Size4KiB::SIZE as u32); let frame: PhysFrame = FRAME_ALLOCATOR.allocate_frame().ok_or(Error::OutOfMemory)?; - let addr = frame.start_address().as_hhdm_virt(); + let phys = frame.start_address(); + let addr = phys.as_hhdm_virt(); + let descriptors = addr - .read_mut::<[TxDescriptor; TX_DESC_NUM]>() + .read_mut::<[TxDescriptor; TX_DESC_NUM as usize]>() .ok_or(Error::NotSupported)?; for desc in descriptors { desc.status = TStatus::DD; } - let phys = frame.start_address(); - self.write(Register::TxDesLo, phys.as_u64() as _); self.write(Register::TxDesHi, (phys.as_u64() >> 32) as _); - self.write(Register::TxDescLen, TX_DESC_SIZE as _); + self.write(Register::TxDescLen, TX_DESC_SIZE); self.write(Register::TxDescHead, 0); self.write(Register::TxDescTail, 0); @@ -225,6 +283,42 @@ impl E1000 { } fn init_rx(&self) -> Result<(), Error> { + assert!(TX_DESC_SIZE < Size4KiB::SIZE as u32); + + let frame: PhysFrame = + FRAME_ALLOCATOR.allocate_frame().ok_or(Error::OutOfMemory)?; + + let phys = frame.start_address(); + let addr = phys.as_hhdm_virt(); + + let descriptors = addr + .read_mut::<[RxDescriptor; RX_DESC_NUM as usize]>() + .ok_or(Error::NotSupported)?; + + for desc in descriptors { + let frame: PhysFrame = + FRAME_ALLOCATOR.allocate_frame().ok_or(Error::OutOfMemory)?; + + desc.addr = frame.start_address().as_u64(); + } + + self.write(Register::RxDescLo, phys.as_u64() as _); + self.write(Register::RxDescHi, (phys.as_u64() >> 32) as _); + self.write(Register::RxDescLen, RX_DESC_SIZE); + self.write(Register::RxDescHead, 0); + self.write(Register::RxDescTail, RX_DESC_NUM - 1); + + let flags = RCtl::EN + | RCtl::UPE + | RCtl::LPE + | RCtl::MPE + | RCtl::LBM_NONE + | RCtl::RDMTS_EIGHTH + | RCtl::BAM + | RCtl::SECRC + | RCtl::BSIZE_4096; + + self.write(Register::RCtrl, flags.bits()); Ok(()) } From 7c1a1b9ed65585fc6be86b128efd993745cbaf92 Mon Sep 17 00:00:00 2001 From: Andy-Python-Programmer Date: Sat, 11 Feb 2023 15:50:05 +1100 Subject: [PATCH 3/6] e1000: setup interrupts Signed-off-by: Andy-Python-Programmer --- src/aero_kernel/src/acpi/aml.rs | 1 + src/aero_kernel/src/drivers/e1000.rs | 64 +++++++++++++++++++++++++++- src/aero_kernel/src/drivers/lai.rs | 8 +++- src/aero_kernel/src/drivers/pci.rs | 13 ++++-- 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/src/aero_kernel/src/acpi/aml.rs b/src/aero_kernel/src/acpi/aml.rs index 280be84b4cc..60992e06d86 100644 --- a/src/aero_kernel/src/acpi/aml.rs +++ b/src/aero_kernel/src/acpi/aml.rs @@ -17,6 +17,7 @@ pub trait AmlSubsystem: Send + Sync { /// ## Parameters /// * `mode` - IRQ mode (ACPI spec section 5.8.1) fn enable_acpi(&self, mode: u32); + fn pci_route_pin(&self, seg: u16, bus: u8, slot: u8, function: u8, pin: u8) -> u8; } static AML_SUBSYSTEM: Once> = Once::new(); diff --git a/src/aero_kernel/src/drivers/e1000.rs b/src/aero_kernel/src/drivers/e1000.rs index bcb8c5669cf..3c485804960 100644 --- a/src/aero_kernel/src/drivers/e1000.rs +++ b/src/aero_kernel/src/drivers/e1000.rs @@ -19,6 +19,8 @@ use alloc::sync::Arc; +use crate::acpi::aml; +use crate::arch::interrupts::{self, InterruptStack}; use crate::drivers::pci::*; use crate::mem::paging::*; @@ -39,10 +41,15 @@ enum Error { #[derive(Copy, Clone)] #[repr(usize)] enum Register { - Control = 0x00, + Control = 0x0, + Status = 0x8, + Eeprom = 0x14, - RCtrl = 0x0100, + ICause = 0xc0, + IMask = 0xd0, + + RCtrl = 0x100, /// Lower bits of the 64 bit descriptor base address. RxDescLo = 0x2800, /// Upper 32 bits of the 64 bit descriptor base address. @@ -90,6 +97,18 @@ bitflags::bitflags! { } } +bitflags::bitflags! { + struct ECtl: u32 { + const LRST = (1 << 3); + const ASDE = (1 << 5); + const SLU = (1 << 6); // Set Link Up + const ILOS = (1 << 7); + const RST = (1 << 26); + const VME = (1 << 30); + const PHY_RST = (1 << 31); + } +} + bitflags::bitflags! { struct TCtl: u32 { const EN = 1 << 1; // Transmit Enable @@ -208,6 +227,11 @@ impl E1000 { _ => return Err(Error::UnknownBar), }; + log::debug!( + "{:?}", + header.capabilities().collect::>() + ); + let this = Self { base: registers_addr.as_hhdm_virt(), }; @@ -242,10 +266,42 @@ impl E1000 { this.init_tx()?; this.init_rx()?; + // XXX: The e1000 does not support MSIx and MSI. + let gsi = aml::get_subsystem().pci_route_pin( + 0, + header.bus(), + header.device(), + header.function(), + header.interrupt_pin(), + ); + + let vector = interrupts::allocate_vector(); + interrupts::register_handler(vector, irq_handler); + + crate::arch::apic::io_apic_setup_legacy_irq(gsi, vector, 0); + + // Enable interrupts! + this.write(Register::IMask, 0); + this.read(Register::ICause); + + this.link_up(); + + this.receive(); + log::trace!("e1000: successfully initialized"); Ok(()) } + fn receive(&self) {} + + fn link_up(&self) { + self.insert_flags(Register::Control, ECtl::SLU.bits()); + + while self.read(Register::Status) & 2 != 2 { + core::hint::spin_loop(); + } + } + fn init_tx(&self) -> Result<(), Error> { assert!(TX_DESC_SIZE < Size4KiB::SIZE as u32); @@ -395,6 +451,10 @@ impl PciDeviceHandle for Handler { } } +fn irq_handler(_stack: &mut InterruptStack) { + unreachable!() +} + fn init() { register_device_driver(Handler::new()) } diff --git a/src/aero_kernel/src/drivers/lai.rs b/src/aero_kernel/src/drivers/lai.rs index b6d55ab2ae0..4a9e98a897f 100644 --- a/src/aero_kernel/src/drivers/lai.rs +++ b/src/aero_kernel/src/drivers/lai.rs @@ -121,6 +121,12 @@ impl aml::AmlSubsystem for LaiSubsystem { fn enable_acpi(&self, mode: u32) { lai::enable_acpi(mode); } + + fn pci_route_pin(&self, seg: u16, bus: u8, slot: u8, function: u8, pin: u8) -> u8 { + lai::pci_route_pin(seg, bus, slot, function, pin) + .expect("lai: failed to route pin") + .base as u8 + } } pub fn init_lai() { @@ -134,4 +140,4 @@ pub fn init_lai() { aml::init(subsystem); } -crate::module_init!(init_lai, ModuleType::Other); +crate::module_init!(init_lai, ModuleType::Block); diff --git a/src/aero_kernel/src/drivers/pci.rs b/src/aero_kernel/src/drivers/pci.rs index 0015b9c442b..c920f5836f9 100644 --- a/src/aero_kernel/src/drivers/pci.rs +++ b/src/aero_kernel/src/drivers/pci.rs @@ -586,10 +586,13 @@ impl PciHeader { io::outl(PCI_CONFIG_ADDRESS_PORT, address); + let offset = (offset & 0b11) * 8; + let val = io::inl(PCI_CONFIG_DATA_PORT); + match core::mem::size_of::() { - 1 => io::inb(PCI_CONFIG_DATA_PORT) as u32, // u8 - 2 => io::inw(PCI_CONFIG_DATA_PORT) as u32, // u16 - 4 => io::inl(PCI_CONFIG_DATA_PORT), // u32 + 1 => (val >> offset) as u8 as u32, // u8 + 2 => (val >> offset) as u16 as u32, // u16 + 4 => val, // u32 width => unreachable!("unknown PCI read width: `{}`", width), } } @@ -730,6 +733,10 @@ impl PciHeader { } } + pub fn interrupt_pin(&self) -> u8 { + unsafe { self.read::(0x3d) as u8 } + } + // NOTE: The Base Address registers are optional registers used to map internal // (device-specific) registers into Memory or I/O Spaces. Refer to the PCI Local Bus // Specification for a detailed discussion of base address registers. From 162abd5f22ada7f233d7106e8f1b7b1677fe267f Mon Sep 17 00:00:00 2001 From: Andy-Python-Programmer Date: Sun, 12 Feb 2023 17:01:00 +1100 Subject: [PATCH 4/6] net: init Signed-off-by: Andy-Python-Programmer --- src/aero_kernel/src/drivers/e1000.rs | 73 ++++++++++++++++++++++--- src/aero_kernel/src/main.rs | 4 ++ src/aero_kernel/src/net/arp.rs | 80 ++++++++++++++++++++++++++++ src/aero_kernel/src/net/dhcp.rs | 29 ++++++++++ src/aero_kernel/src/net/ethernet.rs | 60 +++++++++++++++++++++ src/aero_kernel/src/net/ip.rs | 30 +++++++++++ src/aero_kernel/src/net/mod.rs | 64 ++++++++++++++++++++++ 7 files changed, 334 insertions(+), 6 deletions(-) create mode 100644 src/aero_kernel/src/net/arp.rs create mode 100644 src/aero_kernel/src/net/dhcp.rs create mode 100644 src/aero_kernel/src/net/ethernet.rs create mode 100644 src/aero_kernel/src/net/ip.rs create mode 100644 src/aero_kernel/src/net/mod.rs diff --git a/src/aero_kernel/src/drivers/e1000.rs b/src/aero_kernel/src/drivers/e1000.rs index 3c485804960..f1f8ae86be5 100644 --- a/src/aero_kernel/src/drivers/e1000.rs +++ b/src/aero_kernel/src/drivers/e1000.rs @@ -23,6 +23,8 @@ use crate::acpi::aml; use crate::arch::interrupts::{self, InterruptStack}; use crate::drivers::pci::*; use crate::mem::paging::*; +use crate::net::{self, ethernet, MacAddr, NetworkDevice}; +use crate::utils::sync::BMutex; const TX_DESC_NUM: u32 = 32; const TX_DESC_SIZE: u32 = TX_DESC_NUM * core::mem::size_of::() as u32; @@ -212,10 +214,14 @@ impl<'a> Eeprom<'a> { struct E1000 { base: VirtAddr, + mac: MacAddr, + + tx_cur: usize, + tx_ring: VirtAddr, } impl E1000 { - fn new(header: &PciHeader) -> Result<(), Error> { + fn new(header: &PciHeader) -> Result { header.enable_bus_mastering(); header.enable_mmio(); @@ -232,8 +238,12 @@ impl E1000 { header.capabilities().collect::>() ); - let this = Self { + let mut this = Self { base: registers_addr.as_hhdm_virt(), + mac: MacAddr([0; 6]), + + tx_cur: 0, + tx_ring: VirtAddr::zero(), }; this.reset(); @@ -263,6 +273,8 @@ impl E1000 { mac[5] ); + this.mac = MacAddr(mac); + this.init_tx()?; this.init_rx()?; @@ -289,7 +301,27 @@ impl E1000 { this.receive(); log::trace!("e1000: successfully initialized"); - Ok(()) + Ok(this) + } + + fn send(&mut self, packet: ethernet::Packet) { + let cur = self.tx_cur; + let ring = self.tx_ring(); + let e: PhysFrame = FRAME_ALLOCATOR.allocate_frame().unwrap(); + + unsafe { + *(e.start_address().as_hhdm_virt().as_ptr::() as *mut ethernet::Packet) = packet; + } + + ring[cur].addr = e.start_address().as_u64(); + ring[cur].length = core::mem::size_of::() as u16; + ring[cur].cmd = 0b1011; + ring[cur].status = TStatus::empty(); + + drop(ring); + self.tx_cur = (self.tx_cur + 1) % TX_DESC_NUM as usize; + + self.write(Register::TxDescTail, self.tx_cur as u32); } fn receive(&self) {} @@ -302,7 +334,13 @@ impl E1000 { } } - fn init_tx(&self) -> Result<(), Error> { + fn tx_ring(&mut self) -> &mut [TxDescriptor] { + self.tx_ring + .read_mut::<[TxDescriptor; TX_DESC_NUM as usize]>() + .unwrap() + } + + fn init_tx(&mut self) -> Result<(), Error> { assert!(TX_DESC_SIZE < Size4KiB::SIZE as u32); let frame: PhysFrame = @@ -319,6 +357,8 @@ impl E1000 { desc.status = TStatus::DD; } + self.tx_ring = addr; + self.write(Register::TxDesLo, phys.as_u64() as _); self.write(Register::TxDesHi, (phys.as_u64() >> 32) as _); self.write(Register::TxDescLen, TX_DESC_SIZE); @@ -433,6 +473,24 @@ impl E1000 { } } +struct Device(BMutex); + +impl Device { + fn new(e1000: E1000) -> Self { + Self(BMutex::new(e1000)) + } +} + +impl NetworkDevice for Device { + fn send(&self, packet: ethernet::Packet) { + self.0.lock().send(packet) + } + + fn mac(&self) -> net::MacAddr { + self.0.lock().mac + } +} + struct Handler; impl Handler { @@ -447,12 +505,15 @@ impl PciDeviceHandle for Handler { } fn start(&self, header: &PciHeader, _offset_table: &mut OffsetPageTable) { - E1000::new(header).unwrap() + let e1000 = E1000::new(header).unwrap(); + let device = Arc::new(Device::new(e1000)); + + net::add_device(device); } } fn irq_handler(_stack: &mut InterruptStack) { - unreachable!() + log::debug!("a!") } fn init() { diff --git a/src/aero_kernel/src/main.rs b/src/aero_kernel/src/main.rs index 76d5e5ce1ad..452b2e808f8 100644 --- a/src/aero_kernel/src/main.rs +++ b/src/aero_kernel/src/main.rs @@ -82,6 +82,7 @@ mod fs; mod logger; mod mem; mod modules; +mod net; mod rendy; mod socket; mod syscall; @@ -144,6 +145,9 @@ fn kernel_main_thread() { modules::init(); log::info!("loaded kernel modules"); + net::init(); + log::info!("initialized networking stack"); + #[cfg(target_arch = "x86_64")] arch::enable_acpi(); diff --git a/src/aero_kernel/src/net/arp.rs b/src/aero_kernel/src/net/arp.rs new file mode 100644 index 00000000000..bce677fd85b --- /dev/null +++ b/src/aero_kernel/src/net/arp.rs @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2021-2023 The Aero Project Developers. + * + * This file is part of The Aero Project. + * + * Aero is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Aero is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Aero. If not, see . + */ + +// Address Resolution Protocol + +use alloc::collections::BTreeMap; +use spin::{Once, RwLock}; + +use super::ethernet::MacAddr; +use super::ip::Ipv4Addr; + +struct Entry { + mac: MacAddr, +} + +impl Entry { + fn new(mac: MacAddr) -> Self { + Self { mac } + } +} + +struct Cache(BTreeMap); + +impl Cache { + fn new() -> Self { + Self(BTreeMap::new()) + } + + fn insert(&mut self, ip: Ipv4Addr, mac: MacAddr) { + if let Some(_entry) = self.0.get_mut(&ip) { + todo!() + } else { + self.0.insert(ip, Entry::new(mac)); + } + } + + fn get(&self, ip: Ipv4Addr) -> Option { + if let Some(entry) = self.0.get(&ip) { + return Some(entry.mac); + } + + None + } +} + +static CACHE: Once> = Once::new(); + +pub fn get(ip: Ipv4Addr) -> Option { + CACHE + .get() + .as_ref() + .expect("arp: cache not initialized") + .read() + .get(ip) +} + +pub fn init() { + CACHE.call_once(|| { + let mut cache = Cache::new(); + cache.insert(Ipv4Addr::BROADCAST, MacAddr::BROADCAST); + + RwLock::new(cache) + }); +} diff --git a/src/aero_kernel/src/net/dhcp.rs b/src/aero_kernel/src/net/dhcp.rs new file mode 100644 index 00000000000..67fe517b3dd --- /dev/null +++ b/src/aero_kernel/src/net/dhcp.rs @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2021-2023 The Aero Project Developers. + * + * This file is part of The Aero Project. + * + * Aero is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Aero is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Aero. If not, see . + */ + +// Dynamic Host Configuration Protocol + +use super::{ethernet, ip::Ipv4Addr}; + +pub fn init() { + // Send DHCP discover message (UDP: source port=67; destination port=68). + let balls = ethernet::Packet::new(ethernet::Type::Ip); + + super::ethernet::send_packet(balls, Ipv4Addr::BROADCAST); +} diff --git a/src/aero_kernel/src/net/ethernet.rs b/src/aero_kernel/src/net/ethernet.rs new file mode 100644 index 00000000000..7da3c4d088b --- /dev/null +++ b/src/aero_kernel/src/net/ethernet.rs @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2021-2023 The Aero Project Developers. + * + * This file is part of The Aero Project. + * + * Aero is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Aero is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Aero. If not, see . + */ + +use super::arp; +use super::ip::Ipv4Addr; + +#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)] +#[repr(C)] +pub struct MacAddr(pub [u8; 6]); + +impl MacAddr { + pub const BROADCAST: Self = Self([0xff; 6]); +} + +#[repr(u16)] +pub enum Type { + Ip = 0x800, +} + +#[repr(C, packed)] +pub struct Packet { + pub dest_mac: MacAddr, + pub src_mac: MacAddr, + pub typ: Type, +} + +impl Packet { + /// Creates a new ethernet packet. + pub fn new(typ: Type) -> Self { + let src_mac = super::default_device().mac(); + Self { + src_mac, + dest_mac: MacAddr([0; 6]), + typ, + } + } +} + +pub fn send_packet(mut packet: Packet, ip: Ipv4Addr) { + if let Some(addr) = arp::get(ip) { + packet.dest_mac = addr; + super::default_device().send(packet); + } +} diff --git a/src/aero_kernel/src/net/ip.rs b/src/aero_kernel/src/net/ip.rs new file mode 100644 index 00000000000..06b32232801 --- /dev/null +++ b/src/aero_kernel/src/net/ip.rs @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2021-2023 The Aero Project Developers. + * + * This file is part of The Aero Project. + * + * Aero is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Aero is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Aero. If not, see . + */ + +/// Size of IPv4 adderess in octets. +/// +/// [RFC 8200 § 2]: https://www.rfc-editor.org/rfc/rfc791#section-3.2 +pub const ADDR_SIZE: usize = 4; + +#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)] +pub struct Ipv4Addr(pub [u8; ADDR_SIZE]); + +impl Ipv4Addr { + pub const BROADCAST: Self = Self([0xff; ADDR_SIZE]); +} diff --git a/src/aero_kernel/src/net/mod.rs b/src/aero_kernel/src/net/mod.rs new file mode 100644 index 00000000000..d15f4918331 --- /dev/null +++ b/src/aero_kernel/src/net/mod.rs @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2021-2023 The Aero Project Developers. + * + * This file is part of The Aero Project. + * + * Aero is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Aero is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Aero. If not, see . + */ + +use alloc::{sync::Arc, vec::Vec}; +use spin::RwLock; + +pub mod arp; +pub mod dhcp; +pub mod ethernet; +pub mod ip; + +pub use ethernet::MacAddr; + +pub trait NetworkDevice: Send + Sync { + fn send(&self, packet: ethernet::Packet); + fn mac(&self) -> MacAddr; +} + +static DEVICES: RwLock>> = RwLock::new(Vec::new()); +static DEFAULT_DEVICE: RwLock>> = RwLock::new(None); + +pub fn add_device(device: Arc) { + DEVICES.write().push(device.clone()); + + let mut default_device = DEFAULT_DEVICE.write(); + if default_device.is_none() { + *default_device = Some(device); + } +} + +pub fn default_device() -> Arc { + DEFAULT_DEVICE + .read() + .as_ref() + .expect("net: no devices found") + .clone() +} + +// Initialize the networking stack. +pub fn init() { + if DEFAULT_DEVICE.read().is_none() { + // No network devices are avaliable. + return; + } + + arp::init(); + dhcp::init(); +} From 61e257b2dac0e6f64898c9cc2f18656ec56cdc9e Mon Sep 17 00:00:00 2001 From: Andy-Python-Programmer Date: Wed, 15 Feb 2023 18:22:50 +1100 Subject: [PATCH 5/6] net: init Signed-off-by: Andy-Python-Programmer --- src/aero_kernel/src/drivers/block/nvme/mod.rs | 7 +- .../src/drivers/block/nvme/queue.rs | 2 +- src/aero_kernel/src/drivers/e1000.rs | 216 +++++++++++++--- src/aero_kernel/src/main.rs | 1 + src/aero_kernel/src/net/dhcp.rs | 192 ++++++++++++++- src/aero_kernel/src/net/ethernet.rs | 60 +++-- src/aero_kernel/src/net/ip.rs | 81 ++++++ src/aero_kernel/src/net/mod.rs | 130 +++++++++- src/aero_kernel/src/net/udp.rs | 77 ++++++ src/aero_kernel/src/socket/inet.rs | 28 +++ src/aero_kernel/src/socket/mod.rs | 12 +- .../src/{drivers/block/nvme => utils}/dma.rs | 7 +- src/aero_kernel/src/utils/mod.rs | 1 + userland/Cargo.lock | 232 +++--------------- 14 files changed, 776 insertions(+), 270 deletions(-) create mode 100644 src/aero_kernel/src/net/udp.rs create mode 100644 src/aero_kernel/src/socket/inet.rs rename src/aero_kernel/src/{drivers/block/nvme => utils}/dma.rs (95%) diff --git a/src/aero_kernel/src/drivers/block/nvme/mod.rs b/src/aero_kernel/src/drivers/block/nvme/mod.rs index 56e43b7caaf..900a58efce5 100644 --- a/src/aero_kernel/src/drivers/block/nvme/mod.rs +++ b/src/aero_kernel/src/drivers/block/nvme/mod.rs @@ -18,13 +18,11 @@ */ mod command; -mod dma; mod queue; use core::mem::MaybeUninit; use command::*; -use dma::*; use queue::*; use alloc::sync::Arc; @@ -37,6 +35,7 @@ use crate::drivers::pci::*; use crate::fs::block::{install_block_device, BlockDevice, BlockDeviceInterface}; use crate::mem::paging::*; +use crate::utils::dma::*; use crate::utils::sync::BMutex; use crate::utils::{CeilDiv, VolatileCell}; @@ -339,7 +338,7 @@ impl<'a> Controller<'a> { registers.set_enable(true)?; - let identity = Dma::::new(); + let identity = Dma::::zeroed(); let mut identify_command = IdentifyCommand::default(); identify_command.opcode = AdminOpcode::Identify as u8; @@ -417,7 +416,7 @@ impl<'a> Controller<'a> { continue; } - let identity = Dma::::new(); + let identity = Dma::::zeroed(); let mut identify_command = IdentifyCommand::default(); identify_command.opcode = AdminOpcode::Identify as u8; diff --git a/src/aero_kernel/src/drivers/block/nvme/queue.rs b/src/aero_kernel/src/drivers/block/nvme/queue.rs index ab4fdf5777a..9e2b3e47976 100644 --- a/src/aero_kernel/src/drivers/block/nvme/queue.rs +++ b/src/aero_kernel/src/drivers/block/nvme/queue.rs @@ -2,9 +2,9 @@ use core::cell::UnsafeCell; use core::sync::atomic::{AtomicU16, Ordering}; use crate::mem::paging::PhysAddr; +use crate::utils::dma::Dma; use super::command::{Command, CompletionEntry}; -use super::dma::Dma; use super::*; const fn calculate_doorbell_offset(queue_id: u16, multiplier: usize, dstrd: usize) -> usize { diff --git a/src/aero_kernel/src/drivers/e1000.rs b/src/aero_kernel/src/drivers/e1000.rs index f1f8ae86be5..d63ad482058 100644 --- a/src/aero_kernel/src/drivers/e1000.rs +++ b/src/aero_kernel/src/drivers/e1000.rs @@ -18,13 +18,17 @@ */ use alloc::sync::Arc; +use spin::Once; use crate::acpi::aml; use crate::arch::interrupts::{self, InterruptStack}; use crate::drivers::pci::*; use crate::mem::paging::*; -use crate::net::{self, ethernet, MacAddr, NetworkDevice}; -use crate::utils::sync::BMutex; +use crate::userland::scheduler; +use crate::utils::sync::{BlockQueue, Mutex}; + +use crate::net::{self, ethernet}; +use crate::net::{MacAddr, NetworkDevice, PacketBaseTrait}; const TX_DESC_NUM: u32 = 32; const TX_DESC_SIZE: u32 = TX_DESC_NUM * core::mem::size_of::() as u32; @@ -49,6 +53,7 @@ enum Register { Eeprom = 0x14, ICause = 0xc0, + IRate = 0xc4, IMask = 0xd0, RCtrl = 0x100, @@ -91,6 +96,7 @@ bitflags::bitflags! { } bitflags::bitflags! { + #[derive(Default)] struct TStatus: u8 { const DD = 1 << 0; // Descriptor Done const EC = 1 << 1; // Excess Collisions @@ -101,13 +107,13 @@ bitflags::bitflags! { bitflags::bitflags! { struct ECtl: u32 { - const LRST = (1 << 3); - const ASDE = (1 << 5); - const SLU = (1 << 6); // Set Link Up - const ILOS = (1 << 7); - const RST = (1 << 26); - const VME = (1 << 30); - const PHY_RST = (1 << 31); + const LRST = 1 << 3; + const ASDE = 1 << 5; + const SLU = 1 << 6; // Set Link Up + const ILOS = 1 << 7; + const RST = 1 << 26; + const VME = 1 << 30; + const PHY_RST = 1 << 31; } } @@ -169,6 +175,26 @@ bitflags::bitflags! { } } +bitflags::bitflags! { + pub struct InterruptFlags: u32 { + const TXDW = 1 << 0; // Transmit Descriptor Written Back + const TXQE = 1 << 1; // Transmit Queue Empty + const LSC = 1 << 2; // Link Status Change + const RXDMT0 = 1 << 4; // Receive Descriptor Minimum Threshold + const DSW = 1 << 5; // Disable SW Write Access + const RXO = 1 << 6; // Receiver Overrun + const RXT0 = 1 << 7; // Receiver Timer Interrupt + const MDAC = 1 << 9; // MDIO Access Complete + const PHYINT = 1 << 12; // PHY Interrupt + const LSECPN = 1 << 14; // MACsec Packet Number + const TXD_LOW = 1 << 15; // Transmit Descriptor Low Threshold hit + const SRPD = 1 << 16; // Small Receive Packet Detected + const ACK = 1 << 17; // Receive ACK Frame Detected + const ECCER = 1 << 22; // ECC Error + } +} + +#[derive(Default)] #[repr(C, packed)] struct TxDescriptor { pub addr: u64, @@ -180,6 +206,7 @@ struct TxDescriptor { pub special: u16, } +#[derive(Default)] #[repr(C, packed)] struct RxDescriptor { pub addr: u64, @@ -218,6 +245,9 @@ struct E1000 { tx_cur: usize, tx_ring: VirtAddr, + + rx_cur: usize, + rx_ring: VirtAddr, } impl E1000 { @@ -233,17 +263,15 @@ impl E1000 { _ => return Err(Error::UnknownBar), }; - log::debug!( - "{:?}", - header.capabilities().collect::>() - ); - let mut this = Self { base: registers_addr.as_hhdm_virt(), mac: MacAddr([0; 6]), tx_cur: 0, tx_ring: VirtAddr::zero(), + + rx_cur: 0, + rx_ring: VirtAddr::zero(), }; this.reset(); @@ -292,29 +320,63 @@ impl E1000 { crate::arch::apic::io_apic_setup_legacy_irq(gsi, vector, 0); + // Clear statistical counters. + for i in 0..128 { + unsafe { + this.write_raw(0x5200 + i * 4, 0); + } + } + // Enable interrupts! - this.write(Register::IMask, 0); + this.write( + Register::IMask, + (InterruptFlags::TXDW + | InterruptFlags::TXQE + | InterruptFlags::LSC + | InterruptFlags::RXDMT0 + | InterruptFlags::DSW + | InterruptFlags::RXO + | InterruptFlags::RXT0 + | InterruptFlags::MDAC + | InterruptFlags::PHYINT + | InterruptFlags::LSECPN + | InterruptFlags::TXD_LOW + | InterruptFlags::SRPD + | InterruptFlags::ACK + | InterruptFlags::ECCER) + .bits(), + ); this.read(Register::ICause); this.link_up(); - this.receive(); - log::trace!("e1000: successfully initialized"); Ok(this) } - fn send(&mut self, packet: ethernet::Packet) { - let cur = self.tx_cur; - let ring = self.tx_ring(); - let e: PhysFrame = FRAME_ALLOCATOR.allocate_frame().unwrap(); + fn handle_irq(&mut self) { + let cause = self.read(Register::ICause); + log::debug!("cause: {cause}"); + if cause & 0x80 != 0x80 { + return; + } - unsafe { - *(e.start_address().as_hhdm_virt().as_ptr::() as *mut ethernet::Packet) = packet; + let idx = self.rx_cur; + let descriptor = &self.rx_ring()[idx]; + log::debug!("{}", descriptor.status); + + if descriptor.status & 0x1 == 0x1 { + // we got some packies right here mate. lets notify the boyz + DEVICE.get().unwrap().wq.notify_complete(); } + } - ring[cur].addr = e.start_address().as_u64(); - ring[cur].length = core::mem::size_of::() as u16; + fn send(&mut self, packet: net::Packet) { + let cur = self.tx_cur; + let ring = self.tx_ring(); + + ring[cur].addr = unsafe { packet.addr() - crate::PHYSICAL_MEMORY_OFFSET }; + ring[cur].length = packet.len() as _; ring[cur].cmd = 0b1011; ring[cur].status = TStatus::empty(); @@ -324,7 +386,36 @@ impl E1000 { self.write(Register::TxDescTail, self.tx_cur as u32); } - fn receive(&self) {} + fn recv(&mut self) -> Option { + let id = self.rx_cur; + let desc = &mut self.rx_ring()[id]; + + if desc.status & 0x1 != 0x1 { + return None; + } + + Some(net::RecvPacket { + packet: net::Packet::::new( + PhysAddr::new(desc.addr).as_hhdm_virt(), + desc.length as usize, + ), + id, + }) + } + + fn recv_end(&mut self, id: usize) { + let desc = &mut self.rx_ring()[id]; + + if desc.status & 0x1 != 0x1 { + unreachable!() + } + + desc.status = 0; + + let old = self.rx_cur; + self.rx_cur = (self.rx_cur + 1) % RX_DESC_NUM as usize; + self.write(Register::RxDescTail, old as u32); + } fn link_up(&self) { self.insert_flags(Register::Control, ECtl::SLU.bits()); @@ -334,6 +425,12 @@ impl E1000 { } } + fn rx_ring(&mut self) -> &mut [RxDescriptor] { + self.rx_ring + .read_mut::<[RxDescriptor; RX_DESC_NUM as usize]>() + .unwrap() + } + fn tx_ring(&mut self) -> &mut [TxDescriptor] { self.tx_ring .read_mut::<[TxDescriptor; TX_DESC_NUM as usize]>() @@ -354,6 +451,7 @@ impl E1000 { .ok_or(Error::NotSupported)?; for desc in descriptors { + *desc = TxDescriptor::default(); desc.status = TStatus::DD; } @@ -365,7 +463,7 @@ impl E1000 { self.write(Register::TxDescHead, 0); self.write(Register::TxDescTail, 0); - let mut flags = TCtl::EN | TCtl::PSP | TCtl::RTLC; + let mut flags = TCtl { bits: 1 << 28 } | TCtl::EN | TCtl::PSP | TCtl::RTLC; flags.set_collision_distance(64); flags.set_collision_threshold(15); @@ -373,12 +471,12 @@ impl E1000 { // TODO: Set the default values for the Tx Inter Packet // Gap Timer. - // self.write(Register::Tipg, 0x??????) + // self.write(Register::Tipg, 0x???????); Ok(()) } - fn init_rx(&self) -> Result<(), Error> { + fn init_rx(&mut self) -> Result<(), Error> { assert!(TX_DESC_SIZE < Size4KiB::SIZE as u32); let frame: PhysFrame = @@ -395,9 +493,12 @@ impl E1000 { let frame: PhysFrame = FRAME_ALLOCATOR.allocate_frame().ok_or(Error::OutOfMemory)?; + *desc = RxDescriptor::default(); desc.addr = frame.start_address().as_u64(); } + self.rx_ring = addr; + self.write(Register::RxDescLo, phys.as_u64() as _); self.write(Register::RxDescHi, (phys.as_u64() >> 32) as _); self.write(Register::RxDescLen, RX_DESC_SIZE); @@ -457,37 +558,71 @@ impl E1000 { } fn write(&self, register: Register, value: u32) { - unsafe { - let register = self.base.as_mut_ptr::().add(register as usize); - core::ptr::write_volatile(register as *mut u32, value); - } + unsafe { self.write_raw(register as u32, value) } } fn read(&self, register: Register) -> u32 { unsafe { self.read_raw(register as u32) } } + unsafe fn write_raw(&self, register: u32, value: u32) { + unsafe { + let register = self.base.as_mut_ptr::().add(register as usize); + core::ptr::write_volatile(register as *mut u32, value); + } + } + unsafe fn read_raw(&self, register: u32) -> u32 { let register = self.base.as_ptr::().add(register as usize); core::ptr::read_volatile(register as *const u32) } } -struct Device(BMutex); +struct Device { + e1000: Mutex, + wq: BlockQueue, +} impl Device { fn new(e1000: E1000) -> Self { - Self(BMutex::new(e1000)) + Self { + e1000: Mutex::new(e1000), + wq: BlockQueue::new(), + } + } + + fn handle_irq(&self) { + self.e1000.lock().handle_irq() } } impl NetworkDevice for Device { - fn send(&self, packet: ethernet::Packet) { - self.0.lock().send(packet) + fn send(&self, packet: net::Packet) { + self.e1000.lock_irq().send(packet) + } + + fn recv(&self) -> net::RecvPacket { + let task = scheduler::get_scheduler().current_task(); + self.wq.insert(task.clone()); + + loop { + let mut e1000 = self.e1000.lock_irq(); + if let Some(data) = e1000.recv() { + self.wq.remove(task.clone()); + return data; + } else { + // drop(e1000); + // scheduler::get_scheduler().inner.await_io().unwrap(); + } + } + } + + fn recv_end(&self, packet_id: usize) { + self.e1000.lock_irq().recv_end(packet_id) } fn mac(&self) -> net::MacAddr { - self.0.lock().mac + self.e1000.lock_irq().mac } } @@ -508,12 +643,15 @@ impl PciDeviceHandle for Handler { let e1000 = E1000::new(header).unwrap(); let device = Arc::new(Device::new(e1000)); + DEVICE.call_once(|| device.clone()); net::add_device(device); } } +static DEVICE: Once> = Once::new(); + fn irq_handler(_stack: &mut InterruptStack) { - log::debug!("a!") + DEVICE.get().map(|e| e.handle_irq()); } fn init() { diff --git a/src/aero_kernel/src/main.rs b/src/aero_kernel/src/main.rs index 452b2e808f8..f22f166fb4c 100644 --- a/src/aero_kernel/src/main.rs +++ b/src/aero_kernel/src/main.rs @@ -42,6 +42,7 @@ allocator_api, nonnull_slice_from_raw_parts, maybe_uninit_write_slice, + slice_ptr_get, maybe_uninit_as_bytes )] #![deny(trivial_numeric_casts, unused_allocation)] diff --git a/src/aero_kernel/src/net/dhcp.rs b/src/aero_kernel/src/net/dhcp.rs index 67fe517b3dd..c728e468b70 100644 --- a/src/aero_kernel/src/net/dhcp.rs +++ b/src/aero_kernel/src/net/dhcp.rs @@ -19,11 +19,195 @@ // Dynamic Host Configuration Protocol -use super::{ethernet, ip::Ipv4Addr}; +use byteorder::{ByteOrder, NetworkEndian}; +use simple_endian::BigEndian; + +use super::ip::Ipv4Addr; +use super::udp::{self, Udp}; +use super::{ConstPacketKind, Packet, PacketDownHierarchy, PacketHeader, PacketUpHierarchy}; + +const DHCP_XID: u32 = 0x43424140; + +#[repr(u8)] +enum DhcpType { + BootRequest = 1u8.swap_bytes(), + BootReply = 2u8.swap_bytes(), +} + +#[repr(u8)] +enum HType { + Ethernet = 1u8.swap_bytes(), +} + +#[repr(C, packed)] +struct Header { + op: DhcpType, + htype: HType, + hlen: BigEndian, + hops: BigEndian, + xid: BigEndian, + seconds: BigEndian, + flags: BigEndian, + client_ip: Ipv4Addr, + your_ip: Ipv4Addr, + server_ip: Ipv4Addr, + gateway_ip: Ipv4Addr, + client_hw_addr: [u8; 16], + server_name: [u8; 64], + file: [u8; 128], + options: [u8; 64], +} + +impl Header { + fn options_mut(&mut self) -> OptionsWriter<'_> { + OptionsWriter::new(&mut self.options) + } +} + +pub struct Dhcp; + +impl ConstPacketKind for Dhcp { + const HSIZE: usize = core::mem::size_of::
(); +} + +impl PacketUpHierarchy for Packet {} +impl PacketHeader
for Packet { + fn send(&self) { + self.downgrade().send() // send the UDP packet + } +} + +#[repr(u8)] +enum MessageType { + Discover = 1u8.swap_bytes(), +} + +#[repr(u8)] +enum DhcpOption { + HostName = 12, + MessageType = 53, + ParameterRequestList = 55, + ClientIdentifier = 61, + End = 255, +} + +struct OptionsWriter<'a>(&'a mut [u8]); + +impl<'a> OptionsWriter<'a> { + fn new(options: &'a mut [u8]) -> Self { + options.fill(0); + Self(options).set_magic_cookie() + } + + fn insert(&mut self, kind: DhcpOption, data: &'_ [u8]) { + let total_len = 2 + data.len(); + + assert!(data.len() < u8::MAX as _); + assert!(self.0.len() > total_len); + + let (buf, rest) = core::mem::take(&mut self.0).split_at_mut(total_len); + self.0 = rest; + + buf[0] = kind as u8; + buf[1] = data.len() as _; + buf[2..].copy_from_slice(data); + } + + fn insert_padding(&mut self, size: usize) { + let (buf, rest) = core::mem::take(&mut self.0).split_at_mut(size); + self.0 = rest; + + buf.fill(0); + } + + fn set_magic_cookie(mut self) -> Self { + let (buf, rest) = core::mem::take(&mut self.0).split_at_mut(core::mem::size_of::()); + + // The first four octets of the 'options' field of the DHCP message + // contain the (decimal) values 99, 130, 83 and 99, respectively. + // + // CC: (https://www.rfc-editor.org/rfc/rfc2131#section-3) + NetworkEndian::write_u32(buf, 0x63825363); + self.0 = rest; + self + } + + fn set_message_type(mut self, typ: MessageType) -> Self { + self.insert(DhcpOption::MessageType, &[typ as u8]); + self + } + + fn set_parameter_request_list(mut self) -> Self { + // TODO: Take all of the request flags as an argument. + self.insert( + DhcpOption::ParameterRequestList, + &[ + 1, // Subnet Mask + 3, // Router + 15, // Domain Name + 6, // Domain Server + ], + ); + self + } + + fn set_client_identifier(mut self) -> Self { + let mac = super::default_device().mac(); + + let mut data = [0; 7]; + data[0] = HType::Ethernet as u8; + data[1..].copy_from_slice(mac.0.as_slice()); + + self.insert(DhcpOption::ClientIdentifier, data.as_slice()); + self + } + + fn set_host_name(mut self, name: &str) -> Self { + self.insert(DhcpOption::HostName, name.as_bytes()); + self.insert_padding(1); // null-terminator + self + } +} + +impl<'a> Drop for OptionsWriter<'a> { + fn drop(&mut self) { + self.insert(DhcpOption::End, &[]); + } +} pub fn init() { - // Send DHCP discover message (UDP: source port=67; destination port=68). - let balls = ethernet::Packet::new(ethernet::Type::Ip); + // Send DHCP discover message. + let mut packet = Packet::::create(68, 67, Dhcp::HSIZE, Ipv4Addr::BROADCAST).upgrade(); + let header = packet.header_mut(); + + header.htype = HType::Ethernet; + header.hlen = BigEndian::::from(6); + header.hops = BigEndian::::from(0); + header.xid = BigEndian::::from(DHCP_XID); + header.seconds = BigEndian::::from(0); + { + // Set the HW address. + let mac = super::default_device().mac(); + header.client_hw_addr[0..6].copy_from_slice(mac.0.as_slice()); + header.client_hw_addr[6..].fill(0); + } + header.server_name.fill(0); + header.file.fill(0); + header.options.fill(0); + + header.op = DhcpType::BootRequest; + header.flags = BigEndian::from(0x8000); // broadcast + header.client_ip = Ipv4Addr::EMPTY; + header.your_ip = Ipv4Addr::EMPTY; + header.server_ip = Ipv4Addr::EMPTY; + header.gateway_ip = Ipv4Addr::EMPTY; + + let _ = header + .options_mut() + .set_message_type(MessageType::Discover) + .set_host_name("Aero") + .set_client_identifier() + .set_parameter_request_list(); - super::ethernet::send_packet(balls, Ipv4Addr::BROADCAST); + packet.send() } diff --git a/src/aero_kernel/src/net/ethernet.rs b/src/aero_kernel/src/net/ethernet.rs index 7da3c4d088b..fbaf49bf163 100644 --- a/src/aero_kernel/src/net/ethernet.rs +++ b/src/aero_kernel/src/net/ethernet.rs @@ -17,8 +17,12 @@ * along with Aero. If not, see . */ -use super::arp; -use super::ip::Ipv4Addr; +use core::alloc::{Allocator, Layout}; + +use crate::mem::paging::{PageSize, Size4KiB}; +use crate::utils::dma::DmaAllocator; + +use super::*; #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)] #[repr(C)] @@ -30,31 +34,55 @@ impl MacAddr { #[repr(u16)] pub enum Type { - Ip = 0x800, + Ip = 0x800u16.swap_bytes(), } #[repr(C, packed)] -pub struct Packet { +pub struct Header { pub dest_mac: MacAddr, pub src_mac: MacAddr, pub typ: Type, } -impl Packet { - /// Creates a new ethernet packet. - pub fn new(typ: Type) -> Self { +#[derive(Debug, Clone)] +pub struct Eth; + +impl ConstPacketKind for Eth { + const HSIZE: usize = core::mem::size_of::
(); +} + +impl Packet { + pub fn create(typ: Type, mut size: usize) -> Packet { + size += Eth::HSIZE; + let src_mac = super::default_device().mac(); - Self { - src_mac, - dest_mac: MacAddr([0; 6]), - typ, - } + + // Allocate the packet (needs to be 4KiB aligned). + let layout = unsafe { Layout::from_size_align_unchecked(size, Size4KiB::SIZE as usize) }; + let ptr = DmaAllocator.allocate_zeroed(layout).expect("net: OOM!"); + let addr = VirtAddr::new(ptr.as_mut_ptr() as u64); + + let mut packet = Packet::::new(addr, size); + let header = packet.header_mut(); + + header.src_mac = src_mac; + header.typ = typ; + + packet } } -pub fn send_packet(mut packet: Packet, ip: Ipv4Addr) { - if let Some(addr) = arp::get(ip) { - packet.dest_mac = addr; - super::default_device().send(packet); +impl PacketHeader
for Packet { + fn send(&self) { + let ip = self.upgrade().header().dest_ip; + + if let Some(addr) = arp::get(ip) { + let mut packet = self.clone(); + { + let header = packet.header_mut(); + header.dest_mac = addr; + } + super::default_device().send(packet); + } } } diff --git a/src/aero_kernel/src/net/ip.rs b/src/aero_kernel/src/net/ip.rs index 06b32232801..838221b0aca 100644 --- a/src/aero_kernel/src/net/ip.rs +++ b/src/aero_kernel/src/net/ip.rs @@ -17,6 +17,10 @@ * along with Aero. If not, see . */ +use simple_endian::BigEndian; + +use super::*; + /// Size of IPv4 adderess in octets. /// /// [RFC 8200 § 2]: https://www.rfc-editor.org/rfc/rfc791#section-3.2 @@ -27,4 +31,81 @@ pub struct Ipv4Addr(pub [u8; ADDR_SIZE]); impl Ipv4Addr { pub const BROADCAST: Self = Self([0xff; ADDR_SIZE]); + pub const EMPTY: Self = Self([0x00; ADDR_SIZE]); +} + +#[derive(Debug, Copy, Clone)] +#[repr(u8)] +pub enum Type { + Udp = 17u8.swap_bytes(), +} + +#[repr(C, packed)] +pub struct Header { + pub v: BigEndian, + pub tos: BigEndian, + pub length: BigEndian, + pub ident: BigEndian, + pub frag_offset: BigEndian, + pub ttl: BigEndian, + pub protocol: Type, + pub hcrc: BigEndian, + pub src_ip: Ipv4Addr, + pub dest_ip: Ipv4Addr, +} + +impl Header { + /// Set the payload length. + fn set_length(&mut self, length: u16) { + self.length = BigEndian::from(length); + } +} + +#[derive(Clone)] +pub struct Ipv4; + +impl ConstPacketKind for Ipv4 { + const HSIZE: usize = core::mem::size_of::
(); +} + +impl Packet { + pub fn create(protocol: Type, dest: Ipv4Addr, mut size: usize) -> Packet { + size += Ipv4::HSIZE; + + let mut packet = Packet::::create(ethernet::Type::Ip, size).upgrade(); + let header = packet.header_mut(); + + header.v = BigEndian::::from(0x45); + header.tos = BigEndian::::from(0); + header.ident = BigEndian::::from(0); + header.frag_offset = BigEndian::::from(0); + header.ttl = BigEndian::::from(64); + header.hcrc = BigEndian::::from(0); + + header.set_length(size as _); + + header.protocol = protocol; + header.dest_ip = dest; + + // FIXME: Set the source IPv4 address. + header.src_ip = Ipv4Addr([0; 4]); + + // TODO: Header checksum + packet + } +} + +impl PacketUpHierarchy for Packet {} +impl PacketHeader
for Packet { + fn send(&self) { + { + let mut this = self.clone(); + let header = this.header_mut(); + { + header.hcrc = BigEndian::from(0); + // FIXME: + } + } + self.downgrade().send() // send the ethernet packet + } } diff --git a/src/aero_kernel/src/net/mod.rs b/src/aero_kernel/src/net/mod.rs index d15f4918331..41558718de4 100644 --- a/src/aero_kernel/src/net/mod.rs +++ b/src/aero_kernel/src/net/mod.rs @@ -17,6 +17,8 @@ * along with Aero. If not, see . */ +use core::marker::PhantomData; + use alloc::{sync::Arc, vec::Vec}; use spin::RwLock; @@ -24,17 +26,132 @@ pub mod arp; pub mod dhcp; pub mod ethernet; pub mod ip; +pub mod udp; + +pub use ethernet::{Eth, MacAddr}; -pub use ethernet::MacAddr; +use crate::{ + mem::paging::VirtAddr, + userland::{scheduler, task::Task}, +}; +#[downcastable] pub trait NetworkDevice: Send + Sync { - fn send(&self, packet: ethernet::Packet); + fn send(&self, packet: Packet); + fn recv(&self) -> RecvPacket; + fn recv_end(&self, packet_id: usize); fn mac(&self) -> MacAddr; } +#[derive(Debug)] +pub struct RecvPacket { + pub packet: Packet, + pub id: usize, +} + +impl Drop for RecvPacket { + fn drop(&mut self) { + default_device().recv_end(self.id) + } +} + +pub trait PacketKind {} + +pub trait ConstPacketKind: PacketKind { + const HSIZE: usize; +} + +impl PacketKind for T {} + +impl PacketDownHierarchy for Packet +where + U: PacketKind, + D: ConstPacketKind, + Packet: PacketUpHierarchy, +{ +} + +pub trait PacketBaseTrait { + fn addr(&self) -> VirtAddr; + fn len(&self) -> usize; +} + +pub trait PacketTrait: PacketBaseTrait { + fn header_size(&self) -> usize; +} + +impl PacketTrait for Packet { + fn header_size(&self) -> usize { + T::HSIZE + } +} + +#[derive(Debug, Copy, Clone)] +pub struct Packet { + pub addr: VirtAddr, + pub len: usize, + _phantom: PhantomData, +} + +impl PacketBaseTrait for Packet { + fn addr(&self) -> VirtAddr { + self.addr + } + + fn len(&self) -> usize { + self.len + } +} + +impl Packet { + pub fn new(addr: VirtAddr, len: usize) -> Packet { + Packet:: { + addr, + len, + _phantom: PhantomData::default(), + } + } +} + +pub trait PacketUpHierarchy: PacketTrait { + fn upgrade(&self) -> Packet { + let header_size = self.header_size(); + Packet::::new(self.addr() + header_size, self.len() - header_size) + } +} + +pub trait PacketDownHierarchy: PacketBaseTrait { + fn downgrade(&self) -> Packet { + let header_size = B::HSIZE; + Packet::::new(self.addr() - header_size, self.len() + header_size) + } +} + +pub trait PacketHeader: PacketBaseTrait { + fn send(&self); + + fn header(&self) -> &H { + self.addr().read_mut::().unwrap() + } + + fn header_mut(&mut self) -> &mut H { + self.addr().read_mut::().unwrap() + } +} + static DEVICES: RwLock>> = RwLock::new(Vec::new()); static DEFAULT_DEVICE: RwLock>> = RwLock::new(None); +fn packet_processor_thread() { + let device = default_device(); + + loop { + log::debug!("bruh!"); + let packet = device.recv(); + log::debug!("{packet:?}"); + } +} + pub fn add_device(device: Arc) { DEVICES.write().push(device.clone()); @@ -42,6 +159,12 @@ pub fn add_device(device: Arc) { if default_device.is_none() { *default_device = Some(device); } + + scheduler::get_scheduler().register_task(Task::new_kernel(packet_processor_thread, true)); +} + +pub fn has_default_device() -> bool { + DEFAULT_DEVICE.read().as_ref().is_some() } pub fn default_device() -> Arc { @@ -54,11 +177,12 @@ pub fn default_device() -> Arc { // Initialize the networking stack. pub fn init() { - if DEFAULT_DEVICE.read().is_none() { + if !has_default_device() { // No network devices are avaliable. return; } arp::init(); + log::info!("net::arp: initialized cache"); dhcp::init(); } diff --git a/src/aero_kernel/src/net/udp.rs b/src/aero_kernel/src/net/udp.rs new file mode 100644 index 00000000000..51733d2cc78 --- /dev/null +++ b/src/aero_kernel/src/net/udp.rs @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2021-2023 The Aero Project Developers. + * + * This file is part of The Aero Project. + * + * Aero is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Aero is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Aero. If not, see . + */ + +use simple_endian::BigEndian; + +use super::ip::{Ipv4, Ipv4Addr}; +use super::{ip, PacketDownHierarchy}; + +use super::{ConstPacketKind, Packet, PacketHeader, PacketUpHierarchy}; + +#[derive(Copy, Clone)] +pub struct Udp; + +impl ConstPacketKind for Udp { + const HSIZE: usize = core::mem::size_of::
(); +} + +impl Packet { + pub fn create(src_port: u16, dest_port: u16, mut size: usize, target: Ipv4Addr) -> Packet { + size += Udp::HSIZE; + + let ip_packet = Packet::::create(ip::Type::Udp, target, size); + let mut packet = ip_packet.upgrade(); + + let header = packet.header_mut(); + + header.src_port = BigEndian::from(src_port); + header.dst_port = BigEndian::from(dest_port); + header.len = BigEndian::from(size as u16); + + packet + } +} + +impl PacketUpHierarchy for Packet {} +impl PacketHeader
for Packet { + fn send(&self) { + { + let mut this = self.clone(); + let header = this.header_mut(); + header.compute_checksum(self.downgrade().header()); + } + + self.downgrade().send() // send the IP packet + } +} + +#[repr(C, packed)] +pub struct Header { + pub src_port: BigEndian, + pub dst_port: BigEndian, + pub len: BigEndian, + pub crc: BigEndian, +} + +impl Header { + fn compute_checksum(&mut self, _header: &ip::Header) { + self.crc = BigEndian::from(0); + // FIXME: + } +} diff --git a/src/aero_kernel/src/socket/inet.rs b/src/aero_kernel/src/socket/inet.rs new file mode 100644 index 00000000000..863f29e2843 --- /dev/null +++ b/src/aero_kernel/src/socket/inet.rs @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2021-2023 The Aero Project Developers. + * + * This file is part of The Aero Project. + * + * Aero is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Aero is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Aero. If not, see . + */ + +use alloc::sync::Arc; + +pub struct InetSocket {} + +impl InetSocket { + pub fn new() -> Arc { + Arc::new(Self {}) + } +} diff --git a/src/aero_kernel/src/socket/mod.rs b/src/aero_kernel/src/socket/mod.rs index 8c347b9ab92..fda07b7c1b5 100644 --- a/src/aero_kernel/src/socket/mod.rs +++ b/src/aero_kernel/src/socket/mod.rs @@ -17,6 +17,9 @@ * along with Aero. If not, see . */ +pub mod inet; +pub mod unix; + use aero_syscall::*; use crate::mem::paging::VirtAddr; @@ -45,6 +48,11 @@ impl<'a> SocketAddr<'a> { _ => None, } } -} -pub mod unix; + pub fn as_inet(&self) -> Option<&'a SocketAddrInet> { + match self { + SocketAddr::INet(addr) => Some(addr), + _ => None, + } + } +} diff --git a/src/aero_kernel/src/drivers/block/nvme/dma.rs b/src/aero_kernel/src/utils/dma.rs similarity index 95% rename from src/aero_kernel/src/drivers/block/nvme/dma.rs rename to src/aero_kernel/src/utils/dma.rs index 9e60149243d..9a5f63e3370 100644 --- a/src/aero_kernel/src/drivers/block/nvme/dma.rs +++ b/src/aero_kernel/src/utils/dma.rs @@ -63,6 +63,11 @@ pub type DmaBuffer = Box; pub struct Dma(DmaBuffer); impl Dma { + /// Creates a new DMA buffer intialized with `value`. + pub fn new(value: T) -> Self { + Dma(DmaBuffer::new_in(value, DmaAllocator)) + } + /// Creates a new DMA (Direct Memory Access) buffer and is initialized /// with zeros. /// @@ -70,7 +75,7 @@ impl Dma { /// ```rust,no_run /// let dma: Command = Dma::new(); /// ``` - pub fn new() -> Self { + pub fn zeroed() -> Self { let mut buffer = DmaBuffer::new_uninit_in(DmaAllocator); // SAFETY: Box returns a non-null and aligned pointer. diff --git a/src/aero_kernel/src/utils/mod.rs b/src/aero_kernel/src/utils/mod.rs index 46ba8405b42..ec5ed2f7051 100644 --- a/src/aero_kernel/src/utils/mod.rs +++ b/src/aero_kernel/src/utils/mod.rs @@ -32,6 +32,7 @@ fn get_cpu_count() -> usize { pub mod bitmap; pub mod buffer; +pub mod dma; pub mod sync; pub fn validate_mut_ptr(ptr: *mut T) -> Option<&'static mut T> { diff --git a/userland/Cargo.lock b/userland/Cargo.lock index 1f3fe579f22..276703d9a8c 100644 --- a/userland/Cargo.lock +++ b/userland/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ "lazy_static", "postcard", "serde", - "spin 0.9.4", + "spin 0.9.5", ] [[package]] @@ -40,20 +40,11 @@ dependencies = [ "version_check", ] -[[package]] -name = "aho-corasick" -version = "0.7.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" -dependencies = [ - "memchr", -] - [[package]] name = "atomic-polyfill" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c041a8d9751a520ee19656232a18971f18946a7900f1520ee4400002244dd89" +checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" dependencies = [ "critical-section", ] @@ -64,33 +55,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "bare-metal" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" -dependencies = [ - "rustc_version 0.2.3", -] - -[[package]] -name = "bare-metal" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" - -[[package]] -name = "bit_field" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" - -[[package]] -name = "bitfield" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" - [[package]] name = "bitflags" version = "1.3.2" @@ -109,39 +73,11 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cortex-m" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70858629a458fdfd39f9675c4dc309411f2a3f83bede76988d81bf1a0ecee9e0" -dependencies = [ - "bare-metal 0.2.5", - "bitfield", - "embedded-hal", - "volatile-register", -] - [[package]] name = "critical-section" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95da181745b56d4bd339530ec393508910c909c784e8962d15d722bacf0bcbcd" -dependencies = [ - "bare-metal 1.0.0", - "cfg-if", - "cortex-m", - "riscv", -] - -[[package]] -name = "embedded-hal" -version = "0.2.7" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" -dependencies = [ - "nb 0.1.3", - "void", -] +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" [[package]] name = "getrandom" @@ -150,7 +86,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", - "libc 0.2.137", + "libc 0.2.139", "wasi", ] @@ -180,9 +116,9 @@ checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" dependencies = [ "atomic-polyfill", "hash32", - "rustc_version 0.4.0", + "rustc_version", "serde", - "spin 0.9.4", + "spin 0.9.5", "stable_deref_trait", ] @@ -206,13 +142,13 @@ dependencies = [ [[package]] name = "libc" version = "0.2.125" -source = "git+https://github.com/andy-Python-Programmer/libc#213e47d8f5d87b87539e57dc7d9c24c77d9ba609" +source = "git+https://github.com/andy-Python-Programmer/libc#403b85dfae3708de1328a8c4b246c437194b8e6d" [[package]] name = "libc" -version = "0.2.137" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "lock_api" @@ -224,32 +160,11 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "nb" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" -dependencies = [ - "nb 1.0.0", -] - -[[package]] -name = "nb" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" - [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "postcard" @@ -270,76 +185,29 @@ checksum = "7c68cb38ed13fd7bc9dd5db8f165b7c8d9c1a315104083a2b10f11354c2af97f" [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] -[[package]] -name = "regex" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" - -[[package]] -name = "riscv" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6907ccdd7a31012b70faf2af85cd9e5ba97657cc3987c4f13f8e4d2c2a088aba" -dependencies = [ - "bare-metal 1.0.0", - "bit_field", - "riscv-target", -] - -[[package]] -name = "riscv-target" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222" -dependencies = [ - "lazy_static", - "regex", -] - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.14", + "semver", ] [[package]] @@ -350,39 +218,24 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" - -[[package]] -name = "semver-parser" -version = "0.7.0" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" [[package]] name = "serde" -version = "1.0.147" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", @@ -397,9 +250,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spin" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +checksum = "7dccf47db1b41fa1573ed27ccf5e08e3ca771cb994f776668c5ebda893b248fc" dependencies = [ "lock_api", ] @@ -412,9 +265,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "syn" -version = "1.0.103" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", @@ -428,14 +281,14 @@ dependencies = [ "aero_ipc", "aero_syscall", "hashbrown", - "spin 0.9.4", + "spin 0.9.5", ] [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "utest" @@ -454,33 +307,12 @@ dependencies = [ "syn", ] -[[package]] -name = "vcell" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" - [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - -[[package]] -name = "volatile-register" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6" -dependencies = [ - "vcell", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -494,7 +326,7 @@ dependencies = [ "aero_ipc", "aero_syscall", "hashbrown", - "spin 0.9.4", + "spin 0.9.5", ] [[package]] From 569b9896f76fe1fce65208cb261f68e5632bd263 Mon Sep 17 00:00:00 2001 From: Andy-Python-Programmer Date: Fri, 17 Feb 2023 18:16:07 +1100 Subject: [PATCH 6/6] bootstrap::llvm: update to 14.0.1 Signed-off-by: Andy-Python-Programmer --- bootstrap.yml | 4 +- patches/llvm/llvm.patch | 159 ++++++++++++++++++++-------------------- 2 files changed, 82 insertions(+), 81 deletions(-) diff --git a/bootstrap.yml b/bootstrap.yml index af3335f1c7e..cfa6e692fb0 100644 --- a/bootstrap.yml +++ b/bootstrap.yml @@ -75,8 +75,8 @@ sources: - name: llvm subdir: 'bundled' git: 'https://github.com/llvm/llvm-project.git' - tag: 'llvmorg-13.0.0' - version: '13.0.0' + tag: 'llvmorg-14.0.1' + version: '14.0.1' # --------------------------------------------------------------------------- # Rust patched crates start diff --git a/patches/llvm/llvm.patch b/patches/llvm/llvm.patch index fdf2018b488..17987cb2a11 100644 --- a/patches/llvm/llvm.patch +++ b/patches/llvm/llvm.patch @@ -1,34 +1,34 @@ -From e8b0511dc10a7bf17b34021e58f7ca71bef59fc5 Mon Sep 17 00:00:00 2001 -From: czapek1337 -Date: Sat, 8 Jan 2022 05:22:31 +0100 -Subject: [PATCH] targets: add new aero target +From 20cff6e42171169bd1b78d7ccffec0ab608e1eaa Mon Sep 17 00:00:00 2001 +From: Andy-Python-Programmer +Date: Thu, 16 Feb 2023 17:54:52 +1100 +Subject: [PATCH] targets: add aero +Signed-off-by: Andy-Python-Programmer --- - clang/lib/Basic/Targets.cpp | 6 + - clang/lib/Basic/Targets/OSTargets.h | 28 ++ - clang/lib/Driver/CMakeLists.txt | 1 + - clang/lib/Driver/Driver.cpp | 4 + - clang/lib/Driver/ToolChains/Aero.cpp | 438 ++++++++++++++++++ - clang/lib/Driver/ToolChains/Aero.h | 49 ++ - clang/lib/Driver/ToolChains/Gnu.cpp | 13 +- - llvm/cmake/modules/CrossCompile.cmake | 4 +- - llvm/include/llvm/ADT/Triple.h | 5 +- - llvm/include/llvm/Support/SwapByteOrder.h | 2 +- - llvm/lib/Support/Triple.cpp | 6 + - llvm/lib/Support/Unix/Path.inc | 6 +- - llvm/lib/Support/Unix/Program.inc | 1 + - llvm/tools/llvm-dwarfdump/Statistics.cpp | 1 + - llvm/tools/llvm-shlib/CMakeLists.txt | 1 + - llvm/utils/benchmark/src/benchmark_register.h | 1 + - 16 files changed, 556 insertions(+), 10 deletions(-) + clang/lib/Basic/Targets.cpp | 6 + + clang/lib/Basic/Targets/OSTargets.h | 28 ++ + clang/lib/Driver/CMakeLists.txt | 1 + + clang/lib/Driver/Driver.cpp | 4 + + clang/lib/Driver/ToolChains/Aero.cpp | 438 ++++++++++++++++++++++ + clang/lib/Driver/ToolChains/Aero.h | 49 +++ + clang/lib/Driver/ToolChains/Gnu.cpp | 13 +- + llvm/cmake/modules/CrossCompile.cmake | 4 +- + llvm/include/llvm/ADT/Triple.h | 5 +- + llvm/include/llvm/Support/SwapByteOrder.h | 2 +- + llvm/lib/Support/Triple.cpp | 6 + + llvm/lib/Support/Unix/Path.inc | 6 +- + llvm/lib/Support/Unix/Program.inc | 1 + + llvm/tools/llvm-dwarfdump/Statistics.cpp | 2 + + llvm/tools/llvm-shlib/CMakeLists.txt | 1 + + 15 files changed, 556 insertions(+), 10 deletions(-) create mode 100644 clang/lib/Driver/ToolChains/Aero.cpp create mode 100644 clang/lib/Driver/ToolChains/Aero.h diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp -index c063f8ca4..d8b6878f1 100644 +index 994a491cdd..098b0d5fb7 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp -@@ -144,6 +144,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, +@@ -149,6 +149,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new NetBSDTargetInfo(Triple, Opts); case llvm::Triple::OpenBSD: return new OpenBSDTargetInfo(Triple, Opts); @@ -37,7 +37,7 @@ index c063f8ca4..d8b6878f1 100644 case llvm::Triple::Win32: switch (Triple.getEnvironment()) { case llvm::Triple::GNU: -@@ -387,6 +389,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, +@@ -420,6 +422,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new FuchsiaTargetInfo(Triple, Opts); case llvm::Triple::Linux: return new LinuxTargetInfo(Triple, Opts); @@ -46,7 +46,7 @@ index c063f8ca4..d8b6878f1 100644 default: return new RISCV64TargetInfo(Triple, Opts); } -@@ -553,6 +557,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, +@@ -586,6 +590,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, } case llvm::Triple::Haiku: return new HaikuTargetInfo(Triple, Opts); @@ -56,13 +56,13 @@ index c063f8ca4..d8b6878f1 100644 return new NaClTargetInfo(Triple, Opts); case llvm::Triple::PS4: diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h -index 70fac030b..93fc21c3d 100644 +index 3c1830d5f8..2123019378 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h -@@ -342,6 +342,34 @@ public: +@@ -338,6 +338,34 @@ public: : OSTargetInfo(Triple, Opts) {} }; - + +// Aero Target +template +class LLVM_LIBRARY_VISIBILITY AeroTargetInfo : public OSTargetInfo { @@ -95,10 +95,10 @@ index 70fac030b..93fc21c3d 100644 template class LLVM_LIBRARY_VISIBILITY MinixTargetInfo : public OSTargetInfo { diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt -index 6f25d3588..a59e549ef 100644 +index 78e8fd1852..8a53a0a7ab 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt -@@ -54,6 +54,7 @@ add_clang_library(clangDriver +@@ -59,6 +59,7 @@ add_clang_library(clangDriver ToolChains/Hexagon.cpp ToolChains/Hurd.cpp ToolChains/Linux.cpp @@ -107,10 +107,10 @@ index 6f25d3588..a59e549ef 100644 ToolChains/MinGW.cpp ToolChains/Minix.cpp diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp -index fb8335a36..05adcae7d 100644 +index 3bfddeefc7..9773e5efd1 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp -@@ -29,6 +29,7 @@ +@@ -30,6 +30,7 @@ #include "ToolChains/Hurd.h" #include "ToolChains/Lanai.h" #include "ToolChains/Linux.h" @@ -118,7 +118,7 @@ index fb8335a36..05adcae7d 100644 #include "ToolChains/MSP430.h" #include "ToolChains/MSVC.h" #include "ToolChains/MinGW.h" -@@ -4853,6 +4854,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, +@@ -5564,6 +5565,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::Fuchsia: TC = std::make_unique(*this, Target, Args); break; @@ -130,7 +130,7 @@ index fb8335a36..05adcae7d 100644 break; diff --git a/clang/lib/Driver/ToolChains/Aero.cpp b/clang/lib/Driver/ToolChains/Aero.cpp new file mode 100644 -index 000000000..4cd7765ae +index 0000000000..4cd7765aeb --- /dev/null +++ b/clang/lib/Driver/ToolChains/Aero.cpp @@ -0,0 +1,438 @@ @@ -574,7 +574,7 @@ index 000000000..4cd7765ae + diff --git a/clang/lib/Driver/ToolChains/Aero.h b/clang/lib/Driver/ToolChains/Aero.h new file mode 100644 -index 000000000..e9016f4a8 +index 0000000000..e9016f4a81 --- /dev/null +++ b/clang/lib/Driver/ToolChains/Aero.h @@ -0,0 +1,49 @@ @@ -628,7 +628,7 @@ index 000000000..e9016f4a8 + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MANAGARM_H diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp -index da39f29e4..b6f6bb439 100644 +index 7a9570a686..8114baabb0 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -246,6 +246,8 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { @@ -640,40 +640,40 @@ index da39f29e4..b6f6bb439 100644 return "aarch64linux"; case llvm::Triple::aarch64_be: return "aarch64linuxb"; -@@ -2077,7 +2079,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( +@@ -2073,7 +2075,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( static const char *const AArch64LibDirs[] = {"/lib64", "/lib"}; static const char *const AArch64Triples[] = { "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux", -- "aarch64-suse-linux", "aarch64-linux-android"}; -+ "aarch64-suse-linux", "aarch64-linux-android", -+ "aarch64-aero", "aarch64-aero-system", "aarch64-aero-kernel"}; +- "aarch64-suse-linux"}; ++ "aarch64-suse-linux", "aarch64-aero", "aarch64-aero-system", ++ "aarch64-aero-kernel"}; static const char *const AArch64beLibDirs[] = {"/lib"}; static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu", "aarch64_be-linux-gnu"}; -@@ -2105,7 +2108,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( +@@ -2099,7 +2102,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( "x86_64-redhat-linux", "x86_64-suse-linux", "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux", "x86_64-unknown-linux", -- "x86_64-amazon-linux", "x86_64-linux-android"}; -+ "x86_64-amazon-linux", "x86_64-linux-android", -+ "x86_64-aero", "x86_64-aero-system", "x86_64-aero-kernel"}; +- "x86_64-amazon-linux"}; ++ "x86_64-amazon-linux", "x86_64-aero", "x86_64-aero-system", ++ "x86_64-aero-kernel"}; static const char *const X32Triples[] = {"x86_64-linux-gnux32", "x86_64-pc-linux-gnux32"}; static const char *const X32LibDirs[] = {"/libx32", "/lib"}; -@@ -2183,7 +2187,10 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( +@@ -2171,7 +2175,10 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( + static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"}; + static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu", "riscv64-linux-gnu", - "riscv64-unknown-elf", - "riscv64-redhat-linux", -- "riscv64-suse-linux"}; -+ "riscv64-suse-linux", +- "riscv64-unknown-elf"}; ++ "riscv64-unknown-elf", + "riscv64-aero", + "riscv64-aero-kernel", + "riscv64-aero-system"}; - + static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"}; static const char *const SPARCv8Triples[] = {"sparc-linux-gnu", diff --git a/llvm/cmake/modules/CrossCompile.cmake b/llvm/cmake/modules/CrossCompile.cmake -index 8a6e880c4..fb86a7c17 100644 +index 2a39b6a40a..ceceb2aab9 100644 --- a/llvm/cmake/modules/CrossCompile.cmake +++ b/llvm/cmake/modules/CrossCompile.cmake @@ -17,8 +17,8 @@ function(llvm_create_cross_target project_name target_name toolchain buildtype) @@ -688,10 +688,10 @@ index 8a6e880c4..fb86a7c17 100644 endif() set(CROSS_TOOLCHAIN_FLAGS_${target_name} ${CROSS_TOOLCHAIN_FLAGS_INIT} diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h -index 76a754d67..5899b5449 100644 +index 42277c0130..35516ec5af 100644 --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h -@@ -168,6 +168,7 @@ public: +@@ -181,6 +181,7 @@ public: Linux, Lv2, // PS3 MacOSX, @@ -699,7 +699,7 @@ index 76a754d67..5899b5449 100644 NetBSD, OpenBSD, Solaris, -@@ -217,7 +218,9 @@ public: +@@ -232,7 +233,9 @@ public: CoreCLR, Simulator, // Simulator variants of other systems, e.g., Apple's iOS MacABI, // Mac Catalyst variant of Apple's iOS deployment target. @@ -711,12 +711,12 @@ index 76a754d67..5899b5449 100644 enum ObjectFormatType { UnknownObjectFormat, diff --git a/llvm/include/llvm/Support/SwapByteOrder.h b/llvm/include/llvm/Support/SwapByteOrder.h -index e8612ba66..7c4e941bd 100644 +index e8612ba665..7c4e941bd2 100644 --- a/llvm/include/llvm/Support/SwapByteOrder.h +++ b/llvm/include/llvm/Support/SwapByteOrder.h @@ -22,7 +22,7 @@ #endif - + #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \ - defined(__Fuchsia__) || defined(__EMSCRIPTEN__) + defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__aero__) @@ -724,18 +724,18 @@ index e8612ba66..7c4e941bd 100644 #elif defined(_AIX) #include diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp -index 883115463..e27e27ecc 100644 +index a9afcc9db9..ccb0ca0601 100644 --- a/llvm/lib/Support/Triple.cpp +++ b/llvm/lib/Support/Triple.cpp -@@ -189,6 +189,7 @@ StringRef Triple::getOSTypeName(OSType Kind) { +@@ -195,6 +195,7 @@ StringRef Triple::getOSTypeName(OSType Kind) { case UnknownOS: return "unknown"; - + case AIX: return "aix"; + case Aero: return "aero"; case AMDHSA: return "amdhsa"; case AMDPAL: return "amdpal"; case Ananas: return "ananas"; -@@ -245,6 +246,7 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) { +@@ -251,6 +252,7 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) { case GNUX32: return "gnux32"; case GNUILP32: return "gnu_ilp32"; case Itanium: return "itanium"; @@ -743,23 +743,23 @@ index 883115463..e27e27ecc 100644 case MSVC: return "msvc"; case MacABI: return "macabi"; case Musl: return "musl"; -@@ -252,6 +254,7 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) { +@@ -258,6 +260,7 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) { case MuslEABIHF: return "musleabihf"; case MuslX32: return "muslx32"; case Simulator: return "simulator"; + case System: return "system"; } - + llvm_unreachable("Invalid EnvironmentType!"); -@@ -502,6 +505,7 @@ static Triple::VendorType parseVendor(StringRef VendorName) { - +@@ -512,6 +515,7 @@ static Triple::VendorType parseVendor(StringRef VendorName) { + static Triple::OSType parseOS(StringRef OSName) { return StringSwitch(OSName) + .StartsWith("aero", Triple::Aero) .StartsWith("ananas", Triple::Ananas) .StartsWith("cloudabi", Triple::CloudABI) .StartsWith("darwin", Triple::Darwin) -@@ -560,9 +564,11 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { +@@ -570,9 +574,11 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { .StartsWith("musl", Triple::Musl) .StartsWith("msvc", Triple::MSVC) .StartsWith("itanium", Triple::Itanium) @@ -772,11 +772,11 @@ index 883115463..e27e27ecc 100644 .Default(Triple::UnknownEnvironment); } diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc -index 2a03dc682..e75ff461d 100644 +index 788460d657..85d46701e2 100644 --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc -@@ -64,7 +64,7 @@ extern char **environ; - +@@ -74,7 +74,7 @@ extern char **environ; + #include #if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && \ - !defined(__linux__) && !defined(__FreeBSD_kernel__) && !defined(_AIX) @@ -784,7 +784,7 @@ index 2a03dc682..e75ff461d 100644 #include #define STATVFS statvfs #define FSTATVFS fstatvfs -@@ -73,7 +73,7 @@ extern char **environ; +@@ -83,7 +83,7 @@ extern char **environ; #if defined(__OpenBSD__) || defined(__FreeBSD__) #include #include @@ -793,9 +793,9 @@ index 2a03dc682..e75ff461d 100644 #if defined(HAVE_LINUX_MAGIC_H) #include #else -@@ -431,7 +431,7 @@ std::error_code remove(const Twine &path, bool IgnoreNonExisting) { +@@ -478,7 +478,7 @@ std::error_code remove(const Twine &path, bool IgnoreNonExisting) { } - + static bool is_local_impl(struct STATVFS &Vfs) { -#if defined(__linux__) || defined(__GNU__) +#if defined(__linux__) || defined(__GNU__) || defined(__aero__) @@ -803,32 +803,32 @@ index 2a03dc682..e75ff461d 100644 #define NFS_SUPER_MAGIC 0x6969 #endif diff --git a/llvm/lib/Support/Unix/Program.inc b/llvm/lib/Support/Unix/Program.inc -index 520685a0e..e6c2ddf20 100644 +index 089342030b..0616096541 100644 --- a/llvm/lib/Support/Unix/Program.inc +++ b/llvm/lib/Support/Unix/Program.inc -@@ -39,6 +39,7 @@ +@@ -41,6 +41,7 @@ #if HAVE_UNISTD_H #include #endif +#undef HAVE_POSIX_SPAWN #ifdef HAVE_POSIX_SPAWN #include - + diff --git a/llvm/tools/llvm-dwarfdump/Statistics.cpp b/llvm/tools/llvm-dwarfdump/Statistics.cpp -index 19a971afa..929184bfc 100644 +index 5c08e43b4b..a19c74e82c 100644 --- a/llvm/tools/llvm-dwarfdump/Statistics.cpp +++ b/llvm/tools/llvm-dwarfdump/Statistics.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// - + +#include + #include "llvm-dwarfdump.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringSet.h" diff --git a/llvm/tools/llvm-shlib/CMakeLists.txt b/llvm/tools/llvm-shlib/CMakeLists.txt -index 3eb6db33a..554264a07 100644 +index 8e2b78f1b8..e1bd74eaf7 100644 --- a/llvm/tools/llvm-shlib/CMakeLists.txt +++ b/llvm/tools/llvm-shlib/CMakeLists.txt @@ -36,6 +36,7 @@ if(LLVM_BUILD_LLVM_DYLIB) @@ -839,5 +839,6 @@ index 3eb6db33a..554264a07 100644 OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD") OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia") OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly") --- -2.34.1 +-- +2.39.1 +