# IOAPIC devices

This driver is defined inside `shelter/lib/include/devs/apic/ioapic.h` and implemented inside `shelter/lib/src/devs/apic/ioapic.c`.

## Driver initialization

During the MADT parsing, all IOAPIC entries are counted. Then, a call to `sh_ioapic_init_devs(sh_uint8 max_lapic_id)` is made to initialize the driver internal state. This call allocates an array indexed by IOAPIC id.

## Device initialization

After that, each time a IOAPIC entry is parsed, a call to `sh_ioapic_init(sh_uint32 base,sh_uint8 ioapic_id,sh_uint32 gsi_base,sh_ioapic_DEVICE *ioapic)` is made. This does three things:
1) Identity map the memory space for the LAPIC
2) Fill the structure for the LAPIC device
3) Initialize the device without modifying the IOREDTBL for the moment

Then, a call to `sh_ioapic_bind(sh_ioapic_DEVICE *ioapic_dev)` is made, registering the LAPIC structure in the array.

## Basic IOAPIC management

For basic IOAPIC management, the following function are provided:
- `sh_ioapic_get_dev_ioapic_id(sh_uint64 ioapic_id)`: return a `sh_ioapic_DEVICE*` pointing to the IOAPIC structure corresponding to the provided IOAPIC id
- `sh_ioapic_get_dev_by_gsi(sh_uint32 gsi)`: return a `sh_ioapic_DEVICE*` pointing to the IOAPIC structure of the IOAPIC that manages the provided GSI
- `sh_ioapic_read_ioredtbl_entry(sh_ioapic_DEVICE *ioapic_dev,sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry)`: read a IOREDTBL entry and put its value into `entry`. If the GSI isn't managed by the provided device, raise an error
- `sh_ioapic_write_ioredtbl_entry(sh_ioapic_DEVICE *ioapic_dev,sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry)`: write and IOREDTBL entry corresponding to the provided GSI. If the GSI isn't managed by the provided device, raise an error

IOREDTBL read and write are thread-safe operations.

## Higher level operations

The following higher level operations are provided:
- `sh_ioapic_mask_gsi(sh_ioapic_DEVICE *dev,sh_uint32 gsi)`: mask the provided GSI. If the GSI isn't managed by the provided device, raise an error
- `sh_ioapic_unmask_gsi(sh_ioapic_DEVICE *dev,sh_uint32 gsi)`: unmask the provided GSI. If the GSI isn't managed by the provided device, raise an error
- `sh_ioapic_mask_all()`: mask all the GSI for all registered IOAPIC.

If you are looking for an even more abstracted API, please check the GSI subsystem.
