PatchworkOS  dbbdc99
A non-POSIX operating system.
Loading...
Searching...
No Matches
ioapic.c
Go to the documentation of this file.
3
4#include <kernel/cpu/cpu.h>
5#include <kernel/cpu/irq.h>
6#include <kernel/log/log.h>
7#include <kernel/mem/vmm.h>
10
11#include <assert.h>
12#include <sys/defs.h>
13
20
21static void ioapic_write(ioapic_t* ioapic, ioapic_register_t reg, uint32_t value)
22{
25 WRITE_32(base + IOAPIC_MMIO_REG_DATA, value);
26}
27
29{
30 ioapic_version_t version;
31 version.raw = ioapic_read(ioapic, IOAPIC_REG_VERSION);
32 return version;
33}
34
36{
37 assert(ioapic != NULL);
38 assert(gsi >= ioapic->globalSystemInterruptBase);
39 assert(gsi < ioapic->globalSystemInterruptBase + ioapic_version_read(ioapic).maxRedirs);
40
41 uint32_t pin = gsi - ioapic->globalSystemInterruptBase;
42 ioapic_write(ioapic, IOAPIC_REG_REDIRECTION_BASE + (pin * 2), entry.raw.low);
43 ioapic_write(ioapic, IOAPIC_REG_REDIRECTION_BASE + (pin * 2) + 1, entry.raw.high);
44}
45
47{
48 CLI_SCOPE();
49
50 ioapic_t* ioapic = irq->domain->data;
51
52 ioapic_redirect_entry_t redirect = {
53 .vector = irq->virt,
54 .deliveryMode = IOAPIC_DELIVERY_NORMAL,
55 .destinationMode = IOAPIC_DESTINATION_PHYSICAL,
56 .deliveryStatus = 0,
58 .remoteIRR = 0,
60 .mask = 0,
61 .destination = _pcpu_lapic->lapicId,
62 };
63
64 ioapic_redirect_write(ioapic, irq->phys, redirect);
65 return 0;
66}
67
68static void ioapic_disable(irq_t* irq)
69{
70 ioapic_t* ioapic = irq->domain->data;
71
72 ioapic_redirect_entry_t redirect = {.mask = 1};
73
74 ioapic_redirect_write(ioapic, irq->phys, redirect);
75}
76
77static void ioapic_eoi(irq_t* irq)
78{
79 UNUSED(irq);
80
82}
83
85 .name = "IO APIC",
86 .enable = ioapic_enable,
87 .disable = ioapic_disable,
88 .ack = NULL,
89 .eoi = ioapic_eoi,
90};
91
93{
95 if (madt == NULL)
96 {
97 LOG_ERR("no MADT table found\n");
98 return ERR;
99 }
100
101 ioapic_t* ioapic;
102 MADT_FOR_EACH(madt, ioapic)
103 {
105 {
106 continue;
107 }
108
109 void* virtAddr = (void*)PML_LOWER_TO_HIGHER(ioapic->ioApicAddress);
111 NULL) == NULL)
112 {
113 LOG_ERR("failed to map io apic\n");
114 return ERR;
115 }
116
117 uint32_t maxRedirs = ioapic_version_read(ioapic).maxRedirs;
118
119 LOG_INFO("found I/O APIC globalSystemInterruptBase=0x%02x maxRedirs=0x%02x\n",
120 ioapic->globalSystemInterruptBase, maxRedirs);
121
122 // Mask all interrupts.
123 for (uint32_t i = ioapic->globalSystemInterruptBase; i < ioapic->globalSystemInterruptBase + maxRedirs; i++)
124 {
125 ioapic_redirect_entry_t maskedEntry = {.mask = 1};
126 ioapic_redirect_write(ioapic, i, maskedEntry);
127 }
128
130 ioapic->globalSystemInterruptBase + maxRedirs, ioapic) == ERR)
131 {
132 LOG_ERR("failed to register io apic irq chip\n");
133 return ERR;
134 }
135 }
136
137 return 0;
138}
#define assert(expression)
Definition assert.h:29
sdt_header_t * acpi_tables_lookup(const char *signature, uint64_t minSize, uint64_t n)
Lookup the n'th table matching the signature.
Definition tables.c:259
#define MADT_FOR_EACH(madt, ic)
Iterate over all MADT interrupt controllers.
Definition tables.h:193
#define MADT_SIGNATURE
MADT table signature.
Definition tables.h:202
#define INTERRUPT_CONTROLLER_IO_APIC
Definition tables.h:122
#define CLI_SCOPE()
Macro to increment CLI depth for the duration of the current scope.
Definition cli.h:56
uint64_t irq_chip_register(irq_chip_t *chip, irq_phys_t start, irq_phys_t end, void *data)
Register an IRQ chip for a range of physical IRQs.
Definition irq.c:328
@ IRQ_TRIGGER_EDGE
If set, the IRQ is edge triggered. Otherwise, level triggered.
Definition irq.h:97
@ IRQ_POLARITY_LOW
If set, the IRQ is active low. Otherwise, active high.
Definition irq.h:95
ioapic_register_t
IO APIC Registers.
Definition ioapic.h:55
uint32_t ioapic_gsi_t
IO APIC Global System Interrupt type.
Definition ioapic.h:38
uint64_t ioapic_all_init(void)
Initialize all IO APICs found in the system.
Definition ioapic.c:92
@ IOAPIC_DELIVERY_NORMAL
Definition ioapic.h:68
@ IOAPIC_REG_VERSION
Definition ioapic.h:57
@ IOAPIC_REG_REDIRECTION_BASE
Definition ioapic.h:59
@ IOAPIC_POLARITY_LOW
Definition ioapic.h:103
@ IOAPIC_POLARITY_HIGH
Definition ioapic.h:102
@ IOAPIC_MMIO_REG_DATA
Definition ioapic.h:47
@ IOAPIC_MMIO_REG_SELECT
Definition ioapic.h:46
@ IOAPIC_TRIGGER_LEVEL
Definition ioapic.h:93
@ IOAPIC_TRIGGER_EDGE
Definition ioapic.h:92
@ IOAPIC_DESTINATION_PHYSICAL
Definition ioapic.h:82
lapic_t PERCPU _pcpu_lapic
The per-CPU local APIC structure.
void lapic_write(uint32_t reg, uint32_t value)
Write to a local apic register.
Definition lapic.c:42
@ LAPIC_REG_EOI
Definition lapic.h:57
#define LOG_ERR(format,...)
Definition log.h:93
#define LOG_INFO(format,...)
Definition log.h:91
#define PML_LOWER_TO_HIGHER(addr)
Converts an address from the lower half to the higher half.
@ PML_PRESENT
@ PML_WRITE
@ PML_GLOBAL
void * vmm_map(space_t *space, void *virtAddr, phys_addr_t physAddr, size_t length, pml_flags_t flags, space_callback_func_t func, void *data)
Maps physical memory to virtual memory in a given address space.
Definition vmm.c:226
#define UNUSED(x)
Mark a variable as unused.
Definition defs.h:96
#define NULL
Pointer error value.
Definition NULL.h:25
#define ERR
Integer error value.
Definition ERR.h:17
#define PAGE_SIZE
The size of a memory page in bytes.
Definition PAGE_SIZE.h:8
static irq_chip_t ioApicChip
Definition ioapic.c:84
static void ioapic_disable(irq_t *irq)
Definition ioapic.c:68
static ioapic_version_t ioapic_version_read(ioapic_t *ioapic)
Definition ioapic.c:28
static void ioapic_redirect_write(ioapic_t *ioapic, ioapic_gsi_t gsi, ioapic_redirect_entry_t entry)
Definition ioapic.c:35
static void ioapic_eoi(irq_t *irq)
Definition ioapic.c:77
static uint32_t ioapic_read(ioapic_t *ioapic, ioapic_register_t reg)
Definition ioapic.c:14
static uint64_t ioapic_enable(irq_t *irq)
Definition ioapic.c:46
static void ioapic_write(ioapic_t *ioapic, ioapic_register_t reg, uint32_t value)
Definition ioapic.c:21
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:43
interrupt_controller_type_t type
Definition tables.h:130
uint32_t high
Definition ioapic.h:149
uint32_t low
Definition ioapic.h:148
IO APIC.
Definition tables.h:165
uint32_t ioApicAddress
Definition tables.h:169
uint32_t globalSystemInterruptBase
Definition tables.h:170
interrupt_controller_header_t header
Definition tables.h:166
IO APIC Version Structure.
Definition ioapic.h:113
uint32_t raw
Definition ioapic.h:115
uint8_t maxRedirs
Definition ioapic.h:120
IRQ chip structure.
Definition irq.h:142
const char * name
Definition irq.h:143
void * data
Definition irq.h:130
IRQ structure.
Definition irq.h:109
irq_virt_t virt
Definition irq.h:111
irq_domain_t * domain
Definition irq.h:114
irq_phys_t phys
Definition irq.h:110
irq_flags_t flags
Definition irq.h:112
lapic_id_t lapicId
Definition lapic.h:127
Multiple APIC Description Table.
Definition tables.h:180
IO APIC Redirection Entry Structure.
Definition ioapic.h:132
struct ioapic_redirect_entry_t::PACKED raw
#define WRITE_32(address, value)
Definition utils.h:16
#define READ_32(address)
Definition utils.h:15