Initial UEFI port
diff --git a/.gitignore b/.gitignore
index 67e67357..d94bee1a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,11 @@
/bin
/toolchain
+/gnu-efi
+/ovmf
/**/*.o
/**/*.d
/**/*.a
+/**/*.EFI
/**/*.bin
/**/*.bin.gz
/**/*.elf
@@ -14,3 +17,4 @@
.vscode
/stivale
/test_image
+!/stage23/font.bin
diff --git a/Makefile b/Makefile
index 518dd382..e48f3a78 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,7 @@ OBJCOPY = objcopy
CFLAGS = -O2 -pipe -Wall -Wextra
PREFIX = /usr/local
DESTDIR =
+TARGET = bios
PATH := $(shell pwd)/toolchain/bin:$(PATH)
@@ -27,31 +28,36 @@ install: all
install -m 644 bin/limine-cd.bin $(DESTDIR)$(PREFIX)/share/
install -m 644 bin/limine-pxe.bin $(DESTDIR)$(PREFIX)/share/
+ifeq ($(TARGET), bios)
bootloader: | decompressor stage23
mkdir -p bin
cd stage1/hdd && nasm bootsect.asm -fbin -o ../../bin/limine-hdd.bin
cd stage1/cd && nasm bootsect.asm -fbin -o ../../bin/limine-cd.bin
cd stage1/pxe && nasm bootsect.asm -fbin -o ../../bin/limine-pxe.bin
cp stage23/limine.sys ./bin/
+else ifeq ($(TARGET), uefi)
+bootloader: stage23
+ mkdir -p bin
+ cp stage23/BOOTX64.EFI ./bin/
+endif
bootloader-clean: stage23-clean decompressor-clean
distclean: clean bootloader-clean test-clean
rm -rf bin stivale toolchain
-tinf-clean:
- cd tinf && rm -rf *.o *.d
-
stivale:
git clone https://github.com/stivale/stivale.git
-stage23: tinf-clean stivale
- $(MAKE) -C stage23 all
+stage23: stivale
+ cd tinf && rm -rf *.o *.d
+ $(MAKE) -C stage23 all TARGET=$(TARGET)
stage23-clean:
$(MAKE) -C stage23 clean
-decompressor: tinf-clean
+decompressor:
+ cd tinf && rm -rf *.o *.d
$(MAKE) -C decompressor all
decompressor-clean:
@@ -64,6 +70,14 @@ test-clean:
toolchain:
./make_toolchain.sh ./toolchain -j`nproc`
+gnu-efi:
+ git clone https://git.code.sf.net/p/gnu-efi/code --branch=3.0.12 --depth=1 $@
+
+ovmf:
+ mkdir -p ovmf
+ wget https://efi.akeo.ie/OVMF/OVMF-X64.zip
+ cd ovmf && 7z x OVMF-X64.zip
+
test.hdd:
rm -f test.hdd
dd if=/dev/zero bs=1M count=0 seek=64 of=test.hdd
@@ -109,12 +123,20 @@ fat32-test: | test-clean test.hdd bootloader all
sudo mount `cat loopback_dev`p1 test_image
sudo mkdir test_image/boot
sudo cp -rv bin/* test/* test_image/boot/
+ifeq ($(TARGET), uefi)
+ sudo mkdir -p test_image/EFI/BOOT
+ sudo cp bin/BOOTX64.EFI test_image/EFI/BOOT/
+endif
sync
sudo umount test_image/
sudo losetup -d `cat loopback_dev`
rm -rf test_image loopback_dev
bin/limine-install test.hdd
+ifeq ($(TARGET), bios)
qemu-system-x86_64 -net none -smp 4 -enable-kvm -cpu host -hda test.hdd -debugcon stdio
+else ifeq ($(TARGET), uefi)
+ qemu-system-x86_64 -L ovmf -bios ovmf/OVMF.fd -net none -smp 4 -enable-kvm -cpu host -hda test.hdd -debugcon stdio
+endif
iso9660-test: | test-clean test.hdd bootloader all
$(MAKE) -C test
diff --git a/make_toolchain.sh b/make_toolchain.sh
index e2345577..86dc2b9c 100755
--- a/make_toolchain.sh
+++ b/make_toolchain.sh
@@ -3,9 +3,9 @@
set -e
set -x
-TARGET=i386-elf
+TARGET="i386-elf x86_64-elf"
BINUTILSVERSION=2.36.1
-GCCVERSION=11-20210228
+GCCVERSION=10.2.0
NASMVERSION=2.15.05
GZIPVERSION=1.10
@@ -20,7 +20,7 @@ if [ ! -f binutils-$BINUTILSVERSION.tar.gz ]; then
wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILSVERSION.tar.gz
fi
if [ ! -f gcc-$GCCVERSION.tar.xz ]; then
- wget https://ftp.nluug.nl/languages/gcc/snapshots/$GCCVERSION/gcc-$GCCVERSION.tar.xz
+ wget https://ftp.gnu.org/gnu/gcc/gcc-$GCCVERSION/gcc-$GCCVERSION.tar.gz
fi
if [ ! -f nasm-$NASMVERSION.tar.gz ]; then
wget https://www.nasm.us/pub/nasm/releasebuilds/$NASMVERSION/nasm-$NASMVERSION.tar.gz
@@ -34,28 +34,34 @@ mkdir build
cd build
tar -xf ../binutils-$BINUTILSVERSION.tar.gz
-tar -xf ../gcc-$GCCVERSION.tar.xz
+tar -xf ../gcc-$GCCVERSION.tar.gz
tar -xf ../nasm-$NASMVERSION.tar.gz
tar -xf ../gzip-$GZIPVERSION.tar.gz
+for i in $TARGET; do
+rm -rf build-binutils
mkdir build-binutils
cd build-binutils
-../binutils-$BINUTILSVERSION/configure --target=$TARGET --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror --enable-64-bit-bfd
+../binutils-$BINUTILSVERSION/configure --target=$i --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror $([ $i = "x86_64-elf" ] && echo --enable-targets=x86_64-elf,x86_64-pe) --enable-64-bit-bfd
make
make install
cd ..
+done
cd gcc-$GCCVERSION
contrib/download_prerequisites
cd ..
+for i in $TARGET; do
+rm -rf build-gcc
mkdir build-gcc
cd build-gcc
-../gcc-$GCCVERSION/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c --without-headers
+../gcc-$GCCVERSION/configure --target=$i --prefix="$PREFIX" --disable-nls --enable-languages=c --without-headers
make all-gcc
make all-target-libgcc
make install-gcc
make install-target-libgcc
cd ..
+done
mkdir build-nasm
cd build-nasm
diff --git a/stage23/Makefile b/stage23/Makefile
index c753cee3..68afb6fa 100644
--- a/stage23/Makefile
+++ b/stage23/Makefile
@@ -1,8 +1,18 @@
-CC = i386-elf-gcc
-LD = i386-elf-gcc
-OBJCOPY = i386-elf-objcopy
-OBJDUMP = i386-elf-objdump
-READELF = i386-elf-readelf
+TARGET = bios
+
+ifeq ($(TARGET), bios)
+ TOOLCHAIN=i386-elf
+else ifeq ($(TARGET), uefi)
+ TOOLCHAIN=x86_64-elf
+else
+ $(error Invalid toolchain)
+endif
+
+CC = $(TOOLCHAIN)-gcc
+LD = $(TOOLCHAIN)-gcc
+OBJCOPY = $(TOOLCHAIN)-objcopy
+OBJDUMP = $(TOOLCHAIN)-objdump
+READELF = $(TOOLCHAIN)-readelf
COM_OUTPUT = false
E9_OUTPUT = false
@@ -19,6 +29,7 @@ INTERNAL_CFLAGS := \
-fno-stack-protector \
-fno-pic \
-fno-omit-frame-pointer \
+ -fno-lto \
-Wno-address-of-packed-member \
-masm=intel \
-mgeneral-regs-only \
@@ -27,27 +38,60 @@ INTERNAL_CFLAGS := \
-DLIMINE_VERSION='"$(LIMINE_VERSION)"' \
-DCOM_OUTPUT=$(COM_OUTPUT) \
-DE9_OUTPUT=$(E9_OUTPUT) \
+ -D$(TARGET)=1 \
-I. \
-I..
+ifeq ($(TARGET), uefi)
+ INTERNAL_CFLAGS += \
+ -I../gnu-efi/inc \
+ -I../gnu-efi/inc/x86_64 \
+ -fpic \
+ -fshort-wchar \
+ -mno-red-zone \
+ -mcmodel=small
+endif
+
LDFLAGS = -Os
INTERNAL_LDFLAGS := \
- -lgcc \
- -static-libgcc \
+ -fno-lto \
-nostdlib \
- -no-pie \
- -z max-page-size=0x1000 \
- -static
+ -z max-page-size=0x1000
+
+ifeq ($(TARGET), bios)
+ INTERNAL_LDFLAGS += \
+ -static \
+ -no-pie \
+ -lgcc \
+ -static-libgcc
+else ifeq ($(TARGET), uefi)
+ INTERNAL_LDFLAGS += \
+ -shared \
+ -z nocombreloc \
+ -Wl,-Bsymbolic
+endif
.PHONY: all clean
C_FILES := $(shell find -L ./ -type f -name '*.c' | sort)
+ifeq ($(TARGET), bios)
ASM_FILES := $(shell find -L ./ -type f -name '*.asm' | sort)
+endif
OBJ := $(ASM_FILES:.asm=.o) $(C_FILES:.c=.o)
+ifeq ($(TARGET), uefi)
+OBJ += sys/smp_trampoline.o ../gnu-efi/lib/x86_64/efi_stub.o
+endif
HEADER_DEPS := $(C_FILES:.c=.d)
+ifeq ($(TARGET), bios)
all: limine.sys stage2.bin stage2.bin.gz
+else ifeq ($(TARGET), uefi)
+all: BOOTX64.EFI
+endif
+
+BOOTX64.EFI: limine.elf
+ $(OBJCOPY) -I elf64-x86-64 -O efi-app-x86_64 limine.elf $@
stage2.bin.gz: stage2.bin
gzip -n -9 < stage2.bin > stage2.bin.gz
@@ -56,30 +100,43 @@ stage2.bin: limine.sys
dd if=limine.sys bs=$$(( 0x$$($(READELF) -S limine.elf | grep .stage3.text | sed 's/^.*] //' | awk '{print $$3}' | sed 's/^0*//') - 0x8000 )) count=1 of=$@
limine.map.o: limine_nomap.elf
+ifeq ($(TARGET), bios)
./gensyms.sh $(OBJDUMP) limine_nomap.elf limine
+else ifeq ($(TARGET), uefi)
+ ./gensyms64.sh $(OBJDUMP) limine_nomap.elf limine
+endif
limine.sys: limine.elf
$(OBJCOPY) -O binary $< $@
limine_nomap.elf: $(OBJ)
- $(LD) $(OBJ) font.o $(LDFLAGS) $(INTERNAL_LDFLAGS) -Tlinker_nomap.ld -o $@
+ $(LD) $(OBJ) font.o $(LDFLAGS) $(INTERNAL_LDFLAGS) -Tlinker_nomap_$(TARGET).ld -o $@
+ifeq ($(TARGET), bios)
$(LD) $(OBJ) font.o $(LDFLAGS) $(INTERNAL_LDFLAGS) -Wl,--gc-sections -Tlinker_stage2only.ld -o limine_stage2only.elf || \
( echo "This error means that stage 2 was trying to use stage 3 symbols before loading stage 3" && \
false )
+endif
font.o:
$(OBJCOPY) -B i8086 -I binary -O default font.bin $@
limine.elf: $(OBJ) font.o limine.map.o
- $(LD) $(OBJ) font.o limine.map.o $(LDFLAGS) $(INTERNAL_LDFLAGS) -Tlinker.ld -o $@
+ $(LD) $(OBJ) font.o limine.map.o $(LDFLAGS) $(INTERNAL_LDFLAGS) -Tlinker_$(TARGET).ld -o $@
-include $(HEADER_DEPS)
%.o: %.c
$(CC) $(CFLAGS) $(INTERNAL_CFLAGS) -c $< -o $@
+%.o: %.S
+ $(CC) $(CFLAGS) $(INTERNAL_CFLAGS) -c $< -o $@
+ifeq ($(TARGET), bios)
%.o: %.asm
nasm $< -f elf32 -o $@
+else ifeq ($(TARGET), uefi)
+%.o: %.asm
+ nasm $< -f elf64 -o $@
+endif
clean:
rm -f limine.elf limine_nomap.elf limine_stage2only.elf font.o limine.map.o limine.sys stage2.bin stage2.bin.gz $(OBJ) $(HEADER_DEPS)
diff --git a/stage23/drivers/disk.h b/stage23/drivers/disk.h
index eade9f5f..c5a6b1fd 100644
--- a/stage23/drivers/disk.h
+++ b/stage23/drivers/disk.h
@@ -2,6 +2,7 @@
#define __DRIVERS__DISK_H__
#include <stdint.h>
+#include <lib/part.h>
struct bios_drive_params {
uint16_t buf_size;
@@ -16,5 +17,6 @@ struct bios_drive_params {
int disk_get_sector_size(int drive);
int disk_read(int drive, void *buffer, uint64_t loc, uint64_t count);
+size_t disk_create_index(struct volume **ret);
#endif
diff --git a/stage23/drivers/disk.s2.c b/stage23/drivers/disk.s2.c
index 1b641449..08806c71 100644
--- a/stage23/drivers/disk.s2.c
+++ b/stage23/drivers/disk.s2.c
@@ -1,3 +1,5 @@
+#if defined(bios)
+
#include <stdint.h>
#include <stddef.h>
#include <drivers/disk.h>
@@ -103,3 +105,98 @@ int disk_read(int drive, void *buffer, uint64_t loc, uint64_t count) {
return 0;
}
+
+size_t disk_create_index(struct volume **ret) {
+ struct volume *volume_index;
+ size_t volume_count = 0, volume_index_i = 0;
+
+ for (uint8_t drive = 0x80; drive; drive++) {
+ struct rm_regs r = {0};
+ struct bios_drive_params drive_params;
+
+ r.eax = 0x4800;
+ r.edx = drive;
+ r.ds = rm_seg(&drive_params);
+ r.esi = rm_off(&drive_params);
+
+ drive_params.buf_size = sizeof(struct bios_drive_params);
+
+ rm_int(0x13, &r, &r);
+
+ if (r.eflags & EFLAGS_CF)
+ continue;
+
+ print("Found BIOS drive %x\n", drive);
+ print(" ... %X total %u-byte sectors\n",
+ drive_params.lba_count, drive_params.bytes_per_sect);
+
+ volume_count++;
+
+ struct volume block;
+
+ block.drive = drive;
+ block.sector_size = drive_params.bytes_per_sect;
+ block.first_sect = 0;
+ block.sect_count = drive_params.lba_count;
+
+ for (int part = 0; ; part++) {
+ struct volume p;
+ int ret = part_get(&p, &block, part);
+
+ if (ret == END_OF_TABLE || ret == INVALID_TABLE)
+ break;
+ if (ret == NO_PARTITION)
+ continue;
+
+ volume_count++;
+ }
+ }
+
+ volume_index = ext_mem_alloc(sizeof(struct volume) * volume_count);
+
+ for (uint8_t drive = 0x80; drive; drive++) {
+ struct rm_regs r = {0};
+ struct bios_drive_params drive_params;
+
+ r.eax = 0x4800;
+ r.edx = drive;
+ r.ds = rm_seg(&drive_params);
+ r.esi = rm_off(&drive_params);
+
+ drive_params.buf_size = sizeof(struct bios_drive_params);
+
+ rm_int(0x13, &r, &r);
+
+ if (r.eflags & EFLAGS_CF)
+ continue;
+
+ struct volume *block = &volume_index[volume_index_i++];
+
+ block->drive = drive;
+ block->partition = -1;
+ block->sector_size = drive_params.bytes_per_sect;
+ block->first_sect = 0;
+ block->sect_count = drive_params.lba_count;
+
+ if (gpt_get_guid(&block->guid, block)) {
+ block->guid_valid = true;
+ }
+
+ for (int part = 0; ; part++) {
+ struct volume p;
+ int ret = part_get(&p, block, part);
+
+ if (ret == END_OF_TABLE || ret == INVALID_TABLE)
+ break;
+ if (ret == NO_PARTITION)
+ continue;
+
+ volume_index[volume_index_i++] = p;
+ }
+ }
+
+ *ret = volume_index;
+ return volume_count;
+}
+
+#endif
diff --git a/stage23/drivers/gop.c b/stage23/drivers/gop.c
new file mode 100644
index 00000000..1acaca9f
--- /dev/null
+++ b/stage23/drivers/gop.c
@@ -0,0 +1,19 @@
+#if defined (uefi)
+
+#include <efi.h>
+#include <lib/blib.h>
+#include <drivers/gop.h>
+
+bool init_gop(struct fb_info *ret,
+ uint16_t target_width, uint16_t target_height, uint16_t target_bpp) {
+ (void)ret; (void)target_width; (void)target_height; (void)target_bpp;
+
+ EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
+
+ uefi_call_wrapper(gBS->LocateProtocol, 3, &gop_guid, NULL, (void **)&gop);
+
+ for (;;);
+}
+
+#endif
diff --git a/stage23/drivers/gop.h b/stage23/drivers/gop.h
new file mode 100644
index 00000000..704cce2f
--- /dev/null
+++ b/stage23/drivers/gop.h
@@ -0,0 +1,16 @@
+#ifndef __DRIVERS__GOP_H__
+#define __DRIVERS__GOP_H__
+
+#if defined (uefi)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <efi.h>
+#include <lib/fb.h>
+
+bool init_gop(struct fb_info *ret,
+ uint16_t target_width, uint16_t target_height, uint16_t target_bpp);
+
+#endif
+
+#endif
diff --git a/stage23/drivers/vbe.c b/stage23/drivers/vbe.c
index 2cb420b5..3f2519ad 100644
--- a/stage23/drivers/vbe.c
+++ b/stage23/drivers/vbe.c
@@ -1,3 +1,5 @@
+#if defined (bios)
+
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
@@ -263,3 +265,5 @@ retry:
return false;
}
+
+#endif
diff --git a/stage23/drivers/vga_textmode.s2.c b/stage23/drivers/vga_textmode.s2.c
index bd8677d1..99cad37f 100644
--- a/stage23/drivers/vga_textmode.s2.c
+++ b/stage23/drivers/vga_textmode.s2.c
@@ -1,3 +1,5 @@
+#if defined (bios)
+
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
@@ -167,3 +169,5 @@ void text_putchar(uint8_t c) {
draw_cursor();
}
}
+
+#endif
diff --git a/stage23/entry.s2.c b/stage23/entry.s2.c
index 5e009207..a78ce59e 100644
--- a/stage23/entry.s2.c
+++ b/stage23/entry.s2.c
@@ -22,11 +22,14 @@
extern uint64_t stage3_build_id;
-uint8_t boot_drive;
+drive_t boot_drive;
int boot_partition = -1;
bool booted_from_pxe = false;
bool booted_from_cd = false;
+
+#if defined (bios)
+
bool stage3_loaded = false;
extern symbol stage3_addr;
@@ -105,3 +108,5 @@ void entry(uint8_t _boot_drive, int boot_from) {
stage3(boot_from);
}
+
+#endif
diff --git a/stage23/entry.s3.c b/stage23/entry.s3.c
index c575b5ad..ef581180 100644
--- a/stage23/entry.s3.c
+++ b/stage23/entry.s3.c
@@ -20,6 +20,18 @@
#include <pxe/pxe.h>
#include <pxe/tftp.h>
+#if defined (uefi)
+EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
+ (void)ImageHandle;
+
+ gST = SystemTable;
+ gBS = SystemTable->BootServices;
+ gRT = SystemTable->RuntimeServices;
+
+ for (;;);
+}
+#endif
+
__attribute__((section(".stage3_build_id")))
uint64_t stage3_build_id = BUILD_ID;
diff --git a/stage23/fs/echfs.h b/stage23/fs/echfs.h
index 517e71fe..92f221c9 100644
--- a/stage23/fs/echfs.h
+++ b/stage23/fs/echfs.h
@@ -21,7 +21,6 @@ struct echfs_dir_entry {
} __attribute__((packed));
struct echfs_file_handle {
- int disk;
struct volume part;
uint64_t block_size;
uint64_t block_count;
diff --git a/stage23/fs/echfs.s2.c b/stage23/fs/echfs.s2.c
index 50df73d7..89a838de 100644
--- a/stage23/fs/echfs.s2.c
+++ b/stage23/fs/echfs.s2.c
@@ -69,7 +69,6 @@ bool echfs_get_guid(struct guid *guid, struct volume *part) {
int echfs_open(struct echfs_file_handle *ret, struct volume *part, const char *path) {
const char *fullpath = path;
- ret->disk = part->drive;
ret->part = *part;
struct echfs_identity_table id_table;
diff --git a/stage23/fs/fat32.h b/stage23/fs/fat32.h
index a560289d..abd56adb 100644
--- a/stage23/fs/fat32.h
+++ b/stage23/fs/fat32.h
@@ -5,7 +5,6 @@
#include <lib/part.h>
struct fat32_context {
- int drive;
struct volume part;
uint8_t sectors_per_cluster;
uint16_t reserved_sectors;
diff --git a/stage23/fs/fat32.s2.c b/stage23/fs/fat32.s2.c
index cc43f8f4..a9edf310 100644
--- a/stage23/fs/fat32.s2.c
+++ b/stage23/fs/fat32.s2.c
@@ -69,7 +69,6 @@ struct fat32_lfn_entry {
static int fat32_init_context(struct fat32_context* context, struct volume *part) {
context->part = *part;
- context->drive = part->drive;
struct fat32_bpb bpb;
volume_read(&context->part, &bpb, 0, sizeof(struct fat32_bpb));
diff --git a/stage23/gensyms64.sh b/stage23/gensyms64.sh
new file mode 100755
index 00000000..ffad0834
--- /dev/null
+++ b/stage23/gensyms64.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+set -e
+
+TMP1=$(mktemp)
+TMP2=$(mktemp)
+TMP3=$(mktemp)
+TMP4=$(mktemp)
+
+$1 -t "$2" | sed '/\bd\b/d' | sort > "$TMP1"
+grep "\.text" < "$TMP1" | cut -d' ' -f1 > "$TMP2"
+grep "\.text" < "$TMP1" | awk 'NF{ print $NF }' > "$TMP3"
+
+echo "section .map" > "$TMP4"
+echo "global $3_map" >> "$TMP4"
+echo "$3_map:" >> "$TMP4"
+
+paste -d'$' "$TMP2" "$TMP3" | sed 's/^/dq 0x/g' | sed 's/$/", 0/g' | sed 's/\$/\ndb "/g' >> "$TMP4"
+
+echo "dq 0xffffffffffffffff" >> "$TMP4"
+
+nasm -f elf64 "$TMP4" -o $3.map.o
+
+rm "$TMP1" "$TMP2" "$TMP3" "$TMP4"
diff --git a/stage23/lib/acpi.c b/stage23/lib/acpi.c
index 15c41c6b..bd18f5a6 100644
--- a/stage23/lib/acpi.c
+++ b/stage23/lib/acpi.c
@@ -45,16 +45,16 @@ void *acpi_get_table(const char *signature, int index) {
struct rsdt *rsdt;
if (use_xsdt)
- rsdt = (struct rsdt *)(size_t)rsdp->xsdt_addr;
+ rsdt = (struct rsdt *)(uintptr_t)rsdp->xsdt_addr;
else
- rsdt = (struct rsdt *)rsdp->rsdt_addr;
+ rsdt = (struct rsdt *)(uintptr_t)rsdp->rsdt_addr;
for (size_t i = 0; i < rsdt->length - sizeof(struct sdt); i++) {
struct sdt *ptr;
if (use_xsdt)
- ptr = (struct sdt *)(size_t)((uint64_t *)rsdt->ptrs_start)[i];
+ ptr = (struct sdt *)(uintptr_t)((uint64_t *)rsdt->ptrs_start)[i];
else
- ptr = (struct sdt *)((uint32_t *)rsdt->ptrs_start)[i];
+ ptr = (struct sdt *)(uintptr_t)((uint32_t *)rsdt->ptrs_start)[i];
if (!memcmp(ptr->signature, signature, 4)
&& !acpi_checksum(ptr, ptr->length)
diff --git a/stage23/lib/blib.c b/stage23/lib/blib.c
index bdd62d66..6eee5e33 100644
--- a/stage23/lib/blib.c
+++ b/stage23/lib/blib.c
@@ -8,6 +8,12 @@
#include <lib/real.h>
#include <fs/file.h>
+#if defined (uefi)
+EFI_SYSTEM_TABLE *gST;
+EFI_BOOT_SERVICES *gBS;
+EFI_RUNTIME_SERVICES *gRT;
+#endif
+
bool parse_resolution(int *width, int *height, int *bpp, const char *buf) {
int res[3] = {0};
diff --git a/stage23/lib/blib.h b/stage23/lib/blib.h
index b02c74c9..cedff14c 100644
--- a/stage23/lib/blib.h
+++ b/stage23/lib/blib.h
@@ -5,8 +5,18 @@
#include <stdint.h>
#include <stdbool.h>
#include <fs/file.h>
+#include <lib/part.h>
+#if defined (uefi)
+# include <efi.h>
+#endif
+
+#if defined (uefi)
+extern EFI_SYSTEM_TABLE *gST;
+extern EFI_BOOT_SERVICES *gBS;
+extern EFI_RUNTIME_SERVICES *gRT;
+#endif
-extern uint8_t boot_drive;
+extern drive_t boot_drive;
extern int boot_partition;
extern bool booted_from_pxe;
diff --git a/stage23/lib/builtins.s2.asm b/stage23/lib/builtins.s2.asm
deleted file mode 100644
index 924cbe16..00000000
--- a/stage23/lib/builtins.s2.asm
+++ /dev/null
@@ -1,75 +0,0 @@
-section .text
-
-global memcpy
-memcpy:
- push esi
- push edi
- mov eax, dword [esp+12]
- mov edi, eax
- mov esi, dword [esp+16]
- mov ecx, dword [esp+20]
- rep movsb
- pop edi
- pop esi
- ret
-
-global memset
-memset:
- push edi
- mov edx, dword [esp+8]
- mov edi, edx
- mov eax, dword [esp+12]
- mov ecx, dword [esp+16]
- rep stosb
- mov eax, edx
- pop edi
- ret
-
-global memmove
-memmove:
- push esi
- push edi
- mov eax, dword [esp+12]
- mov edi, eax
- mov esi, dword [esp+16]
- mov ecx, dword [esp+20]
-
- cmp edi, esi
- ja .copy_backwards
-
- rep movsb
- jmp .done
-
- .copy_backwards:
- lea edi, [edi+ecx-1]
- lea esi, [esi+ecx-1]
- std
- rep movsb
- cld
-
- .done:
- pop edi
- pop esi
- ret
-
-global memcmp
-memcmp:
- push esi
- push edi
- mov edi, dword [esp+12]
- mov esi, dword [esp+16]
- mov ecx, dword [esp+20]
- repe cmpsb
- jecxz .equal
- mov al, byte [edi-1]
- sub al, byte [esi-1]
- movsx eax, al
- jmp .done
-
- .equal:
- mov eax, ecx
-
- .done:
- pop edi
- pop esi
- ret
diff --git a/stage23/lib/config.c b/stage23/lib/config.c
index c9c7fa9b..f4d1bc05 100644
--- a/stage23/lib/config.c
+++ b/stage23/lib/config.c
@@ -34,6 +34,7 @@ int init_config_disk(struct volume *part) {
return init_config(config_size);
}
+#if defined (bios)
int init_config_pxe(void) {
struct tftp_file_handle cfg;
if (tftp_open(&cfg, 0, 69, "limine.cfg")
@@ -47,6 +48,7 @@ int init_config_pxe(void) {
return init_config(cfg.file_size);
}
+#endif
#define NOT_CHILD (-1)
#define DIRECT_CHILD 0
diff --git a/stage23/lib/elf.c b/stage23/lib/elf.c
index f4c52b9c..b8b60d7d 100644
--- a/stage23/lib/elf.c
+++ b/stage23/lib/elf.c
@@ -311,16 +311,16 @@ int elf64_load(struct file_handle *fd, uint64_t *entry_point, uint64_t *top, uin
memmap_alloc_range((size_t)load_vaddr, (size_t)phdr.p_memsz, alloc_type, true, true);
- fread(fd, (void *)(uint32_t)load_vaddr, phdr.p_offset, phdr.p_filesz);
+ fread(fd, (void *)(uintptr_t)load_vaddr, phdr.p_offset, phdr.p_filesz);
size_t to_zero = (size_t)(phdr.p_memsz - phdr.p_filesz);
if (to_zero) {
- void *ptr = (void *)(uint32_t)(load_vaddr + phdr.p_filesz);
+ void *ptr = (void *)(uintptr_t)(load_vaddr + phdr.p_filesz);
memset(ptr, 0, to_zero);
}
- if (elf64_apply_relocations(fd, &hdr, (void *)(uint32_t)load_vaddr, phdr.p_vaddr, phdr.p_memsz, slide))
+ if (elf64_apply_relocations(fd, &hdr, (void *)(uintptr_t)load_vaddr, phdr.p_vaddr, phdr.p_memsz, slide))
return -1;
}
@@ -364,12 +364,12 @@ int elf32_load(struct file_handle *fd, uint32_t *entry_point, uint32_t *top, uin
memmap_alloc_range((size_t)phdr.p_paddr, (size_t)phdr.p_memsz, alloc_type, true, true);
- fread(fd, (void *)phdr.p_paddr, phdr.p_offset, phdr.p_filesz);
+ fread(fd, (void *)(uintptr_t)phdr.p_paddr, phdr.p_offset, phdr.p_filesz);
size_t to_zero = (size_t)(phdr.p_memsz - phdr.p_filesz);
if (to_zero) {
- void *ptr = (void *)(phdr.p_paddr + phdr.p_filesz);
+ void *ptr = (void *)(uintptr_t)(phdr.p_paddr + phdr.p_filesz);
memset(ptr, 0, to_zero);
}
}
diff --git a/stage23/lib/fb.c b/stage23/lib/fb.c
index 23a424b0..82ba9280 100644
--- a/stage23/lib/fb.c
+++ b/stage23/lib/fb.c
@@ -2,8 +2,13 @@
#include <stdbool.h>
#include <lib/fb.h>
#include <drivers/vbe.h>
+#include <drivers/gop.h>
bool fb_init(struct fb_info *ret,
uint16_t target_width, uint16_t target_height, uint16_t target_bpp) {
+#if defined (bios)
return init_vbe(ret, target_width, target_height, target_bpp);
+#elif defined (uefi)
+ return init_gop(ret, target_width, target_height, target_bpp);
+#endif
}
diff --git a/stage23/lib/gterm.c b/stage23/lib/gterm.c
index 2ef88ce5..c5798fae 100644
--- a/stage23/lib/gterm.c
+++ b/stage23/lib/gterm.c
@@ -363,7 +363,7 @@ bool gterm_init(int *_rows, int *_cols, uint32_t *_colours, int _margin, int _ma
|| fbinfo.blue_mask_shift != 0)
return false;
- gterm_framebuffer = (void *)fbinfo.framebuffer_addr;
+ gterm_framebuffer = (void *)(uintptr_t)fbinfo.framebuffer_addr;
gterm_width = fbinfo.framebuffer_width;
gterm_height = fbinfo.framebuffer_height;
gterm_bpp = fbinfo.framebuffer_bpp;
diff --git a/stage23/lib/libc.s2.c b/stage23/lib/libc.s2.c
index 56854437..3b378523 100644
--- a/stage23/lib/libc.s2.c
+++ b/stage23/lib/libc.s2.c
@@ -19,6 +19,56 @@ int tolower(int c) {
return c;
}
+void *memcpy(void *dest, const void *src, size_t n) {
+ uint8_t *pdest = dest;
+ const uint8_t *psrc = src;
+
+ for (size_t i = 0; i < n; i++) {
+ pdest[i] = psrc[i];
+ }
+
+ return dest;
+}
+
+void *memset(void *s, int c, size_t n) {
+ uint8_t *p = s;
+
+ for (size_t i = 0; i < n; i++) {
+ p[i] = (uint8_t)c;
+ }
+
+ return s;
+}
+
+void *memmove(void *dest, const void *src, size_t n) {
+ uint8_t *pdest = dest;
+ const uint8_t *psrc = src;
+
+ if (src > dest) {
+ for (size_t i = 0; i < n; i++) {
+ pdest[i] = psrc[i];
+ }
+ } else if (src < dest) {
+ for (size_t i = n; i > 0; i--) {
+ pdest[i-1] = psrc[i-1];
+ }
+ }
+
+ return dest;
+}
+
+int memcmp(const void *s1, const void *s2, size_t n) {
+ const uint8_t *p1 = s1;
+ const uint8_t *p2 = s2;
+
+ for (size_t i = 0; i < n; i++) {
+ if (p1[i] != p2[i])
+ return p1[i] < p2[i] ? -1 : 1;
+ }
+
+ return 0;
+}
+
char *strcpy(char *dest, const char *src) {
size_t i;
diff --git a/stage23/lib/panic.s2.c b/stage23/lib/panic.s2.c
index d86b4e5f..fbb58eb3 100644
--- a/stage23/lib/panic.s2.c
+++ b/stage23/lib/panic.s2.c
@@ -17,5 +17,9 @@ __attribute__((noreturn)) void panic(const char *fmt, ...) {
print("\n");
print_stacktrace(NULL);
+#if defined (bios)
rm_hcf();
+#elif defined (uefi)
+ for (;;) asm ("hlt");
+#endif
}
diff --git a/stage23/lib/part.h b/stage23/lib/part.h
index 38dfbc7f..9243f51b 100644
--- a/stage23/lib/part.h
+++ b/stage23/lib/part.h
@@ -4,13 +4,22 @@
#include <stdint.h>
#include <stdbool.h>
#include <lib/guid.h>
+#if defined (uefi)
+# include <efi.h>
+#endif
#define NO_PARTITION (-1)
#define INVALID_TABLE (-2)
#define END_OF_TABLE (-3)
+#if defined (bios)
+typedef int drive_t;
+#elif defined (uefi)
+typedef EFI_HANDLE drive_t;
+#endif
+
struct volume {
- int drive;
+ drive_t drive;
int partition;
int sector_size;
uint64_t first_sect;
@@ -23,9 +32,11 @@ struct volume {
void volume_create_index(void);
+bool gpt_get_guid(struct guid *guid, struct volume *volume);
+
int part_get(struct volume *part, struct volume *volume, int partition);
bool volume_get_by_guid(struct volume *part, struct guid *guid);
-bool volume_get_by_coord(struct volume *part, int drive, int partition);
+bool volume_get_by_coord(struct volume *part, drive_t drive, int partition);
int volume_read(struct volume *part, void *buffer, uint64_t loc, uint64_t count);
diff --git a/stage23/lib/part.s2.c b/stage23/lib/part.s2.c
index 4ef76441..17af8d3e 100644
--- a/stage23/lib/part.s2.c
+++ b/stage23/lib/part.s2.c
@@ -1,14 +1,26 @@
#include <stddef.h>
#include <stdint.h>
#include <lib/part.h>
-#include <drivers/disk.h>
+#if defined (bios)
+# include <drivers/disk.h>
+#include <lib/real.h>
+#endif
#include <lib/libc.h>
#include <lib/blib.h>
-#include <lib/real.h>
#include <lib/print.h>
#include <mm/pmm.h>
#include <fs/file.h>
+size_t volume_get_sector_size(struct volume *volume) {
+#if defined (bios)
+ return disk_get_sector_size(volume->drive);
+#elif defined (uefi)
+ (void)volume;
+ return -1;
+#endif
+
+}
+
struct gpt_table_header {
// the head
char signature[8];
@@ -46,10 +58,10 @@ struct gpt_entry {
uint16_t partition_name[36];
} __attribute__((packed));
-static bool gpt_get_guid(struct guid *guid, struct volume *volume) {
+bool gpt_get_guid(struct guid *guid, struct volume *volume) {
struct gpt_table_header header = {0};
- int sector_size = disk_get_sector_size(volume->drive);
+ int sector_size = volume_get_sector_size(volume);
// read header, located after the first block
volume_read(volume, &header, sector_size * 1, sizeof(header));
@@ -69,7 +81,7 @@ static bool gpt_get_guid(struct guid *guid, struct volume *volume) {
static int gpt_get_part(struct volume *ret, struct volume *volume, int partition) {
struct gpt_table_header header = {0};
- int sector_size = disk_get_sector_size(volume->drive);
+ int sector_size = volume_get_sector_size(volume);
// read header, located after the first block
volume_read(volume, &header, sector_size * 1, sizeof(header));
@@ -155,7 +167,7 @@ static int mbr_get_logical_part(struct volume *ret, struct volume *extended_part
ret->drive = extended_part->drive;
ret->partition = partition + 4;
- ret->sector_size = disk_get_sector_size(extended_part->drive);
+ ret->sector_size = volume_get_sector_size(extended_part);
ret->first_sect = extended_part->first_sect + ebr_sector + entry.first_sect;
ret->sect_count = entry.sect_count;
@@ -174,7 +186,7 @@ static int mbr_get_logical_part(struct volume *ret, struct volume *extended_part
static int mbr_get_part(struct volume *ret, struct volume *volume, int partition) {
// Check if actually valid mbr
- uint16_t hint;
+ uint16_t hint = 0;
volume_read(volume, &hint, 444, sizeof(uint16_t));
if (hint && hint != 0x5a5a)
return INVALID_TABLE;
@@ -196,7 +208,7 @@ static int mbr_get_part(struct volume *ret, struct volume *volume, int partition
extended_part.drive = volume->drive;
extended_part.partition = i;
- extended_part.sector_size = disk_get_sector_size(volume->drive);
+ extended_part.sector_size = volume_get_sector_size(volume);
extended_part.first_sect = entry.first_sect;
extended_part.sect_count = entry.sect_count;
@@ -217,7 +229,7 @@ static int mbr_get_part(struct volume *ret, struct volume *volume, int partition
ret->drive = volume->drive;
ret->partition = partition;
- ret->sector_size = disk_get_sector_size(volume->drive);
+ ret->sector_size = volume_get_sector_size(volume);
ret->first_sect = entry.first_sect;
ret->sect_count = entry.sect_count;
@@ -252,92 +264,11 @@ static struct volume *volume_index = NULL;
static size_t volume_index_i = 0;
void volume_create_index(void) {
- size_t volume_count = 0;
-
- for (uint8_t drive = 0x80; drive; drive++) {
- struct rm_regs r = {0};
- struct bios_drive_params drive_params;
-
- r.eax = 0x4800;
- r.edx = drive;
- r.ds = rm_seg(&drive_params);
- r.esi = rm_off(&drive_params);
-
- drive_params.buf_size = sizeof(struct bios_drive_params);
-
- rm_int(0x13, &r, &r);
+#if defined (bios)
+ volume_index_i = disk_create_index(&volume_index);
+#elif defined (uefi)
- if (r.eflags & EFLAGS_CF)
- continue;
-
- print("Found BIOS drive %x\n", drive);
- print(" ... %X total %u-byte sectors\n",
- drive_params.lba_count, drive_params.bytes_per_sect);
-
- volume_count++;
-
- struct volume block;
-
- block.drive = drive;
- block.sector_size = drive_params.bytes_per_sect;
- block.first_sect = 0;
- block.sect_count = drive_params.lba_count;
-
- for (int part = 0; ; part++) {
- struct volume p;
- int ret = part_get(&p, &block, part);
-
- if (ret == END_OF_TABLE || ret == INVALID_TABLE)
- break;
- if (ret == NO_PARTITION)
- continue;
-
- volume_count++;
- }
- }
-
- volume_index = ext_mem_alloc(sizeof(struct volume) * volume_count);
-
- for (uint8_t drive = 0x80; drive; drive++) {
- struct rm_regs r = {0};
- struct bios_drive_params drive_params;
-
- r.eax = 0x4800;
- r.edx = drive;
- r.ds = rm_seg(&drive_params);
- r.esi = rm_off(&drive_params);
-
- drive_params.buf_size = sizeof(struct bios_drive_params);
-
- rm_int(0x13, &r, &r);
-
- if (r.eflags & EFLAGS_CF)
- continue;
-
- struct volume *block = &volume_index[volume_index_i++];
-
- block->drive = drive;
- block->partition = -1;
- block->sector_size = drive_params.bytes_per_sect;
- block->first_sect = 0;
- block->sect_count = drive_params.lba_count;
-
- if (gpt_get_guid(&block->guid, block)) {
- block->guid_valid = true;
- }
-
- for (int part = 0; ; part++) {
- struct volume p;
- int ret = part_get(&p, block, part);
-
- if (ret == END_OF_TABLE || ret == INVALID_TABLE)
- break;
- if (ret == NO_PARTITION)
- continue;
-
- volume_index[volume_index_i++] = p;
- }
- }
+#endif
}
bool volume_get_by_guid(struct volume *part, struct guid *guid) {
@@ -358,7 +289,7 @@ found:
return true;
}
-bool volume_get_by_coord(struct volume *part, int drive, int partition) {
+bool volume_get_by_coord(struct volume *part, drive_t drive, int partition) {
size_t i;
for (i = 0; i < volume_index_i; i++) {
if (volume_index[i].drive == drive
@@ -373,6 +304,11 @@ found:
}
int volume_read(struct volume *part, void *buffer, uint64_t loc, uint64_t count) {
+#if defined (bios)
return disk_read(part->drive, buffer,
loc + (part->first_sect * part->sector_size), count);
+#elif defined (uefi)
+ (void)part; (void)buffer; (void)loc; (void)count;
+ return -1;
+#endif
}
diff --git a/stage23/lib/readline.c b/stage23/lib/readline.c
index 42713d90..8b7b5a6d 100644
--- a/stage23/lib/readline.c
+++ b/stage23/lib/readline.c
@@ -4,10 +4,14 @@
#include <lib/libc.h>
#include <lib/blib.h>
#include <lib/term.h>
-#include <lib/real.h>
+#if defined (bios)
+# include <lib/real.h>
+#elif defined (uefi)
+# include <efi.h>
+#endif
-int getchar_internal(uint32_t eax) {
- switch ((eax >> 8) & 0xff) {
+int getchar_internal(uint8_t scancode, uint8_t ascii) {
+ switch (scancode) {
case 0x44:
return GETCHAR_F10;
case 0x4b:
@@ -29,19 +33,33 @@ int getchar_internal(uint32_t eax) {
case 0x51:
return GETCHAR_PGDOWN;
}
- char c = eax & 0xff;
- switch (c) {
+ switch (ascii) {
case '\r':
return '\n';
}
- return c;
+ return ascii;
}
+#if defined (bios)
int getchar(void) {
struct rm_regs r = {0};
rm_int(0x16, &r, &r);
- return getchar_internal(r.eax);
+ return getchar_internal((r.eax >> 8) & 0xff, r.eax);
}
+#endif
+
+#if defined (uefi)
+int getchar(void) {
+ EFI_INPUT_KEY key = {0};
+ uefi_call_wrapper(gST->ConIn->ReadKeyStroke, 2, gST->ConIn, &key);
+ return getchar_internal(key.ScanCode, key.UnicodeChar);
+}
+
+int pit_sleep_and_quit_on_keypress(uint32_t pit_ticks) {
+ (void)pit_ticks;
+ return getchar();
+}
+#endif
static void reprint_string(int x, int y, const char *s) {
int orig_x, orig_y;
diff --git a/stage23/lib/term.c b/stage23/lib/term.c
index 441c924b..dbe0d832 100644
--- a/stage23/lib/term.c
+++ b/stage23/lib/term.c
@@ -10,8 +10,10 @@ void term_vbe(uint32_t *colours, int margin, int margin_gradient, struct image *
term_deinit();
if (!gterm_init(&term_rows, &term_cols, colours, margin, margin_gradient, background)) {
+#if defined (bios)
// Failed to set VBE properly, default to text mode
term_textmode();
+#endif
return;
}
diff --git a/stage23/lib/term.s2.c b/stage23/lib/term.s2.c
index 2058deba..469fafe0 100644
--- a/stage23/lib/term.s2.c
+++ b/stage23/lib/term.s2.c
@@ -23,6 +23,7 @@ void (*term_double_buffer_flush)(void);
int term_rows, term_cols;
+#if defined (bios)
void term_textmode(void) {
term_deinit();
init_vga_textmode(&term_rows, &term_cols);
@@ -41,11 +42,14 @@ void term_textmode(void) {
term_backend = TEXTMODE;
}
+#endif
void term_deinit(void) {
+#if defined (bios)
struct rm_regs r = {0};
r.eax = 0x0003;
rm_int(0x10, &r, &r);
+#endif
term_backend = NOT_READY;
}
diff --git a/stage23/lib/time.c b/stage23/lib/time.c
index 7120dc95..1660c635 100644
--- a/stage23/lib/time.c
+++ b/stage23/lib/time.c
@@ -1,7 +1,11 @@
#include <stddef.h>
#include <stdint.h>
#include <lib/time.h>
-#include <lib/real.h>
+#if defined (bios)
+# include <lib/real.h>
+#elif defined (uefi)
+# include <efi.h>
+#endif
#include <lib/blib.h>
// Julian date calculation from https://en.wikipedia.org/wiki/Julian_day
@@ -22,6 +26,7 @@ static uint64_t get_unix_epoch(uint8_t seconds, uint8_t minutes, uint8_t hours,
return (jdn_diff * (60 * 60 * 24)) + hours * 3600 + minutes * 60 + seconds;
}
+#if defined (bios)
uint64_t time(void) {
struct rm_regs r = {0};
@@ -42,3 +47,14 @@ uint64_t time(void) {
return get_unix_epoch(second, minute, hour, day, month, year);
}
+#endif
+
+#if defined (uefi)
+uint64_t time(void) {
+ EFI_TIME time;
+ uefi_call_wrapper(gRT->GetTime, 2, &time, NULL);
+
+ return get_unix_epoch(time.Second, time.Minute, time.Hour,
+ time.Day, time.Month, time.Year);
+}
+#endif
diff --git a/stage23/lib/trace.s2.c b/stage23/lib/trace.s2.c
index 2c502949..c4bf7183 100644
--- a/stage23/lib/trace.s2.c
+++ b/stage23/lib/trace.s2.c
@@ -11,33 +11,41 @@
extern symbol limine_map;
char *trace_address(size_t *off, size_t addr) {
+#if defined (bios)
if (!stage3_loaded)
return NULL;
+#endif
- uint32_t prev_addr = 0;
- char *prev_sym = NULL;
+ uintptr_t prev_addr = 0;
+ char *prev_sym = NULL;
for (size_t i = 0;;) {
- if (*((uint32_t *)&limine_map[i]) >= addr) {
+ if (*((uintptr_t *)&limine_map[i]) >= addr) {
*off = addr - prev_addr;
return prev_sym;
}
- prev_addr = *((uint32_t *)&limine_map[i]);
- i += sizeof(uint32_t);
+ prev_addr = *((uintptr_t *)&limine_map[i]);
+ i += sizeof(uintptr_t);
prev_sym = &limine_map[i];
while (limine_map[i++] != 0);
}
}
void print_stacktrace(size_t *base_ptr) {
+#if defined (bios)
if (!stage3_loaded) {
print("trace: Stack trace omitted because stage 3 was not loaded yet.\n");
return;
}
+#endif
if (base_ptr == NULL) {
asm volatile (
+#if defined (bios)
"mov %0, ebp"
+#elif defined (uefi)
+ "mov %0, rbp"
+#endif
: "=g"(base_ptr)
:: "memory"
);
diff --git a/stage23/lib/uri.c b/stage23/lib/uri.c
index 883dc09e..d355556b 100644
--- a/stage23/lib/uri.c
+++ b/stage23/lib/uri.c
@@ -54,6 +54,7 @@ bool uri_resolve(char *uri, char **resource, char **root, char **path) {
return true;
}
+#if defined (bios)
// BIOS partitions are specified in the <BIOS drive>:<partition> form.
// The drive may be omitted, the partition cannot.
static bool parse_bios_partition(char *loc, uint8_t *drive, uint8_t *partition) {
@@ -106,6 +107,7 @@ static bool uri_bios_dispatch(struct file_handle *fd, char *loc, char *path) {
return true;
}
+#endif
static bool uri_guid_dispatch(struct file_handle *fd, char *guid_str, char *path) {
struct guid guid;
@@ -127,6 +129,7 @@ static bool uri_guid_dispatch(struct file_handle *fd, char *guid_str, char *path
return true;
}
+#if defined (bios)
static bool uri_tftp_dispatch(struct file_handle *fd, char *root, char *path) {
uint32_t ip;
if (!strcmp(root, "")) {
@@ -149,10 +152,13 @@ static bool uri_tftp_dispatch(struct file_handle *fd, char *root, char *path) {
fd->size = cfg->file_size;
return true;
}
+#endif
static bool uri_boot_dispatch(struct file_handle *fd, char *s_part, char *path) {
+#if defined (bios)
if (booted_from_pxe)
return uri_tftp_dispatch(fd, s_part, path);
+#endif
int partition;
@@ -194,16 +200,21 @@ bool uri_open(struct file_handle *fd, char *uri) {
resource++;
}
- if (!strcmp(resource, "bios")) {
+ if (0) {
+#if defined (bios)
+ } else if (!strcmp(resource, "bios")) {
ret = uri_bios_dispatch(fd, root, path);
+#endif
} else if (!strcmp(resource, "boot")) {
ret = uri_boot_dispatch(fd, root, path);
} else if (!strcmp(resource, "guid")) {
ret = uri_guid_dispatch(fd, root, path);
} else if (!strcmp(resource, "uuid")) {
ret = uri_guid_dispatch(fd, root, path);
+#if defined (bios)
} else if (!strcmp(resource, "tftp")) {
ret = uri_tftp_dispatch(fd, root, path);
+#endif
} else {
panic("Resource `%s` not valid.", resource);
}
diff --git a/stage23/linker.ld b/stage23/linker_bios.ld
similarity index 100%
rename from stage23/linker.ld
rename to stage23/linker_bios.ld
diff --git a/stage23/linker_nomap.ld b/stage23/linker_nomap_bios.ld
similarity index 100%
rename from stage23/linker_nomap.ld
rename to stage23/linker_nomap_bios.ld
diff --git a/stage23/linker_nomap_uefi.ld b/stage23/linker_nomap_uefi.ld
new file mode 100644
index 00000000..16e400d2
--- /dev/null
+++ b/stage23/linker_nomap_uefi.ld
@@ -0,0 +1,33 @@
+OUTPUT_FORMAT(elf64-x86-64)
+ENTRY(efi_main)
+
+SECTIONS
+{
+ . = 4K;
+
+ .text : {
+ *(.text*)
+ }
+
+ .data : {
+ *(.realmode*)
+ *(.data*)
+ }
+
+ .rodata : {
+ *(.rodata*)
+ }
+
+ .map : {
+ limine_map = .;
+ }
+
+ .bss : {
+ *(COMMON)
+ *(.bss*)
+ }
+
+ /DISCARD/ : {
+ *(*)
+ }
+}
diff --git a/stage23/linker_uefi.ld b/stage23/linker_uefi.ld
new file mode 100644
index 00000000..283366d4
--- /dev/null
+++ b/stage23/linker_uefi.ld
@@ -0,0 +1,33 @@
+OUTPUT_FORMAT(elf64-x86-64)
+ENTRY(efi_main)
+
+SECTIONS
+{
+ . = 4K;
+
+ .text : {
+ *(.text*)
+ }
+
+ .data : {
+ *(.realmode*)
+ *(.data*)
+ }
+
+ .rodata : {
+ *(.rodata*)
+ }
+
+ .map : {
+ *(.map*)
+ }
+
+ .bss : {
+ *(COMMON)
+ *(.bss*)
+ }
+
+ /DISCARD/ : {
+ *(*)
+ }
+}
diff --git a/stage23/mm/mtrr.c b/stage23/mm/mtrr.c
index 34efbea4..4c900f20 100644
--- a/stage23/mm/mtrr.c
+++ b/stage23/mm/mtrr.c
@@ -118,7 +118,7 @@ void mtrr_save(void) {
uint8_t var_reg_count = ia32_mtrrcap & 0xff;
if (!saved_mtrr)
- saved_mtrr = conv_mem_alloc(var_reg_count * sizeof(struct mtrr));
+ saved_mtrr = ext_mem_alloc(var_reg_count * sizeof(struct mtrr));
for (uint8_t i = 0; i < var_reg_count; i++) {
saved_mtrr[i].base = rdmsr(0x200 + i * 2);
diff --git a/stage23/mm/pmm.s2.c b/stage23/mm/pmm.s2.c
index 0cbda451..4baa5414 100644
--- a/stage23/mm/pmm.s2.c
+++ b/stage23/mm/pmm.s2.c
@@ -6,6 +6,9 @@
#include <lib/blib.h>
#include <lib/libc.h>
#include <lib/print.h>
+#if defined (uefi)
+# include <efi.h>
+#endif
#define PAGE_SIZE 4096
#define MEMMAP_BASE ((size_t)0x100000)
@@ -183,6 +186,7 @@ struct e820_entry_t *get_memmap(size_t *entries) {
return memmap;
}
+#if defined (bios)
void init_memmap(void) {
for (size_t i = 0; i < e820_entries; i++) {
if (memmap_entries == MEMMAP_MAX_ENTRIES) {
@@ -196,6 +200,7 @@ void init_memmap(void) {
allocations_disallowed = false;
}
+#endif
void *ext_mem_alloc(size_t count) {
return ext_mem_alloc_type(count, MEMMAP_BOOTLOADER_RECLAIMABLE);
@@ -209,6 +214,7 @@ void *ext_mem_alloc_type(size_t count, uint32_t type) {
return ext_mem_alloc_aligned_type(count, 4, type);
}
+#if defined (bios)
// Allocate memory top down, hopefully without bumping into kernel or modules
void *ext_mem_alloc_aligned_type(size_t count, size_t alignment, uint32_t type) {
if (allocations_disallowed)
@@ -251,6 +257,24 @@ void *ext_mem_alloc_aligned_type(size_t count, size_t alignment, uint32_t type)
panic("High memory allocator: Out of memory");
}
+#endif
+
+#if defined (uefi)
+void *ext_mem_alloc_aligned_type(size_t count, size_t alignment, uint32_t type) {
+ (void)type;
+
+ void *ret;
+
+ if (alignment && alignment % 4096 == 0) {
+ uefi_call_wrapper(gBS->AllocatePages, 4, 0, 2, DIV_ROUNDUP(count, 4096),
+ &ret);
+ } else {
+ uefi_call_wrapper(gBS->AllocatePool, 3, 4, count, &ret);
+ }
+
+ return ret;
+}
+#endif
bool memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type, bool free_only, bool do_panic) {
uint64_t top = base + length;
@@ -317,6 +341,7 @@ bool memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type, bool free
return false;
}
+#if defined (bios)
extern symbol bss_end;
static size_t bump_allocator_base = (size_t)bss_end;
static size_t bump_allocator_limit = 0x70000;
@@ -338,3 +363,4 @@ void *conv_mem_alloc_aligned(size_t count, size_t alignment) {
return ret;
}
+#endif
diff --git a/stage23/protos/chainload.c b/stage23/protos/chainload.c
index 8bcc66eb..73092258 100644
--- a/stage23/protos/chainload.c
+++ b/stage23/protos/chainload.c
@@ -1,3 +1,5 @@
+#if defined (bios)
+
#include <stddef.h>
#include <stdint.h>
#include <protos/chainload.h>
@@ -84,3 +86,5 @@ void chainload(char *config) {
spinup(drive);
}
+
+#endif
diff --git a/stage23/protos/linux.c b/stage23/protos/linux.c
index 86cafdbe..5803942e 100644
--- a/stage23/protos/linux.c
+++ b/stage23/protos/linux.c
@@ -1,3 +1,5 @@
+#if defined (bios)
+
#include <stdint.h>
#include <stddef.h>
#include <protos/linux.h>
@@ -194,3 +196,5 @@ void linux_load(char *config, char *cmdline) {
spinup(real_mode_code_seg, kernel_entry_seg, real_mode_and_heap_size);
}
+
+#endif
diff --git a/stage23/protos/stivale.c b/stage23/protos/stivale.c
index a596f0bc..42a8db34 100644
--- a/stage23/protos/stivale.c
+++ b/stage23/protos/stivale.c
@@ -249,6 +249,7 @@ __attribute__((noreturn)) void stivale_spinup(
uint64_t entry_point, void *stivale_struct, uint64_t stack) {
mtrr_restore();
+#if defined (bios)
if (bits == 64) {
// If we're going 64, we might as well call this BIOS interrupt
// to tell the BIOS that we are entering Long Mode, since it is in
@@ -258,10 +259,12 @@ __attribute__((noreturn)) void stivale_spinup(
r.ebx = 0x02; // Long mode only
rm_int(0x15, &r, &r);
}
+#endif
pic_mask_all();
pic_flush();
+#if defined (bios)
if (bits == 64) {
if (level5pg) {
// Enable CR4.LA57
@@ -367,5 +370,11 @@ __attribute__((noreturn)) void stivale_spinup(
: "memory"
);
}
+#elif defined (uefi)
+ (void)bits; (void)level5pg; (void)pagemap; (void)entry_point;
+ (void)stivale_struct; (void)stack;
+
+#endif
+
for (;;);
}
diff --git a/stage23/protos/stivale2.c b/stage23/protos/stivale2.c
index a2129035..ed0e0be7 100644
--- a/stage23/protos/stivale2.c
+++ b/stage23/protos/stivale2.c
@@ -327,6 +327,7 @@ void stivale2_load(char *config, char *cmdline, bool pxe) {
}
}
+#if defined (bios)
//////////////////////////////////////////////
// Create PXE struct tag
//////////////////////////////////////////////
@@ -336,7 +337,11 @@ void stivale2_load(char *config, char *cmdline, bool pxe) {
tag->server_ip = get_boot_server_info();
append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
}
+#else
+ (void)pxe;
+#endif
+#if defined (bios)
//////////////////////////////////////////////
// Create memmap struct tag
//////////////////////////////////////////////
@@ -356,6 +361,7 @@ void stivale2_load(char *config, char *cmdline, bool pxe) {
append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
}
+#endif
//////////////////////////////////////////////
// List tags
diff --git a/stage23/pxe/pxe.c b/stage23/pxe/pxe.c
index e3b5051e..60070f48 100644
--- a/stage23/pxe/pxe.c
+++ b/stage23/pxe/pxe.c
@@ -1,3 +1,5 @@
+#if defined (bios)
+
#include <lib/print.h>
#include <lib/real.h>
#include <pxe/pxe.h>
@@ -41,3 +43,5 @@ void pxe_init(void) {
set_pxe_fp(bangpxe->rm_entry);
print("Successfully initialized pxe");
}
+
+#endif
diff --git a/stage23/pxe/tftp.c b/stage23/pxe/tftp.c
index 51693506..aab56e94 100644
--- a/stage23/pxe/tftp.c
+++ b/stage23/pxe/tftp.c
@@ -1,3 +1,5 @@
+#if defined (bios)
+
#include <pxe/tftp.h>
#include <pxe/pxe.h>
#include <lib/real.h>
@@ -23,13 +25,13 @@ int tftp_open(struct tftp_file_handle *handle, uint32_t server_ip, uint16_t serv
struct bootph *ph = (struct bootph*)(void *) (((((uint32_t)cachedinfo.buffer) >> 16) << 4) + (((uint32_t)cachedinfo.buffer) & 0xFFFF));
server_ip = ph->sip;
}
-
+
struct PXENV_UNDI_GET_INFORMATION undi_info = { 0 };
ret = pxe_call(UNDI_GET_INFORMATION, ((uint16_t)rm_seg(&undi_info)), (uint16_t)rm_off(&undi_info));
if (ret) {
return -1;
}
-
+
//TODO figure out a more proper way to do this.
uint16_t mtu = undi_info.MaxTranUnit - 48;
@@ -106,3 +108,5 @@ int tftp_read(void* fd, void *buf, uint64_t loc, uint64_t count) {
memcpy(buf, handle->data + loc, count);
return 0;
}
+
+#endif
diff --git a/stage23/sys/a20.s2.c b/stage23/sys/a20.s2.c
index 571f7d6c..e3e1f8c2 100644
--- a/stage23/sys/a20.s2.c
+++ b/stage23/sys/a20.s2.c
@@ -1,3 +1,5 @@
+#if defined (bios)
+
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
@@ -52,3 +54,5 @@ bool a20_enable(void) {
return false;
}
+
+#endif
diff --git a/stage23/sys/e820.s2.c b/stage23/sys/e820.s2.c
index c275be26..3fe10629 100644
--- a/stage23/sys/e820.s2.c
+++ b/stage23/sys/e820.s2.c
@@ -1,3 +1,5 @@
+#if defined (bios)
+
#include <stdint.h>
#include <stddef.h>
#include <sys/e820.h>
@@ -43,3 +45,5 @@ load_up:
e820_map = conv_mem_alloc(sizeof(struct e820_entry_t) * e820_entries);
goto load_up;
}
+
+#endif
diff --git a/stage23/sys/smp.c b/stage23/sys/smp.c
index 6b5d166f..322cc719 100644
--- a/stage23/sys/smp.c
+++ b/stage23/sys/smp.c
@@ -207,7 +207,7 @@ struct smp_information *init_smp(size_t header_hack_size,
// Try to start the AP
if (!smp_start_ap(lapic->lapic_id, &gdtr, info_struct,
- longmode, lv5, (uint32_t)pagemap.top_level,
+ longmode, lv5, (uintptr_t)pagemap.top_level,
x2apic)) {
print("smp: FAILED to bring-up AP\n");
continue;
@@ -244,7 +244,7 @@ struct smp_information *init_smp(size_t header_hack_size,
// Try to start the AP
if (!smp_start_ap(x2apic->x2apic_id, &gdtr, info_struct,
- longmode, lv5, (uint32_t)pagemap.top_level,
+ longmode, lv5, (uintptr_t)pagemap.top_level,
true)) {
print("smp: FAILED to bring-up AP\n");
continue;
