From f05a333a0f27f401ff32cfd2e74364ee4ecc893a Mon Sep 17 00:00:00 2001 From: Minep Date: Mon, 4 Jul 2022 13:05:04 +0100 Subject: [PATCH 1/1] feat: Ability to send command to ATA device. feat: Implementation of IDENTIFY (PACKET) DEVICE command issuing. --- lunaix-os/.gitignore | 3 +- lunaix-os/config/make-debug-tool | 3 + lunaix-os/hal/ahci/ahci.c | 196 +++++++++++++++++++++-- lunaix-os/hal/ahci/utils.c | 31 ++++ lunaix-os/includes/arch/x86/interrupts.h | 1 + lunaix-os/includes/arch/x86/vectors.h | 5 + lunaix-os/includes/hal/ahci.h | 80 --------- lunaix-os/includes/hal/ahci/ahci.h | 173 ++++++++++++++++++++ lunaix-os/includes/hal/ahci/utils.h | 13 ++ lunaix-os/includes/lunaix/mm/vmm.h | 3 + lunaix-os/includes/lunaix/spike.h | 8 + lunaix-os/kernel/asm/x86/idt.c | 2 + lunaix-os/kernel/asm/x86/interrupt.S | 2 + lunaix-os/kernel/mm/vmm.c | 19 +++ lunaix-os/kernel/proc0.c | 2 +- 15 files changed, 443 insertions(+), 98 deletions(-) create mode 100644 lunaix-os/hal/ahci/utils.c delete mode 100644 lunaix-os/includes/hal/ahci.h create mode 100644 lunaix-os/includes/hal/ahci/ahci.h create mode 100644 lunaix-os/includes/hal/ahci/utils.h diff --git a/lunaix-os/.gitignore b/lunaix-os/.gitignore index 0b666f6..31aeefd 100644 --- a/lunaix-os/.gitignore +++ b/lunaix-os/.gitignore @@ -4,4 +4,5 @@ playground/ .vscode/*.log .VSCodeCounter/ .idea -bx_enh_dbg.ini \ No newline at end of file +bx_enh_dbg.ini +machine/ \ No newline at end of file diff --git a/lunaix-os/config/make-debug-tool b/lunaix-os/config/make-debug-tool index 647a456..8d4e13d 100644 --- a/lunaix-os/config/make-debug-tool +++ b/lunaix-os/config/make-debug-tool @@ -4,7 +4,10 @@ QEMU_MON_PORT := 45454 QEMU_OPTIONS := -s -S -m 1G \ -rtc base=utc \ -no-reboot \ + -machine q35 \ -no-shutdown \ -d cpu_reset \ + -drive id=disk,file="machine/disk0.vdi",if=none \ -device ahci,id=ahci \ + -device ide-hd,drive=disk,bus=ahci.0 \ -monitor telnet::$(QEMU_MON_PORT),server,nowait & \ No newline at end of file diff --git a/lunaix-os/hal/ahci/ahci.c b/lunaix-os/hal/ahci/ahci.c index c5989fb..57bedb6 100644 --- a/lunaix-os/hal/ahci/ahci.c +++ b/lunaix-os/hal/ahci/ahci.c @@ -8,12 +8,14 @@ * @copyright Copyright (c) 2022 * */ -#include +#include +#include #include #include -#include #include #include +#include +#include #include #include @@ -24,6 +26,9 @@ LOG_MODULE("AHCI") static struct ahci_hba hba; +void +__ahci_hba_isr(isr_param param); + void ahci_init() { @@ -41,6 +46,11 @@ ahci_init() pci_write_cspace(ahci_dev->cspace_base, PCI_REG_STATUS_CMD, cmd); + pci_setup_msi(ahci_dev, AHCI_HBA_IV); + intr_subscribe(AHCI_HBA_IV, __ahci_hba_isr); + + memset(&hba, 0, sizeof(hba)); + hba.base = (hba_reg_t*)ioremap(PCI_BAR_ADDR_MM(bar6), size); // 重置HBA @@ -48,7 +58,8 @@ ahci_init() wait_until(!(hba.base[HBA_RGHC] & HBA_RGHC_RESET)); // 启用AHCI工作模式,启用中断 - hba.base[HBA_RGHC] |= (HBA_RGHC_ACHI_ENABLE | HBA_RGHC_INTR_ENABLE); + hba.base[HBA_RGHC] |= HBA_RGHC_ACHI_ENABLE; + hba.base[HBA_RGHC] |= HBA_RGHC_INTR_ENABLE; // As per section 3.1.1, this is 0 based value. hba_reg_t cap = hba.base[HBA_RCAP]; @@ -66,7 +77,7 @@ ahci_init() } struct ahci_port* port = - (struct ahci_port*)lxmalloc(sizeof(struct ahci_port)); + (struct ahci_port*)valloc(sizeof(struct ahci_port)); hba_reg_t* port_regs = (hba_reg_t*)(&hba.base[HBA_RPBASE + i * HBA_RPSIZE]); @@ -87,18 +98,30 @@ ahci_init() port_regs[HBA_RPxCLB] = clb_pa + clbp * HBA_CLB_SIZE; port_regs[HBA_RPxFB] = fis_pa + fisp * HBA_FIS_SIZE; - *port = - (struct ahci_port){ .regs = port_regs, - .ssts = port_regs[HBA_RPxSSTS], - .cmdlstv = clb_pg_addr + clbp * HBA_CLB_SIZE, - .fisv = fis_pg_addr + fisp * HBA_FIS_SIZE }; + *port = (struct ahci_port){ .regs = port_regs, + .ssts = port_regs[HBA_RPxSSTS], + .cmdlst = clb_pg_addr + clbp * HBA_CLB_SIZE, + .fis = fis_pg_addr + fisp * HBA_FIS_SIZE }; /* 初始化端口,并置于就绪状态 */ port_regs[HBA_RPxCI] = 0; - port_regs[HBA_RPxIE] |= (HBA_PxINTR_DMA | HBA_PxINTR_D2HR); - port_regs[HBA_RPxCMD] |= (HBA_PxCMD_FRE | HBA_PxCMD_ST); + + // 需要通过全部置位去清空这些寄存器(相当的奇怪……) + port_regs[HBA_RPxSERR] = -1; + + port_regs[HBA_RPxIE] |= (HBA_PxINTR_DMA); + port_regs[HBA_RPxIE] |= (HBA_PxINTR_D2HR); hba.ports[i] = port; + + if (HBA_RPxSSTS_IF(port->ssts)) { + wait_until(!(port_regs[HBA_RPxCMD] & HBA_PxCMD_CR)); + port_regs[HBA_RPxCMD] |= HBA_PxCMD_FRE; + port_regs[HBA_RPxCMD] |= HBA_PxCMD_ST; + if (!ahci_identify_device(port)) { + kprintf(KERROR "fail to probe device info"); + } + } } } @@ -107,14 +130,155 @@ char sata_ifs[][20] = { "Not detected", "SATA II (3.0Gbps)", "SATA III (6.0Gbps)" }; +void +__ahci_hba_isr(isr_param param) +{ + // TODO: hba interrupt + kprintf(KDEBUG "HBA INTR\n"); +} + void ahci_list_device() { - kprintf(KINFO "Version: %x; Ports: %d\n", hba.version, hba.ports_num); + kprintf(KINFO "Version: %x; Ports: %d; Slot: %d\n", + hba.version, + hba.ports_num, + hba.cmd_slots); + struct ahci_port* port; for (size_t i = 0; i < 32; i++) { - struct ahci_port* port = hba.ports[i]; - if (!port) + port = hba.ports[i]; + + // 愚蠢的gcc似乎认为 struct ahci_port* 不可能为空 + // 所以将这个非常关键的if给优化掉了。 + // 这里将指针强制转换为整数,欺骗gcc :) + if ((uintptr_t)port == 0) { continue; - kprintf("\t Port %d: %s\n", i, &sata_ifs[HBA_RPxSSTS_IF(port->ssts)]); + } + + int device_state = HBA_RPxSSTS_IF(port->ssts); + + kprintf("\t Port %d: %s (%x)\n", + i, + &sata_ifs[device_state], + port->regs[HBA_RPxSIG]); + + struct ahci_device_info* dev_info = port->device_info; + if (!device_state || !dev_info) { + continue; + } + + kprintf("\t\t capacity: %d KiB\n", + (dev_info->max_lba * dev_info->sector_size) >> 10); + kprintf("\t\t sector size: %dB\n", dev_info->sector_size); + kprintf("\t\t model: %s\n", &dev_info->model); + kprintf("\t\t serial: %s\n", &dev_info->serial_num); } -} \ No newline at end of file +} + +int +achi_alloc_slot(struct ahci_port* port) +{ + hba_reg_t pxsact = port->regs[HBA_RPxSACT]; + hba_reg_t pxci = port->regs[HBA_RPxCI]; + hba_reg_t free_bmp = pxsact | pxci; + uint32_t i = 0; + for (; i <= hba.cmd_slots && (free_bmp & 0x1); i++, free_bmp >>= 1) + ; + return i | -(i > hba.cmd_slots); +} + +void +__ahci_create_fis(struct sata_reg_fis* cmd_fis, + uint8_t command, + uint32_t lba_lo, + uint32_t lba_hi, + uint16_t sector_count) +{ + cmd_fis->head.type = SATA_REG_FIS_H2D; + cmd_fis->head.options = SATA_REG_FIS_COMMAND; + cmd_fis->head.status_cmd = command; + cmd_fis->dev = 0; + + cmd_fis->lba0 = SATA_LBA_COMPONENT(lba_lo, 0); + cmd_fis->lba8 = SATA_LBA_COMPONENT(lba_lo, 8); + cmd_fis->lba16 = SATA_LBA_COMPONENT(lba_lo, 16); + cmd_fis->lba24 = SATA_LBA_COMPONENT(lba_lo, 24); + + cmd_fis->lba32 = SATA_LBA_COMPONENT(lba_hi, 0); + cmd_fis->lba40 = SATA_LBA_COMPONENT(lba_hi, 8); + + cmd_fis->count = sector_count; +} + +int +ahci_identify_device(struct ahci_port* port) +{ + int slot = achi_alloc_slot(port); + assert_msg(slot >= 0, "No free slot"); + + // 清空任何待响应的中断 + port->regs[HBA_RPxIS] = 0; + + /* 发送ATA命令,参考:SATA AHCI Spec Rev.1.3.1, section 5.5 */ + + // 构建命令头(Command Header)和命令表(Command Table) + struct ahci_hba_cmdh* cmd_header = &port->cmdlst[slot]; + struct ahci_hba_cmdt* cmd_table = valloc_dma(sizeof(struct ahci_hba_cmdt)); + + memset(cmd_header, 0, sizeof(*cmd_header)); + memset(cmd_table, 0, sizeof(*cmd_table)); + + // 预备DMA接收缓存,用于存放HBA传回的数据 + uint16_t* data_in = (uint16_t*)valloc_dma(512); + + cmd_table->entries[0] = + (struct ahci_hba_prdte){ .data_base = vmm_v2p(data_in), + .byte_count = 511 }; // byte_count是从0开始算的 + + // 在命令表中构建命令FIS + struct sata_reg_fis* cmd_fis = (struct sata_reg_fis*)cmd_table->command_fis; + + // 根据设备类型使用合适的命令 + if (port->regs[HBA_RPxSIG] == HBA_DEV_SIG_ATA) { + // ATA 一般为硬盘 + __ahci_create_fis(cmd_fis, ATA_IDENTIFY_DEVICE, 0, 0, 0); + } else { + // ATAPI 一般为光驱,软驱,或者磁带机 + __ahci_create_fis(cmd_fis, ATA_IDENTIFY_PAKCET_DEVICE, 0, 0, 0); + } + + // 将命令表挂到命令头上 + cmd_header->cmd_table_base = vmm_v2p(cmd_table); + cmd_header->prdt_len = 1; + cmd_header->options |= + HBA_CMDH_FIS_LEN(sizeof(*cmd_fis)) | HBA_CMDH_CLR_BUSY; + + // PxCI寄存器置位,告诉HBA这儿有个数据需要发送到SATA端口 + port->regs[HBA_RPxCI] = (1 << slot); + + wait_until(!(port->regs[HBA_RPxCI] & (1 << slot))); + + /* + 等待数据到达内存 + 解析IDENTIFY DEVICE传回来的数据。 + 参考: + * ATA/ATAPI Command Set - 3 (ACS-3), Section 7.12.7 + + 注意:ATAPI无法通过IDENTIFY PACKET DEVICE 获取容量信息。 + 这需要另外使用特殊的SCSI命令中的READ CAPACITY(16) + 来获取,这种命令需要使用ATA的PACKET命令发出。 + 参考: + * ATA/ATAPI Command Set - 3 (ACS-3), Section 7.18 + * SATA AHCI HBA Spec, Section 5.3.7 + * SCSI Command Reference Manual, Section 3.26 + */ + port->device_info = valloc(sizeof(struct ahci_device_info)); + ahci_parse_dev_info(port->device_info, data_in); + + vfree_dma(data_in); + vfree_dma(cmd_table); + + return 1; +} + +// TODO: Support ATAPI Device. \ No newline at end of file diff --git a/lunaix-os/hal/ahci/utils.c b/lunaix-os/hal/ahci/utils.c new file mode 100644 index 0000000..279cd50 --- /dev/null +++ b/lunaix-os/hal/ahci/utils.c @@ -0,0 +1,31 @@ +#include +#include + +#define IDDEV_MAXLBA_OFFSET 60 +#define IDDEV_LSECSIZE_OFFSET 117 +#define IDDEV_WWN_OFFSET 108 +#define IDDEV_SERIALNUM_OFFSET 10 +#define IDDEV_MODELNUM_OFFSET 27 + +void +ahci_parse_dev_info(struct ahci_device_info* dev_info, uint16_t* data) +{ + dev_info->max_lba = *((uint32_t*)(data + IDDEV_MAXLBA_OFFSET)); + dev_info->sector_size = *((uint32_t*)(data + IDDEV_LSECSIZE_OFFSET)); + memcpy(&dev_info->wwn, (uint8_t*)(data + IDDEV_WWN_OFFSET), 8); + if (!dev_info->sector_size) { + dev_info->sector_size = 512; + } + ahci_parsestr(&dev_info->serial_num, data + IDDEV_SERIALNUM_OFFSET, 10); + ahci_parsestr(&dev_info->model, data + IDDEV_MODELNUM_OFFSET, 20); +} + +void +ahci_parsestr(char* str, uint16_t* reg_start, int size_word) +{ + for (int i = 0, j = 0; i < size_word; i++, j += 2) { + uint16_t reg = *(reg_start + i); + str[j] = (char)(reg >> 8); + str[j + 1] = (char)(reg & 0xff); + } +} \ No newline at end of file diff --git a/lunaix-os/includes/arch/x86/interrupts.h b/lunaix-os/includes/arch/x86/interrupts.h index 88138b6..862ef05 100644 --- a/lunaix-os/includes/arch/x86/interrupts.h +++ b/lunaix-os/includes/arch/x86/interrupts.h @@ -65,6 +65,7 @@ ISR(32) ISR(33) ISR(201) +ISR(202) ISR(210) diff --git a/lunaix-os/includes/arch/x86/vectors.h b/lunaix-os/includes/arch/x86/vectors.h index 5fb424f..e4a1968 100644 --- a/lunaix-os/includes/arch/x86/vectors.h +++ b/lunaix-os/includes/arch/x86/vectors.h @@ -1,6 +1,8 @@ #ifndef __LUNAIX_VECTORS_H #define __LUNAIX_VECTORS_H +// clang-format off + #define FAULT_DIVISION_ERROR 0 #define FAULT_TRAP_DEBUG_EXCEPTION 1 #define INT_NMI 2 @@ -32,6 +34,7 @@ // Keyboard #define PC_KBD_IV 201 +#define AHCI_HBA_IV 202 #define RTC_TIMER_IV 210 @@ -45,4 +48,6 @@ #define PC_AT_IRQ_RTC 8 #define PC_AT_IRQ_KBD 1 +// clang-format on + #endif /* __LUNAIX_VECTORS_H */ diff --git a/lunaix-os/includes/hal/ahci.h b/lunaix-os/includes/hal/ahci.h deleted file mode 100644 index dc30ca8..0000000 --- a/lunaix-os/includes/hal/ahci.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef __LUNAIX_AHCI_H -#define __LUNAIX_AHCI_H - -/* - * Macro naming rule: - * HBA_R[xxx] - * HBA Register [xxx] - * e.g. HBA_RPxCLB is Register PxCLB - * - * All registers offset are 0 based index of a DWORD array - */ - -#define AHCI_HBA_CLASS 0x10601 - -#define HBA_RCAP 0 -#define HBA_RGHC 1 -#define HBA_RIS 2 -#define HBA_RPI 3 -#define HBA_RVER 4 - -#define HBA_RPBASE (0x40) -#define HBA_RPSIZE (0x80 >> 2) -#define HBA_RPxCLB 0 -#define HBA_RPxFB 2 -#define HBA_RPxIS 4 -#define HBA_RPxIE 5 -#define HBA_RPxCMD 6 -#define HBA_RPxTFD 8 -#define HBA_RPxSIG 9 -#define HBA_RPxSSTS 10 -#define HBA_RPxSCTL 11 -#define HBA_RPxSERR 12 -#define HBA_RPxSACT 13 -#define HBA_RPxCI 14 -#define HBA_RPxSNTF 15 -#define HBA_RPxFBS 16 - -#define HBA_PxCMD_FRE (1 << 4) -#define HBA_PxCMD_ST (1) -#define HBA_PxINTR_DMA (1 << 2) -#define HBA_PxINTR_D2HR (1) - -#define HBA_RGHC_ACHI_ENABLE (1 << 31) -#define HBA_RGHC_INTR_ENABLE (1 << 1) -#define HBA_RGHC_RESET 1 - -#define HBA_RPxSSTS_PWR(x) (((x) >> 8) & 0xf) -#define HBA_RPxSSTS_IF(x) (((x) >> 4) & 0xf) -#define HBA_RPxSSTS_PHYSTATE(x) ((x)&0xf) - -typedef unsigned int hba_reg_t; - -struct ahci_port -{ - hba_reg_t* regs; - unsigned int ssts; - void* cmdlstv; - void* fisv; -}; - -struct ahci_hba -{ - volatile hba_reg_t* base; - unsigned int ports_num; - unsigned int cmd_slots; - unsigned int version; - struct ahci_port* ports[32]; -}; - -/** - * @brief 初始化AHCI与HBA - * - */ -void -ahci_init(); - -void -ahci_list_device(); - -#endif /* __LUNAIX_AHCI_H */ diff --git a/lunaix-os/includes/hal/ahci/ahci.h b/lunaix-os/includes/hal/ahci/ahci.h new file mode 100644 index 0000000..c0c483a --- /dev/null +++ b/lunaix-os/includes/hal/ahci/ahci.h @@ -0,0 +1,173 @@ +#ifndef __LUNAIX_AHCI_H +#define __LUNAIX_AHCI_H + +#include + +/* + * Macro naming rule: + * HBA_R[xxx] + * HBA Register [xxx] + * e.g. HBA_RPxCLB is Register PxCLB + * + * All registers offset are 0 based index of a DWORD array + */ + +#define AHCI_HBA_CLASS 0x10601 + +#define HBA_RCAP 0 +#define HBA_RGHC 1 +#define HBA_RIS 2 +#define HBA_RPI 3 +#define HBA_RVER 4 + +#define HBA_RPBASE (0x40) +#define HBA_RPSIZE (0x80 >> 2) +#define HBA_RPxCLB 0 +#define HBA_RPxFB 2 +#define HBA_RPxIS 4 +#define HBA_RPxIE 5 +#define HBA_RPxCMD 6 +#define HBA_RPxTFD 8 +#define HBA_RPxSIG 9 +#define HBA_RPxSSTS 10 +#define HBA_RPxSCTL 11 +#define HBA_RPxSERR 12 +#define HBA_RPxSACT 13 +#define HBA_RPxCI 14 +#define HBA_RPxSNTF 15 +#define HBA_RPxFBS 16 + +#define HBA_PxCMD_FRE (1 << 4) +#define HBA_PxCMD_CR (1 << 15) +#define HBA_PxCMD_FR (1 << 14) +#define HBA_PxCMD_ST (1) +#define HBA_PxINTR_DMA (1 << 2) +#define HBA_PxINTR_D2HR (1) + +#define HBA_RGHC_ACHI_ENABLE (1 << 31) +#define HBA_RGHC_INTR_ENABLE (1 << 1) +#define HBA_RGHC_RESET 1 + +#define HBA_RPxSSTS_PWR(x) (((x) >> 8) & 0xf) +#define HBA_RPxSSTS_IF(x) (((x) >> 4) & 0xf) +#define HBA_RPxSSTS_PHYSTATE(x) ((x)&0xf) + +#define HBA_DEV_SIG_ATAPI 0xeb140101 +#define HBA_DEV_SIG_ATA 0x00000101 + +#define __HBA_PACKED__ __attribute__((packed)) + +typedef unsigned int hba_reg_t; + +#define HBA_CMDH_FIS_LEN(fis_bytes) (((fis_bytes) / 4) & 0x1f) +#define HBA_CMDH_ATAPI (1 << 5) +#define HBA_CMDH_WRITE (1 << 6) +#define HBA_CMDH_PREFETCH (1 << 7) +#define HBA_CMDH_R (1 << 8) +#define HBA_CMDH_CLR_BUSY (1 << 10) +#define HBA_CMDH_PRDT_LEN(entries) (((entries)&0xffff) << 16) + +struct ahci_hba_cmdh +{ + uint16_t options; + uint16_t prdt_len; + uint32_t transferred_size; + uint32_t cmd_table_base; + uint32_t reserved[5]; +} __HBA_PACKED__; + +#define HBA_PRDTE_BYTE_CNT(cnt) ((cnt & 0x3FFFFF) | 0x1) + +struct ahci_hba_prdte +{ + uint32_t data_base; + uint32_t reserved[2]; + uint32_t byte_count; +} __HBA_PACKED__; + +struct ahci_hba_cmdt +{ + uint8_t command_fis[64]; + uint8_t atapi_cmd[16]; + uint8_t reserved[0x30]; + struct ahci_hba_prdte entries[3]; +} __HBA_PACKED__; + +#define SATA_REG_FIS_D2H 0x34 +#define SATA_REG_FIS_H2D 0x27 +#define SATA_REG_FIS_COMMAND 0x80 +#define SATA_LBA_COMPONENT(lba, offset) ((((lba_lo) >> (offset)) & 0xff)) + +struct sata_fis_head +{ + uint8_t type; + uint8_t options; + uint8_t status_cmd; + uint8_t feat_err; +} __HBA_PACKED__; + +struct sata_reg_fis +{ + struct sata_fis_head head; + + uint8_t lba0, lba8, lba16; + uint8_t dev; + uint8_t lba24, lba32, lba40; + uint8_t reserved1; + + uint16_t count; + + uint8_t reserved[6]; +} __HBA_PACKED__; + +struct sata_data_fis +{ + struct sata_fis_head head; + + uint8_t data[0]; +} __HBA_PACKED__; + +struct ahci_device_info +{ + char serial_num[20]; + char model[40]; + uint32_t max_lba; + uint32_t sector_size; + uint8_t wwn[8]; +}; + +struct ahci_port +{ + volatile hba_reg_t* regs; + unsigned int ssts; + struct ahci_hba_cmdh* cmdlst; + struct sata_fis_head* fis; + struct ahci_device_info* device_info; +}; + +struct ahci_hba +{ + volatile hba_reg_t* base; + unsigned int ports_num; + unsigned int cmd_slots; + unsigned int version; + struct ahci_port* ports[32]; +}; + +#define ATA_IDENTIFY_DEVICE 0xec +#define ATA_IDENTIFY_PAKCET_DEVICE 0xa1 + +/** + * @brief 初始化AHCI与HBA + * + */ +void +ahci_init(); + +void +ahci_list_device(); + +int +ahci_identify_device(struct ahci_port* port); + +#endif /* __LUNAIX_AHCI_H */ diff --git a/lunaix-os/includes/hal/ahci/utils.h b/lunaix-os/includes/hal/ahci/utils.h new file mode 100644 index 0000000..1ff5f32 --- /dev/null +++ b/lunaix-os/includes/hal/ahci/utils.h @@ -0,0 +1,13 @@ +#ifndef __LUNAIX_AHCI_UTILS_H +#define __LUNAIX_AHCI_UTILS_H + +#include +#include + +void +ahci_parse_dev_info(struct ahci_device_info* dev_info, uint16_t* data); + +void +ahci_parsestr(char* str, uint16_t* reg_start, int size_word); + +#endif /* __LUNAIX_UTILS_H */ diff --git a/lunaix-os/includes/lunaix/mm/vmm.h b/lunaix-os/includes/lunaix/mm/vmm.h index 98f5763..182058b 100644 --- a/lunaix-os/includes/lunaix/mm/vmm.h +++ b/lunaix-os/includes/lunaix/mm/vmm.h @@ -119,4 +119,7 @@ vmm_next_free(uintptr_t start, int options); void* vmm_vmap(uintptr_t paddr, size_t size, pt_attr attr); +void* +vmm_v2p(void* va); + #endif /* __LUNAIX_VMM_H */ diff --git a/lunaix-os/includes/lunaix/spike.h b/lunaix-os/includes/lunaix/spike.h index 48a1904..cbdadfb 100644 --- a/lunaix-os/includes/lunaix/spike.h +++ b/lunaix-os/includes/lunaix/spike.h @@ -52,4 +52,12 @@ panick(const char* msg); while (!(cond)) \ ; +#define wait_until_expire(cond, max) \ + ({ \ + unsigned int __wcounter__ = (max); \ + while (!(cond) && __wcounter__-- > 0) \ + ; \ + __wcounter__; \ + }) + #endif /* __LUNAIX_SPIKE_H */ diff --git a/lunaix-os/kernel/asm/x86/idt.c b/lunaix-os/kernel/asm/x86/idt.c index 3e408fd..d2578f7 100644 --- a/lunaix-os/kernel/asm/x86/idt.c +++ b/lunaix-os/kernel/asm/x86/idt.c @@ -51,7 +51,9 @@ _init_idt() _set_idt_intr_entry(APIC_LINT0_IV, 0x08, _asm_isr251, 0); _set_idt_intr_entry(APIC_SPIV_IV, 0x08, _asm_isr252, 0); _set_idt_intr_entry(APIC_TIMER_IV, 0x08, _asm_isr253, 0); + _set_idt_intr_entry(PC_KBD_IV, 0x08, _asm_isr201, 0); + _set_idt_intr_entry(AHCI_HBA_IV, 0x08, _asm_isr202, 0); _set_idt_intr_entry(RTC_TIMER_IV, 0x08, _asm_isr210, 0); diff --git a/lunaix-os/kernel/asm/x86/interrupt.S b/lunaix-os/kernel/asm/x86/interrupt.S index dc5c4c3..7382142 100644 --- a/lunaix-os/kernel/asm/x86/interrupt.S +++ b/lunaix-os/kernel/asm/x86/interrupt.S @@ -42,7 +42,9 @@ isr_template APIC_TIMER_IV isr_template APIC_SPIV_IV isr_template RTC_TIMER_IV + isr_template PC_KBD_IV + isr_template AHCI_HBA_IV interrupt_wrapper: /* diff --git a/lunaix-os/kernel/mm/vmm.c b/lunaix-os/kernel/mm/vmm.c index fe3d65c..6e134fd 100644 --- a/lunaix-os/kernel/mm/vmm.c +++ b/lunaix-os/kernel/mm/vmm.c @@ -128,6 +128,25 @@ vmm_lookup(uintptr_t va, v_mapping* mapping) return 0; } +void* +vmm_v2p(void* va) +{ + uint32_t l1_index = L1_INDEX(va); + uint32_t l2_index = L2_INDEX(va); + + x86_page_table* l1pt = (x86_page_table*)L1_BASE_VADDR; + x86_pte_t l1pte = l1pt->entry[l1_index]; + + if (l1pte) { + x86_pte_t* l2pte = + &((x86_page_table*)L2_VADDR(l1_index))->entry[l2_index]; + if (l2pte) { + return PG_ENTRY_ADDR(*l2pte) | ((uintptr_t)va & 0xfff); + } + } + return 0; +} + void* vmm_mount_pd(uintptr_t mnt, void* pde) { diff --git a/lunaix-os/kernel/proc0.c b/lunaix-os/kernel/proc0.c index e943974..dcd6bf4 100644 --- a/lunaix-os/kernel/proc0.c +++ b/lunaix-os/kernel/proc0.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include -- 2.27.0