PatchworkOS  da8a090
A non-POSIX operating system.
Loading...
Searching...
No Matches
lapic.c
Go to the documentation of this file.
2
3#include <kernel/cpu/cpu.h>
4#include <kernel/cpu/ipi.h>
5#include <kernel/cpu/irq.h>
6#include <kernel/log/log.h>
7#include <kernel/mem/vmm.h>
10
11#include <assert.h>
12#include <kernel/defs.h>
13
15
16static lapic_t lapics[CPU_MAX] = {[0 ... CPU_MAX - 1] = {.lapicId = -1, .ticksPerMs = 0}};
17
19{
20 return READ_32(lapicBase + reg);
21}
22
24{
25 WRITE_32(lapicBase + reg, value);
26}
27
48
50{
51 assert(cpuId < CPU_MAX);
52 return &lapics[cpuId];
53}
54
55static void lapic_interrupt(cpu_t* cpu, irq_virt_t virt)
56{
57 lapic_id_t lapicId = lapics[cpu->id].lapicId;
58
61}
62
63static void lapic_eoi(cpu_t* cpu)
64{
65 (void)cpu;
66
68}
69
71 .name = "Local APIC IPI",
72 .interrupt = lapic_interrupt,
73 .eoi = lapic_eoi,
74};
75
77{
79 if (madt == NULL)
80 {
81 LOG_ERR("no MADT table found\n");
82 return ERR;
83 }
84
85 if (madt->header.length < sizeof(madt_t))
86 {
87 LOG_ERR("madt table too small\n");
88 return ERR;
89 }
90
92 {
93 LOG_ERR("madt has invalid lapic address\n");
94 return ERR;
95 }
96
100 {
101 LOG_ERR("failed to map local apic\n");
102 return ERR;
103 }
104
105 LOG_INFO("local apic mapped base=0x%016lx phys=0x%016lx\n", lapicBase,
107
109 {
111 LOG_ERR("failed to register lapic ipi chip\n");
112 return ERR;
113 }
114
115 return 0;
116}
117
123
124void lapic_send_sipi(lapic_id_t id, void* entryPoint)
125{
126 assert((uintptr_t)entryPoint % PAGE_SIZE == 0);
127
130}
#define assert(expression)
Definition assert.h:29
@ VECTOR_SPURIOUS
Made available for any component to use as a sink for spurious interrupts.
Definition interrupt.h:129
uint64_t ipi_chip_register(ipi_chip_t *chip)
Register an IPI chip.
Definition ipi.c:63
uint8_t irq_virt_t
Virtual IRQ numbers.
Definition irq.h:57
#define CPU_MAX
Maximum number of CPUs supported.
Definition cpu.h:51
#define LOG_ERR(format,...)
Definition log.h:108
#define LOG_INFO(format,...)
Definition log.h:106
#define PML_LOWER_TO_HIGHER(addr)
Converts an address from the lower half to the higher half.
@ PML_PRESENT
@ PML_WRITE
@ PML_GLOBAL
void * vmm_map(space_t *space, void *virtAddr, void *physAddr, uint64_t length, pml_flags_t flags, space_callback_func_t func, void *private)
Maps physical memory to virtual memory in a given address space.
Definition vmm.c:226
void * vmm_unmap(space_t *space, void *virtAddr, uint64_t length)
Unmaps virtual memory from a given address space.
Definition vmm.c:334
#define PAGE_SIZE
The size of a memory page in bytes.
Definition proc.h:102
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
sdt_header_t * acpi_tables_lookup(const char *signature, uint64_t minSize, uint64_t n)
Lookup the n'th table matching the signature.
Definition tables.c:260
#define MADT_SIGNATURE
MADT table signature.
Definition tables.h:202
lapic_t * lapic_get(uint32_t cpuId)
Get the lapic data for the specified CPU.
Definition lapic.c:49
void lapic_init(cpu_t *cpu)
Initialize the local APIC for a CPU.
Definition lapic.c:28
#define LAPIC_REG_ID_OFFSET
The offset at which the lapic id is stored in the LAPIC_REG_ID register.
Definition lapic.h:81
void lapic_send_init(lapic_id_t id)
Send an INIT IPI to the specified local APIC.
Definition lapic.c:118
void lapic_send_sipi(lapic_id_t id, void *entryPoint)
Send a Startup IPI (SIPI) to the specified local APIC.
Definition lapic.c:124
uint32_t lapic_read(uint32_t reg)
Read from a local apic register.
Definition lapic.c:18
uint64_t lapic_global_init(void)
Initialize the local APIC subsystem.
Definition lapic.c:76
uint8_t lapic_id_t
Local APIC ID type.
Definition lapic.h:32
void lapic_write(uint32_t reg, uint32_t value)
Write to a local apic register.
Definition lapic.c:23
@ LAPIC_LVT_MASKED
Definition lapic.h:90
@ LAPIC_SPURIOUS_ENABLE
Definition lapic.h:89
@ LAPIC_MSR_BSP
Definition lapic.h:41
@ LAPIC_MSR_ENABLE
Definition lapic.h:40
@ LAPIC_REG_TASK_PRIORITY
Definition lapic.h:52
@ LAPIC_REG_LVT_PERFCTR
Definition lapic.h:69
@ LAPIC_REG_LVT_THERMAL
Definition lapic.h:68
@ LAPIC_REG_LVT_LINT0
Definition lapic.h:70
@ LAPIC_REG_ID
Definition lapic.h:50
@ LAPIC_REG_LVT_ERROR
Definition lapic.h:72
@ LAPIC_REG_ICR1
Definition lapic.h:66
@ LAPIC_REG_EOI
Definition lapic.h:55
@ LAPIC_REG_LVT_LINT1
Definition lapic.h:71
@ LAPIC_REG_SPURIOUS
Definition lapic.h:59
@ LAPIC_REG_ICR0
Definition lapic.h:65
@ LAPIC_REG_LVT_TIMER
Definition lapic.h:67
@ LAPIC_ICR_STARTUP
Definition lapic.h:104
@ LAPIC_ICR_FIXED
Definition lapic.h:99
@ LAPIC_ICR_INIT
Definition lapic.h:103
static void lapic_eoi(cpu_t *cpu)
Definition lapic.c:63
static uintptr_t lapicBase
Definition lapic.c:14
static void lapic_interrupt(cpu_t *cpu, irq_virt_t virt)
Definition lapic.c:55
static ipi_chip_t lapicIpiChip
Definition lapic.c:70
static lapic_t lapics[CPU_MAX]
Definition lapic.c:16
static void msr_write(uint32_t msr, uint64_t value)
Definition regs.h:71
static uint64_t msr_read(uint32_t msr)
Definition regs.h:63
#define MSR_LAPIC
Definition regs.h:12
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:43
CPU structure.
Definition cpu.h:122
cpuid_t id
Definition cpu.h:123
Inter-Processor Interrupt (IPI) chip structure.
Definition ipi.h:36
const char * name
Definition ipi.h:37
Local APIC Structure.
Definition lapic.h:123
lapic_id_t lapicId
Definition lapic.h:125
Multiple APIC Description Table.
Definition tables.h:180
sdt_header_t header
Definition tables.h:181
uint32_t localInterruptControllerAddress
Definition tables.h:182
uint32_t length
Definition acpi.h:92
#define WRITE_32(address, value)
Definition utils.h:10
#define READ_32(address)
Definition utils.h:9