hba->global_hba_control |= AHCI_ENABLE;
+ hba->global_hba_control |= AHCI_INTERRUPT_ENABLE;
+
uint32_t cap = hba->capability;
int num_ports = (cap & 0x1F) + 1;
}
}
}
-
- // TODO
- // 开启ahci的global_hba_control的interrupt enable位
- hba->global_hba_control |= AHCI_INTERRUPT_ENABLE;
}
void init_ahci() {
const static int AHCI_FIS_TYPE_REG_H2D = 0x27;
const static int AHCI_FIS_TYPE_REG_D2H = 0x34;
+const static uint32_t AHCI_INTERRUPT_ENABLE_DHRS = (1U << 0); // device to host fis interrupt enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_PSE = (1U << 1); // pio setup fis interrupt enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_DSE = (1U << 2); // DMA setup fis interrupt enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_SDBE = (1U << 3); // set device bits interrupt enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_UFE = (1U << 4); // unknown fis interrupt enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_DPE = (1U << 5); // descriptor process error interrupt enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_PCE = (1U << 6); // port change error interrupt enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_DMPE = (1U << 7); // device mechanical presence enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_PRCE = (1U << 22); // phyrdy change interrupt enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_IPME = (1U << 23); // incorrect port multiplier interrupt enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_OFE = (1U << 24); // overflow error interrupt enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_INFE = (1U << 26); // interface non-fatal error enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_IFE = (1U << 27); // interface fatal error enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_HBDE = (1U << 28); // host bus data error enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_HBFE = (1U << 29); // host bus fatal error enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_TFEE = (1U << 30); // task file error enable
+const static uint32_t AHCI_INTERRUPT_ENABLE_CPDE = (1U << 31); // cold presence detect enable
+
typedef struct {
uint8_t fis_type;
uint8_t pmport : 4; // port multiplier
#include <string.h>
#include <system.h>
+int sata_irq_triggered = 0;
+
void init_sata_device(ahci_hba_t* hba, ahci_port_t* port, int index) {
assert(hba != NULL);
assert(port != NULL);
// 写1清0
port->interrupt_status = port->interrupt_status;
+ port->interrupt_enable = AHCI_INTERRUPT_ENABLE_DHRS;
+ asm("sti");
//
port->cmd_issue = 1 << 0;
sata_read_identify_string(identify, 27, 46, s);
printk("HD Model: %s\n", s);
+
+ // while (!sata_irq_triggered) {
+ // // asm("sti");
+ // asm("pause");
+ // }
+
+ // 1. 等待端口空闲(确保上一条命令完全完成)
+ while (port->cmd_issue & 1) {
+ // 命令位仍被置位,等待清除
+ }
+ while (port->sata_active & 1) {
+ // 等待active位清除
+ }
+
+ memset(fis, 0, sizeof(ahci_fis_reg_h2d_t));
+ fis->fis_type = AHCI_FIS_TYPE_REG_H2D;
+ fis->c = 1;
+ fis->command = SATA_CMD_IDENTIFY;
+ fis->device = SATA_DEVICE_LBA;
+
+ sata->cmd_list0->cfl = sizeof(ahci_fis_reg_h2d_t) / sizeof(uint32_t);
+ sata->cmd_list0->prdtl = 1;
+ sata->cmd_list0->w = 0; // read
+ sata->cmd_list0->a = 0; // ata device
+ sata->cmd_list0->prd_byte_count = 0;
+ // 清除中断状态
+ // 写1清0
+ port->interrupt_status = port->interrupt_status;
+
+ port->interrupt_enable = AHCI_INTERRUPT_ENABLE_DHRS;
+
+ //
+ port->cmd_issue = 1 << 0;
}
sata_device_t sata_devices[MAX_SATA_DEVICES] = {0};
uint64_t ioapic_rte_read(uint32_t index);
void ioapic_rte_write(uint32_t index, uint64_t v);
+
+void ioapic_eoi();
ap_pit_ticks++;
- system.lapic->write(LAPIC_EOI, 0);
+ ioapic_eoi();
}
void do_ap_no_irq_handler() {
ap_lapic_ticks++;
- system.lapic->write(LAPIC_EOI, 0);
+ ioapic_eoi();
}
void _system_monitor() {
iounmap(rcba_virt_base);
}
+void ioapic_eoi() {
+ system.lapic->write(LAPIC_EOI, 0);
+}
+
+extern int sata_irq_triggered;
+void sata0_irq_handler() {
+ printk("SATA#0 IRQ\n");
+ sata_irq_triggered = 1;
+ ioapic_eoi();
+}
+
void ioapic_init() {
// 把IO APIC映射进地址空间
ioapic_map.phys_base = system.ioapic_addr;
rte.destination = 0;
ioapic_rte_write(IOAPIC_RTE(1), rte.value);
irq_set_chip(0x01, &ioapic_chip);
+
+ //
+ int irq = 0x0B; // 11
+ rte.value = 0;
+ rte.vector = 0x20 + irq;
+ rte.delivery_mode = IOAPIC_DELIVERY_MODE_FIXED;
+ rte.destination_mode = IOAPIC_PHYSICAL_DESTINATION;
+ rte.trigger_mode = IOAPIC_TRIGGER_MODE_EDGE;
+ rte.mask = IOAPIC_INT_UNMASKED;
+ rte.destination = 0;
+ ioapic_rte_write(IOAPIC_RTE(irq), rte.value);
+ irq_set_chip(irq, &ioapic_chip);
+
+ request_irq(irq, sata0_irq_handler, "SATA#0", "SATA#0");
#endif
}