From 8d94ea66a3eb3e02039730c8d08e9bead8c344b8 Mon Sep 17 00:00:00 2001 From: YJwu2023 Date: Mon, 28 Aug 2023 15:43:07 +0800 Subject: [PATCH] Patch ahci (#348) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Modify the ahci module and delete the useless c code 修改ahci使其不再依赖旧的pci函数 删除旧的pci、msi函数代码 --- kernel/src/arch/x86_64/ia64_msi.c | 28 -- kernel/src/arch/x86_64/ia64_msi.h | 11 - kernel/src/debug/traceback/traceback.h | 8 +- kernel/src/driver/disk/Makefile | 7 +- kernel/src/driver/disk/ahci/ahci.c | 32 -- kernel/src/driver/disk/ahci/ahci.h | 359 ---------------- kernel/src/driver/disk/ahci/ahci_rust.h | 19 - kernel/src/driver/disk/ahci/mod.rs | 117 ++--- kernel/src/driver/pci/Makefile | 7 +- kernel/src/driver/pci/msi.c | 340 --------------- kernel/src/driver/pci/msi.h | 110 ----- kernel/src/driver/pci/pci.c | 542 ------------------------ kernel/src/driver/pci/pci.h | 225 ---------- kernel/src/driver/virtio/virtio.rs | 4 +- kernel/src/include/bindings/wrapper.h | 2 - kernel/src/main.c | 3 - kernel/src/time/syscall.rs | 3 +- kernel/src/time/timekeeping.rs | 4 +- 18 files changed, 73 insertions(+), 1748 deletions(-) delete mode 100644 kernel/src/arch/x86_64/ia64_msi.c delete mode 100644 kernel/src/arch/x86_64/ia64_msi.h delete mode 100644 kernel/src/driver/disk/ahci/ahci.c delete mode 100644 kernel/src/driver/disk/ahci/ahci_rust.h delete mode 100644 kernel/src/driver/pci/msi.c delete mode 100644 kernel/src/driver/pci/msi.h delete mode 100644 kernel/src/driver/pci/pci.c delete mode 100644 kernel/src/driver/pci/pci.h diff --git a/kernel/src/arch/x86_64/ia64_msi.c b/kernel/src/arch/x86_64/ia64_msi.c deleted file mode 100644 index a2b36076e..000000000 --- a/kernel/src/arch/x86_64/ia64_msi.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "ia64_msi.h" - -/** - * @brief 生成架构相关的msi的message address - * - */ -#define ia64_pci_get_arch_msi_message_address(processor) ((0xfee00000UL | (processor << 12))) - -/** - * @brief 生成架构相关的message data - * - */ -#define ia64_pci_get_arch_msi_message_data(vector, processor, edge_trigger, assert) ((uint32_t)((vector & 0xff) | (edge_trigger == 1 ? 0 : (1 << 15)) | ((assert == 0) ? 0 : (1 << 14)))) - -/** - * @brief 生成msi消息 - * - * @param msi_desc msi描述符 - * @return struct msi_msg_t* msi消息指针(在描述符内) - */ -struct msi_msg_t *msi_arch_get_msg(struct msi_desc_t *msi_desc) -{ - msi_desc->msg.address_hi = 0; - msi_desc->msg.address_lo = ia64_pci_get_arch_msi_message_address(msi_desc->processor); - msi_desc->msg.data = ia64_pci_get_arch_msi_message_data(msi_desc->irq_num, msi_desc->processor, msi_desc->edge_trigger, msi_desc->assert); - msi_desc->msg.vector_control = 0; - return &(msi_desc->msg); -} diff --git a/kernel/src/arch/x86_64/ia64_msi.h b/kernel/src/arch/x86_64/ia64_msi.h deleted file mode 100644 index 43dd15676..000000000 --- a/kernel/src/arch/x86_64/ia64_msi.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -/** - * @brief 生成msi消息 - * - * @param msi_desc msi描述符 - * @return struct msi_msg_t* msi消息指针(在描述符内) - */ -struct msi_msg_t *msi_arch_get_msg(struct msi_desc_t *msi_desc); \ No newline at end of file diff --git a/kernel/src/debug/traceback/traceback.h b/kernel/src/debug/traceback/traceback.h index 79a6209b1..837cb502d 100644 --- a/kernel/src/debug/traceback/traceback.h +++ b/kernel/src/debug/traceback/traceback.h @@ -1,17 +1,17 @@ #pragma once #include -#include +#include // 使用弱引用属性导出kallsyms中的符号表。 // 采用weak属性是由于第一次编译时,kallsyms还未链接进来,若不使用weak属性则会报错 extern const uint64_t kallsyms_address[] __attribute__((weak)); extern const uint64_t kallsyms_num __attribute__((weak)); extern const uint64_t kallsyms_names_index[] __attribute__((weak)); -extern const char* kallsyms_names __attribute__((weak)); +extern const char *kallsyms_names __attribute__((weak)); /** * @brief 追溯内核栈调用情况 - * + * * @param regs 内核栈结构体 */ -void traceback(struct pt_regs * regs); \ No newline at end of file +void traceback(struct pt_regs *regs); \ No newline at end of file diff --git a/kernel/src/driver/disk/Makefile b/kernel/src/driver/disk/Makefile index 960b6131f..377024dc4 100644 --- a/kernel/src/driver/disk/Makefile +++ b/kernel/src/driver/disk/Makefile @@ -1,10 +1,7 @@ -all: ata.o ahci.o +all: ata.o CFLAGS += -I . ata.o: ata.c - $(CC) $(CFLAGS) -c ata.c -o ata.o - -ahci.o: ahci/ahci.c - $(CC) $(CFLAGS) -c ahci/ahci.c -o ahci/ahci.o \ No newline at end of file + $(CC) $(CFLAGS) -c ata.c -o ata.o \ No newline at end of file diff --git a/kernel/src/driver/disk/ahci/ahci.c b/kernel/src/driver/disk/ahci/ahci.c deleted file mode 100644 index b58daebf7..000000000 --- a/kernel/src/driver/disk/ahci/ahci.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "ahci.h" -#include -#include -#include -#include -#include -#include - -/// @brief 保留了对 pci设备获取 和 mm内存映射 的依赖 -void ahci_cpp_init(uint32_t *count_ahci_devices, struct pci_device_structure_header_t *ahci_devs[MAX_AHCI_DEVICES], struct pci_device_structure_general_device_t *gen_devs[MAX_AHCI_DEVICES]) -{ - kinfo("Initializing AHCI..."); - - pci_get_device_structure(0x1, 0x6, ahci_devs, count_ahci_devices); - - if (*count_ahci_devices == 0) - { - kwarn("There is no AHCI device found on this computer!"); - return; - } - - for (int i = 0; i < *count_ahci_devices; i++) - { - gen_devs[i] = ((struct pci_device_structure_general_device_t *)(ahci_devs[i])); - } - - // 映射ABAR - uint32_t bar5 = gen_devs[0]->BAR5; - rs_map_phys(AHCI_MAPPING_BASE, (ul)(bar5)&PAGE_2M_MASK, PAGE_2M_SIZE, PAGE_KERNEL_PAGE); - - kinfo("ABAR mapped!"); -} diff --git a/kernel/src/driver/disk/ahci/ahci.h b/kernel/src/driver/disk/ahci/ahci.h index d518a5414..c554d8a11 100644 --- a/kernel/src/driver/disk/ahci/ahci.h +++ b/kernel/src/driver/disk/ahci/ahci.h @@ -1,364 +1,5 @@ #pragma once -#include -#include -#include - -/** - * @todo 加入io调度器(当操作系统实现了多进程之后要加入这个) - * - */ -#define AHCI_MAPPING_BASE SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + AHCI_MAPPING_OFFSET - -#define MAX_AHCI_DEVICES 100 - -#define HBA_PxCMD_ST 0x0001 -#define HBA_PxCMD_FRE 0x0010 -#define HBA_PxCMD_FR 0x4000 -#define HBA_PxCMD_CR 0x8000 - -#define AHCI_DEV_BUSY 0x80 -#define AHCI_DEV_DRQ 0x08 - -#define AHCI_CMD_READ_DMA_EXT 0x25 -#define AHCI_CMD_WRITE_DMA_EXT 0x30 - -#define HBA_PxIS_TFES (1 << 30) /* TFES - Task File Error Status */ - -#define AHCI_SUCCESS 0 // 请求成功 -#define E_NOEMPTYSLOT 1 // 没有空闲的slot -#define E_PORT_HUNG 2 // 端口被挂起 -#define E_TASK_FILE_ERROR 3 // 任务文件错误 -#define E_UNSUPPORTED_CMD 4 // 不支持的命令 - -extern struct block_device_operation ahci_operation; - -/** - * @brief 在SATA3.0规范中定义的Frame Information Structure类型 - * - */ -typedef enum -{ - FIS_TYPE_REG_H2D = 0x27, // Register FIS - host to device - FIS_TYPE_REG_D2H = 0x34, // Register FIS - device to host - FIS_TYPE_DMA_ACT = 0x39, // DMA activate FIS - device to host - FIS_TYPE_DMA_SETUP = 0x41, // DMA setup FIS - bidirectional - FIS_TYPE_DATA = 0x46, // Data FIS - bidirectional - FIS_TYPE_BIST = 0x58, // BIST activate FIS - bidirectional - FIS_TYPE_PIO_SETUP = 0x5F, // PIO setup FIS - device to host - FIS_TYPE_DEV_BITS = 0xA1, // Set device bits FIS - device to host -} FIS_TYPE; - -/** - * @brief FIS_REG_H2D 被用于从主机向设备发送控制命令 - * 注意:reserved bit应当被清零 - */ -typedef struct tagFIS_REG_H2D -{ - // DWORD 0 - uint8_t fis_type; // FIS_TYPE_REG_H2D - - uint8_t pmport : 4; // Port multiplier - uint8_t rsv0 : 3; // Reserved - uint8_t c : 1; // 1: Command, 0: Control - - uint8_t command; // Command register - uint8_t featurel; // Feature register, 7:0 - - // DWORD 1 - uint8_t lba0; // LBA low register, 7:0 - uint8_t lba1; // LBA mid register, 15:8 - uint8_t lba2; // LBA high register, 23:16 - uint8_t device; // Device register - - // DWORD 2 - uint8_t lba3; // LBA register, 31:24 - uint8_t lba4; // LBA register, 39:32 - uint8_t lba5; // LBA register, 47:40 - uint8_t featureh; // Feature register, 15:8 - - // DWORD 3 - uint8_t countl; // Count register, 7:0 - uint8_t counth; // Count register, 15:8 - uint8_t icc; // Isochronous command completion - uint8_t control; // Control register - - // DWORD 4 - uint8_t rsv1[4]; // Reserved -} FIS_REG_H2D; - -// A device to host register FIS is used by the device to notify the host that some ATA register has changed. -// It contains the updated task files such as status, error and other registers. -typedef struct tagFIS_REG_D2H -{ - // DWORD 0 - uint8_t fis_type; // FIS_TYPE_REG_D2H - - uint8_t pmport : 4; // Port multiplier - uint8_t rsv0 : 2; // Reserved - uint8_t i : 1; // Interrupt bit - uint8_t rsv1 : 1; // Reserved - - uint8_t status; // Status register - uint8_t error; // Error register - - // DWORD 1 - uint8_t lba0; // LBA low register, 7:0 - uint8_t lba1; // LBA mid register, 15:8 - uint8_t lba2; // LBA high register, 23:16 - uint8_t device; // Device register - - // DWORD 2 - uint8_t lba3; // LBA register, 31:24 - uint8_t lba4; // LBA register, 39:32 - uint8_t lba5; // LBA register, 47:40 - uint8_t rsv2; // Reserved - - // DWORD 3 - uint8_t countl; // Count register, 7:0 - uint8_t counth; // Count register, 15:8 - uint8_t rsv3[2]; // Reserved - - // DWORD 4 - uint8_t rsv4[4]; // Reserved -} FIS_REG_D2H; - -// This FIS is used by the host or device to send data payload. The data size can be varied. -typedef struct tagFIS_DATA -{ - // DWORD 0 - uint8_t fis_type; // FIS_TYPE_DATA - - uint8_t pmport : 4; // Port multiplier - uint8_t rsv0 : 4; // Reserved - - uint8_t rsv1[2]; // Reserved - - // DWORD 1 ~ N - uint32_t data[1]; // Payload -} FIS_DATA; - -// This FIS is used by the device to tell the host that it’s about to send or ready to receive a PIO data payload. -typedef struct tagFIS_PIO_SETUP -{ - // DWORD 0 - uint8_t fis_type; // FIS_TYPE_PIO_SETUP - - uint8_t pmport : 4; // Port multiplier - uint8_t rsv0 : 1; // Reserved - uint8_t d : 1; // Data transfer direction, 1 - device to host - uint8_t i : 1; // Interrupt bit - uint8_t rsv1 : 1; - - uint8_t status; // Status register - uint8_t error; // Error register - - // DWORD 1 - uint8_t lba0; // LBA low register, 7:0 - uint8_t lba1; // LBA mid register, 15:8 - uint8_t lba2; // LBA high register, 23:16 - uint8_t device; // Device register - - // DWORD 2 - uint8_t lba3; // LBA register, 31:24 - uint8_t lba4; // LBA register, 39:32 - uint8_t lba5; // LBA register, 47:40 - uint8_t rsv2; // Reserved - - // DWORD 3 - uint8_t countl; // Count register, 7:0 - uint8_t counth; // Count register, 15:8 - uint8_t rsv3; // Reserved - uint8_t e_status; // New value of status register - - // DWORD 4 - uint16_t tc; // Transfer count - uint8_t rsv4[2]; // Reserved -} FIS_PIO_SETUP; - -typedef struct tagFIS_DMA_SETUP -{ - // DWORD 0 - uint8_t fis_type; // FIS_TYPE_DMA_SETUP - - uint8_t pmport : 4; // Port multiplier - uint8_t rsv0 : 1; // Reserved - uint8_t d : 1; // Data transfer direction, 1 - device to host - uint8_t i : 1; // Interrupt bit - uint8_t a : 1; // Auto-activate. Specifies if DMA Activate FIS is needed - - uint8_t rsved[2]; // Reserved - - // DWORD 1&2 - - uint64_t DMAbufferID; // DMA Buffer Identifier. Used to Identify DMA buffer in host memory. - // SATA Spec says host specific and not in Spec. Trying AHCI spec might work. - - // DWORD 3 - uint32_t rsvd; // More reserved - - // DWORD 4 - uint32_t DMAbufOffset; // Byte offset into buffer. First 2 bits must be 0 - - // DWORD 5 - uint32_t TransferCount; // Number of bytes to transfer. Bit 0 must be 0 - - // DWORD 6 - uint32_t resvd; // Reserved - -} FIS_DMA_SETUP; - -typedef volatile struct tagHBA_PORT -{ - uint64_t clb; // 0x00, command list base address, 1K-byte aligned - uint64_t fb; // 0x08, FIS base address, 256-byte aligned - uint32_t is; // 0x10, interrupt status - uint32_t ie; // 0x14, interrupt enable - uint32_t cmd; // 0x18, command and status - uint32_t rsv0; // 0x1C, Reserved - uint32_t tfd; // 0x20, task file data - uint32_t sig; // 0x24, signature - uint32_t ssts; // 0x28, SATA status (SCR0:SStatus) - uint32_t sctl; // 0x2C, SATA control (SCR2:SControl) - uint32_t serr; // 0x30, SATA error (SCR1:SError) - uint32_t sact; // 0x34, SATA active (SCR3:SActive) - uint32_t ci; // 0x38, command issue - uint32_t sntf; // 0x3C, SATA notification (SCR4:SNotification) - uint32_t fbs; // 0x40, FIS-based switch control - uint32_t rsv1[11]; // 0x44 ~ 0x6F, Reserved - uint32_t vendor[4]; // 0x70 ~ 0x7F, vendor specific -} HBA_PORT; -typedef volatile struct tagHBA_MEM -{ - // 0x00 - 0x2B, Generic Host Control - uint32_t cap; // 0x00, Host capability - uint32_t ghc; // 0x04, Global host control - uint32_t is; // 0x08, Interrupt status - uint32_t pi; // 0x0C, Port implemented - uint32_t vs; // 0x10, Version - uint32_t ccc_ctl; // 0x14, Command completion coalescing control - uint32_t ccc_pts; // 0x18, Command completion coalescing ports - uint32_t em_loc; // 0x1C, Enclosure management location - uint32_t em_ctl; // 0x20, Enclosure management control - uint32_t cap2; // 0x24, Host capabilities extended - uint32_t bohc; // 0x28, BIOS/OS handoff control and status - - // 0x2C - 0x9F, Reserved - uint8_t rsv[0xA0 - 0x2C]; - - // 0xA0 - 0xFF, Vendor specific registers - uint8_t vendor[0x100 - 0xA0]; - - // 0x100 - 0x10FF, Port control registers - HBA_PORT ports[32]; // 1 ~ 32 -} HBA_MEM; - -// There are four kinds of FIS which may be sent to the host by the device as indicated in the following structure declaration. -// -typedef volatile struct tagHBA_FIS -{ - // 0x00 - FIS_DMA_SETUP dsfis; // DMA Setup FIS - uint8_t pad0[4]; - - // 0x20 - FIS_PIO_SETUP psfis; // PIO Setup FIS - uint8_t pad1[12]; - - // 0x40 - FIS_REG_D2H rfis; // Register – Device to Host FIS - uint8_t pad2[4]; - - // 0x58 - // FIS_DEV_BITS sdbfis; // Set Device Bit FIS - - // 0x60 - uint8_t ufis[64]; - - // 0xA0 - uint8_t rsv[0x100 - 0xA0]; -} HBA_FIS; - -typedef struct tagHBA_CMD_HEADER -{ - // DW0 - uint8_t cfl : 5; // Command FIS length in DWORDS, 2 ~ 16 - uint8_t a : 1; // ATAPI - uint8_t w : 1; // Write, 1: H2D, 0: D2H - uint8_t p : 1; // Prefetchable - - uint8_t r : 1; // Reset - uint8_t b : 1; // BIST - uint8_t c : 1; // Clear busy upon R_OK - uint8_t rsv0 : 1; // Reserved - uint8_t pmp : 4; // Port multiplier port - - uint16_t prdtl; // Physical region descriptor table length in entries - - // DW1 - volatile uint32_t prdbc; // Physical region descriptor byte count transferred - - // DW2, 3 - uint64_t ctba; // Command table descriptor base address - - // DW4 - 7 - uint32_t rsv1[4]; // Reserved -} HBA_CMD_HEADER; - -typedef struct tagHBA_PRDT_ENTRY -{ - uint64_t dba; // Data base address - uint32_t rsv0; // Reserved - - // DW3 - uint32_t dbc : 22; // Byte count, 4M max - uint32_t rsv1 : 9; // Reserved - uint32_t i : 1; // Interrupt on completion -} HBA_PRDT_ENTRY; - -typedef struct tagHBA_CMD_TBL -{ - // 0x00 - uint8_t cfis[64]; // Command FIS - - // 0x40 - uint8_t acmd[16]; // ATAPI command, 12 or 16 bytes - - // 0x50 - uint8_t rsv[48]; // Reserved - - // 0x80 - HBA_PRDT_ENTRY prdt_entry[1]; // Physical region descriptor table entries, 0 ~ 65535 -} HBA_CMD_TBL; - -struct ahci_device_t -{ - uint32_t type; // 设备类型 - struct pci_device_structure_header_t *dev_struct; - HBA_MEM *hba_mem; -} ahci_devices[MAX_AHCI_DEVICES]; - -#define SATA_SIG_ATA 0x00000101 // SATA drive -#define SATA_SIG_ATAPI 0xEB140101 // SATAPI drive -#define SATA_SIG_SEMB 0xC33C0101 // Enclosure management bridge -#define SATA_SIG_PM 0x96690101 // Port multiplier - -#define AHCI_DEV_NULL 0 -#define AHCI_DEV_SATA 1 -#define AHCI_DEV_SEMB 2 -#define AHCI_DEV_PM 3 -#define AHCI_DEV_SATAPI 4 - -#define HBA_PORT_IPM_ACTIVE 1 -#define HBA_PORT_DET_PRESENT 3 - -struct ahci_request_packet_t -{ - struct block_device_request_packet blk_pak; // 块设备请求包 - uint8_t ahci_ctrl_num; // ahci控制器号, 默认应为0 - uint8_t port_num; // ahci的设备端口号 -}; - /** * @brief 初始化ahci模块 * diff --git a/kernel/src/driver/disk/ahci/ahci_rust.h b/kernel/src/driver/disk/ahci/ahci_rust.h deleted file mode 100644 index 8d37743a6..000000000 --- a/kernel/src/driver/disk/ahci/ahci_rust.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// 计算HBA_MEM的虚拟内存地址 -#define MAX_AHCI_DEVICES 100 -#define AHCI_MAPPING_BASE SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + AHCI_MAPPING_OFFSET - -/// @brief 保留了对 pci设备获取 和 mm内存映射 的依赖 -void ahci_cpp_init(uint32_t *count_ahci_devices, struct pci_device_structure_header_t *ahci_devs[MAX_AHCI_DEVICES], struct pci_device_structure_general_device_t *gen_devs[MAX_AHCI_DEVICES]); \ No newline at end of file diff --git a/kernel/src/driver/disk/ahci/mod.rs b/kernel/src/driver/disk/ahci/mod.rs index fbb3d7f2b..4f4729be9 100644 --- a/kernel/src/driver/disk/ahci/mod.rs +++ b/kernel/src/driver/disk/ahci/mod.rs @@ -5,9 +5,13 @@ pub mod hba; use crate::filesystem::vfs::io::device::BlockDevice; // 依赖的rust工具包 +use crate::driver::pci::pci::{ + get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST, +}; use crate::filesystem::devfs::devfs_register; use crate::filesystem::vfs::io::disk_info::BLK_GF_AHCI; use crate::kerror; +use crate::libs::rwlock::RwLockWriteGuard; use crate::libs::spinlock::{SpinLock, SpinLockGuard}; use crate::mm::virt_2_phys; use crate::syscall::SystemError; @@ -20,21 +24,23 @@ use crate::{ kdebug, }; use ahci_inode::LockedAhciInode; -use alloc::boxed::Box; -use alloc::string::ToString; -use alloc::{format, string::String, sync::Arc, vec::Vec}; -use core::sync::atomic::compiler_fence; - -// 依赖的C结构体/常量 -use crate::include::bindings::bindings::{ - ahci_cpp_init, pci_device_structure_general_device_t, pci_device_structure_header_t, - AHCI_MAPPING_BASE, MAX_AHCI_DEVICES, PAGE_2M_MASK, +use alloc::{ + boxed::Box, + collections::LinkedList, + format, + string::{String, ToString}, + sync::Arc, + vec::Vec, }; +use core::sync::atomic::compiler_fence; // 仅module内可见 全局数据区 hbr_port, disks static LOCKED_HBA_MEM_LIST: SpinLock> = SpinLock::new(Vec::new()); static LOCKED_DISKS_LIST: SpinLock>> = SpinLock::new(Vec::new()); +const AHCI_CLASS: u8 = 0x1; +const AHCI_SUBCLASS: u8 = 0x6; + /* TFES - Task File Error Status */ #[allow(non_upper_case_globals)] pub const HBA_PxIS_TFES: u32 = 1 << 30; @@ -48,53 +54,57 @@ pub extern "C" fn ahci_init() -> i32 { return r.unwrap_err().to_posix_errno(); } } -/// @brief: 初始化 ahci -pub fn ahci_rust_init() -> Result<(), SystemError> { - compiler_fence(core::sync::atomic::Ordering::SeqCst); - let mut ahci_dev_counts: u32 = 0; - let mut ahci_devs: [*mut pci_device_structure_header_t; MAX_AHCI_DEVICES as usize] = - [0 as *mut pci_device_structure_header_t; MAX_AHCI_DEVICES as usize]; - let mut gen_devs: [*mut pci_device_structure_general_device_t; MAX_AHCI_DEVICES as usize] = - [0 as *mut pci_device_structure_general_device_t; MAX_AHCI_DEVICES as usize]; +/// @brief 寻找所有的ahci设备 +/// @param list 链表的写锁 +/// @return Result>, SystemError> 成功则返回包含所有ahci设备结构体的可变引用的链表,失败则返回err +fn ahci_device_search<'a>( + list: &'a mut RwLockWriteGuard<'_, LinkedList>>, +) -> Result>, SystemError> { + let result = get_pci_device_structure_mut(list, AHCI_CLASS, AHCI_SUBCLASS); - compiler_fence(core::sync::atomic::Ordering::SeqCst); - unsafe { - // 单线程 init, 所以写 ahci_devs 全局变量不会出错? - ahci_cpp_init( - (&mut ahci_dev_counts) as *mut u32, - (&mut ahci_devs) as *mut *mut pci_device_structure_header_t, - (&mut gen_devs) as *mut *mut pci_device_structure_general_device_t, - ); + if result.is_empty() { + return Err(SystemError::ENODEV); } - compiler_fence(core::sync::atomic::Ordering::SeqCst); + kdebug!("{}", result.len()); + Ok(result) +} +/// @brief: 初始化 ahci +pub fn ahci_rust_init() -> Result<(), SystemError> { + let mut list = PCI_DEVICE_LINKEDLIST.write(); + let ahci_device = ahci_device_search(&mut list)?; // 全局数据 - 列表 let mut disks_list = LOCKED_DISKS_LIST.lock(); - for i in 0..(ahci_dev_counts as usize) { + for device in ahci_device { + let standard_device = device.as_standard_device_mut().unwrap(); + standard_device.bar_ioremap(); // 对于每一个ahci控制器分配一块空间 (目前slab algorithm最大支持1MB) let ahci_port_base_vaddr = Box::leak(Box::new([0u8; (1 << 20) as usize])) as *mut u8 as usize; - compiler_fence(core::sync::atomic::Ordering::SeqCst); - // 获取全局引用 : 计算 HBA_MEM 的虚拟地址 依赖于C的宏定义 cal_HBA_MEM_VIRT_ADDR - let virt_addr = AHCI_MAPPING_BASE as usize + unsafe { (*gen_devs[i]).BAR5 as usize } - - (unsafe { (*gen_devs[0]).BAR5 as usize } & PAGE_2M_MASK as usize); - compiler_fence(core::sync::atomic::Ordering::SeqCst); - + let virtaddr = standard_device + .bar() + .ok_or(SystemError::EACCES)? + .get_bar(5) + .or(Err(SystemError::EACCES))? + .virtual_address() + .unwrap(); // 最后把这个引用列表放入到全局列表 let mut hba_mem_list = LOCKED_HBA_MEM_LIST.lock(); - hba_mem_list.push(unsafe { (virt_addr as *mut HbaMem).as_mut().unwrap() }); - let pi = volatile_read!(hba_mem_list[i].pi); + //这里两次unsafe转引用规避rust只能有一个可变引用的检查,提高运行速度 + let hba_mem = unsafe { (virtaddr as *mut HbaMem).as_mut().unwrap() }; + hba_mem_list.push(unsafe { (virtaddr as *mut HbaMem).as_mut().unwrap() }); + let pi = volatile_read!(hba_mem.pi); + let hba_mem_index = hba_mem_list.len() - 1; drop(hba_mem_list); - compiler_fence(core::sync::atomic::Ordering::SeqCst); - // 初始化所有的port let mut id = 0; for j in 0..32 { if (pi >> j) & 1 > 0 { - let mut hba_mem_list = LOCKED_HBA_MEM_LIST.lock(); - let tp = hba_mem_list[i].ports[j].check_type(); + let hba_mem_list = LOCKED_HBA_MEM_LIST.lock(); + let hba_mem_port = &mut hba_mem.ports[j]; + let tp = hba_mem_port.check_type(); match tp { HbaPortType::None => { kdebug!(" Find a None type Disk."); @@ -108,7 +118,6 @@ pub fn ahci_rust_init() -> Result<(), SystemError> { // 计算地址 let fb = virt_2_phys(ahci_port_base_vaddr + (32 << 10) + (j << 8)); let clb = virt_2_phys(ahci_port_base_vaddr + (j << 10)); - compiler_fence(core::sync::atomic::Ordering::SeqCst); let ctbas = (0..32) .map(|x| { virt_2_phys( @@ -118,17 +127,14 @@ pub fn ahci_rust_init() -> Result<(), SystemError> { .collect::>(); // 初始化 port - hba_mem_list[i].ports[j].init(clb as u64, fb as u64, &ctbas); - - // 释放锁 + hba_mem_port.init(clb as u64, fb as u64, &ctbas); drop(hba_mem_list); compiler_fence(core::sync::atomic::Ordering::SeqCst); - // 创建 disk disks_list.push(LockedAhciDisk::new( format!("ahci_disk_{}", id), BLK_GF_AHCI, - i as u8, + hba_mem_index as u8, j as u8, )?); id += 1; // ID 从0开始 @@ -144,7 +150,7 @@ pub fn ahci_rust_init() -> Result<(), SystemError> { kerror!( "Ahci_{} ctrl = {}, port = {} failed to register, error code = {:?}", id, - i, + hba_mem_index as u8, j, err ); @@ -168,23 +174,20 @@ pub fn disks() -> Vec> { /// @brief: 通过 name 获取 disk pub fn get_disks_by_name(name: String) -> Result, SystemError> { - compiler_fence(core::sync::atomic::Ordering::SeqCst); let disks_list: SpinLockGuard>> = LOCKED_DISKS_LIST.lock(); - for i in 0..disks_list.len() { - if disks_list[i].0.lock().name == name { - return Ok(disks_list[i].clone()); - } - } - compiler_fence(core::sync::atomic::Ordering::SeqCst); - return Err(SystemError::ENXIO); + let result = disks_list + .iter() + .find(|x| x.0.lock().name == name) + .ok_or(SystemError::ENXIO)? + .clone(); + return Ok(result); } /// @brief: 通过 ctrl_num 和 port_num 获取 port -pub fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort { - compiler_fence(core::sync::atomic::Ordering::SeqCst); +fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort { let list: SpinLockGuard> = LOCKED_HBA_MEM_LIST.lock(); let port: &HbaPort = &list[ctrl_num as usize].ports[port_num as usize]; - compiler_fence(core::sync::atomic::Ordering::SeqCst); + return unsafe { (port as *const HbaPort as *mut HbaPort).as_mut().unwrap() }; } diff --git a/kernel/src/driver/pci/Makefile b/kernel/src/driver/pci/Makefile index 91c133187..318284815 100644 --- a/kernel/src/driver/pci/Makefile +++ b/kernel/src/driver/pci/Makefile @@ -1,14 +1,9 @@ -all: pci.o pci_irq.o msi.o +all: pci_irq.o CFLAGS += -I . -pci.o: pci.c - $(CC) $(CFLAGS) -c pci.c -o pci.o pci_irq.o: pci_irq.c $(CC) $(CFLAGS) -c pci_irq.c -o pci_irq.o -msi.o: msi.c - $(CC) $(CFLAGS) -c msi.c -o msi.o - diff --git a/kernel/src/driver/pci/msi.c b/kernel/src/driver/pci/msi.c deleted file mode 100644 index e59ffc8a6..000000000 --- a/kernel/src/driver/pci/msi.c +++ /dev/null @@ -1,340 +0,0 @@ -#include "msi.h" -#include "pci.h" -#include -#include - -/** - * @brief 生成msi消息 - * - * @param msi_desc msi描述符 - * @return struct msi_msg_t* msi消息指针(在描述符内) - */ -extern struct msi_msg_t *msi_arch_get_msg(struct msi_desc_t *msi_desc); - -/** - * @brief 读取msix的capability list - * - * @param msi_desc msi描述符 - * @param cap_off capability list的offset - * @return struct pci_msix_cap_t 对应的capability list - */ -static __always_inline struct pci_msix_cap_t __msi_read_msix_cap_list(struct msi_desc_t *msi_desc, uint32_t cap_off) -{ - struct pci_msix_cap_t cap_list = {0}; - uint32_t dw0; - dw0 = pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off); - io_lfence(); - cap_list.cap_id = dw0 & 0xff; - cap_list.next_off = (dw0 >> 8) & 0xff; - cap_list.msg_ctrl = (dw0 >> 16) & 0xffff; - - cap_list.dword1 = - pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x4); - cap_list.dword2 = - pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x8); - return cap_list; -} - -static __always_inline struct pci_msi_cap_t __msi_read_cap_list(struct msi_desc_t *msi_desc, uint32_t cap_off) -{ - struct pci_msi_cap_t cap_list = {0}; - uint32_t dw0; - dw0 = pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off); - cap_list.cap_id = dw0 & 0xff; - cap_list.next_off = (dw0 >> 8) & 0xff; - cap_list.msg_ctrl = (dw0 >> 16) & 0xffff; - - cap_list.msg_addr_lo = - pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x4); - uint16_t msg_data_off = 0xc; - if (cap_list.msg_ctrl & (1 << 7)) // 64位 - { - cap_list.msg_addr_hi = - pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x8); - } - else - { - cap_list.msg_addr_hi = 0; - msg_data_off = 0x8; - } - - cap_list.msg_data = pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, - cap_off + msg_data_off) & - 0xffff; - - cap_list.mask = - pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x10); - cap_list.pending = - pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x14); - - return cap_list; -} - -/** - * @brief 映射设备的msix表 //MSIX表不再单独映射(To do) - * - * @param pci_dev pci设备信息结构体 - * @param msix_cap msix capability list的结构体 - * @return int 错误码 - */ -static __always_inline int __msix_map_table(struct pci_device_structure_header_t *pci_dev, - struct pci_msix_cap_t *msix_cap) -{ - // 计算bar寄存器的offset - uint32_t bar_off = 0x10 + 4 * (msix_cap->dword1 & 0x7); - - // msix table相对于bar寄存器中存储的地址的offset - pci_dev->msix_offset = msix_cap->dword1 & (~0x7); - pci_dev->msix_table_size = (msix_cap->msg_ctrl & 0x7ff) + 1; - pci_dev->msix_mmio_size = pci_dev->msix_table_size * 16 + pci_dev->msix_offset; - - // 申请mmio空间 - mmio_create(pci_dev->msix_mmio_size, VM_IO | VM_DONTCOPY, &pci_dev->msix_mmio_vaddr, &pci_dev->msix_mmio_size); - pci_dev->msix_mmio_vaddr &= (~0xf); - uint32_t bar = pci_read_config(pci_dev->bus, pci_dev->device, pci_dev->func, bar_off); - // kdebug("pci_dev->msix_mmio_vaddr=%#018lx, bar=%#010lx, table offset=%#010lx, table_size=%#010lx, mmio_size=%d", - // pci_dev->msix_mmio_vaddr, bar, pci_dev->msix_offset, pci_dev->msix_table_size, pci_dev->msix_mmio_size); - - // 将msix table映射到页表 - rs_map_phys(pci_dev->msix_mmio_vaddr, bar, pci_dev->msix_mmio_size, PAGE_KERNEL_PAGE); - return 0; -} - -/** - * @brief 将msi_desc中的数据填写到msix表的指定表项处 - * - * @param pci_dev pci设备结构体 - * @param msi_desc msi描述符 - */ -static __always_inline void __msix_set_entry(struct msi_desc_t *msi_desc) -{ - uint64_t *ptr = - (uint64_t *)(msi_desc->pci_dev->msix_mmio_vaddr + msi_desc->pci_dev->msix_offset + msi_desc->msi_index * 16); - *ptr = ((uint64_t)(msi_desc->msg.address_hi) << 32) | (msi_desc->msg.address_lo); - io_mfence(); - ++ptr; - io_mfence(); - *ptr = ((uint64_t)(msi_desc->msg.vector_control) << 32) | (msi_desc->msg.data); - io_mfence(); -} - -/** - * @brief 清空设备的msix table的指定表项 - * - * @param pci_dev pci设备 - * @param msi_index 表项号 - */ -static __always_inline void __msix_clear_entry(struct pci_device_structure_header_t *pci_dev, uint16_t msi_index) -{ - uint64_t *ptr = (uint64_t *)(pci_dev->msix_mmio_vaddr + pci_dev->msix_offset + msi_index * 16); - *ptr = 0; - ++ptr; - *ptr = 0; -} - -/** - * @brief 启用 Message Signaled Interrupts - * - * @param header 设备header - * @param vector 中断向量号 - * @param processor 要投递到的处理器 - * @param edge_trigger 是否边缘触发 - * @param assert 是否高电平触发 - * - * @return 返回码 - */ -int pci_enable_msi(struct msi_desc_t *msi_desc) -{ - struct pci_device_structure_header_t *ptr = msi_desc->pci_dev; - uint32_t cap_ptr; - uint32_t tmp; - uint16_t message_control; - uint64_t message_addr; - - // 先尝试获取msi-x,若不存在,则获取msi capability - if (msi_desc->pci.msi_attribute.is_msix) - { - cap_ptr = pci_enumerate_capability_list(ptr, 0x11); - if (((int32_t)cap_ptr) < 0) - { - cap_ptr = pci_enumerate_capability_list(ptr, 0x05); - if (((int32_t)cap_ptr) < 0) - return -ENOSYS; - msi_desc->pci.msi_attribute.is_msix = 0; - } - } - else - { - cap_ptr = pci_enumerate_capability_list(ptr, 0x05); - if (((int32_t)cap_ptr) < 0) - return -ENOSYS; - msi_desc->pci.msi_attribute.is_msix = 0; - } - // 获取msi消息 - msi_arch_get_msg(msi_desc); - - if (msi_desc->pci.msi_attribute.is_msix) // MSI-X - { - kdebug("is msix"); - // 读取msix的信息 - struct pci_msix_cap_t cap = __msi_read_msix_cap_list(msi_desc, cap_ptr); - // 映射msix table - __msix_map_table(msi_desc->pci_dev, &cap); - io_mfence(); - // 设置msix的中断 - __msix_set_entry(msi_desc); - io_mfence(); - - // todo: disable intx - // 使能msi-x - tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值 - tmp |= (1U << 31); - pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr, tmp); - } - else - { - kdebug("is msi"); - tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值 - message_control = (tmp >> 16) & 0xffff; - - // 写入message address - message_addr = ((((uint64_t)msi_desc->msg.address_hi) << 32) | msi_desc->msg.address_lo); // 获取message address - pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x4, (uint32_t)(message_addr & 0xffffffff)); - - if (message_control & (1 << 7)) // 64位 - pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x8, - (uint32_t)((message_addr >> 32) & 0xffffffff)); - - // 写入message data - - tmp = msi_desc->msg.data; - if (message_control & (1 << 7)) // 64位 - pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0xc, tmp); - else - pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x8, tmp); - - // 使能msi - tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值 - tmp |= (1 << 16); - pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr, tmp); - } - - return 0; -} - -/** - * @brief 在已配置好msi寄存器的设备上,使能msi - * - * @param header 设备头部 - * @return int 返回码 - */ -int pci_start_msi(void *header) -{ - struct pci_device_structure_header_t *ptr = (struct pci_device_structure_header_t *)header; - uint32_t cap_ptr; - uint32_t tmp; - - switch (ptr->HeaderType) - { - case 0x00: // general device - if (!(ptr->Status & 0x10)) - return -ENOSYS; - cap_ptr = ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer; - - tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值 - - if (tmp & 0xff != 0x5) - return -ENOSYS; - - // 使能msi - tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值 - tmp |= (1 << 16); - pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr, tmp); - - break; - - case 0x01: // pci to pci bridge - if (!(ptr->Status & 0x10)) - return -ENOSYS; - cap_ptr = ((struct pci_device_structure_pci_to_pci_bridge_t *)ptr)->Capability_Pointer; - - tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值 - - if (tmp & 0xff != 0x5) - return -ENOSYS; - - // 使能msi - tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值 - tmp |= (1 << 16); - pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr, tmp); - - break; - case 0x02: // pci to card bus bridge - return -ENOSYS; - break; - - default: // 不应该到达这里 - return -EINVAL; - break; - } - - return 0; -} -/** - * @brief 禁用指定设备的msi - * - * @param header pci header - * @return int - */ -int pci_disable_msi(void *header) -{ - struct pci_device_structure_header_t *ptr = (struct pci_device_structure_header_t *)header; - uint32_t cap_ptr; - uint32_t tmp; - - switch (ptr->HeaderType) - { - case 0x00: // general device - if (!(ptr->Status & 0x10)) - return -ENOSYS; - cap_ptr = ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer; - - tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值 - - if (tmp & 0xff != 0x5) - return -ENOSYS; - - // 禁用msi - tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值 - tmp &= (~(1 << 16)); - pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr, tmp); - - break; - - case 0x01: // pci to pci bridge - if (!(ptr->Status & 0x10)) - return -ENOSYS; - cap_ptr = ((struct pci_device_structure_pci_to_pci_bridge_t *)ptr)->Capability_Pointer; - - tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值 - - if (tmp & 0xff != 0x5) - return -ENOSYS; - - // 禁用msi - tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值 - tmp &= (~(1 << 16)); - pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr, tmp); - - break; - case 0x02: // pci to card bus bridge - return -ENOSYS; - break; - - default: // 不应该到达这里 - return -EINVAL; - break; - } - - return 0; -} \ No newline at end of file diff --git a/kernel/src/driver/pci/msi.h b/kernel/src/driver/pci/msi.h deleted file mode 100644 index 734775b28..000000000 --- a/kernel/src/driver/pci/msi.h +++ /dev/null @@ -1,110 +0,0 @@ -#pragma once -#include - -/** - * @brief msi消息内容结构体 - * - */ -struct msi_msg_t -{ - uint32_t address_lo; - uint32_t address_hi; - uint32_t data; - uint32_t vector_control; -}; -struct pci_msi_desc_t -{ - union - { - uint32_t msi_mask; // [PCI MSI] MSI cached mask bits - uint32_t msix_ctrl; // [PCI MSI-X] MSI-X cached per vector control bits - }; - - struct - { - uint8_t is_msix : 1; // [PCI MSI/X] True if MSI-X - uint8_t can_mask : 1; // [PCI MSI/X] Masking supported? - uint8_t is_64 : 1; // [PCI MSI/X] Address size: 0=32bit 1=64bit - } msi_attribute; -}; - -/** - * @brief msi capability list的结构 - * - */ -struct pci_msi_cap_t -{ - uint8_t cap_id; - uint8_t next_off; - uint16_t msg_ctrl; - - uint32_t msg_addr_lo; - uint32_t msg_addr_hi; - - uint16_t msg_data; - uint16_t Rsvd; - - uint32_t mask; - uint32_t pending; -}; - -/** - * @brief MSI-X的capability list结构体 - * - */ -struct pci_msix_cap_t -{ - uint8_t cap_id; - uint8_t next_off; - uint16_t msg_ctrl; - - uint32_t dword1; // 该DWORD的组成为:[Table Offset][BIR2:0]. - // 由于Table Offset是8字节对齐的,因此mask掉该dword的BIR部分,就是table offset的值 - uint32_t dword2; // 该DWORD的组成为:[Pending Bit Offset][Pending Bit BIR2:0]. - // 由于Pending Bit Offset是8字节对齐的,因此mask掉该dword的BIR部分,就是Pending Bit Offset的值 -}; - -/** - * @brief msi描述符 - * - */ -struct msi_desc_t -{ - uint16_t irq_num; // 中断向量号 - uint16_t processor; // 定向投递的处理器 - uint16_t edge_trigger; // 是否边缘触发 - uint16_t assert; // 是否高电平触发 - struct pci_device_structure_header_t *pci_dev; // 对应的pci设备的结构体 - struct msi_msg_t msg; // msi消息 - uint16_t msi_index; // msi描述符的index - struct pci_msi_desc_t pci; // 与pci相关的msi描述符数据 -}; - -/** - * @brief 启用 Message Signaled Interrupts - * - * @param header 设备header - * @param vector 中断向量号 - * @param processor 要投递到的处理器 - * @param edge_trigger 是否边缘触发 - * @param assert 是否高电平触发 - * - * @return 返回码 - */ -int pci_enable_msi(struct msi_desc_t *msi_desc); - -/** - * @brief 禁用指定设备的msi - * - * @param header pci header - * @return int - */ -int pci_disable_msi(void *header); - -/** - * @brief 在已配置好msi寄存器的设备上,使能msi - * - * @param header 设备头部 - * @return int 返回码 - */ -int pci_start_msi(void *header); \ No newline at end of file diff --git a/kernel/src/driver/pci/pci.c b/kernel/src/driver/pci/pci.c deleted file mode 100644 index db39e754c..000000000 --- a/kernel/src/driver/pci/pci.c +++ /dev/null @@ -1,542 +0,0 @@ -#include "pci.h" -#include -#include -#include -#include - -static uint count_device_list = 0; -static void pci_checkBus(uint8_t bus); - -/** - * @brief 将设备信息结构体加到链表里面 - * - */ -#define ADD_DEVICE_STRUCT_TO_LIST(ret) \ - do \ - { \ - if (count_device_list > 0) \ - { \ - ++count_device_list; \ - list_add(pci_device_structure_list, &(ret->header.list)); \ - } \ - else \ - { \ - ++count_device_list; \ - list_init(&(ret->header.list)); \ - pci_device_structure_list = &(ret->header.list); \ - } \ - } while (0) - - -/** - * @brief 从pci配置空间读取信息 - * - * @param bus 总线号 - * @param slot 设备号 - * @param func 功能号 - * @param offset 字节偏移量 - * @return uint 寄存器值 - */ -uint32_t pci_read_config(uchar bus, uchar slot, uchar func, uchar offset) -{ - uint lbus = (uint)bus; - uint lslot = (uint)slot; - uint lfunc = ((uint)func) & 7; - - // 构造pci配置空间地址 - uint address = (uint)((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xfc) | ((uint)0x80000000)); - io_out32(PORT_PCI_CONFIG_ADDRESS, address); - // 读取返回的数据 - uint32_t ret = (uint)(io_in32(PORT_PCI_CONFIG_DATA)); - - return ret; -} - -/** - * @brief 向pci配置空间写入信息 - * - * @param bus 总线号 - * @param slot 设备号 - * @param func 功能号 - * @param offset 字节偏移量 - * @return uint 返回码 - */ -uint pci_write_config(uchar bus, uchar slot, uchar func, uchar offset, uint32_t data) -{ - uint lbus = (uint)bus; - uint lslot = (uint)slot; - uint lfunc = ((uint)func) & 7; - - // 构造pci配置空间地址 - uint address = (uint)((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xfc) | ((uint)0x80000000)); - io_out32(PORT_PCI_CONFIG_ADDRESS, address); - - // 写入数据 - io_out32(PORT_PCI_CONFIG_DATA, data); - - return 0; -} - -/** - * @brief 读取type为0x0的pci设备的header - * 本函数只应被 pci_read_header()调用 - * @param header 返回的header - * @param bus 总线号 - * @param slot 插槽号 - * @param func 功能号 - */ -static void pci_read_general_device_header(struct pci_device_structure_general_device_t *header, uchar bus, uchar slot, uchar func) -{ - uint32_t tmp32; - header->BAR0 = pci_read_config(bus, slot, func, 0x10); - header->BAR1 = pci_read_config(bus, slot, func, 0x14); - header->BAR2 = pci_read_config(bus, slot, func, 0x18); - header->BAR3 = pci_read_config(bus, slot, func, 0x1c); - header->BAR4 = pci_read_config(bus, slot, func, 0x20); - header->BAR5 = pci_read_config(bus, slot, func, 0x24); - header->Cardbus_CIS_Pointer = pci_read_config(bus, slot, func, 0x28); - - tmp32 = pci_read_config(bus, slot, func, 0x2c); - header->Subsystem_Vendor_ID = tmp32 & 0xffff; - header->Subsystem_ID = (tmp32 >> 16) & 0xffff; - - header->Expansion_ROM_base_address = pci_read_config(bus, slot, func, 0x30); - - tmp32 = pci_read_config(bus, slot, func, 0x34); - header->Capabilities_Pointer = tmp32 & 0xff; - header->reserved0 = (tmp32 >> 8) & 0xff; - header->reserved1 = (tmp32 >> 16) & 0xffff; - - header->reserved2 = pci_read_config(bus, slot, func, 0x38); - - tmp32 = pci_read_config(bus, slot, func, 0x3c); - header->Interrupt_Line = tmp32 & 0xff; - header->Interrupt_PIN = (tmp32 >> 8) & 0xff; - header->Min_Grant = (tmp32 >> 16) & 0xff; - header->Max_Latency = (tmp32 >> 24) & 0xff; -} - -/** - * @brief 读取type为0x1的pci_to_pci_bridge的header - * 本函数只应被 pci_read_header()调用 - * @param header 返回的header - * @param bus 总线号 - * @param slot 插槽号 - * @param func 功能号 - */ -static void pci_read_pci_to_pci_bridge_header(struct pci_device_structure_pci_to_pci_bridge_t *header, uchar bus, uchar slot, uchar func) -{ - uint32_t tmp32; - header->BAR0 = pci_read_config(bus, slot, func, 0x10); - header->BAR1 = pci_read_config(bus, slot, func, 0x14); - - tmp32 = pci_read_config(bus, slot, func, 0x18); - - header->Primary_Bus_Number = tmp32 & 0xff; - header->Secondary_Bus_Number = (tmp32 >> 8) & 0xff; - header->Subordinate_Bus_Number = (tmp32 >> 16) & 0xff; - header->Secondary_Latency_Timer = (tmp32 >> 24) & 0xff; - - tmp32 = pci_read_config(bus, slot, func, 0x1c); - header->io_base = tmp32 & 0xff; - header->io_limit = (tmp32 >> 8) & 0xff; - header->Secondary_Status = (tmp32 >> 16) & 0xffff; - - tmp32 = pci_read_config(bus, slot, func, 0x20); - header->Memory_Base = tmp32 & 0xffff; - header->Memory_Limit = (tmp32 >> 16) & 0xffff; - - tmp32 = pci_read_config(bus, slot, func, 0x24); - header->Prefetchable_Memory_Base = tmp32 & 0xffff; - header->Prefetchable_Memory_Limit = (tmp32 >> 16) & 0xffff; - - header->Prefetchable_Base_Upper_32_Bits = pci_read_config(bus, slot, func, 0x28); - header->Prefetchable_Limit_Upper_32_Bits = pci_read_config(bus, slot, func, 0x2c); - - tmp32 = pci_read_config(bus, slot, func, 0x30); - header->io_Base_Upper_16_Bits = tmp32 & 0xffff; - header->io_Limit_Upper_16_Bits = (tmp32 >> 16) & 0xffff; - - tmp32 = pci_read_config(bus, slot, func, 0x34); - header->Capability_Pointer = tmp32 & 0xff; - header->reserved0 = (tmp32 >> 8) & 0xff; - header->reserved1 = (tmp32 >> 16) & 0xffff; - - header->Expansion_ROM_base_address = pci_read_config(bus, slot, func, 0x38); - - tmp32 = pci_read_config(bus, slot, func, 0x3c); - header->Interrupt_Line = tmp32 & 0xff; - header->Interrupt_PIN = (tmp32 >> 8) & 0xff; - header->Bridge_Control = (tmp32 >> 16) & 0xffff; -} - -/** - * @brief 读取type为0x2的pci_to_cardbus_bridge的header - * 本函数只应被 pci_read_header()调用 - * @param header 返回的header - * @param bus 总线号 - * @param slot 插槽号 - * @param func 功能号 - */ -static void pci_read_pci_to_cardbus_bridge_header(struct pci_device_structure_pci_to_cardbus_bridge_t *header, uchar bus, uchar slot, uchar func) -{ - uint32_t tmp32; - - header->CardBus_Socket_ExCa_base_address = pci_read_config(bus, slot, func, 0x10); - - tmp32 = pci_read_config(bus, slot, func, 0x14); - header->Offset_of_capabilities_list = tmp32 & 0xff; - header->Reserved = (tmp32 >> 8) & 0xff; - header->Secondary_status = (tmp32 >> 16) & 0xff; - - tmp32 = pci_read_config(bus, slot, func, 0x18); - header->PCI_bus_number = tmp32 & 0xff; - header->CardBus_bus_number = (tmp32 >> 8) & 0xff; - header->Subordinate_bus_number = (tmp32 >> 16) & 0xff; - header->CardBus_latency_timer = (tmp32 >> 24) & 0xff; - - header->Memory_Base_Address0 = pci_read_config(bus, slot, func, 0x1c); - header->Memory_Limit0 = pci_read_config(bus, slot, func, 0x20); - header->Memory_Base_Address1 = pci_read_config(bus, slot, func, 0x24); - header->Memory_Limit1 = pci_read_config(bus, slot, func, 0x28); - - header->IO_Base_Address0 = pci_read_config(bus, slot, func, 0x2c); - header->IO_Limit0 = pci_read_config(bus, slot, func, 0x30); - header->IO_Base_Address1 = pci_read_config(bus, slot, func, 0x34); - header->IO_Limit1 = pci_read_config(bus, slot, func, 0x38); - - tmp32 = pci_read_config(bus, slot, func, 0x3c); - header->Interrupt_Line = tmp32 & 0xff; - header->Interrupt_PIN = (tmp32 >> 8) & 0xff; - header->Bridge_Control = (tmp32 >> 16) & 0xffff; - - tmp32 = pci_read_config(bus, slot, func, 0x40); - header->Subsystem_Device_ID = tmp32 & 0xffff; - header->Subsystem_Vendor_ID = (tmp32 >> 16) & 0xffff; - - header->PC_Card_legacy_mode_base_address_16_bit = pci_read_config(bus, slot, func, 0x44); -} - -/** - * @brief 读取pci设备标头 - * - * @param type 标头类型 - * @param bus 总线号 - * @param slot 插槽号 - * @param func 功能号 - * @param add_to_list 添加到链表 - * @return 返回的header - */ -void *pci_read_header(int *type, uchar bus, uchar slot, uchar func, bool add_to_list) -{ - struct pci_device_structure_header_t *common_header = (struct pci_device_structure_header_t *)kmalloc(127, 0); - common_header->bus = bus; - common_header->device = slot; - common_header->func = func; - - uint32_t tmp32; - // 先读取公共header - tmp32 = pci_read_config(bus, slot, func, 0x0); - common_header->Vendor_ID = tmp32 & 0xffff; - common_header->Device_ID = (tmp32 >> 16) & 0xffff; - - tmp32 = pci_read_config(bus, slot, func, 0x4); - common_header->Command = tmp32 & 0xffff; - common_header->Status = (tmp32 >> 16) & 0xffff; - - tmp32 = pci_read_config(bus, slot, func, 0x8); - common_header->RevisionID = tmp32 & 0xff; - common_header->ProgIF = (tmp32 >> 8) & 0xff; - common_header->SubClass = (tmp32 >> 16) & 0xff; - common_header->Class_code = (tmp32 >> 24) & 0xff; - - tmp32 = pci_read_config(bus, slot, func, 0xc); - common_header->CacheLineSize = tmp32 & 0xff; - common_header->LatencyTimer = (tmp32 >> 8) & 0xff; - common_header->HeaderType = (tmp32 >> 16) & 0xff; - common_header->BIST = (tmp32 >> 24) & 0xff; - - void *ret; - if (common_header->Vendor_ID == 0xffff) - { - *type = -ENXIO; - kfree(common_header); - return NULL; - } - - // 根据公共头部,判断该结构所属的类型 - switch (common_header->HeaderType) - { - case 0x0: // general device - ret = common_header; - - pci_read_general_device_header((struct pci_device_structure_general_device_t *)ret, bus, slot, func); - if (add_to_list) - ADD_DEVICE_STRUCT_TO_LIST(((struct pci_device_structure_general_device_t *)ret)); - - *type = 0x0; - return ret; - break; - case 0x1: - ret = common_header; - pci_read_pci_to_pci_bridge_header((struct pci_device_structure_pci_to_pci_bridge_t *)ret, bus, slot, func); - if (add_to_list) - ADD_DEVICE_STRUCT_TO_LIST(((struct pci_device_structure_pci_to_pci_bridge_t *)ret)); - - *type = 0x1; - return ret; - break; - case 0x2: - ret = common_header; - pci_read_pci_to_cardbus_bridge_header((struct pci_device_structure_pci_to_cardbus_bridge_t *)ret, bus, slot, func); - if (add_to_list) - ADD_DEVICE_STRUCT_TO_LIST(((struct pci_device_structure_pci_to_cardbus_bridge_t *)ret)); - - *type = 0x2; - return ret; - break; - default: // 错误的头类型 这里不应该被执行 - // kerror("PCI->pci_read_header(): Invalid header type."); - *type = -EINVAL; - // kerror("vendor id=%#010lx", common_header->Vendor_ID); - // kerror("header type = %d", common_header->HeaderType); - kfree(common_header); - return NULL; - break; - } -} -static void pci_checkFunction(uint8_t bus, uint8_t device, uint8_t function) -{ - int header_type; - struct pci_device_structure_header_t *header = pci_read_header(&header_type, bus, device, function, true); - - if (header_type == -EINVAL) - { - // kerror("pci_checkFunction(): wrong header type!"); - // 此处内存已经在read header函数里面释放,不用重复释放 - return; - } - // header = ((struct pci_device_structure_general_device_t *)raw_header)->header; - - if ((header->Class_code == 0x6) && (header->SubClass == 0x4)) - { - uint8_t SecondaryBus = ((struct pci_device_structure_pci_to_pci_bridge_t *)header)->Secondary_Bus_Number; - pci_checkBus(SecondaryBus); - } -} - -static int pci_checkDevice(uint8_t bus, uint8_t device) -{ - int header_type; - - struct pci_device_structure_header_t *header = pci_read_header(&header_type, bus, device, 0, false); - if (header_type == -EINVAL) - { - // 此处内存已经在read header函数里面释放,不用重复释放 - return -EINVAL; - } - if (header_type == -ENXIO) - { - // kerror("DEVICE INVALID"); - return -ENXIO; - } - - uint16_t vendorID = header->Vendor_ID; - - if (vendorID == 0xffff) // 设备不存在 - { - kfree(header); - return -ENXIO; - } - pci_checkFunction(bus, device, 0); - - header_type = header->HeaderType; - if ((header_type & 0x80) != 0) - { - kdebug("Multi func device"); - // 这是一个多function的设备,因此查询剩余的function - for (uint8_t func = 1; func < 8; ++func) - { - struct pci_device_structure_header_t *tmp_header; - tmp_header = (struct pci_device_structure_header_t *)pci_read_header(&header_type, bus, device, func, false); - - if (tmp_header->Vendor_ID != 0xffff) - pci_checkFunction(bus, device, func); - - // 释放内存 - kfree(tmp_header); - } - } - - kfree(header); - return 0; -} - -static void pci_checkBus(uint8_t bus) -{ - for (uint8_t device = 0; device < 32; ++device) - { - pci_checkDevice(bus, device); - } -} - -/** - * @brief 扫描所有pci总线上的所有设备 - * - */ -void pci_checkAllBuses() -{ - kinfo("Checking all devices in PCI bus..."); - int header_type; - struct pci_device_structure_header_t *header = pci_read_header(&header_type, 0, 0, 0, false); - - if (header_type == EINVAL) - { - kBUG("pci_checkAllBuses(): wrong header type!"); - // 此处内存已经在read header函数里面释放,不用重复释放 - return; - } - - header_type = header->HeaderType; - - if ((header_type & 0x80) == 0) // Single pci host controller - { - pci_checkBus(0); - } - else - { - // Multiple PCI host controller - // 那么总线0,设备0,功能1则是总线1的pci主机控制器,以此类推 - struct pci_device_structure_header_t *tmp_header; - for (uint8_t func = 0; func < 8; ++func) - { - tmp_header = (struct pci_device_structure_header_t *)pci_read_header(&header_type, 0, 0, func, false); - - if (WARN_ON(header->Vendor_ID != 0xffff)) // @todo 这里的判断条件可能有点问题 - { - kfree(tmp_header); - break; - } - - pci_checkBus(func); - - kfree(tmp_header); - } - } - kfree(header); -} - -void pci_init() -{ - kinfo("Initializing PCI bus..."); - pci_checkAllBuses(); - kinfo("Total pci device and function num = %d", count_device_list); - - struct pci_device_structure_header_t *ptr = container_of(pci_device_structure_list, struct pci_device_structure_header_t, list); - for (int i = 0; i < count_device_list; ++i) - { - if (ptr->HeaderType == 0x0) - { - if (ptr->Status & 0x10) - { - kinfo("[ pci device %d ] class code = %d\tsubclass=%d\tstatus=%#010lx\tcap_pointer=%#010lx\tbar5=%#010lx, vendor=%#08x, device id=%#08x", i, ptr->Class_code, ptr->SubClass, ptr->Status, ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer, ((struct pci_device_structure_general_device_t *)ptr)->BAR5, - ptr->Vendor_ID, ptr->Device_ID); - uint32_t tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer); - } - else - { - - kinfo("[ pci device %d ] class code = %d\tsubclass=%d\tstatus=%#010lx\t", i, ptr->Class_code, ptr->SubClass, ptr->Status); - } - } - else if (ptr->HeaderType == 0x1) - { - if (ptr->Status & 0x10) - { - kinfo("[ pci device %d ] class code = %d\tsubclass=%d\tstatus=%#010lx\tcap_pointer=%#010lx", i, ptr->Class_code, ptr->SubClass, ptr->Status, ((struct pci_device_structure_pci_to_pci_bridge_t *)ptr)->Capability_Pointer); - } - else - { - - kinfo("[ pci device %d ] class code = %d\tsubclass=%d\tstatus=%#010lx\t", i, ptr->Class_code, ptr->SubClass, ptr->Status); - } - } - else if (ptr->HeaderType == 0x2) - { - kinfo("[ pci device %d ] class code = %d\tsubclass=%d\tstatus=%#010lx\t", i, ptr->Class_code, ptr->SubClass, ptr->Status); - } - - ptr = container_of(list_next(&(ptr->list)), struct pci_device_structure_header_t, list); - } - kinfo("PCI bus initialized."); -} - - -/** - * @brief 获取 device structure - * - * @param class_code - * @param sub_class - * @param res 返回的结果数组 - */ -void pci_get_device_structure(uint8_t class_code, uint8_t sub_class, struct pci_device_structure_header_t *res[], uint32_t *count_res) -{ - - struct pci_device_structure_header_t *ptr = container_of(pci_device_structure_list, struct pci_device_structure_header_t, list); - *count_res = 0; - - for (int i = 0; i < count_device_list; ++i) - { - if ((ptr->Class_code == class_code) && (ptr->SubClass == sub_class)) - { - kdebug("[%d] class_code=%d, sub_class=%d, progIF=%d, bar5=%#010lx", i, ptr->Class_code, ptr->SubClass, ptr->ProgIF, ((struct pci_device_structure_general_device_t *)ptr)->BAR5); - - res[*count_res] = ptr; - ++(*count_res); - } - ptr = container_of(list_next(&(ptr->list)), struct pci_device_structure_header_t, list); - } -} - -/** - * @brief 寻找符合指定类型的capability list - * - * @param pci_dev pci设备header - * @param cap_type c要寻找的capability类型 - * @return uint64_t cap list的偏移量 - */ -int32_t pci_enumerate_capability_list(struct pci_device_structure_header_t *pci_dev, uint32_t cap_type) -{ - uint32_t cap_offset; - switch (pci_dev->HeaderType) - { - case 0x00: - - cap_offset = ((struct pci_device_structure_general_device_t *)pci_dev)->Capabilities_Pointer; - break; - - case 0x10: - cap_offset = ((struct pci_device_structure_pci_to_pci_bridge_t *)pci_dev)->Capability_Pointer; - break; - default: - // 不支持 - return -ENOSYS; - } - uint32_t tmp; - while (1) - { - tmp = pci_read_config(pci_dev->bus, pci_dev->device, pci_dev->func, cap_offset); - if ((tmp & 0xff) != cap_type) - { - if (((tmp & 0xff00) >> 8)) - { - cap_offset = (tmp & 0xff00)>>8; - continue; - } - else - return -ENOSYS; - } - - return cap_offset; - } -} \ No newline at end of file diff --git a/kernel/src/driver/pci/pci.h b/kernel/src/driver/pci/pci.h deleted file mode 100644 index 92814bd49..000000000 --- a/kernel/src/driver/pci/pci.h +++ /dev/null @@ -1,225 +0,0 @@ -#pragma once - -#include -#include - -#define PORT_PCI_CONFIG_ADDRESS 0xcf8 -#define PORT_PCI_CONFIG_DATA 0xcfc - -// pci设备结构信息的链表 -struct List *pci_device_structure_list = NULL; - -/** - * @brief 初始化pci驱动 - * - */ -void pci_init(); -void rs_pci_init(); -// pci设备结构的通用标题字段 -struct pci_device_structure_header_t -{ - struct List list; - - // 包含msix table地址的bar的mmio基地址 - uint64_t msix_mmio_vaddr; - uint64_t msix_mmio_size; // msix映射长度 - uint32_t msix_offset; // msix表的offset - uint16_t msix_table_size; // msix表的表项数量 - - // ==== 以下三个变量表示该结构体所处的位置 - uint8_t bus; - uint8_t device; - uint8_t func; - - uint16_t Vendor_ID; // 供应商ID 0xffff是一个无效值,在读取访问不存在的设备的配置空间寄存器时返回 - uint16_t Device_ID; // 设备ID,标志特定设备 - - uint16_t Command; // 提供对设备生成和响应pci周期的能力的控制 向该寄存器写入0时,设备与pci总线断开除配置空间访问以外的所有连接 - uint16_t Status; // 用于记录pci总线相关时间的状态信息寄存器 - - uint8_t RevisionID; // 修订ID,指定特定设备的修订标志符 - uint8_t ProgIF; // 编程接口字节,一个只读寄存器,指定设备具有的寄存器级别的编程接口(如果有的话) - uint8_t SubClass; // 子类。指定设备执行的特定功能的只读寄存器 - uint8_t Class_code; // 类代码,一个只读寄存器,指定设备执行的功能类型 - - uint8_t CacheLineSize; // 缓存线大小:以 32 位为单位指定系统缓存线大小。设备可以限制它可以支持的缓存线大小的数量,如果不支持的值写入该字段,设备将表现得好像写入了 0 值 - uint8_t LatencyTimer; // 延迟计时器:以 PCI 总线时钟为单位指定延迟计时器。 - uint8_t HeaderType; // 标头类型 a value of 0x0 specifies a general device, a value of 0x1 specifies a PCI-to-PCI bridge, and a value of 0x2 specifies a CardBus bridge. If bit 7 of this register is set, the device has multiple functions; otherwise, it is a single function device. - uint8_t BIST; // Represents that status and allows control of a devices BIST (built-in self test). - // Here is the layout of the BIST register: - // | bit7 | bit6 | Bits 5-4 | Bits 3-0 | - // | BIST Capable | Start BIST | Reserved | Completion Code | - // for more details, please visit https://wiki.osdev.org/PCI -}; - -/** - * @brief 表头类型为0x0的pci设备结构 - * - */ -struct pci_device_structure_general_device_t -{ - struct pci_device_structure_header_t header; - uint32_t BAR0; - uint32_t BAR1; - uint32_t BAR2; - uint32_t BAR3; - uint32_t BAR4; - uint32_t BAR5; - uint32_t Cardbus_CIS_Pointer; // 指向卡信息结构,供在 CardBus 和 PCI 之间共享芯片的设备使用。 - - uint16_t Subsystem_Vendor_ID; - uint16_t Subsystem_ID; - - uint32_t Expansion_ROM_base_address; - - uint8_t Capabilities_Pointer; - uint8_t reserved0; - uint16_t reserved1; - - uint32_t reserved2; - - uint8_t Interrupt_Line; // 指定设备的中断引脚连接到系统中断控制器的哪个输入,并由任何使用中断引脚的设备实现。对于 x86 架构,此寄存器对应于 PIC IRQ 编号 0-15(而不是 I/O APIC IRQ 编号),并且值0xFF定义为无连接。 - uint8_t Interrupt_PIN; // 指定设备使用的中断引脚。其中值为0x1INTA#、0x2INTB#、0x3INTC#、0x4INTD#,0x0表示设备不使用中断引脚。 - uint8_t Min_Grant; // 一个只读寄存器,用于指定设备所需的突发周期长度(以 1/4 微秒为单位)(假设时钟速率为 33 MHz) - uint8_t Max_Latency; // 一个只读寄存器,指定设备需要多长时间访问一次 PCI 总线(以 1/4 微秒为单位)。 -} __attribute__((packed)); - -/** - * @brief 表头类型为0x1的pci设备结构(PCI to PCI Bridge) - * - */ -struct pci_device_structure_pci_to_pci_bridge_t -{ - struct pci_device_structure_header_t header; - - uint32_t BAR0; - uint32_t BAR1; - - uint8_t Primary_Bus_Number; - uint8_t Secondary_Bus_Number; - uint8_t Subordinate_Bus_Number; - uint8_t Secondary_Latency_Timer; - - uint8_t io_base; - uint8_t io_limit; - uint16_t Secondary_Status; - - uint16_t Memory_Base; - uint16_t Memory_Limit; - - uint16_t Prefetchable_Memory_Base; - uint16_t Prefetchable_Memory_Limit; - - uint32_t Prefetchable_Base_Upper_32_Bits; - uint32_t Prefetchable_Limit_Upper_32_Bits; - - uint16_t io_Base_Upper_16_Bits; - uint16_t io_Limit_Upper_16_Bits; - - uint8_t Capability_Pointer; - uint8_t reserved0; - uint16_t reserved1; - - uint32_t Expansion_ROM_base_address; - - uint8_t Interrupt_Line; - uint8_t Interrupt_PIN; - uint16_t Bridge_Control; - -} __attribute__((packed)); - -/** - * @brief 表头类型为0x2的pci设备结构(PCI to CardBus Bridge) - * - */ -struct pci_device_structure_pci_to_cardbus_bridge_t -{ - struct pci_device_structure_header_t header; - - uint32_t CardBus_Socket_ExCa_base_address; - - uint8_t Offset_of_capabilities_list; - uint8_t Reserved; - uint16_t Secondary_status; - - uint8_t PCI_bus_number; - uint8_t CardBus_bus_number; - uint8_t Subordinate_bus_number; - uint8_t CardBus_latency_timer; - - uint32_t Memory_Base_Address0; - uint32_t Memory_Limit0; - uint32_t Memory_Base_Address1; - uint32_t Memory_Limit1; - uint32_t IO_Base_Address0; - uint32_t IO_Limit0; - uint32_t IO_Base_Address1; - uint32_t IO_Limit1; - - uint8_t Interrupt_Line; - uint8_t Interrupt_PIN; - uint16_t Bridge_Control; - - uint16_t Subsystem_Device_ID; - uint16_t Subsystem_Vendor_ID; - - uint32_t PC_Card_legacy_mode_base_address_16_bit; - -} __attribute__((packed)); - -/** - * @brief 从pci配置空间读取信息 - * - * @param bus 总线号 - * @param slot 插槽号 - * @param func 功能号 - * @param offset 字节偏移量 - * @return uint 寄存器值 - */ -uint32_t pci_read_config(uchar bus, uchar slot, uchar func, uchar offset); - -/** - * @brief 向pci配置空间写入信息 - * - * @param bus 总线号 - * @param slot 设备号 - * @param func 功能号 - * @param offset 字节偏移量 - * @return uint 寄存器值 - */ -uint pci_write_config(uchar bus, uchar slot, uchar func, uchar offset, uint32_t data); - -/** - * @brief 读取pci设备标头 - * - * @param type 标头类型 - * @param bus 总线号 - * @param slot 插槽号 - * @param func 功能号 - * @return 返回的header的指针 - */ -void *pci_read_header(int *type, uchar bus, uchar slot, uchar func, bool add_to_list); - -/** - * @brief 扫描所有pci总线上的所有设备 - * - */ -void pci_checkAllBuses(); - -/** - * @brief 获取 device structure - * - * @param class_code - * @param sub_class - * @param res 返回的结果数组 - */ -void pci_get_device_structure(uint8_t class_code, uint8_t sub_class, struct pci_device_structure_header_t *res[], uint32_t *count_res); - -/** - * @brief 寻找符合指定类型的capability list - * - * @param pci_dev pci设备header - * @param cap_type c要寻找的capability类型 - * @return uint64_t cap list的偏移量 - */ -int32_t pci_enumerate_capability_list(struct pci_device_structure_header_t *pci_dev, uint32_t cap_type); \ No newline at end of file diff --git a/kernel/src/driver/virtio/virtio.rs b/kernel/src/driver/virtio/virtio.rs index 3e20c6874..92b173063 100644 --- a/kernel/src/driver/virtio/virtio.rs +++ b/kernel/src/driver/virtio/virtio.rs @@ -1,9 +1,9 @@ use super::transport_pci::PciTransport; use super::virtio_impl::HalImpl; use crate::driver::net::virtio_net::virtio_net; -use crate::driver::pci::pci::PciDeviceStructureGeneralDevice; use crate::driver::pci::pci::{ - get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST, + get_pci_device_structure_mut, PciDeviceStructure, PciDeviceStructureGeneralDevice, + PCI_DEVICE_LINKEDLIST, }; use crate::libs::rwlock::RwLockWriteGuard; use crate::{kdebug, kerror, kwarn}; diff --git a/kernel/src/include/bindings/wrapper.h b/kernel/src/include/bindings/wrapper.h index 82d79699f..bb451d1f6 100644 --- a/kernel/src/include/bindings/wrapper.h +++ b/kernel/src/include/bindings/wrapper.h @@ -30,9 +30,7 @@ #include #include #include -#include #include -#include #include #include #include diff --git a/kernel/src/main.c b/kernel/src/main.c index 9c860719c..14635d67a 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -27,7 +27,6 @@ #include "driver/keyboard/ps2_keyboard.h" #include "driver/mouse/ps2_mouse.h" #include "driver/multiboot2/multiboot2.h" -#include "driver/pci/pci.h" #include #include #include @@ -165,8 +164,6 @@ void system_initialize() ps2_keyboard_init(); io_mfence(); - pci_init(); - rs_pci_init(); // 这里必须加内存屏障,否则会出错 diff --git a/kernel/src/time/syscall.rs b/kernel/src/time/syscall.rs index 4404fd1bc..8df5edd2f 100644 --- a/kernel/src/time/syscall.rs +++ b/kernel/src/time/syscall.rs @@ -81,8 +81,7 @@ impl Syscall { timezone: *mut PosixTimeZone, ) -> Result { // TODO; 处理时区信息 - // kdebug!("enter sys_do_gettimeofday"); - if tv == null_mut() { + if tv.is_null() { return Err(SystemError::EFAULT); } let mut tv_buf = diff --git a/kernel/src/time/timekeeping.rs b/kernel/src/time/timekeeping.rs index 8b7148199..447c5e09c 100644 --- a/kernel/src/time/timekeeping.rs +++ b/kernel/src/time/timekeeping.rs @@ -142,7 +142,9 @@ impl Timekeeper { } } pub fn timekeeper() -> &'static Timekeeper { - return unsafe { __TIMEKEEPER.as_ref().unwrap() }; + let r = unsafe { __TIMEKEEPER.as_ref().unwrap() }; + + return r; } pub fn timekeeper_init() {