|
PatchworkOS
|
Advanced Programmable Interrupt Controller. More...
Data Structures | |
| struct | ioapic_version_t |
| IO APIC Version Structure. More... | |
| struct | ioapic_redirect_entry_t |
| IO APIC Redirection Entry Structure. More... | |
Macros | |
| #define | LAPIC_REG_ICR1_ID_OFFSET 24 |
| The offset at which the lapic id is stored in the LAPIC_REG_ID register. | |
| #define | IOAPIC_REG_REDIRECTION(pin, high) (0x10 + (pin) * 2 + (high)) |
| Macro to get the redirection entry register for a specific pin. | |
| #define | APIC_TIMER_TICKS_FIXED_POINT_OFFSET 32 |
| APIC Timer Ticks Fixed Point Offset. | |
Typedefs | |
| typedef uint8_t | lapic_id_t |
| Local APIC ID type. | |
| typedef uint32_t | ioapic_gsi_t |
| IO APIC Global System Interrupt type. | |
Functions | |
| void | apic_timer_one_shot (interrupt_t vector, uint32_t ticks) |
| Configure the apic timer in one-shot mode. | |
| uint64_t | apic_timer_ticks_per_ns (void) |
| Apic timer ticks per nanosecond. | |
| void | lapic_cpu_init (void) |
| Initialize the local apic for the current cpu. | |
| lapic_id_t | lapic_self_id (void) |
| Get the lapic id of the current cpu. | |
| void | lapic_write (lapic_register_t reg, uint32_t value) |
| Write to a local apic register. | |
| uint32_t | lapic_read (lapic_register_t reg) |
| Read from a local apic register. | |
| void | lapic_send_init (lapic_id_t id) |
| Send an INIT IPI to a local apic. | |
| void | lapic_send_sipi (lapic_id_t id, void *entryPoint) |
| Send a Startup IPI to a local apic. | |
| void | lapic_send_ipi (lapic_id_t id, interrupt_t vector) |
| Send an Inter-Processor Interrupt (IPI) to a local apic. | |
| void | lapic_eoi (void) |
| Send an End Of Interrupt (EOI) signal to the local apic. | |
| uint32_t | ioapic_read (ioapic_t *ioapic, ioapic_register_t reg) |
| Read from an IOAPIC register. | |
| void | ioapic_write (ioapic_t *ioapic, ioapic_register_t reg, uint32_t value) |
| Write to an IOAPIC register. | |
| ioapic_version_t | ioapic_get_version (ioapic_t *ioapic) |
| Get the IOAPIC version. | |
| ioapic_t * | ioapic_from_gsi (ioapic_gsi_t gsi) |
| Get the IOAPIC id responsible for a given GSI. | |
| void | ioapic_set_redirect (interrupt_t vector, ioapic_gsi_t gsi, ioapic_delivery_mode_t deliveryMode, ioapic_polarity_t polarity, ioapic_trigger_mode_t triggerMode, cpu_t *cpu, bool enable) |
| Set an IOAPIC redirection entry. | |
Advanced Programmable Interrupt Controller.
| #define APIC_TIMER_TICKS_FIXED_POINT_OFFSET 32 |
| #define IOAPIC_REG_REDIRECTION | ( | pin, | |
| high | |||
| ) | (0x10 + (pin) * 2 + (high)) |
Macro to get the redirection entry register for a specific pin.
This is used since a redirect entry is 64 bits (a qword/two dwords) and each register is 32 bits (a dword), so each pin uses two registers.
| pin | The pin number as in the gsi - the ioapics base gsi. |
| high | 0 for the low dword, 1 for the high dword. |
| #define LAPIC_REG_ICR1_ID_OFFSET 24 |
| typedef uint32_t ioapic_gsi_t |
| typedef uint8_t lapic_id_t |
| enum apic_timer_divider_t |
| enum apic_timer_mode_t |
| enum ioapic_polarity_t |
| enum ioapic_register_t |
| enum lapic_flags_t |
| enum lapic_icr_flags_t |
| enum lapic_msr_flags_t |
| enum lapic_register_t |
Local APIC Registers.
| void apic_timer_one_shot | ( | interrupt_t | vector, |
| uint32_t | ticks | ||
| ) |
Configure the apic timer in one-shot mode.
Cnfigures the apic timer on the caller cpu to fire a single interrupt after the specified amount of ticks.
| vector | The interrupt vector to fire when the timer expires. |
| ticks | The amount of ticks to wait before firing the interrupt. |
Definition at line 105 of file apic.c.
References APIC_TIMER_DIV_DEFAULT, APIC_TIMER_MASKED, APIC_TIMER_ONE_SHOT, initialized, LAPIC_REG_LVT_TIMER, LAPIC_REG_TIMER_DIVIDER, LAPIC_REG_TIMER_INITIAL_COUNT, lapic_write(), NULL, and panic().
Referenced by timer_one_shot().
| uint64_t apic_timer_ticks_per_ns | ( | void | ) |
Apic timer ticks per nanosecond.
Retrieves the ticks that occur every nanosecond in the apic timer on the caller cpu. Due to the fact that this amount of ticks is very small, most likely less then 1, we used fixed point arithmetic to store the result, the offset used for this is APIC_TIMER_TICKS_FIXED_POINT_OFFSET.
Definition at line 119 of file apic.c.
References APIC_TIMER_DIV_DEFAULT, APIC_TIMER_MASKED, APIC_TIMER_TICKS_FIXED_POINT_OFFSET, CLOCKS_PER_SEC, hpet_wait(), initialized, interrupt_disable(), interrupt_enable(), lapic_read(), LAPIC_REG_LVT_TIMER, LAPIC_REG_TIMER_CURRENT_COUNT, LAPIC_REG_TIMER_DIVIDER, LAPIC_REG_TIMER_INITIAL_COUNT, lapic_write(), LOG_DEBUG, NULL, panic(), and UINT32_MAX.
Referenced by timer_ctx_init().
| ioapic_t * ioapic_from_gsi | ( | ioapic_gsi_t | gsi | ) |
Get the IOAPIC id responsible for a given GSI.
| gsi | The GSI to get the IOAPIC id for. |
Definition at line 282 of file apic.c.
References ioapic_t::globalSystemInterruptBase, ioapic_t::header, initialized, INTERRUPT_CONTROLLER_IO_APIC, ioapic_get_version(), madt, MADT_FOR_EACH, ioapic_version_t::maxRedirs, NULL, panic(), and interrupt_controller_header_t::type.
Referenced by ioapic_set_redirect().
| ioapic_version_t ioapic_get_version | ( | ioapic_t * | ioapic | ) |
Get the IOAPIC version.
| ioapic | The IOAPIC to get the version for. |
Definition at line 270 of file apic.c.
References initialized, ioapic_read(), IOAPIC_REG_VERSION, NULL, panic(), and ioapic_version_t::raw.
Referenced by ioapic_all_init(), and ioapic_from_gsi().
| uint32_t ioapic_read | ( | ioapic_t * | ioapic, |
| ioapic_register_t | reg | ||
| ) |
Read from an IOAPIC register.
| ioapic | The IOAPIC to read from. |
| reg | The register to read. |
Definition at line 246 of file apic.c.
References initialized, IOAPIC_MMIO_REG_DATA, IOAPIC_MMIO_REG_SELECT, ioapic_t::ioApicAddress, NULL, panic(), PML_LOWER_TO_HIGHER, READ_32, and WRITE_32.
Referenced by ioapic_get_version().
| void ioapic_set_redirect | ( | interrupt_t | vector, |
| ioapic_gsi_t | gsi, | ||
| ioapic_delivery_mode_t | deliveryMode, | ||
| ioapic_polarity_t | polarity, | ||
| ioapic_trigger_mode_t | triggerMode, | ||
| cpu_t * | cpu, | ||
| bool | enable | ||
| ) |
Set an IOAPIC redirection entry.
When an interrupt is triggered on the given GSI, the IOAPIC will use the redirection entry to determine how and where to send the interrupt.
Say we recieve a GSI 1 interrupt (this would usually be a interrupt from the first ps/2 port), and we have a redirection entry which sends it to vector 0x21 (we usually want to avoid using vectors 0x00-0x20 as those are reserved for exceptions) to the CPU with id 0, the IOAPIC will then send an interrupt to CPU 0 with vector 0x21.
| vector | The interrupt vector to set. |
| gsi | The GSI to set the redirection for. |
| deliveryMode | The delivery mode to use. |
| polarity | The polarity to use. |
| triggerMode | The trigger mode to use. |
| cpu | The target cpu to send the interrupt to. |
| enable | Whether to enable or disable the redirection. |
Definition at line 307 of file apic.c.
References ioapic_t::globalSystemInterruptBase, ioapic_redirect_entry_t::PACKED::high, cpu_t::id, initialized, ioapic_from_gsi(), IOAPIC_REG_REDIRECTION, ioapic_write(), cpu_t::lapicId, LOG_INFO, ioapic_redirect_entry_t::PACKED::low, NULL, panic(), and ioapic_redirect_entry_t::raw.
Referenced by irq_install().
| void ioapic_write | ( | ioapic_t * | ioapic, |
| ioapic_register_t | reg, | ||
| uint32_t | value | ||
| ) |
Write to an IOAPIC register.
| ioapic | The IOAPIC to write to. |
| reg | The register to write. |
| value | The value to write. |
Definition at line 258 of file apic.c.
References initialized, IOAPIC_MMIO_REG_DATA, IOAPIC_MMIO_REG_SELECT, ioapic_t::ioApicAddress, NULL, panic(), PML_LOWER_TO_HIGHER, and WRITE_32.
Referenced by ioapic_all_init(), and ioapic_set_redirect().
| void lapic_cpu_init | ( | void | ) |
Initialize the local apic for the current cpu.
Definition at line 147 of file apic.c.
References APIC_TIMER_MASKED, initialized, LAPIC_LVT_MASKED, LAPIC_MSR_BSP, LAPIC_MSR_ENABLE, lapic_read(), LAPIC_REG_LVT_ERROR, LAPIC_REG_LVT_LINT0, LAPIC_REG_LVT_LINT1, LAPIC_REG_LVT_PERFCTR, LAPIC_REG_LVT_THERMAL, LAPIC_REG_LVT_TIMER, LAPIC_REG_SPURIOUS, LAPIC_REG_TASK_PRIORITY, lapic_self_id(), LAPIC_SPURIOUS_ENABLE, lapic_write(), LOG_INFO, MSR_LAPIC, msr_read(), msr_write(), NULL, panic(), and smp_self_unsafe().
Referenced by cpu_init().
| void lapic_eoi | ( | void | ) |
Send an End Of Interrupt (EOI) signal to the local apic.
Must be called after handling an interrupt to notify the local apic that the interrupt has been handled.
Definition at line 236 of file apic.c.
References initialized, LAPIC_REG_EOI, lapic_write(), NULL, and panic().
Referenced by interrupt_handler(), and irq_dispatch().
| uint32_t lapic_read | ( | lapic_register_t | reg | ) |
Read from a local apic register.
| reg | The register to read from. |
Definition at line 191 of file apic.c.
References initialized, lapicBase, NULL, panic(), and READ_32.
Referenced by apic_timer_ticks_per_ns(), lapic_cpu_init(), and lapic_self_id().
| lapic_id_t lapic_self_id | ( | void | ) |
Get the lapic id of the current cpu.
Definition at line 171 of file apic.c.
References initialized, lapic_read(), LAPIC_REG_ICR1_ID_OFFSET, LAPIC_REG_ID, NULL, and panic().
Referenced by cpu_init(), lapic_cpu_init(), smp_others_init(), and syscall_handler().
| void lapic_send_init | ( | lapic_id_t | id | ) |
Send an INIT IPI to a local apic.
Sending an INIT IPI will cause the target CPU to enter its initialization state which should be done before sending a SIPI.
| id | The lapic id to send the INIT IPI to. |
Definition at line 201 of file apic.c.
References initialized, LAPIC_ICR_INIT, LAPIC_REG_ICR0, LAPIC_REG_ICR1, LAPIC_REG_ICR1_ID_OFFSET, lapic_write(), NULL, and panic().
Referenced by trampoline_send_startup_ipi().
| void lapic_send_ipi | ( | lapic_id_t | id, |
| interrupt_t | vector | ||
| ) |
Send an Inter-Processor Interrupt (IPI) to a local apic.
The effect of sending an IPI is the same as if asm volatile("int <vector>") was executed on the target CPU.
| id | The lapic id to send the IPI to. |
| vector | The interrupt vector to send. |
Definition at line 225 of file apic.c.
References initialized, LAPIC_ICR_CLEAR_INIT_LEVEL, LAPIC_REG_ICR0, LAPIC_REG_ICR1, LAPIC_REG_ICR1_ID_OFFSET, lapic_write(), NULL, and panic().
Referenced by smp_halt_others(), space_tlb_shootdown(), syscall_handler(), and timer_notify().
| void lapic_send_sipi | ( | lapic_id_t | id, |
| void * | entryPoint | ||
| ) |
Send a Startup IPI to a local apic.
Sending a SIPI will cause the target CPU to start executing at the specified entry point, its important to give a small delay after sending an INIT IPI before sending the SIPI to give the hardware time to process the INIT.
| id | The lapic id to send the SIPI to. |
| entryPoint | The entry point to start executing at, must be page aligned. |
Definition at line 212 of file apic.c.
References assert, initialized, LAPIC_ICR_STARTUP, LAPIC_REG_ICR0, LAPIC_REG_ICR1, LAPIC_REG_ICR1_ID_OFFSET, lapic_write(), NULL, PAGE_SIZE, and panic().
Referenced by trampoline_send_startup_ipi().
| void lapic_write | ( | lapic_register_t | reg, |
| uint32_t | value | ||
| ) |
Write to a local apic register.
| reg | The register to write to. |
| value | The value to write. |
Definition at line 181 of file apic.c.
References initialized, lapicBase, NULL, panic(), and WRITE_32.
Referenced by apic_timer_one_shot(), apic_timer_ticks_per_ns(), lapic_cpu_init(), lapic_eoi(), lapic_send_init(), lapic_send_ipi(), and lapic_send_sipi().