Add AHCI PCI IRQ handling

This commit is contained in:
Mark
2019-10-23 18:21:42 +03:00
parent 4067092423
commit 778eec2582
8 changed files with 62 additions and 11 deletions
+2
View File
@@ -220,6 +220,8 @@ struct ahci_command_table_entry {
#define AHCI_PORT_CMD_LIST(p) (struct ahci_command_header *) MM_VIRTUALIZE(((uintptr_t) (p)->p_clbu << 32) | ((p)->p_clb))
#define AHCI_CMD_TABLE_ENTRY(l, i) (struct ahci_command_table_entry *) MM_VIRTUALIZE(((uintptr_t) (l)[i].ctbau << 32) | ((l)[i].ctba))
int ahci_irq(void);
// TODO: accept block device instead of port registers
void ahci_sata_read(struct ahci_port_registers *port, void *buf, uint32_t nsect, uint64_t lba);
+2
View File
@@ -1,4 +1,5 @@
#pragma once
#include "sys/amd64/hw/pci/pci.h"
#include "sys/types.h"
#define IRQ_LEG_KEYBOARD 1
@@ -8,6 +9,7 @@ typedef int (*irq_handler_t) (void);
int irq_add_handler(uint8_t gsi, irq_handler_t handler);
int irq_add_leg_handler(uint8_t leg_irq, irq_handler_t handler);
int irq_add_pci_handler(pci_addr_t addr, uint8_t pin, irq_handler_t handler);
void irq_enable_ioapic_mode(void);
void irq_init(void);
-6
View File
@@ -117,8 +117,6 @@ void amd64_acpi_smp(struct acpi_madt *madt) {
offset += ent_hdr->length;
}
amd64_smp_init();
}
#endif
@@ -173,8 +171,4 @@ void amd64_apic_init(void) {
#endif
amd64_timer_init();
extern mm_space_t mm_kernel;
// Initialization finished, can unmap 0 -> 0 mapping now
mm_kernel[0] = 0;
}
+29
View File
@@ -22,6 +22,29 @@ static int ahci_alloc_cmd(struct ahci_port_registers *port) {
return -1;
}
struct ahci_registers *controller0 = NULL;
static void ahci_irq_port(struct ahci_port_registers *port) {
if (port->p_is & (1 << 0)) {
// TODO: integrate this with reading code
}
port->p_is = 0;
}
int ahci_irq(void) {
if (controller0->is) {
for (size_t port = 0; port < 32; ++port) {
ahci_irq_port(&controller0->ports[port]);
controller0->is &= ~(1 << port);
}
return 0;
}
return -1;
}
void ahci_sata_read(struct ahci_port_registers *port, void *buf, uint32_t nsect, uint64_t lba) {
port->p_is = -1;
@@ -227,6 +250,9 @@ void ahci_port_init(uint8_t n, struct ahci_port_registers *port) {
case AHCI_PORT_SIG_SATA:
ahci_sata_port_init(port);
ahci_sata_port_identify(port);
// Enable IRQs
port->p_ie |= (1 << 0);
break;
default:
kdebug("Skipping unknown drive type\n");
@@ -272,4 +298,7 @@ void ahci_init(struct ahci_registers *regs) {
ahci_port_init(i, port);
}
}
// Enable HBA interrupts
regs->ghc |= 1 << 1;
}
-2
View File
@@ -284,8 +284,6 @@ int ide_ata_read_pio(struct ide_device *dev, void *buf, size_t nsect, uint64_t l
return 0;
}
static char test_buf[65536 * 2] __attribute__((aligned(65536)));
void ide_init(struct ide_controller *ide) {
// Initialize from PCI IDE information: BARs
ide->channels[0].base = ide->bar0;
+15 -1
View File
@@ -7,7 +7,7 @@
#include "sys/panic.h"
#include "sys/debug.h"
#define IRQ_MAX 16 // Maximum assignable IRQ vectors
#define IRQ_MAX 32 // Maximum assignable IRQ vectors
#define IRQ_MAX_HANDLERS 4 // Maximum handlers per IRQ vector (sharing)
static irq_handler_t handlers[IRQ_MAX * IRQ_MAX_HANDLERS] = {0};
@@ -87,6 +87,20 @@ int irq_add_leg_handler(uint8_t leg_irq, irq_handler_t handler) {
}
}
int irq_add_pci_handler(pci_addr_t addr, uint8_t pin, irq_handler_t handler) {
_assert(pin < 4);
uint32_t irq_route = amd64_pci_pin_irq_route(PCI_BUS(addr), PCI_DEV(addr), PCI_FUNC(addr), pin);
_assert(irq_route != PCI_IRQ_INVALID);
if (irq_route == PCI_IRQ_NO_ROUTE) {
panic("TODO: allocate PCI IRQ routes\n");
}
kdebug("Assigning handler to " PCI_FMTADDR " INT%c# -> GSI%d", PCI_VAADDR(addr), pin + 'A', irq_route);
return irq_add_handler(irq_route, handler);
}
void irq_enable_ioapic_mode(void) {
ioapic_available = 1;
// Copy current table
+8
View File
@@ -1,6 +1,7 @@
#include "sys/amd64/hw/pci/ahci.h"
#include "sys/amd64/hw/ide/ahci.h"
#include "sys/amd64/hw/ide/ata.h"
#include "sys/amd64/hw/irq.h"
#include "sys/amd64/mm/phys.h"
#include "sys/assert.h"
#include "sys/string.h"
@@ -13,6 +14,8 @@ static struct pci_ahci ahci;
void pci_ahci_init(pci_addr_t addr) {
kdebug("Initializing AHCI controller at " PCI_FMTADDR "\n", PCI_VAADDR(addr));
uint32_t irq = pci_config_read_dword(addr, 0x3C);
ahci.addr = addr;
ahci.abar_phys = pci_config_read_dword(addr, 0x24);
ahci.regs = (struct ahci_registers *) MM_VIRTUALIZE(ahci.abar_phys);
@@ -20,4 +23,9 @@ void pci_ahci_init(pci_addr_t addr) {
kdebug("AHCI registers: %p\n", ahci.regs);
ahci_init(ahci.regs);
uint8_t int_pin = ((irq >> 8) & 0xFF);
if (int_pin) {
irq_add_pci_handler(addr, int_pin - 1, ahci_irq);
}
}
+6 -2
View File
@@ -4,6 +4,7 @@
#include "sys/amd64/syscall.h"
#include "sys/amd64/hw/idt.h"
#include "sys/amd64/mm/mm.h"
#include "sys/amd64/smp/smp.h"
#include "sys/amd64/mm/phys.h"
#include "sys/amd64/hw/acpi.h"
#include "sys/amd64/hw/apic.h"
@@ -31,11 +32,14 @@ void kernel_main(struct amd64_loader_data *data) {
amd64_mm_init(data);
amd64_acpi_init();
pci_init();
extern void sched_init(void);
sched_init();
amd64_apic_init();
pci_init();
#if defined(AMD64_SMP)
amd64_smp_init();
#endif
amd64_syscall_init();