forked from lolo859/vystem
71 lines
3.3 KiB
C
71 lines
3.3 KiB
C
// SPDX-License-Identifier: MPL-2.0
|
|
#ifndef SH_LIB_IOAPIC_H
|
|
#define SH_LIB_IOAPIC_H
|
|
#include "std/stdlib.h"
|
|
#include "memory/page.h"
|
|
#define SH_IOAPIC_OFFSET_IOREGSEL 0x00
|
|
#define SH_IOAPIC_OFFSET_IOWIN 0x10
|
|
#define SH_IOAPIC_REGISTER_IOAPICID 0x00
|
|
#define SH_IOAPIC_REGISTER_IOAPICVER 0x01
|
|
#define SH_IOAPIC_REGISTER_IOAPICARB 0x02
|
|
#define SH_IOAPIC_REGISTER_IOREDTBL_BASE 0x10
|
|
// IOAPIC device structure
|
|
typedef struct {
|
|
volatile sh_uint32 *base;
|
|
sh_uint8 ioapic_id;
|
|
sh_uint32 gsi_base;
|
|
sh_uint32 gsi_count; // must be completed by reading the IOAPICVER register in the sh_ioapic_init call
|
|
sh_SPIN_LOCK lock;
|
|
} sh_ioapic_DEVICE;
|
|
// Initialize an IOAPIC device structure, intented to initialize all IOAPIC devices structures during MADT parsing
|
|
SH_STATUS sh_ioapic_init(sh_uint32 base,sh_uint8 ioapic_id,sh_uint32 gsi_base,sh_ioapic_DEVICE *ioapic);
|
|
// Initialize DevS IOAPIC backend (max_ioapic_id is the max IOAPIC id, not the number of IOAPIC counted)
|
|
SH_STATUS sh_ioapic_init_devs(sh_uint8 max_ioapic_id);
|
|
// Bind a LAPIC device to DevS LAPIC backend
|
|
SH_STATUS sh_ioapic_bind(sh_ioapic_DEVICE *lapic_dev);
|
|
// Return a pointer to an IOAPIC device based on the provided IOAPIC id
|
|
sh_ioapic_DEVICE *sh_ioapic_get_dev_ioapic_id(sh_uint64 ioapic_id);
|
|
#define SH_IOAPIC_IOREDTBL_DELIVERY_FIXED 0b000
|
|
#define SH_IOAPIC_IOREDTBL_DELIVERY_LOWEST_PRIORITY 0b001
|
|
#define SH_IOAPIC_IOREDTBL_DELIVERY_NMI 0b100
|
|
#define SH_IOAPIC_IOREDTBL_DELIVERY_INIT 0b101
|
|
#define SH_IOAPIC_IOREDTBL_DELIVERY_EXTINT 0b111
|
|
#define SH_IOAPIC_IOREDTBL_TRIGGER_EDGE 0b0
|
|
#define SH_IOAPIC_IOREDTBL_TRIGGER_LEVEL 0b1
|
|
#define SH_IOAPIC_IOREDTBL_POLARITY_HIGH 0b0
|
|
#define SH_IOAPIC_IOREDTBL_POLARITY_LOW 0b1
|
|
#define SH_IOAPIC_IOREDTBL_DEST_MODE_PHYSICAL 0b0
|
|
#define SH_IOAPIC_IOREDTBL_DEST_MODE_LOGICAL 0b1
|
|
// IOREDTBL entry structure
|
|
typedef struct {
|
|
sh_uint32 low;
|
|
sh_uint32 high;
|
|
} sh_ioapic_IOREDTBL_ENTRY;
|
|
// Create an IOREDTBL entry
|
|
inline sh_ioapic_IOREDTBL_ENTRY sh_ioapic_make_ioredtbl_entry(sh_uint8 vector,sh_uint8 delivery_mode,sh_uint8 destination_mode,sh_uint8 polarity,sh_uint8 trigger_mode,sh_bool mask,sh_uint8 apic_id) {
|
|
sh_ioapic_IOREDTBL_ENTRY e={0};
|
|
e.low=(e.low& ~0xFFU)|vector;
|
|
e.low=(e.low& ~(0x7U<<8))|((delivery_mode&0x7U)<<8);
|
|
e.low=(e.low& ~(1U<<11))|((destination_mode&0x1U)<<11);
|
|
e.low=(e.low& ~(1U<<13))|((polarity&0x1U)<<13);
|
|
e.low=(e.low& ~(1U<<15))|((trigger_mode&0x1U)<<15);
|
|
e.low=(e.low& ~(1U<<16))|((mask&0x1U)<<16);
|
|
e.high=(e.high& ~(0xFFU<<24))|((sh_uint32)apic_id<<24);
|
|
return e;
|
|
}
|
|
// Mask an IOREDTBL entry for the provided GSI
|
|
SH_STATUS sh_ioapic_mask_gsi(sh_ioapic_DEVICE *dev,sh_uint32 gsi);
|
|
// Unmask an IOREDTBL entry for the provided GSI
|
|
SH_STATUS sh_ioapic_unmask_gsi(sh_ioapic_DEVICE *dev,sh_uint32 gsi);
|
|
// Read an IOREDTBL entry for the provided GSI
|
|
SH_STATUS sh_ioapic_read_ioredtbl_entry(sh_ioapic_DEVICE *ioapic_dev,sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry);
|
|
// Write an IOREDTBL entry for the provided GSI
|
|
SH_STATUS sh_ioapic_write_ioredtbl_entry(sh_ioapic_DEVICE *ioapic_dev,sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry);
|
|
// Mask all IOREDTBL entries for all IOAPIC
|
|
SH_STATUS sh_ioapic_mask_all();
|
|
// Return the IOAPIC device corresponding to the provided GSI
|
|
sh_ioapic_DEVICE *sh_ioapic_get_dev_by_gsi(sh_uint32 gsi);
|
|
// Parse an IOAPIC DevS query
|
|
SH_STATUS sh_ioapic_devs_query(char *sub_path,sh_devs_RESULT *result);
|
|
#endif
|