Vystem 0.2
This commit is contained in:
70
shelter/lib/include/devs/apic/ioapic.h
Normal file
70
shelter/lib/include/devs/apic/ioapic.h
Normal file
@@ -0,0 +1,70 @@
|
||||
// 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
|
||||
83
shelter/lib/include/devs/apic/lapic.h
Normal file
83
shelter/lib/include/devs/apic/lapic.h
Normal file
@@ -0,0 +1,83 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
#ifndef SH_LIB_LAPIC_H
|
||||
#define SH_LIB_LAPIC_H
|
||||
#include "std/status.h"
|
||||
#include "std/type.h"
|
||||
#include "memory/page.h"
|
||||
#include "devs/devs.h"
|
||||
#define SH_LAPIC_OFFSET_ID 0x020
|
||||
#define SH_LAPIC_OFFSET_VERSION 0x030
|
||||
#define SH_LAPIC_OFFSET_EOI 0x0B0
|
||||
#define SH_LAPIC_OFFSET_SVR 0x0F0
|
||||
#define SH_LAPIC_OFFSET_ESR 0x280
|
||||
#define SH_LAPIC_OFFSET_ICR_LOW 0x300
|
||||
#define SH_LAPIC_OFFSET_ICR_HIGH 0x310
|
||||
#define SH_LAPIC_OFFSET_LVT_TIMER 0x320
|
||||
#define SH_LAPIC_OFFSET_LVT_ERROR 0x370
|
||||
#define SH_LAPIC_OFFSET_TIMER_INIT 0x380
|
||||
#define SH_LAPIC_OFFSET_TIMER_CURR 0x390
|
||||
#define SH_LAPIC_OFFSET_TIMER_DIV 0x3E0
|
||||
#define SH_LAPIC_TIMER_DIVIDER 0x3
|
||||
// LAPIC device structure
|
||||
typedef struct {
|
||||
volatile sh_uint32 *base;
|
||||
sh_uint8 apic_id;
|
||||
sh_uint8 acpi_processor_id;
|
||||
sh_uint32 flags;
|
||||
sh_uint32 spurious_vector;
|
||||
} sh_lapic_DEVICE;
|
||||
// Initialize a LAPIC device structure, intented to initialize all LAPIC devices structures during MADT parsing
|
||||
SH_STATUS sh_lapic_init(sh_uint64 lapic_phys,sh_uint8 spurious_vector,sh_uint8 apic_id,sh_uint8 apic_processor_id,sh_uint32 flags,sh_lapic_DEVICE *lapic);
|
||||
// Initialize LAPIC for this CPU, intended to be used once by each CPU
|
||||
SH_STATUS sh_lapic_init_dev(sh_uint8 spurious_vector,sh_lapic_DEVICE *lapic);
|
||||
// Initialize DevS LAPIC backend (max_lapic_id is the max LAPIC id, not the number of LAPIC counted)
|
||||
SH_STATUS sh_lapic_init_devs(sh_uint16 max_lapic_id,sh_uint16 max_acpi_processor_id);
|
||||
// Bind a LAPIC device to DevS LAPIC backend
|
||||
SH_STATUS sh_lapic_bind(sh_lapic_DEVICE *lapic_dev);
|
||||
// Write 0 in provided LAPIC device EOI register
|
||||
void sh_lapic_eoi(sh_lapic_DEVICE *lapic);
|
||||
// Return a pointer to a LAPIC device based on the provided APIC id
|
||||
sh_lapic_DEVICE *sh_lapic_get_dev_apic_id(sh_uint64 apic_id);
|
||||
// Return a pointer to a LAPIC device based on the provided ACPI processor id
|
||||
sh_lapic_DEVICE *sh_lapic_get_dev_acpi_cpu_id(sh_uint64 acpi_processor_id);
|
||||
// Launch a LAPIC one-shot timer, independantely of the calibrated state of the LAPIC
|
||||
SH_STATUS sh_lapic_timer_one_shot(sh_lapic_DEVICE *lapic_dev,sh_uint32 initial_value);
|
||||
// Calibrate the LAPIC frequency
|
||||
SH_STATUS sh_lapic_calibrate(sh_lapic_DEVICE *lapic_dev,sh_uint64 cpu_freq);
|
||||
// Return the LAPIC frequency
|
||||
sh_uint64 sh_lapic_get_frequency();
|
||||
// Launch a LAPIC one-shot timer, LAPIC frequency need to be set
|
||||
SH_STATUS sh_lapic_timer_one_shot_us(sh_lapic_DEVICE *lapic_dev,sh_uint64 microseconds_count);
|
||||
// Return LAPIC DevS array
|
||||
sh_lapic_DEVICE **sh_lapic_get_by_apic_id_array();
|
||||
// Return max LAPIC APIC id
|
||||
sh_uint64 sh_lapic_get_max_apic_id();
|
||||
// Return max ACPI processor id
|
||||
sh_uint64 sh_lapic_get_max_acpi_processor_id();
|
||||
// Return LAPIC count
|
||||
sh_uint64 sh_lapic_get_lapic_count();
|
||||
#define SH_LAPIC_IPI_TYPE_NMI 0b100
|
||||
#define SH_LAPIC_IPI_TYPE_INIT 0b101
|
||||
#define SH_LAPIC_IPI_TYPE_STARTUP 0b110
|
||||
#define SH_LAPIC_IPI_TYPE_FIXED 0b000
|
||||
#define SH_LAPIC_IPI_DESTINATION_SPECIFIC (0b00<<18)
|
||||
#define SH_LAPIC_IPI_DESTINATION_SELF (0b01<<18)
|
||||
#define SH_LAPIC_IPI_DESTINATION_ALL (0b10<<18)
|
||||
#define SH_LAPIC_IPI_DESTINATION_ALL_EXCLUDING_SELF (0b11<<18)
|
||||
#define SH_LAPIC_IPI_NO_DESTINATION (sh_int16)(-1)
|
||||
// Return SH_TRUE if LAPIC IPI feature is busy
|
||||
sh_bool sh_lapic_ipi_is_busy(sh_lapic_DEVICE *lapic_dev);
|
||||
// Return LAPIC id of current core, return -1 if error happened
|
||||
sh_int16 sh_lapic_get_current_core();
|
||||
// Send a fixed IPI with the specified vector. lapic_dev must be the struct of the current CPU.
|
||||
// If destination_mode!=SH_LAPIC_IPI_DESTINATION_SPECIFIC, target_lapic_id must be SH_LAPIC_IPI_NO_DESTINATION
|
||||
SH_STATUS sh_lapic_send_fixed_ipi(sh_lapic_DEVICE *lapic_dev,sh_uint8 vector,sh_uint32 destination_mode,sh_int16 target_lapic_id);
|
||||
// Send any IPI other than a fixed IPI to specified destination. lapic_dev must be the struct of the current CPU.
|
||||
// ipi_type must be either SH_LAPIC_IPI_TYPE_INIT, SH_LAPIC_IPI_TYPE_STARTUP or SH_LAPIC_IPI_TYPE_NMI
|
||||
// If ipi_type is SH_LAPIC_IPI_TYPE_STARTUP, start_address must contain the starting address. Address constraint (compatible with 16 bits mode) are checked.
|
||||
// If ipi_type isn't SH_LAPIC_IPI_TYPE_STARTUP, start_address must be zero.
|
||||
// If destination_mode!=SH_LAPIC_IPI_DESTINATION_SPECIFIC, target_lapic_id must be SH_LAPIC_IPI_NO_DESTINATION
|
||||
SH_STATUS sh_lapic_send_ipi(sh_lapic_DEVICE *lapic_dev,sh_uint32 ipi_type,sh_uint32 destination_mode,sh_int16 target_lapic_id,sh_page_PHYSICAL_ADDRESS start_address);
|
||||
// Parse a LAPIC DevS query
|
||||
SH_STATUS sh_lapic_devs_query(char *sub_path,sh_devs_RESULT *result);
|
||||
#endif
|
||||
Reference in New Issue
Block a user