forked from lolo859/vystem
63 lines
2.7 KiB
C
63 lines
2.7 KiB
C
// SPDX-License-Identifier: MPL-2.0
|
|
#ifndef SH_LIB_GSI_H
|
|
#define SH_LIB_GSI_H
|
|
#include "std/stdlib.h"
|
|
#include "devs/apic/ioapic.h"
|
|
// GSI polarity enum
|
|
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
|
|
};
|
|
// GSI trigger mode enum
|
|
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
|
|
};
|
|
// Interrupt source override (ISO) structure
|
|
typedef struct {
|
|
sh_uint32 gsi;
|
|
// must default to SH_FALSE
|
|
sh_bool valid;
|
|
// when ISOs array is initialized, this field must default to 0
|
|
sh_uint8 source_irq;
|
|
// these two fields are determined by the flags field in the MADT entry. Bus-default value are resolved when writing IOREDTBL
|
|
enum sh_gsi_POLARITY polarity;
|
|
enum sh_gsi_TRIGGER_MODE trigger_mode;
|
|
// when ISOs array is initialized, this field must default to 0
|
|
sh_uint8 bus;
|
|
} sh_gsi_ISO;
|
|
// Initialize a 256 elements array of sh_gsi_ISO structs
|
|
SH_STATUS sh_gsi_iso_array_init();
|
|
// Register an ISO, this function is supposed to be used during MADT parsing when encountering an ISO. It expect the field as they are provided into the MADT entry
|
|
SH_STATUS sh_gsi_iso_register(sh_uint8 bus,sh_uint8 source,sh_uint32 gsi,sh_uint16 flags);
|
|
// Return an ISO structure for the given interrupt
|
|
sh_gsi_ISO *sh_gsi_get_iso_by_irq(sh_uint8 irq);
|
|
// Return an ISO structure for the given GSI
|
|
sh_gsi_ISO *sh_gsi_get_iso_by_gsi(sh_uint32 gsi);
|
|
// These two functions provide a thread-safe and "interrupt-storm" safe way to get and set IOREDTBL entries
|
|
// Read the IOREDTBL entry associated with the provided GSI
|
|
SH_STATUS sh_gsi_get(sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry);
|
|
// Set the provided GSI to the corresponding IOREDTBL entry, mask the IOOREDTBL entry and doesn't unmask it
|
|
SH_STATUS sh_gsi_set(sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry);
|
|
// Set the provided IRQ to IOREDTBL entry, calculate the expected GSI using sh_gsi_get_iso_by_irq
|
|
SH_STATUS sh_gsi_irq_set(sh_uint8 irq,sh_ioapic_IOREDTBL_ENTRY *entry);
|
|
// Mask the IOREDTBL entry corresponding to the provided GSI
|
|
inline SH_STATUS sh_gsi_mask(sh_uint32 gsi) {
|
|
return sh_ioapic_mask_gsi(sh_ioapic_get_dev_by_gsi(gsi),gsi);
|
|
}
|
|
// Unmask the IOREDTBL entry corresponding to the provided GSI
|
|
inline SH_STATUS sh_gsi_unmask(sh_uint32 gsi) {
|
|
return sh_ioapic_unmask_gsi(sh_ioapic_get_dev_by_gsi(gsi),gsi);
|
|
}
|
|
// Mask the IOREDTBL entry corresponding to the provided IRQ
|
|
SH_STATUS sh_gsi_irq_mask(sh_uint8 irq);
|
|
// Unmask the IOREDTBL entry corresponding to the provided IRQ
|
|
SH_STATUS sh_gsi_irq_unmask(sh_uint8 irq);
|
|
// Load all legacy IRQ to IOREDTBL entries, intented to be called only one time
|
|
SH_STATUS sh_gsi_irq_switch();
|
|
#endif
|