From 75fc078c96fc6136ec9313892a60815c5eb8013b Mon Sep 17 00:00:00 2001 From: Adam Greloch Date: Fri, 22 Nov 2024 15:55:44 +0100 Subject: [PATCH 1/5] hal/ia32: allow for pci device selection based on progif All USB UHCI/OHCI/EHCI/XHCI controllers have the same class:subclass 0c:03 and need to be differentiated based on progif (e.g. 0x20 for EHCI) JIRA: RTOS-937 --- hal/ia32/pci.c | 53 ++++++++++++++++++++++------------------ include/arch/ia32/ia32.h | 1 + 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/hal/ia32/pci.c b/hal/ia32/pci.c index 9de96ca7e..fa351d688 100644 --- a/hal/ia32/pci.c +++ b/hal/ia32/pci.c @@ -110,7 +110,7 @@ int hal_pciGetDevice(pci_id_t *id, pci_dev_t *dev, void *caps) { spinlock_ctx_t sc; unsigned char b, d, f, i; - u32 dv, cl, mask, val; + u32 val0, cl, progif, mask, valB, val2; int res = EOK; if ((id == NULL) || (dev == NULL)) @@ -122,57 +122,62 @@ int hal_pciGetDevice(pci_id_t *id, pci_dev_t *dev, void *caps) hal_spinlockSet(&pci_common.spinlock, &sc); do { - if ((dv = _hal_pciGet(b, d, f, 0)) == 0xffffffff) + if ((val0 = _hal_pciGet(b, d, f, 0)) == 0xffffffff) break; - if ((id->vendor != PCI_ANY) && (id->vendor != (dv & 0xffff))) + if ((id->vendor != PCI_ANY) && (id->vendor != (val0 & 0xffff))) break; - if ((id->device != PCI_ANY) && (id->device != (dv >> 16))) + if ((id->device != PCI_ANY) && (id->device != (val0 >> 16))) break; - cl = _hal_pciGet(b, d, f, 2) >> 16; + val2 = _hal_pciGet(b, d, f, 0x2); + + cl = val2 >> 16; + progif = (val2 >> 8) & 0xff; if ((id->cl != PCI_ANY) && (id->cl != cl)) break; - val = _hal_pciGet(b, d, f, 0xb); + if ((id->progif != PCI_ANY) && (id->progif != progif)) + break; + + valB = _hal_pciGet(b, d, f, 0xb); - if ((id->subdevice != PCI_ANY) && (id->subdevice != (val >> 16))) + if ((id->subdevice != PCI_ANY) && (id->subdevice != (valB >> 16))) break; - if ((id->subvendor != PCI_ANY) && (id->subvendor != (val & 0xffff))) + if ((id->subvendor != PCI_ANY) && (id->subvendor != (valB & 0xffff))) break; dev->bus = b; dev->dev = d; dev->func = f; - dev->vendor = dv & 0xffff; - dev->device = dv >> 16; + dev->vendor = val0 & 0xffff; + dev->device = val0 >> 16; dev->cl = cl; - dev->subvendor = val & 0xffff; - dev->subdevice = val >> 16; + dev->subvendor = valB & 0xffff; + dev->subdevice = valB >> 16; - dv = _hal_pciGet(b, d, f, 1); - dev->status = dv >> 16; - dev->command = dv & 0xffff; + val0 = _hal_pciGet(b, d, f, 0x1); + dev->status = val0 >> 16; + dev->command = val0 & 0xffff; - val = _hal_pciGet(b, d, f, 2); - dev->progif = (val >> 8) & 0xff; - dev->revision = val & 0xff; - dev->type = (_hal_pciGet(b, d, f, 3) >> 16) & 0xff; - dev->irq = _hal_pciGet(b, d, f, 15) & 0xff; + dev->progif = progif; + dev->revision = val2 & 0xff; + dev->type = (_hal_pciGet(b, d, f, 0x3) >> 16) & 0xff; + dev->irq = _hal_pciGet(b, d, f, 0xf) & 0xff; /* Get resources */ for (i = 0; i < 6; i++) { - dev->resources[i].base = _hal_pciGet(b, d, f, 4 + i); + dev->resources[i].base = _hal_pciGet(b, d, f, 0x4 + i); /* Get resource flags and size */ - _hal_pciSet(b, d, f, 4 + i, 0xffffffff); - dev->resources[i].limit = _hal_pciGet(b, d, f, 4 + i); + _hal_pciSet(b, d, f, 0x4 + i, 0xffffffff); + dev->resources[i].limit = _hal_pciGet(b, d, f, 0x4 + i); mask = (dev->resources[i].base & 0x1) ? ~0x3 : ~0xf; dev->resources[i].limit = (~(dev->resources[i].limit & mask)) + 1; - _hal_pciSet(b, d, f, 4 + i, dev->resources[i].base); + _hal_pciSet(b, d, f, 0x4 + i, dev->resources[i].base); dev->resources[i].flags = dev->resources[i].base & ~mask; dev->resources[i].base &= mask; } diff --git a/include/arch/ia32/ia32.h b/include/arch/ia32/ia32.h index 2f34833df..3ec0f13cc 100644 --- a/include/arch/ia32/ia32.h +++ b/include/arch/ia32/ia32.h @@ -27,6 +27,7 @@ typedef struct { unsigned short subvendor; unsigned short subdevice; unsigned short cl; + unsigned short progif; } __attribute__((packed)) pci_id_t; From 0601f4204e4eb5dcb07200a7a0a6ac377544eeb6 Mon Sep 17 00:00:00 2001 From: Adam Greloch Date: Mon, 25 Nov 2024 09:28:39 +0100 Subject: [PATCH 2/5] hal/ia32: add pctl_usbownership command JIRA: RTOS-937 --- hal/ia32/cpu.c | 4 ++++ hal/ia32/pci.c | 38 ++++++++++++++++++++++++++++++++++++++ hal/ia32/pci.h | 3 +++ include/arch/ia32/ia32.h | 15 ++++++++++----- 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/hal/ia32/cpu.c b/hal/ia32/cpu.c index f88c1328b..bbcc9ec02 100644 --- a/hal/ia32/cpu.c +++ b/hal/ia32/cpu.c @@ -557,6 +557,10 @@ int hal_platformctl(void *ptr) case pctl_busmaster: if (data->action == pctl_set) { return hal_pciSetBusmaster(&data->busmaster.dev, data->busmaster.enable); + + case pctl_usbownership: + if (data->action == pctl_set) { + return hal_pciSetUsbOwnership(&data->usbownership.dev, data->usbownership.eecp, data->usbownership.osOwned); } break; diff --git a/hal/ia32/pci.c b/hal/ia32/pci.c index fa351d688..0e396928b 100644 --- a/hal/ia32/pci.c +++ b/hal/ia32/pci.c @@ -106,6 +106,44 @@ int hal_pciSetBusmaster(pci_dev_t *dev, u8 enable) } +int hal_pciSetUsbOwnership(pci_dev_t *dev, u8 eecp, u8 osOwned) +{ + spinlock_ctx_t sc; + u32 dv; + u8 reg = eecp >> 2U; /* eecp is a pci config offset */ + + if (dev == NULL) { + return -EINVAL; + } + + hal_spinlockSet(&pci_common.spinlock, &sc); + dv = _hal_pciGet(dev->bus, dev->dev, dev->func, reg); + if (osOwned != 0) { + dv |= (1 << 24); + } + else { + dv &= ~(1 << 24); + } + _hal_pciSet(dev->bus, dev->dev, dev->func, reg, dv); + + for (;;) { + dv = _hal_pciGet(dev->bus, dev->dev, dev->func, reg); + if ((osOwned != 0) && ((dv & (1 << 24)) != 0) && ((dv & (1 << 16)) == 0)) { + break; + } + + if ((osOwned == 0) && ((dv & (1 << 24)) == 0) && ((dv & (1 << 16)) != 0)) { + break; + } + } + hal_spinlockClear(&pci_common.spinlock, &sc); + + dev->command = dv & 0xffff; + + return EOK; +} + + int hal_pciGetDevice(pci_id_t *id, pci_dev_t *dev, void *caps) { spinlock_ctx_t sc; diff --git a/hal/ia32/pci.h b/hal/ia32/pci.h index cb6f2b8db..3babbbe36 100644 --- a/hal/ia32/pci.h +++ b/hal/ia32/pci.h @@ -22,6 +22,9 @@ extern int hal_pciSetBusmaster(pci_dev_t *dev, u8 enable); +extern int hal_pciSetUsbOwnership(pci_dev_t *dev, u8 eecp, u8 enable); + + extern int hal_pciGetDevice(pci_id_t *id, pci_dev_t *dev, void *caps); diff --git a/include/arch/ia32/ia32.h b/include/arch/ia32/ia32.h index 3ec0f13cc..9af974c08 100644 --- a/include/arch/ia32/ia32.h +++ b/include/arch/ia32/ia32.h @@ -72,17 +72,18 @@ typedef struct { } __attribute__((packed)) pci_dev_t; -/* clang-format off */ typedef struct { + /* clang-format off */ enum { pctl_set = 0, pctl_get } action; - enum { pctl_pci = 0, pctl_busmaster, pctl_reboot, pctl_graphmode } type; + enum { pctl_pci = 0, pctl_busmaster, pctl_usbownership, pctl_reboot, pctl_graphmode } type; + /* clang-format on */ union { struct { pci_id_t id; pci_dev_t dev; - void* caps; + void *caps; } pci; struct { @@ -90,6 +91,12 @@ typedef struct { int enable; } busmaster; + struct { + pci_dev_t dev; + short osOwned; + short eecp; + } usbownership; + struct { unsigned int magic; unsigned int reason; @@ -105,7 +112,5 @@ typedef struct { }; } platformctl_t; -/* clang-format on */ - #endif From 0ff94d430186518c7be884ce2606a489eaab0b5e Mon Sep 17 00:00:00 2001 From: Adam Greloch Date: Mon, 25 Nov 2024 09:29:52 +0100 Subject: [PATCH 3/5] hal/ia32: add pctl_pcicfg command Allows for controlling the state of various pci device configuration registers JIRA: RTOS-937 --- hal/ia32/cpu.c | 6 ++++-- hal/ia32/pci.c | 34 +++++++++++++++++++++++++++------- hal/ia32/pci.h | 10 +++++----- include/arch/ia32/ia32.h | 15 ++++++++++----- 4 files changed, 46 insertions(+), 19 deletions(-) diff --git a/hal/ia32/cpu.c b/hal/ia32/cpu.c index bbcc9ec02..b8ce1b3da 100644 --- a/hal/ia32/cpu.c +++ b/hal/ia32/cpu.c @@ -554,9 +554,11 @@ int hal_platformctl(void *ptr) } break; - case pctl_busmaster: + case pctl_pcicfg: if (data->action == pctl_set) { - return hal_pciSetBusmaster(&data->busmaster.dev, data->busmaster.enable); + return hal_pciSetConfigOption(&data->pcicfg.dev, data->pcicfg.cfg, data->pcicfg.enable); + } + break; case pctl_usbownership: if (data->action == pctl_set) { diff --git a/hal/ia32/pci.c b/hal/ia32/pci.c index 0e396928b..3c80b8f07 100644 --- a/hal/ia32/pci.c +++ b/hal/ia32/pci.c @@ -5,8 +5,8 @@ * * PCI driver * - * Copyright 2018, 2019, 2020 Phoenix Systems - * Author: Aleksander Kaminski, Kamil Amanowicz, Lukasz Kosinski + * Copyright 2018, 2019, 2020, 2024 Phoenix Systems + * Author: Aleksander Kaminski, Kamil Amanowicz, Lukasz Kosinski, Adam Greloch * * This file is part of Phoenix-RTOS. * @@ -84,19 +84,24 @@ static int _hal_pciGetCaps(pci_dev_t *dev, void *caps) } -int hal_pciSetBusmaster(pci_dev_t *dev, u8 enable) +/* Sets a bit in PCI configuration command register */ +int _hal_pciSetCmdRegBit(pci_dev_t *dev, u8 bit, u8 enable) { spinlock_ctx_t sc; u32 dv; - if (dev == NULL) + if (dev == NULL) { return -EINVAL; + } hal_spinlockSet(&pci_common.spinlock, &sc); dv = _hal_pciGet(dev->bus, dev->dev, dev->func, 1); - dv &= ~(1 << 2); - if (enable) - dv |= (1 << 2); + if (enable != 0) { + dv |= (1 << bit); + } + else { + dv &= ~(1 << bit); + } _hal_pciSet(dev->bus, dev->dev, dev->func, 1, dv); hal_spinlockClear(&pci_common.spinlock, &sc); @@ -144,6 +149,21 @@ int hal_pciSetUsbOwnership(pci_dev_t *dev, u8 eecp, u8 osOwned) } +int hal_pciSetConfigOption(pci_dev_t *dev, pci_cfg_t cfg, u8 enable) +{ + switch (cfg) { + case pci_cfg_interruptdisable: + return _hal_pciSetCmdRegBit(dev, 10, enable); + case pci_cfg_memoryspace: + return _hal_pciSetCmdRegBit(dev, 1, enable); + case pci_cfg_busmaster: + return _hal_pciSetCmdRegBit(dev, 2, enable); + default: + return -EINVAL; + } +} + + int hal_pciGetDevice(pci_id_t *id, pci_dev_t *dev, void *caps) { spinlock_ctx_t sc; diff --git a/hal/ia32/pci.h b/hal/ia32/pci.h index 3babbbe36..67a63a5b6 100644 --- a/hal/ia32/pci.h +++ b/hal/ia32/pci.h @@ -5,8 +5,8 @@ * * PCI driver * - * Copyright 2019, 2020 Phoenix Systems - * Author: Kamil Amanowicz, Lukasz Kosinski + * Copyright 2019, 2020, 2024 Phoenix Systems + * Author: Kamil Amanowicz, Lukasz Kosinski, Adam Greloch * * This file is part of Phoenix-RTOS. * @@ -19,15 +19,15 @@ #include "include/arch/ia32/ia32.h" -extern int hal_pciSetBusmaster(pci_dev_t *dev, u8 enable); - - extern int hal_pciSetUsbOwnership(pci_dev_t *dev, u8 eecp, u8 enable); extern int hal_pciGetDevice(pci_id_t *id, pci_dev_t *dev, void *caps); +extern int hal_pciSetConfigOption(pci_dev_t *dev, pci_cfg_t option, u8 enable); + + extern void _hal_pciInit(void); diff --git a/include/arch/ia32/ia32.h b/include/arch/ia32/ia32.h index 9af974c08..34556f79a 100644 --- a/include/arch/ia32/ia32.h +++ b/include/arch/ia32/ia32.h @@ -5,8 +5,8 @@ * * IA32 basic peripherals control functions * - * Copyright 2018, 2019, 2020 Phoenix Systems - * Author: Aleksander Kaminski, Kamil Amanowicz, Lukasz Kosinski + * Copyright 2018, 2019, 2020, 2024 Phoenix Systems + * Author: Aleksander Kaminski, Kamil Amanowicz, Lukasz Kosinski, Adam Greloch * * This file is part of Phoenix-RTOS. * @@ -72,11 +72,15 @@ typedef struct { } __attribute__((packed)) pci_dev_t; +/* clang-format off */ +typedef enum { pci_cfg_interruptdisable, pci_cfg_memoryspace, pci_cfg_busmaster} pci_cfg_t; +/* clang-format on */ + typedef struct { /* clang-format off */ enum { pctl_set = 0, pctl_get } action; - enum { pctl_pci = 0, pctl_busmaster, pctl_usbownership, pctl_reboot, pctl_graphmode } type; + enum { pctl_pci = 0, pctl_pcicfg, pctl_usbownership, pctl_reboot, pctl_graphmode } type; /* clang-format on */ union { @@ -88,8 +92,9 @@ typedef struct { struct { pci_dev_t dev; - int enable; - } busmaster; + pci_cfg_t cfg; + short enable; + } pcicfg; struct { pci_dev_t dev; From 196cfdbea1d4f5f5c817be999536880a6496732f Mon Sep 17 00:00:00 2001 From: Adam Greloch Date: Mon, 9 Dec 2024 13:12:04 +0100 Subject: [PATCH 4/5] ia32: add rsdp address passing via platformctl JIRA: RTOS-990 --- hal/ia32/Makefile | 2 +- hal/ia32/acpi.c | 31 +++++++++++++++++++++++++++++++ hal/ia32/acpi.h | 23 +++++++++++++++++++++++ hal/ia32/cpu.c | 7 +++++++ include/arch/ia32/ia32.h | 9 ++++++++- include/arch/ia32/syspage.h | 1 + 6 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 hal/ia32/acpi.c create mode 100644 hal/ia32/acpi.h diff --git a/hal/ia32/Makefile b/hal/ia32/Makefile index 4ca7a85a5..25d211e94 100644 --- a/hal/ia32/Makefile +++ b/hal/ia32/Makefile @@ -7,7 +7,7 @@ include hal/tlb/Makefile -OBJS += $(addprefix $(PREFIX_O)hal/ia32/, _init.o _exceptions.o _interrupts.o spinlock.o exceptions.o interrupts.o cpu.o pmap.o timer.o hal.o string.o pci.o init.o) +OBJS += $(addprefix $(PREFIX_O)hal/ia32/, _init.o _exceptions.o _interrupts.o spinlock.o exceptions.o interrupts.o cpu.o pmap.o timer.o hal.o string.o pci.o init.o acpi.o) CFLAGS += -Ihal/ia32 ifeq ($(CONSOLE), vga) diff --git a/hal/ia32/acpi.c b/hal/ia32/acpi.c new file mode 100644 index 000000000..772ac3a98 --- /dev/null +++ b/hal/ia32/acpi.c @@ -0,0 +1,31 @@ +/* + * Phoenix-RTOS + * + * Operating system kernel + * + * ACPI kernel-userspace interface + * + * Copyright 2025 Phoenix Systems + * Author: Adam Greloch + * + * %LICENSE% + */ + +#include "include/errno.h" +#include "include/arch/ia32/ia32.h" +#include "halsyspage.h" + + +int hal_acpiGet(acpi_var_t var, int *value) +{ + switch (var) { + case acpi_rsdpAddr: + if (syspage->hs.acpi_version != ACPI_RSDP) { + return -EINVAL; + } + *value = syspage->hs.rsdp; + return EOK; + } + + return -EINVAL; +} diff --git a/hal/ia32/acpi.h b/hal/ia32/acpi.h new file mode 100644 index 000000000..99fbf56c0 --- /dev/null +++ b/hal/ia32/acpi.h @@ -0,0 +1,23 @@ +/* + * Phoenix-RTOS + * + * Operating system kernel + * + * ACPI kernel-userspace interface + * + * Copyright 2025 Phoenix Systems + * Author: Adam Greloch + * + * %LICENSE% + */ + +#ifndef _HAL_ACPI_H_ +#define _HAL_ACPI_H_ + +#include "include/arch/ia32/ia32.h" + + +extern int hal_acpiGet(acpi_var_t var, int *value); + + +#endif diff --git a/hal/ia32/cpu.c b/hal/ia32/cpu.c index b8ce1b3da..7a835421d 100644 --- a/hal/ia32/cpu.c +++ b/hal/ia32/cpu.c @@ -22,6 +22,7 @@ #include "hal/pmap.h" #include "hal/hal.h" #include "hal/tlb/tlb.h" +#include "acpi.h" #include "pci.h" #include "ia32.h" #include "halsyspage.h" @@ -548,6 +549,12 @@ int hal_platformctl(void *ptr) platformctl_t *data = (platformctl_t *)ptr; switch (data->type) { + case pctl_acpi: + if (data->action == pctl_get) { + return hal_acpiGet(data->acpi.var, &data->acpi.value); + } + break; + case pctl_pci: if (data->action == pctl_get) { return hal_pciGetDevice(&data->pci.id, &data->pci.dev, data->pci.caps); diff --git a/include/arch/ia32/ia32.h b/include/arch/ia32/ia32.h index 34556f79a..7e574983b 100644 --- a/include/arch/ia32/ia32.h +++ b/include/arch/ia32/ia32.h @@ -72,6 +72,8 @@ typedef struct { } __attribute__((packed)) pci_dev_t; +typedef enum { acpi_rsdpAddr = 0 } acpi_var_t; + /* clang-format off */ typedef enum { pci_cfg_interruptdisable, pci_cfg_memoryspace, pci_cfg_busmaster} pci_cfg_t; /* clang-format on */ @@ -80,10 +82,15 @@ typedef enum { pci_cfg_interruptdisable, pci_cfg_memoryspace, pci_cfg_busmaster} typedef struct { /* clang-format off */ enum { pctl_set = 0, pctl_get } action; - enum { pctl_pci = 0, pctl_pcicfg, pctl_usbownership, pctl_reboot, pctl_graphmode } type; + enum { pctl_pci = 0, pctl_acpi, pctl_pcicfg, pctl_usbownership, pctl_reboot, pctl_graphmode } type; /* clang-format on */ union { + struct { + acpi_var_t var; + int value; + } acpi; + struct { pci_id_t id; pci_dev_t dev; diff --git a/include/arch/ia32/syspage.h b/include/arch/ia32/syspage.h index e5b902d92..c06914c7a 100644 --- a/include/arch/ia32/syspage.h +++ b/include/arch/ia32/syspage.h @@ -38,6 +38,7 @@ typedef struct { unsigned int ebda; unsigned int acpi_version; + unsigned long rsdp; /* addr_t */ unsigned int localApicAddr; unsigned long madt; /* addr_t */ unsigned int madtLength; From 08122da790a5ac809f2465d590482309db6d502d Mon Sep 17 00:00:00 2001 From: Adam Greloch Date: Mon, 13 Jan 2025 11:01:53 +0100 Subject: [PATCH 5/5] hal/ia32: configure PCI interrupts when using IO APIC JIRA: RTOS-990 --- hal/ia32/_interrupts.S | 8 ++++++++ hal/ia32/interrupts.c | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/hal/ia32/_interrupts.S b/hal/ia32/_interrupts.S index e0d63de3f..505c9c6bc 100644 --- a/hal/ia32/_interrupts.S +++ b/hal/ia32/_interrupts.S @@ -179,6 +179,14 @@ INTERRUPT(_interrupts_irq12, 12, interrupts_dispatchIRQ) INTERRUPT(_interrupts_irq13, 13, interrupts_dispatchIRQ) INTERRUPT(_interrupts_irq14, 14, interrupts_dispatchIRQ) INTERRUPT(_interrupts_irq15, 15, interrupts_dispatchIRQ) +INTERRUPT(_interrupts_irq16, 16, interrupts_dispatchIRQ) +INTERRUPT(_interrupts_irq17, 17, interrupts_dispatchIRQ) +INTERRUPT(_interrupts_irq18, 18, interrupts_dispatchIRQ) +INTERRUPT(_interrupts_irq19, 19, interrupts_dispatchIRQ) +INTERRUPT(_interrupts_irq20, 20, interrupts_dispatchIRQ) +INTERRUPT(_interrupts_irq21, 21, interrupts_dispatchIRQ) +INTERRUPT(_interrupts_irq22, 22, interrupts_dispatchIRQ) +INTERRUPT(_interrupts_irq23, 23, interrupts_dispatchIRQ) INTERRUPT(_interrupts_unexpected, 255, _interrupts_unexpected) diff --git a/hal/ia32/interrupts.c b/hal/ia32/interrupts.c index d52d3be44..d79177fa3 100644 --- a/hal/ia32/interrupts.c +++ b/hal/ia32/interrupts.c @@ -46,6 +46,14 @@ extern void _interrupts_irq12(void); extern void _interrupts_irq13(void); extern void _interrupts_irq14(void); extern void _interrupts_irq15(void); +extern void _interrupts_irq16(void); +extern void _interrupts_irq17(void); +extern void _interrupts_irq18(void); +extern void _interrupts_irq19(void); +extern void _interrupts_irq20(void); +extern void _interrupts_irq21(void); +extern void _interrupts_irq22(void); +extern void _interrupts_irq23(void); extern void _interrupts_unexpected(void); @@ -55,7 +63,8 @@ extern void _interrupts_syscall(void); extern void _interrupts_TLBShootdown(void); -#define SIZE_INTERRUPTS 16 +#define ISA_INTERRUPTS 16 +#define SIZE_INTERRUPTS 24 struct { @@ -209,6 +218,20 @@ int interrupts_dispatchIRQ(unsigned int n, cpu_context_t *ctx) } +static inline void _hal_ioapicUnmaskPCI(unsigned int n) +{ + u32 high, low; + + _hal_ioapicReadIRQ(interrupts_common.irqs[n].ioapic, n, &high, &low); + + if ((low & IOAPIC_IRQ_MASK) != 0) { + /* PCI interrupts are active low level triggered */ + low |= (IOAPIC_INTPOL | IOAPIC_TRIGGER); + _hal_ioapicWriteIRQ(interrupts_common.irqs[n].ioapic, n, high, low & ~IOAPIC_IRQ_MASK); + } +} + + int hal_interruptsSetHandler(intr_handler_t *h) { spinlock_ctx_t sc; @@ -219,6 +242,10 @@ int hal_interruptsSetHandler(intr_handler_t *h) hal_spinlockSet(&interrupts_common.interrupts[h->n].spinlock, &sc); HAL_LIST_ADD(&interrupts_common.interrupts[h->n].handler, h); + if (h->n >= ISA_INTERRUPTS) { + /* Assume IRQs above ISA_INTERRUPTS are PCI interrupts */ + _hal_ioapicUnmaskPCI(h->n); + } hal_spinlockClear(&interrupts_common.interrupts[h->n].spinlock, &sc); return EOK; @@ -429,8 +456,8 @@ static int _hal_ioapicInit(void) } } - /* Enable all IRQS */ - for (i = 0; i < SIZE_INTERRUPTS; ++i) { + /* Enable all ISA IRQs */ + for (i = 0; i < ISA_INTERRUPTS; ++i) { _hal_ioapicReadIRQ(interrupts_common.irqs[i].ioapic, i, &high, &low); _hal_ioapicWriteIRQ(interrupts_common.irqs[i].ioapic, i, high, low & ~IOAPIC_IRQ_MASK); } @@ -480,6 +507,14 @@ void _hal_interruptsInit(void) _interrupts_setIDTEntry(INTERRUPTS_VECTOR_OFFSET + 13, _interrupts_irq13, flags); _interrupts_setIDTEntry(INTERRUPTS_VECTOR_OFFSET + 14, _interrupts_irq14, flags); _interrupts_setIDTEntry(INTERRUPTS_VECTOR_OFFSET + 15, _interrupts_irq15, flags); + _interrupts_setIDTEntry(INTERRUPTS_VECTOR_OFFSET + 16, _interrupts_irq16, flags); + _interrupts_setIDTEntry(INTERRUPTS_VECTOR_OFFSET + 17, _interrupts_irq17, flags); + _interrupts_setIDTEntry(INTERRUPTS_VECTOR_OFFSET + 18, _interrupts_irq18, flags); + _interrupts_setIDTEntry(INTERRUPTS_VECTOR_OFFSET + 19, _interrupts_irq19, flags); + _interrupts_setIDTEntry(INTERRUPTS_VECTOR_OFFSET + 20, _interrupts_irq20, flags); + _interrupts_setIDTEntry(INTERRUPTS_VECTOR_OFFSET + 21, _interrupts_irq21, flags); + _interrupts_setIDTEntry(INTERRUPTS_VECTOR_OFFSET + 22, _interrupts_irq22, flags); + _interrupts_setIDTEntry(INTERRUPTS_VECTOR_OFFSET + 23, _interrupts_irq23, flags); for (k = 0; k < SIZE_INTERRUPTS; k++) { hal_spinlockCreate(&interrupts_common.interrupts[k].spinlock, "interrupts_common.interrupts[].spinlock");