Compare commits
161 Commits
92ccd189e7
...
master
Author | SHA1 | Date | |
---|---|---|---|
3996f71316 | |||
ed704e2cef | |||
0ac80c76b0 | |||
3830af45c8 | |||
49cebd277c | |||
a1ec132d09 | |||
00b779fb91 | |||
a513909189 | |||
cdfb1e39c0 | |||
e9838d530f | |||
247ef1bbd1 | |||
933083ffeb | |||
70d6931e3b | |||
acbf051dbc | |||
0117080b61 | |||
ef9393e694 | |||
082cb66c7e | |||
b624214433 | |||
26517e8e28 | |||
b72f3ee00d | |||
071f414f07 | |||
04a4b1395c | |||
18d646ff8b | |||
20b4545cae | |||
fc47ff581e | |||
08793178f1 | |||
3c1c63e970 | |||
57ba9ff126 | |||
c0178a1405 | |||
dc8df7fade | |||
c30d2d2ea6 | |||
443cf0e4ff | |||
de20efa0f3 | |||
2cfd3ee2fa | |||
c345e2284e | |||
bc2b115cb3 | |||
91d648ade4 | |||
0232849994 | |||
73effcd52a | |||
62cf07afc7 | |||
0e4a35eb86 | |||
fa8a774115 | |||
39981fdbbf | |||
10711f7fb3 | |||
0fb63b4695 | |||
46e52c8d48 | |||
4e8afae5fb | |||
20a89502c0 | |||
8db585f581 | |||
e03e950879 | |||
2b93d6d184 | |||
d7562b98c1 | |||
f5f44da5f6 | |||
1fd6c4e221 | |||
96ce9233ff | |||
c07a2c957b | |||
8d081bedb0 | |||
3b1bb9d531 | |||
5af7c5276a | |||
5c7fb3e1cf | |||
397379bca3 | |||
475f77d30f | |||
d5c2df7365 | |||
83a28bd25b | |||
3f2c35f4cb | |||
8a9687c007 | |||
d50bdd0051 | |||
0c65bd9891 | |||
222e846881 | |||
a24b1fc677 | |||
a8005917eb | |||
97bc0aa05b | |||
6cd4c73438 | |||
9694d1a5a0 | |||
e245ecca3c | |||
3f0231be3f | |||
a1b3d4efa4 | |||
8269e097d6 | |||
dcc68154b2 | |||
81dc694a23 | |||
5b6408b06b | |||
b7ad1e0633 | |||
1b5701a659 | |||
e01d8d5e1a | |||
44b5aa305c | |||
c94ef4d990 | |||
2c0d50a401 | |||
1af0d1f5bc | |||
504bdbd4ba | |||
c364dca5e5 | |||
8d0f80f821 | |||
4cedfda19b | |||
40b7dcedf8 | |||
24a90b24e8 | |||
d7153bf0b6 | |||
ad56890ee9 | |||
2d7ceb4b43 | |||
4c17f26915 | |||
024a5b2e21 | |||
9e9d2c5190 | |||
e5e707eb54 | |||
b3894f1600 | |||
b0e543177b | |||
ba1c0eedbd | |||
ac1cc172f7 | |||
6a8af7727e | |||
91e65bb35a | |||
0a5523f234 | |||
ce63020b34 | |||
40ccb7d476 | |||
062e98d714 | |||
69e23a9ca3 | |||
26ff717b50 | |||
e6891b39cc | |||
dc3d80d707 | |||
2f9f4d9397 | |||
91c493c818 | |||
c4c26e0e19 | |||
3b42abc027 | |||
71be9c5fb3 | |||
4ade9ad1a0 | |||
ac195acd2f | |||
1029db6342 | |||
ab224eda8e | |||
94dd38d010 | |||
a9ac962051 | |||
e71361dcca | |||
659f98910d | |||
80a788617e | |||
9644ad0b4e | |||
4f3053bc8e | |||
0cbf308d95 | |||
b04ebd9c71 | |||
97bfa178d1 | |||
cd0e262e56 | |||
643d692259 | |||
3b18f56376 | |||
b89882e1cf | |||
c31c00e8cd | |||
d399922de6 | |||
fb5e88a175 | |||
f42c4b7e44 | |||
708c53c64d | |||
ca92a0e6a8 | |||
90266f044b | |||
afa4d383e0 | |||
8a12f23b69 | |||
920de10025 | |||
0fb3a1ca75 | |||
ddca5f687e | |||
4e3c386942 | |||
2015e0e0aa | |||
13ab117b1b | |||
73f27f730b | |||
0273330cf4 | |||
60a530b900 | |||
7a52f2f051 | |||
8cf1bde879 | |||
182c6e2956 | |||
9d8849a425 | |||
3f6df79885 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,4 @@
|
|||||||
/limine
|
/limine
|
||||||
/iso_root
|
/iso_root
|
||||||
/base_root
|
|
||||||
*.iso
|
*.iso
|
||||||
*.img
|
*.img
|
||||||
|
54
Makefile
54
Makefile
@ -1,7 +1,15 @@
|
|||||||
.PHONY: all clean prepare cleanall iso base
|
.PHONY: clean prepare cleanall iso base kernel user test
|
||||||
|
|
||||||
all:
|
ARCH ?= x86_64
|
||||||
make -C kernel all
|
|
||||||
|
kernel:
|
||||||
|
make -C kernel ARCH=$(ARCH) ROOT=$(PWD) all
|
||||||
|
|
||||||
|
user:
|
||||||
|
make -C user ARCH=$(ARCH) ROOT=$(PWD) all
|
||||||
|
|
||||||
|
ulib:
|
||||||
|
make -C ulib ARCH=$(ARCH) ROOT=$(PWD) all
|
||||||
|
|
||||||
prepare:
|
prepare:
|
||||||
if [ ! -d limine ]; then \
|
if [ ! -d limine ]; then \
|
||||||
@ -9,37 +17,31 @@ prepare:
|
|||||||
cd limine; \
|
cd limine; \
|
||||||
make; \
|
make; \
|
||||||
fi
|
fi
|
||||||
|
if [ ! -d toolchain/binutils-gdb ]; then \
|
||||||
|
cd toolchain; \
|
||||||
|
git clone git://sourceware.org/git/binutils-gdb.git --depth=1; \
|
||||||
|
$(PWD)/scripts/build-binutils-gdb.sh; \
|
||||||
|
cd ..; \
|
||||||
|
fi
|
||||||
|
if [ ! -d toolchain/gcc ]; then \
|
||||||
|
cd toolchain; \
|
||||||
|
git clone https://gcc.gnu.org/git/gcc.git --depth=1; \
|
||||||
|
$(PWD)/scripts/build-gcc.sh; \
|
||||||
|
cd ..; \
|
||||||
|
fi
|
||||||
|
|
||||||
cleanall:
|
cleanall:
|
||||||
make clean
|
make clean
|
||||||
rm -rf limine
|
rm -rf limine
|
||||||
rm -rf littlefs-fuse
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
make -C kernel clean
|
make -C kernel ARCH=$(ARCH) ROOT=$(PWD) clean
|
||||||
|
make -C user ARCH=$(ARCH) ROOT=$(PWD) clean
|
||||||
|
make -C ulib ARCH=$(ARCH) ROOT=$(PWD) clean
|
||||||
rm -f mop2.iso base.img
|
rm -f mop2.iso base.img
|
||||||
|
|
||||||
base:
|
base:
|
||||||
@rm -f base.img
|
./scripts/mkbaseimg.sh
|
||||||
@rm -rf base_root
|
|
||||||
@mkdir -p base_root
|
|
||||||
mklittlefs -c base_root -b 4096 -s $$((1<<20)) base.img
|
|
||||||
|
|
||||||
iso:
|
iso:
|
||||||
@rm -rf iso_root
|
./scripts/mkiso.sh
|
||||||
@mkdir -p iso_root/boot
|
|
||||||
@cp -v kernel/mop2 iso_root/boot
|
|
||||||
@cp -v base.img iso_root
|
|
||||||
@mkdir -p iso_root/boot/limine
|
|
||||||
@cp -v limine.conf limine/limine-bios.sys limine/limine-bios-cd.bin \
|
|
||||||
limine/limine-uefi-cd.bin iso_root/boot/limine
|
|
||||||
@mkdir -p iso_root/EFI/BOOT
|
|
||||||
@cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT
|
|
||||||
@cp -v limine/BOOTIA32.EFI iso_root/EFI/BOOT
|
|
||||||
@xorriso -as mkisofs -R -r -J -b boot/limine/limine-bios-cd.bin \
|
|
||||||
-no-emul-boot -boot-load-size 4 -boot-info-table -hfsplus \
|
|
||||||
-apm-block-size 2048 --efi-boot boot/limine/limine-uefi-cd.bin \
|
|
||||||
-efi-boot-part --efi-boot-image --protective-msdos-label \
|
|
||||||
iso_root -o mop2.iso
|
|
||||||
@./limine/limine bios-install mop2.iso
|
|
||||||
|
|
||||||
|
3
base/bin/.gitignore
vendored
Normal file
3
base/bin/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
|
!.gitkeep
|
3
base/scripts/init.tb
Normal file
3
base/scripts/init.tb
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
print 'this is an init script!'
|
||||||
|
base:/bin/pctl ls
|
||||||
|
base:/bin/tb -m interactive -preload base:/scripts/rc.tb
|
4
base/scripts/rc.tb
Normal file
4
base/scripts/rc.tb
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
mkalias pctl base:/bin/pctl
|
||||||
|
mkalias tb base:/bin/tb
|
||||||
|
mkalias fs base:/bin/fs
|
||||||
|
mkalias dev base:/bin/dev
|
6292
dlmalloc/malloc.c
Normal file
6292
dlmalloc/malloc.c
Normal file
File diff suppressed because it is too large
Load Diff
12
dlmalloc/malloc.h
Normal file
12
dlmalloc/malloc.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef MALLOC_MALLOC_H_
|
||||||
|
#define MALLOC_MALLOC_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void *dlmalloc(size_t);
|
||||||
|
void dlfree(void *);
|
||||||
|
void *dlcalloc(size_t, size_t);
|
||||||
|
void *dlrealloc(void *, size_t);
|
||||||
|
void *dlrealloc_in_place(void *, size_t);
|
||||||
|
|
||||||
|
#endif // MALLOC_MALLOC_H_
|
@ -1,24 +1,23 @@
|
|||||||
|
include $(ROOT)/mk/grabsrc.mk
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
ARCH ?= x86_64
|
|
||||||
PUTCHAR_ ?= fb
|
PUTCHAR_ ?= fb
|
||||||
|
|
||||||
CFLAGS := -ffreestanding -Wall -Wextra -g -fcommon -nostdinc
|
CFLAGS := -ffreestanding -Wall -Wextra -g -fcommon -nostdinc
|
||||||
|
|
||||||
CFLAGS += -I. \
|
CFLAGS += -I. \
|
||||||
-I../limine \
|
-I$(ROOT)/limine \
|
||||||
-I./std/include \
|
-I$(ROOT)/std/include \
|
||||||
-I./flanterm/src \
|
-I./std \
|
||||||
-DPRINTF_INCLUDE_CONFIG_H=1 \
|
-I./flanterm/src \
|
||||||
-DLFS_NO_ASSERT \
|
-I$(ROOT)/share \
|
||||||
-DLFS_NO_DEBUG \
|
-DPRINTF_INCLUDE_CONFIG_H=1 \
|
||||||
-DLFS_NO_WARN \
|
-DLFS_NO_ASSERT \
|
||||||
-DLFS_NO_ERROR \
|
-DLFS_NO_DEBUG \
|
||||||
-DUACPI_BAREBONES_MODE
|
-DLFS_NO_WARN \
|
||||||
|
-DLFS_NO_ERROR \
|
||||||
ifeq ($(ARCH),x86_64)
|
-DUACPI_BAREBONES_MODE
|
||||||
CFLAGS += -I./hal/x86_64/uACPI/include
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(PUTCHAR_),fb)
|
ifeq ($(PUTCHAR_),fb)
|
||||||
CFLAGS += -DPUTCHAR_=PUTCHAR_FB
|
CFLAGS += -DPUTCHAR_=PUTCHAR_FB
|
||||||
@ -29,42 +28,42 @@ endif
|
|||||||
include arch/$(ARCH)/$(ARCH).mk
|
include arch/$(ARCH)/$(ARCH).mk
|
||||||
include extconf/extra.mk
|
include extconf/extra.mk
|
||||||
|
|
||||||
LDFLAGS := -nostdlib -static -T arch/$(ARCH)/link.ld $(shell $(CC) -print-libgcc-file-name)
|
LDFLAGS += -nostdlib -static -T arch/$(ARCH)/link.ld $(shell $(CC) -print-libgcc-file-name)
|
||||||
|
|
||||||
SRCFILES := $(wildcard *.c) \
|
SRCFILES :=
|
||||||
$(wildcard printf/*.c) \
|
|
||||||
$(wildcard bitmap/*.c) \
|
|
||||||
$(wildcard pmm/*.c) \
|
|
||||||
$(wildcard bootinfo/*.c) \
|
|
||||||
$(wildcard spinlock/*.c) \
|
|
||||||
$(wildcard term/*.c) \
|
|
||||||
$(wildcard vmm/*.c) \
|
|
||||||
$(wildcard dlmalloc/*.c) \
|
|
||||||
$(wildcard vfs/*.c) \
|
|
||||||
$(wildcard storedev/*.c) \
|
|
||||||
$(wildcard util/*.c) \
|
|
||||||
$(wildcard fs/kvfs/*.c) \
|
|
||||||
$(wildcard fs/littlefs/*.c) \
|
|
||||||
$(wildcard fs/portlfs/*.c) \
|
|
||||||
$(wildcard baseimg/*.c) \
|
|
||||||
$(wildcard hal/*.c) \
|
|
||||||
$(wildcard hal/$(ARCH)/*.c) \
|
|
||||||
$(wildcard hal/$(ARCH)/*.S) \
|
|
||||||
$(wildcard paging/$(ARCH)/*.c) \
|
|
||||||
$(wildcard paging/*.c) \
|
|
||||||
$(wildcard *.S) \
|
|
||||||
$(wildcard std/*.c) \
|
|
||||||
$(wildcard flanterm/src/*.c) \
|
|
||||||
$(wildcard flanterm/src/flanterm_backends/*.c)
|
|
||||||
|
|
||||||
ifeq ($(ARCH),x86_64)
|
SRCFILES += $(call GRABSRC, \
|
||||||
SRCFILES += $(wildcard hal/x86_64/uACPI/source/*.c)
|
. \
|
||||||
SRCFILES += $(wildcard hal/x86_64/port-uACPI/*.c)
|
printf \
|
||||||
endif
|
bitmap \
|
||||||
|
pmm \
|
||||||
|
bootinfo \
|
||||||
|
spinlock \
|
||||||
|
term \
|
||||||
|
dlmalloc \
|
||||||
|
vfs \
|
||||||
|
storedev \
|
||||||
|
util \
|
||||||
|
fs/kvfs \
|
||||||
|
fs/littlefs \
|
||||||
|
fs/portlfs \
|
||||||
|
baseimg \
|
||||||
|
proc \
|
||||||
|
hal \
|
||||||
|
hal/$(ARCH) \
|
||||||
|
std \
|
||||||
|
flanterm/src \
|
||||||
|
flanterm/src/flanterm_backends \
|
||||||
|
syscall \
|
||||||
|
path \
|
||||||
|
rbuf \
|
||||||
|
ipc/pipe \
|
||||||
|
dev \
|
||||||
|
)
|
||||||
|
|
||||||
CFILES := $(filter %.c,$(SRCFILES))
|
CFILES := $(call GET_CFILES, $(SRCFILES))
|
||||||
ASFILES := $(filter %.S,$(SRCFILES))
|
ASFILES := $(call GET_ASFILES, $(SRCFILES))
|
||||||
OBJ := $(patsubst %.c,%.o,$(CFILES)) $(patsubst %.S,%.o,$(ASFILES))
|
OBJ := $(call GET_OBJ, $(SRCFILES))
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
CC := x86_64-elf-gcc
|
include $(ROOT)/mk/arch/toolchain-x86_64.mk
|
||||||
LD := x86_64-elf-ld
|
|
||||||
|
|
||||||
CFLAGS += -m64 \
|
CFLAGS += -m64 \
|
||||||
-fPIE \
|
-fPIE \
|
||||||
@ -12,7 +11,7 @@ CFLAGS += -m64 \
|
|||||||
-mno-red-zone \
|
-mno-red-zone \
|
||||||
-fno-stack-protector \
|
-fno-stack-protector \
|
||||||
-fno-stack-check \
|
-fno-stack-check \
|
||||||
-Os \
|
-O0 \
|
||||||
|
|
||||||
LDFLAGS += -m elf_x86_64 \
|
LDFLAGS += -m elf_x86_64 \
|
||||||
-pie \
|
-pie \
|
||||||
|
6
kernel/atomic.h
Normal file
6
kernel/atomic.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef ATOMIC_H_
|
||||||
|
#define ATOMIC_H_
|
||||||
|
|
||||||
|
#define ATOMIC(X) _Atomic(X)
|
||||||
|
|
||||||
|
#endif // ATOMIC_H_
|
@ -32,7 +32,7 @@ void baseimg_init(void) {
|
|||||||
hal_hang();
|
hal_hang();
|
||||||
} else {
|
} else {
|
||||||
LOG("baseimg", "base.img found\n");
|
LOG("baseimg", "base.img found\n");
|
||||||
LOG("baseimg", "addr = %p, size = %lld\n", baseimg->address, baseimg->size);
|
LOG("baseimg", "addr = %p, size = %lu\n", baseimg->address, baseimg->size);
|
||||||
for (size_t i = 0; i < 30; i++) {
|
for (size_t i = 0; i < 30; i++) {
|
||||||
kprintf("%02X ", ((uint8_t *)(baseimg->address))[i]);
|
kprintf("%02X ", ((uint8_t *)(baseimg->address))[i]);
|
||||||
if (i > 0 && (i + 1) % 10 == 0) {
|
if (i > 0 && (i + 1) % 10 == 0) {
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
|
#include "util/util.h"
|
||||||
#define DIV_ROUNDUP(num, div) ((num + div - 1) / div)
|
#include "kprintf.h"
|
||||||
|
|
||||||
void *bitmap_toptr(BitMap *bm, size_t block) {
|
void *bitmap_toptr(BitMap *bm, size_t block) {
|
||||||
uint8_t *ptr = (uint8_t *)(bm->mem_start + (block * BITMAP_BLOCK_SIZE));
|
uint8_t *ptr = (uint8_t *)(bm->mem_start + (block * BITMAP_BLOCK_SIZE));
|
||||||
@ -17,12 +17,12 @@ size_t bitmap_toblock(BitMap *bm, void *ptr) {
|
|||||||
|
|
||||||
size_t bitmap_toblock_roundup(BitMap *bm, void *ptr) {
|
size_t bitmap_toblock_roundup(BitMap *bm, void *ptr) {
|
||||||
uint8_t *p = ptr;
|
uint8_t *p = ptr;
|
||||||
return (size_t)DIV_ROUNDUP((size_t)(p - bm->mem_start), BITMAP_BLOCK_SIZE);
|
return (size_t)_DIV_ROUNDUP((size_t)(p - bm->mem_start), BITMAP_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bitmap_calcsize(size_t total) {
|
size_t bitmap_calcsize(size_t total) {
|
||||||
size_t nblocks = DIV_ROUNDUP(total, BITMAP_BLOCK_SIZE);
|
size_t nblocks = _DIV_ROUNDUP(total, BITMAP_BLOCK_SIZE);
|
||||||
size_t nbytes = DIV_ROUNDUP(nblocks, 8);
|
size_t nbytes = _DIV_ROUNDUP(nblocks, 8);
|
||||||
return nbytes;
|
return nbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ void bitmap_markregion(BitMap *bm, void *baseptr, size_t size, bool is_used) {
|
|||||||
|
|
||||||
if (is_used) {
|
if (is_used) {
|
||||||
base = bitmap_toblock(bm, baseptr);
|
base = bitmap_toblock(bm, baseptr);
|
||||||
size1 = DIV_ROUNDUP(size, BITMAP_BLOCK_SIZE);
|
size1 = _DIV_ROUNDUP(size, BITMAP_BLOCK_SIZE);
|
||||||
} else {
|
} else {
|
||||||
base = bitmap_toblock(bm, baseptr);
|
base = bitmap_toblock(bm, baseptr);
|
||||||
size1 = size / BITMAP_BLOCK_SIZE;
|
size1 = size / BITMAP_BLOCK_SIZE;
|
||||||
@ -105,13 +105,3 @@ void *bitmap_alloc(BitMap *bm, size_t blocks) {
|
|||||||
void bitmap_free(BitMap *bm, void *base, size_t blocks) {
|
void bitmap_free(BitMap *bm, void *base, size_t blocks) {
|
||||||
bitmap_markregion(bm, base, BITMAP_BLOCK_SIZE * blocks, 0);
|
bitmap_markregion(bm, base, BITMAP_BLOCK_SIZE * blocks, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bitmap_allocpageframe(BitMap *bm) {
|
|
||||||
size_t pickedreg = bitmap_freeregion(bm, 1);
|
|
||||||
bitmap_markblocks(bm, pickedreg, 1, 1);
|
|
||||||
return (bm->mem_start + (pickedreg * BITMAP_BLOCK_SIZE));
|
|
||||||
}
|
|
||||||
|
|
||||||
void bitmap_freepageframe(BitMap *bm, void *addr) {
|
|
||||||
bitmap_markregion(bm, addr, BITMAP_BLOCK_SIZE * 1, 0);
|
|
||||||
}
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "hal/hal.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t *map;
|
uint8_t *map;
|
||||||
size_t nblocks;
|
size_t nblocks;
|
||||||
@ -12,11 +14,10 @@ typedef struct {
|
|||||||
size_t alloc_blocks;
|
size_t alloc_blocks;
|
||||||
size_t last_deep_frag;
|
size_t last_deep_frag;
|
||||||
uintptr_t mem_start;
|
uintptr_t mem_start;
|
||||||
bool init;
|
|
||||||
} BitMap;
|
} BitMap;
|
||||||
|
|
||||||
#define BITMAP_BLOCKS_PER_BYTE 8
|
#define BITMAP_BLOCKS_PER_BYTE 8
|
||||||
#define BITMAP_BLOCK_SIZE 0x1000
|
#define BITMAP_BLOCK_SIZE HAL_PAGE_SIZE
|
||||||
#define BITMAP_INVALID_BLOCK ((size_t)-1)
|
#define BITMAP_INVALID_BLOCK ((size_t)-1)
|
||||||
|
|
||||||
void *bitmap_toptr(BitMap *bm, size_t block);
|
void *bitmap_toptr(BitMap *bm, size_t block);
|
||||||
@ -30,7 +31,5 @@ void bitmap_markregion(BitMap *bm, void *baseptr, size_t size, bool is_used);
|
|||||||
size_t bitmap_freeregion(BitMap *bm, size_t blocks);
|
size_t bitmap_freeregion(BitMap *bm, size_t blocks);
|
||||||
void *bitmap_alloc(BitMap *bm, size_t blocks);
|
void *bitmap_alloc(BitMap *bm, size_t blocks);
|
||||||
void bitmap_free(BitMap *bm, void *base, size_t blocks);
|
void bitmap_free(BitMap *bm, void *base, size_t blocks);
|
||||||
size_t bitmap_allocpageframe(BitMap *bm);
|
|
||||||
void bitmap_freepageframe(BitMap *bm, void *addr);
|
|
||||||
|
|
||||||
#endif // BITMAP_BITMAP_H_
|
#endif // BITMAP_BITMAP_H_
|
||||||
|
@ -13,11 +13,7 @@ BootInfo BOOT_INFO;
|
|||||||
static volatile struct limine_paging_mode_request paging_req = {
|
static volatile struct limine_paging_mode_request paging_req = {
|
||||||
.id = LIMINE_PAGING_MODE_REQUEST,
|
.id = LIMINE_PAGING_MODE_REQUEST,
|
||||||
.revision = 0,
|
.revision = 0,
|
||||||
#if defined(__x86_64__)
|
|
||||||
.mode = LIMINE_PAGING_MODE_X86_64_4LVL,
|
.mode = LIMINE_PAGING_MODE_X86_64_4LVL,
|
||||||
#else
|
|
||||||
# error "Paging mode is unknown for this architecture"
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_REQ(kernel_address, KERNEL_ADDRESS);
|
DEFINE_REQ(kernel_address, KERNEL_ADDRESS);
|
||||||
@ -38,9 +34,7 @@ void bootinfo_init(void) {
|
|||||||
BOOT_INFO.modules = modulesres;
|
BOOT_INFO.modules = modulesres;
|
||||||
|
|
||||||
struct limine_paging_mode_response *pagingres = paging_req.response;
|
struct limine_paging_mode_response *pagingres = paging_req.response;
|
||||||
#if defined(__x86_64__)
|
|
||||||
if (pagingres->mode != LIMINE_PAGING_MODE_X86_64_4LVL) {
|
if (pagingres->mode != LIMINE_PAGING_MODE_X86_64_4LVL) {
|
||||||
#endif
|
|
||||||
hal_hang();
|
hal_hang();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#ifndef COMPILER_ATTR_H_
|
#ifndef COMPILER_ATTR_H_
|
||||||
#define COMPILER_ATTR_H_
|
#define COMPILER_ATTR_H_
|
||||||
|
|
||||||
#define PACKED __attribute__((packed))
|
#define PACKED __attribute__((packed))
|
||||||
|
#define ALIGNED(x) __attribute__((aligned((x))))
|
||||||
|
#define NORETURN __attribute__((noreturn))
|
||||||
|
#define UNUSED __attribute__((unused))
|
||||||
|
|
||||||
#endif // COMPILER_ATTR_H_
|
#endif // COMPILER_ATTR_H_
|
||||||
|
22
kernel/dev/dev.c
Normal file
22
kernel/dev/dev.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "spinlock/spinlock.h"
|
||||||
|
#include "dev.h"
|
||||||
|
#include "hshtb.h"
|
||||||
|
#include "hal/hal.h"
|
||||||
|
#include "termdev.h"
|
||||||
|
#include "ps2kbdev.h"
|
||||||
|
#include "serialdev.h"
|
||||||
|
#include "fbdev.h"
|
||||||
|
|
||||||
|
DevTable DEVTABLE;
|
||||||
|
|
||||||
|
void dev_init(void) {
|
||||||
|
hal_memset(&DEVTABLE, 0, sizeof(DEVTABLE));
|
||||||
|
spinlock_init(&DEVTABLE.spinlock);
|
||||||
|
|
||||||
|
termdev_init();
|
||||||
|
ps2kbdev_init();
|
||||||
|
serialdev_init();
|
||||||
|
fbdev_init();
|
||||||
|
}
|
28
kernel/dev/dev.h
Normal file
28
kernel/dev/dev.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef DEV_DEV_H_
|
||||||
|
#define DEV_DEV_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "spinlock/spinlock.h"
|
||||||
|
|
||||||
|
#define DEV_FNS_MAX 32
|
||||||
|
|
||||||
|
typedef int32_t (*DevFn)(uint8_t *buffer, size_t len, void *extra);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int _hshtbstate;
|
||||||
|
char ident[0x100];
|
||||||
|
DevFn fns[DEV_FNS_MAX];
|
||||||
|
SpinLock spinlock;
|
||||||
|
} Dev;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SpinLock spinlock;
|
||||||
|
Dev devs[0x100];
|
||||||
|
} DevTable;
|
||||||
|
|
||||||
|
extern DevTable DEVTABLE;
|
||||||
|
|
||||||
|
void dev_init(void);
|
||||||
|
|
||||||
|
#endif // DEV_DEV_H_
|
29
kernel/dev/fbdev.c
Normal file
29
kernel/dev/fbdev.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "fbdev.h"
|
||||||
|
#include "dev.h"
|
||||||
|
#include "sysdefs/devctl.h"
|
||||||
|
#include "hshtb.h"
|
||||||
|
#include "spinlock/spinlock.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
#include "hal/hal.h"
|
||||||
|
#include "bootinfo/bootinfo.h"
|
||||||
|
#include "errors.h"
|
||||||
|
|
||||||
|
int32_t fbdev_getinfo(uint8_t *buffer, size_t len, void *extra) {
|
||||||
|
FbDevGetInfo info = {
|
||||||
|
.w = BOOT_INFO.fb->width,
|
||||||
|
.h = BOOT_INFO.fb->height,
|
||||||
|
.margin = 20,
|
||||||
|
.fontw = 8,
|
||||||
|
.fonth = 16,
|
||||||
|
};
|
||||||
|
hal_memcpy(buffer, &info, sizeof(info));
|
||||||
|
return E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fbdev_init(void) {
|
||||||
|
Dev *fbdev;
|
||||||
|
HSHTB_ALLOC(DEVTABLE.devs, ident, "fbdev", fbdev);
|
||||||
|
fbdev->fns[DEV_FBDEV_GETINFO] = &fbdev_getinfo;
|
||||||
|
}
|
7
kernel/dev/fbdev.h
Normal file
7
kernel/dev/fbdev.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef DEV_FBDEV_H_
|
||||||
|
#define DEV_FBDEV_H_
|
||||||
|
|
||||||
|
int32_t fbdev_getinfo(uint8_t *buffer, size_t len, void *extra);
|
||||||
|
void fbdev_init(void);
|
||||||
|
|
||||||
|
#endif // DEV_FBDEV_H_
|
259
kernel/dev/ps2kbdev.c
Normal file
259
kernel/dev/ps2kbdev.c
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "kprintf.h"
|
||||||
|
#include "hal/hal.h"
|
||||||
|
#include "ps2kbdev.h"
|
||||||
|
#include "dev.h"
|
||||||
|
#include "errors.h"
|
||||||
|
#include "dlmalloc/malloc.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
#include "hshtb.h"
|
||||||
|
#include "sysdefs/devctl.h"
|
||||||
|
#include "proc/proc.h"
|
||||||
|
|
||||||
|
#define KB_CTL_STATUS 0x64
|
||||||
|
#define KB_DATA_IN_BUF 0x01
|
||||||
|
#define KB_DATA 0x60
|
||||||
|
|
||||||
|
#define KB_SHIFT (1<<0)
|
||||||
|
#define KB_CTL (1<<1)
|
||||||
|
#define KB_ALT (1<<2)
|
||||||
|
|
||||||
|
#define KB_CAPSLOCK (1<<3)
|
||||||
|
#define KB_NUMLOCK (1<<4)
|
||||||
|
#define KB_SCRLLOCK (1<<5)
|
||||||
|
#define KB_E0ESC (1<<6)
|
||||||
|
|
||||||
|
#define KB_HOME 0xe0
|
||||||
|
#define KB_END 0xe1
|
||||||
|
#define KB_UP 0xe2
|
||||||
|
#define KB_DOWN 0xe3
|
||||||
|
#define KB_LEFT 0xe4
|
||||||
|
#define KB_RIGHT 0xe5
|
||||||
|
#define KB_PAGEUP 0xe6
|
||||||
|
#define KB_PAGEDN 0xe7
|
||||||
|
#define KB_INSERT 0xe8
|
||||||
|
#define KB_DELETE 0xe9
|
||||||
|
|
||||||
|
#define C(x) ((x)-'@')
|
||||||
|
|
||||||
|
static uint8_t shiftcode[0x100] = {
|
||||||
|
[0x1d] KB_CTL,
|
||||||
|
[0x2a] KB_SHIFT,
|
||||||
|
[0x36] KB_SHIFT,
|
||||||
|
[0x38] KB_ALT,
|
||||||
|
[0x9d] KB_CTL,
|
||||||
|
[0xb8] KB_ALT,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t togglecode[0x100] = {
|
||||||
|
[0x3a] KB_CAPSLOCK,
|
||||||
|
[0x45] KB_NUMLOCK,
|
||||||
|
[0x46] KB_SCRLLOCK,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t normalmap[0x100] = {
|
||||||
|
0x0, 0x1b, '1', '2', '3', '4', '5', '6',
|
||||||
|
'7', '8', '9', '0', '-', '=', '\b', '\t',
|
||||||
|
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
|
||||||
|
'o', 'p', '[', ']', '\n', 0x0, 'a', 's',
|
||||||
|
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
|
||||||
|
'\'', '`', 0x0, '\\', 'z', 'x', 'c', 'v',
|
||||||
|
'b', 'n', 'm', ',', '.', '/', 0x0, '*',
|
||||||
|
0x0, ' ', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7',
|
||||||
|
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||||
|
'2', '3', '0', '.', 0x0, 0x0, 0x0, 0x0,
|
||||||
|
[0x9c] '\n',
|
||||||
|
[0xb5] '/',
|
||||||
|
[0xc8] KB_UP, [0xd0] KB_DOWN,
|
||||||
|
[0xc9] KB_PAGEUP, [0xd1] KB_PAGEDN,
|
||||||
|
[0xcb] KB_LEFT, [0xcd] KB_RIGHT,
|
||||||
|
[0x97] KB_HOME, [0xcf] KB_END,
|
||||||
|
[0xd2] KB_INSERT, [0xd3] KB_DELETE,
|
||||||
|
[0xc7] KB_HOME,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t shiftmap[256] = {
|
||||||
|
0x0, 033,'!', '@', '#', '$', '%', '^',
|
||||||
|
'&', '*', '(', ')', '_', '+', '\b', '\t',
|
||||||
|
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
|
||||||
|
'O', 'P', '{', '}', '\n', 0x0, 'A', 'S',
|
||||||
|
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
|
||||||
|
'"', '~', 0x0, '|', 'Z', 'X', 'C', 'V',
|
||||||
|
'B', 'N', 'M', '<', '>', '?', 0x0, '*',
|
||||||
|
0x0, ' ', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7',
|
||||||
|
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||||
|
'2', '3', '0', '.', 0x0, 0x0, 0x0, 0x0,
|
||||||
|
[0x9C] '\n',
|
||||||
|
[0xB5] '/',
|
||||||
|
[0xc8] KB_UP, [0xd0] KB_DOWN,
|
||||||
|
[0xc9] KB_PAGEUP, [0xd1] KB_PAGEDN,
|
||||||
|
[0xcb] KB_LEFT, [0xcd] KB_RIGHT,
|
||||||
|
[0x97] KB_HOME, [0xcf] KB_END,
|
||||||
|
[0xd2] KB_INSERT, [0xd3] KB_DELETE,
|
||||||
|
[0xc7] KB_HOME,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t ctlmap[256] =
|
||||||
|
{
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
C('Q'), C('W'), C('E'), C('R'), C('T'), C('Y'), C('U'), C('I'),
|
||||||
|
C('O'), C('P'), 0x0, 0x0, '\r', 0x0, C('A'), C('S'),
|
||||||
|
C('D'), C('F'), C('G'), C('H'), C('J'), C('K'), C('L'), 0x0,
|
||||||
|
0x0, 0x0, 0x0, C('\\'), C('Z'), C('X'), C('C'), C('V'),
|
||||||
|
C('B'), C('N'), C('M'), 0x0, 0x0, C('/'), 0x0, 0x0,
|
||||||
|
[0x9C] '\r',
|
||||||
|
[0xB5] C('/'),
|
||||||
|
[0xc8] KB_UP, [0xd0] KB_DOWN,
|
||||||
|
[0xc9] KB_PAGEUP, [0xd1] KB_PAGEDN,
|
||||||
|
[0xcb] KB_LEFT, [0xcd] KB_RIGHT,
|
||||||
|
[0x97] KB_HOME, [0xcf] KB_END,
|
||||||
|
[0xd2] KB_INSERT, [0xd3] KB_DELETE,
|
||||||
|
[0xc7] KB_HOME,
|
||||||
|
};
|
||||||
|
|
||||||
|
int32_t ps2kb_intr(void) {
|
||||||
|
static uint8_t shift;
|
||||||
|
static uint8_t *charcode[4] = { normalmap, shiftmap, ctlmap, ctlmap };
|
||||||
|
uint32_t st, data, c;
|
||||||
|
|
||||||
|
st = io_in8(KB_CTL_STATUS);
|
||||||
|
if (!(st & KB_DATA_IN_BUF)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data = io_in8(KB_DATA);
|
||||||
|
|
||||||
|
if (data == 0xe0) {
|
||||||
|
shift |= KB_E0ESC;
|
||||||
|
return 0;
|
||||||
|
} else if (data & 0x80) {
|
||||||
|
data = (shift & KB_E0ESC ? data : data & 0x7F);
|
||||||
|
shift &= ~(shiftcode[data] | KB_E0ESC);
|
||||||
|
return 0;
|
||||||
|
} else if (shift & KB_E0ESC) {
|
||||||
|
data |= 0x80;
|
||||||
|
shift &= ~KB_E0ESC;
|
||||||
|
}
|
||||||
|
|
||||||
|
shift |= shiftcode[data];
|
||||||
|
shift ^= togglecode[data];
|
||||||
|
c = charcode[shift & (KB_CTL | KB_SHIFT)][data];
|
||||||
|
if (shift & KB_CAPSLOCK) {
|
||||||
|
if ('a' <= c && c <= 'z') {
|
||||||
|
c += 'A' - 'a';
|
||||||
|
} else if ('A' <= c && c <= 'Z') {
|
||||||
|
c += 'a' - 'A';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct Ps2kbEvConsumer {
|
||||||
|
struct Ps2kbEvConsumer *next;
|
||||||
|
Proc *proc;
|
||||||
|
RBuf rbuf;
|
||||||
|
} Ps2kbEvConsumer;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
SpinLock spinlock;
|
||||||
|
Ps2kbEvConsumer *list;
|
||||||
|
} PS2KB_CONSUMERS = {0};
|
||||||
|
|
||||||
|
int32_t ps2kbdev_readch(uint8_t *buffer, size_t len, void *extra) {
|
||||||
|
uint64_t pid = (uint64_t)buffer;
|
||||||
|
Proc *consproc = NULL;
|
||||||
|
spinlock_acquire(&PROCS.spinlock);
|
||||||
|
Proc *proc, *proctmp;
|
||||||
|
LL_FOREACH_SAFE(PROCS.procs, proc, proctmp) {
|
||||||
|
if (proc->pid == pid) {
|
||||||
|
consproc = proc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spinlock_release(&PROCS.spinlock);
|
||||||
|
|
||||||
|
if (consproc == NULL) {
|
||||||
|
return E_INVALIDOPER;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t b;
|
||||||
|
int32_t r = -1;
|
||||||
|
|
||||||
|
spinlock_acquire(&PS2KB_CONSUMERS.spinlock);
|
||||||
|
Ps2kbEvConsumer *cons, *constmp;
|
||||||
|
LL_FOREACH_SAFE(PS2KB_CONSUMERS.list, cons, constmp) {
|
||||||
|
if (cons->proc == consproc) {
|
||||||
|
r = rbuf_pop(&cons->rbuf, &b);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spinlock_release(&PS2KB_CONSUMERS.spinlock);
|
||||||
|
|
||||||
|
if (r == 0) {
|
||||||
|
return b;
|
||||||
|
} else {
|
||||||
|
return E_NOTYET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CONSUMER_RBUF_MAX 0x400
|
||||||
|
|
||||||
|
int32_t ps2kbdev_attchcons(uint8_t *buffer, size_t len, void *extra) {
|
||||||
|
uint64_t pid = (uint64_t)buffer;
|
||||||
|
spinlock_acquire(&PROCS.spinlock);
|
||||||
|
Proc *proc, *proctmp;
|
||||||
|
LL_FOREACH_SAFE(PROCS.procs, proc, proctmp) {
|
||||||
|
if (proc->pid == pid) {
|
||||||
|
Ps2kbEvConsumer *cons = dlmalloc(sizeof(*cons));
|
||||||
|
cons->proc = proc;
|
||||||
|
uint8_t *buf = dlmalloc(CONSUMER_RBUF_MAX);
|
||||||
|
rbuf_init(&cons->rbuf, buf, CONSUMER_RBUF_MAX);
|
||||||
|
spinlock_acquire(&PS2KB_CONSUMERS.spinlock);
|
||||||
|
LL_APPEND(PS2KB_CONSUMERS.list, cons);
|
||||||
|
spinlock_release(&PS2KB_CONSUMERS.spinlock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spinlock_release(&PROCS.spinlock);
|
||||||
|
return E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ps2kbdev_intr(void) {
|
||||||
|
int32_t c = ps2kb_intr();
|
||||||
|
if (c >= 0) {
|
||||||
|
uint8_t b = c;
|
||||||
|
spinlock_acquire(&PS2KB_CONSUMERS.spinlock);
|
||||||
|
Ps2kbEvConsumer *cons, *constmp;
|
||||||
|
LL_FOREACH_SAFE(PS2KB_CONSUMERS.list, cons, constmp) {
|
||||||
|
bool found = false;
|
||||||
|
spinlock_acquire(&PROCS.spinlock);
|
||||||
|
Proc *proc, *proctmp;
|
||||||
|
LL_FOREACH_SAFE(PROCS.procs, proc, proctmp) {
|
||||||
|
if (proc == cons->proc) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
LL_REMOVE(PS2KB_CONSUMERS.list, cons);
|
||||||
|
}
|
||||||
|
spinlock_release(&PROCS.spinlock);
|
||||||
|
|
||||||
|
rbuf_push(&cons->rbuf, b);
|
||||||
|
}
|
||||||
|
spinlock_release(&PS2KB_CONSUMERS.spinlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ps2kbdev_init(void) {
|
||||||
|
intr_attchhandler(&ps2kbdev_intr, INTR_IRQBASE+1);
|
||||||
|
|
||||||
|
Dev *ps2kbdev;
|
||||||
|
HSHTB_ALLOC(DEVTABLE.devs, ident, "ps2kbdev", ps2kbdev);
|
||||||
|
spinlock_init(&ps2kbdev->spinlock);
|
||||||
|
spinlock_init(&PS2KB_CONSUMERS.spinlock);
|
||||||
|
ps2kbdev->fns[DEV_PS2KBDEV_READCH] = &ps2kbdev_readch;
|
||||||
|
ps2kbdev->fns[DEV_PS2KBDEV_ATTCHCONS] = &ps2kbdev_attchcons;
|
||||||
|
}
|
10
kernel/dev/ps2kbdev.h
Normal file
10
kernel/dev/ps2kbdev.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef DEV_PS2KBDEV_H_
|
||||||
|
#define DEV_PS2KBDEV_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "dev.h"
|
||||||
|
|
||||||
|
void ps2kbdev_init(void);
|
||||||
|
|
||||||
|
#endif // DEV_PS2KBDEV_H_
|
81
kernel/dev/serialdev.c
Normal file
81
kernel/dev/serialdev.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "dev.h"
|
||||||
|
#include "serialdev.h"
|
||||||
|
#include "errors.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
#include "hshtb.h"
|
||||||
|
#include "sysdefs/devctl.h"
|
||||||
|
#include "kprintf.h"
|
||||||
|
#include "hal/hal.h"
|
||||||
|
|
||||||
|
// https://wiki.osdev.org/Serial_Ports
|
||||||
|
|
||||||
|
#define PORT 0x3f8
|
||||||
|
|
||||||
|
void serial_init(void) {
|
||||||
|
io_out8(PORT+1, 0x00);
|
||||||
|
io_out8(PORT+3, 0x80);
|
||||||
|
io_out8(PORT+0, 0x03);
|
||||||
|
io_out8(PORT+1, 0x00);
|
||||||
|
io_out8(PORT+3, 0x03);
|
||||||
|
io_out8(PORT+2, 0xC7);
|
||||||
|
io_out8(PORT+4, 0x0B);
|
||||||
|
io_out8(PORT+4, 0x1E);
|
||||||
|
io_out8(PORT+0, 0xAE);
|
||||||
|
|
||||||
|
if (io_in8(PORT+0) != 0xAE) {
|
||||||
|
ERR("serial", "serial is faulty!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
io_out8(PORT+4, 0x0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
int serial_recvready(void) {
|
||||||
|
return io_in8(PORT+5) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t serial_recvb(void) {
|
||||||
|
return io_in8(PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
int serial_sendready(void) {
|
||||||
|
return io_in8(PORT+5) & 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_sendb(uint8_t b) {
|
||||||
|
io_out8(PORT, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t serialdev_sendb(uint8_t *buffer, size_t len, void *extra) {
|
||||||
|
(void)len; (void)extra;
|
||||||
|
serial_sendb(buffer[0]);
|
||||||
|
return E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t serialdev_sendready(uint8_t *buffer, size_t len, void *extra) {
|
||||||
|
(void)buffer; (void)len; (void) extra;
|
||||||
|
return serial_sendready();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t serialdev_recvb(uint8_t *buffer, size_t len, void *extra) {
|
||||||
|
(void)buffer; (void)len; (void)extra;
|
||||||
|
return serial_recvb();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t serialdev_recvready(uint8_t *buffer, size_t len, void *extra) {
|
||||||
|
(void)buffer; (void)len; (void)extra;
|
||||||
|
return serial_recvready();
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialdev_init(void) {
|
||||||
|
Dev *serialdev = NULL;
|
||||||
|
HSHTB_ALLOC(DEVTABLE.devs, ident, "serialdev", serialdev);
|
||||||
|
serialdev->fns[DEV_SERIALDEV_SENDB] = &serialdev_sendb;
|
||||||
|
serialdev->fns[DEV_SERIALDEV_SENDREADY] = &serialdev_sendready;
|
||||||
|
serialdev->fns[DEV_SERIALDEV_RECVB] = &serialdev_recvb;
|
||||||
|
serialdev->fns[DEV_SERIALDEV_RECVREADY] = &serialdev_recvready;
|
||||||
|
spinlock_init(&serialdev->spinlock);
|
||||||
|
serial_init();
|
||||||
|
}
|
10
kernel/dev/serialdev.h
Normal file
10
kernel/dev/serialdev.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef DEV_SERIALDEV_H_
|
||||||
|
#define DEV_SERIALDEV_H_
|
||||||
|
|
||||||
|
int32_t serialdev_sendb(uint8_t *buffer, size_t len, void *extra);
|
||||||
|
int32_t serialdev_sendready(uint8_t *buffer, size_t len, void *extra);
|
||||||
|
int32_t serialdev_recvb(uint8_t *buffer, size_t len, void *extra);
|
||||||
|
int32_t serialdev_recvready(uint8_t *buffer, size_t len, void *extra);
|
||||||
|
void serialdev_init(void);
|
||||||
|
|
||||||
|
#endif // DEV_SERIALDEV_H_
|
22
kernel/dev/termdev.c
Normal file
22
kernel/dev/termdev.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "kprintf.h"
|
||||||
|
#include "hal/hal.h"
|
||||||
|
#include "termdev.h"
|
||||||
|
#include "dev.h"
|
||||||
|
#include "errors.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
#include "hshtb.h"
|
||||||
|
#include "sysdefs/devctl.h"
|
||||||
|
|
||||||
|
int32_t termdev_putch(uint8_t *buffer, size_t len, void *extra) {
|
||||||
|
kprintf("%.*s", (int)len, (char *)buffer);
|
||||||
|
return E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void termdev_init(void) {
|
||||||
|
Dev *termdev = NULL;
|
||||||
|
HSHTB_ALLOC(DEVTABLE.devs, ident, "termdev", termdev);
|
||||||
|
termdev->fns[DEV_TERMDEV_PUTCH] = &termdev_putch;
|
||||||
|
spinlock_init(&termdev->spinlock);
|
||||||
|
}
|
11
kernel/dev/termdev.h
Normal file
11
kernel/dev/termdev.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef DEV_TERMDEV_H_
|
||||||
|
#define DEV_TERMDEV_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "dev.h"
|
||||||
|
|
||||||
|
int32_t termdev_putch(uint8_t *buffer, size_t len, void *extra);
|
||||||
|
void termdev_init(void);
|
||||||
|
|
||||||
|
#endif // DEV_TERMDEV_H_
|
73
kernel/dlmalloc/dlmalloc_port.inc
Normal file
73
kernel/dlmalloc/dlmalloc_port.inc
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Config
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "hal/hal.h"
|
||||||
|
#include "spinlock/spinlock.h"
|
||||||
|
#include "kprintf.h"
|
||||||
|
#include "bitmap/bitmap.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
#include "pmm/pmm.h"
|
||||||
|
#include "malloc.h"
|
||||||
|
#include "bootinfo/bootinfo.h"
|
||||||
|
|
||||||
|
#define USE_DL_PREFIX 1
|
||||||
|
#define LACKS_SYS_TYPES_H 1
|
||||||
|
#define NO_MALLOC_STATS 1
|
||||||
|
#define LACKS_ERRNO_H 1
|
||||||
|
#define LACKS_TIME_H 1
|
||||||
|
#define LACKS_STDLIB_H 1
|
||||||
|
#define LACKS_SYS_MMAN_H 1
|
||||||
|
#define LACKS_FCNTL_H 1
|
||||||
|
#define LACKS_UNISTD_H 1
|
||||||
|
#define LACKS_SYS_PARAM_H 1
|
||||||
|
#define LACKS_STRINGS_H 1
|
||||||
|
#define LACKS_SCHED_H 1
|
||||||
|
#define HAVE_MMAP 0
|
||||||
|
#define ABORT \
|
||||||
|
do { \
|
||||||
|
ERR("dlmalloc", "Aborting..."); \
|
||||||
|
hal_hang(); \
|
||||||
|
} while(0)
|
||||||
|
#define MALLOC_FAILURE_ACTION
|
||||||
|
#define HAVE_MORECORE 1
|
||||||
|
#define USE_LOCKS 2
|
||||||
|
#define malloc_getpagesize 0x1000
|
||||||
|
#define EINVAL 0xdeadbeef
|
||||||
|
#define ENOMEM 0xb16b00b5
|
||||||
|
#define MORECORE_CONTIGUOUS 0
|
||||||
|
|
||||||
|
#define MLOCK_T SpinLock
|
||||||
|
|
||||||
|
int ACQUIRE_LOCK(SpinLock *sl) {
|
||||||
|
spinlock_acquire(sl);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RELEASE_LOCK(SpinLock *sl) {
|
||||||
|
spinlock_release(sl);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int INITIAL_LOCK(SpinLock *sl) {
|
||||||
|
spinlock_init(sl);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MLOCK_T malloc_global_mutex = { 0 };
|
||||||
|
|
||||||
|
void *_last = 0;
|
||||||
|
|
||||||
|
void *sbrk(long inc) {
|
||||||
|
if (inc < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!inc) {
|
||||||
|
return _last;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t blocks = _DIV_ROUNDUP(inc, BITMAP_BLOCK_SIZE);
|
||||||
|
uint8_t *virt = VIRT(pmm_alloc(blocks));
|
||||||
|
hal_memset(virt, 0, blocks * BITMAP_BLOCK_SIZE);
|
||||||
|
_last = (void *)(virt + inc);
|
||||||
|
return virt;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
1
kernel/dlmalloc/malloc.c
Symbolic link
1
kernel/dlmalloc/malloc.c
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../dlmalloc/malloc.c
|
@ -1,13 +0,0 @@
|
|||||||
#ifndef MALLOC_MALLOC_H_
|
|
||||||
#define MALLOC_MALLOC_H_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
void *dlmalloc(size_t);
|
|
||||||
void dlfree(void *);
|
|
||||||
void *dlcalloc(size_t, size_t);
|
|
||||||
void *dlrealloc(void *, size_t);
|
|
||||||
void *dlrealloc_in_place(void *, size_t);
|
|
||||||
void dlmalloc_check(void);
|
|
||||||
|
|
||||||
#endif // MALLOC_MALLOC_H_
|
|
1
kernel/dlmalloc/malloc.h
Symbolic link
1
kernel/dlmalloc/malloc.h
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../dlmalloc/malloc.h
|
355
kernel/elf.h
Normal file
355
kernel/elf.h
Normal file
@ -0,0 +1,355 @@
|
|||||||
|
#ifndef ELF_H_
|
||||||
|
#define ELF_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define ELFCLASS64 2
|
||||||
|
#define ELFDATA2LSB 1
|
||||||
|
#define ELFOSABI_SYSV 0
|
||||||
|
#define EM_X86_64 62
|
||||||
|
|
||||||
|
#define SHT_NULL 0
|
||||||
|
#define SHT_PROGBITS 1
|
||||||
|
#define SHT_SYMTAB 2
|
||||||
|
#define SHT_STRTAB 3
|
||||||
|
#define SHT_RELA 4
|
||||||
|
#define SHT_HASH 5
|
||||||
|
#define SHT_DYNAMIC 6
|
||||||
|
#define SHT_NOBITS 8
|
||||||
|
#define SHT_DYNSYM 11
|
||||||
|
|
||||||
|
#define SHF_WRITE 1
|
||||||
|
#define SHF_ALLOC 2
|
||||||
|
#define SHF_EXECINSTR 4
|
||||||
|
|
||||||
|
typedef uint64_t Elf64_Addr;
|
||||||
|
typedef uint64_t Elf64_Off;
|
||||||
|
typedef uint16_t Elf64_Half;
|
||||||
|
typedef uint32_t Elf64_Word;
|
||||||
|
typedef int32_t Elf64_Sword;
|
||||||
|
typedef uint64_t Elf64_Xword;
|
||||||
|
typedef int64_t Elf64_Sxword;
|
||||||
|
|
||||||
|
typedef uint32_t Elf32_Addr;
|
||||||
|
typedef uint32_t Elf32_Off;
|
||||||
|
typedef uint16_t Elf32_Half;
|
||||||
|
typedef uint32_t Elf32_Word;
|
||||||
|
typedef int32_t Elf32_Sword;
|
||||||
|
typedef uint64_t Elf32_Xword;
|
||||||
|
typedef int64_t Elf32_Sxword;
|
||||||
|
|
||||||
|
#define EI_NIDENT (16)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char e_ident[EI_NIDENT]; /* ELF identification */
|
||||||
|
Elf32_Half e_type; /* Object file type */
|
||||||
|
Elf32_Half e_machine; /* Machine type */
|
||||||
|
Elf32_Word e_version; /* Object file version */
|
||||||
|
Elf32_Addr e_entry; /* Entry point address */
|
||||||
|
Elf32_Off e_phoff; /* Program header offset */
|
||||||
|
Elf32_Off e_shoff; /* Section header offset */
|
||||||
|
Elf32_Word e_flags; /* Processor-specific flags */
|
||||||
|
Elf32_Half e_ehsize; /* ELF header size */
|
||||||
|
Elf32_Half e_phentsize; /* Size of program header entry */
|
||||||
|
Elf32_Half e_phnum; /* Number of program header entries */
|
||||||
|
Elf32_Half e_shentsize; /* Size of section header entry */
|
||||||
|
Elf32_Half e_shnum; /* Number of section header entries */
|
||||||
|
Elf32_Half e_shstrndx; /* Section name string table index */
|
||||||
|
} Elf32_Ehdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char e_ident[EI_NIDENT]; /* ELF identification */
|
||||||
|
Elf64_Half e_type; /* Object file type */
|
||||||
|
Elf64_Half e_machine; /* Machine type */
|
||||||
|
Elf64_Word e_version; /* Object file version */
|
||||||
|
Elf64_Addr e_entry; /* Entry point address */
|
||||||
|
Elf64_Off e_phoff; /* Program header offset */
|
||||||
|
Elf64_Off e_shoff; /* Section header offset */
|
||||||
|
Elf64_Word e_flags; /* Processor-specific flags */
|
||||||
|
Elf64_Half e_ehsize; /* ELF header size */
|
||||||
|
Elf64_Half e_phentsize; /* Size of program header entry */
|
||||||
|
Elf64_Half e_phnum; /* Number of program header entries */
|
||||||
|
Elf64_Half e_shentsize; /* Size of section header entry */
|
||||||
|
Elf64_Half e_shnum; /* Number of section header entries */
|
||||||
|
Elf64_Half e_shstrndx; /* Section name string table index */
|
||||||
|
} Elf64_Ehdr;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ET_NONE = 0,
|
||||||
|
ET_REL = 1,
|
||||||
|
ET_EXEC = 2,
|
||||||
|
ET_DYN = 3,
|
||||||
|
ET_CORE = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { SHN_UNDEF = 0, SHN_ABS = 0xFFF1 };
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf64_Word st_name;
|
||||||
|
unsigned char st_info;
|
||||||
|
unsigned char st_other;
|
||||||
|
Elf64_Half st_shndx;
|
||||||
|
Elf64_Addr st_value;
|
||||||
|
Elf64_Xword st_size;
|
||||||
|
} Elf64_Sym;
|
||||||
|
|
||||||
|
enum { STB_GLOBAL = 1, STB_WEAK = 2, STB_GNU_UNIQUE = 10 };
|
||||||
|
|
||||||
|
enum { STT_OBJECT = 1, STT_FUNC = 2, STT_TLS = 6 };
|
||||||
|
|
||||||
|
enum {
|
||||||
|
R_X86_64_NONE = 0,
|
||||||
|
R_X86_64_64 = 1,
|
||||||
|
R_X86_64_COPY = 5,
|
||||||
|
R_X86_64_GLOB_DAT = 6,
|
||||||
|
R_X86_64_JUMP_SLOT = 7,
|
||||||
|
R_X86_64_RELATIVE = 8,
|
||||||
|
R_X86_64_DTPMOD64 = 16,
|
||||||
|
R_X86_64_DTPOFF64 = 17,
|
||||||
|
R_X86_64_TPOFF64 = 18,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
R_AARCH64_ABS64 = 257,
|
||||||
|
R_AARCH64_COPY = 1024,
|
||||||
|
R_AARCH64_GLOB_DAT = 1025,
|
||||||
|
R_AARCH64_JUMP_SLOT = 1026,
|
||||||
|
R_AARCH64_RELATIVE = 1027,
|
||||||
|
R_AARCH64_TLS_TPREL = 1030,
|
||||||
|
R_AARCH64_TLSDESC = 1031
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf64_Addr r_offset;
|
||||||
|
uint64_t r_info;
|
||||||
|
} Elf64_Rel;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf64_Addr r_offset;
|
||||||
|
Elf64_Xword r_info;
|
||||||
|
Elf64_Sxword r_addend;
|
||||||
|
} Elf64_Rela;
|
||||||
|
|
||||||
|
static inline Elf64_Xword ELF64_R_SYM(Elf64_Xword info) { return info >> 32; }
|
||||||
|
static inline Elf64_Xword ELF64_R_TYPE(Elf64_Xword info) {
|
||||||
|
return info & 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PT_LOAD = 1,
|
||||||
|
PT_DYNAMIC = 2,
|
||||||
|
PT_INTERP = 3,
|
||||||
|
PT_NOTE = 4,
|
||||||
|
PT_PHDR = 6,
|
||||||
|
PT_TLS = 7,
|
||||||
|
PT_GNU_EH_FRAME = 0x6474E550,
|
||||||
|
PT_GNU_STACK = 0x6474E551,
|
||||||
|
PT_GNU_RELRO = 0x6474E552,
|
||||||
|
PT_GNU_PROPERTY = 0x6474E553,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { PF_X = 1, PF_W = 2, PF_R = 4 };
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf64_Word p_type; /* Type of segment */
|
||||||
|
Elf64_Word p_flags; /* Segment attributes */
|
||||||
|
Elf64_Off p_offset; /* Offset in file */
|
||||||
|
Elf64_Addr p_vaddr; /* Virtual address in memory */
|
||||||
|
Elf64_Addr p_paddr; /* Reserved */
|
||||||
|
Elf64_Xword p_filesz; /* Size of segment in file */
|
||||||
|
Elf64_Xword p_memsz; /* Size of segment in memory */
|
||||||
|
Elf64_Xword p_align; /* Alignment of segment */
|
||||||
|
} Elf64_Phdr;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DT_NULL = 0,
|
||||||
|
DT_NEEDED = 1,
|
||||||
|
DT_PLTRELSZ = 2,
|
||||||
|
DT_PLTGOT = 3,
|
||||||
|
DT_HASH = 4,
|
||||||
|
DT_STRTAB = 5,
|
||||||
|
DT_SYMTAB = 6,
|
||||||
|
DT_RELA = 7,
|
||||||
|
DT_RELASZ = 8,
|
||||||
|
DT_RELAENT = 9,
|
||||||
|
DT_STRSZ = 10,
|
||||||
|
DT_SYMENT = 11,
|
||||||
|
DT_INIT = 12,
|
||||||
|
DT_FINI = 13,
|
||||||
|
DT_SONAME = 14,
|
||||||
|
DT_RPATH = 15,
|
||||||
|
DT_SYMBOLIC = 16,
|
||||||
|
DT_REL = 17,
|
||||||
|
DT_BIND_NOW = 24,
|
||||||
|
DT_INIT_ARRAY = 25,
|
||||||
|
DT_FINI_ARRAY = 26,
|
||||||
|
DT_INIT_ARRAYSZ = 27,
|
||||||
|
DT_FINI_ARRAYSZ = 28,
|
||||||
|
DT_RUNPATH = 29,
|
||||||
|
DT_PLTREL = 20,
|
||||||
|
DT_DEBUG = 21,
|
||||||
|
DT_JMPREL = 23,
|
||||||
|
DT_FLAGS = 30,
|
||||||
|
DT_GNU_HASH = 0x6ffffef5,
|
||||||
|
DT_TLSDESC_PLT = 0x6ffffef6,
|
||||||
|
DT_TLSDESC_GOT = 0x6ffffef7,
|
||||||
|
DT_VERSYM = 0x6ffffff0,
|
||||||
|
DT_RELACOUNT = 0x6ffffff9,
|
||||||
|
DT_FLAGS_1 = 0x6ffffffb,
|
||||||
|
DT_VERDEF = 0x6ffffffc,
|
||||||
|
DT_VERDEFNUM = 0x6ffffffd,
|
||||||
|
DT_VERNEED = 0x6ffffffe,
|
||||||
|
DT_VERNEEDNUM = 0x6fffffff
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// For DT_FLAGS.
|
||||||
|
DF_SYMBOLIC = 0x02,
|
||||||
|
DF_STATIC_TLS = 0x10,
|
||||||
|
|
||||||
|
// For DT_FLAGS_1.
|
||||||
|
DF_1_NOW = 0x00000001
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Sword d_tag;
|
||||||
|
union {
|
||||||
|
Elf32_Word d_val;
|
||||||
|
Elf32_Addr d_ptr;
|
||||||
|
} d_un;
|
||||||
|
} Elf32_Dyn;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf64_Sxword d_tag;
|
||||||
|
union {
|
||||||
|
Elf64_Xword d_val;
|
||||||
|
Elf64_Addr d_ptr;
|
||||||
|
} d_un;
|
||||||
|
} Elf64_Dyn;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Word sh_name;
|
||||||
|
Elf32_Word sh_type;
|
||||||
|
Elf32_Word sh_flags;
|
||||||
|
Elf32_Addr sh_addr;
|
||||||
|
Elf32_Off sh_offset;
|
||||||
|
Elf32_Word sh_size;
|
||||||
|
Elf32_Word sh_link;
|
||||||
|
Elf32_Word sh_info;
|
||||||
|
Elf32_Word sh_addralign;
|
||||||
|
Elf32_Word sh_entsize;
|
||||||
|
} Elf32_Shdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf64_Word sh_name;
|
||||||
|
Elf64_Word sh_type;
|
||||||
|
Elf64_Xword sh_flags;
|
||||||
|
Elf64_Addr sh_addr;
|
||||||
|
Elf64_Off sh_offset;
|
||||||
|
Elf64_Xword sh_size;
|
||||||
|
Elf64_Word sh_link;
|
||||||
|
Elf64_Word sh_info;
|
||||||
|
Elf64_Xword sh_addralign;
|
||||||
|
Elf64_Xword sh_entsize;
|
||||||
|
} Elf64_Shdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Word n_namesz;
|
||||||
|
Elf32_Word n_descsz;
|
||||||
|
Elf32_Word n_type;
|
||||||
|
} Elf32_Nhdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf64_Word n_namesz;
|
||||||
|
Elf64_Word n_descsz;
|
||||||
|
Elf64_Word n_type;
|
||||||
|
} Elf64_Nhdr;
|
||||||
|
|
||||||
|
/* ST_TYPE (subfield of st_info) values (symbol type) */
|
||||||
|
#define STT_NOTYPE 0
|
||||||
|
#define STT_OBJECT 1
|
||||||
|
#define STT_FUNC 2
|
||||||
|
#define STT_SECTION 3
|
||||||
|
#define STT_FILE 4
|
||||||
|
|
||||||
|
/* ST_BIND (subfield of st_info) values (symbol binding) */
|
||||||
|
#define STB_LOCAL 0
|
||||||
|
#define STB_GLOBAL 1
|
||||||
|
#define STB_WEAK 2
|
||||||
|
|
||||||
|
/* sh_type (section type) values */
|
||||||
|
#define SHT_NULL 0
|
||||||
|
#define SHT_PROGBITS 1
|
||||||
|
#define SHT_SYMTAB 2
|
||||||
|
#define SHT_STRTAB 3
|
||||||
|
#define SHT_RELA 4
|
||||||
|
#define SHT_NOBITS 8
|
||||||
|
#define SHT_REL 9
|
||||||
|
#define SHT_INIT_ARRAY 14
|
||||||
|
#define SHT_FINI_ARRAY 15
|
||||||
|
#define SHT_SYMTAB_SHNDX 18
|
||||||
|
|
||||||
|
/* special section indices */
|
||||||
|
#define SHN_UNDEF 0
|
||||||
|
#define SHN_LORESERVE 0xff00
|
||||||
|
#define SHN_COMMON 0xfff2
|
||||||
|
#define SHN_XINDEX 0xffff
|
||||||
|
#define SHN_HIRESERVE 0xff00
|
||||||
|
|
||||||
|
/* values for e_machine */
|
||||||
|
#define EM_NONE 0
|
||||||
|
#define EM_SPARC 2
|
||||||
|
#define EM_386 3
|
||||||
|
#define EM_PPC 20
|
||||||
|
#define EM_PPC64 21
|
||||||
|
#define EM_X86_64 62
|
||||||
|
|
||||||
|
/* e_indent constants */
|
||||||
|
#define EI_MAG0 0
|
||||||
|
#define ELFMAG0 0x7f
|
||||||
|
|
||||||
|
#define EI_MAG1 1
|
||||||
|
#define ELFMAG1 'E'
|
||||||
|
|
||||||
|
#define EI_MAG2 2
|
||||||
|
#define ELFMAG2 'L'
|
||||||
|
|
||||||
|
#define EI_MAG3 3
|
||||||
|
#define ELFMAG3 'F'
|
||||||
|
|
||||||
|
#define EI_CLASS 4
|
||||||
|
#define ELFCLASSNONE 0
|
||||||
|
#define ELFCLASS32 1
|
||||||
|
#define ELFCLASS64 2
|
||||||
|
#define ELFCLASSNUM 3
|
||||||
|
|
||||||
|
#define EI_DATA 5
|
||||||
|
#define ELFDATANONE 0
|
||||||
|
#define ELFDATA2LSB 1
|
||||||
|
#define ELFDATA2MSB 2
|
||||||
|
#define ELFDATANUM 3
|
||||||
|
|
||||||
|
#define AT_NULL 0
|
||||||
|
#define AT_IGNORE 1
|
||||||
|
#define AT_EXECFD 2
|
||||||
|
#define AT_PHDR 3
|
||||||
|
#define AT_PHENT 4
|
||||||
|
#define AT_PHNUM 5
|
||||||
|
#define AT_PAGESZ 6
|
||||||
|
#define AT_BASE 7
|
||||||
|
#define AT_FLAGS 8
|
||||||
|
#define AT_ENTRY 9
|
||||||
|
#define AT_NOTELF 10
|
||||||
|
#define AT_UID 11
|
||||||
|
#define AT_EUID 12
|
||||||
|
#define AT_GID 13
|
||||||
|
#define AT_EGID 14
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t entry;
|
||||||
|
uint64_t phdr;
|
||||||
|
uint64_t phent;
|
||||||
|
uint64_t phnum;
|
||||||
|
} ElfAuxval;
|
||||||
|
|
||||||
|
#endif // ELF_H_
|
@ -1,13 +0,0 @@
|
|||||||
#ifndef ERRORS_H_
|
|
||||||
#define ERRORS_H_
|
|
||||||
|
|
||||||
#define E_OK 0
|
|
||||||
#define E_NOMEMORY -1
|
|
||||||
#define E_UNKNOWN_FSTYPE -2
|
|
||||||
#define E_NOENTRY -3
|
|
||||||
#define E_OUTOFBOUNDS -4
|
|
||||||
#define E_UNKNOWN_SDTYPE -5
|
|
||||||
#define E_TODO -6
|
|
||||||
#define E_GENERIC_ERROR -7
|
|
||||||
|
|
||||||
#endif // ERRORS_H_
|
|
345
kernel/fm-t-437.f16.h
Normal file
345
kernel/fm-t-437.f16.h
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
unsigned char FM_T_437_F16[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0x81, 0xa5, 0xa5, 0x81, 0x81,
|
||||||
|
0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x7e, 0xff, 0xff,
|
||||||
|
0xdb, 0xdb, 0xff, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00,
|
||||||
|
0x00, 0x22, 0x22, 0x77, 0x7f, 0x7f, 0x7f, 0x7f, 0x3e, 0x3e, 0x1c, 0x1c,
|
||||||
|
0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x1c, 0x3e, 0x3e, 0x7f, 0x7f,
|
||||||
|
0x3e, 0x3e, 0x1c, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x1c,
|
||||||
|
0x1c, 0x08, 0x6b, 0x7f, 0x7f, 0x6b, 0x08, 0x1c, 0x3e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x08, 0x1c, 0x3e, 0x7f, 0x7f, 0x7f, 0x7f, 0x2a, 0x08, 0x1c,
|
||||||
|
0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x7e, 0x7e, 0x7e,
|
||||||
|
0x7e, 0x7e, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe7, 0xc3,
|
||||||
|
0xc3, 0x81, 0x81, 0x81, 0x81, 0x81, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24,
|
||||||
|
0x18, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe7, 0xdb, 0xdb, 0xbd, 0xbd, 0xbd,
|
||||||
|
0xbd, 0xbd, 0xdb, 0xdb, 0xe7, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x03, 0x05,
|
||||||
|
0x05, 0x08, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00, 0x00,
|
||||||
|
0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x08, 0x08, 0x3e,
|
||||||
|
0x08, 0x08, 0x00, 0x00, 0x00, 0x08, 0x0c, 0x0a, 0x0a, 0x09, 0x09, 0x09,
|
||||||
|
0x08, 0x08, 0x38, 0x78, 0x78, 0x30, 0x00, 0x00, 0x00, 0x3f, 0x21, 0x3f,
|
||||||
|
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x67, 0xe7, 0xe2, 0x40, 0x00,
|
||||||
|
0x00, 0x49, 0x49, 0x2a, 0x36, 0x14, 0x22, 0xe3, 0x22, 0x14, 0x36, 0x2a,
|
||||||
|
0x49, 0x49, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e,
|
||||||
|
0x7c, 0x78, 0x70, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06,
|
||||||
|
0x0e, 0x1e, 0x3e, 0x7e, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x1c, 0x2a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x2a,
|
||||||
|
0x1c, 0x08, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
|
||||||
|
0x22, 0x22, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x3f, 0x49, 0x49,
|
||||||
|
0x49, 0x49, 0x39, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0x00,
|
||||||
|
0x00, 0x3c, 0x42, 0x42, 0x40, 0x20, 0x58, 0x44, 0x22, 0x1a, 0x04, 0x02,
|
||||||
|
0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x2a,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x2a, 0x1c, 0x08, 0x3e, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x1c, 0x2a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x2a, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x04, 0x02, 0x7f, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x7f, 0x20, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40,
|
||||||
|
0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x24, 0x42, 0xff, 0x42, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x1c, 0x1c, 0x3e, 0x3e, 0x7f, 0x7f,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x3e, 0x3e,
|
||||||
|
0x1c, 0x1c, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
|
||||||
|
0x08, 0x08, 0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x24,
|
||||||
|
0x7e, 0x24, 0x24, 0x24, 0x24, 0x24, 0x7e, 0x24, 0x24, 0x24, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x1e, 0x2b, 0x28, 0x28, 0x28, 0x1c, 0x0a, 0x0a, 0x0a, 0x6a,
|
||||||
|
0x3c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x32, 0x52, 0x54, 0x64, 0x08, 0x08,
|
||||||
|
0x10, 0x10, 0x26, 0x2a, 0x4a, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44,
|
||||||
|
0x44, 0x44, 0x28, 0x18, 0x24, 0x45, 0x42, 0x42, 0x42, 0x3d, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00, 0x20, 0x10, 0x10,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x08, 0x49, 0x2a, 0x1c, 0x1c, 0x7f, 0x1c, 0x1c, 0x2a, 0x49,
|
||||||
|
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x3e,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x08, 0x10, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02,
|
||||||
|
0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24,
|
||||||
|
0x24, 0x18, 0x00, 0x00, 0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42,
|
||||||
|
0x42, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00,
|
||||||
|
0x00, 0x3c, 0x42, 0x42, 0x02, 0x02, 0x02, 0x1c, 0x02, 0x02, 0x02, 0x42,
|
||||||
|
0x42, 0x3c, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x0c, 0x14, 0x14, 0x24, 0x24,
|
||||||
|
0x44, 0x44, 0x44, 0x7e, 0x04, 0x04, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40,
|
||||||
|
0x40, 0x40, 0x7c, 0x02, 0x02, 0x02, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||||
|
0x42, 0x3c, 0x00, 0x00, 0x00, 0x7e, 0x42, 0x42, 0x42, 0x04, 0x04, 0x04,
|
||||||
|
0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42,
|
||||||
|
0x42, 0x42, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x42,
|
||||||
|
0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
|
||||||
|
0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x10, 0x20, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x04,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00,
|
||||||
|
0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20,
|
||||||
|
0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x3c, 0x42, 0x42, 0x42, 0x02, 0x04, 0x08, 0x08, 0x08, 0x00, 0x00,
|
||||||
|
0x08, 0x08, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x41, 0x49, 0x55, 0x55, 0x55,
|
||||||
|
0x55, 0x55, 0x57, 0x4b, 0x20, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x24, 0x42,
|
||||||
|
0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00,
|
||||||
|
0x00, 0x7c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x3c, 0x22, 0x22, 0x22, 0x22,
|
||||||
|
0x22, 0x7c, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x42, 0x40, 0x40, 0x40, 0x40,
|
||||||
|
0x40, 0x40, 0x40, 0x42, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x78, 0x24, 0x22,
|
||||||
|
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x78, 0x00, 0x00,
|
||||||
|
0x00, 0x7e, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40,
|
||||||
|
0x40, 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7c,
|
||||||
|
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x42,
|
||||||
|
0x40, 0x40, 0x40, 0x40, 0x4e, 0x42, 0x42, 0x42, 0x22, 0x1c, 0x00, 0x00,
|
||||||
|
0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42,
|
||||||
|
0x42, 0x42, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x04,
|
||||||
|
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x42, 0x42, 0x44, 0x44, 0x48, 0x50, 0x50, 0x68, 0x48, 0x44, 0x44,
|
||||||
|
0x42, 0x42, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
||||||
|
0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x41, 0x63, 0x63,
|
||||||
|
0x55, 0x55, 0x49, 0x49, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x00, 0x00,
|
||||||
|
0x00, 0x42, 0x42, 0x62, 0x62, 0x52, 0x52, 0x4a, 0x4a, 0x46, 0x46, 0x42,
|
||||||
|
0x42, 0x42, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||||
|
0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x78, 0x44, 0x42,
|
||||||
|
0x42, 0x42, 0x44, 0x78, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
|
||||||
|
0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x52, 0x4a, 0x44,
|
||||||
|
0x44, 0x3a, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7c,
|
||||||
|
0x48, 0x48, 0x44, 0x44, 0x42, 0x42, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42,
|
||||||
|
0x40, 0x40, 0x40, 0x3c, 0x02, 0x02, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||||
|
0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41,
|
||||||
|
0x41, 0x41, 0x41, 0x41, 0x22, 0x22, 0x22, 0x14, 0x1c, 0x08, 0x00, 0x00,
|
||||||
|
0x00, 0x41, 0x41, 0x41, 0x41, 0x49, 0x49, 0x49, 0x49, 0x55, 0x55, 0x55,
|
||||||
|
0x22, 0x22, 0x00, 0x00, 0x00, 0x41, 0x41, 0x22, 0x36, 0x14, 0x08, 0x08,
|
||||||
|
0x08, 0x14, 0x36, 0x22, 0x41, 0x41, 0x00, 0x00, 0x00, 0x41, 0x41, 0x22,
|
||||||
|
0x22, 0x14, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
|
||||||
|
0x00, 0x7e, 0x02, 0x02, 0x04, 0x04, 0x08, 0x18, 0x10, 0x20, 0x20, 0x40,
|
||||||
|
0x40, 0x7e, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
|
||||||
|
0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x02, 0x00, 0x00,
|
||||||
|
0x00, 0x1c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||||
|
0x04, 0x1c, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x04,
|
||||||
|
0x3c, 0x44, 0x44, 0x44, 0x48, 0x36, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40,
|
||||||
|
0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x40, 0x40,
|
||||||
|
0x42, 0x3c, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x3a, 0x46, 0x42,
|
||||||
|
0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x3c, 0x42, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x0c, 0x12, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x46, 0x42,
|
||||||
|
0x42, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x02, 0x3c, 0x00, 0x40, 0x40, 0x40,
|
||||||
|
0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x08, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x0c, 0x04, 0x04,
|
||||||
|
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x24, 0x18, 0x00, 0x40, 0x40, 0x40,
|
||||||
|
0x40, 0x42, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x6d, 0x49,
|
||||||
|
0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||||
|
0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42,
|
||||||
|
0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x02,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x32, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40,
|
||||||
|
0x40, 0x3c, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x12, 0x0c, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||||
|
0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41,
|
||||||
|
0x41, 0x22, 0x22, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x66, 0x24, 0x18, 0x24, 0x66,
|
||||||
|
0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42,
|
||||||
|
0x42, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x02, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x7e, 0x02, 0x04, 0x04, 0x18, 0x20, 0x20, 0x40, 0x7e, 0x00, 0x00,
|
||||||
|
0x00, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x00, 0x00,
|
||||||
|
0x00, 0x32, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28,
|
||||||
|
0x44, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x42,
|
||||||
|
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x22, 0x1c, 0x08, 0x38,
|
||||||
|
0x00, 0x42, 0x42, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||||
|
0x46, 0x3a, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x00, 0x3c, 0x42, 0x42,
|
||||||
|
0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x10, 0x28, 0x44,
|
||||||
|
0x00, 0x38, 0x44, 0x04, 0x3c, 0x44, 0x44, 0x44, 0x48, 0x36, 0x00, 0x00,
|
||||||
|
0x00, 0x44, 0x44, 0x00, 0x00, 0x38, 0x44, 0x04, 0x3c, 0x44, 0x44, 0x44,
|
||||||
|
0x48, 0x36, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x00, 0x38, 0x44, 0x04,
|
||||||
|
0x3c, 0x44, 0x44, 0x44, 0x48, 0x36, 0x00, 0x00, 0x00, 0x18, 0x24, 0x18,
|
||||||
|
0x00, 0x38, 0x44, 0x04, 0x3c, 0x44, 0x44, 0x44, 0x48, 0x36, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x40, 0x40,
|
||||||
|
0x42, 0x3c, 0x08, 0x38, 0x00, 0x18, 0x24, 0x42, 0x00, 0x3c, 0x42, 0x42,
|
||||||
|
0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x42, 0x42, 0x00,
|
||||||
|
0x00, 0x3c, 0x42, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x20, 0x10, 0x08, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x7e, 0x40, 0x40,
|
||||||
|
0x42, 0x3c, 0x00, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x18, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22,
|
||||||
|
0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00,
|
||||||
|
0x00, 0x20, 0x10, 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x1c, 0x00, 0x00, 0x00, 0x42, 0x42, 0x18, 0x24, 0x42, 0x42, 0x42,
|
||||||
|
0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x18, 0x24, 0x18,
|
||||||
|
0x24, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00,
|
||||||
|
0x04, 0x08, 0x7e, 0x40, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40,
|
||||||
|
0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x49, 0x09,
|
||||||
|
0x39, 0x4f, 0x48, 0x48, 0x49, 0x36, 0x00, 0x00, 0x00, 0x1f, 0x28, 0x48,
|
||||||
|
0x48, 0x48, 0x48, 0x7f, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x24, 0x42, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||||
|
0x42, 0x3c, 0x00, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x3c, 0x42, 0x42,
|
||||||
|
0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
|
||||||
|
0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x24, 0x42, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||||
|
0x46, 0x3a, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x00, 0x42, 0x42, 0x42,
|
||||||
|
0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x42, 0x42, 0x00,
|
||||||
|
0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x02, 0x3c,
|
||||||
|
0x42, 0x42, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||||
|
0x42, 0x3c, 0x00, 0x00, 0x42, 0x42, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||||
|
0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
|
||||||
|
0x08, 0x3e, 0x49, 0x48, 0x48, 0x48, 0x48, 0x49, 0x3e, 0x08, 0x08, 0x00,
|
||||||
|
0x00, 0x0c, 0x12, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x08, 0x38, 0x49,
|
||||||
|
0x49, 0x36, 0x00, 0x00, 0x00, 0x41, 0x41, 0x22, 0x22, 0x14, 0x7f, 0x08,
|
||||||
|
0x08, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x78, 0x44, 0x42,
|
||||||
|
0x42, 0x44, 0x78, 0x40, 0x44, 0x5f, 0x44, 0x44, 0x45, 0x42, 0x00, 0x00,
|
||||||
|
0x00, 0x06, 0x09, 0x09, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x48,
|
||||||
|
0x48, 0x30, 0x00, 0x00, 0x00, 0x08, 0x10, 0x20, 0x00, 0x38, 0x44, 0x04,
|
||||||
|
0x3c, 0x44, 0x44, 0x44, 0x48, 0x36, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10,
|
||||||
|
0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00,
|
||||||
|
0x00, 0x04, 0x08, 0x10, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||||
|
0x42, 0x3c, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x00, 0x42, 0x42, 0x42,
|
||||||
|
0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x32, 0x4c, 0x00,
|
||||||
|
0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00,
|
||||||
|
0x32, 0x4c, 0x00, 0x42, 0x62, 0x62, 0x52, 0x52, 0x4a, 0x4a, 0x46, 0x46,
|
||||||
|
0x42, 0x42, 0x00, 0x00, 0x00, 0x38, 0x48, 0x48, 0x34, 0x00, 0x7c, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x48, 0x48,
|
||||||
|
0x30, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x10, 0x20, 0x40, 0x42, 0x42,
|
||||||
|
0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e,
|
||||||
|
0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x30, 0x10, 0x10, 0x11, 0x3a, 0x04, 0x08, 0x16, 0x29, 0x42,
|
||||||
|
0x04, 0x08, 0x0f, 0x00, 0x00, 0x10, 0x30, 0x10, 0x10, 0x11, 0x3a, 0x04,
|
||||||
|
0x08, 0x12, 0x26, 0x4a, 0x1f, 0x02, 0x02, 0x00, 0x00, 0x00, 0x08, 0x08,
|
||||||
|
0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x24, 0x48, 0x24, 0x12, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x24, 0x12,
|
||||||
|
0x24, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
|
||||||
|
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
|
||||||
|
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
|
||||||
|
0x55, 0xaa, 0x55, 0xaa, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb,
|
||||||
|
0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08,
|
||||||
|
0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x24, 0x24, 0x24, 0x24, 0xe4, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x24, 0x24, 0x24,
|
||||||
|
0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08,
|
||||||
|
0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x24, 0x24, 0xe4, 0x04, 0xe4, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x04,
|
||||||
|
0xe4, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x24, 0x24, 0xe4, 0x04, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0xfc, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08,
|
||||||
|
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xff, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x27, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x24, 0x24, 0x27, 0x20, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x20, 0x27, 0x24, 0x24, 0x24,
|
||||||
|
0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0xe7, 0x00,
|
||||||
|
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xff, 0x00, 0xe7, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x27, 0x20, 0x27, 0x24, 0x24, 0x24,
|
||||||
|
0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||||
|
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x24, 0x24, 0xe7, 0x00, 0xe7, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xff, 0x00, 0xff, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x24, 0x24, 0x24,
|
||||||
|
0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x0f, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x3f, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x24, 0x24, 0x24, 0x24, 0xff, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xff, 0x08, 0xff, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
|
||||||
|
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
|
||||||
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
||||||
|
0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x32, 0x4a, 0x4a, 0x44, 0x44, 0x44, 0x44, 0x4a, 0x32, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x48, 0x44, 0x42, 0x42,
|
||||||
|
0x42, 0x4c, 0x40, 0x40, 0x00, 0x7e, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40,
|
||||||
|
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x7f, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00,
|
||||||
|
0x00, 0x7f, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x40,
|
||||||
|
0x40, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x48, 0x44,
|
||||||
|
0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5d, 0x40, 0x40,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x4e, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x00, 0x00, 0x00, 0x7f, 0x08, 0x08, 0x1c, 0x22, 0x41, 0x41,
|
||||||
|
0x41, 0x22, 0x1c, 0x08, 0x08, 0x7f, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24,
|
||||||
|
0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x24, 0x24, 0x18, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24,
|
||||||
|
0x24, 0x66, 0x00, 0x00, 0x00, 0x0e, 0x11, 0x08, 0x04, 0x1c, 0x22, 0x42,
|
||||||
|
0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x02, 0x02, 0x04, 0x3c, 0x4a, 0x4a, 0x52, 0x52, 0x3c, 0x20,
|
||||||
|
0x40, 0x40, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x20, 0x20, 0x40, 0x40, 0x7c,
|
||||||
|
0x40, 0x40, 0x20, 0x20, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
|
||||||
|
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x3e,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
|
||||||
|
0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x7e, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x04,
|
||||||
|
0x00, 0x7e, 0x00, 0x00, 0x00, 0x06, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x48, 0x48, 0x48, 0x30, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x18, 0x18,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x4c, 0x00,
|
||||||
|
0x32, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x48, 0x48,
|
||||||
|
0x48, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x08,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x28, 0x68, 0x28, 0x18, 0x18, 0x08, 0x00, 0x00,
|
||||||
|
0x00, 0x58, 0x64, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x04, 0x18, 0x20, 0x3c, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
unsigned int FM_T_437_F16_len = 4096;
|
@ -1,107 +0,0 @@
|
|||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include "spinlock/spinlock.h"
|
|
||||||
#include "errors.h"
|
|
||||||
#include "hal/hal.h"
|
|
||||||
#include "hshtb.h"
|
|
||||||
#include "kprintf.h"
|
|
||||||
#include "vfs/vfs.h"
|
|
||||||
#include "dlmalloc/malloc.h"
|
|
||||||
#include "util/util.h"
|
|
||||||
|
|
||||||
int32_t kvfs_read(struct VfsMountPoint *vmp, const char *key, uint8_t *const buffer, size_t n, size_t off) {
|
|
||||||
KvfsNode *node = NULL;
|
|
||||||
|
|
||||||
spinlock_acquire(&vmp->spinlock);
|
|
||||||
HSHTB_GET(&vmp->fs.kvfs, nodes, (char *)key, key_, node);
|
|
||||||
spinlock_release(&vmp->spinlock);
|
|
||||||
|
|
||||||
if (node == NULL) {
|
|
||||||
return E_NOENTRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
spinlock_acquire(&node->spinlock);
|
|
||||||
vmp->backingsd->read(vmp->backingsd, buffer, n, off);
|
|
||||||
spinlock_release(&node->spinlock);
|
|
||||||
return E_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t kvfs_write(struct VfsMountPoint *vmp, const char *key, const uint8_t *const buffer, size_t n, size_t off) {
|
|
||||||
KvfsNode *node = NULL;
|
|
||||||
|
|
||||||
spinlock_acquire(&vmp->spinlock);
|
|
||||||
HSHTB_GET(&vmp->fs.kvfs, nodes, (char *)key, key_, node);
|
|
||||||
spinlock_release(&vmp->spinlock);
|
|
||||||
if (node == NULL) {
|
|
||||||
return E_NOENTRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
spinlock_acquire(&node->spinlock);
|
|
||||||
vmp->backingsd->write(vmp->backingsd, buffer, n, off);
|
|
||||||
spinlock_release(&node->spinlock);
|
|
||||||
return E_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t kvfs_remove(struct VfsMountPoint *vmp, const char *key) {
|
|
||||||
KvfsNode *node = NULL;
|
|
||||||
|
|
||||||
spinlock_acquire(&vmp->spinlock);
|
|
||||||
HSHTB_GET(&vmp->fs.kvfs, nodes, (char *)key, key_, node);
|
|
||||||
spinlock_release(&vmp->spinlock);
|
|
||||||
|
|
||||||
if (node == NULL) {
|
|
||||||
return E_NOENTRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
spinlock_acquire(&node->spinlock);
|
|
||||||
hal_memset(node, 0, sizeof(*node));
|
|
||||||
spinlock_release(&node->spinlock);
|
|
||||||
return E_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t kvfs_cleanup(struct VfsMountPoint *vmp) {
|
|
||||||
int32_t err = vmp->backingsd->cleanup(vmp->backingsd);
|
|
||||||
if (err != E_OK) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
return E_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t kvfs_create(struct VfsMountPoint *vmp, const char *path, int32_t type) {
|
|
||||||
(void)type;
|
|
||||||
KvfsNode *node = NULL;
|
|
||||||
|
|
||||||
spinlock_acquire(&vmp->spinlock);
|
|
||||||
HSHTB_ALLOC(&vmp->fs.kvfs, nodes, (char *)path, key_, node);
|
|
||||||
spinlock_release(&vmp->spinlock);
|
|
||||||
|
|
||||||
if (node == NULL) {
|
|
||||||
return E_NOMEMORY;
|
|
||||||
}
|
|
||||||
return E_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool kvfs_check(void) {
|
|
||||||
int32_t ret;
|
|
||||||
|
|
||||||
ret = vfs_create("tmpvars", "hello", VFS_CREATE_FILE);
|
|
||||||
if (ret != E_OK) return false;
|
|
||||||
|
|
||||||
char *hello = "WAWAWAWA!!!";
|
|
||||||
ret = vfs_write("tmpvars", "hello", hello, hal_strlen(hello)+1, 0);
|
|
||||||
if (ret != E_OK) return false;
|
|
||||||
|
|
||||||
char buf[20];
|
|
||||||
ret = vfs_read("tmpvars", "hello", buf, sizeof(buf), 0);
|
|
||||||
if (ret != E_OK) return false;
|
|
||||||
|
|
||||||
vfs_remove("tmpvars", "hello");
|
|
||||||
if (ret != E_OK) return false;
|
|
||||||
|
|
||||||
ret = vfs_read("tmpvars", "hello", buf, sizeof(buf), 0);
|
|
||||||
if (ret != E_NOENTRY) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
|||||||
#ifndef FS_KVFS_KVFS_H_
|
|
||||||
#define FS_KVFS_KVFS_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
struct VfsMountPoint;
|
|
||||||
|
|
||||||
#define KVFS_NODE_KEY_MAX 128
|
|
||||||
#define KVFS_NODES_MAX 256
|
|
||||||
#define KVFS_BUFFER_SIZE (1024 * 2)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bool taken;
|
|
||||||
uint8_t key_[KVFS_NODE_KEY_MAX];
|
|
||||||
SpinLock spinlock;
|
|
||||||
} KvfsNode;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
KvfsNode nodes[KVFS_NODES_MAX];
|
|
||||||
} Kvfs;
|
|
||||||
|
|
||||||
int32_t kvfs_read(struct VfsMountPoint *vmp, const char *key, uint8_t *const buffer, size_t n, size_t off);
|
|
||||||
int32_t kvfs_write(struct VfsMountPoint *vmp, const char *key, const uint8_t *const buffer, size_t n, size_t off);
|
|
||||||
int32_t kvfs_remove(struct VfsMountPoint *vmp, const char *key);
|
|
||||||
int32_t kvfs_create(struct VfsMountPoint *vmp, const char *path, int32_t type);
|
|
||||||
int32_t kvfs_cleanup(struct VfsMountPoint *vmp);
|
|
||||||
bool kvfs_check(void);
|
|
||||||
|
|
||||||
#endif // FS_KVFS_KVFS_H_
|
|
@ -5,96 +5,216 @@
|
|||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "dlmalloc/malloc.h"
|
#include "dlmalloc/malloc.h"
|
||||||
|
#include "hal/hal.h"
|
||||||
#define CHECK(err) \
|
|
||||||
do { \
|
|
||||||
int ok = (err); \
|
|
||||||
kprintf("ok = %d\n", ok); \
|
|
||||||
if (ok < 0) goto bad; \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
int32_t littlefs_read(struct VfsMountPoint *vmp, const char *path, uint8_t *const buffer, size_t n, size_t off) {
|
|
||||||
spinlock_acquire(&vmp->spinlock);
|
|
||||||
|
|
||||||
LittleFs *fs = &vmp->fs.littlefs;
|
|
||||||
lfs_file_t file;
|
|
||||||
CHECK(lfs_file_open(&fs->instance, &file, path, LFS_O_RDONLY));
|
|
||||||
CHECK(lfs_file_seek(&fs->instance, &file, off, LFS_SEEK_SET));
|
|
||||||
CHECK(lfs_file_read(&fs->instance, &file, buffer + off, n));
|
|
||||||
CHECK(lfs_file_close(&fs->instance, &file));
|
|
||||||
|
|
||||||
spinlock_release(&vmp->spinlock);
|
|
||||||
return E_OK;
|
|
||||||
bad:
|
|
||||||
spinlock_release(&vmp->spinlock);
|
|
||||||
return E_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t littlefs_write(struct VfsMountPoint *vmp, const char *path, const uint8_t *const buffer, size_t n, size_t off) {
|
|
||||||
spinlock_acquire(&vmp->spinlock);
|
|
||||||
|
|
||||||
LittleFs *fs = &vmp->fs.littlefs;
|
|
||||||
lfs_file_t file;
|
|
||||||
CHECK(lfs_file_open(&fs->instance, &file, path, LFS_O_WRONLY));
|
|
||||||
CHECK(lfs_file_seek(&fs->instance, &file, off, LFS_SEEK_SET));
|
|
||||||
CHECK(lfs_file_write(&fs->instance, &file, buffer, n));
|
|
||||||
CHECK(lfs_file_close(&fs->instance, &file));
|
|
||||||
|
|
||||||
spinlock_release(&vmp->spinlock);
|
|
||||||
return E_OK;
|
|
||||||
bad:
|
|
||||||
spinlock_release(&vmp->spinlock);
|
|
||||||
return E_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t littlefs_remove(struct VfsMountPoint *vmp, const char *path) {
|
|
||||||
spinlock_acquire(&vmp->spinlock);
|
|
||||||
|
|
||||||
LittleFs *fs = &vmp->fs.littlefs;
|
|
||||||
CHECK(lfs_remove(&fs->instance, path));
|
|
||||||
|
|
||||||
spinlock_release(&vmp->spinlock);
|
|
||||||
return E_OK;
|
|
||||||
bad:
|
|
||||||
spinlock_release(&vmp->spinlock);
|
|
||||||
return E_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t littlefs_cleanup(struct VfsMountPoint *vmp) {
|
int32_t littlefs_cleanup(struct VfsMountPoint *vmp) {
|
||||||
dlfree(vmp->fs.littlefs.instance.cfg);
|
dlfree((void *)vmp->fs.littlefs.instance.cfg);
|
||||||
int32_t err = vmp->backingsd->cleanup(vmp->backingsd);
|
int32_t err = vmp->backingsd->cleanup(vmp->backingsd);
|
||||||
if (err != E_OK) {
|
if (err != E_OK) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
err = lfs_unmount(&vmp->fs.littlefs.instance);
|
err = lfs_unmount(&vmp->fs.littlefs.instance);
|
||||||
if (err < 0) { return E_GENERIC_ERROR; }
|
if (err < 0) { return E_BADIO; }
|
||||||
return E_OK;
|
return E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t littlefs_create(struct VfsMountPoint *vmp, const char *path, int32_t type) {
|
void littlefs_vobj_cleanup(struct VfsObj *vobj) {
|
||||||
|
if (vobj->extra != NULL) {
|
||||||
|
lfs_file_close(&vobj->vmp->fs.littlefs.instance, (lfs_file_t *)vobj->extra);
|
||||||
|
dlfree(vobj->extra);
|
||||||
|
}
|
||||||
|
dlfree(vobj);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t littlefs_vobj_read(struct VfsObj *vobj, uint8_t *const buffer, size_t n, size_t off) {
|
||||||
|
if (!(vobj->flags & VFS_FLAG_READ)) {
|
||||||
|
return E_INVALIDOPER;
|
||||||
|
}
|
||||||
|
|
||||||
|
spinlock_acquire(&vobj->spinlock);
|
||||||
|
|
||||||
|
int ok = lfs_file_seek(&vobj->vmp->fs.littlefs.instance, (lfs_file_t *)vobj->extra, off, LFS_SEEK_SET);
|
||||||
|
if (ok < 0) {
|
||||||
|
spinlock_release(&vobj->spinlock);
|
||||||
|
return E_BADIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = lfs_file_read(&vobj->vmp->fs.littlefs.instance, (lfs_file_t *)vobj->extra, buffer, n);
|
||||||
|
if (ok < 0) {
|
||||||
|
spinlock_release(&vobj->spinlock);
|
||||||
|
return E_BADIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
spinlock_release(&vobj->spinlock);
|
||||||
|
return E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t littlefs_vobj_write(struct VfsObj *vobj, const uint8_t *const buffer, size_t n, size_t off) {
|
||||||
|
if (!(vobj->flags & VFS_FLAG_WRITE)) {
|
||||||
|
return E_INVALIDOPER;
|
||||||
|
}
|
||||||
|
|
||||||
|
spinlock_acquire(&vobj->spinlock);
|
||||||
|
|
||||||
|
int ok = lfs_file_seek(&vobj->vmp->fs.littlefs.instance, (lfs_file_t *)vobj->extra, off, LFS_SEEK_SET);
|
||||||
|
if (ok < 0) {
|
||||||
|
spinlock_release(&vobj->spinlock);
|
||||||
|
return E_BADIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = lfs_file_write(&vobj->vmp->fs.littlefs.instance, (lfs_file_t *)vobj->extra, buffer, n);
|
||||||
|
if (ok < 0) {
|
||||||
|
spinlock_release(&vobj->spinlock);
|
||||||
|
return E_BADIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
spinlock_release(&vobj->spinlock);
|
||||||
|
return E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, IoctlStat *statbuf) {
|
||||||
|
struct lfs_info info;
|
||||||
|
|
||||||
spinlock_acquire(&vmp->spinlock);
|
spinlock_acquire(&vmp->spinlock);
|
||||||
|
|
||||||
LittleFs *fs = &vmp->fs.littlefs;
|
int ok = lfs_stat(&vmp->fs.littlefs.instance, path, &info);
|
||||||
switch (type) {
|
if (ok < 0) {
|
||||||
case VFS_CREATE_DIR:
|
spinlock_release(&vmp->spinlock);
|
||||||
CHECK(lfs_mkdir(&fs->instance, path));
|
return E_BADIO;
|
||||||
break;
|
}
|
||||||
case VFS_CREATE_FILE: {
|
|
||||||
lfs_file_t file;
|
if (info.type == LFS_TYPE_REG) {
|
||||||
CHECK(lfs_file_open(&fs->instance, &file, path, LFS_O_CREAT | LFS_O_WRONLY));
|
statbuf->type = IOCTLSTAT_FILE;
|
||||||
CHECK(lfs_file_close(&fs->instance, &file));
|
statbuf->size = info.size;
|
||||||
} break;
|
} else if (info.type == LFS_TYPE_DIR) {
|
||||||
|
statbuf->type = IOCTLSTAT_DIR;
|
||||||
|
statbuf->size = 0;
|
||||||
|
// TODO: find a better way than this... !!!
|
||||||
|
lfs_dir_t dir;
|
||||||
|
ok = lfs_dir_open(&vmp->fs.littlefs.instance, &dir, path);
|
||||||
|
if (ok < 0) {
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
return E_BADIO;
|
||||||
|
}
|
||||||
|
struct lfs_info info2;
|
||||||
|
while (lfs_dir_read(&vmp->fs.littlefs.instance, &dir, &info2) > 0) {
|
||||||
|
statbuf->size++;
|
||||||
|
}
|
||||||
|
lfs_dir_close(&vmp->fs.littlefs.instance, &dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
spinlock_release(&vmp->spinlock);
|
spinlock_release(&vmp->spinlock);
|
||||||
return E_OK;
|
return E_OK;
|
||||||
bad:
|
|
||||||
spinlock_release(&vmp->spinlock);
|
|
||||||
return E_GENERIC_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool littlefs_check(void) {
|
int32_t littlefs_mkdir(struct VfsMountPoint *vmp, const char *path) {
|
||||||
return true;
|
spinlock_acquire(&vmp->spinlock);
|
||||||
|
int ok = lfs_mkdir(&vmp->fs.littlefs.instance, path);
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
if (ok < 0) {
|
||||||
|
return E_BADIO;
|
||||||
|
}
|
||||||
|
return E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VfsObj *littlefs_open(struct VfsMountPoint *vmp, const char *path, uint32_t flags) {
|
||||||
|
VfsObj *vobj = dlmalloc(sizeof(*vobj));
|
||||||
|
if (vobj == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
hal_memset(vobj, 0, sizeof(*vobj));
|
||||||
|
spinlock_init(&vobj->spinlock);
|
||||||
|
|
||||||
|
int lfs_flags = 0;
|
||||||
|
lfs_file_t *file = dlmalloc(sizeof(*file));
|
||||||
|
if (file == NULL) {
|
||||||
|
dlfree(vobj);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
spinlock_acquire(&vmp->spinlock);
|
||||||
|
|
||||||
|
LittleFs *fs = &vmp->fs.littlefs;
|
||||||
|
|
||||||
|
if (flags & VFS_FLAG_MAKE) {
|
||||||
|
lfs_flags |= LFS_O_CREAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags == VFS_FLAG_READ) {
|
||||||
|
lfs_flags |= LFS_O_RDONLY;
|
||||||
|
} else if (flags == VFS_FLAG_WRITE) {
|
||||||
|
lfs_flags |= LFS_O_WRONLY;
|
||||||
|
} else if ((flags & VFS_FLAG_READ) && (flags & VFS_FLAG_WRITE)) {
|
||||||
|
lfs_flags |= LFS_O_RDWR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ok = lfs_file_open(&fs->instance, file, path, lfs_flags);
|
||||||
|
|
||||||
|
if (ok < 0) {
|
||||||
|
dlfree(vobj);
|
||||||
|
dlfree(file);
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vobj->flags = flags;
|
||||||
|
vobj->extra = file;
|
||||||
|
vobj->extrasize = sizeof(*file);
|
||||||
|
vobj->vmp = vmp;
|
||||||
|
vobj->cleanup = &littlefs_vobj_cleanup;
|
||||||
|
vobj->read = &littlefs_vobj_read;
|
||||||
|
vobj->write = &littlefs_vobj_write;
|
||||||
|
hal_strcpy(vobj->path, path);
|
||||||
|
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
return vobj;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t littlefs_fetchdirent(struct VfsMountPoint *vmp, const char *path, IoctlDirent *direntbuf, size_t idx) {
|
||||||
|
size_t i = 0;
|
||||||
|
struct lfs_info statinfo;
|
||||||
|
int ok;
|
||||||
|
|
||||||
|
spinlock_acquire(&vmp->spinlock);
|
||||||
|
|
||||||
|
ok = lfs_stat(&vmp->fs.littlefs.instance, path, &statinfo);
|
||||||
|
if (ok < 0) {
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
return E_BADIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statinfo.type != LFS_TYPE_DIR) {
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
return E_BADIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
lfs_dir_t dir;
|
||||||
|
ok = lfs_dir_open(&vmp->fs.littlefs.instance, &dir, path);
|
||||||
|
if (ok < 0) {
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
return E_BADIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lfs_info entinfo;
|
||||||
|
while (lfs_dir_read(&vmp->fs.littlefs.instance, &dir, &entinfo) > 0) {
|
||||||
|
if (i == idx) {
|
||||||
|
if (entinfo.type == LFS_TYPE_REG) {
|
||||||
|
direntbuf->stat.type = IOCTLSTAT_FILE;
|
||||||
|
direntbuf->stat.size = entinfo.size;
|
||||||
|
} else if (entinfo.type == LFS_TYPE_DIR) {
|
||||||
|
direntbuf->stat.type = IOCTLSTAT_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
hal_memcpy(direntbuf->name, entinfo.name, sizeof(direntbuf->name));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
lfs_dir_close(&vmp->fs.littlefs.instance, &dir);
|
||||||
|
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
return E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) {
|
int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) {
|
||||||
@ -119,3 +239,4 @@ int portlfs_sync(const struct lfs_config *c) {
|
|||||||
(void)c;
|
(void)c;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,21 +4,22 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "fs/littlefs/lfs.h"
|
#include "fs/littlefs/lfs.h"
|
||||||
|
#include "sysdefs/ioctl.h"
|
||||||
|
|
||||||
#define LITTLEFS_BLOCK_SIZE 4096
|
#define LITTLEFS_BLOCK_SIZE 4096
|
||||||
|
|
||||||
struct VfsMountPoint;
|
struct VfsMountPoint;
|
||||||
|
struct VfsObj;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
lfs_t instance;
|
lfs_t instance;
|
||||||
} LittleFs;
|
} LittleFs;
|
||||||
|
|
||||||
int32_t littlefs_read(struct VfsMountPoint *vmp, const char *path, uint8_t *const buffer, size_t n, size_t off);
|
|
||||||
int32_t littlefs_write(struct VfsMountPoint *vmp, const char *path, const uint8_t *const buffer, size_t n, size_t off);
|
|
||||||
int32_t littlefs_remove(struct VfsMountPoint *vmp, const char *path);
|
|
||||||
int32_t littlefs_create(struct VfsMountPoint *vmp, const char *path, int32_t type);
|
|
||||||
int32_t littlefs_cleanup(struct VfsMountPoint *vmp);
|
int32_t littlefs_cleanup(struct VfsMountPoint *vmp);
|
||||||
bool littlefs_check(void);
|
struct VfsObj *littlefs_open(struct VfsMountPoint *vmp, const char *path, uint32_t flags);
|
||||||
|
int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, IoctlStat *statbuf);
|
||||||
|
int32_t littlefs_fetchdirent(struct VfsMountPoint *vmp, const char *path, IoctlDirent *direntbuf, size_t idx);
|
||||||
|
int32_t littlefs_mkdir(struct VfsMountPoint *vmp, const char *path);
|
||||||
|
|
||||||
int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size);
|
int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size);
|
||||||
int portlfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size);
|
int portlfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size);
|
||||||
|
@ -18,10 +18,14 @@ size_t hal_strcspn(const char *s, const char *reject);
|
|||||||
size_t hal_strspn(const char *s, const char *accept);
|
size_t hal_strspn(const char *s, const char *accept);
|
||||||
char *hal_strcpy(char *dest, const char *src);
|
char *hal_strcpy(char *dest, const char *src);
|
||||||
char *hal_strchr(const char *s, int c);
|
char *hal_strchr(const char *s, int c);
|
||||||
void hal_init_withmalloc(void);
|
void hal_wait(uint32_t ms);
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#define HAL_PAGE_SIZE 0x1000
|
||||||
# define HAL_PAGE_SIZE 0x1000
|
#include "x86_64/vmm.h"
|
||||||
#endif
|
#include "x86_64/switch.h"
|
||||||
|
#include "x86_64/paging.h"
|
||||||
|
#include "x86_64/intr.h"
|
||||||
|
#include "x86_64/io.h"
|
||||||
|
#include "x86_64/gdt.h"
|
||||||
|
|
||||||
#endif // KERNEL_HAL_HAL_H_
|
#endif // KERNEL_HAL_HAL_H_
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "uacpi/uacpi.h"
|
|
||||||
#include "uacpi/utilities.h"
|
|
||||||
#include "hal/hal.h"
|
|
||||||
#include "kprintf.h"
|
|
||||||
#include "dlmalloc/malloc.h"
|
|
||||||
|
|
||||||
#define PREINIT_BUFFER_SIZE 0x1000
|
|
||||||
|
|
||||||
void acpi_init(void) {
|
|
||||||
uacpi_status ret;
|
|
||||||
|
|
||||||
void *preinit_buffer = dlmalloc(PREINIT_BUFFER_SIZE);
|
|
||||||
ret = uacpi_setup_early_table_access(preinit_buffer, PREINIT_BUFFER_SIZE);
|
|
||||||
if (uacpi_unlikely_error(ret)) {
|
|
||||||
ERR("acpi", "init err %s\n", uacpi_status_to_string(ret));
|
|
||||||
hal_hang();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if (uacpi_unlikely_error(ret)) { */
|
|
||||||
/* ERR("acpi", "init err %s\n", uacpi_status_to_string(ret)); */
|
|
||||||
/* hal_hang(); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* if (uacpi_unlikely_error(ret)) { */
|
|
||||||
/* ERR("acpi", "init err %s\n", uacpi_status_to_string(ret)); */
|
|
||||||
/* hal_hang(); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
LOG("hal", "acpi init\n");
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
#ifndef HAL_ACPI_H_
|
|
||||||
#define HAL_ACPI_H_
|
|
||||||
|
|
||||||
void acpi_init(void);
|
|
||||||
|
|
||||||
#endif // HAL_ACPI_H_
|
|
@ -2,8 +2,13 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "compiler/attr.h"
|
#include "compiler/attr.h"
|
||||||
#include "hal/hal.h"
|
#include "hal/hal.h"
|
||||||
|
#include "gdt.h"
|
||||||
|
|
||||||
#define GDT_SIZE 5
|
#define GDT_PRESENT 0x80
|
||||||
|
#define GDT_TSS 0x89
|
||||||
|
|
||||||
|
#define KSTACK (1024*2*4096)
|
||||||
|
ALIGNED(16) static uint8_t kernelstack[KSTACK];
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t limitlow;
|
uint16_t limitlow;
|
||||||
@ -25,70 +30,63 @@ typedef struct {
|
|||||||
GdtEntry tsshigh;
|
GdtEntry tsshigh;
|
||||||
} PACKED ExtendedGdt;
|
} PACKED ExtendedGdt;
|
||||||
|
|
||||||
typedef struct {
|
ALIGNED(16) Tss tss = {0};
|
||||||
uint32_t resv0;
|
ALIGNED(16) static ExtendedGdt gdt = {0};
|
||||||
uint64_t rsp0;
|
|
||||||
uint64_t rsp1;
|
|
||||||
uint64_t rsp2;
|
|
||||||
uint64_t resv1;
|
|
||||||
uint64_t ist[7];
|
|
||||||
uint64_t resv2;
|
|
||||||
uint16_t resv3;
|
|
||||||
uint16_t iopb_off;
|
|
||||||
} PACKED Tss;
|
|
||||||
|
|
||||||
static Tss tss = {0};
|
void gdt_setentry(GdtEntry *ent, uint32_t base, uint32_t limit, uint8_t acc, uint8_t gran) {
|
||||||
static ExtendedGdt *curgdt = NULL;
|
ent->baselow = base & 0xffff;
|
||||||
|
ent->basemid = (base >> 16) & 0xff;
|
||||||
#define KCODE 0x08
|
ent->basehigh = (base >> 24) & 0xff;
|
||||||
#define KDATA 0x10
|
ent->limitlow = limit & 0xffff;
|
||||||
#define UCODE 0x18
|
ent->gran = ((limit >> 16) & 0x0f) | (gran & 0xf0);
|
||||||
#define UDATA 0x20
|
ent->access = acc;
|
||||||
#define TSS 0x28
|
|
||||||
|
|
||||||
#define GDT_PRESENT 0x80
|
|
||||||
#define GDT_TSS 0x89
|
|
||||||
|
|
||||||
static uint64_t gdt_curretbase(void) {
|
|
||||||
GdtPtr gdtr;
|
|
||||||
asm volatile("sgdt %0" : "=m"(gdtr));
|
|
||||||
return gdtr.base;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gdt_setentry(GdtEntry *entry, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) {
|
|
||||||
entry->baselow = base & 0xffff;
|
|
||||||
entry->basemid = (base >> 16) & 0xff;
|
|
||||||
entry->basehigh = (base >> 24) & 0xff;
|
|
||||||
entry->limitlow = limit & 0xffff;
|
|
||||||
entry->gran = ((limit >> 16) & 0x0f) | (gran & 0xf0);
|
|
||||||
entry->access = access;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gdt_init(void) {
|
void gdt_init(void) {
|
||||||
uint64_t base = gdt_curretbase();
|
|
||||||
curgdt = (ExtendedGdt *)base;
|
|
||||||
|
|
||||||
hal_memset(&tss, 0, sizeof(tss));
|
hal_memset(&tss, 0, sizeof(tss));
|
||||||
tss.iopb_off = sizeof(tss);
|
tss.iopb_off = sizeof(tss);
|
||||||
|
|
||||||
|
tss.rsp0 = (uint64_t)(kernelstack + sizeof(kernelstack));
|
||||||
|
|
||||||
uint64_t tss_base = (uint64_t)&tss;
|
uint64_t tss_base = (uint64_t)&tss;
|
||||||
uint32_t tss_limit = sizeof(tss) - 1;
|
uint32_t tss_limit = sizeof(tss) - 1;
|
||||||
|
|
||||||
gdt_setentry(&curgdt->tsslow, tss_base & 0xFFFFFFFF, tss_limit, GDT_PRESENT | GDT_TSS, 0x0);
|
gdt_setentry(&gdt.old[0], 0, 0, 0, 0);
|
||||||
|
gdt_setentry(&gdt.old[1], 0, 0xFFFFF, 0x9a, 0xA0);
|
||||||
|
gdt_setentry(&gdt.old[2], 0, 0xFFFFF, 0x92, 0xC0);
|
||||||
|
gdt_setentry(&gdt.old[3], 0, 0xFFFFF, 0xfa, 0xA0);
|
||||||
|
gdt_setentry(&gdt.old[4], 0, 0xFFFFF, 0xf2, 0xC0);
|
||||||
|
|
||||||
GdtEntry *tsshigh = &curgdt->tsshigh;
|
gdt_setentry(&gdt.tsslow, tss_base & 0xFFFFFFFF, tss_limit, GDT_PRESENT | GDT_TSS, 0x0);
|
||||||
tsshigh->baselow = (tss_base >> 32) & 0xffff;
|
|
||||||
tsshigh->basemid = (tss_base >> 48) & 0xff;
|
uint32_t tssbasehi = tss_base >> 32;
|
||||||
tsshigh->basehigh = (tss_base >> 56) & 0xff;
|
gdt.tsshigh.limitlow = tssbasehi & 0xffff;
|
||||||
tsshigh->access = 0;
|
gdt.tsshigh.baselow = (tssbasehi >> 16) & 0xffff;
|
||||||
tsshigh->gran = 0;
|
gdt.tsshigh.basemid = 0;
|
||||||
tsshigh->limitlow = 0;
|
gdt.tsshigh.basehigh = 0;
|
||||||
|
gdt.tsshigh.access = 0;
|
||||||
|
gdt.tsshigh.gran = 0;
|
||||||
|
|
||||||
GdtPtr gdtr;
|
GdtPtr gdtr;
|
||||||
asm volatile("sgdt %0" : "=m"(gdtr));
|
gdtr.limit = sizeof(gdt) - 1;
|
||||||
gdtr.limit = sizeof(ExtendedGdt) - 1;
|
gdtr.base = (uint64_t)&gdt;
|
||||||
asm volatile("lgdt %0" :: "m"(gdtr));
|
asm volatile("lgdt %0" :: "m"(gdtr));
|
||||||
|
|
||||||
asm volatile("ltr %0" :: "r"((uint16_t)0x28));
|
asm volatile(
|
||||||
|
"pushq %[kcode]\n"
|
||||||
|
"lea 1f(%%rip), %%rax\n"
|
||||||
|
"pushq %%rax\n"
|
||||||
|
"lretq\n"
|
||||||
|
"1:\n"
|
||||||
|
"movw %[kdata], %%ax\n"
|
||||||
|
"movw %%ax, %%ds\n"
|
||||||
|
"movw %%ax, %%es\n"
|
||||||
|
"movw %%ax, %%ss\n"
|
||||||
|
:
|
||||||
|
: [kcode] "i"(KCODE), [kdata] "i"(KDATA)
|
||||||
|
: "rax", "memory"
|
||||||
|
);
|
||||||
|
|
||||||
|
asm volatile("ltr %0" :: "r"((uint16_t)TSS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,26 @@
|
|||||||
#ifndef HAL_GDT_H_
|
#ifndef HAL_GDT_H_
|
||||||
#define HAL_GDT_H_
|
#define HAL_GDT_H_
|
||||||
|
|
||||||
|
#define KCODE 0x08
|
||||||
|
#define KDATA 0x10
|
||||||
|
#define UCODE 0x18
|
||||||
|
#define UDATA 0x20
|
||||||
|
#define TSS 0x28
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t resv0;
|
||||||
|
uint64_t rsp0;
|
||||||
|
uint64_t rsp1;
|
||||||
|
uint64_t rsp2;
|
||||||
|
uint64_t resv1;
|
||||||
|
uint64_t ist[7];
|
||||||
|
uint64_t resv2;
|
||||||
|
uint16_t resv3;
|
||||||
|
uint16_t iopb_off;
|
||||||
|
} PACKED Tss;
|
||||||
|
|
||||||
|
ALIGNED(16) extern Tss tss;
|
||||||
|
|
||||||
void gdt_init(void);
|
void gdt_init(void);
|
||||||
|
|
||||||
#endif // HAL_GDT_H_
|
#endif // HAL_GDT_H_
|
||||||
|
@ -2,17 +2,17 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "hal/hal.h"
|
#include "hal/hal.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "serial.h"
|
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
#include "idt.h"
|
#include "intr.h"
|
||||||
#include "acpi.h"
|
#include "pic.h"
|
||||||
|
#include "pit.h"
|
||||||
|
|
||||||
void hal_init(void) {
|
void hal_init(void) {
|
||||||
if (!serial_init()) {
|
|
||||||
hal_hang(); // going further makes no sense
|
|
||||||
}
|
|
||||||
LOG("hal", "serial init\n");
|
|
||||||
gdt_init();
|
gdt_init();
|
||||||
|
intr_init();
|
||||||
|
pic_init();
|
||||||
|
pit_init();
|
||||||
|
hal_intr_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((noreturn)) void hal_hang(void) {
|
__attribute__((noreturn)) void hal_hang(void) {
|
||||||
@ -21,7 +21,7 @@ __attribute__((noreturn)) void hal_hang(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hal_init_withmalloc(void) {
|
void hal_wait(uint32_t ms) {
|
||||||
acpi_init();
|
pit_wait(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include "idt.h"
|
|
||||||
#include "kprintf.h"
|
|
||||||
|
|
||||||
#define ENTRIES 256
|
|
||||||
static IdtGate idtgates[ENTRIES] = {0};
|
|
||||||
static Idt idt;
|
|
||||||
|
|
||||||
void idt_setgate(int i, uint64_t handler, uint8_t flags) {
|
|
||||||
idtgates[i].isrlow = (uint16_t)handler;
|
|
||||||
idtgates[i].kernelcs = 40;
|
|
||||||
idtgates[i].ist = 0;
|
|
||||||
idtgates[i].resv = 0;
|
|
||||||
idtgates[i].attrs = flags;
|
|
||||||
idtgates[i].isrmid = (uint16_t)(handler >> 16);
|
|
||||||
idtgates[i].isrhigh = (uint16_t)(handler >> 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
void idt_init(void) {
|
|
||||||
idt.base = (uint64_t)&idtgates;
|
|
||||||
idt.limit = ENTRIES * sizeof(IdtGate) - 1;
|
|
||||||
asm volatile("lidt %0" :: "m"(idt) : "memory");
|
|
||||||
|
|
||||||
LOG("idt", "idt init\n");
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
#ifndef HAL_IDT_H_
|
|
||||||
#define HAL_IDT_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "compiler/attr.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t isrlow;
|
|
||||||
uint16_t kernelcs;
|
|
||||||
uint8_t ist;
|
|
||||||
uint8_t attrs;
|
|
||||||
uint16_t isrmid;
|
|
||||||
uint32_t isrhigh;
|
|
||||||
uint32_t resv;
|
|
||||||
} PACKED IdtGate;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t limit;
|
|
||||||
uint64_t base;
|
|
||||||
} PACKED Idt;
|
|
||||||
|
|
||||||
void idt_init(void);
|
|
||||||
|
|
||||||
#endif // HAL_IDT_H_
|
|
@ -1,9 +0,0 @@
|
|||||||
.global hal_intr_enable
|
|
||||||
hal_intr_enable:
|
|
||||||
sti
|
|
||||||
ret
|
|
||||||
|
|
||||||
.global hal_intr_disable
|
|
||||||
hal_intr_disable:
|
|
||||||
cli
|
|
||||||
ret
|
|
243
kernel/hal/x86_64/intr.c
Normal file
243
kernel/hal/x86_64/intr.c
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "intr.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "gdt.h"
|
||||||
|
#include "hal/hal.h"
|
||||||
|
#include "kprintf.h"
|
||||||
|
#include "compiler/attr.h"
|
||||||
|
#include "pic.h"
|
||||||
|
#include "pit.h"
|
||||||
|
#include "proc/proc.h"
|
||||||
|
#include "syscall/syscall.h"
|
||||||
|
#include "errors.h"
|
||||||
|
#include "ipc/pipe/pipe.h"
|
||||||
|
#include "rbuf/rbuf.h"
|
||||||
|
#include "dlmalloc/malloc.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
|
||||||
|
typedef struct IntrHandler {
|
||||||
|
struct IntrHandler *next;
|
||||||
|
void (*fn)(void);
|
||||||
|
int irq;
|
||||||
|
} IntrHandler;
|
||||||
|
|
||||||
|
IntrHandler *INTR_HANDLERS = NULL;
|
||||||
|
|
||||||
|
void intr_attchhandler(void (*fn)(void), int irq) {
|
||||||
|
IntrHandler *ih = dlmalloc(sizeof(*ih));
|
||||||
|
ih->fn = fn;
|
||||||
|
ih->irq = irq;
|
||||||
|
LL_APPEND(INTR_HANDLERS, ih);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct BackTraceFrame {
|
||||||
|
struct BackTraceFrame *rbp;
|
||||||
|
uint64_t rip;
|
||||||
|
} BackTraceFrame;
|
||||||
|
|
||||||
|
void backtrace(BackTraceFrame *bt) {
|
||||||
|
kprintf("Backtrace:\n");
|
||||||
|
for (size_t frame = 0; bt; frame++) {
|
||||||
|
kprintf(" %zu: 0x%lx\n", frame, bt->rip);
|
||||||
|
bt = bt->rbp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hal_intr_disable(void) {
|
||||||
|
asm volatile("cli");
|
||||||
|
}
|
||||||
|
|
||||||
|
void hal_intr_enable(void) {
|
||||||
|
asm volatile("sti");
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t intrlow;
|
||||||
|
uint16_t kernelcs;
|
||||||
|
uint8_t ist;
|
||||||
|
uint8_t attrs;
|
||||||
|
uint16_t intrmid;
|
||||||
|
uint32_t intrhigh;
|
||||||
|
uint32_t resv;
|
||||||
|
} PACKED IdtGate;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t limit;
|
||||||
|
uint64_t base;
|
||||||
|
} PACKED Idt;
|
||||||
|
|
||||||
|
#define ENTRIES 256
|
||||||
|
ALIGNED(0x10) static IdtGate idtgates[ENTRIES] = {0};
|
||||||
|
static Idt idt = {0};
|
||||||
|
|
||||||
|
void idt_setentry(int i, uint64_t handler, uint8_t flags) {
|
||||||
|
idtgates[i].intrlow = handler & 0xffff;
|
||||||
|
idtgates[i].kernelcs = KCODE;
|
||||||
|
idtgates[i].ist = 0;
|
||||||
|
idtgates[i].attrs = flags;
|
||||||
|
idtgates[i].intrmid = (handler >> 16) & 0xFFFF;
|
||||||
|
idtgates[i].intrhigh = (handler >> 32) & 0xFFFFFFFF;
|
||||||
|
idtgates[i].resv = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void idt_init(void) {
|
||||||
|
idt.base = (uint64_t)&idtgates;
|
||||||
|
idt.limit = ENTRIES * sizeof(IdtGate) - 1;
|
||||||
|
asm volatile("lidt %0" :: "m"(idt) : "memory");
|
||||||
|
|
||||||
|
LOG("hal", "idt init\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void *ISR_REDIRTABLE[];
|
||||||
|
|
||||||
|
static const char *exceptions[] = {
|
||||||
|
"#DE", "#DB", "NMI",
|
||||||
|
"#BP", "#OF", "#BR",
|
||||||
|
"#UD", "#NM", "#DF",
|
||||||
|
"CSO", "#TS", "#NP",
|
||||||
|
"#SS", "#GP", "#PF",
|
||||||
|
"RES", "#MF", "#AC",
|
||||||
|
"#MC", "#XM", "#VE",
|
||||||
|
"#CP",
|
||||||
|
};
|
||||||
|
|
||||||
|
void intr_init(void) {
|
||||||
|
#define MKINTR(N) \
|
||||||
|
extern void intr_vec##N(void); \
|
||||||
|
idt_setentry(N, (uint64_t)&intr_vec##N, 0x8E);
|
||||||
|
|
||||||
|
MKINTR(0);
|
||||||
|
MKINTR(1);
|
||||||
|
MKINTR(2);
|
||||||
|
MKINTR(4);
|
||||||
|
MKINTR(5);
|
||||||
|
MKINTR(6);
|
||||||
|
MKINTR(7);
|
||||||
|
MKINTR(8);
|
||||||
|
MKINTR(9);
|
||||||
|
MKINTR(10);
|
||||||
|
MKINTR(11);
|
||||||
|
MKINTR(12);
|
||||||
|
MKINTR(13);
|
||||||
|
MKINTR(14);
|
||||||
|
MKINTR(15);
|
||||||
|
MKINTR(16);
|
||||||
|
MKINTR(17);
|
||||||
|
MKINTR(18);
|
||||||
|
MKINTR(19);
|
||||||
|
MKINTR(20);
|
||||||
|
MKINTR(21);
|
||||||
|
MKINTR(22);
|
||||||
|
MKINTR(23);
|
||||||
|
MKINTR(24);
|
||||||
|
MKINTR(25);
|
||||||
|
MKINTR(26);
|
||||||
|
MKINTR(27);
|
||||||
|
MKINTR(28);
|
||||||
|
MKINTR(29);
|
||||||
|
MKINTR(30);
|
||||||
|
MKINTR(31);
|
||||||
|
MKINTR(32);
|
||||||
|
MKINTR(33);
|
||||||
|
MKINTR(34);
|
||||||
|
MKINTR(35);
|
||||||
|
MKINTR(36);
|
||||||
|
MKINTR(37);
|
||||||
|
MKINTR(38);
|
||||||
|
MKINTR(39);
|
||||||
|
MKINTR(40);
|
||||||
|
MKINTR(41);
|
||||||
|
MKINTR(42);
|
||||||
|
MKINTR(43);
|
||||||
|
MKINTR(44);
|
||||||
|
MKINTR(45);
|
||||||
|
MKINTR(46);
|
||||||
|
MKINTR(47);
|
||||||
|
|
||||||
|
extern void intr_vec128(void);
|
||||||
|
idt_setentry(0x80, (uint64_t)&intr_vec128, 0xEE);
|
||||||
|
|
||||||
|
idt_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void intr_dumpframe(IntrStackFrame *frame) {
|
||||||
|
uint64_t cr2;
|
||||||
|
asm volatile("mov %%cr2, %0" : "=r"(cr2));
|
||||||
|
uint64_t cr3;
|
||||||
|
asm volatile("mov %%cr3, %0" : "=r"(cr3));
|
||||||
|
uint64_t cr4;
|
||||||
|
asm volatile("mov %%cr4, %0" : "=r"(cr4));
|
||||||
|
kprintf("rax=%016lx rcx=%016lx rdx=%016lx\n"
|
||||||
|
"rsi=%016lx rdi=%016lx r8 =%016lx\n"
|
||||||
|
"r9 =%016lx r10=%016lx r11=%016lx\n"
|
||||||
|
"rip=%016lx rfl=%016lx rsp=%016lx\n"
|
||||||
|
"cs =%016lx ss =%016lx trp=%016lx\n"
|
||||||
|
"cr2=%016lx cr3=%016lx cr4=%016lx\n"
|
||||||
|
"\n\n",
|
||||||
|
frame->regs.rax, frame->regs.rcx, frame->regs.rdx,
|
||||||
|
frame->regs.rsi, frame->regs.rdi, frame->regs.r8,
|
||||||
|
frame->regs.r9, frame->regs.r10, frame->regs.r11,
|
||||||
|
frame->rip, frame->rflags, frame->rsp,
|
||||||
|
frame->cs, frame->ss, frame->trapnum,
|
||||||
|
cr2, cr3, cr4
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hal_syscalldispatch(IntrStackFrame *frame) {
|
||||||
|
uint64_t sysnum = frame->regs.rax;
|
||||||
|
if (sysnum < SYSCALLS_MAX) {
|
||||||
|
SyscallFn fn = SYSCALL_TABLE[sysnum];
|
||||||
|
if (fn == NULL) {
|
||||||
|
frame->regs.rax = E_BADSYSCALL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int32_t ret = fn(frame, frame->regs.rdi, frame->regs.rsi, frame->regs.rdx,
|
||||||
|
frame->regs.r10, frame->regs.r8, frame->regs.r9);
|
||||||
|
|
||||||
|
if (ret == E_DOSCHEDULING) {
|
||||||
|
proc_sched((void *)frame);
|
||||||
|
}
|
||||||
|
frame->regs.rax = *(uint64_t *)&ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void intr_eoi() {
|
||||||
|
io_out8(PIC2_CMD, PIC_EOI);
|
||||||
|
io_out8(PIC1_CMD, PIC_EOI);
|
||||||
|
}
|
||||||
|
|
||||||
|
void intr_handleintr(IntrStackFrame *frame) {
|
||||||
|
if (frame->trapnum <= 31) {
|
||||||
|
kprintf("ERROR %s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum);
|
||||||
|
intr_dumpframe(frame);
|
||||||
|
backtrace((BackTraceFrame *)frame->regs.rbp);
|
||||||
|
if (hal_vmm_current_cr3() != KERNEL_CR3) {
|
||||||
|
kprintf("killed pid %ld %s\n", PROCS.current->pid, PROCS.current->name);
|
||||||
|
proc_killself();
|
||||||
|
proc_sched((void *)frame);
|
||||||
|
}
|
||||||
|
hal_hang();
|
||||||
|
} else if (frame->trapnum >= 32 && frame->trapnum <= 47) {
|
||||||
|
switch (frame->trapnum) {
|
||||||
|
case INTR_IRQBASE+0:
|
||||||
|
PIT_TICKS++;
|
||||||
|
intr_eoi();
|
||||||
|
proc_sched((void *)frame);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
IntrHandler *ih, *ihtmp;
|
||||||
|
LL_FOREACH_SAFE(INTR_HANDLERS, ih, ihtmp) {
|
||||||
|
if (ih->irq == frame->trapnum) {
|
||||||
|
ih->fn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intr_eoi();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (frame->trapnum == 0x80) {
|
||||||
|
hal_syscalldispatch(frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
39
kernel/hal/x86_64/intr.h
Normal file
39
kernel/hal/x86_64/intr.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef HAL_INTR_H_
|
||||||
|
#define HAL_INTR_H_
|
||||||
|
|
||||||
|
#define INTR_IRQBASE 0x20
|
||||||
|
|
||||||
|
#include "compiler/attr.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t r15;
|
||||||
|
uint64_t r14;
|
||||||
|
uint64_t r13;
|
||||||
|
uint64_t r12;
|
||||||
|
uint64_t r11;
|
||||||
|
uint64_t r10;
|
||||||
|
uint64_t r9;
|
||||||
|
uint64_t r8;
|
||||||
|
uint64_t rbp;
|
||||||
|
uint64_t rdi;
|
||||||
|
uint64_t rsi;
|
||||||
|
uint64_t rdx;
|
||||||
|
uint64_t rcx;
|
||||||
|
uint64_t rax;
|
||||||
|
} PACKED SavedRegs;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SavedRegs regs;
|
||||||
|
uint64_t trapnum;
|
||||||
|
uint64_t errnum;
|
||||||
|
uint64_t rip;
|
||||||
|
uint64_t cs;
|
||||||
|
uint64_t rflags;
|
||||||
|
uint64_t rsp;
|
||||||
|
uint64_t ss;
|
||||||
|
} PACKED IntrStackFrame;
|
||||||
|
|
||||||
|
void intr_attchhandler(void (*fn)(void), int irq);
|
||||||
|
void intr_init(void);
|
||||||
|
|
||||||
|
#endif // HAL_INTR_H_
|
221
kernel/hal/x86_64/intr0.S
Normal file
221
kernel/hal/x86_64/intr0.S
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
#include "regs.S"
|
||||||
|
|
||||||
|
.extern intr_handleintr
|
||||||
|
|
||||||
|
.global intr_vec0
|
||||||
|
.global intr_vec1
|
||||||
|
.global intr_vec2
|
||||||
|
.global intr_vec3
|
||||||
|
.global intr_vec4
|
||||||
|
.global intr_vec5
|
||||||
|
.global intr_vec6
|
||||||
|
.global intr_vec7
|
||||||
|
.global intr_vec8
|
||||||
|
.global intr_vec9
|
||||||
|
.global intr_vec10
|
||||||
|
.global intr_vec11
|
||||||
|
.global intr_vec12
|
||||||
|
.global intr_vec13
|
||||||
|
.global intr_vec14
|
||||||
|
.global intr_vec15
|
||||||
|
.global intr_vec16
|
||||||
|
.global intr_vec17
|
||||||
|
.global intr_vec18
|
||||||
|
.global intr_vec19
|
||||||
|
.global intr_vec20
|
||||||
|
.global intr_vec21
|
||||||
|
.global intr_vec22
|
||||||
|
.global intr_vec23
|
||||||
|
.global intr_vec24
|
||||||
|
.global intr_vec25
|
||||||
|
.global intr_vec26
|
||||||
|
.global intr_vec27
|
||||||
|
.global intr_vec28
|
||||||
|
.global intr_vec29
|
||||||
|
.global intr_vec30
|
||||||
|
.global intr_vec31
|
||||||
|
.global intr_vec32
|
||||||
|
.global intr_vec33
|
||||||
|
.global intr_vec34
|
||||||
|
.global intr_vec35
|
||||||
|
.global intr_vec36
|
||||||
|
.global intr_vec37
|
||||||
|
.global intr_vec38
|
||||||
|
.global intr_vec39
|
||||||
|
.global intr_vec40
|
||||||
|
.global intr_vec41
|
||||||
|
.global intr_vec42
|
||||||
|
.global intr_vec43
|
||||||
|
.global intr_vec44
|
||||||
|
.global intr_vec45
|
||||||
|
.global intr_vec46
|
||||||
|
.global intr_vec47
|
||||||
|
.global intr_vec128
|
||||||
|
|
||||||
|
.macro _vecintr_errorcode_present_save num
|
||||||
|
pushq $\num
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro _vecintr_plain_save num
|
||||||
|
pushq $0x0
|
||||||
|
pushq $\num
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro _vecintr_bodygen
|
||||||
|
cli
|
||||||
|
_push_regs
|
||||||
|
cld
|
||||||
|
movq %rsp, %rdi
|
||||||
|
call intr_handleintr
|
||||||
|
_pop_regs
|
||||||
|
add $0x10, %rsp
|
||||||
|
iretq
|
||||||
|
.endm
|
||||||
|
|
||||||
|
intr_vec0:
|
||||||
|
_vecintr_plain_save 0
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec1:
|
||||||
|
_vecintr_plain_save 1
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec2:
|
||||||
|
_vecintr_plain_save 2
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec3:
|
||||||
|
_vecintr_plain_save 3
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec4:
|
||||||
|
_vecintr_plain_save 4
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec5:
|
||||||
|
_vecintr_plain_save 5
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec6:
|
||||||
|
_vecintr_plain_save 6
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec7:
|
||||||
|
_vecintr_plain_save 7
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec8:
|
||||||
|
_vecintr_errorcode_present_save 8
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec9:
|
||||||
|
_vecintr_plain_save 9
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec10:
|
||||||
|
_vecintr_errorcode_present_save 10
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec11:
|
||||||
|
_vecintr_errorcode_present_save 11
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec12:
|
||||||
|
_vecintr_errorcode_present_save 12
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec13:
|
||||||
|
_vecintr_errorcode_present_save 13
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec14:
|
||||||
|
_vecintr_errorcode_present_save 14
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec15:
|
||||||
|
_vecintr_plain_save 15
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec16:
|
||||||
|
_vecintr_plain_save 16
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec17:
|
||||||
|
_vecintr_errorcode_present_save 17
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec18:
|
||||||
|
_vecintr_plain_save 18
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec19:
|
||||||
|
_vecintr_plain_save 19
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec20:
|
||||||
|
_vecintr_plain_save 20
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec21:
|
||||||
|
_vecintr_errorcode_present_save 21
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec22:
|
||||||
|
_vecintr_plain_save 22
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec23:
|
||||||
|
_vecintr_plain_save 23
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec24:
|
||||||
|
_vecintr_plain_save 24
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec25:
|
||||||
|
_vecintr_plain_save 25
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec26:
|
||||||
|
_vecintr_plain_save 26
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec27:
|
||||||
|
_vecintr_plain_save 27
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec28:
|
||||||
|
_vecintr_plain_save 28
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec29:
|
||||||
|
_vecintr_errorcode_present_save 29
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec30:
|
||||||
|
_vecintr_errorcode_present_save 30
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec31:
|
||||||
|
_vecintr_plain_save 31
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec32:
|
||||||
|
_vecintr_plain_save 32
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec33:
|
||||||
|
_vecintr_plain_save 33
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec34:
|
||||||
|
_vecintr_plain_save 34
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec35:
|
||||||
|
_vecintr_plain_save 35
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec36:
|
||||||
|
_vecintr_plain_save 36
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec37:
|
||||||
|
_vecintr_plain_save 37
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec38:
|
||||||
|
_vecintr_plain_save 38
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec39:
|
||||||
|
_vecintr_plain_save 39
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec40:
|
||||||
|
_vecintr_plain_save 40
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec41:
|
||||||
|
_vecintr_plain_save 41
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec42:
|
||||||
|
_vecintr_plain_save 42
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec43:
|
||||||
|
_vecintr_plain_save 43
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec44:
|
||||||
|
_vecintr_plain_save 44
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec45:
|
||||||
|
_vecintr_plain_save 45
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec46:
|
||||||
|
_vecintr_plain_save 46
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec47:
|
||||||
|
_vecintr_plain_save 47
|
||||||
|
_vecintr_bodygen
|
||||||
|
intr_vec128:
|
||||||
|
_vecintr_plain_save 128
|
||||||
|
_vecintr_bodygen
|
4
kernel/hal/x86_64/paging.S
Normal file
4
kernel/hal/x86_64/paging.S
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.global hal_loadpd
|
||||||
|
hal_loadpd:
|
||||||
|
mov %rdi, %cr3
|
||||||
|
retq
|
6
kernel/hal/x86_64/paging.h
Normal file
6
kernel/hal/x86_64/paging.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef HAL_PAGING_H_
|
||||||
|
#define HAL_PAGING_H_
|
||||||
|
|
||||||
|
void hal_loadpd(PgTable *cr3);
|
||||||
|
|
||||||
|
#endif // HAL_PAGING_H_
|
22
kernel/hal/x86_64/pic.c
Normal file
22
kernel/hal/x86_64/pic.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "pic.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "intr.h"
|
||||||
|
|
||||||
|
void pic_init(void) {
|
||||||
|
io_out8(PIC1_CMD, ICW1_INIT | ICW1_ICW4);
|
||||||
|
io_out8(PIC2_CMD, ICW1_INIT | ICW1_ICW4);
|
||||||
|
|
||||||
|
io_out8(PIC1_DATA, INTR_IRQBASE);
|
||||||
|
io_out8(PIC2_DATA, INTR_IRQBASE+8);
|
||||||
|
|
||||||
|
io_out8(PIC1_DATA, 2);
|
||||||
|
io_out8(PIC2_DATA, 2);
|
||||||
|
|
||||||
|
io_out8(PIC1_DATA, ICW4_8086);
|
||||||
|
io_out8(PIC2_DATA, ICW4_8086);
|
||||||
|
|
||||||
|
io_out8(PIC1_DATA, 0);
|
||||||
|
io_out8(PIC2_DATA, 0);
|
||||||
|
}
|
25
kernel/hal/x86_64/pic.h
Normal file
25
kernel/hal/x86_64/pic.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef HAL_PIC_H_
|
||||||
|
#define HAL_PIC_H_
|
||||||
|
|
||||||
|
#define PIC1_CMD 0x0020
|
||||||
|
#define PIC1_DATA 0x0021
|
||||||
|
#define PIC2_CMD 0x00A0
|
||||||
|
#define PIC2_DATA 0x00A1
|
||||||
|
|
||||||
|
#define PIC_EOI 0x20
|
||||||
|
|
||||||
|
#define ICW1_ICW4 0x01
|
||||||
|
#define ICW1_SINGLE 0x02
|
||||||
|
#define ICW1_ADI 0x04
|
||||||
|
#define ICW1_LTIM 0x08
|
||||||
|
#define ICW1_INIT 0x10
|
||||||
|
|
||||||
|
#define ICW4_8086 0x01
|
||||||
|
#define ICW4_AUTO 0x02
|
||||||
|
#define ICW4_BUFSLAVE 0x04
|
||||||
|
#define ICW4_BUFMASTER 0x0C
|
||||||
|
#define ICW4_SFNM 0x10
|
||||||
|
|
||||||
|
void pic_init(void);
|
||||||
|
|
||||||
|
#endif // HAL_PIC_H_
|
40
kernel/hal/x86_64/pit.c
Normal file
40
kernel/hal/x86_64/pit.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include "pit.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
|
#define PIT_COUNTER0 0x40
|
||||||
|
#define PIT_CMD 0x43
|
||||||
|
#define PIT_CMD_BINARY 0x00
|
||||||
|
#define PIT_CMD_BCD 0x01
|
||||||
|
#define PIT_CMD_MODE0 0x00
|
||||||
|
#define PIT_CMD_MODE1 0x02
|
||||||
|
#define PIT_CMD_MODE2 0x04
|
||||||
|
#define PIT_CMD_MODE3 0x06
|
||||||
|
#define PIT_CMD_MODE4 0x08
|
||||||
|
#define PIT_CMD_MODE5 0x0A
|
||||||
|
#define PIT_CMD_LATCH 0x00
|
||||||
|
#define PIT_CMD_RW_LOW 0x10
|
||||||
|
#define PIT_CMD_RW_HI 0x20
|
||||||
|
#define PIT_CMD_RW_BOTH 0x30
|
||||||
|
#define PIT_CMD_COUNTER0 0x00
|
||||||
|
#define PIT_CMD_COUNTER1 0x40
|
||||||
|
#define PIT_CMD_COUNTER2 0x80
|
||||||
|
#define PIT_CMD_READBACK 0xC0
|
||||||
|
|
||||||
|
#define PIT_FREQ 1193182
|
||||||
|
|
||||||
|
volatile uint32_t PIT_TICKS;
|
||||||
|
|
||||||
|
void pit_init(void) {
|
||||||
|
uint32_t hz = 1000;
|
||||||
|
uint32_t div = PIT_FREQ / hz;
|
||||||
|
io_out8(PIT_CMD, PIT_CMD_BINARY | PIT_CMD_MODE3 | PIT_CMD_RW_BOTH | PIT_CMD_COUNTER0);
|
||||||
|
io_out8(PIT_COUNTER0, div);
|
||||||
|
io_out8(PIT_COUNTER0, div >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pit_wait(uint32_t ms) {
|
||||||
|
uint32_t now = PIT_TICKS;
|
||||||
|
++ms;
|
||||||
|
while (PIT_TICKS - now < ms);
|
||||||
|
}
|
11
kernel/hal/x86_64/pit.h
Normal file
11
kernel/hal/x86_64/pit.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef HAL_PIT_H_
|
||||||
|
#define HAL_PIT_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern volatile uint32_t PIT_TICKS;
|
||||||
|
|
||||||
|
void pit_init(void);
|
||||||
|
void pit_wait(uint32_t ms);
|
||||||
|
|
||||||
|
#endif // HAL_PIT_H_
|
@ -1,45 +0,0 @@
|
|||||||
#include "uacpi/uacpi.h"
|
|
||||||
#include "dlmalloc/malloc.h"
|
|
||||||
#include "bootinfo/bootinfo.h"
|
|
||||||
#include "hal/x86_64/io.h"
|
|
||||||
#include "kprintf.h"
|
|
||||||
#include "compiler/builtins.h"
|
|
||||||
|
|
||||||
void *uacpi_kernel_alloc(uacpi_size size) {
|
|
||||||
return dlmalloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uacpi_kernel_free(void *ptr) {
|
|
||||||
return dlfree(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uacpi_kernel_log(uacpi_log_level lvl, const uacpi_char *s) {
|
|
||||||
char *t;
|
|
||||||
switch (lvl) {
|
|
||||||
case UACPI_LOG_DEBUG: t = "Debug"; break;
|
|
||||||
case UACPI_LOG_TRACE: t = "Trace"; break;
|
|
||||||
case UACPI_LOG_INFO: t = "Info"; break;
|
|
||||||
case UACPI_LOG_WARN: t = "Warn"; break;
|
|
||||||
case UACPI_LOG_ERROR: t = "Error"; break;
|
|
||||||
default:
|
|
||||||
unreachable();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
LOG("uACPI", "[%s] %s", t, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len) {
|
|
||||||
(void)len;
|
|
||||||
return (void *)(BOOT_INFO.hhdm_off + addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uacpi_kernel_unmap(void *addr, uacpi_size len) {
|
|
||||||
(void)addr;
|
|
||||||
(void)len;
|
|
||||||
}
|
|
||||||
|
|
||||||
uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *out) {
|
|
||||||
*out = BOOT_INFO.rsdp;
|
|
||||||
return UACPI_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
33
kernel/hal/x86_64/regs.S
Normal file
33
kernel/hal/x86_64/regs.S
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
.macro _push_regs
|
||||||
|
push %rax
|
||||||
|
push %rcx
|
||||||
|
push %rdx
|
||||||
|
push %rsi
|
||||||
|
push %rdi
|
||||||
|
push %rbp
|
||||||
|
push %r8
|
||||||
|
push %r9
|
||||||
|
push %r10
|
||||||
|
push %r11
|
||||||
|
push %r12
|
||||||
|
push %r13
|
||||||
|
push %r14
|
||||||
|
push %r15
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro _pop_regs
|
||||||
|
pop %r15
|
||||||
|
pop %r14
|
||||||
|
pop %r13
|
||||||
|
pop %r12
|
||||||
|
pop %r11
|
||||||
|
pop %r10
|
||||||
|
pop %r9
|
||||||
|
pop %r8
|
||||||
|
pop %rbp
|
||||||
|
pop %rdi
|
||||||
|
pop %rsi
|
||||||
|
pop %rdx
|
||||||
|
pop %rcx
|
||||||
|
pop %rax
|
||||||
|
.endm
|
@ -1,51 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "io.h"
|
|
||||||
#include "putchar.h"
|
|
||||||
|
|
||||||
#define SERIAL_PORT 0x3f8
|
|
||||||
|
|
||||||
static int serial_received(void) {
|
|
||||||
return io_in8(SERIAL_PORT + 5) & 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t serial_read(void) {
|
|
||||||
while (serial_received() == 0);
|
|
||||||
return io_in8(SERIAL_PORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int serial_trans_empty(void) {
|
|
||||||
return io_in8(SERIAL_PORT + 5) & 0x20;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void serial_write(uint8_t value) {
|
|
||||||
while (!serial_trans_empty());
|
|
||||||
io_out8(SERIAL_PORT, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// REFERENCE: https://wiki.osdev.org/Serial_Ports
|
|
||||||
bool serial_init(void) {
|
|
||||||
io_out8(SERIAL_PORT + 1, 0x00);
|
|
||||||
io_out8(SERIAL_PORT + 3, 0x80);
|
|
||||||
io_out8(SERIAL_PORT + 0, 0x03);
|
|
||||||
io_out8(SERIAL_PORT + 1, 0x00);
|
|
||||||
io_out8(SERIAL_PORT + 3, 0x03);
|
|
||||||
io_out8(SERIAL_PORT + 2, 0xc7);
|
|
||||||
io_out8(SERIAL_PORT + 4, 0x0b);
|
|
||||||
io_out8(SERIAL_PORT + 4, 0x1e);
|
|
||||||
io_out8(SERIAL_PORT + 0, 0xae);
|
|
||||||
|
|
||||||
if (io_in8(SERIAL_PORT + 0) != 0xae) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
io_out8(SERIAL_PORT + 4, 0x0f);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PUTCHAR_ == PUTCHAR_SERIAL
|
|
||||||
// For printf library
|
|
||||||
void putchar_(char c) {
|
|
||||||
serial_write(c);
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,8 +0,0 @@
|
|||||||
#ifndef HAL_SERIAL_H_
|
|
||||||
#define HAL_SERIAL_H_
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
bool serial_init(void);
|
|
||||||
|
|
||||||
#endif // HAL_SERIAL_H_
|
|
12
kernel/hal/x86_64/switch.S
Normal file
12
kernel/hal/x86_64/switch.S
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "regs.S"
|
||||||
|
|
||||||
|
.global hal_switchproc
|
||||||
|
hal_switchproc:
|
||||||
|
testq %rsi, %rsi
|
||||||
|
je 1f
|
||||||
|
movq %rsi, %cr3
|
||||||
|
1:
|
||||||
|
mov %rdi, %rsp
|
||||||
|
_pop_regs
|
||||||
|
add $0x10, %rsp
|
||||||
|
iretq
|
6
kernel/hal/x86_64/switch.h
Normal file
6
kernel/hal/x86_64/switch.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef HAL_SWITCH_H_
|
||||||
|
#define HAL_SWITCH_H_
|
||||||
|
|
||||||
|
extern void hal_switchproc(void *newsp, PgTable *cr3);
|
||||||
|
|
||||||
|
#endif // HAL_SWITCH_H_
|
@ -1,81 +0,0 @@
|
|||||||
name: CI
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lint-python-scripts:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: true
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Install flake8 & mypy
|
|
||||||
run: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install python3 python3-pip
|
|
||||||
export PIP_BREAK_SYSTEM_PACKAGES=1
|
|
||||||
pip install flake8 mypy
|
|
||||||
|
|
||||||
- name: Run flake8 on the project
|
|
||||||
run: flake8 --ignore=E743 tests/*.py tests/utilities/*.py tests/generated_test_cases/*.py
|
|
||||||
|
|
||||||
- name: Run mypy on the project
|
|
||||||
run: mypy --disallow-incomplete-defs --no-implicit-optional tests/*.py tests/utilities/*.py tests/generated_test_cases/*.py
|
|
||||||
build-and-run-tests:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: true
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- if: ${{ matrix.os != 'macos-latest' }}
|
|
||||||
name: Set up OpenWatcom
|
|
||||||
uses: open-watcom/setup-watcom@v0
|
|
||||||
with:
|
|
||||||
version: '2.0'
|
|
||||||
- if: ${{ matrix.os == 'ubuntu-latest' }}
|
|
||||||
name: Install tools & libraries (Ubuntu)
|
|
||||||
run: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install python3 python3-pytest acpica-tools cmake gcc-multilib g++-multilib
|
|
||||||
# https://github.com/actions/runner-images/issues/9491#issuecomment-1989718917
|
|
||||||
sudo sysctl vm.mmap_rnd_bits=28
|
|
||||||
- if: ${{ matrix.os == 'macos-latest' }}
|
|
||||||
name: Install tools & libraries (MacOS)
|
|
||||||
run: |
|
|
||||||
export PIP_BREAK_SYSTEM_PACKAGES=1
|
|
||||||
brew install python3 acpica cmake
|
|
||||||
python3 -m pip install pytest
|
|
||||||
- if: ${{ matrix.os == 'windows-latest' }}
|
|
||||||
name: Install tools & libraries (Windows)
|
|
||||||
run: |
|
|
||||||
choco install python3 iasl cmake llvm
|
|
||||||
python3 -m pip install pytest
|
|
||||||
|
|
||||||
- name: Ensure reduced-hardware/unsized-frees/fmt-logging/no-kernel-init/builtin-string build compiles
|
|
||||||
run: |
|
|
||||||
cd ${{ github.workspace}}/tests/runner
|
|
||||||
mkdir reduced-hw-build && cd reduced-hw-build
|
|
||||||
cmake .. -DREDUCED_HARDWARE_BUILD=1 -DSIZED_FREES_BUILD=0 -DFORMATTED_LOGGING_BUILD=1 -DNATIVE_ALLOC_ZEROED=1 -DKERNEL_INITIALIZATION=0 -DBUILTIN_STRING=1
|
|
||||||
cmake --build .
|
|
||||||
|
|
||||||
- name: Run tests (64-bit)
|
|
||||||
run: python3 ${{ github.workspace }}/tests/run_tests.py --bitness=64 --large --barebones
|
|
||||||
|
|
||||||
# MacOS doesn't want to compile i386 (at least easily) so just ignore it:
|
|
||||||
# ld: warning: The i386 architecture is deprecated for macOS
|
|
||||||
# ld: dynamic executables or dylibs must link with libSystem.dylib for architecture i386
|
|
||||||
# clang: error: linker command failed with exit code 1 (use -v to see invocation)
|
|
||||||
- if: ${{ matrix.os != 'macos-latest' }}
|
|
||||||
name: Run tests (32-bit)
|
|
||||||
run: python3 ${{ github.workspace }}/tests/run_tests.py --bitness=32 --large --barebones
|
|
||||||
|
|
||||||
- if: ${{ matrix.os != 'macos-latest' }}
|
|
||||||
name: Run tests (OpenWatcom)
|
|
||||||
run: python3 ${{ github.workspace }}/tests/run_tests.py --large --barebones --watcom
|
|
9
kernel/hal/x86_64/uACPI/.gitignore
vendored
9
kernel/hal/x86_64/uACPI/.gitignore
vendored
@ -1,9 +0,0 @@
|
|||||||
.DS_Store
|
|
||||||
*.aml
|
|
||||||
*.dsl
|
|
||||||
.idea/
|
|
||||||
cmake-build-*/
|
|
||||||
build-*/
|
|
||||||
tests/bin/
|
|
||||||
tests/acpi-dumps/
|
|
||||||
__pycache__
|
|
@ -1,399 +0,0 @@
|
|||||||
# uACPI
|
|
||||||
|
|
||||||
A portable and easy-to-integrate implementation of the Advanced Configuration and Power Interface (ACPI).
|
|
||||||
|
|
||||||
[](https://github.com/UltraOS/uACPI/actions/workflows/main.yml)
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- A fast and well-tested AML interpreter optimized to use very little stack space
|
|
||||||
- NT-compatible on a fundamental level (see [examples](#more-detailed-overview))
|
|
||||||
- Very easy to integrate (ships with own overridable standard library implementation)
|
|
||||||
- Highly flexible and configurable (optional sized frees, reduced-hw-only mode, etc.)
|
|
||||||
- A fairly advanced event subsystem (GPE/fixed, wake, implicit notify, AML handlers)
|
|
||||||
- Table management API (search, dynamic installation/loading, overrides, etc.)
|
|
||||||
- Operation region subsystem (user handlers, support for BufferAcc opregions, builtins for common types)
|
|
||||||
- Sleep state management (transition to any S state, wake vector programming)
|
|
||||||
- PCI routing table retrieval & interrupt model API
|
|
||||||
- Device search API
|
|
||||||
- Resource subsystem supporting every resource defined by ACPI 6.6
|
|
||||||
- Interface & feature management exposed via _OSI
|
|
||||||
- Client-defined Notify() handlers
|
|
||||||
- Firmware global lock management (_GL, locked fields, public API)
|
|
||||||
- GAS read/write API
|
|
||||||
- Fully thread safe
|
|
||||||
- Supports both 32-bit and 64-bit platforms
|
|
||||||
- A special barebones mode with only table API (see [config.h](include/uacpi/platform/config.h#L127))
|
|
||||||
|
|
||||||
## Why would I use this over ACPICA?
|
|
||||||
|
|
||||||
### 1. Performance
|
|
||||||
|
|
||||||
uACPI shows a consistent speedup of about **3.5x** over ACPICA in synthetic AML tests.
|
|
||||||
|
|
||||||
<details><summary>More details</summary>
|
|
||||||
|
|
||||||
Code that was tested:
|
|
||||||
```asl
|
|
||||||
Method (TOMS, 2, NotSerialized) {
|
|
||||||
Return ((Arg1 - Arg0) / 10000)
|
|
||||||
}
|
|
||||||
|
|
||||||
Method (ADDM, 1, NotSerialized) {
|
|
||||||
Local0 = 0
|
|
||||||
|
|
||||||
While (Arg0) {
|
|
||||||
Local0 += Arg0 + Arg0
|
|
||||||
Arg0--
|
|
||||||
}
|
|
||||||
|
|
||||||
Return (Local0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record start time
|
|
||||||
Local0 = Timer
|
|
||||||
|
|
||||||
// Run 10 million additions
|
|
||||||
Local1 = ADDM(10000000)
|
|
||||||
|
|
||||||
// Make sure the answer matches expected
|
|
||||||
If (Local1 != 0x5AF31112D680) {
|
|
||||||
Printf("Bad test result %o", Local1)
|
|
||||||
Return (1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record end time
|
|
||||||
Local2 = Timer
|
|
||||||
|
|
||||||
Printf("10,000,000 additions took %o ms",
|
|
||||||
ToDecimalString(TOMS(Local0, Local2)))
|
|
||||||
```
|
|
||||||
|
|
||||||
Compile options (acpiexec and uACPI's test-runner): `-O3 -flto -march=znver4 -mtune=znver4`
|
|
||||||
CPU: AMD Ryzen 9 9950X3D
|
|
||||||
Raw test scores (~average over 10 runs):
|
|
||||||
- ACPICA: 16661 ms
|
|
||||||
- uACPI: 4753 ms
|
|
||||||
|
|
||||||
**Raw difference: 3.5053x**
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
Real hardware tests of the same operating system using uACPI vs ACPICA show
|
|
||||||
at least a **1.75-2x speedup** while measuring the time it takes to load the initial
|
|
||||||
AML namespace.
|
|
||||||
|
|
||||||
<details><summary>More details</summary>
|
|
||||||
|
|
||||||
OS: [proxima](https://github.com/proxima-os)
|
|
||||||
|
|
||||||
Compile options: `-O3 -flto`
|
|
||||||
|
|
||||||
### Test Subject 1
|
|
||||||
|
|
||||||
Specs: Gigabyte B550M S2H, AMD Ryzen 5800X, 64GB RAM
|
|
||||||
Firmware: F19d (10097 AML opcodes)
|
|
||||||
|
|
||||||
Results:
|
|
||||||
- ACPICA: 3,936,953 ns
|
|
||||||
- uACPI: 1,902,077 ns
|
|
||||||
|
|
||||||
**Raw difference: 2.0698x**
|
|
||||||
|
|
||||||
### Test Subject 2
|
|
||||||
|
|
||||||
Specs: Toshiba Portege R30-A, Intel Core i5-4200M, 4GB RAM
|
|
||||||
Firmware: 4.40 (4962 AML opcodes)
|
|
||||||
|
|
||||||
Results:
|
|
||||||
- ACPICA: 10,899,233 ns
|
|
||||||
- uACPI: 6,227,036 ns
|
|
||||||
|
|
||||||
**Raw difference: 1.7503x**
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### 2. NT-compatible from the ground up
|
|
||||||
|
|
||||||
Over the decades of development, ACPICA has accumulated a lot of workarounds for
|
|
||||||
AML expecting NT-specific behaviors, and is still missing compatibility in a lot
|
|
||||||
of critical aspects.
|
|
||||||
|
|
||||||
uACPI, on the other hand, is built to be natively NT-compatible without extra
|
|
||||||
workarounds.
|
|
||||||
|
|
||||||
Some specific highlights include:
|
|
||||||
- Reference objects, especially multi-level reference chains
|
|
||||||
- Implicit cast semantics
|
|
||||||
- Object mutability
|
|
||||||
- Named object resolution, especially for named objects inside packages
|
|
||||||
|
|
||||||
### 3. Fundamental safety
|
|
||||||
|
|
||||||
uACPI is built to always assume the worst about the AML byte code it's executing,
|
|
||||||
and as such, has a more sophisticated object lifetime tracking system, as well
|
|
||||||
as carefully designed handling for various edge-cases, including race conditions.
|
|
||||||
|
|
||||||
Some of the standard uACPI test cases crash both ACPICA, and the NT AML
|
|
||||||
interpreters.
|
|
||||||
|
|
||||||
While a permanent fuzzing solution for uACPI is currently WIP, it has already
|
|
||||||
been fuzzed quite extensively and all known issues have been fixed.
|
|
||||||
|
|
||||||
### 4. No recursion
|
|
||||||
|
|
||||||
Running at kernel level has a lot of very strict limitations, one of which is a
|
|
||||||
tiny stack size, which can sometimes be only a few pages in length.
|
|
||||||
|
|
||||||
Of course, both ACPICA and uACPI have non-recursive AML interpreters, but there
|
|
||||||
are still edge cases that cause potentially unbounded recursion.
|
|
||||||
|
|
||||||
One such example are the dynamic table load operators from AML
|
|
||||||
(`Load`/`LoadTable`): these cause a linear growth in stack usage per call in
|
|
||||||
ACPICA, whereas in uACPI these are treated as special method calls,
|
|
||||||
and as such, don't increase stack usage whatsoever.
|
|
||||||
|
|
||||||
### More detailed overview
|
|
||||||
Expressions within package:
|
|
||||||
```asl
|
|
||||||
Method (TEST) {
|
|
||||||
Local0 = 10
|
|
||||||
Local1 = Package { Local0 * 5 }
|
|
||||||
Return (DerefOf(Local1[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ACPICA: AE_SUPPORT, Expressions within package elements are not supported
|
|
||||||
// Windows, uACPI: Local0 = 50
|
|
||||||
Local0 = TEST()
|
|
||||||
```
|
|
||||||
|
|
||||||
Packages outside of a control method:
|
|
||||||
```asl
|
|
||||||
// ACPICA: internal error
|
|
||||||
// Windows, uACPI: ok
|
|
||||||
Local0 = Package { 1 }
|
|
||||||
```
|
|
||||||
|
|
||||||
Reference rebind semantics:
|
|
||||||
```asl
|
|
||||||
Local0 = 123
|
|
||||||
Local1 = RefOf(Local0)
|
|
||||||
|
|
||||||
// ACPICA: Local1 = 321, Local0 = 123
|
|
||||||
// Windows, uACPI: Local1 = reference->Local0, Local0 = 321
|
|
||||||
Local1 = 321
|
|
||||||
```
|
|
||||||
|
|
||||||
Increment/Decrement:
|
|
||||||
```asl
|
|
||||||
Local0 = 123
|
|
||||||
Local1 = RefOf(Local0)
|
|
||||||
|
|
||||||
// ACPICA: error
|
|
||||||
// Windows, uACPI: Local0 = 124
|
|
||||||
Local1++
|
|
||||||
```
|
|
||||||
|
|
||||||
Multilevel references:
|
|
||||||
```asl
|
|
||||||
Local0 = 123
|
|
||||||
Local1 = RefOf(Local0)
|
|
||||||
Local2 = RefOf(Local1)
|
|
||||||
|
|
||||||
// ACPICA: Local3 = reference->Local0
|
|
||||||
// Windows, uACPI: Local3 = 123
|
|
||||||
Local3 = DerefOf(Local2)
|
|
||||||
```
|
|
||||||
|
|
||||||
Implict-cast semantics:
|
|
||||||
```asl
|
|
||||||
Name (TEST, "BAR")
|
|
||||||
|
|
||||||
// ACPICA: TEST = "00000000004F4F46"
|
|
||||||
// Windows, uACPI: TEST = "FOO"
|
|
||||||
TEST = 0x4F4F46
|
|
||||||
```
|
|
||||||
|
|
||||||
Buffer size mutability:
|
|
||||||
```asl
|
|
||||||
Name (TEST, "XXXX")
|
|
||||||
Name (VAL, "")
|
|
||||||
|
|
||||||
// ACPICA: TEST = "LONGSTRING"
|
|
||||||
// Windows, UACPI: TEST = "LONG"
|
|
||||||
TEST = "LONGSTRING"
|
|
||||||
|
|
||||||
// ACPICA: VAL = "FOO"
|
|
||||||
// Windows, UACPI: VAL = ""
|
|
||||||
VAL = "FOO"
|
|
||||||
```
|
|
||||||
|
|
||||||
Returning a reference to a local object:
|
|
||||||
```asl
|
|
||||||
Method (TEST) {
|
|
||||||
Local0 = 123
|
|
||||||
|
|
||||||
// Use-after-free in ACPICA, perfectly fine in uACPI
|
|
||||||
Return (RefOf(Local0))
|
|
||||||
}
|
|
||||||
|
|
||||||
Method (FOO) {
|
|
||||||
Name (TEST, 123)
|
|
||||||
|
|
||||||
// Use-after-free in ACPICA, object lifetime prolonged in uACPI (node is still removed from the namespace)
|
|
||||||
Return (RefOf(TEST))
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
CopyObject into self:
|
|
||||||
```asl
|
|
||||||
Method (TEST) {
|
|
||||||
CopyObject(123, TEST)
|
|
||||||
Return (1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Segfault in ACPICA, prints 1 in uACPI
|
|
||||||
Debug = TEST()
|
|
||||||
|
|
||||||
// Unreachable in ACPICA, prints 123 in uACPI
|
|
||||||
Debug = TEST
|
|
||||||
```
|
|
||||||
|
|
||||||
There's even more examples, but this should be enough to demonstrate the fundamental differences in designs.
|
|
||||||
|
|
||||||
## Integrating into a kernel
|
|
||||||
|
|
||||||
### 1. Add uACPI sources & include directories into your project
|
|
||||||
|
|
||||||
#### If you're using CMake
|
|
||||||
Simply add the following lines to your cmake:
|
|
||||||
```cmake
|
|
||||||
include(uacpi/uacpi.cmake)
|
|
||||||
|
|
||||||
target_sources(
|
|
||||||
my-kernel
|
|
||||||
PRIVATE
|
|
||||||
${UACPI_SOURCES}
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(
|
|
||||||
my-kernel
|
|
||||||
PRIVATE
|
|
||||||
${UACPI_INCLUDES}
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### If you're using Meson
|
|
||||||
Add the following lines to your meson.build:
|
|
||||||
```meson
|
|
||||||
uacpi = subproject('uacpi')
|
|
||||||
|
|
||||||
uacpi_sources = uacpi.get_variable('sources')
|
|
||||||
my_kernel_sources += uacpi_sources
|
|
||||||
|
|
||||||
uacpi_includes = uacpi.get_variable('includes')
|
|
||||||
my_kernel_includes += uacpi_includes
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Any other build system
|
|
||||||
- Add all .c files from [source](source) into your target sources
|
|
||||||
- Add [include](include) into your target include directories
|
|
||||||
|
|
||||||
### 2. Implement/override platform-specific headers
|
|
||||||
|
|
||||||
uACPI defines all platform/architecture-specific functionality in a few headers inside [include/uacpi/platform](include/uacpi/platform)
|
|
||||||
|
|
||||||
All of the headers can be "implemented" by your project in a few ways:
|
|
||||||
- Implement the expected helpers exposed by the headers
|
|
||||||
- Replace the expected helpers by your own and override uACPI to use them by defining the respective `UACPI_OVERRIDE_X` variable.
|
|
||||||
In this case, the header becomes a proxy that includes a corresponding `uacpi_x.h` header exported by your project.
|
|
||||||
|
|
||||||
Currently used platform-specific headers are:
|
|
||||||
- [arch_helpers.h](include/uacpi/platform/arch_helpers.h) - defines architecture/cpu-specific helpers & thread-id-related interfaces
|
|
||||||
- [compiler.h](include/uacpi/platform/compiler.h) - defines compiler-specific helpers like attributes and intrinsics.
|
|
||||||
This already works for MSVC, clang & GCC so you most likely won't have to override it.
|
|
||||||
- [atomic.h](include/uacpi/platform/atomic.h) - defines compiler-specific helpers for dealing with atomic operations.
|
|
||||||
Same as the header above, this should work out of the box for MSVC, clang & GCC.
|
|
||||||
- [libc.h](include/uacpi/platform/libc.h) - an empty header by default, but may be overriden by your project
|
|
||||||
if it implements any of the libc functions used by uACPI (by default uACPI uses its
|
|
||||||
own implementations to be platform-independent and to make porting easier). The
|
|
||||||
internal implementation is just the bare minimum and not optimized in any way.
|
|
||||||
- [types.h](include/uacpi/platform/types.h) - typedefs a bunch of uacpi-specific types using the `stdint.h` header. You don't have to override this
|
|
||||||
unless you don't provide `stdint.h`.
|
|
||||||
- [config.h](include/uacpi/platform/config.h) - various compile-time options and settings, preconfigured to reasonable defaults.
|
|
||||||
|
|
||||||
### 3. Implement kernel API
|
|
||||||
|
|
||||||
uACPI relies on kernel-specific API to do things like mapping/unmapping memory, writing/reading to/from IO, PCI config space, and many more things.
|
|
||||||
|
|
||||||
This API is declared in [kernel_api.h](include/uacpi/kernel_api.h) and is implemented by your kernel.
|
|
||||||
|
|
||||||
### 4. Initialize uACPI
|
|
||||||
|
|
||||||
That's it, uACPI is now integrated into your project.
|
|
||||||
|
|
||||||
You should proceed to initialization.
|
|
||||||
Refer to the [uACPI page](https://wiki.osdev.org/uACPI) on osdev wiki to see a
|
|
||||||
snippet for basic initialization, as well as some code examples of how you may
|
|
||||||
want to use certain APIs.
|
|
||||||
|
|
||||||
All of the headers and APIs defined in [uacpi](include/uacpi/) are public and may be utilized by your project.
|
|
||||||
Anything inside [uacpi/internal](include/uacpi/internal) is considered private/undocumented and unstable API.
|
|
||||||
|
|
||||||
## Developing and contributing
|
|
||||||
|
|
||||||
Most development work is fully doable in userland using the test runner.
|
|
||||||
|
|
||||||
### Setting up an IDE:
|
|
||||||
|
|
||||||
Simply open [tests/runner/CMakeLists.txt](tests/runner/CMakeLists.txt) in your favorite IDE.
|
|
||||||
|
|
||||||
For Visual Studio:
|
|
||||||
```
|
|
||||||
cd tests\runner && mkdir build && cd build && cmake ..
|
|
||||||
```
|
|
||||||
|
|
||||||
Then just simply open the .sln file generated by cmake.
|
|
||||||
|
|
||||||
### Running the test suite:
|
|
||||||
```
|
|
||||||
./tests/run_tests.py
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to contribute:
|
|
||||||
- Commits are expected to be atomic (changing one specific thing, or introducing one feature) with detailed description (if one is warranted for), an S-o-b line is welcome
|
|
||||||
- Code style is 4-space tabs, 80 cols, the rest can be seen by just looking at the current code
|
|
||||||
|
|
||||||
**All contributions are very welcome!**
|
|
||||||
|
|
||||||
## Notable projects using uACPI & performance leaderboards
|
|
||||||
|
|
||||||
| Project | Description | (qemu w/ Q35 + KVM) ops/s | CPU |
|
|
||||||
|--- |--- |--- |--- |
|
|
||||||
| [proxima](https://github.com/proxima-os/) | Unix-like microkernel-based operating system with uACPI running in userspace | 10,454,158 | AMD Ryzen 9 9950X3D |
|
|
||||||
| [ilobilix](https://github.com/ilobilo/ilobilix) | Yet another monolithic Linux clone wannabe. Currently under a rewrite | 8,703,286 | AMD Ryzen 9 9950X3D |
|
|
||||||
| [Crescent2](https://github.com/Qwinci/crescent2) | An NT driver compatible kernel and userspace | 6,818,418 | Intel Core i5-13600K |
|
|
||||||
| [davix](https://github.com/dbstream/davix) | Yet another unix-like by some bored nerd | 6,364,623 | Intel Core i7-13700K |
|
|
||||||
| [Managarm](https://github.com/managarm/managarm) | Pragmatic microkernel-based OS with fully asynchronous I/O | 5,618,646 | Intel Core i7-14700K |
|
|
||||||
| [ChronOS](https://github.com/BUGO07/chronos) | Another basic hobby os held together by duct tape, made in rust | 5,416,703 | Intel Core Ultra 7 265KF |
|
|
||||||
| [pmOS](https://gitlab.com/mishakov/pmos) | Microkernel-based operating system written from scratch with uACPI running in userspace | 5,354,445 | AMD Ryzen 9 5900X |
|
|
||||||
| [menix](https://github.com/menix-os/menix) | A minimal and expandable Unix-like operating system | 5,239,043 | Intel Core Ultra 7 265KF |
|
|
||||||
| [Ironclad](https://ironclad.nongnu.org) | Formally verified, hard real-time capable kernel written in SPARK and Ada | 4,802,816 | Intel Core i9-13900KS |
|
|
||||||
| [Astral](https://github.com/mathewnd/astral) | Operating system written in C which aims be POSIX-compliant | 4,189,189 | Intel Core i5-13600K |
|
|
||||||
| [Keyronex](https://github.com/Keyronex/Keyronex) | Layered kernel with fundamentally asynchronous I/O and working set model-based memory management | 4,013,691 | AMD Ryzen 5800X |
|
|
||||||
| [Orange](https://github.com/cppLover0/Orange) | x86_64 Unix-like OS | 2,377,330 | AMD Ryzen 5 3600 |
|
|
||||||
| [OBOS](https://github.com/OBOS-dev/obos) | Hybrid Kernel with advanced driver loading | 2,141,179 | Intel Core i5-13600K |
|
|
||||||
| [NyauxKC](https://github.com/rayanmargham/NyauxKC) | Monolithic UNIX-like multi-architecture kernel | 1,966,580 | Intel Core i7-13700K |
|
|
||||||
| [ElysiumOS](https://github.com/imwux/elysium-os) | Hybrid Unix-like kernel | 1,737,654 | AMD Ryzen 7 5800X3D |
|
|
||||||
| [imaginarium](https://github.com/Khitiara/imaginarium) | Ziggy osdev experiments inspired by the NT kernel (using the zig general purpose allocator) | 1,504,436 | AMD Ryzen 7 3700X |
|
|
||||||
| [BadgerOS](https://github.com/badgeteam/BadgerOS) | A monolithic lightweight UNIX clone | 1,018,518 | AMD Ryzen 5 3600 |
|
|
||||||
| [Hyra](https://github.com/sigsegv7/Hyra) | Monolithic UNIX-like OS by [OSMORA.ORG](https://osmora.org) | 199,873 | Intel Core i3-3220 |
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
<a href="https://opensource.org/licenses/MIT">
|
|
||||||
<img align="right" height="96" alt="MIT License" src="https://branding.cute.engineering/licenses/mit.svg" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
uACPI is licensed under the **MIT License**.
|
|
||||||
The full license text is provided in the [LICENSE](LICENSE) file inside the root directory.
|
|
File diff suppressed because it is too large
Load Diff
@ -1,53 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/log.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the minimum log level to be accepted by the logging facilities. Any logs
|
|
||||||
* below this level are discarded and not passed to uacpi_kernel_log, etc.
|
|
||||||
*
|
|
||||||
* 0 is treated as a special value that resets the setting to the default value.
|
|
||||||
*
|
|
||||||
* E.g. for a log level of UACPI_LOG_INFO:
|
|
||||||
* UACPI_LOG_DEBUG -> discarded
|
|
||||||
* UACPI_LOG_TRACE -> discarded
|
|
||||||
* UACPI_LOG_INFO -> allowed
|
|
||||||
* UACPI_LOG_WARN -> allowed
|
|
||||||
* UACPI_LOG_ERROR -> allowed
|
|
||||||
*/
|
|
||||||
void uacpi_context_set_log_level(uacpi_log_level);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enables table checksum validation at installation time instead of first use.
|
|
||||||
* Note that this makes uACPI map the entire table at once, which not all
|
|
||||||
* hosts are able to handle at early init.
|
|
||||||
*/
|
|
||||||
void uacpi_context_set_proactive_table_checksum(uacpi_bool);
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
/*
|
|
||||||
* Set the maximum number of seconds a While loop is allowed to run for before
|
|
||||||
* getting timed out.
|
|
||||||
*
|
|
||||||
* 0 is treated a special value that resets the setting to the default value.
|
|
||||||
*/
|
|
||||||
void uacpi_context_set_loop_timeout(uacpi_u32 seconds);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the maximum call stack depth AML can reach before getting aborted.
|
|
||||||
*
|
|
||||||
* 0 is treated as a special value that resets the setting to the default value.
|
|
||||||
*/
|
|
||||||
void uacpi_context_set_max_call_stack_depth(uacpi_u32 depth);
|
|
||||||
|
|
||||||
uacpi_u32 uacpi_context_get_loop_timeout(void);
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,286 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/uacpi.h>
|
|
||||||
#include <uacpi/acpi.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
typedef enum uacpi_fixed_event {
|
|
||||||
UACPI_FIXED_EVENT_TIMER_STATUS = 1,
|
|
||||||
UACPI_FIXED_EVENT_POWER_BUTTON,
|
|
||||||
UACPI_FIXED_EVENT_SLEEP_BUTTON,
|
|
||||||
UACPI_FIXED_EVENT_RTC,
|
|
||||||
UACPI_FIXED_EVENT_MAX = UACPI_FIXED_EVENT_RTC,
|
|
||||||
} uacpi_fixed_event;
|
|
||||||
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_install_fixed_event_handler(
|
|
||||||
uacpi_fixed_event event, uacpi_interrupt_handler handler, uacpi_handle user
|
|
||||||
))
|
|
||||||
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_uninstall_fixed_event_handler(
|
|
||||||
uacpi_fixed_event event
|
|
||||||
))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable/disable a fixed event. Note that the event is automatically enabled
|
|
||||||
* upon installing a handler to it.
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_enable_fixed_event(uacpi_fixed_event event)
|
|
||||||
)
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_disable_fixed_event(uacpi_fixed_event event)
|
|
||||||
)
|
|
||||||
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_clear_fixed_event(uacpi_fixed_event event)
|
|
||||||
)
|
|
||||||
|
|
||||||
typedef enum uacpi_event_info {
|
|
||||||
// Event is enabled in software
|
|
||||||
UACPI_EVENT_INFO_ENABLED = (1 << 0),
|
|
||||||
|
|
||||||
// Event is enabled in software (only for wake)
|
|
||||||
UACPI_EVENT_INFO_ENABLED_FOR_WAKE = (1 << 1),
|
|
||||||
|
|
||||||
// Event is masked
|
|
||||||
UACPI_EVENT_INFO_MASKED = (1 << 2),
|
|
||||||
|
|
||||||
// Event has a handler attached
|
|
||||||
UACPI_EVENT_INFO_HAS_HANDLER = (1 << 3),
|
|
||||||
|
|
||||||
// Hardware enable bit is set
|
|
||||||
UACPI_EVENT_INFO_HW_ENABLED = (1 << 4),
|
|
||||||
|
|
||||||
// Hardware status bit is set
|
|
||||||
UACPI_EVENT_INFO_HW_STATUS = (1 << 5),
|
|
||||||
} uacpi_event_info;
|
|
||||||
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_fixed_event_info(
|
|
||||||
uacpi_fixed_event event, uacpi_event_info *out_info
|
|
||||||
))
|
|
||||||
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_gpe_info(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx,
|
|
||||||
uacpi_event_info *out_info
|
|
||||||
))
|
|
||||||
|
|
||||||
// Set if the handler wishes to reenable the GPE it just handled
|
|
||||||
#define UACPI_GPE_REENABLE (1 << 7)
|
|
||||||
|
|
||||||
typedef uacpi_interrupt_ret (*uacpi_gpe_handler)(
|
|
||||||
uacpi_handle ctx, uacpi_namespace_node *gpe_device, uacpi_u16 idx
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef enum uacpi_gpe_triggering {
|
|
||||||
UACPI_GPE_TRIGGERING_LEVEL = 0,
|
|
||||||
UACPI_GPE_TRIGGERING_EDGE = 1,
|
|
||||||
UACPI_GPE_TRIGGERING_MAX = UACPI_GPE_TRIGGERING_EDGE,
|
|
||||||
} uacpi_gpe_triggering;
|
|
||||||
|
|
||||||
const uacpi_char *uacpi_gpe_triggering_to_string(
|
|
||||||
uacpi_gpe_triggering triggering
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Installs a handler to the provided GPE at 'idx' controlled by device
|
|
||||||
* 'gpe_device'. The GPE is automatically disabled & cleared according to the
|
|
||||||
* configured triggering upon invoking the handler. The event is optionally
|
|
||||||
* re-enabled (by returning UACPI_GPE_REENABLE from the handler)
|
|
||||||
*
|
|
||||||
* NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_install_gpe_handler(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx,
|
|
||||||
uacpi_gpe_triggering triggering, uacpi_gpe_handler handler, uacpi_handle ctx
|
|
||||||
))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Installs a raw handler to the provided GPE at 'idx' controlled by device
|
|
||||||
* 'gpe_device'. The handler is dispatched immediately after the event is
|
|
||||||
* received, status & enable bits are untouched.
|
|
||||||
*
|
|
||||||
* NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_install_gpe_handler_raw(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx,
|
|
||||||
uacpi_gpe_triggering triggering, uacpi_gpe_handler handler, uacpi_handle ctx
|
|
||||||
))
|
|
||||||
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_uninstall_gpe_handler(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_gpe_handler handler
|
|
||||||
))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Marks the GPE 'idx' managed by 'gpe_device' as wake-capable. 'wake_device' is
|
|
||||||
* optional and configures the GPE to generate an implicit notification whenever
|
|
||||||
* an event occurs.
|
|
||||||
*
|
|
||||||
* NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_setup_gpe_for_wake(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx,
|
|
||||||
uacpi_namespace_node *wake_device
|
|
||||||
))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Mark a GPE managed by 'gpe_device' as enabled/disabled for wake. The GPE must
|
|
||||||
* have previously been marked by calling uacpi_gpe_setup_for_wake. This
|
|
||||||
* function only affects the GPE enable register state following the call to
|
|
||||||
* uacpi_gpe_enable_all_for_wake.
|
|
||||||
*
|
|
||||||
* NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_enable_gpe_for_wake(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx
|
|
||||||
))
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_disable_gpe_for_wake(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx
|
|
||||||
))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finalize GPE initialization by enabling all GPEs not configured for wake and
|
|
||||||
* having a matching AML handler detected.
|
|
||||||
*
|
|
||||||
* This should be called after the kernel power managment subsystem has
|
|
||||||
* enumerated all of the devices, executing their _PRW methods etc., and
|
|
||||||
* marking those it wishes to use for wake by calling uacpi_setup_gpe_for_wake
|
|
||||||
* or uacpi_mark_gpe_for_wake.
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_finalize_gpe_initialization(void)
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable/disable a general purpose event managed by 'gpe_device'. Internally
|
|
||||||
* this uses reference counting to make sure a GPE is not disabled until all
|
|
||||||
* possible users of it do so. GPEs not marked for wake are enabled
|
|
||||||
* automatically so this API is only needed for wake events or those that don't
|
|
||||||
* have a corresponding AML handler.
|
|
||||||
*
|
|
||||||
* NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_enable_gpe(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx
|
|
||||||
))
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_disable_gpe(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx
|
|
||||||
))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Clear the status bit of the event 'idx' managed by 'gpe_device'.
|
|
||||||
*
|
|
||||||
* NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_clear_gpe(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx
|
|
||||||
))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Suspend/resume a general purpose event managed by 'gpe_device'. This bypasses
|
|
||||||
* the reference counting mechanism and unconditionally clears/sets the
|
|
||||||
* corresponding bit in the enable registers. This is used for switching the GPE
|
|
||||||
* to poll mode.
|
|
||||||
*
|
|
||||||
* NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_suspend_gpe(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx
|
|
||||||
))
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_resume_gpe(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx
|
|
||||||
))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finish handling the GPE managed by 'gpe_device' at 'idx'. This clears the
|
|
||||||
* status registers if it hasn't been cleared yet and re-enables the event if
|
|
||||||
* it was enabled before.
|
|
||||||
*
|
|
||||||
* NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_finish_handling_gpe(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx
|
|
||||||
))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Hard mask/umask a general purpose event at 'idx' managed by 'gpe_device'.
|
|
||||||
* This is used to permanently silence an event so that further calls to
|
|
||||||
* enable/disable as well as suspend/resume get ignored. This might be necessary
|
|
||||||
* for GPEs that cause an event storm due to the kernel's inability to properly
|
|
||||||
* handle them. The only way to enable a masked event is by a call to unmask.
|
|
||||||
*
|
|
||||||
* NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_mask_gpe(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx
|
|
||||||
))
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_unmask_gpe(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u16 idx
|
|
||||||
))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Disable all GPEs currently set up on the system.
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_disable_all_gpes(void)
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable all GPEs not marked as wake. This is only needed after the system
|
|
||||||
* wakes from a shallow sleep state and is called automatically by wake code.
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_enable_all_runtime_gpes(void)
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable all GPEs marked as wake. This is only needed before the system goes
|
|
||||||
* to sleep is called automatically by sleep code.
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_enable_all_wake_gpes(void)
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Install/uninstall a new GPE block, usually defined by a device in the
|
|
||||||
* namespace with a _HID of ACPI0006.
|
|
||||||
*/
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_install_gpe_block(
|
|
||||||
uacpi_namespace_node *gpe_device, uacpi_u64 address,
|
|
||||||
uacpi_address_space address_space, uacpi_u16 num_registers,
|
|
||||||
uacpi_u32 irq
|
|
||||||
))
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_uninstall_gpe_block(
|
|
||||||
uacpi_namespace_node *gpe_device
|
|
||||||
))
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/platform/compiler.h>
|
|
||||||
|
|
||||||
#define UACPI_BUILD_BUG_ON_WITH_MSG(expr, msg) UACPI_STATIC_ASSERT(!(expr), msg)
|
|
||||||
|
|
||||||
#define UACPI_BUILD_BUG_ON(expr) \
|
|
||||||
UACPI_BUILD_BUG_ON_WITH_MSG(expr, "BUILD BUG: " #expr " evaluated to true")
|
|
||||||
|
|
||||||
#define UACPI_EXPECT_SIZEOF(type, size) \
|
|
||||||
UACPI_BUILD_BUG_ON_WITH_MSG(sizeof(type) != size, \
|
|
||||||
"BUILD BUG: invalid type size")
|
|
@ -1,3 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/platform/compiler.h>
|
|
@ -1,155 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/acpi.h>
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/uacpi.h>
|
|
||||||
#include <uacpi/internal/dynamic_array.h>
|
|
||||||
#include <uacpi/internal/shareable.h>
|
|
||||||
#include <uacpi/context.h>
|
|
||||||
|
|
||||||
struct uacpi_runtime_context {
|
|
||||||
/*
|
|
||||||
* A local copy of FADT that has been verified & converted to most optimal
|
|
||||||
* format for faster access to the registers.
|
|
||||||
*/
|
|
||||||
struct acpi_fadt fadt;
|
|
||||||
|
|
||||||
uacpi_u64 flags;
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
/*
|
|
||||||
* A cached pointer to FACS so that we don't have to look it up in interrupt
|
|
||||||
* contexts as we can't take mutexes.
|
|
||||||
*/
|
|
||||||
struct acpi_facs *facs;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* pm1{a,b}_evt_blk split into two registers for convenience
|
|
||||||
*/
|
|
||||||
struct acpi_gas pm1a_status_blk;
|
|
||||||
struct acpi_gas pm1b_status_blk;
|
|
||||||
struct acpi_gas pm1a_enable_blk;
|
|
||||||
struct acpi_gas pm1b_enable_blk;
|
|
||||||
|
|
||||||
#define UACPI_SLEEP_TYP_INVALID 0xFF
|
|
||||||
uacpi_u8 last_sleep_typ_a;
|
|
||||||
uacpi_u8 last_sleep_typ_b;
|
|
||||||
|
|
||||||
uacpi_u8 s0_sleep_typ_a;
|
|
||||||
uacpi_u8 s0_sleep_typ_b;
|
|
||||||
|
|
||||||
uacpi_bool global_lock_acquired;
|
|
||||||
|
|
||||||
#ifndef UACPI_REDUCED_HARDWARE
|
|
||||||
uacpi_bool was_in_legacy_mode;
|
|
||||||
uacpi_bool has_global_lock;
|
|
||||||
uacpi_bool sci_handle_valid;
|
|
||||||
uacpi_handle sci_handle;
|
|
||||||
#endif
|
|
||||||
uacpi_u64 opcodes_executed;
|
|
||||||
|
|
||||||
uacpi_u32 loop_timeout_seconds;
|
|
||||||
uacpi_u32 max_call_stack_depth;
|
|
||||||
|
|
||||||
uacpi_u32 global_lock_seq_num;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These are stored here to protect against stuff like:
|
|
||||||
* - CopyObject(JUNK, \)
|
|
||||||
* - CopyObject(JUNK, \_GL)
|
|
||||||
*/
|
|
||||||
uacpi_mutex *global_lock_mutex;
|
|
||||||
uacpi_object *root_object;
|
|
||||||
|
|
||||||
#ifndef UACPI_REDUCED_HARDWARE
|
|
||||||
uacpi_handle *global_lock_event;
|
|
||||||
uacpi_handle *global_lock_spinlock;
|
|
||||||
uacpi_bool global_lock_pending;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uacpi_bool bad_timesource;
|
|
||||||
uacpi_u8 init_level;
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
#ifndef UACPI_REDUCED_HARDWARE
|
|
||||||
uacpi_bool is_hardware_reduced;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a per-table value but we mimic the NT implementation:
|
|
||||||
* treat all other definition blocks as if they were the same revision
|
|
||||||
* as DSDT.
|
|
||||||
*/
|
|
||||||
uacpi_bool is_rev1;
|
|
||||||
|
|
||||||
uacpi_u8 log_level;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct uacpi_runtime_context g_uacpi_rt_ctx;
|
|
||||||
|
|
||||||
static inline uacpi_bool uacpi_check_flag(uacpi_u64 flag)
|
|
||||||
{
|
|
||||||
return (g_uacpi_rt_ctx.flags & flag) == flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uacpi_bool uacpi_should_log(enum uacpi_log_level lvl)
|
|
||||||
{
|
|
||||||
return lvl <= g_uacpi_rt_ctx.log_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uacpi_bool uacpi_is_hardware_reduced(void)
|
|
||||||
{
|
|
||||||
#ifndef UACPI_REDUCED_HARDWARE
|
|
||||||
return g_uacpi_rt_ctx.is_hardware_reduced;
|
|
||||||
#else
|
|
||||||
return UACPI_TRUE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
static inline const uacpi_char *uacpi_init_level_to_string(uacpi_u8 lvl)
|
|
||||||
{
|
|
||||||
switch (lvl) {
|
|
||||||
case UACPI_INIT_LEVEL_EARLY:
|
|
||||||
return "early";
|
|
||||||
case UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED:
|
|
||||||
return "subsystem initialized";
|
|
||||||
case UACPI_INIT_LEVEL_NAMESPACE_LOADED:
|
|
||||||
return "namespace loaded";
|
|
||||||
case UACPI_INIT_LEVEL_NAMESPACE_INITIALIZED:
|
|
||||||
return "namespace initialized";
|
|
||||||
default:
|
|
||||||
return "<invalid>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UACPI_ENSURE_INIT_LEVEL_AT_LEAST(lvl) \
|
|
||||||
do { \
|
|
||||||
if (uacpi_unlikely(g_uacpi_rt_ctx.init_level < lvl)) { \
|
|
||||||
uacpi_error( \
|
|
||||||
"while evaluating %s: init level %d (%s) is too low, " \
|
|
||||||
"expected at least %d (%s)\n", __FUNCTION__, \
|
|
||||||
g_uacpi_rt_ctx.init_level, \
|
|
||||||
uacpi_init_level_to_string(g_uacpi_rt_ctx.init_level), lvl, \
|
|
||||||
uacpi_init_level_to_string(lvl) \
|
|
||||||
); \
|
|
||||||
return UACPI_STATUS_INIT_LEVEL_MISMATCH; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define UACPI_ENSURE_INIT_LEVEL_IS(lvl) \
|
|
||||||
do { \
|
|
||||||
if (uacpi_unlikely(g_uacpi_rt_ctx.init_level != lvl)) { \
|
|
||||||
uacpi_error( \
|
|
||||||
"while evaluating %s: invalid init level %d (%s), " \
|
|
||||||
"expected %d (%s)\n", __FUNCTION__, \
|
|
||||||
g_uacpi_rt_ctx.init_level, \
|
|
||||||
uacpi_init_level_to_string(g_uacpi_rt_ctx.init_level), lvl, \
|
|
||||||
uacpi_init_level_to_string(lvl) \
|
|
||||||
); \
|
|
||||||
return UACPI_STATUS_INIT_LEVEL_MISMATCH; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
@ -1,185 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/internal/stdlib.h>
|
|
||||||
#include <uacpi/kernel_api.h>
|
|
||||||
|
|
||||||
#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE(name, type, inline_capacity) \
|
|
||||||
struct name { \
|
|
||||||
type inline_storage[inline_capacity]; \
|
|
||||||
type *dynamic_storage; \
|
|
||||||
uacpi_size dynamic_capacity; \
|
|
||||||
uacpi_size size_including_inline; \
|
|
||||||
}; \
|
|
||||||
|
|
||||||
#define DYNAMIC_ARRAY_SIZE(arr) ((arr)->size_including_inline)
|
|
||||||
|
|
||||||
#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE_EXPORTS(name, type, prefix) \
|
|
||||||
prefix uacpi_size name##_inline_capacity(struct name *arr); \
|
|
||||||
prefix type *name##_at(struct name *arr, uacpi_size idx); \
|
|
||||||
prefix type *name##_alloc(struct name *arr); \
|
|
||||||
prefix type *name##_calloc(struct name *arr); \
|
|
||||||
prefix void name##_pop(struct name *arr); \
|
|
||||||
prefix uacpi_size name##_size(struct name *arr); \
|
|
||||||
prefix type *name##_last(struct name *arr) \
|
|
||||||
prefix void name##_clear(struct name *arr);
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
#define DYNAMIC_ARRAY_ALLOC_FN(name, type, prefix) \
|
|
||||||
UACPI_MAYBE_UNUSED \
|
|
||||||
prefix type *name##_alloc(struct name *arr) \
|
|
||||||
{ \
|
|
||||||
uacpi_size inline_cap; \
|
|
||||||
type *out_ptr; \
|
|
||||||
\
|
|
||||||
inline_cap = name##_inline_capacity(arr); \
|
|
||||||
\
|
|
||||||
if (arr->size_including_inline >= inline_cap) { \
|
|
||||||
uacpi_size dynamic_size; \
|
|
||||||
\
|
|
||||||
dynamic_size = arr->size_including_inline - inline_cap; \
|
|
||||||
if (dynamic_size == arr->dynamic_capacity) { \
|
|
||||||
uacpi_size bytes, type_size; \
|
|
||||||
void *new_buf; \
|
|
||||||
\
|
|
||||||
type_size = sizeof(*arr->dynamic_storage); \
|
|
||||||
\
|
|
||||||
if (arr->dynamic_capacity == 0) { \
|
|
||||||
bytes = type_size * inline_cap; \
|
|
||||||
} else { \
|
|
||||||
bytes = (arr->dynamic_capacity / 2) * type_size; \
|
|
||||||
if (bytes == 0) \
|
|
||||||
bytes += type_size; \
|
|
||||||
\
|
|
||||||
bytes += arr->dynamic_capacity * type_size; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
new_buf = uacpi_kernel_alloc(bytes); \
|
|
||||||
if (uacpi_unlikely(new_buf == UACPI_NULL)) \
|
|
||||||
return UACPI_NULL; \
|
|
||||||
\
|
|
||||||
arr->dynamic_capacity = bytes / type_size; \
|
|
||||||
\
|
|
||||||
if (arr->dynamic_storage) { \
|
|
||||||
uacpi_memcpy(new_buf, arr->dynamic_storage, \
|
|
||||||
dynamic_size * type_size); \
|
|
||||||
} \
|
|
||||||
uacpi_free(arr->dynamic_storage, dynamic_size * type_size); \
|
|
||||||
arr->dynamic_storage = new_buf; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
out_ptr = &arr->dynamic_storage[dynamic_size]; \
|
|
||||||
goto ret; \
|
|
||||||
} \
|
|
||||||
out_ptr = &arr->inline_storage[arr->size_including_inline]; \
|
|
||||||
ret: \
|
|
||||||
arr->size_including_inline++; \
|
|
||||||
return out_ptr; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DYNAMIC_ARRAY_CLEAR_FN(name, type, prefix) \
|
|
||||||
prefix void name##_clear(struct name *arr) \
|
|
||||||
{ \
|
|
||||||
uacpi_free( \
|
|
||||||
arr->dynamic_storage, \
|
|
||||||
arr->dynamic_capacity * sizeof(*arr->dynamic_storage) \
|
|
||||||
); \
|
|
||||||
arr->size_including_inline = 0; \
|
|
||||||
arr->dynamic_capacity = 0; \
|
|
||||||
arr->dynamic_storage = UACPI_NULL; \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define DYNAMIC_ARRAY_ALLOC_FN(name, type, prefix) \
|
|
||||||
UACPI_MAYBE_UNUSED \
|
|
||||||
prefix type *name##_alloc(struct name *arr) \
|
|
||||||
{ \
|
|
||||||
uacpi_size inline_cap; \
|
|
||||||
type *out_ptr; \
|
|
||||||
\
|
|
||||||
inline_cap = name##_inline_capacity(arr); \
|
|
||||||
\
|
|
||||||
if (arr->size_including_inline >= inline_cap) { \
|
|
||||||
uacpi_size dynamic_size; \
|
|
||||||
\
|
|
||||||
dynamic_size = arr->size_including_inline - inline_cap; \
|
|
||||||
if (uacpi_unlikely(dynamic_size == arr->dynamic_capacity)) \
|
|
||||||
return UACPI_NULL; \
|
|
||||||
\
|
|
||||||
out_ptr = &arr->dynamic_storage[dynamic_size]; \
|
|
||||||
goto ret; \
|
|
||||||
} \
|
|
||||||
out_ptr = &arr->inline_storage[arr->size_including_inline]; \
|
|
||||||
ret: \
|
|
||||||
arr->size_including_inline++; \
|
|
||||||
return out_ptr; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DYNAMIC_ARRAY_CLEAR_FN(name, type, prefix) \
|
|
||||||
prefix void name##_clear(struct name *arr) \
|
|
||||||
{ \
|
|
||||||
arr->size_including_inline = 0; \
|
|
||||||
arr->dynamic_capacity = 0; \
|
|
||||||
arr->dynamic_storage = UACPI_NULL; \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL(name, type, prefix) \
|
|
||||||
UACPI_MAYBE_UNUSED \
|
|
||||||
prefix uacpi_size name##_inline_capacity(struct name *arr) \
|
|
||||||
{ \
|
|
||||||
return sizeof(arr->inline_storage) / sizeof(arr->inline_storage[0]); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
UACPI_MAYBE_UNUSED \
|
|
||||||
prefix uacpi_size name##_capacity(struct name *arr) \
|
|
||||||
{ \
|
|
||||||
return name##_inline_capacity(arr) + arr->dynamic_capacity; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
prefix type *name##_at(struct name *arr, uacpi_size idx) \
|
|
||||||
{ \
|
|
||||||
if (idx >= arr->size_including_inline) \
|
|
||||||
return UACPI_NULL; \
|
|
||||||
\
|
|
||||||
if (idx < name##_inline_capacity(arr)) \
|
|
||||||
return &arr->inline_storage[idx]; \
|
|
||||||
\
|
|
||||||
return &arr->dynamic_storage[idx - name##_inline_capacity(arr)]; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
DYNAMIC_ARRAY_ALLOC_FN(name, type, prefix) \
|
|
||||||
\
|
|
||||||
UACPI_MAYBE_UNUSED \
|
|
||||||
prefix type *name##_calloc(struct name *arr) \
|
|
||||||
{ \
|
|
||||||
type *ret; \
|
|
||||||
\
|
|
||||||
ret = name##_alloc(arr); \
|
|
||||||
if (ret) \
|
|
||||||
uacpi_memzero(ret, sizeof(*ret)); \
|
|
||||||
\
|
|
||||||
return ret; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
UACPI_MAYBE_UNUSED \
|
|
||||||
prefix void name##_pop(struct name *arr) \
|
|
||||||
{ \
|
|
||||||
if (arr->size_including_inline == 0) \
|
|
||||||
return; \
|
|
||||||
\
|
|
||||||
arr->size_including_inline--; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
UACPI_MAYBE_UNUSED \
|
|
||||||
prefix uacpi_size name##_size(struct name *arr) \
|
|
||||||
{ \
|
|
||||||
return arr->size_including_inline; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
UACPI_MAYBE_UNUSED \
|
|
||||||
prefix type *name##_last(struct name *arr) \
|
|
||||||
{ \
|
|
||||||
return name##_at(arr, arr->size_including_inline - 1); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
DYNAMIC_ARRAY_CLEAR_FN(name, type, prefix)
|
|
@ -1,25 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/event.h>
|
|
||||||
|
|
||||||
// This fixed event is internal-only, and we don't expose it in the enum
|
|
||||||
#define UACPI_FIXED_EVENT_GLOBAL_LOCK 0
|
|
||||||
|
|
||||||
UACPI_ALWAYS_OK_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_initialize_events_early(void)
|
|
||||||
)
|
|
||||||
|
|
||||||
UACPI_ALWAYS_OK_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_initialize_events(void)
|
|
||||||
)
|
|
||||||
UACPI_STUB_IF_REDUCED_HARDWARE(
|
|
||||||
void uacpi_deinitialize_events(void)
|
|
||||||
)
|
|
||||||
|
|
||||||
UACPI_STUB_IF_REDUCED_HARDWARE(
|
|
||||||
void uacpi_events_match_post_dynamic_table_load(void)
|
|
||||||
)
|
|
||||||
|
|
||||||
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
|
|
||||||
uacpi_status uacpi_clear_all_events(void)
|
|
||||||
)
|
|
@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/helpers.h>
|
|
||||||
|
|
||||||
#define UACPI_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
|
||||||
|
|
||||||
#define UACPI_UNUSED(x) (void)(x)
|
|
@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/status.h>
|
|
||||||
#include <uacpi/internal/namespace.h>
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
enum uacpi_table_load_cause {
|
|
||||||
UACPI_TABLE_LOAD_CAUSE_LOAD_OP,
|
|
||||||
UACPI_TABLE_LOAD_CAUSE_LOAD_TABLE_OP,
|
|
||||||
UACPI_TABLE_LOAD_CAUSE_INIT,
|
|
||||||
UACPI_TABLE_LOAD_CAUSE_HOST,
|
|
||||||
};
|
|
||||||
|
|
||||||
uacpi_status uacpi_execute_table(void*, enum uacpi_table_load_cause cause);
|
|
||||||
uacpi_status uacpi_osi(uacpi_handle handle, uacpi_object *retval);
|
|
||||||
|
|
||||||
uacpi_status uacpi_execute_control_method(
|
|
||||||
uacpi_namespace_node *scope, uacpi_control_method *method,
|
|
||||||
const uacpi_object_array *args, uacpi_object **ret
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
@ -1,77 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/internal/types.h>
|
|
||||||
#include <uacpi/acpi.h>
|
|
||||||
#include <uacpi/io.h>
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
typedef struct uacpi_mapped_gas {
|
|
||||||
uacpi_handle mapping;
|
|
||||||
uacpi_u8 access_bit_width;
|
|
||||||
uacpi_u8 total_bit_width;
|
|
||||||
uacpi_u8 bit_offset;
|
|
||||||
|
|
||||||
uacpi_status (*read)(
|
|
||||||
uacpi_handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out
|
|
||||||
);
|
|
||||||
uacpi_status (*write)(
|
|
||||||
uacpi_handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in
|
|
||||||
);
|
|
||||||
|
|
||||||
void (*unmap)(uacpi_handle, uacpi_size);
|
|
||||||
} uacpi_mapped_gas;
|
|
||||||
|
|
||||||
uacpi_status uacpi_map_gas_noalloc(
|
|
||||||
const struct acpi_gas *gas, uacpi_mapped_gas *out_mapped
|
|
||||||
);
|
|
||||||
void uacpi_unmap_gas_nofree(uacpi_mapped_gas *gas);
|
|
||||||
|
|
||||||
uacpi_size uacpi_round_up_bits_to_bytes(uacpi_size bit_length);
|
|
||||||
|
|
||||||
void uacpi_read_buffer_field(
|
|
||||||
const uacpi_buffer_field *field, void *dst
|
|
||||||
);
|
|
||||||
void uacpi_write_buffer_field(
|
|
||||||
uacpi_buffer_field *field, const void *src, uacpi_size size
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_field_unit_get_read_type(
|
|
||||||
struct uacpi_field_unit *field, uacpi_object_type *out_type
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_field_unit_get_bit_length(
|
|
||||||
struct uacpi_field_unit *field, uacpi_size *out_length
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_read_field_unit(
|
|
||||||
uacpi_field_unit *field, void *dst, uacpi_size size,
|
|
||||||
uacpi_data_view *wtr_response
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_write_field_unit(
|
|
||||||
uacpi_field_unit *field, const void *src, uacpi_size size,
|
|
||||||
uacpi_data_view *wtr_response
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_system_memory_read(
|
|
||||||
void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_system_memory_write(
|
|
||||||
void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 in
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_system_io_read(
|
|
||||||
uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_system_io_write(
|
|
||||||
uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_pci_read(
|
|
||||||
uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_pci_write(
|
|
||||||
uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
@ -1,23 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/kernel_api.h>
|
|
||||||
#include <uacpi/internal/context.h>
|
|
||||||
#include <uacpi/log.h>
|
|
||||||
|
|
||||||
#ifdef UACPI_FORMATTED_LOGGING
|
|
||||||
#define uacpi_log uacpi_kernel_log
|
|
||||||
#else
|
|
||||||
UACPI_PRINTF_DECL(2, 3)
|
|
||||||
void uacpi_log(uacpi_log_level, const uacpi_char*, ...);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define uacpi_log_lvl(lvl, ...) \
|
|
||||||
do { if (uacpi_should_log(lvl)) uacpi_log(lvl, __VA_ARGS__); } while (0)
|
|
||||||
|
|
||||||
#define uacpi_debug(...) uacpi_log_lvl(UACPI_LOG_DEBUG, __VA_ARGS__)
|
|
||||||
#define uacpi_trace(...) uacpi_log_lvl(UACPI_LOG_TRACE, __VA_ARGS__)
|
|
||||||
#define uacpi_info(...) uacpi_log_lvl(UACPI_LOG_INFO, __VA_ARGS__)
|
|
||||||
#define uacpi_warn(...) uacpi_log_lvl(UACPI_LOG_WARN, __VA_ARGS__)
|
|
||||||
#define uacpi_error(...) uacpi_log_lvl(UACPI_LOG_ERROR, __VA_ARGS__)
|
|
||||||
|
|
||||||
void uacpi_logger_initialize(void);
|
|
@ -1,82 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/internal/types.h>
|
|
||||||
#include <uacpi/kernel_api.h>
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
uacpi_bool uacpi_this_thread_owns_aml_mutex(uacpi_mutex*);
|
|
||||||
|
|
||||||
uacpi_status uacpi_acquire_aml_mutex(uacpi_mutex*, uacpi_u16 timeout);
|
|
||||||
uacpi_status uacpi_release_aml_mutex(uacpi_mutex*);
|
|
||||||
|
|
||||||
static inline uacpi_status uacpi_acquire_native_mutex(uacpi_handle mtx)
|
|
||||||
{
|
|
||||||
if (uacpi_unlikely(mtx == UACPI_NULL))
|
|
||||||
return UACPI_STATUS_INVALID_ARGUMENT;
|
|
||||||
|
|
||||||
return uacpi_kernel_acquire_mutex(mtx, 0xFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
uacpi_status uacpi_acquire_native_mutex_with_timeout(
|
|
||||||
uacpi_handle mtx, uacpi_u16 timeout
|
|
||||||
);
|
|
||||||
|
|
||||||
static inline uacpi_status uacpi_release_native_mutex(uacpi_handle mtx)
|
|
||||||
{
|
|
||||||
if (uacpi_unlikely(mtx == UACPI_NULL))
|
|
||||||
return UACPI_STATUS_INVALID_ARGUMENT;
|
|
||||||
|
|
||||||
uacpi_kernel_release_mutex(mtx);
|
|
||||||
return UACPI_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uacpi_status uacpi_acquire_native_mutex_may_be_null(
|
|
||||||
uacpi_handle mtx
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (mtx == UACPI_NULL)
|
|
||||||
return UACPI_STATUS_OK;
|
|
||||||
|
|
||||||
return uacpi_kernel_acquire_mutex(mtx, 0xFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uacpi_status uacpi_release_native_mutex_may_be_null(
|
|
||||||
uacpi_handle mtx
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (mtx == UACPI_NULL)
|
|
||||||
return UACPI_STATUS_OK;
|
|
||||||
|
|
||||||
uacpi_kernel_release_mutex(mtx);
|
|
||||||
return UACPI_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct uacpi_recursive_lock {
|
|
||||||
uacpi_handle mutex;
|
|
||||||
uacpi_size depth;
|
|
||||||
uacpi_thread_id owner;
|
|
||||||
};
|
|
||||||
|
|
||||||
uacpi_status uacpi_recursive_lock_init(struct uacpi_recursive_lock *lock);
|
|
||||||
uacpi_status uacpi_recursive_lock_deinit(struct uacpi_recursive_lock *lock);
|
|
||||||
|
|
||||||
uacpi_status uacpi_recursive_lock_acquire(struct uacpi_recursive_lock *lock);
|
|
||||||
uacpi_status uacpi_recursive_lock_release(struct uacpi_recursive_lock *lock);
|
|
||||||
|
|
||||||
struct uacpi_rw_lock {
|
|
||||||
uacpi_handle read_mutex;
|
|
||||||
uacpi_handle write_mutex;
|
|
||||||
uacpi_size num_readers;
|
|
||||||
};
|
|
||||||
|
|
||||||
uacpi_status uacpi_rw_lock_init(struct uacpi_rw_lock *lock);
|
|
||||||
uacpi_status uacpi_rw_lock_deinit(struct uacpi_rw_lock *lock);
|
|
||||||
|
|
||||||
uacpi_status uacpi_rw_lock_read(struct uacpi_rw_lock *lock);
|
|
||||||
uacpi_status uacpi_rw_unlock_read(struct uacpi_rw_lock *lock);
|
|
||||||
|
|
||||||
uacpi_status uacpi_rw_lock_write(struct uacpi_rw_lock *lock);
|
|
||||||
uacpi_status uacpi_rw_unlock_write(struct uacpi_rw_lock *lock);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
@ -1,123 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/internal/shareable.h>
|
|
||||||
#include <uacpi/status.h>
|
|
||||||
#include <uacpi/namespace.h>
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
#define UACPI_NAMESPACE_NODE_FLAG_ALIAS (1 << 0)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This node has been uninstalled and has no object associated with it.
|
|
||||||
*
|
|
||||||
* This is used to handle edge cases where an object needs to reference
|
|
||||||
* a namespace node, where the node might end up going out of scope before
|
|
||||||
* the object lifetime ends.
|
|
||||||
*/
|
|
||||||
#define UACPI_NAMESPACE_NODE_FLAG_DANGLING (1u << 1)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This node is method-local and must not be exposed via public API as its
|
|
||||||
* lifetime is limited.
|
|
||||||
*/
|
|
||||||
#define UACPI_NAMESPACE_NODE_FLAG_TEMPORARY (1u << 2)
|
|
||||||
|
|
||||||
#define UACPI_NAMESPACE_NODE_PREDEFINED (1u << 31)
|
|
||||||
|
|
||||||
typedef struct uacpi_namespace_node {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
uacpi_object_name name;
|
|
||||||
uacpi_u32 flags;
|
|
||||||
uacpi_object *object;
|
|
||||||
struct uacpi_namespace_node *parent;
|
|
||||||
struct uacpi_namespace_node *child;
|
|
||||||
struct uacpi_namespace_node *next;
|
|
||||||
} uacpi_namespace_node;
|
|
||||||
|
|
||||||
uacpi_status uacpi_initialize_namespace(void);
|
|
||||||
void uacpi_deinitialize_namespace(void);
|
|
||||||
|
|
||||||
uacpi_namespace_node *uacpi_namespace_node_alloc(uacpi_object_name name);
|
|
||||||
void uacpi_namespace_node_unref(uacpi_namespace_node *node);
|
|
||||||
|
|
||||||
|
|
||||||
uacpi_status uacpi_namespace_node_type_unlocked(
|
|
||||||
const uacpi_namespace_node *node, uacpi_object_type *out_type
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_namespace_node_is_one_of_unlocked(
|
|
||||||
const uacpi_namespace_node *node, uacpi_object_type_bits type_mask,
|
|
||||||
uacpi_bool *out
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_object *uacpi_namespace_node_get_object(const uacpi_namespace_node *node);
|
|
||||||
|
|
||||||
uacpi_object *uacpi_namespace_node_get_object_typed(
|
|
||||||
const uacpi_namespace_node *node, uacpi_object_type_bits type_mask
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_namespace_node_acquire_object(
|
|
||||||
const uacpi_namespace_node *node, uacpi_object **out_obj
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_namespace_node_acquire_object_typed(
|
|
||||||
const uacpi_namespace_node *node, uacpi_object_type_bits,
|
|
||||||
uacpi_object **out_obj
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_namespace_node_reacquire_object(
|
|
||||||
uacpi_object *obj
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_namespace_node_release_object(
|
|
||||||
uacpi_object *obj
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_namespace_node_install(
|
|
||||||
uacpi_namespace_node *parent, uacpi_namespace_node *node
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_namespace_node_uninstall(uacpi_namespace_node *node);
|
|
||||||
|
|
||||||
uacpi_namespace_node *uacpi_namespace_node_find_sub_node(
|
|
||||||
uacpi_namespace_node *parent,
|
|
||||||
uacpi_object_name name
|
|
||||||
);
|
|
||||||
|
|
||||||
enum uacpi_may_search_above_parent {
|
|
||||||
UACPI_MAY_SEARCH_ABOVE_PARENT_NO,
|
|
||||||
UACPI_MAY_SEARCH_ABOVE_PARENT_YES,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum uacpi_permanent_only {
|
|
||||||
UACPI_PERMANENT_ONLY_NO,
|
|
||||||
UACPI_PERMANENT_ONLY_YES,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum uacpi_should_lock {
|
|
||||||
UACPI_SHOULD_LOCK_NO,
|
|
||||||
UACPI_SHOULD_LOCK_YES,
|
|
||||||
};
|
|
||||||
|
|
||||||
uacpi_status uacpi_namespace_node_resolve(
|
|
||||||
uacpi_namespace_node *scope, const uacpi_char *path, enum uacpi_should_lock,
|
|
||||||
enum uacpi_may_search_above_parent, enum uacpi_permanent_only,
|
|
||||||
uacpi_namespace_node **out_node
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_namespace_do_for_each_child(
|
|
||||||
uacpi_namespace_node *parent, uacpi_iteration_callback descending_callback,
|
|
||||||
uacpi_iteration_callback ascending_callback,
|
|
||||||
uacpi_object_type_bits, uacpi_u32 max_depth, enum uacpi_should_lock,
|
|
||||||
enum uacpi_permanent_only, void *user
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_bool uacpi_namespace_node_is_dangling(uacpi_namespace_node *node);
|
|
||||||
uacpi_bool uacpi_namespace_node_is_temporary(uacpi_namespace_node *node);
|
|
||||||
uacpi_bool uacpi_namespace_node_is_predefined(uacpi_namespace_node *node);
|
|
||||||
|
|
||||||
uacpi_status uacpi_namespace_read_lock(void);
|
|
||||||
uacpi_status uacpi_namespace_read_unlock(void);
|
|
||||||
|
|
||||||
uacpi_status uacpi_namespace_write_lock(void);
|
|
||||||
uacpi_status uacpi_namespace_write_unlock(void);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/internal/types.h>
|
|
||||||
#include <uacpi/notify.h>
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
uacpi_status uacpi_initialize_notify(void);
|
|
||||||
void uacpi_deinitialize_notify(void);
|
|
||||||
|
|
||||||
uacpi_status uacpi_notify_all(uacpi_namespace_node *node, uacpi_u64 value);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/internal/types.h>
|
|
||||||
#include <uacpi/opregion.h>
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
uacpi_status uacpi_initialize_opregion(void);
|
|
||||||
void uacpi_deinitialize_opregion(void);
|
|
||||||
|
|
||||||
void uacpi_trace_region_error(
|
|
||||||
uacpi_namespace_node *node, uacpi_char *message, uacpi_status ret
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_install_address_space_handler_with_flags(
|
|
||||||
uacpi_namespace_node *device_node, enum uacpi_address_space space,
|
|
||||||
uacpi_region_handler handler, uacpi_handle handler_context,
|
|
||||||
uacpi_u16 flags
|
|
||||||
);
|
|
||||||
|
|
||||||
void uacpi_opregion_uninstall_handler(uacpi_namespace_node *node);
|
|
||||||
|
|
||||||
uacpi_bool uacpi_address_space_handler_is_default(
|
|
||||||
uacpi_address_space_handler *handler
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_address_space_handlers *uacpi_node_get_address_space_handlers(
|
|
||||||
uacpi_namespace_node *node
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_initialize_opregion_node(uacpi_namespace_node *node);
|
|
||||||
|
|
||||||
uacpi_status uacpi_opregion_attach(uacpi_namespace_node *node);
|
|
||||||
|
|
||||||
void uacpi_install_default_address_space_handlers(void);
|
|
||||||
|
|
||||||
uacpi_bool uacpi_is_buffer_access_address_space(uacpi_address_space space);
|
|
||||||
|
|
||||||
union uacpi_opregion_io_data {
|
|
||||||
uacpi_u64 *integer;
|
|
||||||
uacpi_data_view buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
uacpi_status uacpi_dispatch_opregion_io(
|
|
||||||
uacpi_field_unit *field, uacpi_u32 offset,
|
|
||||||
uacpi_region_op op, union uacpi_opregion_io_data data
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
@ -1,8 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/osi.h>
|
|
||||||
|
|
||||||
uacpi_status uacpi_initialize_interfaces(void);
|
|
||||||
void uacpi_deinitialize_interfaces(void);
|
|
||||||
|
|
||||||
uacpi_status uacpi_handle_osi(const uacpi_char *string, uacpi_bool *out_value);
|
|
@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/registers.h>
|
|
||||||
|
|
||||||
uacpi_status uacpi_initialize_registers(void);
|
|
||||||
void uacpi_deinitialize_registers(void);
|
|
@ -1,327 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/internal/types.h>
|
|
||||||
#include <uacpi/resources.h>
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
enum uacpi_aml_resource {
|
|
||||||
UACPI_AML_RESOURCE_TYPE_INVALID = 0,
|
|
||||||
|
|
||||||
// Small resources
|
|
||||||
UACPI_AML_RESOURCE_IRQ,
|
|
||||||
UACPI_AML_RESOURCE_DMA,
|
|
||||||
UACPI_AML_RESOURCE_START_DEPENDENT,
|
|
||||||
UACPI_AML_RESOURCE_END_DEPENDENT,
|
|
||||||
UACPI_AML_RESOURCE_IO,
|
|
||||||
UACPI_AML_RESOURCE_FIXED_IO,
|
|
||||||
UACPI_AML_RESOURCE_FIXED_DMA,
|
|
||||||
UACPI_AML_RESOURCE_VENDOR_TYPE0,
|
|
||||||
UACPI_AML_RESOURCE_END_TAG,
|
|
||||||
|
|
||||||
// Large resources
|
|
||||||
UACPI_AML_RESOURCE_MEMORY24,
|
|
||||||
UACPI_AML_RESOURCE_GENERIC_REGISTER,
|
|
||||||
UACPI_AML_RESOURCE_VENDOR_TYPE1,
|
|
||||||
UACPI_AML_RESOURCE_MEMORY32,
|
|
||||||
UACPI_AML_RESOURCE_FIXED_MEMORY32,
|
|
||||||
UACPI_AML_RESOURCE_ADDRESS32,
|
|
||||||
UACPI_AML_RESOURCE_ADDRESS16,
|
|
||||||
UACPI_AML_RESOURCE_EXTENDED_IRQ,
|
|
||||||
UACPI_AML_RESOURCE_ADDRESS64,
|
|
||||||
UACPI_AML_RESOURCE_ADDRESS64_EXTENDED,
|
|
||||||
UACPI_AML_RESOURCE_GPIO_CONNECTION,
|
|
||||||
UACPI_AML_RESOURCE_PIN_FUNCTION,
|
|
||||||
UACPI_AML_RESOURCE_SERIAL_CONNECTION,
|
|
||||||
UACPI_AML_RESOURCE_PIN_CONFIGURATION,
|
|
||||||
UACPI_AML_RESOURCE_PIN_GROUP,
|
|
||||||
UACPI_AML_RESOURCE_PIN_GROUP_FUNCTION,
|
|
||||||
UACPI_AML_RESOURCE_PIN_GROUP_CONFIGURATION,
|
|
||||||
UACPI_AML_RESOURCE_CLOCK_INPUT,
|
|
||||||
UACPI_AML_RESOURCE_MAX = UACPI_AML_RESOURCE_CLOCK_INPUT,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum uacpi_aml_resource_size_kind {
|
|
||||||
UACPI_AML_RESOURCE_SIZE_KIND_FIXED,
|
|
||||||
UACPI_AML_RESOURCE_SIZE_KIND_FIXED_OR_ONE_LESS,
|
|
||||||
UACPI_AML_RESOURCE_SIZE_KIND_VARIABLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum uacpi_aml_resource_kind {
|
|
||||||
UACPI_AML_RESOURCE_KIND_SMALL = 0,
|
|
||||||
UACPI_AML_RESOURCE_KIND_LARGE,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum uacpi_resource_convert_opcode {
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_END = 0,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AML -> native:
|
|
||||||
* Take the mask at 'aml_offset' and convert to an array of uacpi_u8
|
|
||||||
* at 'native_offset' with the value corresponding to the bit index.
|
|
||||||
* The array size is written to the byte at offset 'arg2'.
|
|
||||||
*
|
|
||||||
* native -> AML:
|
|
||||||
* Walk each element of the array at 'native_offset' and set the
|
|
||||||
* corresponding bit in the mask at 'aml_offset' to 1. The array size is
|
|
||||||
* read from the byte at offset 'arg2'.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_PACKED_ARRAY_8,
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_PACKED_ARRAY_16,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AML -> native:
|
|
||||||
* Grab the bits at the byte at 'aml_offset' + 'bit_index', and copy its
|
|
||||||
* value into the byte at 'native_offset'.
|
|
||||||
*
|
|
||||||
* native -> AML:
|
|
||||||
* Grab first N bits at 'native_offset' and copy to 'aml_offset' starting
|
|
||||||
* at the 'bit_index'.
|
|
||||||
*
|
|
||||||
* NOTE:
|
|
||||||
* These must be contiguous in this order.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_1,
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_2,
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_3,
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_6 =
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_3 + 3,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AML -> native:
|
|
||||||
* Copy N bytes at 'aml_offset' to 'native_offset'.
|
|
||||||
*
|
|
||||||
* native -> AML:
|
|
||||||
* Copy N bytes at 'native_offset' to 'aml_offset'.
|
|
||||||
*
|
|
||||||
* 'imm' is added to the accumulator.
|
|
||||||
*
|
|
||||||
* NOTE: These are affected by the current value in the accumulator. If it's
|
|
||||||
* set to 0 at the time of evalution, this is executed once, N times
|
|
||||||
* otherwise. 0xFF is considered a special value, which resets the
|
|
||||||
* accumulator to 0 unconditionally.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_FIELD_8,
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_FIELD_16,
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_FIELD_32,
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_FIELD_64,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the length of the current resource is less than 'arg0', then skip
|
|
||||||
* 'imm' instructions.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_SKIP_IF_AML_SIZE_LESS_THAN,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Skip 'imm' instructions if 'arg0' is not equal to the value in the
|
|
||||||
* accumulator.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_SKIP_IF_NOT_EQUALS,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AML -> native:
|
|
||||||
* Set the byte at 'native_offset' to 'imm'.
|
|
||||||
*
|
|
||||||
* native -> AML:
|
|
||||||
* Set the byte at 'aml_offset' to 'imm'.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_SET_TO_IMM,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AML -> native:
|
|
||||||
* Load the AML resoruce length into the accumulator as well as the field at
|
|
||||||
* 'native_offset' of width N.
|
|
||||||
*
|
|
||||||
* native -> AML:
|
|
||||||
* Load the resource length into the accumulator.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_LOAD_AML_SIZE_32,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AML -> native:
|
|
||||||
* Load the 8 bit field at 'aml_offset' into the accumulator and store at
|
|
||||||
* 'native_offset'.
|
|
||||||
*
|
|
||||||
* native -> AML:
|
|
||||||
* Load the 8 bit field at 'native_offset' into the accumulator and store
|
|
||||||
* at 'aml_offset'.
|
|
||||||
*
|
|
||||||
* The accumulator is multiplied by 'imm' unless it's set to zero.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_LOAD_8_STORE,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Load the N bit field at 'native_offset' into the accumulator
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_LOAD_8_NATIVE,
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_LOAD_16_NATIVE,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Load 'imm' into the accumulator.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_LOAD_IMM,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AML -> native:
|
|
||||||
* Load the resource source at offset = aml size + accumulator into the
|
|
||||||
* uacpi_resource_source struct at 'native_offset'. The string bytes are
|
|
||||||
* written to the offset at resource size + accumulator. The presence is
|
|
||||||
* detected by comparing the length of the resource to the offset,
|
|
||||||
* 'arg2' optionally specifies the offset to the upper bound of the string.
|
|
||||||
*
|
|
||||||
* native -> AML:
|
|
||||||
* Load the resource source from the uacpi_resource_source struct at
|
|
||||||
* 'native_offset' to aml_size + accumulator. aml_size + accumulator is
|
|
||||||
* optionally written to 'aml_offset' if it's specified.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_RESOURCE_SOURCE,
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_RESOURCE_SOURCE_NO_INDEX,
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_RESOURCE_LABEL,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AML -> native:
|
|
||||||
* Load the pin table with upper bound specified at 'aml_offset'.
|
|
||||||
* The table length is calculated by subtracting the upper bound from
|
|
||||||
* aml_size and is written into the accumulator.
|
|
||||||
*
|
|
||||||
* native -> AML:
|
|
||||||
* Load the pin table length from 'native_offset' and multiply by 2, store
|
|
||||||
* the result in the accumulator.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_LOAD_PIN_TABLE_LENGTH,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AML -> native:
|
|
||||||
* Store the accumulator divided by 2 at 'native_offset'.
|
|
||||||
* The table is copied to the offset at resource size from offset at
|
|
||||||
* aml_size with the pointer written to the offset at 'arg2'.
|
|
||||||
*
|
|
||||||
* native -> AML:
|
|
||||||
* Read the pin table from resource size offset, write aml_size to
|
|
||||||
* 'aml_offset'. Copy accumulator bytes to the offset at aml_size.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_PIN_TABLE,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AML -> native:
|
|
||||||
* Load vendor data with offset stored at 'aml_offset'. The length is
|
|
||||||
* calculated as aml_size - aml_offset and is written to 'native_offset'.
|
|
||||||
* The data is written to offset - aml_size with the pointer written back
|
|
||||||
* to the offset at 'arg2'.
|
|
||||||
*
|
|
||||||
* native -> AML:
|
|
||||||
* Read vendor data from the pointer at offset 'arg2' and size at
|
|
||||||
* 'native_offset', the offset to write to is calculated as the difference
|
|
||||||
* between the data pointer and the native resource end pointer.
|
|
||||||
* offset + aml_size is written to 'aml_offset' and the data is copied
|
|
||||||
* there as well.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_VENDOR_DATA,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AML -> native:
|
|
||||||
* Read the serial type from the byte at 'aml_offset' and write it to the
|
|
||||||
* type field of the uacpi_resource_serial_bus_common structure. Convert
|
|
||||||
* the serial type to native and set the resource type to it. Copy the
|
|
||||||
* vendor data to the offset at native size, the length is calculated
|
|
||||||
* as type_data_length - extra-type-specific-size, and is written to
|
|
||||||
* vendor_data_length, as well as the accumulator. The data pointer is
|
|
||||||
* written to vendor_data.
|
|
||||||
*
|
|
||||||
* native -> AML:
|
|
||||||
* Set the serial type at 'aml_offset' to the value stored at
|
|
||||||
* 'native_offset'. Load the vendor data to the offset at aml_size,
|
|
||||||
* the length is read from 'vendor_data_length', and the data is copied from
|
|
||||||
* 'vendor_data'.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_SERIAL_TYPE_SPECIFIC,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Produces an error if encountered in the instruction stream.
|
|
||||||
* Used to trap invalid/unexpected code flow.
|
|
||||||
*/
|
|
||||||
UACPI_RESOURCE_CONVERT_OPCODE_UNREACHABLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uacpi_resource_convert_instruction {
|
|
||||||
uacpi_u8 code;
|
|
||||||
|
|
||||||
union {
|
|
||||||
uacpi_u8 aml_offset;
|
|
||||||
uacpi_u8 arg0;
|
|
||||||
} f1;
|
|
||||||
|
|
||||||
union {
|
|
||||||
uacpi_u8 native_offset;
|
|
||||||
uacpi_u8 arg1;
|
|
||||||
} f2;
|
|
||||||
|
|
||||||
union {
|
|
||||||
uacpi_u8 imm;
|
|
||||||
uacpi_u8 bit_index;
|
|
||||||
uacpi_u8 arg2;
|
|
||||||
} f3;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uacpi_resource_spec {
|
|
||||||
uacpi_u8 type : 5;
|
|
||||||
uacpi_u8 native_type : 5;
|
|
||||||
uacpi_u8 resource_kind : 1;
|
|
||||||
uacpi_u8 size_kind : 2;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Size of the resource as appears in the AML byte stream, for variable
|
|
||||||
* length resources this is the minimum.
|
|
||||||
*/
|
|
||||||
uacpi_u16 aml_size;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Size of the native human-readable uacpi resource, for variable length
|
|
||||||
* resources this is the minimum. The final length is this field plus the
|
|
||||||
* result of extra_size_for_native().
|
|
||||||
*/
|
|
||||||
uacpi_u16 native_size;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculate the amount of extra bytes that must be allocated for a specific
|
|
||||||
* native resource given the AML counterpart. This being NULL means no extra
|
|
||||||
* bytes are needed, aka native resources is always the same size.
|
|
||||||
*/
|
|
||||||
uacpi_size (*extra_size_for_native)(
|
|
||||||
const struct uacpi_resource_spec*, void*, uacpi_size
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculate the number of bytes needed to represent a native resource as
|
|
||||||
* AML. The 'aml_size' field is used if this is NULL.
|
|
||||||
*/
|
|
||||||
uacpi_size (*size_for_aml)(
|
|
||||||
const struct uacpi_resource_spec*, uacpi_resource*
|
|
||||||
);
|
|
||||||
|
|
||||||
const struct uacpi_resource_convert_instruction *to_native;
|
|
||||||
const struct uacpi_resource_convert_instruction *to_aml;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef uacpi_iteration_decision (*uacpi_aml_resource_iteration_callback)(
|
|
||||||
void*, uacpi_u8 *data, uacpi_u16 resource_size,
|
|
||||||
const struct uacpi_resource_spec*
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_for_each_aml_resource(
|
|
||||||
uacpi_data_view, uacpi_aml_resource_iteration_callback cb, void *user
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_find_aml_resource_end_tag(
|
|
||||||
uacpi_data_view, uacpi_size *out_offset
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_native_resources_from_aml(
|
|
||||||
uacpi_data_view, uacpi_resources **out_resources
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_native_resources_to_aml(
|
|
||||||
uacpi_resources *resources, uacpi_object **out_template
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
@ -1,21 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
|
|
||||||
struct uacpi_shareable {
|
|
||||||
uacpi_u32 reference_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
void uacpi_shareable_init(uacpi_handle);
|
|
||||||
|
|
||||||
uacpi_bool uacpi_bugged_shareable(uacpi_handle);
|
|
||||||
void uacpi_make_shareable_bugged(uacpi_handle);
|
|
||||||
|
|
||||||
uacpi_u32 uacpi_shareable_ref(uacpi_handle);
|
|
||||||
uacpi_u32 uacpi_shareable_unref(uacpi_handle);
|
|
||||||
|
|
||||||
void uacpi_shareable_unref_and_delete_if_last(
|
|
||||||
uacpi_handle, void (*do_free)(uacpi_handle)
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_u32 uacpi_shareable_refcount(uacpi_handle);
|
|
@ -1,128 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/internal/types.h>
|
|
||||||
#include <uacpi/internal/helpers.h>
|
|
||||||
#include <uacpi/platform/libc.h>
|
|
||||||
#include <uacpi/platform/config.h>
|
|
||||||
#include <uacpi/kernel_api.h>
|
|
||||||
|
|
||||||
#ifdef UACPI_USE_BUILTIN_STRING
|
|
||||||
|
|
||||||
#ifndef uacpi_memcpy
|
|
||||||
void *uacpi_memcpy(void *dest, const void *src, uacpi_size count);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef uacpi_memmove
|
|
||||||
void *uacpi_memmove(void *dest, const void *src, uacpi_size count);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef uacpi_memset
|
|
||||||
void *uacpi_memset(void *dest, uacpi_i32 ch, uacpi_size count);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef uacpi_memcmp
|
|
||||||
uacpi_i32 uacpi_memcmp(const void *lhs, const void *rhs, uacpi_size count);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#ifndef uacpi_memcpy
|
|
||||||
#ifdef UACPI_COMPILER_HAS_BUILTIN_MEMCPY
|
|
||||||
#define uacpi_memcpy __builtin_memcpy
|
|
||||||
#else
|
|
||||||
extern void *memcpy(void *dest, const void *src, uacpi_size count);
|
|
||||||
#define uacpi_memcpy memcpy
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef uacpi_memmove
|
|
||||||
#ifdef UACPI_COMPILER_HAS_BUILTIN_MEMMOVE
|
|
||||||
#define uacpi_memmove __builtin_memmove
|
|
||||||
#else
|
|
||||||
extern void *memmove(void *dest, const void *src, uacpi_size count);
|
|
||||||
#define uacpi_memmove memmove
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef uacpi_memset
|
|
||||||
#ifdef UACPI_COMPILER_HAS_BUILTIN_MEMSET
|
|
||||||
#define uacpi_memset __builtin_memset
|
|
||||||
#else
|
|
||||||
extern void *memset(void *dest, int ch, uacpi_size count);
|
|
||||||
#define uacpi_memset memset
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef uacpi_memcmp
|
|
||||||
#ifdef UACPI_COMPILER_HAS_BUILTIN_MEMCMP
|
|
||||||
#define uacpi_memcmp __builtin_memcmp
|
|
||||||
#else
|
|
||||||
extern int memcmp(const void *lhs, const void *rhs, uacpi_size count);
|
|
||||||
#define uacpi_memcmp memcmp
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef uacpi_strlen
|
|
||||||
uacpi_size uacpi_strlen(const uacpi_char *str);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef uacpi_strnlen
|
|
||||||
uacpi_size uacpi_strnlen(const uacpi_char *str, uacpi_size max);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef uacpi_strcmp
|
|
||||||
uacpi_i32 uacpi_strcmp(const uacpi_char *lhs, const uacpi_char *rhs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef uacpi_snprintf
|
|
||||||
UACPI_PRINTF_DECL(3, 4)
|
|
||||||
uacpi_i32 uacpi_snprintf(
|
|
||||||
uacpi_char *buffer, uacpi_size capacity, const uacpi_char *fmt, ...
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef uacpi_vsnprintf
|
|
||||||
uacpi_i32 uacpi_vsnprintf(
|
|
||||||
uacpi_char *buffer, uacpi_size capacity, const uacpi_char *fmt,
|
|
||||||
uacpi_va_list vlist
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UACPI_SIZED_FREES
|
|
||||||
#define uacpi_free(mem, size) uacpi_kernel_free(mem, size)
|
|
||||||
#else
|
|
||||||
#define uacpi_free(mem, _) uacpi_kernel_free(mem)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define uacpi_memzero(ptr, size) uacpi_memset(ptr, 0, size)
|
|
||||||
|
|
||||||
#define UACPI_COMPARE(x, y, op) ((x) op (y) ? (x) : (y))
|
|
||||||
#define UACPI_MIN(x, y) UACPI_COMPARE(x, y, <)
|
|
||||||
#define UACPI_MAX(x, y) UACPI_COMPARE(x, y, >)
|
|
||||||
|
|
||||||
#define UACPI_ALIGN_UP_MASK(x, mask) (((x) + (mask)) & ~(mask))
|
|
||||||
#define UACPI_ALIGN_UP(x, val, type) UACPI_ALIGN_UP_MASK(x, (type)(val) - 1)
|
|
||||||
|
|
||||||
#define UACPI_ALIGN_DOWN_MASK(x, mask) ((x) & ~(mask))
|
|
||||||
#define UACPI_ALIGN_DOWN(x, val, type) UACPI_ALIGN_DOWN_MASK(x, (type)(val) - 1)
|
|
||||||
|
|
||||||
#define UACPI_IS_ALIGNED_MASK(x, mask) (((x) & (mask)) == 0)
|
|
||||||
#define UACPI_IS_ALIGNED(x, val, type) UACPI_IS_ALIGNED_MASK(x, (type)(val) - 1)
|
|
||||||
|
|
||||||
#define UACPI_IS_POWER_OF_TWO(x, type) UACPI_IS_ALIGNED(x, x, type)
|
|
||||||
|
|
||||||
void uacpi_memcpy_zerout(void *dst, const void *src,
|
|
||||||
uacpi_size dst_size, uacpi_size src_size);
|
|
||||||
|
|
||||||
// Returns the one-based bit location of LSb or 0
|
|
||||||
uacpi_u8 uacpi_bit_scan_forward(uacpi_u64);
|
|
||||||
|
|
||||||
// Returns the one-based bit location of MSb or 0
|
|
||||||
uacpi_u8 uacpi_bit_scan_backward(uacpi_u64);
|
|
||||||
|
|
||||||
#ifndef UACPI_NATIVE_ALLOC_ZEROED
|
|
||||||
void *uacpi_builtin_alloc_zeroed(uacpi_size size);
|
|
||||||
#define uacpi_kernel_alloc_zeroed uacpi_builtin_alloc_zeroed
|
|
||||||
#endif
|
|
@ -1,70 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/internal/context.h>
|
|
||||||
#include <uacpi/internal/interpreter.h>
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/status.h>
|
|
||||||
#include <uacpi/tables.h>
|
|
||||||
|
|
||||||
enum uacpi_table_origin {
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
UACPI_TABLE_ORIGIN_FIRMWARE_VIRTUAL = 0,
|
|
||||||
#endif
|
|
||||||
UACPI_TABLE_ORIGIN_FIRMWARE_PHYSICAL = 1,
|
|
||||||
|
|
||||||
UACPI_TABLE_ORIGIN_HOST_VIRTUAL,
|
|
||||||
UACPI_TABLE_ORIGIN_HOST_PHYSICAL,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uacpi_installed_table {
|
|
||||||
uacpi_phys_addr phys_addr;
|
|
||||||
struct acpi_sdt_hdr hdr;
|
|
||||||
void *ptr;
|
|
||||||
|
|
||||||
uacpi_u16 reference_count;
|
|
||||||
|
|
||||||
#define UACPI_TABLE_LOADED (1 << 0)
|
|
||||||
#define UACPI_TABLE_CSUM_VERIFIED (1 << 1)
|
|
||||||
#define UACPI_TABLE_INVALID (1 << 2)
|
|
||||||
uacpi_u8 flags;
|
|
||||||
uacpi_u8 origin;
|
|
||||||
};
|
|
||||||
|
|
||||||
uacpi_status uacpi_initialize_tables(void);
|
|
||||||
void uacpi_deinitialize_tables(void);
|
|
||||||
|
|
||||||
uacpi_bool uacpi_signatures_match(const void *const lhs, const void *const rhs);
|
|
||||||
uacpi_status uacpi_check_table_signature(void *table, const uacpi_char *expect);
|
|
||||||
uacpi_status uacpi_verify_table_checksum(void *table, uacpi_size size);
|
|
||||||
|
|
||||||
uacpi_status uacpi_table_install_physical_with_origin(
|
|
||||||
uacpi_phys_addr phys, enum uacpi_table_origin origin, uacpi_table *out_table
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_table_install_with_origin(
|
|
||||||
void *virt, enum uacpi_table_origin origin, uacpi_table *out_table
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
void uacpi_table_mark_as_loaded(uacpi_size idx);
|
|
||||||
|
|
||||||
uacpi_status uacpi_table_load_with_cause(
|
|
||||||
uacpi_size idx, enum uacpi_table_load_cause cause
|
|
||||||
);
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
typedef uacpi_iteration_decision (*uacpi_table_iteration_callback)
|
|
||||||
(void *user, struct uacpi_installed_table *tbl, uacpi_size idx);
|
|
||||||
|
|
||||||
uacpi_status uacpi_for_each_table(
|
|
||||||
uacpi_size base_idx, uacpi_table_iteration_callback, void *user
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef uacpi_bool (*uacpi_table_match_callback)
|
|
||||||
(struct uacpi_installed_table *tbl);
|
|
||||||
|
|
||||||
uacpi_status uacpi_table_match(
|
|
||||||
uacpi_size base_idx, uacpi_table_match_callback, uacpi_table *out_table
|
|
||||||
);
|
|
||||||
|
|
||||||
#define UACPI_PRI_TBL_HDR "'%.4s' (OEM ID '%.6s' OEM Table ID '%.8s')"
|
|
||||||
#define UACPI_FMT_TBL_HDR(hdr) (hdr)->signature, (hdr)->oemid, (hdr)->oem_table_id
|
|
@ -1,310 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/status.h>
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/internal/shareable.h>
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
// object->flags field if object->type == UACPI_OBJECT_REFERENCE
|
|
||||||
enum uacpi_reference_kind {
|
|
||||||
UACPI_REFERENCE_KIND_REFOF = 0,
|
|
||||||
UACPI_REFERENCE_KIND_LOCAL = 1,
|
|
||||||
UACPI_REFERENCE_KIND_ARG = 2,
|
|
||||||
UACPI_REFERENCE_KIND_NAMED = 3,
|
|
||||||
UACPI_REFERENCE_KIND_PKG_INDEX = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
// object->flags field if object->type == UACPI_OBJECT_STRING
|
|
||||||
enum uacpi_string_kind {
|
|
||||||
UACPI_STRING_KIND_NORMAL = 0,
|
|
||||||
UACPI_STRING_KIND_PATH,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct uacpi_buffer {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
union {
|
|
||||||
void *data;
|
|
||||||
uacpi_u8 *byte_data;
|
|
||||||
uacpi_char *text;
|
|
||||||
};
|
|
||||||
uacpi_size size;
|
|
||||||
} uacpi_buffer;
|
|
||||||
|
|
||||||
typedef struct uacpi_package {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
uacpi_object **objects;
|
|
||||||
uacpi_size count;
|
|
||||||
} uacpi_package;
|
|
||||||
|
|
||||||
typedef struct uacpi_buffer_field {
|
|
||||||
uacpi_buffer *backing;
|
|
||||||
uacpi_size bit_index;
|
|
||||||
uacpi_u32 bit_length;
|
|
||||||
uacpi_bool force_buffer;
|
|
||||||
} uacpi_buffer_field;
|
|
||||||
|
|
||||||
typedef struct uacpi_buffer_index {
|
|
||||||
uacpi_size idx;
|
|
||||||
uacpi_buffer *buffer;
|
|
||||||
} uacpi_buffer_index;
|
|
||||||
|
|
||||||
typedef struct uacpi_mutex {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
uacpi_handle handle;
|
|
||||||
uacpi_thread_id owner;
|
|
||||||
uacpi_u16 depth;
|
|
||||||
uacpi_u8 sync_level;
|
|
||||||
} uacpi_mutex;
|
|
||||||
|
|
||||||
typedef struct uacpi_event {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
uacpi_handle handle;
|
|
||||||
} uacpi_event;
|
|
||||||
|
|
||||||
typedef struct uacpi_address_space_handler {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
uacpi_region_handler callback;
|
|
||||||
uacpi_handle user_context;
|
|
||||||
struct uacpi_address_space_handler *next;
|
|
||||||
struct uacpi_operation_region *regions;
|
|
||||||
uacpi_u16 space;
|
|
||||||
|
|
||||||
#define UACPI_ADDRESS_SPACE_HANDLER_DEFAULT (1 << 0)
|
|
||||||
uacpi_u16 flags;
|
|
||||||
} uacpi_address_space_handler;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE: These are common object headers.
|
|
||||||
* Any changes to these structs must be propagated to all objects.
|
|
||||||
* ==============================================================
|
|
||||||
* Common for the following objects:
|
|
||||||
* - UACPI_OBJECT_OPERATION_REGION
|
|
||||||
* - UACPI_OBJECT_PROCESSOR
|
|
||||||
* - UACPI_OBJECT_DEVICE
|
|
||||||
* - UACPI_OBJECT_THERMAL_ZONE
|
|
||||||
*/
|
|
||||||
typedef struct uacpi_address_space_handlers {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
uacpi_address_space_handler *head;
|
|
||||||
} uacpi_address_space_handlers;
|
|
||||||
|
|
||||||
typedef struct uacpi_device_notify_handler {
|
|
||||||
uacpi_notify_handler callback;
|
|
||||||
uacpi_handle user_context;
|
|
||||||
struct uacpi_device_notify_handler *next;
|
|
||||||
} uacpi_device_notify_handler;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Common for the following objects:
|
|
||||||
* - UACPI_OBJECT_PROCESSOR
|
|
||||||
* - UACPI_OBJECT_DEVICE
|
|
||||||
* - UACPI_OBJECT_THERMAL_ZONE
|
|
||||||
*/
|
|
||||||
typedef struct uacpi_handlers {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
uacpi_address_space_handler *address_space_head;
|
|
||||||
uacpi_device_notify_handler *notify_head;
|
|
||||||
} uacpi_handlers;
|
|
||||||
|
|
||||||
// This region has a corresponding _REG method that was succesfully executed
|
|
||||||
#define UACPI_OP_REGION_STATE_REG_EXECUTED (1 << 0)
|
|
||||||
|
|
||||||
// This region was successfully attached to a handler
|
|
||||||
#define UACPI_OP_REGION_STATE_ATTACHED (1 << 1)
|
|
||||||
|
|
||||||
typedef struct uacpi_operation_region {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
uacpi_address_space_handler *handler;
|
|
||||||
uacpi_handle user_context;
|
|
||||||
uacpi_u16 space;
|
|
||||||
uacpi_u8 state_flags;
|
|
||||||
uacpi_u64 offset;
|
|
||||||
uacpi_u64 length;
|
|
||||||
|
|
||||||
union {
|
|
||||||
// If space == TABLE_DATA
|
|
||||||
uacpi_u64 table_idx;
|
|
||||||
|
|
||||||
// If space == PCC
|
|
||||||
uacpi_u8 *internal_buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Used to link regions sharing the same handler
|
|
||||||
struct uacpi_operation_region *next;
|
|
||||||
} uacpi_operation_region;
|
|
||||||
|
|
||||||
typedef struct uacpi_device {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
uacpi_address_space_handler *address_space_handlers;
|
|
||||||
uacpi_device_notify_handler *notify_handlers;
|
|
||||||
} uacpi_device;
|
|
||||||
|
|
||||||
typedef struct uacpi_processor {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
uacpi_address_space_handler *address_space_handlers;
|
|
||||||
uacpi_device_notify_handler *notify_handlers;
|
|
||||||
uacpi_u8 id;
|
|
||||||
uacpi_u32 block_address;
|
|
||||||
uacpi_u8 block_length;
|
|
||||||
} uacpi_processor;
|
|
||||||
|
|
||||||
typedef struct uacpi_thermal_zone {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
uacpi_address_space_handler *address_space_handlers;
|
|
||||||
uacpi_device_notify_handler *notify_handlers;
|
|
||||||
} uacpi_thermal_zone;
|
|
||||||
|
|
||||||
typedef struct uacpi_power_resource {
|
|
||||||
uacpi_u8 system_level;
|
|
||||||
uacpi_u16 resource_order;
|
|
||||||
} uacpi_power_resource;
|
|
||||||
|
|
||||||
typedef uacpi_status (*uacpi_native_call_handler)(
|
|
||||||
uacpi_handle ctx, uacpi_object *retval
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef struct uacpi_control_method {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
union {
|
|
||||||
uacpi_u8 *code;
|
|
||||||
uacpi_native_call_handler handler;
|
|
||||||
};
|
|
||||||
uacpi_mutex *mutex;
|
|
||||||
uacpi_u32 size;
|
|
||||||
uacpi_u8 sync_level : 4;
|
|
||||||
uacpi_u8 args : 3;
|
|
||||||
uacpi_u8 is_serialized : 1;
|
|
||||||
uacpi_u8 named_objects_persist: 1;
|
|
||||||
uacpi_u8 native_call : 1;
|
|
||||||
uacpi_u8 owns_code : 1;
|
|
||||||
} uacpi_control_method;
|
|
||||||
|
|
||||||
typedef enum uacpi_access_type {
|
|
||||||
UACPI_ACCESS_TYPE_ANY = 0,
|
|
||||||
UACPI_ACCESS_TYPE_BYTE = 1,
|
|
||||||
UACPI_ACCESS_TYPE_WORD = 2,
|
|
||||||
UACPI_ACCESS_TYPE_DWORD = 3,
|
|
||||||
UACPI_ACCESS_TYPE_QWORD = 4,
|
|
||||||
UACPI_ACCESS_TYPE_BUFFER = 5,
|
|
||||||
} uacpi_access_type;
|
|
||||||
|
|
||||||
typedef enum uacpi_lock_rule {
|
|
||||||
UACPI_LOCK_RULE_NO_LOCK = 0,
|
|
||||||
UACPI_LOCK_RULE_LOCK = 1,
|
|
||||||
} uacpi_lock_rule;
|
|
||||||
|
|
||||||
typedef enum uacpi_update_rule {
|
|
||||||
UACPI_UPDATE_RULE_PRESERVE = 0,
|
|
||||||
UACPI_UPDATE_RULE_WRITE_AS_ONES = 1,
|
|
||||||
UACPI_UPDATE_RULE_WRITE_AS_ZEROES = 2,
|
|
||||||
} uacpi_update_rule;
|
|
||||||
|
|
||||||
typedef enum uacpi_field_unit_kind {
|
|
||||||
UACPI_FIELD_UNIT_KIND_NORMAL = 0,
|
|
||||||
UACPI_FIELD_UNIT_KIND_INDEX = 1,
|
|
||||||
UACPI_FIELD_UNIT_KIND_BANK = 2,
|
|
||||||
} uacpi_field_unit_kind;
|
|
||||||
|
|
||||||
typedef struct uacpi_field_unit {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
|
|
||||||
union {
|
|
||||||
// UACPI_FIELD_UNIT_KIND_NORMAL
|
|
||||||
struct {
|
|
||||||
uacpi_namespace_node *region;
|
|
||||||
};
|
|
||||||
|
|
||||||
// UACPI_FIELD_UNIT_KIND_INDEX
|
|
||||||
struct {
|
|
||||||
struct uacpi_field_unit *index;
|
|
||||||
struct uacpi_field_unit *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// UACPI_FIELD_UNIT_KIND_BANK
|
|
||||||
struct {
|
|
||||||
uacpi_namespace_node *bank_region;
|
|
||||||
struct uacpi_field_unit *bank_selection;
|
|
||||||
uacpi_u64 bank_value;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
uacpi_object *connection;
|
|
||||||
|
|
||||||
uacpi_u32 byte_offset;
|
|
||||||
uacpi_u32 bit_length;
|
|
||||||
uacpi_u32 pin_offset;
|
|
||||||
uacpi_u8 bit_offset_within_first_byte;
|
|
||||||
uacpi_u8 access_width_bytes;
|
|
||||||
uacpi_u8 access_length;
|
|
||||||
|
|
||||||
uacpi_u8 attributes : 4;
|
|
||||||
uacpi_u8 update_rule : 2;
|
|
||||||
uacpi_u8 kind : 2;
|
|
||||||
uacpi_u8 lock_rule : 1;
|
|
||||||
} uacpi_field_unit;
|
|
||||||
|
|
||||||
typedef struct uacpi_object {
|
|
||||||
struct uacpi_shareable shareable;
|
|
||||||
uacpi_u8 type;
|
|
||||||
uacpi_u8 flags;
|
|
||||||
|
|
||||||
union {
|
|
||||||
uacpi_u64 integer;
|
|
||||||
uacpi_package *package;
|
|
||||||
uacpi_buffer_field buffer_field;
|
|
||||||
uacpi_object *inner_object;
|
|
||||||
uacpi_control_method *method;
|
|
||||||
uacpi_buffer *buffer;
|
|
||||||
uacpi_mutex *mutex;
|
|
||||||
uacpi_event *event;
|
|
||||||
uacpi_buffer_index buffer_index;
|
|
||||||
uacpi_operation_region *op_region;
|
|
||||||
uacpi_device *device;
|
|
||||||
uacpi_processor *processor;
|
|
||||||
uacpi_thermal_zone *thermal_zone;
|
|
||||||
uacpi_address_space_handlers *address_space_handlers;
|
|
||||||
uacpi_handlers *handlers;
|
|
||||||
uacpi_power_resource power_resource;
|
|
||||||
uacpi_field_unit *field_unit;
|
|
||||||
};
|
|
||||||
} uacpi_object;
|
|
||||||
|
|
||||||
uacpi_object *uacpi_create_object(uacpi_object_type type);
|
|
||||||
|
|
||||||
enum uacpi_assign_behavior {
|
|
||||||
UACPI_ASSIGN_BEHAVIOR_DEEP_COPY,
|
|
||||||
UACPI_ASSIGN_BEHAVIOR_SHALLOW_COPY,
|
|
||||||
};
|
|
||||||
|
|
||||||
uacpi_status uacpi_object_assign(uacpi_object *dst, uacpi_object *src,
|
|
||||||
enum uacpi_assign_behavior);
|
|
||||||
|
|
||||||
void uacpi_object_attach_child(uacpi_object *parent, uacpi_object *child);
|
|
||||||
void uacpi_object_detach_child(uacpi_object *parent);
|
|
||||||
|
|
||||||
struct uacpi_object *uacpi_create_internal_reference(
|
|
||||||
enum uacpi_reference_kind kind, uacpi_object *child
|
|
||||||
);
|
|
||||||
uacpi_object *uacpi_unwrap_internal_reference(uacpi_object *object);
|
|
||||||
|
|
||||||
enum uacpi_prealloc_objects {
|
|
||||||
UACPI_PREALLOC_OBJECTS_NO,
|
|
||||||
UACPI_PREALLOC_OBJECTS_YES,
|
|
||||||
};
|
|
||||||
|
|
||||||
uacpi_bool uacpi_package_fill(
|
|
||||||
uacpi_package *pkg, uacpi_size num_elements,
|
|
||||||
enum uacpi_prealloc_objects prealloc_objects
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_mutex *uacpi_create_mutex(void);
|
|
||||||
void uacpi_mutex_unref(uacpi_mutex*);
|
|
||||||
|
|
||||||
void uacpi_method_unref(uacpi_control_method*);
|
|
||||||
|
|
||||||
void uacpi_address_space_handler_unref(uacpi_address_space_handler *handler);
|
|
||||||
|
|
||||||
void uacpi_buffer_to_view(uacpi_buffer*, uacpi_data_view*);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
@ -1,45 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/utilities.h>
|
|
||||||
#include <uacpi/internal/log.h>
|
|
||||||
#include <uacpi/internal/stdlib.h>
|
|
||||||
|
|
||||||
static inline uacpi_phys_addr uacpi_truncate_phys_addr_with_warn(uacpi_u64 large_addr)
|
|
||||||
{
|
|
||||||
if (sizeof(uacpi_phys_addr) < 8 && large_addr > 0xFFFFFFFF) {
|
|
||||||
uacpi_warn(
|
|
||||||
"truncating a physical address 0x%"UACPI_PRIX64
|
|
||||||
" outside of address space\n", UACPI_FMT64(large_addr)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uacpi_phys_addr)large_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UACPI_PTR_TO_VIRT_ADDR(ptr) ((uacpi_virt_addr)(ptr))
|
|
||||||
#define UACPI_VIRT_ADDR_TO_PTR(vaddr) ((void*)(vaddr))
|
|
||||||
|
|
||||||
#define UACPI_PTR_ADD(ptr, value) ((void*)(((uacpi_u8*)(ptr)) + value))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Target buffer must have a length of at least 8 bytes.
|
|
||||||
*/
|
|
||||||
void uacpi_eisa_id_to_string(uacpi_u32, uacpi_char *out_string);
|
|
||||||
|
|
||||||
enum uacpi_base {
|
|
||||||
UACPI_BASE_AUTO,
|
|
||||||
UACPI_BASE_OCT = 8,
|
|
||||||
UACPI_BASE_DEC = 10,
|
|
||||||
UACPI_BASE_HEX = 16,
|
|
||||||
};
|
|
||||||
uacpi_status uacpi_string_to_integer(
|
|
||||||
const uacpi_char *str, uacpi_size max_chars, enum uacpi_base base,
|
|
||||||
uacpi_u64 *out_value
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_bool uacpi_is_valid_nameseg(uacpi_u8 *nameseg);
|
|
||||||
|
|
||||||
void uacpi_free_dynamic_string(const uacpi_char *str);
|
|
||||||
|
|
||||||
#define UACPI_NANOSECONDS_PER_SEC (1000ull * 1000ull * 1000ull)
|
|
@ -1,36 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/acpi.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
uacpi_status uacpi_gas_read(const struct acpi_gas *gas, uacpi_u64 *value);
|
|
||||||
uacpi_status uacpi_gas_write(const struct acpi_gas *gas, uacpi_u64 value);
|
|
||||||
|
|
||||||
typedef struct uacpi_mapped_gas uacpi_mapped_gas;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map a GAS for faster access in the future. The handle returned via
|
|
||||||
* 'out_mapped' must be freed & unmapped using uacpi_unmap_gas() when
|
|
||||||
* no longer needed.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_map_gas(const struct acpi_gas *gas, uacpi_mapped_gas **out_mapped);
|
|
||||||
void uacpi_unmap_gas(uacpi_mapped_gas*);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Same as uacpi_gas_{read,write} but operates on a pre-mapped handle for faster
|
|
||||||
* access and/or ability to use in critical sections/irq contexts.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_gas_read_mapped(const uacpi_mapped_gas *gas, uacpi_u64 *value);
|
|
||||||
uacpi_status uacpi_gas_write_mapped(const uacpi_mapped_gas *gas, uacpi_u64 value);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,375 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/platform/arch_helpers.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Returns the PHYSICAL address of the RSDP structure via *out_rsdp_address.
|
|
||||||
uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *out_rsdp_address);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map a physical memory range starting at 'addr' with length 'len', and return
|
|
||||||
* a virtual address that can be used to access it.
|
|
||||||
*
|
|
||||||
* NOTE: 'addr' may be misaligned, in this case the host is expected to round it
|
|
||||||
* down to the nearest page-aligned boundary and map that, while making
|
|
||||||
* sure that at least 'len' bytes are still mapped starting at 'addr'. The
|
|
||||||
* return value preserves the misaligned offset.
|
|
||||||
*
|
|
||||||
* Example for uacpi_kernel_map(0x1ABC, 0xF00):
|
|
||||||
* 1. Round down the 'addr' we got to the nearest page boundary.
|
|
||||||
* Considering a PAGE_SIZE of 4096 (or 0x1000), 0x1ABC rounded down
|
|
||||||
* is 0x1000, offset within the page is 0x1ABC - 0x1000 => 0xABC
|
|
||||||
* 2. Requested 'len' is 0xF00 bytes, but we just rounded the address
|
|
||||||
* down by 0xABC bytes, so add those on top. 0xF00 + 0xABC => 0x19BC
|
|
||||||
* 3. Round up the final 'len' to the nearest PAGE_SIZE boundary, in
|
|
||||||
* this case 0x19BC is 0x2000 bytes (2 pages if PAGE_SIZE is 4096)
|
|
||||||
* 4. Call the VMM to map the aligned address 0x1000 (from step 1)
|
|
||||||
* with length 0x2000 (from step 3). Let's assume the returned
|
|
||||||
* virtual address for the mapping is 0xF000.
|
|
||||||
* 5. Add the original offset within page 0xABC (from step 1) to the
|
|
||||||
* resulting virtual address 0xF000 + 0xABC => 0xFABC. Return it
|
|
||||||
* to uACPI.
|
|
||||||
*/
|
|
||||||
void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Unmap a virtual memory range at 'addr' with a length of 'len' bytes.
|
|
||||||
*
|
|
||||||
* NOTE: 'addr' may be misaligned, see the comment above 'uacpi_kernel_map'.
|
|
||||||
* Similar steps to uacpi_kernel_map can be taken to retrieve the
|
|
||||||
* virtual address originally returned by the VMM for this mapping
|
|
||||||
* as well as its true length.
|
|
||||||
*/
|
|
||||||
void uacpi_kernel_unmap(void *addr, uacpi_size len);
|
|
||||||
|
|
||||||
#ifndef UACPI_FORMATTED_LOGGING
|
|
||||||
void uacpi_kernel_log(uacpi_log_level, const uacpi_char*);
|
|
||||||
#else
|
|
||||||
UACPI_PRINTF_DECL(2, 3)
|
|
||||||
void uacpi_kernel_log(uacpi_log_level, const uacpi_char*, ...);
|
|
||||||
void uacpi_kernel_vlog(uacpi_log_level, const uacpi_char*, uacpi_va_list);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Only the above ^^^ API may be used by early table access and
|
|
||||||
* UACPI_BAREBONES_MODE.
|
|
||||||
*/
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convenience initialization/deinitialization hooks that will be called by
|
|
||||||
* uACPI automatically when appropriate if compiled-in.
|
|
||||||
*/
|
|
||||||
#ifdef UACPI_KERNEL_INITIALIZATION
|
|
||||||
/*
|
|
||||||
* This API is invoked for each initialization level so that appropriate parts
|
|
||||||
* of the host kernel and/or glue code can be initialized at different stages.
|
|
||||||
*
|
|
||||||
* uACPI API that triggers calls to uacpi_kernel_initialize and the respective
|
|
||||||
* 'current_init_lvl' passed to the hook at that stage:
|
|
||||||
* 1. uacpi_initialize() -> UACPI_INIT_LEVEL_EARLY
|
|
||||||
* 2. uacpi_namespace_load() -> UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED
|
|
||||||
* 3. (start of) uacpi_namespace_initialize() -> UACPI_INIT_LEVEL_NAMESPACE_LOADED
|
|
||||||
* 4. (end of) uacpi_namespace_initialize() -> UACPI_INIT_LEVEL_NAMESPACE_INITIALIZED
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_kernel_initialize(uacpi_init_level current_init_lvl);
|
|
||||||
void uacpi_kernel_deinitialize(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Open a PCI device at 'address' for reading & writing.
|
|
||||||
*
|
|
||||||
* Note that this must be able to open any arbitrary PCI device, not just those
|
|
||||||
* detected during kernel PCI enumeration, since the following pattern is
|
|
||||||
* relatively common in AML firmware:
|
|
||||||
* Device (THC0)
|
|
||||||
* {
|
|
||||||
* // Device at 00:10.06
|
|
||||||
* Name (_ADR, 0x00100006) // _ADR: Address
|
|
||||||
*
|
|
||||||
* OperationRegion (THCR, PCI_Config, Zero, 0x0100)
|
|
||||||
* Field (THCR, ByteAcc, NoLock, Preserve)
|
|
||||||
* {
|
|
||||||
* // Vendor ID field in the PCI configuration space
|
|
||||||
* VDID, 32
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* // Check if the device at 00:10.06 actually exists, that is reading
|
|
||||||
* // from its configuration space returns something other than 0xFFs.
|
|
||||||
* If ((VDID != 0xFFFFFFFF))
|
|
||||||
* {
|
|
||||||
* // Actually create the rest of the device's body if it's present
|
|
||||||
* // in the system, otherwise skip it.
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* The handle returned via 'out_handle' is used to perform IO on the
|
|
||||||
* configuration space of the device.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_kernel_pci_device_open(
|
|
||||||
uacpi_pci_address address, uacpi_handle *out_handle
|
|
||||||
);
|
|
||||||
void uacpi_kernel_pci_device_close(uacpi_handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read & write the configuration space of a previously open PCI device.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_kernel_pci_read8(
|
|
||||||
uacpi_handle device, uacpi_size offset, uacpi_u8 *value
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_kernel_pci_read16(
|
|
||||||
uacpi_handle device, uacpi_size offset, uacpi_u16 *value
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_kernel_pci_read32(
|
|
||||||
uacpi_handle device, uacpi_size offset, uacpi_u32 *value
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_kernel_pci_write8(
|
|
||||||
uacpi_handle device, uacpi_size offset, uacpi_u8 value
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_kernel_pci_write16(
|
|
||||||
uacpi_handle device, uacpi_size offset, uacpi_u16 value
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_kernel_pci_write32(
|
|
||||||
uacpi_handle device, uacpi_size offset, uacpi_u32 value
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map a SystemIO address at [base, base + len) and return a kernel-implemented
|
|
||||||
* handle that can be used for reading and writing the IO range.
|
|
||||||
*
|
|
||||||
* NOTE: The x86 architecture uses the in/out family of instructions
|
|
||||||
* to access the SystemIO address space.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_kernel_io_map(
|
|
||||||
uacpi_io_addr base, uacpi_size len, uacpi_handle *out_handle
|
|
||||||
);
|
|
||||||
void uacpi_kernel_io_unmap(uacpi_handle handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read/Write the IO range mapped via uacpi_kernel_io_map
|
|
||||||
* at a 0-based 'offset' within the range.
|
|
||||||
*
|
|
||||||
* NOTE:
|
|
||||||
* The x86 architecture uses the in/out family of instructions
|
|
||||||
* to access the SystemIO address space.
|
|
||||||
*
|
|
||||||
* You are NOT allowed to break e.g. a 4-byte access into four 1-byte accesses.
|
|
||||||
* Hardware ALWAYS expects accesses to be of the exact width.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_kernel_io_read8(
|
|
||||||
uacpi_handle, uacpi_size offset, uacpi_u8 *out_value
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_kernel_io_read16(
|
|
||||||
uacpi_handle, uacpi_size offset, uacpi_u16 *out_value
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_kernel_io_read32(
|
|
||||||
uacpi_handle, uacpi_size offset, uacpi_u32 *out_value
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_kernel_io_write8(
|
|
||||||
uacpi_handle, uacpi_size offset, uacpi_u8 in_value
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_kernel_io_write16(
|
|
||||||
uacpi_handle, uacpi_size offset, uacpi_u16 in_value
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_kernel_io_write32(
|
|
||||||
uacpi_handle, uacpi_size offset, uacpi_u32 in_value
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate a block of memory of 'size' bytes.
|
|
||||||
* The contents of the allocated memory are unspecified.
|
|
||||||
*/
|
|
||||||
void *uacpi_kernel_alloc(uacpi_size size);
|
|
||||||
|
|
||||||
#ifdef UACPI_NATIVE_ALLOC_ZEROED
|
|
||||||
/*
|
|
||||||
* Allocate a block of memory of 'size' bytes.
|
|
||||||
* The returned memory block is expected to be zero-filled.
|
|
||||||
*/
|
|
||||||
void *uacpi_kernel_alloc_zeroed(uacpi_size size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Free a previously allocated memory block.
|
|
||||||
*
|
|
||||||
* 'mem' might be a NULL pointer. In this case, the call is assumed to be a
|
|
||||||
* no-op.
|
|
||||||
*
|
|
||||||
* An optionally enabled 'size_hint' parameter contains the size of the original
|
|
||||||
* allocation. Note that in some scenarios this incurs additional cost to
|
|
||||||
* calculate the object size.
|
|
||||||
*/
|
|
||||||
#ifndef UACPI_SIZED_FREES
|
|
||||||
void uacpi_kernel_free(void *mem);
|
|
||||||
#else
|
|
||||||
void uacpi_kernel_free(void *mem, uacpi_size size_hint);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the number of nanosecond ticks elapsed since boot,
|
|
||||||
* strictly monotonic.
|
|
||||||
*/
|
|
||||||
uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Spin for N microseconds.
|
|
||||||
*/
|
|
||||||
void uacpi_kernel_stall(uacpi_u8 usec);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sleep for N milliseconds.
|
|
||||||
*/
|
|
||||||
void uacpi_kernel_sleep(uacpi_u64 msec);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create/free an opaque non-recursive kernel mutex object.
|
|
||||||
*/
|
|
||||||
uacpi_handle uacpi_kernel_create_mutex(void);
|
|
||||||
void uacpi_kernel_free_mutex(uacpi_handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create/free an opaque kernel (semaphore-like) event object.
|
|
||||||
*/
|
|
||||||
uacpi_handle uacpi_kernel_create_event(void);
|
|
||||||
void uacpi_kernel_free_event(uacpi_handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a unique identifier of the currently executing thread.
|
|
||||||
*
|
|
||||||
* The returned thread id cannot be UACPI_THREAD_ID_NONE.
|
|
||||||
*/
|
|
||||||
uacpi_thread_id uacpi_kernel_get_thread_id(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Try to acquire the mutex with a millisecond timeout.
|
|
||||||
*
|
|
||||||
* The timeout value has the following meanings:
|
|
||||||
* 0x0000 - Attempt to acquire the mutex once, in a non-blocking manner
|
|
||||||
* 0x0001...0xFFFE - Attempt to acquire the mutex for at least 'timeout'
|
|
||||||
* milliseconds
|
|
||||||
* 0xFFFF - Infinite wait, block until the mutex is acquired
|
|
||||||
*
|
|
||||||
* The following are possible return values:
|
|
||||||
* 1. UACPI_STATUS_OK - successful acquire operation
|
|
||||||
* 2. UACPI_STATUS_TIMEOUT - timeout reached while attempting to acquire (or the
|
|
||||||
* single attempt to acquire was not successful for
|
|
||||||
* calls with timeout=0)
|
|
||||||
* 3. Any other value - signifies a host internal error and is treated as such
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_kernel_acquire_mutex(uacpi_handle, uacpi_u16);
|
|
||||||
void uacpi_kernel_release_mutex(uacpi_handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Try to wait for an event (counter > 0) with a millisecond timeout.
|
|
||||||
* A timeout value of 0xFFFF implies infinite wait.
|
|
||||||
*
|
|
||||||
* The internal counter is decremented by 1 if wait was successful.
|
|
||||||
*
|
|
||||||
* A successful wait is indicated by returning UACPI_TRUE.
|
|
||||||
*/
|
|
||||||
uacpi_bool uacpi_kernel_wait_for_event(uacpi_handle, uacpi_u16);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Signal the event object by incrementing its internal counter by 1.
|
|
||||||
*
|
|
||||||
* This function may be used in interrupt contexts.
|
|
||||||
*/
|
|
||||||
void uacpi_kernel_signal_event(uacpi_handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reset the event counter to 0.
|
|
||||||
*/
|
|
||||||
void uacpi_kernel_reset_event(uacpi_handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handle a firmware request.
|
|
||||||
*
|
|
||||||
* Currently either a Breakpoint or Fatal operators.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_kernel_handle_firmware_request(uacpi_firmware_request*);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Install an interrupt handler at 'irq', 'ctx' is passed to the provided
|
|
||||||
* handler for every invocation.
|
|
||||||
*
|
|
||||||
* 'out_irq_handle' is set to a kernel-implemented value that can be used to
|
|
||||||
* refer to this handler from other API.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_kernel_install_interrupt_handler(
|
|
||||||
uacpi_u32 irq, uacpi_interrupt_handler, uacpi_handle ctx,
|
|
||||||
uacpi_handle *out_irq_handle
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Uninstall an interrupt handler. 'irq_handle' is the value returned via
|
|
||||||
* 'out_irq_handle' during installation.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_kernel_uninstall_interrupt_handler(
|
|
||||||
uacpi_interrupt_handler, uacpi_handle irq_handle
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create/free a kernel spinlock object.
|
|
||||||
*
|
|
||||||
* Unlike other types of locks, spinlocks may be used in interrupt contexts.
|
|
||||||
*/
|
|
||||||
uacpi_handle uacpi_kernel_create_spinlock(void);
|
|
||||||
void uacpi_kernel_free_spinlock(uacpi_handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Lock/unlock helpers for spinlocks.
|
|
||||||
*
|
|
||||||
* These are expected to disable interrupts, returning the previous state of cpu
|
|
||||||
* flags, that can be used to possibly re-enable interrupts if they were enabled
|
|
||||||
* before.
|
|
||||||
*
|
|
||||||
* Note that lock is infalliable.
|
|
||||||
*/
|
|
||||||
uacpi_cpu_flags uacpi_kernel_lock_spinlock(uacpi_handle);
|
|
||||||
void uacpi_kernel_unlock_spinlock(uacpi_handle, uacpi_cpu_flags);
|
|
||||||
|
|
||||||
typedef enum uacpi_work_type {
|
|
||||||
/*
|
|
||||||
* Schedule a GPE handler method for execution.
|
|
||||||
* This should be scheduled to run on CPU0 to avoid potential SMI-related
|
|
||||||
* firmware bugs.
|
|
||||||
*/
|
|
||||||
UACPI_WORK_GPE_EXECUTION,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Schedule a Notify(device) firmware request for execution.
|
|
||||||
* This can run on any CPU.
|
|
||||||
*/
|
|
||||||
UACPI_WORK_NOTIFICATION,
|
|
||||||
} uacpi_work_type;
|
|
||||||
|
|
||||||
typedef void (*uacpi_work_handler)(uacpi_handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Schedules deferred work for execution.
|
|
||||||
* Might be invoked from an interrupt context.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_kernel_schedule_work(
|
|
||||||
uacpi_work_type, uacpi_work_handler, uacpi_handle ctx
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Waits for two types of work to finish:
|
|
||||||
* 1. All in-flight interrupts installed via uacpi_kernel_install_interrupt_handler
|
|
||||||
* 2. All work scheduled via uacpi_kernel_schedule_work
|
|
||||||
*
|
|
||||||
* Note that the waits must be done in this order specifically.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_kernel_wait_for_work_completion(void);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,40 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum uacpi_log_level {
|
|
||||||
/*
|
|
||||||
* Super verbose logging, every op & uop being processed is logged.
|
|
||||||
* Mostly useful for tracking down hangs/lockups.
|
|
||||||
*/
|
|
||||||
UACPI_LOG_DEBUG = 5,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A little verbose, every operation region access is traced with a bit of
|
|
||||||
* extra information on top.
|
|
||||||
*/
|
|
||||||
UACPI_LOG_TRACE = 4,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Only logs the bare minimum information about state changes and/or
|
|
||||||
* initialization progress.
|
|
||||||
*/
|
|
||||||
UACPI_LOG_INFO = 3,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Logs recoverable errors and/or non-important aborts.
|
|
||||||
*/
|
|
||||||
UACPI_LOG_WARN = 2,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Logs only critical errors that might affect the ability to initialize or
|
|
||||||
* prevent stable runtime.
|
|
||||||
*/
|
|
||||||
UACPI_LOG_ERROR = 1,
|
|
||||||
} uacpi_log_level;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,186 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/status.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
typedef struct uacpi_namespace_node uacpi_namespace_node;
|
|
||||||
|
|
||||||
uacpi_namespace_node *uacpi_namespace_root(void);
|
|
||||||
|
|
||||||
typedef enum uacpi_predefined_namespace {
|
|
||||||
UACPI_PREDEFINED_NAMESPACE_ROOT = 0,
|
|
||||||
UACPI_PREDEFINED_NAMESPACE_GPE,
|
|
||||||
UACPI_PREDEFINED_NAMESPACE_PR,
|
|
||||||
UACPI_PREDEFINED_NAMESPACE_SB,
|
|
||||||
UACPI_PREDEFINED_NAMESPACE_SI,
|
|
||||||
UACPI_PREDEFINED_NAMESPACE_TZ,
|
|
||||||
UACPI_PREDEFINED_NAMESPACE_GL,
|
|
||||||
UACPI_PREDEFINED_NAMESPACE_OS,
|
|
||||||
UACPI_PREDEFINED_NAMESPACE_OSI,
|
|
||||||
UACPI_PREDEFINED_NAMESPACE_REV,
|
|
||||||
UACPI_PREDEFINED_NAMESPACE_MAX = UACPI_PREDEFINED_NAMESPACE_REV,
|
|
||||||
} uacpi_predefined_namespace;
|
|
||||||
uacpi_namespace_node *uacpi_namespace_get_predefined(
|
|
||||||
uacpi_predefined_namespace
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns UACPI_TRUE if the provided 'node' is an alias.
|
|
||||||
*/
|
|
||||||
uacpi_bool uacpi_namespace_node_is_alias(uacpi_namespace_node *node);
|
|
||||||
|
|
||||||
uacpi_object_name uacpi_namespace_node_name(const uacpi_namespace_node *node);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the type of object stored at the namespace node.
|
|
||||||
*
|
|
||||||
* NOTE: due to the existance of the CopyObject operator in AML, the
|
|
||||||
* return value of this function is subject to TOCTOU bugs.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_namespace_node_type(
|
|
||||||
const uacpi_namespace_node *node, uacpi_object_type *out_type
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns UACPI_TRUE via 'out' if the type of the object stored at the
|
|
||||||
* namespace node matches the provided value, UACPI_FALSE otherwise.
|
|
||||||
*
|
|
||||||
* NOTE: due to the existance of the CopyObject operator in AML, the
|
|
||||||
* return value of this function is subject to TOCTOU bugs.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_namespace_node_is(
|
|
||||||
const uacpi_namespace_node *node, uacpi_object_type type, uacpi_bool *out
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns UACPI_TRUE via 'out' if the type of the object stored at the
|
|
||||||
* namespace node matches any of the type bits in the provided value,
|
|
||||||
* UACPI_FALSE otherwise.
|
|
||||||
*
|
|
||||||
* NOTE: due to the existance of the CopyObject operator in AML, the
|
|
||||||
* return value of this function is subject to TOCTOU bugs.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_namespace_node_is_one_of(
|
|
||||||
const uacpi_namespace_node *node, uacpi_object_type_bits type_mask,
|
|
||||||
uacpi_bool *out
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_size uacpi_namespace_node_depth(const uacpi_namespace_node *node);
|
|
||||||
|
|
||||||
uacpi_namespace_node *uacpi_namespace_node_parent(
|
|
||||||
uacpi_namespace_node *node
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_namespace_node_find(
|
|
||||||
uacpi_namespace_node *parent,
|
|
||||||
const uacpi_char *path,
|
|
||||||
uacpi_namespace_node **out_node
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Same as uacpi_namespace_node_find, except the search recurses upwards when
|
|
||||||
* the namepath consists of only a single nameseg. Usually, this behavior is
|
|
||||||
* only desired if resolving a namepath specified in an aml-provided object,
|
|
||||||
* such as a package element.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_namespace_node_resolve_from_aml_namepath(
|
|
||||||
uacpi_namespace_node *scope,
|
|
||||||
const uacpi_char *path,
|
|
||||||
uacpi_namespace_node **out_node
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef uacpi_iteration_decision (*uacpi_iteration_callback) (
|
|
||||||
void *user, uacpi_namespace_node *node, uacpi_u32 node_depth
|
|
||||||
);
|
|
||||||
|
|
||||||
#define UACPI_MAX_DEPTH_ANY 0xFFFFFFFF
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Depth-first iterate the namespace starting at the first child of 'parent'.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_namespace_for_each_child_simple(
|
|
||||||
uacpi_namespace_node *parent, uacpi_iteration_callback callback, void *user
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Depth-first iterate the namespace starting at the first child of 'parent'.
|
|
||||||
*
|
|
||||||
* 'descending_callback' is invoked the first time a node is visited when
|
|
||||||
* walking down. 'ascending_callback' is invoked the second time a node is
|
|
||||||
* visited after we reach the leaf node without children and start walking up.
|
|
||||||
* Either of the callbacks may be NULL, but not both at the same time.
|
|
||||||
*
|
|
||||||
* Only nodes matching 'type_mask' are passed to the callbacks.
|
|
||||||
*
|
|
||||||
* 'max_depth' is used to limit the maximum reachable depth from 'parent',
|
|
||||||
* where 1 is only direct children of 'parent', 2 is children of first-level
|
|
||||||
* children etc. Use UACPI_MAX_DEPTH_ANY or -1 to specify infinite depth.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_namespace_for_each_child(
|
|
||||||
uacpi_namespace_node *parent, uacpi_iteration_callback descending_callback,
|
|
||||||
uacpi_iteration_callback ascending_callback,
|
|
||||||
uacpi_object_type_bits type_mask, uacpi_u32 max_depth, void *user
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Retrieve the next peer namespace node of '*iter', or, if '*iter' is
|
|
||||||
* UACPI_NULL, retrieve the first child of 'parent' instead. The resulting
|
|
||||||
* namespace node is stored at '*iter'.
|
|
||||||
*
|
|
||||||
* This API can be used to implement an "iterator" version of the
|
|
||||||
* for_each_child helpers.
|
|
||||||
*
|
|
||||||
* Example usage:
|
|
||||||
* void recurse(uacpi_namespace_node *parent) {
|
|
||||||
* uacpi_namespace_node *iter = UACPI_NULL;
|
|
||||||
*
|
|
||||||
* while (uacpi_namespace_node_next(parent, &iter) == UACPI_STATUS_OK) {
|
|
||||||
* // Do something with iter...
|
|
||||||
* descending_callback(iter);
|
|
||||||
*
|
|
||||||
* // Recurse down to walk over the children of iter
|
|
||||||
* recurse(iter);
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* Prefer the for_each_child family of helpers if possible instead of this API
|
|
||||||
* as they avoid recursion and/or the need to use dynamic data structures
|
|
||||||
* entirely.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_namespace_node_next(
|
|
||||||
uacpi_namespace_node *parent, uacpi_namespace_node **iter
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Retrieve the next peer namespace node of '*iter', or, if '*iter' is
|
|
||||||
* UACPI_NULL, retrieve the first child of 'parent' instead. The resulting
|
|
||||||
* namespace node is stored at '*iter'. Only nodes which type matches one
|
|
||||||
* of the types set in 'type_mask' are returned.
|
|
||||||
*
|
|
||||||
* See comment above 'uacpi_namespace_node_next' for usage examples.
|
|
||||||
*
|
|
||||||
* Prefer the for_each_child family of helpers if possible instead of this API
|
|
||||||
* as they avoid recursion and/or the need to use dynamic data structures
|
|
||||||
* entirely.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_namespace_node_next_typed(
|
|
||||||
uacpi_namespace_node *parent, uacpi_namespace_node **iter,
|
|
||||||
uacpi_object_type_bits type_mask
|
|
||||||
);
|
|
||||||
|
|
||||||
const uacpi_char *uacpi_namespace_node_generate_absolute_path(
|
|
||||||
const uacpi_namespace_node *node
|
|
||||||
);
|
|
||||||
void uacpi_free_absolute_path(const uacpi_char *path);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,30 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Install a Notify() handler to a device node.
|
|
||||||
* A handler installed to the root node will receive all notifications, even if
|
|
||||||
* a device already has a dedicated Notify handler.
|
|
||||||
* 'handler_context' is passed to the handler on every invocation.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_install_notify_handler(
|
|
||||||
uacpi_namespace_node *node, uacpi_notify_handler handler,
|
|
||||||
uacpi_handle handler_context
|
|
||||||
);
|
|
||||||
|
|
||||||
uacpi_status uacpi_uninstall_notify_handler(
|
|
||||||
uacpi_namespace_node *node, uacpi_notify_handler handler
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,47 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/status.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Install an address space handler to a device node.
|
|
||||||
* The handler is recursively connected to all of the operation regions of
|
|
||||||
* type 'space' underneath 'device_node'. Note that this recursion stops as
|
|
||||||
* soon as another device node that already has an address space handler of
|
|
||||||
* this type installed is encountered.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_install_address_space_handler(
|
|
||||||
uacpi_namespace_node *device_node, enum uacpi_address_space space,
|
|
||||||
uacpi_region_handler handler, uacpi_handle handler_context
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Uninstall the handler of type 'space' from a given device node.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_uninstall_address_space_handler(
|
|
||||||
uacpi_namespace_node *device_node,
|
|
||||||
enum uacpi_address_space space
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Execute _REG(space, ACPI_REG_CONNECT) for all of the opregions with this
|
|
||||||
* address space underneath this device. This should only be called manually
|
|
||||||
* if you want to register an early handler that must be available before the
|
|
||||||
* call to uacpi_namespace_initialize().
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_reg_all_opregions(
|
|
||||||
uacpi_namespace_node *device_node,
|
|
||||||
enum uacpi_address_space space
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,125 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <uacpi/types.h>
|
|
||||||
#include <uacpi/status.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
typedef enum uacpi_vendor_interface {
|
|
||||||
UACPI_VENDOR_INTERFACE_NONE = 0,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_2000,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_XP,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_XP_SP1,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_SERVER_2003,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_XP_SP2,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_SERVER_2003_SP1,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_VISTA,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_SERVER_2008,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_VISTA_SP1,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_VISTA_SP2,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_7,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_8,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_8_1,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_10,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_10_RS1,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_10_RS2,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_10_RS3,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_10_RS4,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_10_RS5,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_10_19H1,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_10_20H1,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_11,
|
|
||||||
UACPI_VENDOR_INTERFACE_WINDOWS_11_22H2,
|
|
||||||
} uacpi_vendor_interface;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the "latest" AML-queried _OSI vendor interface.
|
|
||||||
*
|
|
||||||
* E.g. for the following AML code:
|
|
||||||
* _OSI("Windows 2021")
|
|
||||||
* _OSI("Windows 2000")
|
|
||||||
*
|
|
||||||
* This function will return UACPI_VENDOR_INTERFACE_WINDOWS_11, since this is
|
|
||||||
* the latest version of the interface the code queried, even though the
|
|
||||||
* "Windows 2000" query came after "Windows 2021".
|
|
||||||
*/
|
|
||||||
uacpi_vendor_interface uacpi_latest_queried_vendor_interface(void);
|
|
||||||
|
|
||||||
typedef enum uacpi_interface_kind {
|
|
||||||
UACPI_INTERFACE_KIND_VENDOR = (1 << 0),
|
|
||||||
UACPI_INTERFACE_KIND_FEATURE = (1 << 1),
|
|
||||||
UACPI_INTERFACE_KIND_ALL = UACPI_INTERFACE_KIND_VENDOR |
|
|
||||||
UACPI_INTERFACE_KIND_FEATURE,
|
|
||||||
} uacpi_interface_kind;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Install or uninstall an interface.
|
|
||||||
*
|
|
||||||
* The interface kind is used for matching during interface enumeration in
|
|
||||||
* uacpi_bulk_configure_interfaces().
|
|
||||||
*
|
|
||||||
* After installing an interface, all _OSI queries report it as supported.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_install_interface(
|
|
||||||
const uacpi_char *name, uacpi_interface_kind
|
|
||||||
);
|
|
||||||
uacpi_status uacpi_uninstall_interface(const uacpi_char *name);
|
|
||||||
|
|
||||||
typedef enum uacpi_host_interface {
|
|
||||||
UACPI_HOST_INTERFACE_MODULE_DEVICE = 1,
|
|
||||||
UACPI_HOST_INTERFACE_PROCESSOR_DEVICE,
|
|
||||||
UACPI_HOST_INTERFACE_3_0_THERMAL_MODEL,
|
|
||||||
UACPI_HOST_INTERFACE_3_0_SCP_EXTENSIONS,
|
|
||||||
UACPI_HOST_INTERFACE_PROCESSOR_AGGREGATOR_DEVICE,
|
|
||||||
} uacpi_host_interface;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Same as install/uninstall interface, but comes with an enum of known
|
|
||||||
* interfaces defined by the ACPI specification. These are disabled by default
|
|
||||||
* as they depend on the host kernel support.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_enable_host_interface(uacpi_host_interface);
|
|
||||||
uacpi_status uacpi_disable_host_interface(uacpi_host_interface);
|
|
||||||
|
|
||||||
typedef uacpi_bool (*uacpi_interface_handler)
|
|
||||||
(const uacpi_char *name, uacpi_bool supported);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a custom interface query (_OSI) handler.
|
|
||||||
*
|
|
||||||
* This callback will be invoked for each _OSI query with the value
|
|
||||||
* passed in the _OSI, as well as whether the interface was detected as
|
|
||||||
* supported. The callback is able to override the return value dynamically
|
|
||||||
* or leave it untouched if desired (e.g. if it simply wants to log something or
|
|
||||||
* do internal bookkeeping of some kind).
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_set_interface_query_handler(uacpi_interface_handler);
|
|
||||||
|
|
||||||
typedef enum uacpi_interface_action {
|
|
||||||
UACPI_INTERFACE_ACTION_DISABLE = 0,
|
|
||||||
UACPI_INTERFACE_ACTION_ENABLE,
|
|
||||||
} uacpi_interface_action;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bulk interface configuration, used to disable or enable all interfaces that
|
|
||||||
* match 'kind'.
|
|
||||||
*
|
|
||||||
* This is generally only needed to work around buggy hardware, for example if
|
|
||||||
* requested from the kernel command line.
|
|
||||||
*
|
|
||||||
* By default, all vendor strings (like "Windows 2000") are enabled, and all
|
|
||||||
* host features (like "3.0 Thermal Model") are disabled.
|
|
||||||
*/
|
|
||||||
uacpi_status uacpi_bulk_configure_interfaces(
|
|
||||||
uacpi_interface_action action, uacpi_interface_kind kind
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif // !UACPI_BAREBONES_MODE
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,38 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef UACPI_OVERRIDE_ARCH_HELPERS
|
|
||||||
#include "uacpi_arch_helpers.h"
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <uacpi/platform/atomic.h>
|
|
||||||
|
|
||||||
#ifndef UACPI_ARCH_FLUSH_CPU_CACHE
|
|
||||||
#define UACPI_ARCH_FLUSH_CPU_CACHE() do {} while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef unsigned long uacpi_cpu_flags;
|
|
||||||
|
|
||||||
typedef void *uacpi_thread_id;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Replace as needed depending on your platform's way to represent thread ids.
|
|
||||||
* uACPI offers a few more helpers like uacpi_atomic_{load,store}{8,16,32,64,ptr}
|
|
||||||
* (or you could provide your own helpers)
|
|
||||||
*/
|
|
||||||
#ifndef UACPI_ATOMIC_LOAD_THREAD_ID
|
|
||||||
#define UACPI_ATOMIC_LOAD_THREAD_ID(ptr) ((uacpi_thread_id)uacpi_atomic_load_ptr(ptr))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UACPI_ATOMIC_STORE_THREAD_ID
|
|
||||||
#define UACPI_ATOMIC_STORE_THREAD_ID(ptr, value) uacpi_atomic_store_ptr(ptr, value)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A sentinel value that the kernel promises to NEVER return from
|
|
||||||
* uacpi_kernel_get_current_thread_id or this will break
|
|
||||||
*/
|
|
||||||
#ifndef UACPI_THREAD_ID_NONE
|
|
||||||
#define UACPI_THREAD_ID_NONE ((uacpi_thread_id)-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user