1/* @title: I/O APIC */
2#pragma once
3#include <irq/irq.h>
4#include <stdbool.h>
5#include <stdint.h>
6#include <types/types.h>
7
8#define IOAPIC_REGSEL_INDEX 0 /* IOREGSEL index */
9#define IOAPIC_IOWIN_INDEX 4 /* IOWIN index */
10#define IOAPIC_MMIO_SIZE 0x20 /* 32 bytes */
11
12#define IOAPIC_REG_ID 0x00
13#define IOAPIC_REG_VER 0x01
14#define IOAPIC_REG_ARB 0x02
15#define IOAPIC_REG_REDTBL_BASE 0x10
16
17#define IOAPIC_REDTBL_REG_LOW(pin) \
18 ((uint8_t) (IOAPIC_REG_REDTBL_BASE + (pin) * 2))
19#define IOAPIC_REDTBL_REG_HIGH(pin) \
20 ((uint8_t) (IOAPIC_REG_REDTBL_BASE + (pin) * 2 + 1))
21
22#define IOAPIC_DELIVERY_FIXED 0
23#define IOAPIC_DELIVERY_LOWEST 1
24#define IOAPIC_DELIVERY_SMI 2
25#define IOAPIC_DELIVERY_NMI 4
26#define IOAPIC_DELIVERY_INIT 5
27#define IOAPIC_DELIVERY_EXTINT 7
28
29#define IOAPIC_DEST_PHYSICAL 0
30#define IOAPIC_DEST_LOGICAL 1
31
32#define IOAPIC_POLARITY_ACTIVE_HIGH 0
33#define IOAPIC_POLARITY_ACTIVE_LOW 1
34
35#define IOAPIC_TRIGGER_EDGE 0
36#define IOAPIC_TRIGGER_LEVEL 1
37
38#define IOAPIC_MASK_UNMASKED 0
39#define IOAPIC_MASK_MASKED 1
40#define IOAPIC_REDTBL_MASK (1u << 16)
41
42#define IOAPIC_ISO_POLARITY_MASK 0x03
43#define IOAPIC_ISO_POLARITY_ACTIVE_LOW 0x03
44#define IOAPIC_ISO_TRIGGER_MASK 0x0C
45#define IOAPIC_ISO_TRIGGER_LEVEL 0x0C
46
47struct ioapic_info {
48 uint8_t id;
49 uint32_t gsi_base;
50 uint32_t *mmio_base;
51};
52
53union ioapic_redirection_entry {
54 uint64_t raw;
55 struct __attribute__((packed)) {
56 uint8_t vector; // bits 0-7
57 uint8_t delivery_mode : 3; // bits 8-10
58 uint8_t dest_mode : 1; // bit 11
59 uint8_t delivery_status : 1; // bit 12 (read-only)
60 uint8_t polarity : 1; // bit 13
61 uint8_t remote_irr : 1; // bit 14 (read-only)
62 uint8_t trigger_mode : 1; // bit 15
63 uint8_t mask : 1; // bit 16
64 uint64_t reserved : 39; // bits 17-55
65 uint8_t dest_apic_id; // bits 56-63
66 };
67};
68
69void ioapic_init(void);
70void ioapic_write(uint8_t reg, uint32_t val);
71uint32_t ioapic_read(uint8_t reg);
72void ioapic_set_redirection_entry(int irq, uint64_t entry);
73uint64_t ioapic_get_redirection_entry(int irq);
74void ioapic_route_irq(irq_t irq, uint8_t vector, uint8_t dest_apic_id,
75 bool masked);
76void ioapic_mask_irq(irq_t irq);
77void ioapic_unmask_irq(irq_t irq);
78
79struct irq_chip *ioapic_get_chip(void);
80uint32_t ioapic_isa_to_gsi(uint8_t isa_irq);
81void ioapic_route_isa_irq(uint8_t isa_irq, uint8_t vector, uint8_t dest_apic_id,
82 bool masked);
83void ioapic_route_isa_nmi(uint8_t isa_irq, uint8_t dest_apic_id);
84