mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 20:58:22 +00:00
Merge pull request #8 from d-tatianin/uacpi-integration
uACPI integration
This commit is contained in:
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user