Split lapic and ioapic code
This commit is contained in:
parent
398aac9e2c
commit
7ddeeeca86
5 changed files with 137 additions and 128 deletions
3
Makefile
3
Makefile
|
|
@ -10,9 +10,9 @@ CFLAGS += -DINIT_ASSERTED
|
|||
# Add new source files (C or Assembler) here,
|
||||
# preferentially in alphabetical order.
|
||||
KERNEL_SOURCES_x86_64 := \
|
||||
src/x86_64/apic.c \
|
||||
src/x86_64/cmos.c \
|
||||
src/x86_64/interrupt.S \
|
||||
src/x86_64/lapic.c \
|
||||
src/x86_64/loadcs.S \
|
||||
src/x86_64/uart.c \
|
||||
src/x86_64/string.S \
|
||||
|
|
@ -22,6 +22,7 @@ KERNEL_SOURCES_x86_64 := \
|
|||
src/x86_64/address.c \
|
||||
src/x86_64/ps2_driver.c \
|
||||
src/x86_64/hwclock.c \
|
||||
src/x86_64/ioapic.c \
|
||||
# end of x86_64 specific kernel sources list
|
||||
|
||||
# Architecture-agnostic kernel sources.
|
||||
|
|
|
|||
|
|
@ -25,15 +25,21 @@ uint64_t get_cr4(void);
|
|||
|
||||
#define X86_ASM_INT(value) __asm__("int $" #value :: )
|
||||
|
||||
// Read Model Specific Register (32 or 64 bit)
|
||||
uint64_t readmsr(uint32_t msr);
|
||||
// Write Model Specific Register (32 or 64 bit)
|
||||
void writemsr(uint32_t msr, uint64_t value);
|
||||
|
||||
// write-back invalidate
|
||||
void wbinvd(void);
|
||||
|
||||
// Read Time-Stamp Counter
|
||||
static inline uint64_t
|
||||
rdtsc(void)
|
||||
{
|
||||
uint32_t lo, hi;
|
||||
__asm__ ("rdtsc\n\t" : "=a"(lo), "=d"(hi));
|
||||
return lo | ((uint64_t)hi << 32);
|
||||
uint32_t lo, hi;
|
||||
__asm__ ("rdtsc\n\t" : "=a"(lo), "=d"(hi));
|
||||
return lo | ((uint64_t)hi << 32);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -52,17 +52,17 @@ uint64_t get_cr4(void) {
|
|||
return cr4;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
readmsr(uint32_t msr)
|
||||
{
|
||||
uint32_t lo, hi;
|
||||
__asm__ ("rdmsr\n\t" : "=a"(lo), "=d"(hi) : "c"(msr));
|
||||
return lo | ((uint64_t)hi << 32);
|
||||
uint64_t readmsr(uint32_t msr) {
|
||||
uint32_t lo, hi;
|
||||
__asm__ ("rdmsr\n\t" : "=a"(lo), "=d"(hi) : "c"(msr));
|
||||
return lo | ((uint64_t)hi << 32);
|
||||
}
|
||||
|
||||
void
|
||||
writemsr(uint32_t msr, uint64_t value)
|
||||
{
|
||||
uint32_t lo = value, hi = value >> 32;
|
||||
__asm__ ("wrmsr\n\t" :: "c"(msr), "a"(lo), "d"(hi));
|
||||
void writemsr(uint32_t msr, uint64_t value) {
|
||||
uint32_t lo = value, hi = value >> 32;
|
||||
__asm__ ("wrmsr\n\t" :: "c"(msr), "a"(lo), "d"(hi));
|
||||
}
|
||||
|
||||
void wbinvd(void) {
|
||||
__asm__ volatile ("wbinvd" ::: "memory");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#define SUBSYSTEM "apic"
|
||||
#define SUBSYSTEM "ioapic"
|
||||
#include "x86_64/asm.h"
|
||||
#include "x86_64/apic.h"
|
||||
#include "address.h"
|
||||
|
|
@ -7,118 +7,6 @@
|
|||
#include "acpi.h"
|
||||
#include "std.h"
|
||||
|
||||
#define LAPIC_BASE_PHYS 0xFEE00000
|
||||
|
||||
#define SPURIOUS_VECTOR_APIC_ENABLE 0x100
|
||||
|
||||
#define LVT_TIMER_PERIODIC_BIT (1 << 17)
|
||||
|
||||
static inline void
|
||||
wbinvd(void)
|
||||
{
|
||||
__asm__ volatile ("wbinvd" : : : "memory");
|
||||
}
|
||||
|
||||
struct lapic_register {
|
||||
uint32_t value;
|
||||
uint32_t padding[3];
|
||||
};
|
||||
|
||||
struct lapic {
|
||||
struct lapic_register reserved0[2];
|
||||
struct lapic_register lapic_id;
|
||||
struct lapic_register lapic_version;
|
||||
struct lapic_register reserved1[4];
|
||||
struct lapic_register task_priority;
|
||||
struct lapic_register arbitration_priority;
|
||||
struct lapic_register processor_priority;
|
||||
struct lapic_register eoi;
|
||||
struct lapic_register remote_read;
|
||||
struct lapic_register logical_destination;
|
||||
struct lapic_register destination_format;
|
||||
struct lapic_register spurious_vector;
|
||||
struct lapic_register in_service[8];
|
||||
struct lapic_register trigger_mode[8];
|
||||
struct lapic_register request[8];
|
||||
struct lapic_register error_status;
|
||||
struct lapic_register reserved2[6];
|
||||
struct lapic_register cmci;
|
||||
struct lapic_register command[2];
|
||||
struct lapic_register lvt_timer;
|
||||
struct lapic_register lvt_thermal_sensor;
|
||||
struct lapic_register lvt_perfmon_counter;
|
||||
struct lapic_register lvt_lint0;
|
||||
struct lapic_register lvt_lint1;
|
||||
struct lapic_register lvt_error;
|
||||
struct lapic_register timer_initial;
|
||||
struct lapic_register timer_current;
|
||||
struct lapic_register reserved3[4];
|
||||
struct lapic_register timer_divisor;
|
||||
struct lapic_register reserved4[1];
|
||||
};
|
||||
STATIC_ASSERT(sizeof (struct lapic) == 0x400);
|
||||
|
||||
#define LAPIC_ADDR ((volatile struct lapic *)pa_to_pointer(pa_from_value(LAPIC_BASE_PHYS)))
|
||||
|
||||
void lapic_init(void)
|
||||
{
|
||||
ASSERT((LAPIC_ADDR->lapic_version.value & 0xff) <= 0x15);
|
||||
|
||||
LAPIC_ADDR->spurious_vector.value = SPURIOUS_VECTOR_APIC_ENABLE | 0xff;
|
||||
wbinvd();
|
||||
}
|
||||
|
||||
unsigned lapic_get_id(void)
|
||||
{
|
||||
return LAPIC_ADDR->lapic_id.value >> 24;
|
||||
}
|
||||
|
||||
unsigned int cpu_get_core_id(void) {
|
||||
return lapic_get_id();
|
||||
}
|
||||
|
||||
void lapic_eoi(void)
|
||||
{
|
||||
LAPIC_ADDR->eoi.value = 0;
|
||||
wbinvd();
|
||||
}
|
||||
|
||||
void lapic_unset_timer(void)
|
||||
{
|
||||
LAPIC_ADDR->lvt_timer.value = 0xFF | (1 << 16);
|
||||
wbinvd();
|
||||
}
|
||||
|
||||
void lapic_set_timer_periodic(int vector, uint32_t count)
|
||||
{
|
||||
LAPIC_ADDR->timer_divisor.value = 0xb;
|
||||
wbinvd();
|
||||
LAPIC_ADDR->lvt_timer.value = vector | LVT_TIMER_PERIODIC_BIT;
|
||||
wbinvd();
|
||||
LAPIC_ADDR->timer_initial.value = count;
|
||||
wbinvd();
|
||||
}
|
||||
|
||||
void lapic_set_timer_oneshot(int vector, uint32_t count)
|
||||
{
|
||||
LAPIC_ADDR->timer_divisor.value = 0xb;
|
||||
wbinvd();
|
||||
LAPIC_ADDR->lvt_timer.value = vector;
|
||||
wbinvd();
|
||||
LAPIC_ADDR->timer_initial.value = count;
|
||||
wbinvd();
|
||||
}
|
||||
|
||||
uint32_t lapic_get_timer_value(void)
|
||||
{
|
||||
return LAPIC_ADDR->timer_current.value;
|
||||
}
|
||||
|
||||
uint32_t lapic_get_timer_initial(void)
|
||||
{
|
||||
return LAPIC_ADDR->timer_initial.value;
|
||||
}
|
||||
|
||||
#define IOAPICID 0x00
|
||||
#define IOAPICVER 0x01
|
||||
#define IOAPICARB 0x02
|
||||
114
src/x86_64/lapic.c
Normal file
114
src/x86_64/lapic.c
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
#define SUBSYSTEM "lapic"
|
||||
#include "x86_64/asm.h"
|
||||
#include "x86_64/apic.h"
|
||||
#include "address.h"
|
||||
#include "x86_64/interrupt.h"
|
||||
#include "x86_64/asm.h"
|
||||
#include "acpi.h"
|
||||
#include "std.h"
|
||||
|
||||
#define LAPIC_BASE_PHYS 0xFEE00000
|
||||
|
||||
#define SPURIOUS_VECTOR_APIC_ENABLE 0x100
|
||||
|
||||
#define LVT_TIMER_PERIODIC_BIT (1 << 17)
|
||||
|
||||
struct lapic_register {
|
||||
uint32_t value;
|
||||
uint32_t padding[3];
|
||||
};
|
||||
|
||||
struct lapic {
|
||||
struct lapic_register reserved0[2];
|
||||
struct lapic_register lapic_id;
|
||||
struct lapic_register lapic_version;
|
||||
struct lapic_register reserved1[4];
|
||||
struct lapic_register task_priority;
|
||||
struct lapic_register arbitration_priority;
|
||||
struct lapic_register processor_priority;
|
||||
struct lapic_register eoi;
|
||||
struct lapic_register remote_read;
|
||||
struct lapic_register logical_destination;
|
||||
struct lapic_register destination_format;
|
||||
struct lapic_register spurious_vector;
|
||||
struct lapic_register in_service[8];
|
||||
struct lapic_register trigger_mode[8];
|
||||
struct lapic_register request[8];
|
||||
struct lapic_register error_status;
|
||||
struct lapic_register reserved2[6];
|
||||
struct lapic_register cmci;
|
||||
struct lapic_register command[2];
|
||||
struct lapic_register lvt_timer;
|
||||
struct lapic_register lvt_thermal_sensor;
|
||||
struct lapic_register lvt_perfmon_counter;
|
||||
struct lapic_register lvt_lint0;
|
||||
struct lapic_register lvt_lint1;
|
||||
struct lapic_register lvt_error;
|
||||
struct lapic_register timer_initial;
|
||||
struct lapic_register timer_current;
|
||||
struct lapic_register reserved3[4];
|
||||
struct lapic_register timer_divisor;
|
||||
struct lapic_register reserved4[1];
|
||||
};
|
||||
STATIC_ASSERT(sizeof (struct lapic) == 0x400);
|
||||
|
||||
#define LAPIC_ADDR ((volatile struct lapic *)pa_to_pointer(pa_from_value(LAPIC_BASE_PHYS)))
|
||||
|
||||
void lapic_init(void)
|
||||
{
|
||||
ASSERT((LAPIC_ADDR->lapic_version.value & 0xff) <= 0x15);
|
||||
|
||||
LAPIC_ADDR->spurious_vector.value = SPURIOUS_VECTOR_APIC_ENABLE | 0xff;
|
||||
wbinvd();
|
||||
}
|
||||
|
||||
unsigned lapic_get_id(void)
|
||||
{
|
||||
return LAPIC_ADDR->lapic_id.value >> 24;
|
||||
}
|
||||
|
||||
unsigned int cpu_get_core_id(void) {
|
||||
return lapic_get_id();
|
||||
}
|
||||
|
||||
void lapic_eoi(void)
|
||||
{
|
||||
LAPIC_ADDR->eoi.value = 0;
|
||||
wbinvd();
|
||||
}
|
||||
|
||||
void lapic_unset_timer(void)
|
||||
{
|
||||
LAPIC_ADDR->lvt_timer.value = 0xFF | (1 << 16);
|
||||
wbinvd();
|
||||
}
|
||||
|
||||
void lapic_set_timer_periodic(int vector, uint32_t count)
|
||||
{
|
||||
LAPIC_ADDR->timer_divisor.value = 0xb;
|
||||
wbinvd();
|
||||
LAPIC_ADDR->lvt_timer.value = vector | LVT_TIMER_PERIODIC_BIT;
|
||||
wbinvd();
|
||||
LAPIC_ADDR->timer_initial.value = count;
|
||||
wbinvd();
|
||||
}
|
||||
|
||||
void lapic_set_timer_oneshot(int vector, uint32_t count)
|
||||
{
|
||||
LAPIC_ADDR->timer_divisor.value = 0xb;
|
||||
wbinvd();
|
||||
LAPIC_ADDR->lvt_timer.value = vector;
|
||||
wbinvd();
|
||||
LAPIC_ADDR->timer_initial.value = count;
|
||||
wbinvd();
|
||||
}
|
||||
|
||||
uint32_t lapic_get_timer_value(void)
|
||||
{
|
||||
return LAPIC_ADDR->timer_current.value;
|
||||
}
|
||||
|
||||
uint32_t lapic_get_timer_initial(void)
|
||||
{
|
||||
return LAPIC_ADDR->timer_initial.value;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue