Merge pull request #8 from d-tatianin/uacpi-integration

uACPI integration
This commit is contained in:
Matheus
2024-09-01 19:32:10 -03:00
committed by GitHub
21 changed files with 822 additions and 267 deletions
+13
View File
@@ -0,0 +1,13 @@
#ifndef _ACPI_H
#define _ACPI_H
// Doesn't depend on PCI, only makes table search available
void acpi_early_init(void);
// Loads the actual ACPI namespace, hooks up the power button
void acpi_init(void);
int acpi_poweroff(void);
int acpi_reboot(void);
#endif
+2
View File
@@ -19,6 +19,7 @@
#define IPL_DISK 500
#define IPL_KEYBOARD 600
#define IPL_MOUSE 650
#define IPL_ACPI 700
#define IPL_DPC 900
#define IPL_NORMAL 1000
@@ -28,6 +29,7 @@ typedef struct _isr_t {
struct _isr_t *prev;
void (*func)(struct _isr_t *self, context_t *ctx);
void (*eoi)(struct _isr_t *self);
void *priv;
long id;
long priority;
bool pending;
+3
View File
@@ -11,6 +11,9 @@ typedef semaphore_t mutex_t;
#define MUTEX_ACQUIRE(m, i) \
semaphore_wait(m, i)
#define MUTEX_ACQUIRE_TIMED(m, t, i) \
semaphore_timedwait(m, t, i)
#define MUTEX_RELEASE(m) \
semaphore_signal(m)
+3
View File
@@ -4,6 +4,7 @@
#include <stddef.h>
#include <stdbool.h>
#include <spinlock.h>
#include <time.h>
#define SEM_TAIL 0
#define SEM_HEAD 1
@@ -24,7 +25,9 @@ typedef struct semaphore_t{
int semaphore_wait(semaphore_t *sem, bool interruptible);
int semaphore_timedwait(semaphore_t *sem, time_t timeoutusec, bool interruptible);
void semaphore_signal(semaphore_t *sem);
void semaphore_reset(semaphore_t *sem);
bool semaphore_test(semaphore_t *sem);
bool semaphore_haswaiters(semaphore_t *sem);
+12
View File
@@ -2,6 +2,7 @@
#define _SPINLOCK_H
#include <stdbool.h>
#include <kernel/interrupt.h>
typedef int spinlock_t;
@@ -11,6 +12,12 @@ static inline void spinlock_acquire(spinlock_t *lock){
while(!__sync_bool_compare_and_swap(lock, 0, 1)) asm("pause");
}
static inline bool spinlock_acquireirqclear(spinlock_t *lock){
bool ret = interrupt_set(false);
spinlock_acquire(lock);
return ret;
}
static inline bool spinlock_try(spinlock_t *lock){
return __sync_bool_compare_and_swap(lock, 0, 1);
}
@@ -19,4 +26,9 @@ static inline void spinlock_release(spinlock_t *lock){
*lock = 0;
}
static inline void spinlock_releaseirqrestore(spinlock_t *lock, bool irqstate){
spinlock_release(lock);
interrupt_set(irqstate);
}
#endif
+4
View File
@@ -35,4 +35,8 @@ static inline time_t timespec_diffus(timespec_t a, timespec_t b) {
return nsecdiff / 1000 + secdiff * 1000000;
}
static inline time_t timespec_ns(timespec_t a) {
return a.ns + a.s * 1000000000;
}
#endif
+11
View File
@@ -0,0 +1,11 @@
#include <string.h>
#include <printf.h>
#define uacpi_memcpy memcpy
#define uacpi_memset memset
#define uacpi_memcmp memcmp
#define uacpi_strcmp strcmp
#define uacpi_strlen strlen
#define uacpi_snprintf snprintf
#define uacpi_vsnprintf vsnprintf
+3 -87
View File
@@ -1,92 +1,8 @@
#ifndef _ACPI_H
#define _ACPI_H
#ifndef _ARCH_ACPI_H
#define _ARCH_ACPI_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
typedef struct {
char sig[8];
uint8_t checksum;
char oem[6];
uint8_t revision;
uint32_t rsdt;
uint32_t length;
uint64_t xsdt;
uint8_t xchecksum;
uint8_t reserved[3];
} __attribute__((packed)) rsdp_t;
typedef struct {
char sig[4];
uint32_t length;
uint8_t revision;
uint8_t cechksum;
char oemid[6];
char oemtableid[8];
uint32_t oemrevision;
uint32_t creatorid;
uint32_t creatorrevision;
} __attribute__((packed)) sdtheader_t;
typedef struct {
sdtheader_t header;
uint64_t tables[];
} __attribute__((packed)) xsdt_t;
typedef struct {
sdtheader_t header;
uint32_t tables[];
} __attribute__((packed)) rsdt_t;
typedef struct {
sdtheader_t header;
uint32_t addr;
uint32_t flags;
} __attribute__((packed)) madt_t;
typedef struct {
sdtheader_t header;
uint8_t hwrev;
uint8_t comparatorcount:5;
uint8_t countersize:1;
uint8_t reserved:1;
uint8_t legacy_replacement:1;
uint16_t pcivendor;
uint8_t addrid;
uint8_t bitwidth;
uint8_t bitoffset;
uint8_t reserved2;
uint64_t addr;
uint8_t hpetnum;
uint16_t mintick;
uint8_t pageprot;
} __attribute__((packed)) hpet_t;
typedef struct {
uint64_t address;
uint16_t sgn;
uint8_t startbus;
uint8_t endbus;
uint32_t reserved;
} __attribute__((packed)) mcfgentry_t;
typedef struct {
sdtheader_t header;
uint64_t reserved;
mcfgentry_t entries[];
} __attribute__((packed)) mcfg_t;
#define ACPI_MADT_TYPE_LAPIC 0
#define ACPI_MADT_TYPE_IOAPIC 1
#define ACPI_MADT_TYPE_OVERRIDE 2
#define ACPI_MADT_TYPE_IONMI 3
#define ACPI_MADT_TYPE_LANMI 4
#define ACPI_MADT_TYPE_64BITADDR 5
#define ACPI_MADT_TYPE_X2APIC 9
bool arch_acpi_checksumok(void *table);
void *arch_acpi_findtable(char *sig, int n);
void arch_acpi_init();
uintptr_t arch_get_rsdp(void);
#endif
+2
View File
@@ -54,6 +54,8 @@ static inline uint16_t be_to_cpu_w(uint16_t w) {
return __builtin_bswap16(w);
}
cpu_t *_bsp(void);
static inline cpu_t *_cpu() {
cpu_t *cpu;
asm volatile ("mov %%gs:0, %%rax" : "=a"(cpu) : : "memory");
+10
View File
@@ -14,6 +14,16 @@ static inline uint32_t ind(uint16_t port) {
return ret;
}
static inline void outw(uint16_t port, uint16_t data) {
asm volatile("out %%ax, %%dx" : : "a"(data), "d"(port));
}
static inline uint16_t inw(uint16_t port) {
uint16_t ret;
asm volatile("in %%dx, %%ax" : "=a"(ret) : "d"(port));
return ret;
}
static inline void outb(uint16_t port, uint8_t data) {
asm volatile("out %%al, %%dx" : : "a"(data), "d"(port));
}
+20 -14
View File
@@ -11,8 +11,11 @@
#include <kernel/alloc.h>
#include <arch/cpu.h>
#include <uacpi/acpi.h>
#include <uacpi/tables.h>
static size_t mcfgentrycount;
static mcfgentry_t *mcfgentries;
static struct acpi_mcfg_allocation *mcfgentries;
static uint32_t (*pci_archread32)(int bus, int device, int function, uint32_t offset);
static void (*pci_archwrite32)(int bus, int device, int function, uint32_t offset, uint32_t value);
@@ -31,13 +34,13 @@ static void legacy_write32(int bus, int device, int function, uint32_t offset, u
outd(CONFDATA, value);
}
static inline mcfgentry_t *getmcfgentry(int bus) {
mcfgentry_t *entry;
static inline struct acpi_mcfg_allocation *getmcfgentry(int bus) {
struct acpi_mcfg_allocation *entry;
int i;
for (i = 0; i < mcfgentrycount; ++i) {
entry = &mcfgentries[i];
if (bus >= entry->startbus && bus <= entry->endbus)
if (bus >= entry->start_bus && bus <= entry->end_bus)
break;
}
@@ -48,21 +51,21 @@ static inline mcfgentry_t *getmcfgentry(int bus) {
}
static uint32_t mcfg_read32(int bus, int device, int function, uint32_t offset) {
mcfgentry_t *entry = getmcfgentry(bus);
struct acpi_mcfg_allocation *entry = getmcfgentry(bus);
if (entry == NULL)
return 0xffffffff;
uint64_t base = (uint64_t)entry->address;
volatile uint32_t *address = (uint32_t *)((uintptr_t)base + (((bus - entry->startbus) << 20) | (device << 15) | (function << 12) | (offset & ~0x3)));
volatile uint32_t *address = (uint32_t *)((uintptr_t)base + (((bus - entry->start_bus) << 20) | (device << 15) | (function << 12) | (offset & ~0x3)));
return *address;
}
static void mcfg_write32(int bus, int device, int function, uint32_t offset, uint32_t value) {
mcfgentry_t *entry = getmcfgentry(bus);
struct acpi_mcfg_allocation *entry = getmcfgentry(bus);
uint64_t base = (uint64_t)entry->address;
volatile uint32_t *address = (uint32_t *)((uintptr_t)base + (((bus - entry->startbus) << 20) | (device << 15) | (function << 12) | (offset & ~0x3)));
volatile uint32_t *address = (uint32_t *)((uintptr_t)base + (((bus - entry->start_bus) << 20) | (device << 15) | (function << 12) | (offset & ~0x3)));
*address = value;
}
@@ -77,20 +80,23 @@ static uint64_t msiformatmessage(uint32_t *data, int vector, int edgetrigger, in
#define MCFG_MAPPING_SIZE(buscount) (4096l * 8l * 32l * (buscount))
static void pci_archinit() {
mcfg_t *mcfg = arch_acpi_findtable("MCFG", 0);
uacpi_table tbl;
struct acpi_mcfg *mcfg;
if (mcfg) {
uacpi_status ret = uacpi_table_find_by_signature("MCFG", &tbl);
if (ret == UACPI_STATUS_OK) {
printf("pci: MCFG table found. Using extended configuration space\n");
mcfg = tbl.ptr;
pci_archread32 = mcfg_read32;
pci_archwrite32 = mcfg_write32;
mcfgentrycount = (mcfg->header.length - sizeof(sdtheader_t)) / sizeof(mcfgentry_t);
mcfgentries = alloc(sizeof(mcfgentry_t) * mcfgentrycount);
mcfgentrycount = (mcfg->hdr.length - sizeof(struct acpi_sdt_hdr)) / sizeof(struct acpi_mcfg_allocation);
mcfgentries = alloc(sizeof(struct acpi_mcfg_allocation) * mcfgentrycount);
__assert(mcfgentries);
memcpy(mcfgentries, mcfg->entries, sizeof(mcfgentry_t) * mcfgentrycount);
memcpy(mcfgentries, mcfg->entries, sizeof(struct acpi_mcfg_allocation) * mcfgentrycount);
for (int i = 0; i < mcfgentrycount; ++i) {
void *phys = (void *)mcfgentries[i].address;
uintmax_t pageoffset = (uintptr_t)phys % PAGE_SIZE;
size_t mappingsize = pageoffset + MCFG_MAPPING_SIZE(mcfgentries[i].endbus - mcfgentries[i].startbus + 1);
size_t mappingsize = pageoffset + MCFG_MAPPING_SIZE(mcfgentries[i].end_bus - mcfgentries[i].start_bus + 1);
void *virt = vmm_map(NULL, mappingsize, VMM_FLAGS_PHYSICAL,
ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC | ARCH_MMU_FLAGS_UC, phys);
__assert(virt);