Skip to content

Commit

Permalink
Enumerating ACPI tables for MADT (to process IOAPIC). Refactored ACPI…
Browse files Browse the repository at this point in the history
… table parsing code. Corrected EBDA address loading. Added some helper functions.
  • Loading branch information
shoily committed Dec 1, 2020
1 parent 080027c commit ffcaef6
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 24 deletions.
155 changes: 138 additions & 17 deletions acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,83 @@
#include "krnlconst.h"
#include "debug.h"
#include "type.h"
#include "util.h"
#include "system.h"

extern int ebda;
extern int ioapic_base_register;
extern int ioapic_gsi_base;

typedef struct _RSD {

char signature[8];
byte checksum;
u8 checksum;
char OEMID[6];
byte revision;
int rsdt_address;
u8 revision;
u32 rsdt_address;
}__attribute__((packed)) RSD;

#define CHECK_RSD_PTR(p) (p[0]=='R' && \
p[1]=='S' && \
p[2]=='D' && \
p[3]==' ' && \
p[4]=='P' && \
p[5]=='T' && \
p[6]=='R' && \
p[7]==' ')
typedef struct _ACPI_TABLE {

RSD *rsd;
char signature[4];
u32 length;
u8 revision;
u8 checksum;
char OEMID[6];
char OEM_table_id[8];
u32 OEM_revision;
u32 creator_id;
u32 creator_revision;
}__attribute__((packed)) ACPI_TABLE;

typedef struct _APIC_TABLE {

char type;
char length;

union {
struct {
u8 uid;
u8 apic_id;
u32 flags;
}__attribute__((packed)) processor_lapic;

struct {
u8 id;
u8 reserved;
u32 address;
u32 gsi_base;
}__attribute__((packed)) ioapic;

struct {
u8 bus;
u8 source;
u32 gsi;
u16 flags;
}__attribute__((packed)) int_src_override;

struct {
u16 flags;
u32 gsi;
}__attribute__((packed)) nmi_source;

struct {
u8 uid;
u16 flags;
u8 lapic_lint;
}__attribute__((packed)) lapic_nmi;
} info;

}__attribute__((packed)) APIC_TABLE;

#define RSDPTR_STR "RSD PTR"
#define APIC_STR "APIC"

RSD *rsdp;
ACPI_TABLE *rsdt;
ACPI_TABLE **acpi_tables;

int num_acpi_tables;

bool acpi_find_rsdp() {

Expand All @@ -58,10 +113,10 @@ bool acpi_find_rsdp() {
}
}

if (CHECK_RSD_PTR(cur->signature)) {
if (!memcmp(cur->signature, RSDPTR_STR, strlen(RSDPTR_STR))) {

rsd = cur;
printf(KERNEL_INFO, "RSD PTR: %p\n", (long)rsd-KERNEL_VIRT_ADDR);
rsdp = cur;
printf(KERNEL_INFO, "RSDP: %p\n", (long)rsdp-KERNEL_VIRT_ADDR);
return true;
}

Expand All @@ -71,13 +126,79 @@ bool acpi_find_rsdp() {
return false;
}

void acpi_process_madt(ACPI_TABLE *madt) {

int remaining_bytes;
APIC_TABLE *apic_table;

remaining_bytes = madt->length - 44;
apic_table = (APIC_TABLE*)ADD2PTR(madt, 44);

do {

remaining_bytes -= apic_table->length;

switch(apic_table->type) {

case 0:
{
// local APICs
} break;
case 1:
{
// currently supports one IOAPIC
if (!ioapic_base_register) {
ioapic_base_register = (int)apic_table->info.ioapic.address;
ioapic_gsi_base = (u32)apic_table->info.ioapic.gsi_base;
printf(KERNEL_INFO, "IOAPIC base register: %p\n", ioapic_base_register);
}
} break;
case 2:
{
// interrupt source override
} break;
case 3:
{
// NMI source
} break;
case 4:
{
// local APIC NMI
} break;

}

apic_table = (APIC_TABLE*)ADD2PTR(apic_table, apic_table->length);
} while(remaining_bytes);
}

void acpi_process_table(ACPI_TABLE *acpi_table) {

if (!memcmp(acpi_table->signature, APIC_STR, strlen(APIC_STR))) {

acpi_process_madt(acpi_table);
}
}

void acpi_init() {

rsd = NULL;
rsdp = NULL;
acpi_tables = NULL;
ioapic_base_register = 0;

if (!acpi_find_rsdp()) {

printf(KERNEL_INFO, "No ACPI!!!\n");
return;
}
printf(KERNEL_INFO, "RSDT: %p\n", rsd->rsdt_address);

rsdt = (ACPI_TABLE*)ADD2PTR(rsdp->rsdt_address, KERNEL_VIRT_ADDR);
printf(KERNEL_INFO, "RSDT: %p\n", (long)rsdt-KERNEL_VIRT_ADDR);

num_acpi_tables = (rsdt->length - sizeof(ACPI_TABLE)) / sizeof(void*);
acpi_tables = (ACPI_TABLE**)ADD2PTR(rsdt, sizeof(ACPI_TABLE));

for(int i=0;i<num_acpi_tables;i++) {
acpi_process_table((ACPI_TABLE*)ADD2PTR(acpi_tables[i], KERNEL_VIRT_ADDR));
}
}
6 changes: 5 additions & 1 deletion apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
#include "setup32.h"
#include "debug.h"

int lapic_present = 0;
int lapic_present;
int lapic_base_register;
int lapic_id;
int ioapic_base_register;
u32 ioapic_gsi_base;

extern int _kernel_pg_dir;

Expand Down Expand Up @@ -70,6 +72,8 @@ void init_lapic() {
int eax, edx;
pte_t *pgtable[1];

lapic_present = 0;

__asm__ __volatile__("movl $1, %%eax;"
"cpuid;"
"andl $0x200, %%edx;"
Expand Down
7 changes: 5 additions & 2 deletions setup32.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ int lapic_calibration_tick = 0;
bool lapic_calibration_mode = false;
bool lapic_timer_enabled = false;

#define DEBUG_TIMER

#ifdef DEBUG_TIMER
int timer_counter[MAX_NUM_SMPS];
int seconds[MAX_NUM_SMPS];
Expand All @@ -105,7 +107,7 @@ __attribute__((regparm(0))) void common_interrupt_handler(struct regs_frame *rf)

lapic_calibration_tick++;

} else if (lapic_timer_enabled) {
} else {
#ifdef DEBUG_TIMER
char s[20];
timer_counter[CUR_CPU]++;
Expand All @@ -117,7 +119,7 @@ __attribute__((regparm(0))) void common_interrupt_handler(struct regs_frame *rf)
print_vga_fixed(s, 140, 5+CUR_CPU);
}
#endif
}
}
}
}

Expand Down Expand Up @@ -284,6 +286,7 @@ void setup32() {
init_lapic();

if (!lapic_present) {
lapic_calibration_tick = 1;
init_pic_8259();
init_pit_frequency();
}
Expand Down
2 changes: 0 additions & 2 deletions smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ void copy_smp_init_to_low_mem() {
char *s = (char*)&init_ap;
char *d = (char*)(AP_INIT_PHYS_TEXT+KERNEL_VIRT_ADDR);

printf(KERNEL_DEBUG, "init_ap_size: %d\n", (int)init_ap_size);

for(int i=0;i<(int)init_ap_size;i++) {
*d++ = *s++;
}
Expand Down
2 changes: 1 addition & 1 deletion system.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ void bda_read_table() {

short *p = (short*)(0x40e + KERNEL_VIRT_ADDR);

ebda = (int)(unsigned short)*p;
ebda = ((int)(unsigned short)*p) << 4;

printf(KERNEL_INFO, "EBDA: %x\n", ebda);
}
12 changes: 11 additions & 1 deletion type.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,15 @@ typedef char byte;

#define ADD2PTR(x, y) ((long)(x) + (long)(y))

#endif
typedef unsigned char u8;
typedef char s8;
typedef unsigned short u16;
typedef short s16;
typedef unsigned int u32;
typedef int s32;
typedef long long s64;
typedef unsigned long long u64;

typedef u32 size_t;

#endif
14 changes: 14 additions & 0 deletions util.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,17 @@ void lltoa(long long val, char *str, int base) {
str[16] = 0;
}

int strncmp(const char *s1, const char *s2, size_t len) {

for(size_t i=0;i<len;i++) {

if (*s1 < *s2)
return -1;
else if (*s1 > *s2)
return 1;

s1++; s2++;
}

return 0;
}
4 changes: 4 additions & 0 deletions util.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ typedef unsigned char *va_list;
#define va_start(arg, list) (list = (unsigned char*)&arg+sizeof(arg))
#define va_arg(list, type) *((type *) ((list+=sizeof(type))-sizeof(type)))

int strncmp(const char *s1, const char *s2, size_t len);
int strlen(char *p);

#define memcmp(p1, p2, num) strncmp((const char *)p1, (const char *)p2, num)

void itoa(int val, char *str, int base);
void ltoa(long val, char *str, int base);
void lltoa(long long val, char *str, int base);
Expand Down

0 comments on commit ffcaef6

Please sign in to comment.