3.4 KiB
GSI subsystem
Introduction
This subsystem is responsible for registering all the interrupts sources overrides (ISO) and providing an abstraction to manipulate all the GSI lines and legacy IRQs.
ISOs registering
The subsystem can be initialized using sh_gsi_iso_array_init(). This allocate an array of 256 sh_gsi_ISO in which all the ISOs will be stored.
The ISO struct is the following:
typedef struct {
sh_uint32 gsi;
sh_bool valid;
sh_uint8 source_irq;
enum sh_gsi_POLARITY polarity;
enum sh_gsi_TRIGGER_MODE trigger_mode;
sh_uint8 bus;
} sh_gsi_ISO;
Any sh_gsi_ISO without the valid boolean to SH_TRUE should be considered as not occupied in the array.
The sh_gsi_POLARITY enum can take the following values:
enum sh_gsi_POLARITY {
SH_GSI_POLARITY_NOT_SET=0,
SH_GSI_POLARITY_BUS_DEFAULT,
SH_GSI_POLARITY_ACTIVE_HIGH,
SH_GSI_POLARITY_ACTIVE_LOW
};
The sh_gsi_TRIGGER_MODE enum can take the following values:
enum sh_gsi_TRIGGER_MODE {
SH_GSI_TRIGGER_MODE_NOT_SET=0,
SH_GSI_TRIGGER_MODE_BUS_DEFAULT,
SH_GSI_TRIGGER_MODE_EDGE,
SH_GSI_TRIGGER_MODE_LEVEL
};
Bus defaults are resolved when configuring the IOREDTBL of each IOAPIC.
During the MADT table parsing, ISOs are registered using the sh_gsi_iso_register(sh_uint8 bus,sh_uint8 source,sh_uint32 gsi,sh_uint16 flags) function, which expects the arguments as they are parsed in the MADT table.
Two functions can be used to search for ISOs:
sh_gsi_get_iso_by_irq(sh_uint8 irq): return a*sh_gsi_ISOwith the provided legacy IRQ number. ReturnSH_NULLPTRif not found or errorsh_gsi_get_iso_by_gsi(sh_uint32 gsi): return a*sh_gsi_ISOwith the provided GSI number. ReturnSH_NULLPTRif not found or error
IOAPIC abstraction
The GSI subsystem provides an abstraction to manipulate IOREDTBL entries based on the GSI or legacy IRQ number without interacting directly with the IOAPIC subsystem. The following functions are provided:
sh_gsi_get(sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry): return the IOREDTBL entry corresponding to the provided GSIsh_gsi_set(sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry): set the IOREDTBL entry corresponding to the provided GSI with the provided entry. Automatically mask the IOREDTBL entry before writing the entrysh_gsi_irq_set(sh_uint8 irq,sh_ioapic_IOREDTBL_ENTRY *entry): do the same assh_gsi_set()but retrieves the original GSI before hand, taking into account registered ISOssh_gsi_mask(sh_uint32 gsi): mask the IOREDTBL entry corresponding to the provided GSIsh_gsi_unmask(sh_uint32 gsi): unmask the IOREDTBL entry corresponding to the provided GSIsh_gsi_irq_mask(sh_uint8 irq): do the same assh_gsi_mask()but retrieves the original GSI before hand, taking into account registered ISOssh_gsi_irq_unmask(sh_uint8 irq): do the same assh_gsi_unmask()but retrieves the original GSI before hand, taking into account registered ISOs
Legacy IRQs switch
What we call the legacy IRQs switch is the mapping of all the legacy IRQs to interrupt vectors 32 to 47, exactly like the PIT, and the transfer of legacy IRQs management from the PIT to the IOAPIC.
It's operated by sh_gsi_irq_switch(). This is the only function that is allowed to call sh_irq_switch_irq_management(). By default, all the IOREDTBL entries corresponding to the GSI lines used by all legacy IRQs will be mask.