summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-02-03 21:38:57 -0500
committerFreya Murphy <freya@freyacat.org>2024-02-03 21:39:02 -0500
commit61e7fdf1eb7d5d4a66c443fe6bd16fd2a2a92859 (patch)
tree757350208c44ac1e639dc7095d3e80eedc6cd74a /src
parentformatting (diff)
downloadcorn-61e7fdf1eb7d5d4a66c443fe6bd16fd2a2a92859.tar.gz
corn-61e7fdf1eb7d5d4a66c443fe6bd16fd2a2a92859.tar.bz2
corn-61e7fdf1eb7d5d4a66c443fe6bd16fd2a2a92859.zip
acpi table loading and shutdown works, plus mmap fix :3
Diffstat (limited to '')
-rw-r--r--src/arch/amd64/acpi.c226
-rw-r--r--src/arch/amd64/cpu/idt.c2
-rw-r--r--src/arch/amd64/paging.c10
-rw-r--r--src/kmain.c4
-rw-r--r--src/print.c24
5 files changed, 140 insertions, 126 deletions
diff --git a/src/arch/amd64/acpi.c b/src/arch/amd64/acpi.c
index eb38f73..59e9621 100644
--- a/src/arch/amd64/acpi.c
+++ b/src/arch/amd64/acpi.c
@@ -9,12 +9,12 @@
#include "bindings.h"
struct acpi_header {
- char signature[4];
+ uint32_t signature;
uint32_t length;
uint8_t revision;
uint8_t checksum;
- char oem_id[6];
- char oem_table_id[8];
+ uint8_t oem_id[6];
+ uint8_t oem_table_id[8];
uint32_t oem_revision;
uint32_t creator_id;
uint32_t creator_revision;
@@ -23,9 +23,9 @@ struct acpi_header {
// root system descriptor pointer
// ACPI 1.0
struct rsdp {
- char signature[8];
+ uint8_t signature[8];
uint8_t checksum;
- char oemid[6];
+ uint8_t oemid[6];
uint8_t revision;
uint32_t rsdt_addr;
} __attribute__((packed));
@@ -38,11 +38,12 @@ struct xsdp {
char oemid[6];
uint8_t revision;
uint32_t rsdt_addr;
-
- uint32_t length;
- uint64_t xsdt_addr;
- uint8_t extendeid_checksum;
- uint8_t reserved[3];
+ struct {
+ uint32_t length;
+ uint64_t xsdt_addr;
+ uint8_t extendeid_checksum;
+ uint8_t reserved[3];
+ } ext;
} __attribute__((packed));
// root system descriptor table
@@ -50,14 +51,14 @@ struct xsdp {
struct rsdt {
struct acpi_header h;
uint32_t sdt_pointers[];
-};
+} __attribute__((packed));
// eXtended system descriptor table
// ACPI 2.0
struct xsdt {
struct acpi_header h;
uint64_t sdt_pointers[];
-};
+} __attribute__((packed));
// generic address structure
@@ -69,6 +70,27 @@ struct gas {
uint64_t address;
};
+// differentiated system description table
+struct dsdt {
+ struct acpi_header h;
+ char s5_addr[];
+} __attribute__((packed));
+
+struct apic {
+ struct acpi_header h;
+ // todo
+} __attribute__((packed));
+
+struct hept {
+ struct acpi_header h;
+ // todo
+} __attribute__((packed));
+
+struct waet {
+ struct acpi_header h;
+ // todo
+} __attribute__((packed));
+
// fixed acpi description table
struct fadt {
struct acpi_header h;
@@ -135,15 +157,20 @@ struct fadt {
struct gas x_pm_timer_block;
struct gas x_gpe0_block;
struct gas x_gpe1_block;
-};
+} __attribute__((packed));
struct acpi_state {
union {
struct xsdt *xsdt;
struct rsdt *rsdt;
- } dst;
+ } sdt;
+ struct fadt *fadt;
+ struct dsdt *dsdt;
+ struct apic *apic;
+ struct hept *hept;
+ struct waet *waet;
uint8_t version;
- struct fadt fadt;
+
uint16_t SLP_TYPa;
uint16_t SLP_TYPb;
uint16_t SLP_EN;
@@ -160,11 +187,10 @@ static bool checksum(uint8_t *data, size_t len) {
return sum == 0;
}
-static int read_s5_addr(struct acpi_state *state) {
- uintptr_t ptr = state->fadt.dsdt;
- char *s5_addr = (void *) (ptr + 36);
+static int read_s5_addr(struct dsdt *dsdt) {
+ char *s5_addr = dsdt->s5_addr;
+ int dsdt_len = dsdt->h.length - sizeof(struct acpi_header);
- int dsdt_len = *((int *) (ptr+1)) - 36;
while (0 < dsdt_len--) {
if (memcmp(s5_addr, "_S5_", 4) == 0)
break;
@@ -179,15 +205,15 @@ static int read_s5_addr(struct acpi_state *state) {
if (*s5_addr == 0x0A)
s5_addr++; // skip byteprefix
- state->SLP_TYPa = *(s5_addr)<<10;
+ state.SLP_TYPa = *(s5_addr)<<10;
s5_addr++;
if (*s5_addr == 0x0A)
s5_addr++; // skip byteprefix
- state->SLP_TYPb = *(s5_addr)<<10;
+ state.SLP_TYPb = *(s5_addr)<<10;
- state->SLP_EN = 1<<13;
- state->SCI_EN = 1;
+ state.SLP_EN = 1<<13;
+ state.SCI_EN = 1;
} else {
return -1;
@@ -199,129 +225,115 @@ static int read_s5_addr(struct acpi_state *state) {
return -1;
}
-static void *acpi_find_table_rsdt(struct rsdt *rsdt, const char *identifier, int ident_len) {
- int entries = (rsdt->h.length - sizeof(rsdt->h)) / 4;
+static void acpi_load_table(uint64_t addr);
+static void acpi_load_rsdt_tables(struct rsdt *rsdt) {
+ int entries = (rsdt->h.length - sizeof(rsdt->h)) / 4;
for (int i = 0; i < entries; i++) {
- struct acpi_header *h = (struct acpi_header *) (uintptr_t) rsdt->sdt_pointers[i];
- char buf[6];
- memcpy(buf, h->signature, 4);
- buf[4] = '\n';
- buf[5] = '\0';
- kputs(buf);
- if (!strncmp(h->signature, identifier, ident_len))
- return (void *)h;
+ uint32_t addr = rsdt->sdt_pointers[i];
+ acpi_load_table(addr);
}
-
- // TABLE NOT FOUND
- return NULL;
}
-static void *acpi_find_table_xsdt(struct xsdt *xsdt, const char *identifier, int ident_len) {
+static void acpi_load_xsdt_tables(struct xsdt *xsdt) {
int entries = (xsdt->h.length - sizeof(xsdt->h)) / 8;
-
for (int i = 0; i < entries; i++) {
- struct acpi_header *h = (struct acpi_header *) (uintptr_t) xsdt->sdt_pointers[i];
- if (!strncmp(h->signature, identifier, ident_len))
- return (void *)h;
+ uint64_t addr = xsdt->sdt_pointers[i];
+ acpi_load_table(addr);
}
-
- // TABLE NOT FOUND
- return NULL;
}
-int acpi_init_rsdt(struct rsdt *rsdt) {
-
- kprintf("RSDT: %#016lx\n", (size_t)rsdt);
-
- rsdt = mmap(rsdt, sizeof(struct rsdt));
-
- state.dst.rsdt = rsdt;
- state.version = 0;
-
- if (!checksum((uint8_t *) &rsdt->h, rsdt->h.length))
- return -1;
-
- struct fadt *fadt = acpi_find_table_rsdt(rsdt, "FACP", 4);
- if (!fadt)
- return -1;
-
- if (!checksum((uint8_t *) &fadt->h, fadt->h.length))
- return -1;
-
- state.fadt = *fadt;
+#define SIG_RSDT 0x54445352
+#define SIG_XSDT 0x54445358
+#define SIG_FACP 0x50434146
+#define SIG_DSDT 0x54445344
+#define SIG_APIC 0x43495041
+#define SIG_HEPT 0x54455048
+#define SIG_WAET 0x54454157
- return -1;
+static void acpi_handle_table(struct acpi_header *header) {
+ switch (header->signature) {
+ case SIG_RSDT:
+ state.sdt.rsdt = (struct rsdt *) header;
+ acpi_load_rsdt_tables(state.sdt.rsdt);
+ break;
+ case SIG_XSDT:
+ state.sdt.xsdt = (struct xsdt *) header;
+ acpi_load_xsdt_tables(state.sdt.xsdt);
+ break;
+ case SIG_FACP:
+ state.fadt = (struct fadt *) header;
+ acpi_load_table(state.fadt->dsdt);
+ break;
+ case SIG_DSDT:
+ state.dsdt = (struct dsdt *) header;
+ read_s5_addr(state.dsdt);
+ break;
+ case SIG_APIC:
+ state.apic = (struct apic *) header;
+ break;
+ case SIG_HEPT:
+ state.hept = (struct hept *) header;
+ break;
+ case SIG_WAET:
+ state.waet = (struct waet *) header;
+ break;
+ default:
+ break;
+ }
}
-int acpi_init_xsdt(struct xsdt *xsdt) {
-
- xsdt = mmap(xsdt, sizeof(struct xsdt));
- return -1;
- state.dst.xsdt = xsdt;
- state.version = 2;
-
- if (!checksum((uint8_t *) &xsdt->h, xsdt->h.length))
- return -1;
-
- struct fadt *fadt = acpi_find_table_xsdt(xsdt, "FACP", 4);
- if (!fadt)
- return -1;
-
- if (!checksum((uint8_t *) &fadt->h, fadt->h.length))
- return -1;
-
- state.fadt = *fadt;
+static void acpi_load_table(uint64_t addr) {
+ struct acpi_header *temp, *mapped;
+ uint32_t length;
- return 0;
+ temp = (struct acpi_header * ) (uintptr_t) addr;
+ mapped = mmap(temp, sizeof(struct acpi_header));
+ length = mapped->length;
+ unmap(mapped);
+ mapped = mmap(temp, length);
+ if (!checksum((uint8_t *) mapped, mapped->length)) {
+ unmap(mapped);
+ return;
+ }
+ kprintf("%.*s: %#016lx\n", 4, (char*)&mapped->signature, (size_t)temp);
+ acpi_handle_table(mapped);
}
int acpi_init(void *rootsdp) {
+
+ memset(&state, 0, sizeof(struct acpi_state));
+
struct rsdp *rsdp = (struct rsdp *) rootsdp;
if (!checksum((uint8_t *)rsdp, sizeof(struct rsdp)))
return -1;
- if (strncmp(rsdp->signature, "RSD PTR ", 8) != 0) {
+ if (memcmp(rsdp->signature, "RSD PTR ", 8) != 0) {
panic("invalid acpi rsdp signature: %.*s\n", 8, rsdp->signature);
}
- int res;
-
if (rsdp->revision == 0) {
+ state.version = 0;
kprintf("ACPI 1.0\n");
- kprintf("RSDP: %#016lx\n", (size_t)rsdp);
- res = acpi_init_rsdt(
- (struct rsdt *) (uintptr_t) rsdp->rsdt_addr
- );
+ acpi_load_table(rsdp->rsdt_addr);
} else if (rsdp->revision == 2) {
+ state.version = 2;
struct xsdp *xsdp = (struct xsdp *) rsdp;
kprintf("ACPI 2.0\n");
- kprintf("XSDP: %#016lx\n", (size_t)xsdp);
- res = acpi_init_xsdt(
- (struct xsdt *) (uintptr_t) xsdp->xsdt_addr
- );
+ acpi_load_table(xsdp->ext.xsdt_addr);
} else {
panic("invalid acpi rev: %d\n", rsdp->revision);
}
- if (res) {
- kprintf("...acpi failed to load\n\n");
- return res;
- }
-
- kprintf("\n\n");
-
- int ret = read_s5_addr(&state);
- if (!ret)
- return ret;
+ kprintf("\n");
- outb(state.fadt.smi_command_port,state.fadt.acpi_enable);
+ outb(state.fadt->smi_command_port,state.fadt->acpi_enable);
return 0;
}
int acpi_shutdown(void) {
- outw((unsigned int) state.fadt.pm1_a_control_block, state.SLP_TYPb | state.SLP_EN);
+ outw((unsigned int) state.fadt->pm1_a_control_block, state.SLP_TYPb | state.SLP_EN);
return -1;
}
diff --git a/src/arch/amd64/cpu/idt.c b/src/arch/amd64/cpu/idt.c
index 3e98b55..464bdb0 100644
--- a/src/arch/amd64/cpu/idt.c
+++ b/src/arch/amd64/cpu/idt.c
@@ -135,7 +135,7 @@ void idt_exception_handler(uint64_t exception, uint64_t code, struct isr_regs *s
kprintf("Error code 0x%lX\n", code);
if (exception == EX_PAGE_FAULT) {
- kprintf("Page fault address: 0x%lX\n", cr2);
+ kprintf("Page fault address: %#016lx\n", cr2);
}
kputs("\n");
diff --git a/src/arch/amd64/paging.c b/src/arch/amd64/paging.c
index a80737c..c857d0b 100644
--- a/src/arch/amd64/paging.c
+++ b/src/arch/amd64/paging.c
@@ -539,20 +539,20 @@ void paging_init(void) {
static inline void *page_align(void *addr) {
uintptr_t a = (uintptr_t) addr;
- a += PAGE_SIZE - 1;
a /= PAGE_SIZE;
a *= PAGE_SIZE;
return (void *) a;
}
void *mmap(void *addr, size_t len) {
- len += (long)addr % PAGE_SIZE;
- long pages = (len + PAGE_SIZE - 1) / PAGE_SIZE;
+ void *phys = page_align(addr);
+ ptrdiff_t error = (char*)addr - (char*)phys;
+ len += error;
+ long pages = len / PAGE_SIZE + 1;
void *virt = virtaddr_alloc(pages);
if (virt == NULL) {
return NULL;
}
- void *phys = page_align(addr);
if (map_pages(
kernel_pml4,
virt,
@@ -563,7 +563,7 @@ void *mmap(void *addr, size_t len) {
virtaddr_free(virt);
return NULL;
}
- return virt;
+ return (char*)virt + error;
}
void unmap(void *addr) {
diff --git a/src/kmain.c b/src/kmain.c
index b4ebadb..07165bc 100644
--- a/src/kmain.c
+++ b/src/kmain.c
@@ -15,12 +15,12 @@ void kmain(struct boot_info *info) {
kprintf("enterd kmain\n");
+ //acpi_shutdown();
+
// pages are allocated on write :3
char *test = kalloc(5);
*test = 1;
- //log_backtrace();
-
while (1) {
screen_redraw();
// loop so we dont halt
diff --git a/src/print.c b/src/print.c
index 8cab6e4..a7ce5f6 100644
--- a/src/print.c
+++ b/src/print.c
@@ -95,6 +95,7 @@ static enum printtype conversion_to_printtype(enum format_conversion conversion)
return OCTAL;
case FMT_HEX:
case FMT_HEX_UPPER:
+ case FMT_PTR:
return HEX;
default:
return NONE;
@@ -377,11 +378,12 @@ static void print_number_buffer(
const char *buf, // buffer containing the text we want to print
struct spacing spacing, // the spacing on the left right and middle
enum printtype type,
- enum charcase cc
+ enum charcase cc,
+ enum format_flag flags
) {
// put the 0x at the start of the string
- if (spacing.left && spacing.zero && type == HEX) {
+ if (spacing.left && spacing.zero && type == HEX && (flags & FLG_ALTERNATE)) {
if (cc == UPPERCASE) {
kputs("0X");
} else {
@@ -389,7 +391,7 @@ static void print_number_buffer(
}
}
- if ((!spacing.left || !spacing.zero) && type == OCTAL) {
+ if ((!spacing.left || !spacing.zero) && type == OCTAL && (flags & FLG_ALTERNATE)) {
kputc('0');
}
@@ -397,7 +399,7 @@ static void print_number_buffer(
spacing.zero ? kputc('0') : kputc(' ');
}
- if ((!spacing.left || !spacing.zero) && type == HEX) {
+ if ((!spacing.left || !spacing.zero) && type == HEX && (flags & FLG_ALTERNATE)) {
if (cc == UPPERCASE) {
kputs("0X");
} else {
@@ -457,18 +459,18 @@ static struct spacing get_spacing(
}
unsigned gap = 0;
- if (max > length) {
- gap = max - length;
+ if (min > length) {
+ gap = min - length;
}
spacing.length = length;
if (flags & FLG_LEFT_ALIGN) {
- spacing.left = gap;
- spacing.right = 0;
- } else {
spacing.left = 0;
spacing.right = gap;
+ } else {
+ spacing.left = gap;
+ spacing.right = 0;
}
spacing.zero = (flags & FLG_ZERO);
@@ -574,7 +576,7 @@ static void print_signed_number(
unsigned length = strlen(ptr);
struct spacing spacing =
get_spacing(width, precision, flags, length);
- print_number_buffer(ptr, spacing, type, cc);
+ print_number_buffer(ptr, spacing, type, cc, flags);
}
static void print_unsigned_number(
@@ -591,7 +593,7 @@ static void print_unsigned_number(
unsigned length = strlen(ptr);
struct spacing spacing =
get_spacing(width, precision, flags, length);
- print_number_buffer(ptr, spacing, type, cc);
+ print_number_buffer(ptr, spacing, type, cc, flags);
}
static bool is_conversion_number(enum format_conversion conversion) {