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