summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile.in18
-rwxr-xr-xbootstrap2
-rw-r--r--builddeps/limine.cfg8
-rw-r--r--builddeps/limine.conf13
-rw-r--r--builddeps/tree.jpgbin0 -> 370601 bytes
-rw-r--r--builddeps/user.mk5
-rw-r--r--configure.ac35
-rw-r--r--lib/libc/Makefile9
-rw-r--r--lib/libc/include/arch/amd64/syscall.h105
-rw-r--r--lib/libc/include/string.h39
-rw-r--r--lib/libc/src/string/memcmp.c45
-rw-r--r--lib/libc/src/string/strcmp.c42
-rw-r--r--lib/libc/src/string/strlen.c40
-rw-r--r--share/misc/contrib24
-rw-r--r--sys/arch/aarch64/aarch64/acpi_machdep.c37
-rw-r--r--sys/arch/aarch64/aarch64/machdep.c83
-rw-r--r--sys/arch/aarch64/aarch64/mp.c39
-rw-r--r--sys/arch/aarch64/aarch64/pmap.c68
-rw-r--r--sys/arch/aarch64/aarch64/proc_machdep.c70
-rw-r--r--sys/arch/aarch64/aarch64/reboot.c38
-rw-r--r--sys/arch/aarch64/conf/GENERIC5
-rw-r--r--sys/arch/aarch64/conf/link.ld75
-rw-r--r--sys/arch/aarch64/pci/pci_machdep.c79
-rw-r--r--sys/arch/amd64/amd64/lapic_intr.S5
-rw-r--r--sys/arch/amd64/amd64/machdep.c14
-rw-r--r--sys/arch/amd64/amd64/trap.c20
-rw-r--r--sys/arch/amd64/conf/GENERIC4
-rw-r--r--sys/arch/amd64/isa/i8042.S37
-rw-r--r--sys/arch/amd64/isa/i8042.c457
-rw-r--r--sys/arch/amd64/isa/spkr.c69
-rw-r--r--sys/dev/acpi/acpi_init.c9
-rw-r--r--sys/dev/cons/cons.c318
-rw-r--r--sys/dev/cons/cons_buf.c186
-rw-r--r--sys/dev/ic/nvme.c4
-rw-r--r--sys/dev/video/fbdev.c1
-rw-r--r--sys/include/arch/aarch64/cdefs.h40
-rw-r--r--sys/include/arch/aarch64/cpu.h48
-rw-r--r--sys/include/arch/aarch64/frame.h96
-rw-r--r--sys/include/arch/aarch64/pcb.h40
-rw-r--r--sys/include/arch/aarch64/pio.h43
-rw-r--r--sys/include/arch/aarch64/sync.h35
-rw-r--r--sys/include/arch/aarch64/syscall.h85
-rw-r--r--sys/include/arch/aarch64/vas.h45
-rw-r--r--sys/include/arch/amd64/cdefs.h10
-rw-r--r--sys/include/arch/amd64/cpu.h3
-rw-r--r--sys/include/arch/amd64/isa/i8042var.h88
-rw-r--r--sys/include/arch/amd64/isa/spkr.h37
-rw-r--r--sys/include/arch/amd64/sync.h35
-rw-r--r--sys/include/arch/amd64/syscall.h105
-rw-r--r--sys/include/dev/acpi/acpi.h1
-rw-r--r--sys/include/dev/cons/cons.h5
-rw-r--r--sys/include/dev/cons/consvar.h84
-rw-r--r--sys/include/dev/video/fbdev.h1
-rw-r--r--sys/include/sys/atomic.h34
-rw-r--r--sys/include/sys/schedvar.h2
-rw-r--r--sys/include/sys/spinlock.h7
-rw-r--r--sys/include/sys/syscall.h75
-rw-r--r--sys/kern/exec_elf64.c5
-rw-r--r--sys/kern/init_main.c30
-rw-r--r--sys/kern/kern_descrip.c18
-rw-r--r--sys/kern/kern_sched.c12
-rw-r--r--sys/kern/kern_synch.c52
-rw-r--r--tools/kconf/scan.l1
-rwxr-xr-xtools/taptest3
-rw-r--r--usr.bin/link.ld26
-rw-r--r--usr.bin/osh/Makefile6
-rw-r--r--usr.bin/osh/osh.c118
68 files changed, 3000 insertions, 194 deletions
diff --git a/.gitignore b/.gitignore
index 95180ea..001bc03 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,5 +11,6 @@
/stand
/base
/sys/include/machine
+/lib/libc/include/machine/
/share/misc/hwdoc
autom4te.cache
diff --git a/Makefile.in b/Makefile.in
index edf7193..35595b1 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -4,6 +4,7 @@ override PROMPT := printf "%s\t\t%s\n"
###############################
# CFLAGS, QEMU flags + misc
###############################
+override BOOT_FW = @BOOT_FW@
override ARCH = @ARCH@
override HYRA_VERSION = @PACKAGE_VERSION@
override PROMPT := printf "%s\t\t%s\n"
@@ -60,10 +61,11 @@ override KERNEL_HEADER_DEPS = $(KERNEL_CFILES:.c=.d)
# Userland
########################
override SBIN_MAKEDIRS = $(shell find usr.sbin/ -type d -name "*" | awk '!/usr.sbin\/$$/')
+override BIN_MAKEDIRS = $(shell find usr.bin/ -type d -name "*" | awk '!/usr.bin\/$$/')
override USRDIR = $(shell pwd)/base/usr
.PHONY: all
-all: base libc sbin base/boot/hyra-kernel ramfs iso
+all: base libc sbin bin base/boot/hyra-kernel ramfs iso
rm -f sys/include/machine
rm -rf iso_root
@@ -73,16 +75,23 @@ sbin: $(SBIN_MAKEDIRS)
LDSCRIPT=$(shell pwd)/usr.sbin/link.ld USRDIR=$(USRDIR)
find $^ -type f -executable -exec mv {} base/usr/sbin/ \;
+.PHONY: bin
+bin: $(BIN_MAKEDIRS)
+ $(MAKE) -C $^ -I$(shell pwd)/builddeps \
+ LDSCRIPT=$(shell pwd)/usr.bin/link.ld USRDIR=$(USRDIR)
+ find $^ -type f -executable -exec mv {} base/usr/bin/ \;
+
.PHONY: libc
libc:
$(MAKE) -C lib/libc/ -I$(shell pwd)/builddeps \
- USRDIR=$(USRDIR)
+ USRDIR=$(USRDIR) ARCH=$(ARCH)
cp lib/libc/build/libc.a base/usr/lib/
.PHONY: base
base:
mkdir -p base/usr/lib/
mkdir -p base/usr/sbin/
+ mkdir -p base/usr/bin/
mkdir -p base/boot/
mkdir -p base/usr/include/sys/
cp -f sys/include/sys/*.h base/usr/include/sys/
@@ -110,11 +119,12 @@ clean:
iso:
mkdir -p iso_root/boot/
mkdir -p iso_root/EFI/BOOT/
- cp stand/limine/BOOTX64.EFI iso_root/EFI/BOOT/
+ cp stand/limine/$(BOOT_FW) iso_root/EFI/BOOT/
mv ramfs.cpio iso_root/boot/
- cp builddeps/limine.cfg stand/limine/limine-bios.sys \
+ cp builddeps/limine.conf stand/limine/limine-bios.sys \
stand/limine/limine-bios-cd.bin stand/limine/limine-uefi-cd.bin iso_root/
cp base/boot/* iso_root/boot/
+ cp builddeps/tree.jpg iso_root/boot/
xorriso -as mkisofs -b limine-bios-cd.bin -no-emul-boot -boot-load-size 4\
-boot-info-table --efi-boot limine-uefi-cd.bin -efi-boot-part \
--efi-boot-image --protective-msdos-label iso_root -o Hyra.iso > /dev/null
diff --git a/bootstrap b/bootstrap
index 6186385..f9370ab 100755
--- a/bootstrap
+++ b/bootstrap
@@ -23,7 +23,7 @@ prepare() {
}
fetch() {
- try_fetch "git clone https://github.com/limine-bootloader/limine.git --branch=v6.x-branch-binary --depth=1" "stand/limine"
+ try_fetch "git clone https://github.com/limine-bootloader/limine.git --branch=v9.x-binary --depth=1" "stand/limine"
}
build_limine() {
diff --git a/builddeps/limine.cfg b/builddeps/limine.cfg
deleted file mode 100644
index 87b39de..0000000
--- a/builddeps/limine.cfg
+++ /dev/null
@@ -1,8 +0,0 @@
-TIMEOUT=0
-
-:Hyra
-
-PROTOCOL=limine
-KERNEL_PATH=boot:///boot/hyra-kernel
-MODULE_PATH=boot:///boot/ramfs.cpio
-EDITOR_ENABLED=no
diff --git a/builddeps/limine.conf b/builddeps/limine.conf
new file mode 100644
index 0000000..f1907ea
--- /dev/null
+++ b/builddeps/limine.conf
@@ -0,0 +1,13 @@
+timeout=10
+${WALLPAPER_PATH}=boot():/boot/tree.jpg
+wallpaper: ${WALLPAPER_PATH}
+interface_branding_color: 1
+term_background: 40000000
+interface_branding: HYRA // OSMORA GATEWAY
+resolution: 1280x720
+
+/Hyra
+ protocol: limine
+ kernel_path: boot():/boot/hyra-kernel
+ module_path: boot():/boot/ramfs.cpio
+
diff --git a/builddeps/tree.jpg b/builddeps/tree.jpg
new file mode 100644
index 0000000..f22460d
--- /dev/null
+++ b/builddeps/tree.jpg
Binary files differ
diff --git a/builddeps/user.mk b/builddeps/user.mk
index 6c5b028..d7ad582 100644
--- a/builddeps/user.mk
+++ b/builddeps/user.mk
@@ -1,6 +1,7 @@
-CC =
+CC = gcc
LIBDIR =
USRDIR =
LDSCRIPT =
INTERNAL_CFLAGS = -T$(LDSCRIPT) -znoexecstack -nostdlib -I$(USRDIR)/include/ \
- -L$(USRDIR)/lib -lc
+ -L$(USRDIR)/lib -lc -pie -no-pie -fno-stack-protector \
+ -fno-asynchronous-unwind-tables
diff --git a/configure.ac b/configure.ac
index 08cf4dd..3729adb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,12 @@
-AC_INIT([Hyra], [1.5], [ian@osmora.org])
+AC_INIT([Hyra], [1.6], [ian@osmora.org])
+
+TARGET="amd64"
+BOOT_FW="BOOTX64.EFI"
+AC_ARG_ENABLE([aarch64],
+ [AS_HELP_STRING([--enable-aarch64], [Enable AARCH64 Support])],
+ [TARGET="aarch64"],
+ []
+)
KERN_CFLAGS_AMD64="-fexceptions --std=gnu11 -ffreestanding -fno-stack-protector -fno-pic \\
-Werror=implicit -Werror=implicit-function-declaration \\
@@ -10,20 +18,41 @@ KERN_CFLAGS_AMD64="-fexceptions --std=gnu11 -ffreestanding -fno-stack-protector
-I sys/include/ -I sys/include/lib/ -D_KERNEL -Wno-pointer-sign -MMD \\
-Wno-gnu-zero-variadic-macro-arguments -Wno-language-extension-token -Wno-tautological-constant-out-of-range-compare -Wno-c23-extensions"
+
+KERN_CFLAGS_AARCH64="-fexceptions --std=gnu11 -ffreestanding -fno-stack-protector -fno-pic \\
+ -Werror=implicit -Werror=implicit-function-declaration \\
+ -Werror=implicit-int -Werror=int-conversion \\
+ -Werror=missing-prototypes \\
+ -Werror=incompatible-pointer-types -Werror=int-to-pointer-cast \\
+ -Werror=return-type -Wunused -pedantic \\
+ -I sys/include/ -I sys/include/lib/ -D_KERNEL -Wno-pointer-sign -MMD \\
+ -Wno-gnu-zero-variadic-macro-arguments -Wno-language-extension-token -Wno-tautological-constant-out-of-range-compare -Wno-c23-extensions"
+
+
QEMU_FLAGS_AMD64="--enable-kvm -monitor stdio \\
-M q35 -m 1G -smp 4 -cpu host \\
-cdrom Hyra.iso"
+KERN_CFLAGS="$KERN_CFLAGS_AMD64"
+
+if test "x$TARGET" = "xaarch64"
+then
+ KERN_CFLAGS="$KERN_CFLAGS_AARCH64"
+ BOOT_FW="BOOTAA64.EFI"
+fi
+
+
HYRA_BUILDDATE=`export LANG=en_US.UTF-8 ; date`
HYRA_BUILDBRANCH="`basename $PWD`"
AC_SUBST(HYRA_BUILDDATE, [$HYRA_BUILDDATE])
AC_SUBST(HYRA_BUILDBRANCH, [$HYRA_BUILDBRANCH])
-AC_SUBST(KERNEL_CFLAGS, [$KERN_CFLAGS_AMD64])
+AC_SUBST(KERNEL_CFLAGS, [$KERN_CFLAGS])
AC_SUBST(QEMU_FLAGS, [$QEMU_FLAGS_AMD64])
AC_SUBST(QEMU, [qemu-system-x86_64])
-AC_SUBST(ARCH, [amd64])
+AC_SUBST(BOOT_FW, [$BOOT_FW])
+AC_SUBST(ARCH, [$TARGET])
AC_SUBST(TOOLCHAIN, [clang])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
diff --git a/lib/libc/Makefile b/lib/libc/Makefile
index c750d34..43c823e 100644
--- a/lib/libc/Makefile
+++ b/lib/libc/Makefile
@@ -5,7 +5,7 @@ LIBC_ASMFILES = $(shell find src/ -name "*.S")
LIBC_OBJ = $(LIBC_CFILES:.c=.o)
LIBC_ASMOBJ = $(LIBC_ASMFILES:.S=.S.o)
-all: headers $(LIBC_ASMOBJ) $(LIBC_OBJ) build/libc.a
+all: sys/include/machine headers $(LIBC_ASMOBJ) $(LIBC_OBJ) build/libc.a
build/libc.a: build/
ar rcs build/libc.a $(LIBC_OBJ) $(LIBC_ASMOBJ)
@@ -16,8 +16,12 @@ build/libc.a: build/
%.S.o: %.S
$(CC) $(CFLAGS) -Iinclude/ $< -o $@
+sys/include/machine:
+ mkdir -p include/machine/
+ cp include/arch/$(ARCH)/*.h include/machine/
+
.PHONY: headers
-headers:
+headers: sys/include/machine
mkdir -p include/sys/
cp -f $(USRDIR)/include/sys/*.h include/sys
cp -f include/*.h $(USRDIR)/include/
@@ -31,4 +35,5 @@ build/:
.PHONY: clean
clean:
rm -f $(LIBC_OBJ) $(LIBC_ASMOBJ)
+ rm -rf include/machine/
rm -rf build/
diff --git a/lib/libc/include/arch/amd64/syscall.h b/lib/libc/include/arch/amd64/syscall.h
new file mode 100644
index 0000000..cc401e9
--- /dev/null
+++ b/lib/libc/include/arch/amd64/syscall.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_SYSCALL_H_
+#define _MACHINE_SYSCALL_H_
+
+#if !defined(__ASSEMBLER__)
+__always_inline static inline long
+syscall0(uint64_t code)
+{
+ volatile long ret;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code));
+ return ret;
+}
+
+__always_inline static inline long
+syscall1(uint64_t code, uint64_t arg0)
+{
+ volatile long ret;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0) : "memory");
+ return ret;
+}
+
+__always_inline static long inline
+syscall2(uint64_t code, uint64_t arg0, uint64_t arg1)
+{
+ volatile long ret;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1) : "memory");
+ return ret;
+}
+
+__always_inline static inline long
+syscall3(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2)
+{
+ volatile long ret;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2) : "memory");
+ return ret;
+}
+
+__always_inline static inline long
+syscall4(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3)
+{
+ volatile long ret;
+ register uint64_t _arg3 asm("r10") = arg3;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3) : "memory");
+ return ret;
+}
+
+__always_inline static inline long
+syscall5(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4)
+{
+ volatile long ret;
+ register uint64_t _arg3 asm("r10") = arg3;
+ register uint64_t _arg4 asm("r9") = arg4;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3), "r"(_arg4) : "memory");
+ return ret;
+}
+
+__always_inline static inline long
+syscall6(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5)
+{
+ volatile long ret;
+ register uint64_t _arg3 asm("r10") = arg3;
+ register uint64_t _arg4 asm("r9") = arg4;
+ register uint64_t _arg5 asm("r8") = arg5;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5) : "memory");
+ return ret;
+}
+
+#define _SYSCALL_N(a0, a1, a2, a3, a4, a5, a6, name, ...) \
+ name
+
+#define syscall(...) \
+_SYSCALL_N(__VA_ARGS__, syscall6, syscall5, \
+ syscall4, syscall3, syscall2, syscall1, \
+ syscall0)(__VA_ARGS__)
+
+#endif /* !__ASSEMBLER__ */
+#endif /* !_MACHINE_SYSCALL_H_ */
diff --git a/lib/libc/include/string.h b/lib/libc/include/string.h
new file mode 100644
index 0000000..d1613e4
--- /dev/null
+++ b/lib/libc/include/string.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _STRING_H_
+#define _STRING_H_ 1
+
+#include <stddef.h>
+
+size_t strlen(const char *s);
+int memcmp(const void *s1, const void *s2, size_t n);
+int strcmp(const char *s1, const char *s2);
+
+#endif /* !_STRING_H_ */
diff --git a/lib/libc/src/string/memcmp.c b/lib/libc/src/string/memcmp.c
new file mode 100644
index 0000000..404ae2c
--- /dev/null
+++ b/lib/libc/src/string/memcmp.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+int
+memcmp(const void *s1, const void *s2, size_t n)
+{
+ if (n != 0) {
+ const unsigned char *p1 = s1, *p2 = s2;
+
+ do {
+ if (*p1++ != *p2++) {
+ return (*--p1 - *--p2);
+ }
+ } while (--n != 0);
+ }
+ return 0;
+}
diff --git a/lib/libc/src/string/strcmp.c b/lib/libc/src/string/strcmp.c
new file mode 100644
index 0000000..b7a62ab
--- /dev/null
+++ b/lib/libc/src/string/strcmp.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+int
+strcmp(const char *s1, const char *s2)
+{
+ while (*s1 == *s2++) {
+ if (*s1++ == 0) {
+ return (0);
+ }
+ }
+
+ return (*(unsigned char *)s1 - *(unsigned char *)--s2);
+}
diff --git a/lib/libc/src/string/strlen.c b/lib/libc/src/string/strlen.c
new file mode 100644
index 0000000..a07b407
--- /dev/null
+++ b/lib/libc/src/string/strlen.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+size_t
+strlen(const char *s)
+{
+ size_t len;
+
+ len = 0;
+ while (s[len++]);
+ return len - 1;
+}
diff --git a/share/misc/contrib b/share/misc/contrib
index 6f93fb7..a36c127 100644
--- a/share/misc/contrib
+++ b/share/misc/contrib
@@ -21,6 +21,22 @@ is_power_of_two(uint8_t n)
return ((n & 0x01) == 0);
}
+--
+When defining local variables in functions, they
+must be declared at the top:
+
+static void
+foo(void)
+{
+ uint8_t byte;
+ uint16_t pair;
+ uint32_t quad;
+ uint64_t oct;
+
+ ...
+}
+--
+
When checking if an integer is 0 or not, *be explicit* unless it is a bool!
Do not do this:
@@ -87,6 +103,14 @@ a pointer, like, for example:
uint8_t *ptr = NULL;
...
+--
+The preferred pointer style is:
+
+void *p = ...;
+
+-- Not:
+
+void* p = ...;
-- or if you have for example, some sort of counter value
that must have a start:
diff --git a/sys/arch/aarch64/aarch64/acpi_machdep.c b/sys/arch/aarch64/aarch64/acpi_machdep.c
new file mode 100644
index 0000000..f077de3
--- /dev/null
+++ b/sys/arch/aarch64/aarch64/acpi_machdep.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <dev/acpi/acpi.h>
+#include <dev/acpi/acpivar.h>
+
+int
+acpi_init_madt(void)
+{
+ return 0;
+}
diff --git a/sys/arch/aarch64/aarch64/machdep.c b/sys/arch/aarch64/aarch64/machdep.c
new file mode 100644
index 0000000..a29ad7e
--- /dev/null
+++ b/sys/arch/aarch64/aarch64/machdep.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/syslog.h>
+#include <sys/panic.h>
+#include <machine/cpu.h>
+#include <machine/sync.h>
+
+struct cpu_info g_bsp_ci = {0};
+
+void
+cpu_startup(struct cpu_info *ci)
+{
+ /* TODO: STUB */
+ return;
+}
+
+void
+serial_init(void)
+{
+ /* TODO: STUB */
+ return;
+}
+
+void
+md_backtrace(void)
+{
+ /* TODO: STUB */
+ return;
+}
+
+void
+serial_putc(char c)
+{
+ /* TODO: STUB */
+ return;
+}
+
+int
+md_sync_all(void)
+{
+ /* TODO: STUB */
+ return 0;
+}
+
+/*
+ * Get the descriptor for the currently
+ * running processor.
+ */
+struct cpu_info *
+this_cpu(void)
+{
+ struct cpu_info *ci;
+
+ __ASMV("mrs %0, tpidr_el0" : "=r" (ci));
+ return ci;
+}
diff --git a/sys/arch/aarch64/aarch64/mp.c b/sys/arch/aarch64/aarch64/mp.c
new file mode 100644
index 0000000..4e07566
--- /dev/null
+++ b/sys/arch/aarch64/aarch64/mp.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <machine/cpu.h>
+
+#define pr_trace(fmt, ...) kprintf("cpu_mp: " fmt, ##__VA_ARGS__)
+
+void
+mp_bootstrap_aps(struct cpu_info *ci)
+{
+ for (;;);
+}
diff --git a/sys/arch/aarch64/aarch64/pmap.c b/sys/arch/aarch64/aarch64/pmap.c
new file mode 100644
index 0000000..b5ebda9
--- /dev/null
+++ b/sys/arch/aarch64/aarch64/pmap.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <machine/vas.h>
+#include <vm/pmap.h>
+
+struct vas
+pmap_read_vas(void)
+{
+ /* TODO: STUB */
+ struct vas vas = {0};
+ return vas;
+}
+
+void
+pmap_switch_vas(struct vas vas)
+{
+ /* TODO: STUB */
+ return;
+}
+
+int
+pmap_map(struct vas vas, vaddr_t va, paddr_t pa, vm_prot_t prot)
+{
+ /* TODO: STUB */
+ return 0;
+}
+
+int
+pmap_unmap(struct vas vas, vaddr_t va)
+{
+ /* TODO: STUB */
+ return 0;
+}
+
+void
+pmap_destroy_vas(struct vas vas)
+{
+ /* TODO: STUB */
+ return;
+}
diff --git a/sys/arch/aarch64/aarch64/proc_machdep.c b/sys/arch/aarch64/aarch64/proc_machdep.c
new file mode 100644
index 0000000..97902e5
--- /dev/null
+++ b/sys/arch/aarch64/aarch64/proc_machdep.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/proc.h>
+
+/*
+ * MD thread init code
+ *
+ * @p: New process.
+ * @parent: Parent of new process.
+ * @ip: Instruction pointer.
+ */
+int
+md_fork(struct proc *p, struct proc *parent, uintptr_t ip)
+{
+ /* TODO: STUB */
+ return 0;
+}
+
+void
+md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog)
+{
+ /* TODO: STUB */
+ return;
+}
+
+void
+setregs(struct proc *td, struct exec_prog *prog, uintptr_t stack)
+{
+ /* TODO: STUB */
+ return;
+}
+
+/*
+ * Startup a user thread.
+ *
+ * @td: Thread to start up.
+ */
+void
+md_td_kick(struct proc *td)
+{
+ /* TODO: STUB */
+ for (;;);
+}
diff --git a/sys/arch/aarch64/aarch64/reboot.c b/sys/arch/aarch64/aarch64/reboot.c
new file mode 100644
index 0000000..6d82133
--- /dev/null
+++ b/sys/arch/aarch64/aarch64/reboot.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/reboot.h>
+#include <sys/param.h>
+
+void
+cpu_reboot(int method)
+{
+ /* TODO: STUB */
+ for (;;);
+}
diff --git a/sys/arch/aarch64/conf/GENERIC b/sys/arch/aarch64/conf/GENERIC
new file mode 100644
index 0000000..5691685
--- /dev/null
+++ b/sys/arch/aarch64/conf/GENERIC
@@ -0,0 +1,5 @@
+// Kernel options
+option SERIAL_DEBUG yes
+
+// Kernel constants
+setval SCHED_NQUEUE 4
diff --git a/sys/arch/aarch64/conf/link.ld b/sys/arch/aarch64/conf/link.ld
new file mode 100644
index 0000000..c64cec3
--- /dev/null
+++ b/sys/arch/aarch64/conf/link.ld
@@ -0,0 +1,75 @@
+/* Tell the linker that we want an aarch64 ELF64 output file */
+OUTPUT_FORMAT(elf64-littleaarch64)
+OUTPUT_ARCH(aarch64)
+
+/* We want the symbol main to be our entry point */
+ENTRY(main)
+
+/* Define the program headers we want so the bootloader gives us the right */
+/* MMU permissions */
+PHDRS
+{
+ text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */
+ rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */
+ data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */
+ dynamic PT_DYNAMIC FLAGS((1 << 1) | (1 << 2)) ; /* Dynamic PHDR for relocations */
+}
+
+SECTIONS
+{
+ /* We wanna be placed in the topmost 2GiB of the address space, for optimisations */
+ /* and because that is what the Limine spec mandates. */
+ /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */
+ /* that is the beginning of the region. */
+ . = 0xffffffff80000000;
+
+ .text : {
+ *(.text .text.*)
+ } :text
+
+ /* Move to the next memory page for .rodata */
+ . += CONSTANT(MAXPAGESIZE);
+
+ .rodata : {
+ *(.rodata .rodata.*)
+ } :rodata
+
+ .drivers : {
+ __drivers_init_start = .;
+ *(.drivers .drivers)
+ __drivers_init_end = .;
+ } :rodata
+
+ /* Move to the next memory page for .data */
+ . += CONSTANT(MAXPAGESIZE);
+
+ .data : {
+ *(.data .data.*)
+ } :data
+
+ /* Dynamic section for relocations, both in its own PHDR and inside data PHDR */
+ .dynamic : {
+ *(.dynamic)
+ } :data :dynamic
+
+ /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */
+ /* unnecessary zeros will be written to the binary. */
+ /* If you need, for example, .init_array and .fini_array, those should be placed */
+ /* above this. */
+ .bss : {
+ *(.bss .bss.*)
+ *(COMMON)
+ } :data
+
+ /* -- Cache line alignment -- */
+ . = ALIGN(64);
+ .data.cacheline_aligned : {
+ *(.data.cacheline_aligned)
+ }
+
+ /* Discard .note.* and .eh_frame since they may cause issues on some hosts. */
+ /DISCARD/ : {
+ *(.eh_frame)
+ *(.note .note.*)
+ }
+}
diff --git a/sys/arch/aarch64/pci/pci_machdep.c b/sys/arch/aarch64/pci/pci_machdep.c
new file mode 100644
index 0000000..fa92165
--- /dev/null
+++ b/sys/arch/aarch64/pci/pci_machdep.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <dev/pci/pci.h>
+
+pcireg_t
+pci_readl(struct pci_device *dev, uint32_t offset)
+{
+ /* TODO: STUB */
+ return 0;
+}
+
+void
+pci_writel(struct pci_device *dev, uint32_t offset, pcireg_t val)
+{
+ /* TODO: STUB */
+ return;
+}
+
+/*
+ * Map a BAR into kernel memory.
+ *
+ * @dev: Device of BAR to map.
+ * @barno: BAR number to map.
+ * @vap: Resulting virtual address.
+ */
+int
+pci_map_bar(struct pci_device *dev, uint8_t barno, void **vap)
+{
+ /* TODO: STUB */
+ return 0;
+}
+
+void
+pci_msix_eoi(void)
+{
+ return;
+}
+
+/*
+ * Enable MSI-X for a device and allocate an
+ * interrupt vector.
+ *
+ * @dev: Device to enable MSI-X for.
+ * @intr: MSI-X interrupt descriptor.
+ */
+int
+pci_enable_msix(struct pci_device *dev, const struct msi_intr *intr)
+{
+ /* TODO: STUB */
+ return 0;
+}
diff --git a/sys/arch/amd64/amd64/lapic_intr.S b/sys/arch/amd64/amd64/lapic_intr.S
index ab6f5ab..e22cbca 100644
--- a/sys/arch/amd64/amd64/lapic_intr.S
+++ b/sys/arch/amd64/amd64/lapic_intr.S
@@ -33,6 +33,7 @@
.globl lapic_tmr_isr
INTRENTRY(lapic_tmr_isr, handle_lapic_tmr)
handle_lapic_tmr:
- call sched_switch
- call lapic_eoi
+ call sched_switch // Context switch per every timer IRQ
+ call i8042_sync // Sometimes needed depending on i8042 quirks
+ call lapic_eoi // Done! Signal that we finished to the Local APIC
retq
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index a5fb4bf..07d6cdd 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -40,7 +40,9 @@
#include <machine/cpuid.h>
#include <machine/lapic.h>
#include <machine/uart.h>
+#include <machine/sync.h>
#include <machine/intr.h>
+#include <machine/isa/i8042var.h>
#if defined(__SPECTRE_IBRS)
#define SPECTRE_IBRS __SPECTRE_IBRS
@@ -207,6 +209,17 @@ this_cpu(void)
return ci;
}
+/*
+ * Sync all system operation
+ */
+int
+md_sync_all(void)
+{
+ lapic_eoi();
+ i8042_sync();
+ return 0;
+}
+
void
cpu_startup(struct cpu_info *ci)
{
@@ -220,6 +233,5 @@ cpu_startup(struct cpu_info *ci)
init_tss(ci);
try_mitigate_spectre();
- __ASMV("sti"); /* Unmask interrupts */
lapic_init();
}
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c
index 29056b0..9a3a7ba 100644
--- a/sys/arch/amd64/amd64/trap.c
+++ b/sys/arch/amd64/amd64/trap.c
@@ -35,6 +35,8 @@
#include <sys/syscall.h>
#include <sys/sched.h>
#include <sys/proc.h>
+#include <machine/cpu.h>
+#include <machine/isa/i8042var.h>
#include <machine/trap.h>
#include <machine/frame.h>
#include <machine/intr.h>
@@ -118,6 +120,20 @@ trap_user(struct trapframe *tf)
dispatch_signals(td);
}
+static void
+trap_quirks(struct cpu_info *ci)
+{
+ static uint8_t count;
+
+ if (ISSET(ci->irq_mask, CPU_IRQ(1)) && count < 1) {
+ ++count;
+ pr_error("detected buggy i8042\n");
+ pr_error("applying I8042_HOSTILE quirk\n");
+ i8042_quirk(I8042_HOSTILE);
+ return;
+ }
+}
+
void
trap_syscall(struct trapframe *tf)
{
@@ -139,6 +155,8 @@ trap_syscall(struct trapframe *tf)
void
trap_handler(struct trapframe *tf)
{
+ struct cpu_info *ci;
+
splraise(IPL_HIGH);
if (tf->trapno >= NELEM(trap_type)) {
@@ -146,6 +164,8 @@ trap_handler(struct trapframe *tf)
}
pr_error("got %s\n", trap_type[tf->trapno]);
+ ci = this_cpu();
+ trap_quirks(ci);
/* Handle traps from userland */
if (ISSET(tf->cs, 3)) {
diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC
index 19c9a62..d3a4368 100644
--- a/sys/arch/amd64/conf/GENERIC
+++ b/sys/arch/amd64/conf/GENERIC
@@ -4,3 +4,7 @@ option SERIAL_DEBUG yes
// Kernel constants
setval SCHED_NQUEUE 4
+
+// Console attributes
+setval CONSOLE_BG 0x000000
+setval CONSOLE_FG 0XB57614
diff --git a/sys/arch/amd64/isa/i8042.S b/sys/arch/amd64/isa/i8042.S
new file mode 100644
index 0000000..123d3a5
--- /dev/null
+++ b/sys/arch/amd64/isa/i8042.S
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/frameasm.h>
+
+ .text
+ .globl i8042_kb_isr
+INTRENTRY(i8042_kb_isr, handle_kb)
+handle_kb:
+ call i8042_kb_event
+ retq
diff --git a/sys/arch/amd64/isa/i8042.c b/sys/arch/amd64/isa/i8042.c
new file mode 100644
index 0000000..2582d8f
--- /dev/null
+++ b/sys/arch/amd64/isa/i8042.c
@@ -0,0 +1,457 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/driver.h>
+#include <sys/errno.h>
+#include <sys/syslog.h>
+#include <sys/spinlock.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/reboot.h>
+#include <sys/queue.h>
+#include <dev/acpi/acpi.h>
+#include <dev/timer.h>
+#include <dev/cons/cons.h>
+#include <machine/cpu.h>
+#include <machine/pio.h>
+#include <machine/isa/i8042var.h>
+#include <machine/isa/spkr.h>
+#include <machine/idt.h>
+#include <machine/ioapic.h>
+#include <machine/intr.h>
+#include <machine/lapic.h>
+#include <machine/cdefs.h>
+#include <string.h>
+#include <assert.h>
+
+#define KEY_REP_MAX 2
+
+#define pr_trace(fmt, ...) kprintf("i8042: " fmt, ##__VA_ARGS__)
+#define pr_error(...) pr_trace(__VA_ARGS__)
+
+#define IO_NOP() inb(0x80)
+
+static struct spinlock data_lock;
+static struct spinlock isr_lock;
+static bool shift_key = false;
+static bool capslock = false;
+static bool capslock_released = true;
+static uint16_t quirks = 0;
+static struct proc polltd;
+static struct timer tmr;
+static bool is_init = false;
+
+static int dev_send(bool aux, uint8_t data);
+static int i8042_kb_getc(uint8_t sc, char *chr);
+static void i8042_drain(void);
+
+static char keytab[] = {
+ '\0', '\0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
+ '-', '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
+ 'o', 'p', '[', ']', '\n', '\0', 'a', 's', 'd', 'f', 'g', 'h',
+ 'j', 'k', 'l', ';', '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v',
+ 'b', 'n', 'm', ',', '.', '/', '\0', '\0', '\0', ' '
+};
+
+static char keytab_shift[] = {
+ '\0', '\0', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
+ '_', '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
+ 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', 'D', 'F', 'G', 'H',
+ 'J', 'K', 'L', ':', '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V',
+ 'B', 'N', 'M', '<', '>', '?', '\0', '\0', '\0', ' '
+};
+
+static char keytab_caps[] = {
+ '\0', '\0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
+ '-','=', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
+ 'O', 'P', '[', ']', '\n', '\0', 'A', 'S', 'D', 'F', 'G', 'H',
+ 'J', 'K', 'L', ';', '\'', '`', '\0', '\\', 'Z', 'X', 'C', 'V',
+ 'B', 'N', 'M', ',', '.', '/', '\0', '\0', '\0', ' '
+};
+
+static void
+kbd_set_leds(uint8_t mask)
+{
+ dev_send(false, 0xED);
+ dev_send(false, mask);
+}
+
+/*
+ * Poll the i8042 status register
+ *
+ * @bits: Status bits.
+ * @pollset: True to poll if set
+ */
+static int
+i8042_statpoll(uint8_t bits, bool pollset)
+{
+ size_t usec_start, usec;
+ size_t elapsed_msec;
+ uint8_t val;
+ bool tmp;
+
+ usec_start = tmr.get_time_usec();
+ for (;;) {
+ val = inb(I8042_STATUS);
+ tmp = (pollset) ? ISSET(val, bits) : !ISSET(val, bits);
+ usec = tmr.get_time_usec();
+ elapsed_msec = (usec - usec_start) / 1000;
+
+ IO_NOP();
+
+ /* If tmp is set, the register updated in time */
+ if (tmp) {
+ break;
+ }
+
+ /* Exit with an error if we timeout */
+ if (elapsed_msec > I8042_DELAY) {
+ return -ETIME;
+ }
+ }
+
+ return val;
+}
+
+/*
+ * Drain i8042 internal data registers.
+ */
+static void
+i8042_drain(void)
+{
+ spinlock_acquire(&data_lock);
+ while (ISSET(inb(I8042_STATUS), I8042_OBUFF)) {
+ inb(I8042_DATA);
+ }
+ spinlock_release(&data_lock);
+}
+
+/*
+ * Write to an i8042 register.
+ *
+ * @port: I/O port
+ * @val: Value to write
+ */
+static void
+i8042_write(uint16_t port, uint8_t val)
+{
+ i8042_statpoll(I8042_IBUFF, false);
+ outb(port, val);
+}
+
+/*
+ * Read the i8042 config register
+ */
+static uint8_t
+i8042_read_conf(void)
+{
+ i8042_drain();
+ i8042_write(I8042_CMD, I8042_GET_CONFB);
+ i8042_statpoll(I8042_OBUFF, true);
+ return inb(I8042_DATA);
+}
+
+/*
+ * Write the i8042 config register
+ */
+static void
+i8042_write_conf(uint8_t value)
+{
+ i8042_drain();
+ i8042_statpoll(I8042_IBUFF, false);
+ i8042_write(I8042_CMD, I8042_SET_CONFB);
+ i8042_statpoll(I8042_IBUFF, false);
+ i8042_write(I8042_DATA, value);
+ i8042_drain();
+}
+
+/*
+ * Send a data to a device
+ *
+ * @aux: If true, send to aux device (mouse)
+ * @data: Data to send.
+ */
+static int
+dev_send(bool aux, uint8_t data)
+{
+ if (aux) {
+ i8042_write(I8042_CMD, I8042_PORT1_SEND);
+ }
+
+ i8042_statpoll(I8042_IBUFF, false);
+ i8042_write(I8042_DATA, data);
+ i8042_statpoll(I8042_OBUFF, true);
+ return inb(I8042_DATA);
+}
+
+void
+i8042_kb_event(void)
+{
+ struct cpu_info *ci;
+ struct cons_input input;
+ uint8_t data;
+ char c;
+
+ spinlock_acquire(&isr_lock);
+ ci = this_cpu();
+ ci->irq_mask |= CPU_IRQ(1);
+ data = inb(I8042_DATA);
+
+ if (i8042_kb_getc(data, &c) != 0) {
+ /* No data useful */
+ goto done;
+ }
+ input.scancode = data;
+ input.chr = c;
+ cons_ibuf_push(&g_root_scr, input);
+done:
+ ci->irq_mask &= CPU_IRQ(1);
+ spinlock_release(&isr_lock);
+ lapic_eoi();
+}
+
+static void
+i8042_en_intr(void)
+{
+ uint8_t conf;
+ int vec;
+
+ pr_trace("ENTER -> i8042_en_intr\n");
+ i8042_write(I8042_CMD, I8042_DISABLE_PORT0);
+ pr_trace("port 0 disabled\n");
+
+ vec = intr_alloc_vector("i8042-kb", IPL_BIO);
+ idt_set_desc(vec, IDT_INT_GATE, ISR(i8042_kb_isr), IST_HW_IRQ);
+ ioapic_set_vec(KB_IRQ, vec);
+ ioapic_irq_unmask(KB_IRQ);
+ pr_trace("irq 1 -> vec[%x]\n", vec);
+
+ /* Setup config bits */
+ conf = i8042_read_conf();
+ conf |= I8042_PORT0_INTR;
+ conf &= ~I8042_PORT1_INTR;
+ i8042_write_conf(conf);
+ pr_trace("conf written\n");
+
+ i8042_write(I8042_CMD, I8042_ENABLE_PORT0);
+ pr_trace("port 0 enabled\n");
+}
+
+static void
+esckey_reboot(void)
+{
+ syslock();
+ kprintf("** Machine going down for a reboot");
+
+ for (size_t i = 0; i < 3; ++i) {
+ kprintf(OMIT_TIMESTAMP ".");
+ tmr.msleep(1000);
+ }
+
+ cpu_reboot(0);
+}
+
+/*
+ * Convert scancode to character
+ *
+ * @sc: Scancode
+ * @chr: Character output
+ *
+ * Returns 0 when a char is given back.
+ */
+static int
+i8042_kb_getc(uint8_t sc, char *chr)
+{
+ bool release = ISSET(sc, BIT(7));
+
+ switch (sc) {
+ /* Left alt [press] */
+ case 0x38:
+ esckey_reboot();
+ break;
+ /* Caps lock [press] */
+ case 0x3A:
+ /*
+ * In case we are holding the caps lock button down,
+ * we don't want it to be spam toggled as that would
+ * be pretty strange looking and probably annoying.
+ */
+ if (!capslock_released) {
+ return -EAGAIN;
+ }
+
+ capslock_released = false;
+ capslock = !capslock;
+
+ if (!capslock) {
+ kbd_set_leds(0);
+ } else {
+ kbd_set_leds(I8042_LED_CAPS);
+ }
+ return -EAGAIN;
+ /* Caps lock [release] */
+ case 0xBA:
+ capslock_released = true;
+ return -EAGAIN;
+ /* Shift */
+ case 0x36:
+ case 0xAA:
+ case 0x2A:
+ case 0xB6:
+ if (!release) {
+ shift_key = true;
+ } else {
+ shift_key = false;
+ }
+ return -EAGAIN;
+ }
+
+ if (release) {
+ return -EAGAIN;
+ }
+
+ if (capslock) {
+ *chr = keytab_caps[sc];
+ return 0;
+ }
+
+ if (shift_key) {
+ *chr = keytab_shift[sc];
+ return 0;
+ }
+
+ *chr = keytab[sc];
+ return 0;
+}
+
+static void
+i8042_sync_loop(void)
+{
+ /* Wake up the bus */
+ outb(I8042_DATA, 0x00);
+ i8042_drain();
+
+ for (;;) {
+ i8042_sync();
+ md_pause();
+ }
+}
+
+/*
+ * Grabs a key from the keyboard, used typically
+ * for syncing the machine however can be used
+ * to bypass IRQs in case of buggy EC.
+ */
+void
+i8042_sync(void)
+{
+ static struct spinlock lock;
+ struct cons_input input;
+ uint8_t data;
+ char c;
+
+ if (spinlock_try_acquire(&lock)) {
+ return;
+ }
+
+ if (ISSET(quirks, I8042_HOSTILE) && is_init) {
+ if (i8042_statpoll(I8042_OBUFF, true) < 0) {
+ /* No data ready */
+ goto done;
+ }
+ data = inb(I8042_DATA);
+
+ if (i8042_kb_getc(data, &c) == 0) {
+ input.scancode = data;
+ input.chr = c;
+ cons_ibuf_push(&g_root_scr, input);
+ }
+ }
+done:
+ spinlock_release(&lock);
+}
+
+void
+i8042_quirk(int mask)
+{
+ quirks |= mask;
+}
+
+static int
+i8042_init(void)
+{
+ /* Try to request a general purpose timer */
+ if (req_timer(TIMER_GP, &tmr) != TMRR_SUCCESS) {
+ pr_error("failed to fetch general purpose timer\n");
+ return -ENODEV;
+ }
+
+ /* Ensure it has get_time_usec() */
+ if (tmr.get_time_usec == NULL) {
+ pr_error("general purpose timer has no get_time_usec()\n");
+ return -ENODEV;
+ }
+
+ /* We also need msleep() */
+ if (tmr.msleep == NULL) {
+ pr_error("general purpose timer has no msleep()\n");
+ return -ENODEV;
+ }
+
+ /*
+ * On some thinkpads, e.g., the T420s, the EC implementing
+ * the i8042 logic likes to play cop and throw NMIs at us
+ * for anything we do e.g., config register r/w, IRQs,
+ * etc... As of now, treat the i8042 like a fucking bomb
+ * if this bit is set.
+ */
+ if (strcmp(acpi_oemid(), "LENOVO") == 0) {
+ quirks |= I8042_HOSTILE;
+ pr_trace("lenovo device, assuming hostile\n");
+ pr_trace("disabling irq 1, polling as fallback\n");
+ fork1(&polltd, 0, i8042_sync_loop, NULL);
+ }
+
+ if (!ISSET(quirks, I8042_HOSTILE)) {
+ /* Enable interrupts */
+ i8042_drain();
+ i8042_en_intr();
+ }
+
+ if (dev_send(false, 0xFF) == 0xFC) {
+ pr_error("kbd self test failure\n");
+ return -EIO;
+ }
+
+ is_init = true;
+ return 0;
+}
+
+DRIVER_EXPORT(i8042_init);
diff --git a/sys/arch/amd64/isa/spkr.c b/sys/arch/amd64/isa/spkr.c
new file mode 100644
index 0000000..b1bd2a2
--- /dev/null
+++ b/sys/arch/amd64/isa/spkr.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/errno.h>
+#include <sys/param.h>
+#include <dev/timer.h>
+#include <machine/isa/spkr.h>
+#include <machine/isa/i8254.h>
+#include <machine/pio.h>
+
+#define DIVIDEND 1193180
+#define CTRL_PORT 0x61
+
+int
+pcspkr_tone(uint16_t freq, uint32_t msec)
+{
+ uint32_t divisor;
+ uint8_t tmp;
+ struct timer tmr;
+
+ if (req_timer(TIMER_GP, &tmr) != TMRR_SUCCESS)
+ return -ENOTSUP;
+ if (__unlikely(tmr.msleep == NULL))
+ return -ENOTSUP;
+
+ divisor = DIVIDEND / freq;
+ outb(I8254_COMMAND, 0xB6);
+ outb(I8254_CHANNEL_2, divisor & 0xFF);
+ outb(I8254_CHANNEL_2, (divisor >> 8) & 0xFF);
+
+ /* Oscillate the speaker */
+ tmp = inb(CTRL_PORT);
+ if (!ISSET(tmp, 3)) {
+ tmp |= 3;
+ outb(CTRL_PORT, tmp);
+ }
+
+ /* Sleep then turn off the speaker */
+ tmr.msleep(msec);
+ outb(CTRL_PORT, tmp & ~3);
+ return 0;
+}
diff --git a/sys/dev/acpi/acpi_init.c b/sys/dev/acpi/acpi_init.c
index bc8be77..ecfb129 100644
--- a/sys/dev/acpi/acpi_init.c
+++ b/sys/dev/acpi/acpi_init.c
@@ -36,12 +36,14 @@
#include <dev/acpi/acpivar.h>
#include <dev/pci/pci.h>
#include <vm/vm.h>
+#include <string.h>
#if defined(__x86_64__)
#include <machine/hpet.h>
#endif /* __x86_64__ */
#define pr_trace(fmt, ...) kprintf("acpi: " fmt, ##__VA_ARGS__)
+static char oemid[OEMID_SIZE];
static struct acpi_root_sdt *root_sdt = NULL;
static size_t root_sdt_entries = 0;
static volatile struct limine_rsdp_request rsdp_req = {
@@ -91,6 +93,12 @@ acpi_get_root_sdt_len(void)
return root_sdt_entries;
}
+const char *
+acpi_oemid(void)
+{
+ return oemid;
+}
+
void
acpi_init(void)
{
@@ -103,6 +111,7 @@ acpi_init(void)
/* Fetch the RSDP */
rsdp = rsdp_req.response->address;
acpi_print_oemid("RSDP", rsdp->oemid);
+ memcpy(oemid, rsdp->oemid, OEMID_SIZE);
/* Fetch the root SDT */
if (rsdp->revision >= 2) {
diff --git a/sys/dev/cons/cons.c b/sys/dev/cons/cons.c
index 4b85240..365aa0b 100644
--- a/sys/dev/cons/cons.c
+++ b/sys/dev/cons/cons.c
@@ -31,6 +31,8 @@
#include <sys/types.h>
#include <sys/ascii.h>
#include <sys/device.h>
+#include <sys/errno.h>
+#include <sys/panic.h>
#include <dev/video/fbdev.h>
#include <dev/cons/font.h>
#include <dev/cons/cons.h>
@@ -38,27 +40,32 @@
#include <vm/dynalloc.h>
#include <string.h>
+#define HIDE_CURSOR(SCR) \
+ cons_draw_cursor((SCR), (SCR)->bg)
+
+#define SHOW_CURSOR(SCR) \
+ cons_draw_cursor((SCR), (SCR)->fg)
+
+/* Console background from kconf */
+#if defined(__CONSOLE_BG)
+#define CONSOLE_BG __CONSOLE_BG
+#else
+#define CONSOLE_BG 0x000000
+#endif /* __CONSOLE_BG */
+
+/* Console foreground from kconf */
+#if defined(__CONSOLE_FG)
+#define CONSOLE_FG __CONSOLE_FG
+#else
+#define CONSOLE_FG 0x00AA00
+#endif /* __CONSOLE_FG */
+
struct cons_screen g_root_scr = {0};
static struct cdevsw cons_cdevsw;
-/*
- * Create a chracter descriptor for drawing
- * characters.
- *
- * @c: Character.
- * @fg: Foreground.
- * @bg: Background.
- */
-static inline struct cons_char
-cons_make_char(char c, uint32_t fg, uint32_t bg)
-{
- struct cons_char ch;
-
- ch.fg = fg;
- ch.bg = bg;
- ch.c = c;
- return ch;
-}
+static void cons_draw_cursor(struct cons_screen *scr, uint32_t color);
+static int cons_handle_special(struct cons_screen *scr, char c);
+static void cons_clear_scr(struct cons_screen *scr, uint32_t bg);
/*
* Render a character onto the screen.
@@ -69,10 +76,10 @@ cons_make_char(char c, uint32_t fg, uint32_t bg)
* @y: Y position of char.
*/
static void
-cons_draw_char(struct cons_screen *scr, struct cons_char ch,
- uint32_t x, uint32_t y)
+cons_draw_char(struct cons_screen *scr, struct cons_char ch)
{
size_t idx;
+ uint32_t x, y;
const uint8_t *glyph;
if (scr->fb_mem == NULL) {
@@ -80,6 +87,9 @@ cons_draw_char(struct cons_screen *scr, struct cons_char ch,
}
glyph = &CONS_FONT[(int)ch.c*16];
+ x = ch.x;
+ y = ch.y;
+
for (uint32_t cy = 0; cy < FONT_HEIGHT; ++cy) {
for (uint32_t cx = 0; cx < FONT_WIDTH; ++cx) {
idx = fbdev_get_index(&scr->fbdev, x + (FONT_WIDTH - 1) - cx, y + cy);
@@ -88,33 +98,45 @@ cons_draw_char(struct cons_screen *scr, struct cons_char ch,
}
}
-static void
-cons_draw_cursor(struct cons_screen *scr, uint32_t color)
+/*
+ * Internal helper - flush console row
+ *
+ * @row: Row to flush.
+ */
+static int
+cons_flush_row(struct cons_screen *scr, uint32_t row)
{
- size_t idx;
+ struct cons_buf *bp;
+ struct cons_char cc;
- for (uint32_t cy = 0; cy < FONT_HEIGHT; ++cy) {
- for (uint32_t cx = 0; cx < FONT_WIDTH; ++cx) {
- idx = fbdev_get_index(&scr->fbdev, (scr->curs_col * FONT_WIDTH) + cx, (scr->curs_row * FONT_HEIGHT) + cy);
- scr->fb_mem[idx] = color;
+ bp = scr->ob[row];
+ if (ISSET(bp->flags, CONS_BUF_CLEAN)) {
+ return -EIO;
+ }
+
+ for (int j = 0; j < bp->len; ++j) {
+ if (cons_obuf_pop(bp, &cc) != 0) {
+ continue;
}
+
+ cons_draw_char(scr, cc);
+ bp->flags |= CONS_BUF_CLEAN;
}
+
+ return 0;
}
/*
- * Clear the screen.
+ * Internal helper - flush console
*
- * @scr: Screen to clear.
- * @bg: Color to clear it to.
*/
-static void
-cons_clear_scr(struct cons_screen *scr, uint32_t bg)
+static int
+cons_flush(struct cons_screen *scr)
{
- struct fbdev fbdev = scr->fbdev;
-
- for (size_t i = 0; i < fbdev.height * fbdev.pitch; ++i) {
- scr->fb_mem[i] = bg;
+ for (int i = 0; i < scr->nrows; ++i) {
+ cons_flush_row(scr, i);
}
+ return 0;
}
/*
@@ -128,22 +150,91 @@ cons_clear_scr(struct cons_screen *scr, uint32_t bg)
static int
cons_handle_special(struct cons_screen *scr, char c)
{
+ if (scr->ch_col >= scr->ncols - 20) {
+ scr->ch_col = 0;
+ cons_handle_special(scr, '\n');
+ }
+
switch (c) {
case ASCII_LF:
+ HIDE_CURSOR(scr);
+
+ /* Are we past screen width? */
+ if (scr->ch_row >= scr->nrows - 1) {
+ cons_clear_scr(scr, scr->bg);
+ cons_flush(scr);
+ scr->ch_col = 0;
+ scr->ch_row = 0;
+
+ /* Update cursor */
+ scr->curs_row = 0;
+ scr->curs_col = 0;
+ SHOW_CURSOR(scr);
+ return 0;
+ }
+
/* Make a newline */
- scr->ch_col = 0;
+ cons_flush(scr);
++scr->ch_row;
+ scr->ch_col = 0;
+ cons_flush(scr);
- cons_draw_cursor(scr, scr->bg);
+ /* Update cursor */
+ scr->curs_row += 1;
scr->curs_col = 0;
- scr->curs_row++;
- cons_draw_cursor(scr, scr->last_chr.fg);
+ SHOW_CURSOR(scr);
+ return 0;
+ case ASCII_FF:
+ /*
+ * Fuck what they say, this is now the
+ * "flush" byte ::)
+ */
+ cons_flush(scr);
return 0;
}
return -1;
}
+static void
+cons_draw_cursor(struct cons_screen *scr, uint32_t color)
+{
+ size_t idx;
+
+ /* Past screen width? */
+ if (scr->curs_col >= scr->ncols) {
+ scr->curs_col = 0;
+ scr->curs_row++;
+ }
+
+ for (uint32_t cy = 0; cy < FONT_HEIGHT; ++cy) {
+ for (uint32_t cx = 0; cx < FONT_WIDTH; ++cx) {
+ idx = fbdev_get_index(&scr->fbdev, (scr->curs_col * FONT_WIDTH) + cx, (scr->curs_row * FONT_HEIGHT) + cy);
+ scr->fb_mem[idx] = color;
+ }
+ }
+}
+
+/*
+ * Clear the screen.
+ *
+ * @scr: Screen to clear.
+ * @bg: Color to clear it to.
+ */
+static void
+cons_clear_scr(struct cons_screen *scr, uint32_t bg)
+{
+ struct fbdev fbdev = scr->fbdev;
+ struct cons_buf *bp;
+
+ for (size_t i = 0; i < fbdev.height * fbdev.pitch; ++i) {
+ scr->fb_mem[i] = bg;
+ }
+
+ bp = scr->ob[scr->nrows - 1];
+ bp->flags |= CONS_BUF_CLEAN;
+}
+
/*
* Character device function.
*/
@@ -153,16 +244,87 @@ dev_write(dev_t dev, struct sio_txn *sio, int flags)
char *p;
p = sio->buf;
- spinlock_acquire(&g_root_scr.lock);
for (size_t i = 0; i < sio->len; ++i) {
cons_putch(&g_root_scr, p[i]);
}
+ cons_flush(&g_root_scr);
+ return sio->len;
+}
+
+/*
+ * Character device function.
+ */
+static int
+dev_read(dev_t dev, struct sio_txn *sio, int flags)
+{
+ struct cons_input input;
+ uint8_t *p;
+ int retval;
+ size_t n;
+
+ p = (uint8_t *)sio->buf;
+ n = sio->len;
+
+ /* Must be a power of two */
+ if ((n & 1) != 0) {
+ return -EFAULT;
+ }
+
+ retval = cons_ibuf_pop(&g_root_scr, &input);
+ if (retval < 0) {
+ return -EAGAIN;
+ }
+
+ spinlock_acquire(&g_root_scr.lock);
+ for (;;) {
+ /* Buffer too small */
+ if (n == 0) {
+ break;
+ }
+
+ *p++ = input.chr;
+ *p++ = input.scancode;
+ n -= 2;
+
+ /* Try to get the next byte */
+ retval = cons_ibuf_pop(&g_root_scr, &input);
+ if (retval < 0) {
+ break;
+ }
+ }
spinlock_release(&g_root_scr.lock);
return sio->len;
}
+static int
+cons_init_bufs(struct cons_screen *scr)
+{
+ struct cons_buf *bp;
+ size_t ob_len;
+
+ scr->ib = cons_new_buf(CONS_BUF_INPUT, scr->ncols);
+ if (g_root_scr.ib == NULL) {
+ panic("out of memory\n");
+ }
+
+ ob_len = sizeof(*scr->ob) * scr->nrows;
+ scr->ob = dynalloc(ob_len);
+
+ /* Allocate all output buffers per line */
+ for (size_t i = 0; i < scr->nrows; ++i) {
+ bp = cons_new_buf(CONS_BUF_OUTPUT, scr->ncols);
+ if (bp == NULL) {
+ panic("out of memory\n");
+ }
+ bp->flags |= CONS_BUF_CLEAN;
+ scr->ob[i] = bp;
+ }
+
+ return 0;
+}
+
/*
* Put a character on the screen.
*
@@ -172,44 +334,48 @@ dev_write(dev_t dev, struct sio_txn *sio, int flags)
int
cons_putch(struct cons_screen *scr, char c)
{
- struct cons_char cons_chr;
+ struct cons_buf *bp;
+ struct cons_char cc;
+ size_t max_width;
- if (scr->ch_col > scr->ncols) {
- /* Make a newline as we past the max col */
- scr->ch_col = 0;
- ++scr->ch_row;
- }
-
- if (scr->curs_row >= scr->nrows) {
- /* Went over the screen size */
- /* TODO: Scroll instead of just clearing the screen */
- scr->ch_col = 0;
- scr->ch_row = 0;
- cons_clear_scr(scr, scr->bg);
-
- scr->curs_col = 0;
- scr->curs_row = 0;
- cons_draw_cursor(scr, scr->last_chr.fg);
- }
+ spinlock_acquire(&scr->lock);
- /*
- * If this is a special char that we can handle
- * then handle it and return.
- */
+ /* Handle specials */
if (cons_handle_special(scr, c) == 0) {
- return 0;
+ goto done;
}
- cons_chr = cons_make_char(c, scr->fg, scr->bg);
- scr->last_chr = cons_chr;
+ HIDE_CURSOR(scr);
- /* Draw cursor and character */
- scr->curs_col++;
- cons_draw_cursor(scr, scr->last_chr.fg);
- cons_draw_char(scr, cons_chr, scr->ch_col * FONT_WIDTH,
- scr->ch_row * FONT_HEIGHT);
+ /* Create a new character */
+ cc.c = c;
+ cc.fg = scr->fg;
+ cc.bg = scr->bg;
+ cc.x = scr->ch_col * FONT_WIDTH;
+ cc.y = scr->ch_row * FONT_HEIGHT;
+ /* Push our new character */
+ bp = scr->ob[scr->ch_row];
+ bp->flags &= ~CONS_BUF_CLEAN;
+ cons_obuf_push(bp, cc);
++scr->ch_col;
+
+ /* Check screen bounds */
+ max_width = scr->ncols * FONT_WIDTH;
+ if (cc.x >= max_width - 1) {
+ scr->ch_col = 0;
+ ++scr->ch_row;
+ }
+
+ ++scr->curs_col;
+ if (scr->curs_col > scr->ncols - 1) {
+ scr->curs_col = 0;
+ if (scr->curs_row < scr->nrows)
+ ++scr->curs_row;
+ }
+ SHOW_CURSOR(scr);
+done:
+ spinlock_release(&scr->lock);
return 0;
}
@@ -218,13 +384,17 @@ cons_init(void)
{
struct fbdev fbdev = fbdev_get();
- g_root_scr.fg = 0x00AA00;
- g_root_scr.bg = 0x000000;
+ g_root_scr.ch_col = 0;
+ g_root_scr.ch_row = 0;
+ g_root_scr.fg = CONSOLE_FG;
+ g_root_scr.bg = CONSOLE_BG;
g_root_scr.fb_mem = fbdev.mem;
g_root_scr.nrows = fbdev.height / FONT_HEIGHT;
g_root_scr.ncols = fbdev.width / FONT_WIDTH;
g_root_scr.fbdev = fbdev;
memset(&g_root_scr.lock, 0, sizeof(g_root_scr.lock));
+ cons_init_bufs(&g_root_scr);
+ SHOW_CURSOR(&g_root_scr);
}
/*
@@ -252,6 +422,6 @@ cons_expose(void)
}
static struct cdevsw cons_cdevsw = {
- .read = noread,
+ .read = dev_read,
.write = dev_write
};
diff --git a/sys/dev/cons/cons_buf.c b/sys/dev/cons/cons_buf.c
new file mode 100644
index 0000000..3bc45a1
--- /dev/null
+++ b/sys/dev/cons/cons_buf.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <dev/cons/consvar.h>
+#include <dev/cons/cons.h>
+#include <vm/dynalloc.h>
+#include <string.h>
+#include <assert.h>
+
+/*
+ * Create a new console buffer.
+ *
+ * @type: Buffer type (CONS_BUF_*)
+ * @len: Max length of buffer.
+ */
+struct cons_buf *
+cons_new_buf(uint8_t type, size_t len)
+{
+ struct cons_buf *bp;
+ size_t alloc_len;
+
+ if ((bp = dynalloc(sizeof(*bp))) == NULL) {
+ return NULL;
+ }
+
+ memset(bp, 0, sizeof(*bp));
+ bp->type = type;
+ bp->len = len;
+
+ /* Create the actual buffers now */
+ switch (type) {
+ case CONS_BUF_INPUT:
+ alloc_len = sizeof(*bp->ibuf) * len;
+ bp->ibuf = dynalloc(alloc_len);
+ break;
+ case CONS_BUF_OUTPUT:
+ alloc_len = sizeof(*bp->obuf) * len;
+ bp->obuf = dynalloc(alloc_len);
+ break;
+ }
+
+ return bp;
+}
+
+/*
+ * Push a character to a console output
+ * buffer.
+ *
+ * @bp: Pointer to console buffer.
+ * @c: Character to push.
+ */
+int
+cons_obuf_push(struct cons_buf *bp, struct cons_char c)
+{
+ uint8_t next;
+
+ if (bp == NULL) {
+ return -EINVAL;
+ }
+
+ __assert(bp->type == CONS_BUF_OUTPUT);
+ next = bp->head + 1;
+ if (next > bp->len) {
+ return -ENOSPC;
+ }
+
+ bp->obuf[bp->head] = c;
+ bp->head = next;
+ return 0;
+}
+
+/*
+ * Pop a character from the console
+ * buffer.
+ *
+ * @bp: Pointer to console buffer.
+ * @res: Result is written here.
+ */
+int
+cons_obuf_pop(struct cons_buf *bp, struct cons_char *res)
+{
+ uint8_t next;
+
+ if (bp == NULL || res == NULL) {
+ return -EINVAL;
+ }
+
+ __assert(bp->type == CONS_BUF_OUTPUT);
+
+ /* Do we have any data left? */
+ if (bp->head == bp->tail) {
+ bp->head = 0;
+ bp->tail = 0;
+ return -EAGAIN;
+ }
+
+ next = bp->tail + 1;
+ if (next > bp->len) {
+ next = 0;
+ }
+
+ *res = bp->obuf[bp->tail];
+ bp->tail = next;
+ return 0;
+}
+
+int
+cons_ibuf_push(struct cons_screen *scr, struct cons_input in)
+{
+ struct cons_buf *bp;
+ uint8_t head_next;
+
+ if (scr == NULL) {
+ return -EINVAL;
+ }
+
+ bp = scr->ib;
+ __assert(bp->type == CONS_BUF_INPUT);
+
+ head_next = bp->head + 1;
+ if (head_next > bp->len) {
+ return -ENOSPC;
+ }
+
+ bp->ibuf[bp->head] = in;
+ bp->head = head_next;
+ return 0;
+}
+
+int
+cons_ibuf_pop(struct cons_screen *scr, struct cons_input *res)
+{
+ uint8_t tail_next;
+ struct cons_buf *bp;
+
+ if (scr == NULL || res == NULL) {
+ return -EINVAL;
+ }
+
+ bp = scr->ib;
+ __assert(bp->type == CONS_BUF_INPUT);
+
+ /* Do we have any data left? */
+ if (bp->head == bp->tail) {
+ bp->head = 0;
+ bp->tail = 0;
+ return -EAGAIN;
+ }
+
+ tail_next = bp->tail + 1;
+ if (tail_next > bp->len) {
+ tail_next = 0;
+ }
+
+ *res = bp->ibuf[bp->tail];
+ bp->tail = tail_next;
+ return 0;
+}
diff --git a/sys/dev/ic/nvme.c b/sys/dev/ic/nvme.c
index 749ac93..6753072 100644
--- a/sys/dev/ic/nvme.c
+++ b/sys/dev/ic/nvme.c
@@ -625,6 +625,10 @@ nvme_init(void)
return -ENODEV;
}
+ pr_trace("NVMe storage ctrl <hba? at pci%d:%x.%x.%d>\n",
+ nvme_dev->bus, nvme_dev->device_id, nvme_dev->func,
+ nvme_dev->slot);
+
/* Try to request a general purpose timer */
if (req_timer(TIMER_GP, &tmr) != TMRR_SUCCESS) {
pr_error("failed to fetch general purpose timer\n");
diff --git a/sys/dev/video/fbdev.c b/sys/dev/video/fbdev.c
index cf4954a..f21c769 100644
--- a/sys/dev/video/fbdev.c
+++ b/sys/dev/video/fbdev.c
@@ -48,5 +48,6 @@ fbdev_get(void)
ret.width = FRAMEBUFFER->width;
ret.height = FRAMEBUFFER->height;
ret.pitch = FRAMEBUFFER->pitch;
+ ret.bpp = FRAMEBUFFER->bpp;
return ret;
}
diff --git a/sys/include/arch/aarch64/cdefs.h b/sys/include/arch/aarch64/cdefs.h
new file mode 100644
index 0000000..a22c436
--- /dev/null
+++ b/sys/include/arch/aarch64/cdefs.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _AARCH64_CDEFS_H_
+#define _AARCH64_CDEFS_H_
+
+#include <sys/cdefs.h>
+#include <machine/sync.h>
+
+#define md_pause() __ASMV("yield")
+#define md_intoff() __ASMV("msr daifset, #2")
+#define md_inton() __ASMV("msr daifclr, #2")
+
+#endif /* !_AARCH64_CDEFS_H_ */
diff --git a/sys/include/arch/aarch64/cpu.h b/sys/include/arch/aarch64/cpu.h
new file mode 100644
index 0000000..a6ccdec
--- /dev/null
+++ b/sys/include/arch/aarch64/cpu.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_CPU_H_
+#define _MACHINE_CPU_H_
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/proc.h>
+
+struct cpu_info {
+ struct proc *curtd;
+ struct cpu_info *self;
+};
+
+void cpu_startup(struct cpu_info *ci);
+void mp_bootstrap_aps(struct cpu_info *ci);
+struct cpu_info *this_cpu(void);
+
+extern struct cpu_info g_bsp_ci;
+
+#endif /* !_MACHINE_CPU_H_ */
diff --git a/sys/include/arch/aarch64/frame.h b/sys/include/arch/aarch64/frame.h
new file mode 100644
index 0000000..ec11533
--- /dev/null
+++ b/sys/include/arch/aarch64/frame.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_FRAME_H_
+#define _MACHINE_FRAME_H_
+
+#include <sys/types.h>
+
+typedef uint64_t lreg_t;
+
+/* General purpose registers */
+struct gpregs {
+ lreg_t x0;
+ lreg_t x1;
+ lreg_t x2;
+ lreg_t x3;
+ lreg_t x4;
+ lreg_t x5;
+ lreg_t x6;
+ lreg_t x7;
+ lreg_t x8;
+ lreg_t x9;
+ lreg_t x10;
+ lreg_t x11;
+ lreg_t x12;
+ lreg_t x13;
+ lreg_t x14;
+ lreg_t x15;
+ lreg_t x16;
+ lreg_t x17;
+ lreg_t x18;
+ lreg_t x19;
+ lreg_t x20;
+ lreg_t x21;
+ lreg_t x22;
+ lreg_t x23;
+ lreg_t x24;
+ lreg_t x25;
+ lreg_t x26;
+ lreg_t x27;
+ lreg_t x28;
+ lreg_t x29;
+ lreg_t x30;
+};
+
+/* Stack regs */
+struct sregs {
+ lreg_t sp_el0;
+ lreg_t sp_el1;
+ lreg_t sp_el2;
+};
+
+/* Program status */
+struct pstat {
+ lreg_t spsr_el1;
+ lreg_t spsr_el2;
+ lreg_t spsr_el3;
+};
+
+struct trapframe {
+ struct gpregs gp;
+ struct sregs stack;
+ struct pstat status;
+ lreg_t elr_el1;
+ lreg_t elr_el2;
+ lreg_t elr_el3;
+ lreg_t pc;
+};
+
+#endif /* !_MACHINE_FRAME_H_ */
diff --git a/sys/include/arch/aarch64/pcb.h b/sys/include/arch/aarch64/pcb.h
new file mode 100644
index 0000000..f9a0b1a
--- /dev/null
+++ b/sys/include/arch/aarch64/pcb.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_PCB_H_
+#define _MACHINE_PCB_H_
+
+#include <sys/types.h>
+#include <vm/pmap.h>
+
+struct pcb {
+ struct vas addrsp;
+};
+
+#endif /* !_MACHINE_PCB_H_ */
diff --git a/sys/include/arch/aarch64/pio.h b/sys/include/arch/aarch64/pio.h
new file mode 100644
index 0000000..4aaeece
--- /dev/null
+++ b/sys/include/arch/aarch64/pio.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_PIO_H_
+#define _MACHINE_PIO_H_
+
+#include <sys/cdefs.h>
+
+#define inb(...) (uint8_t)0
+#define inw(...) (uint16_t)0
+#define inl(...) (uint32_t)0
+#define outb(...) __nothing
+#define outw(...) __nothing
+#define outl(...) __nothing
+
+
+#endif /* _MACHINE_PIO_H_ */
diff --git a/sys/include/arch/aarch64/sync.h b/sys/include/arch/aarch64/sync.h
new file mode 100644
index 0000000..f331f43
--- /dev/null
+++ b/sys/include/arch/aarch64/sync.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_SYNC_H_
+#define _MACHINE_SYNC_H_
+
+int md_sync_all(void);
+
+#endif /* !_MACHINE_SYNC_H_ */
diff --git a/sys/include/arch/aarch64/syscall.h b/sys/include/arch/aarch64/syscall.h
new file mode 100644
index 0000000..84a51e0
--- /dev/null
+++ b/sys/include/arch/aarch64/syscall.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_SYSCALL_H_
+#define _MACHINE_SYSCALL_H_
+
+#if !defined(__ASSEMBLER__)
+__always_inline static inline long
+syscall0(uint64_t code)
+{
+ return 0;
+}
+
+__always_inline static inline long
+syscall1(uint64_t code, uint64_t arg0)
+{
+ return 0;
+}
+
+__always_inline static long inline
+syscall2(uint64_t code, uint64_t arg0, uint64_t arg1)
+{
+ return 0;
+}
+
+__always_inline static inline long
+syscall3(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2)
+{
+ return 0;
+}
+
+__always_inline static inline long
+syscall4(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3)
+{
+ return 0;
+}
+
+__always_inline static inline long
+syscall5(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4)
+{
+ return 0;
+}
+
+__always_inline static inline long
+syscall6(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5)
+{
+ return 0;
+}
+
+#define _SYSCALL_N(a0, a1, a2, a3, a4, a5, a6, name, ...) \
+ name
+
+#define syscall(...) \
+_SYSCALL_N(__VA_ARGS__, syscall6, syscall5, \
+ syscall4, syscall3, syscall2, syscall1, \
+ syscall0)(__VA_ARGS__)
+
+#endif /* !__ASSEMBLER__ */
+#endif /* !_MACHINE_SYSCALL_H_ */
diff --git a/sys/include/arch/aarch64/vas.h b/sys/include/arch/aarch64/vas.h
new file mode 100644
index 0000000..07cd576
--- /dev/null
+++ b/sys/include/arch/aarch64/vas.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_VAS_H_
+#define _MACHINE_VAS_H_
+
+#include <sys/types.h>
+#include <sys/spinlock.h>
+
+/*
+ * VAS structure - describes a virtual address space
+ */
+struct vas {
+ paddr_t ttbr0_el1; /* Lower half */
+ paddr_t ttbr1_el1; /* Higher half */
+ struct spinlock *lock;
+};
+
+#endif /* !_MACHINE_VAS_H_ */
diff --git a/sys/include/arch/amd64/cdefs.h b/sys/include/arch/amd64/cdefs.h
index 98d3f0b..256fd8b 100644
--- a/sys/include/arch/amd64/cdefs.h
+++ b/sys/include/arch/amd64/cdefs.h
@@ -31,7 +31,15 @@
#define _AMD64_CDEFS_H_
#include <sys/cdefs.h>
+#include <machine/sync.h>
-#define md_pause() __ASMV("rep; nop")
+/*
+ * Please use CLI wisely, it is a good idea to use
+ * md_sync_all() after using STI to ensure stable
+ * system operation.
+ */
+#define md_pause() __ASMV("rep; nop") /* (F3 90) PAUSE */
+#define md_intoff() __ASMV("cli") /* Clear interrupts */
+#define md_inton() __ASMV("sti") /* Enable interrupts */
#endif /* !_AMD64_CDEFS_H_ */
diff --git a/sys/include/arch/amd64/cpu.h b/sys/include/arch/amd64/cpu.h
index 716f44a..ce42416 100644
--- a/sys/include/arch/amd64/cpu.h
+++ b/sys/include/arch/amd64/cpu.h
@@ -35,11 +35,14 @@
#include <sys/proc.h>
#include <machine/tss.h>
+#define CPU_IRQ(IRQ_N) (BIT((IRQ_N)) & 0xFF)
+
struct cpu_info {
uint32_t apicid;
uint8_t has_x2apic : 1;
uint8_t ipl;
size_t lapic_tmr_freq;
+ uint8_t irq_mask;
struct tss_entry *tss;
struct proc *curtd;
struct cpu_info *self;
diff --git a/sys/include/arch/amd64/isa/i8042var.h b/sys/include/arch/amd64/isa/i8042var.h
new file mode 100644
index 0000000..ebd96ad
--- /dev/null
+++ b/sys/include/arch/amd64/isa/i8042var.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _I8042VAR_H_
+#define _I8042VAR_H_
+
+#include <sys/param.h>
+
+/* I/O bus ports */
+#define I8042_CMD 0x64
+#define I8042_DATA 0x60
+#define I8042_STATUS 0x64
+
+#define KB_IRQ 1 /* Keyboard IRQ */
+#define I8042_DELAY 20 /* Poll delay (in ms) */
+
+/* i8042 status */
+#define I8042_OBUFF BIT(0) /* Output buffer full */
+#define I8042_IBUFF BIT(1) /* Input buffer full */
+#define I8042_TTO BIT(5) /* Transmit timeout */
+#define I8042_RTO BIT(6) /* Receive timeout */
+#define I8042_PAR BIT(7) /* Parity error */
+
+/* i8042 commands */
+#define I8042_SELF_TEST 0xAA
+#define I8042_DISABLE_PORT0 0xAD
+#define I8042_DISABLE_PORT1 0xA7
+#define I8042_ENABLE_PORT0 0xAE
+#define I8042_ENABLE_PORT1 0xA8
+#define I8042_GET_CONFB 0x20
+#define I8042_SET_CONFB 0x60
+#define I8042_PORT1_SEND 0xD4
+
+/* i8042 config bits */
+#define I8042_PORT0_INTR BIT(0)
+#define I8042_PORT1_INTR BIT(1)
+#define I8042_PORT0_CLK BIT(4)
+#define I8042_PORT1_CLK BIT(5)
+
+/* Aux commands */
+#define I8042_AUX_DEFAULTS 0xF5
+#define I8042_AUX_ENABLE 0xF4
+#define I8042_AUX_DISABLE 0xF5
+#define I8042_AUX_RESET 0xFF
+
+/* LED bits */
+#define I8042_LED_SCROLL BIT(0)
+#define I8042_LED_NUM BIT(1)
+#define I8042_LED_CAPS BIT(2)
+
+/* Quirks */
+#define I8042_HOSTILE BIT(0) /* If EC likes throwing NMIs */
+
+/* Apply a quirk to i8042 */
+void i8042_quirk(int mask);
+
+/* Internal - do not use */
+void i8042_sync(void);
+void i8042_kb_isr(void);
+void i8042_kb_event(void);
+
+#endif /* _I8042VAR_H_ */
diff --git a/sys/include/arch/amd64/isa/spkr.h b/sys/include/arch/amd64/isa/spkr.h
new file mode 100644
index 0000000..2691721
--- /dev/null
+++ b/sys/include/arch/amd64/isa/spkr.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ISA_SPKR_H_
+#define _ISA_SPKR_H_
+
+#include <sys/types.h>
+
+int pcspkr_tone(uint16_t freq, uint32_t msec);
+
+#endif
diff --git a/sys/include/arch/amd64/sync.h b/sys/include/arch/amd64/sync.h
new file mode 100644
index 0000000..f331f43
--- /dev/null
+++ b/sys/include/arch/amd64/sync.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_SYNC_H_
+#define _MACHINE_SYNC_H_
+
+int md_sync_all(void);
+
+#endif /* !_MACHINE_SYNC_H_ */
diff --git a/sys/include/arch/amd64/syscall.h b/sys/include/arch/amd64/syscall.h
new file mode 100644
index 0000000..cc401e9
--- /dev/null
+++ b/sys/include/arch/amd64/syscall.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_SYSCALL_H_
+#define _MACHINE_SYSCALL_H_
+
+#if !defined(__ASSEMBLER__)
+__always_inline static inline long
+syscall0(uint64_t code)
+{
+ volatile long ret;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code));
+ return ret;
+}
+
+__always_inline static inline long
+syscall1(uint64_t code, uint64_t arg0)
+{
+ volatile long ret;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0) : "memory");
+ return ret;
+}
+
+__always_inline static long inline
+syscall2(uint64_t code, uint64_t arg0, uint64_t arg1)
+{
+ volatile long ret;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1) : "memory");
+ return ret;
+}
+
+__always_inline static inline long
+syscall3(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2)
+{
+ volatile long ret;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2) : "memory");
+ return ret;
+}
+
+__always_inline static inline long
+syscall4(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3)
+{
+ volatile long ret;
+ register uint64_t _arg3 asm("r10") = arg3;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3) : "memory");
+ return ret;
+}
+
+__always_inline static inline long
+syscall5(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4)
+{
+ volatile long ret;
+ register uint64_t _arg3 asm("r10") = arg3;
+ register uint64_t _arg4 asm("r9") = arg4;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3), "r"(_arg4) : "memory");
+ return ret;
+}
+
+__always_inline static inline long
+syscall6(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5)
+{
+ volatile long ret;
+ register uint64_t _arg3 asm("r10") = arg3;
+ register uint64_t _arg4 asm("r9") = arg4;
+ register uint64_t _arg5 asm("r8") = arg5;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5) : "memory");
+ return ret;
+}
+
+#define _SYSCALL_N(a0, a1, a2, a3, a4, a5, a6, name, ...) \
+ name
+
+#define syscall(...) \
+_SYSCALL_N(__VA_ARGS__, syscall6, syscall5, \
+ syscall4, syscall3, syscall2, syscall1, \
+ syscall0)(__VA_ARGS__)
+
+#endif /* !__ASSEMBLER__ */
+#endif /* !_MACHINE_SYSCALL_H_ */
diff --git a/sys/include/dev/acpi/acpi.h b/sys/include/dev/acpi/acpi.h
index 3e04d5d..9cd6b87 100644
--- a/sys/include/dev/acpi/acpi.h
+++ b/sys/include/dev/acpi/acpi.h
@@ -30,6 +30,7 @@
#ifndef _ACPI_H_
#define _ACPI_H_
+const char *acpi_oemid(void);
void *acpi_query(const char *query);
void acpi_init(void);
diff --git a/sys/include/dev/cons/cons.h b/sys/include/dev/cons/cons.h
index 8e2c2c6..3569c52 100644
--- a/sys/include/dev/cons/cons.h
+++ b/sys/include/dev/cons/cons.h
@@ -33,11 +33,14 @@
#include <sys/types.h>
#include <sys/spinlock.h>
#include <dev/video/fbdev.h>
+#include <dev/cons/consvar.h>
struct cons_char {
char c;
uint32_t fg;
uint32_t bg;
+ uint32_t x;
+ uint32_t y;
};
struct cons_screen {
@@ -53,6 +56,8 @@ struct cons_screen {
uint32_t ch_row; /* Current row */
uint32_t curs_col; /* Cursor col */
uint32_t curs_row; /* Cursor row */
+ struct cons_buf *ib; /* Input buffer */
+ struct cons_buf **ob; /* Output buffers */
struct cons_char last_chr;
struct spinlock lock;
};
diff --git a/sys/include/dev/cons/consvar.h b/sys/include/dev/cons/consvar.h
new file mode 100644
index 0000000..483d5f1
--- /dev/null
+++ b/sys/include/dev/cons/consvar.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_CONSVAR_H_
+#define _DEV_CONSVAR_H_
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+/* Buffer types */
+#define CONS_BUF_INPUT 0
+#define CONS_BUF_OUTPUT 1
+
+/* Buffer flags */
+#define CONS_BUF_CLEAN BIT(0) /* Not recently written to */
+
+extern struct cons_screen scr;
+
+/*
+ * The keyboard packet is two bytes
+ * and the bits are as follows:
+ *
+ * - 0:7 ~ ASCII character
+ * - 8:15 ~ Scancode
+ */
+struct cons_input {
+ union {
+ uint8_t chr;
+ uint8_t scancode;
+ };
+ uint16_t data;
+};
+
+/*
+ * A circular buffer for buffering
+ * keyboard input or console output.
+ */
+struct cons_buf {
+ union {
+ struct cons_input *ibuf;
+ struct cons_char *obuf;
+ void *raw;
+ };
+ uint8_t tail;
+ uint8_t head;
+ uint8_t type;
+ uint8_t flags;
+ size_t len;
+};
+
+struct cons_buf *cons_new_buf(uint8_t type, size_t len);
+int cons_obuf_push(struct cons_buf *bp, struct cons_char c);
+int cons_obuf_pop(struct cons_buf *bp, struct cons_char *res);
+
+int cons_ibuf_push(struct cons_screen *scr, struct cons_input input);
+int cons_ibuf_pop(struct cons_screen *scr, struct cons_input *res);
+
+#endif /* !_DEV_CONSVAR_H_ */
diff --git a/sys/include/dev/video/fbdev.h b/sys/include/dev/video/fbdev.h
index d23fcd6..c80fd92 100644
--- a/sys/include/dev/video/fbdev.h
+++ b/sys/include/dev/video/fbdev.h
@@ -38,6 +38,7 @@ struct fbdev {
uint32_t width;
uint32_t height;
uint32_t pitch;
+ uint32_t bpp;
};
/*
diff --git a/sys/include/sys/atomic.h b/sys/include/sys/atomic.h
index 1cc0e1c..f61bf62 100644
--- a/sys/include/sys/atomic.h
+++ b/sys/include/sys/atomic.h
@@ -54,12 +54,44 @@ atomic_sub_int_nv(volatile unsigned int *p, unsigned int v)
return __sync_sub_and_fetch(p, v);
}
+static inline unsigned int
+atomic_load_int_nv(volatile unsigned int *p, unsigned int v)
+{
+ return __atomic_load_n(p, v);
+}
+
+static inline unsigned int
+atomic_load_long_nv(volatile unsigned long *p, unsigned int v)
+{
+ return __atomic_load_n(p, v);
+}
+
+static inline void
+atomic_store_int_nv(volatile unsigned int *p, int nv, unsigned int v)
+{
+ __atomic_store_n(p, nv, v);
+}
+
+static inline void
+atomic_store_long_nv(volatile unsigned long *p, long nv, unsigned int v)
+{
+ __atomic_store_n(p, nv, v);
+}
+
/* Atomic increment (and fetch) operations */
-#define atoimc_inc_long(P) atomic_add_long_nv((P), 1)
+#define atomic_inc_long(P) atomic_add_long_nv((P), 1)
#define atomic_inc_int(P) atomic_add_int_nv((P), 1)
/* Atomic decrement (and fetch) operations */
#define atomic_dec_long(P) atomic_sub_long_nv((P), 1)
#define atomic_dec_int(P) atomic_sub_int_nv((P), 1)
+/* Atomic load operations */
+#define atomic_load_int(P) atomic_load_int_nv((P), __ATOMIC_SEQ_CST)
+#define atomic_load_long(P) atomic_load_long_nv((P), __ATOMIC_SEQ_CST)
+
+/* Atomic store operations */
+#define atomic_store_int(P, NV) atomic_store_int_nv((P), (NV), __ATOMIC_SEQ_CST)
+#define atomic_store_long(P, NV) atomic_store_long_nv((P), (NV), __ATOMIC_SEQ_CST)
+
#endif /* !_SYS_ATOMIC_H_ */
diff --git a/sys/include/sys/schedvar.h b/sys/include/sys/schedvar.h
index cafc9ab..509e2c9 100644
--- a/sys/include/sys/schedvar.h
+++ b/sys/include/sys/schedvar.h
@@ -36,7 +36,7 @@
#include <machine/cdefs.h>
#if defined(_KERNEL)
-#define DEFAULT_TIMESLICE_USEC 1050
+#define DEFAULT_TIMESLICE_USEC 500
#define SHORT_TIMESLICE_USEC 10
#define SCHED_POLICY_MLFQ 0x00U /* Multilevel feedback queue */
diff --git a/sys/include/sys/spinlock.h b/sys/include/sys/spinlock.h
index c136e05..140addc 100644
--- a/sys/include/sys/spinlock.h
+++ b/sys/include/sys/spinlock.h
@@ -33,15 +33,20 @@
#include <sys/types.h>
struct spinlock {
- volatile bool lock;
+ volatile int lock;
};
#if defined(_KERNEL)
void spinlock_acquire(struct spinlock *lock);
void spinlock_release(struct spinlock *lock);
+
+int spinlock_try_acquire(struct spinlock *lock);
int spinlock_usleep(struct spinlock *lock, size_t usec_max);
+/* System-wide locking (be careful!!) */
+int syslock(void);
+void sysrel(void);
#endif
#endif /* !_SYS_SPINLOCK_H_ */
diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h
index 41d1e78..3f3a8b3 100644
--- a/sys/include/sys/syscall.h
+++ b/sys/include/sys/syscall.h
@@ -33,7 +33,8 @@
#if !defined(__ASSEMBLER__)
#include <sys/types.h>
#include <sys/cdefs.h>
-#endif /* !__ASSEMBLER__ */
+#include <machine/syscall.h>
+#endif
#define SYS_none 0
#define SYS_exit 1
@@ -64,76 +65,4 @@ extern const size_t MAX_SYSCALLS;
extern scret_t(*g_sctab[])(struct syscall_args *);
#endif /* _KERNEL */
-#if !defined(__ASSEMBLER__)
-__always_inline static inline long
-syscall0(uint64_t code)
-{
- volatile long ret;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code));
- return ret;
-}
-
-__always_inline static inline long
-syscall1(uint64_t code, uint64_t arg0)
-{
- volatile long ret;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0) : "memory");
- return ret;
-}
-
-__always_inline static long inline
-syscall2(uint64_t code, uint64_t arg0, uint64_t arg1)
-{
- volatile long ret;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1) : "memory");
- return ret;
-}
-
-__always_inline static inline long
-syscall3(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2)
-{
- volatile long ret;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2) : "memory");
- return ret;
-}
-
-__always_inline static inline long
-syscall4(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3)
-{
- volatile long ret;
- register uint64_t _arg3 asm("r10") = arg3;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3) : "memory");
- return ret;
-}
-
-__always_inline static inline long
-syscall5(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4)
-{
- volatile long ret;
- register uint64_t _arg3 asm("r10") = arg3;
- register uint64_t _arg4 asm("r9") = arg4;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3), "r"(_arg4) : "memory");
- return ret;
-}
-
-__always_inline static inline long
-syscall6(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5)
-{
- volatile long ret;
- register uint64_t _arg3 asm("r10") = arg3;
- register uint64_t _arg4 asm("r9") = arg4;
- register uint64_t _arg5 asm("r8") = arg5;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5) : "memory");
- return ret;
-}
-
-#define _SYSCALL_N(a0, a1, a2, a3, a4, a5, a6, name, ...) \
- name
-
-#define syscall(...) \
-_SYSCALL_N(__VA_ARGS__, syscall6, syscall5, \
- syscall4, syscall3, syscall2, syscall1, \
- syscall0)(__VA_ARGS__)
-
-#endif /* !__ASSEMBLER__ */
#endif /* _SYS_SYSCALL_H_ */
diff --git a/sys/kern/exec_elf64.c b/sys/kern/exec_elf64.c
index c9040dd..3767b0b 100644
--- a/sys/kern/exec_elf64.c
+++ b/sys/kern/exec_elf64.c
@@ -30,6 +30,7 @@
#include <sys/elf.h>
#include <sys/exec.h>
#include <sys/param.h>
+#include <sys/syslog.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/vnode.h>
@@ -42,6 +43,9 @@
#include <string.h>
#include <machine/pcb.h>
+#define pr_trace(fmt, ...) kprintf("elf64: " fmt, ##__VA_ARGS__)
+#define pr_error(...) pr_trace(__VA_ARGS__)
+
#define PHDR(HDRP, IDX) \
(void *)((uintptr_t)HDRP + (HDRP)->e_phoff + (HDRP->e_phentsize * IDX))
@@ -209,6 +213,7 @@ elf64_load(const char *pathname, struct proc *td, struct exec_prog *prog)
/* Try to allocate page frames */
physmem = vm_alloc_frame(page_count);
if (physmem == 0) {
+ pr_error("out of physical memory\n");
status = -ENOMEM;
break;
}
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index f3f88d7..667bb97 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -38,17 +38,25 @@
#include <dev/cons/cons.h>
#include <dev/acpi/acpi.h>
#include <machine/cpu.h>
+#include <machine/cdefs.h>
#include <vm/vm.h>
#include <string.h>
static struct proc proc0;
static void
+copyright(void)
+{
+ kprintf(OMIT_TIMESTAMP
+ "Copyright (c) 2023-2025 Ian Marco Moffett and the OSMORA team\n");
+}
+
+static void
start_init(void)
{
struct proc *td = this_td();
struct execve_args execve_args;
- char *argv[] = { "/usr/sbin/init", NULL };
+ char *argv[] = { "/usr/bin/osh", NULL };
char *envp[] = { NULL };
execve_args.pathname = argv[0];
@@ -56,6 +64,8 @@ start_init(void)
execve_args.envp = envp;
if (execve(td, &execve_args) != 0)
panic("failed to load init\n");
+
+ __builtin_unreachable();
}
int
@@ -64,14 +74,15 @@ main(void)
/* Setup serial driver */
serial_init();
+ /* Init the virtual memory subsystem */
+ vm_init();
+
/* Startup the console */
cons_init();
+ copyright();
kprintf("Starting Hyra/%s v%s: %s\n", HYRA_ARCH, HYRA_VERSION,
HYRA_BUILDDATE);
- /* Init the virtual memory subsystem */
- vm_init();
-
/* Start the ACPI subsystem */
acpi_init();
@@ -81,19 +92,22 @@ main(void)
/* Init the virtual file system */
vfs_init();
- DRIVERS_INIT();
-
/* Expose the console to devfs */
cons_expose();
/* Start scheduler and bootstrap APs */
+ md_intoff();
sched_init();
- mp_bootstrap_aps(&g_bsp_ci);
- /* Startup init */
+ /* Startup pid 1 */
memset(&proc0, 0, sizeof(proc0.tf));
fork1(&proc0, 0, start_init, NULL);
+ /* Load all drivers */
+ DRIVERS_INIT();
+
+ /* Bootstrap APs and here we go! */
+ mp_bootstrap_aps(&g_bsp_ci);
sched_enter();
__builtin_unreachable();
}
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 201db3e..d122e89 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -148,6 +148,7 @@ static int
fd_rw(unsigned int fd, void *buf, size_t count, uint8_t write)
{
char *kbuf = NULL;
+ ssize_t n;
struct filedesc *filedes;
struct sio_txn sio;
scret_t retval = 0;
@@ -194,22 +195,21 @@ fd_rw(unsigned int fd, void *buf, size_t count, uint8_t write)
}
/* Call VFS write hook */
- if ((count = vfs_vop_write(filedes->vp, &sio)) < 0) {
- retval = -EIO;
+ if ((n = vfs_vop_write(filedes->vp, &sio)) < 0) {
+ retval = n;
goto done;
}
} else {
- if ((count = vfs_vop_read(filedes->vp, &sio)) < 0) {
- retval = -EIO;
+ if ((n = vfs_vop_read(filedes->vp, &sio)) < 0) {
+ retval = n;
goto done;
}
- }
- if (copyout(kbuf, buf, count) < 0) {
- retval = -EFAULT;
- goto done;
+ if (copyout(kbuf, buf, count) < 0) {
+ retval = -EFAULT;
+ goto done;
+ }
}
-
retval = count;
done:
if (kbuf != NULL) {
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c
index ca5bfbe..4bbe5a0 100644
--- a/sys/kern/kern_sched.c
+++ b/sys/kern/kern_sched.c
@@ -33,8 +33,10 @@
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/syslog.h>
+#include <sys/atomic.h>
#include <machine/frame.h>
#include <machine/cpu.h>
+#include <machine/cdefs.h>
#include <vm/pmap.h>
#include <dev/timer.h>
#include <assert.h>
@@ -44,7 +46,7 @@
void sched_switch(struct trapframe *tf);
-static sched_policy_t policy = SCHED_POLICY_RR;
+static sched_policy_t policy = SCHED_POLICY_MLFQ;
/*
* Thread ready queues - all threads ready to be
@@ -105,12 +107,14 @@ sched_dequeue_td(void)
if (!TAILQ_EMPTY(&queue->q)) {
td = TAILQ_FIRST(&queue->q);
TAILQ_REMOVE(&queue->q, td, link);
- break;
+ spinlock_release(&tdq_lock);
+ return td;
}
}
+ /* We got nothing */
spinlock_release(&tdq_lock);
- return td;
+ return NULL;
}
/*
@@ -237,6 +241,8 @@ sched_switch(struct trapframe *tf)
void
sched_enter(void)
{
+ md_inton();
+ md_sync_all();
for (;;) {
sched_oneshot(false);
md_pause();
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 2011c61..57b27d0 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/errno.h>
+#include <sys/atomic.h>
#include <sys/syslog.h>
#include <sys/spinlock.h>
#include <dev/timer.h>
@@ -37,6 +38,9 @@
#define pr_trace(fmt, ...) kprintf("synch: " fmt, ##__VA_ARGS__)
#define pr_error(...) pr_trace(__VA_ARGS__)
+/* XXX: Be very careful with this */
+static struct spinlock __syslock;
+
/*
* Returns 0 on success, returns non-zero value
* on timeout/failure.
@@ -79,8 +83,56 @@ spinlock_acquire(struct spinlock *lock)
while (__atomic_test_and_set(&lock->lock, __ATOMIC_ACQUIRE));
}
+/*
+ * Lazy acquire a spinlock
+ *
+ * spinlock_try_acquire() may only spin one thread
+ * at a time, threads that want to spin too must
+ * explicity do it on their own.
+ *
+ * This function returns 1 (a value that may be
+ * spinned on) when the lock is acquired and a
+ * thread is already spinning on it.
+ */
+int
+spinlock_try_acquire(struct spinlock *lock)
+{
+ volatile int locked;
+
+ locked = atomic_load_int(&lock->lock);
+ if (locked != 0) {
+ return 1;
+ }
+
+ while (__atomic_test_and_set(&lock->lock, __ATOMIC_ACQUIRE));
+ return 0;
+}
+
void
spinlock_release(struct spinlock *lock)
{
__atomic_clear(&lock->lock, __ATOMIC_RELEASE);
}
+
+/*
+ * Attempt to hold the system-wide lock, returns 1
+ * if already held.
+ *
+ * XXX: Only use for CRITICAL code sections.
+ */
+int
+syslock(void)
+{
+ return spinlock_try_acquire(&__syslock);
+}
+
+/*
+ * Release the system-wide lock
+ *
+ * XXX: Only use for CRITICAL code sections.
+ */
+void
+sysrel(void)
+{
+ spinlock_release(&__syslock);
+}
diff --git a/tools/kconf/scan.l b/tools/kconf/scan.l
index e9daec0..38cb028 100644
--- a/tools/kconf/scan.l
+++ b/tools/kconf/scan.l
@@ -42,6 +42,7 @@
"yes" { return YES; }
"no" { return NO; }
\"([^\"])*\" { yylval.str = strdup(yytext); return STRING; }
+0[xX][0-9a-fA-F]+ { yylval.str = strdup(yytext); return STRING; }
[a-zA-Z_][a-zA-Z0-9_]+ { yylval.str = strdup(yytext); return IDENTIFIER; }
[0-9]+ { yylval.num = atoi(yytext); return NUMBER; }
[ \t] { /* Ignore */ }
diff --git a/tools/taptest b/tools/taptest
new file mode 100755
index 0000000..aedfbf6
--- /dev/null
+++ b/tools/taptest
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+arping -b -c 3 -I tap0 192.168.10.255
diff --git a/usr.bin/link.ld b/usr.bin/link.ld
new file mode 100644
index 0000000..9fad881
--- /dev/null
+++ b/usr.bin/link.ld
@@ -0,0 +1,26 @@
+ENTRY(_start)
+
+SECTIONS
+{
+ . = 0x10000;
+
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ }
+
+ .data : ALIGN(8)
+ {
+ *(.data)
+ *(.data.*)
+ }
+
+ .bss : ALIGN(8)
+ {
+ __bss_start = .;
+ *(.bss)
+ *(.bss.*)
+ __bss_end = .;
+ }
+}
diff --git a/usr.bin/osh/Makefile b/usr.bin/osh/Makefile
new file mode 100644
index 0000000..28981fe
--- /dev/null
+++ b/usr.bin/osh/Makefile
@@ -0,0 +1,6 @@
+include user.mk
+
+CFILES = $(shell find . -name "*.c")
+
+osh:
+ $(CC) $(CFILES) -o $@ $(INTERNAL_CFLAGS)
diff --git a/usr.bin/osh/osh.c b/usr.bin/osh/osh.c
new file mode 100644
index 0000000..dea4b3f
--- /dev/null
+++ b/usr.bin/osh/osh.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <string.h>
+
+#define prcons(FD, STR) write((FD), (STR), strlen((STR)))
+#define is_ascii(C) ((C) >= 0 && (C) <= 128)
+#define WELCOME \
+ ":::::::::::::::::::::::::::::::::::::::\n" \
+ ":: OSMORA GATEWAY ~ Every key echos ::\n" \
+ ":: ..... Proceed with purpose ..... ::\n" \
+ ":::::::::::::::::::::::::::::::::::::::\n"
+
+#define CMD_ECHO "echo"
+
+static char buf[64];
+static uint8_t i;
+
+static void
+cmd_run(int fd)
+{
+ int cmp;
+ char *p = buf;
+ size_t len;
+ int valid_cmd = 1;
+
+ switch (buf[0]) {
+ case 'e':
+ len = strlen(CMD_ECHO);
+ if (memcmp(buf, CMD_ECHO, len) == 0) {
+ p += len + 1;
+ prcons(fd, "\n");
+ prcons(fd, p);
+ break;
+ }
+
+ valid_cmd = 0;
+ break;
+ default:
+ valid_cmd = 0;
+ break;
+ }
+
+ if (!valid_cmd) {
+ prcons(fd, "\nunrecognized command\n");
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int fd;
+ uint16_t input;
+ char c;
+
+ if ((fd = open("/dev/console", O_RDWR)) < 0) {
+ return fd;
+ }
+
+ i = 0;
+ prcons(fd, WELCOME);
+ prcons(fd, "[root::osmora]~ ");
+ for (;;) {
+ if (read(fd, &input, 2) <= 0) {
+ continue;
+ }
+
+ c = input & 0xFF;
+ if (!is_ascii(c)) {
+ continue;
+ }
+
+ if (i < sizeof(buf)) {
+ buf[i++] = c;
+ buf[i] = 0;
+ }
+ if (c == '\n') {
+ cmd_run(fd);
+ i = 0;
+ buf[i] = 0;
+ prcons(fd, "[root::osmora]~ ");
+ } else {
+ write(fd, &c, 1);
+ }
+ }
+ return 0;
+}