diff options
373 files changed, 3811 insertions, 56529 deletions
@@ -1,38 +1,4 @@ -build
-orange
-orange.iso
-obj
-serial.txt
-trash
-.code
-serial_output.txt
-kernel-deps
-/limine
-initrd/usr/include
-kernel/bin
-kernel/cc-runtime
-kernel/cc-runtime-x86_64
-kernel/freestnd-c-hdrs
-kernel/freestnd-cxx-hdrs
-main.o
-.jinx-cache
-serial.txt
-output.txt
-Orange-distro-build
-ovmf
-cached
-.vscode
-initrd/usr/lib
-initrd/usr/include
-initrd
-orange-mlibc
-sources
-./initrd
-qemu_log.txt
-orange.hdd
-./tools/toolchain/pack
-pack
-initrd.tar
-qemu.txt
-build-x86_64
-linux-headers
\ No newline at end of file +/limine +/edk2-ovmf +*.iso +*.hdd
\ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..2ab02f8 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,17 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "${workspaceFolder}/kernel/uacpi/include" + ], + "defines": [], + "compilerPath": "/usr/bin/clang", + "cStandard": "c17", + "cppStandard": "c++17", + "intelliSenseMode": "linux-clang-x64" + } + ], + "version": 4 +}
\ No newline at end of file diff --git a/GNUmakefile b/GNUmakefile index 1bb2758..97c4632 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,15 +1,17 @@ -# Nuke built-in rules and variables. -MAKEFLAGS += -rR +# Nuke built-in rules. .SUFFIXES: +# Target architecture to build for. Default to x86_64. +ARCH := x86_64 + # Default user QEMU flags. These are appended to the QEMU command calls. -QEMUFLAGS := -m 8G -d int -s -M q35 -smp 1 -enable-kvm -serial stdio -cpu host,+invtsc +QEMUFLAGS := -m 256M -d int -no-reboot -override IMAGE_NAME := orange +override IMAGE_NAME := orange-$(ARCH) # Toolchain for building the 'limine' executable for the host. HOST_CC := cc -HOST_CFLAGS := -g -O2 -pipe +HOST_CFLAGS := -g -O2 -pipe HOST_CPPFLAGS := HOST_LDFLAGS := HOST_LIBS := @@ -21,44 +23,128 @@ all: $(IMAGE_NAME).iso all-hdd: $(IMAGE_NAME).hdd .PHONY: run -run: $(IMAGE_NAME).iso - qemu-system-x86_64 \ +run: run-$(ARCH) + +.PHONY: run-hdd +run-hdd: run-hdd-$(ARCH) + +.PHONY: run-x86_64 +run-x86_64: edk2-ovmf $(IMAGE_NAME).iso + qemu-system-$(ARCH) \ + -enable-kvm \ -M q35 \ + -drive if=pflash,unit=0,format=raw,file=edk2-ovmf/ovmf-code-$(ARCH).fd,readonly=on \ -cdrom $(IMAGE_NAME).iso \ - -boot d \ $(QEMUFLAGS) -.PHONY: run-uefi -run-uefi: ovmf/ovmf-code-x86_64.fd $(IMAGE_NAME).iso - qemu-system-x86_64 \ +.PHONY: run-hdd-x86_64 +run-hdd-x86_64: edk2-ovmf $(IMAGE_NAME).hdd + qemu-system-$(ARCH) \ -M q35 \ - -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-x86_64.fd,readonly=on \ + -drive if=pflash,unit=0,format=raw,file=edk2-ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -hda $(IMAGE_NAME).hdd \ + $(QEMUFLAGS) + +.PHONY: run-aarch64 +run-aarch64: edk2-ovmf $(IMAGE_NAME).iso + qemu-system-$(ARCH) \ + -M virt \ + -cpu cortex-a72 \ + -device ramfb \ + -device qemu-xhci \ + -device usb-kbd \ + -device usb-mouse \ + -drive if=pflash,unit=0,format=raw,file=edk2-ovmf/ovmf-code-$(ARCH).fd,readonly=on \ -cdrom $(IMAGE_NAME).iso \ - -boot d \ $(QEMUFLAGS) -.PHONY: run-hdd -run-hdd: $(IMAGE_NAME).hdd - qemu-system-x86_64 \ - -M q35 \ +.PHONY: run-hdd-aarch64 +run-hdd-aarch64: edk2-ovmf $(IMAGE_NAME).hdd + qemu-system-$(ARCH) \ + -M virt \ + -cpu cortex-a72 \ + -device ramfb \ + -device qemu-xhci \ + -device usb-kbd \ + -device usb-mouse \ + -drive if=pflash,unit=0,format=raw,file=edk2-ovmf/ovmf-code-$(ARCH).fd,readonly=on \ -hda $(IMAGE_NAME).hdd \ $(QEMUFLAGS) -.PHONY: run-hdd-uefi -run-hdd-uefi: ovmf/ovmf-code-x86_64.fd $(IMAGE_NAME).hdd - qemu-system-x86_64 \ +.PHONY: run-riscv64 +run-riscv64: edk2-ovmf $(IMAGE_NAME).iso + qemu-system-$(ARCH) \ + -M virt \ + -cpu rv64 \ + -device ramfb \ + -device qemu-xhci \ + -device usb-kbd \ + -device usb-mouse \ + -drive if=pflash,unit=0,format=raw,file=edk2-ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -cdrom $(IMAGE_NAME).iso \ + $(QEMUFLAGS) + +.PHONY: run-hdd-riscv64 +run-hdd-riscv64: edk2-ovmf $(IMAGE_NAME).hdd + qemu-system-$(ARCH) \ + -M virt \ + -cpu rv64 \ + -device ramfb \ + -device qemu-xhci \ + -device usb-kbd \ + -device usb-mouse \ + -drive if=pflash,unit=0,format=raw,file=edk2-ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -hda $(IMAGE_NAME).hdd \ + $(QEMUFLAGS) + +.PHONY: run-loongarch64 +run-loongarch64: edk2-ovmf $(IMAGE_NAME).iso + qemu-system-$(ARCH) \ + -M virt \ + -cpu la464 \ + -device ramfb \ + -device qemu-xhci \ + -device usb-kbd \ + -device usb-mouse \ + -drive if=pflash,unit=0,format=raw,file=edk2-ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -cdrom $(IMAGE_NAME).iso \ + $(QEMUFLAGS) + +.PHONY: run-hdd-loongarch64 +run-hdd-loongarch64: edk2-ovmf $(IMAGE_NAME).hdd + qemu-system-$(ARCH) \ + -M virt \ + -cpu la464 \ + -device ramfb \ + -device qemu-xhci \ + -device usb-kbd \ + -device usb-mouse \ + -drive if=pflash,unit=0,format=raw,file=edk2-ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -hda $(IMAGE_NAME).hdd \ + $(QEMUFLAGS) + + +.PHONY: run-bios +run-bios: $(IMAGE_NAME).iso + qemu-system-$(ARCH) \ + -M q35 \ + -cdrom $(IMAGE_NAME).iso \ + -boot d \ + $(QEMUFLAGS) + +.PHONY: run-hdd-bios +run-hdd-bios: $(IMAGE_NAME).hdd + qemu-system-$(ARCH) \ -M q35 \ - -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-x86_64.fd,readonly=on \ -hda $(IMAGE_NAME).hdd \ $(QEMUFLAGS) -ovmf/ovmf-code-x86_64.fd: - mkdir -p ovmf - curl -Lo $@ https://github.com/osdev0/edk2-ovmf-nightly/releases/latest/download/ovmf-code-x86_64.fd +edk2-ovmf: + curl -L https://github.com/osdev0/edk2-ovmf-nightly/releases/latest/download/edk2-ovmf.tar.gz | gunzip | tar -xf - limine/limine: rm -rf limine - git clone https://github.com/limine-bootloader/limine.git --branch=v9.x-binary --depth=1 + git clone https://codeberg.org/Limine/Limine.git limine --branch=v10.x-binary --depth=1 $(MAKE) -C limine \ CC="$(HOST_CC)" \ CFLAGS="$(HOST_CFLAGS)" \ @@ -66,22 +152,22 @@ limine/limine: LDFLAGS="$(HOST_LDFLAGS)" \ LIBS="$(HOST_LIBS)" -kernel-deps: - ./kernel/get-deps . +kernel/.deps-obtained: + ./kernel/get-deps .PHONY: kernel -kernel: kernel-deps - rm -rf kernel/src/lib/uACPI/tests +kernel: kernel/.deps-obtained $(MAKE) -C kernel $(IMAGE_NAME).iso: limine/limine kernel rm -rf iso_root mkdir -p iso_root/boot - cp -rf tools/base/* iso_root - cp -v kernel/bin/kernel iso_root/boot/ + cp -v kernel/bin-$(ARCH)/kernel iso_root/boot/ mkdir -p iso_root/boot/limine - cp -v tools/limine.conf limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/boot/limine/ + cp -v limine.conf iso_root/boot/limine/ mkdir -p iso_root/EFI/BOOT +ifeq ($(ARCH),x86_64) + cp -v limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/boot/limine/ cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT/ cp -v limine/BOOTIA32.EFI iso_root/EFI/BOOT/ xorriso -as mkisofs -R -r -J -b boot/limine/limine-bios-cd.bin \ @@ -90,19 +176,63 @@ $(IMAGE_NAME).iso: limine/limine kernel -efi-boot-part --efi-boot-image --protective-msdos-label \ iso_root -o $(IMAGE_NAME).iso ./limine/limine bios-install $(IMAGE_NAME).iso +endif +ifeq ($(ARCH),aarch64) + cp -v limine/limine-uefi-cd.bin iso_root/boot/limine/ + cp -v limine/BOOTAA64.EFI iso_root/EFI/BOOT/ + xorriso -as mkisofs -R -r -J \ + -hfsplus -apm-block-size 2048 \ + --efi-boot boot/limine/limine-uefi-cd.bin \ + -efi-boot-part --efi-boot-image --protective-msdos-label \ + iso_root -o $(IMAGE_NAME).iso +endif +ifeq ($(ARCH),riscv64) + cp -v limine/limine-uefi-cd.bin iso_root/boot/limine/ + cp -v limine/BOOTRISCV64.EFI iso_root/EFI/BOOT/ + xorriso -as mkisofs -R -r -J \ + -hfsplus -apm-block-size 2048 \ + --efi-boot boot/limine/limine-uefi-cd.bin \ + -efi-boot-part --efi-boot-image --protective-msdos-label \ + iso_root -o $(IMAGE_NAME).iso +endif +ifeq ($(ARCH),loongarch64) + cp -v limine/limine-uefi-cd.bin iso_root/boot/limine/ + cp -v limine/BOOTLOONGARCH64.EFI iso_root/EFI/BOOT/ + xorriso -as mkisofs -R -r -J \ + -hfsplus -apm-block-size 2048 \ + --efi-boot boot/limine/limine-uefi-cd.bin \ + -efi-boot-part --efi-boot-image --protective-msdos-label \ + iso_root -o $(IMAGE_NAME).iso +endif rm -rf iso_root $(IMAGE_NAME).hdd: limine/limine kernel rm -f $(IMAGE_NAME).hdd dd if=/dev/zero bs=1M count=0 seek=64 of=$(IMAGE_NAME).hdd +ifeq ($(ARCH),x86_64) PATH=$$PATH:/usr/sbin:/sbin sgdisk $(IMAGE_NAME).hdd -n 1:2048 -t 1:ef00 -m 1 ./limine/limine bios-install $(IMAGE_NAME).hdd +else + PATH=$$PATH:/usr/sbin:/sbin sgdisk $(IMAGE_NAME).hdd -n 1:2048 -t 1:ef00 +endif mformat -i $(IMAGE_NAME).hdd@@1M mmd -i $(IMAGE_NAME).hdd@@1M ::/EFI ::/EFI/BOOT ::/boot ::/boot/limine - mcopy -i $(IMAGE_NAME).hdd@@1M kernel/bin/kernel ::/boot - mcopy -i $(IMAGE_NAME).hdd@@1M limine.conf limine/limine-bios.sys ::/boot/limine + mcopy -i $(IMAGE_NAME).hdd@@1M kernel/bin-$(ARCH)/kernel ::/boot + mcopy -i $(IMAGE_NAME).hdd@@1M limine.conf ::/boot/limine +ifeq ($(ARCH),x86_64) + mcopy -i $(IMAGE_NAME).hdd@@1M limine/limine-bios.sys ::/boot/limine mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTX64.EFI ::/EFI/BOOT mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTIA32.EFI ::/EFI/BOOT +endif +ifeq ($(ARCH),aarch64) + mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTAA64.EFI ::/EFI/BOOT +endif +ifeq ($(ARCH),riscv64) + mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTRISCV64.EFI ::/EFI/BOOT +endif +ifeq ($(ARCH),loongarch64) + mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTLOONGARCH64.EFI ::/EFI/BOOT +endif .PHONY: clean clean: @@ -110,6 +240,6 @@ clean: rm -rf iso_root $(IMAGE_NAME).iso $(IMAGE_NAME).hdd .PHONY: distclean -distclean: clean +distclean: $(MAKE) -C kernel distclean - rm -rf kernel-deps limine ovmf + rm -rf iso_root *.iso *.hdd limine edk2-ovmf diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 73e3d40..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 cppLover0 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/build-cross.sh b/build-cross.sh deleted file mode 100644 index 388e08b..0000000 --- a/build-cross.sh +++ /dev/null @@ -1,7 +0,0 @@ - -export PATH="$HOME/opt/cross/orange/bin:$PATH" - -#sh build-pkg.sh 0/glibc -cd tools -sh toolchain-build.sh "$(realpath ../)" -cd ../
\ No newline at end of file diff --git a/build-pkg.sh b/build-pkg.sh deleted file mode 100644 index da83519..0000000 --- a/build-pkg.sh +++ /dev/null @@ -1,18 +0,0 @@ - -sysroot_path="$(realpath initrd)" - -export PATH="$HOME/opt/cross/orange/bin:$PATH" - -export PKG_CONFIG_SYSROOT_DIR="$sysroot_path" -export PKG_CONFIG_PATH="$sysroot_path/usr/lib/pkgconfig:$sysroot_path/usr/share/pkgconfig:$sysroot_path/usr/local/lib/pkgconfig:$sysroot_path/usr/local/share/pkgconfig:$HOME/opt/cross/orange/lib/pkgconfig:$HOME/opt/cross/orange/share/pkgconfig" -INITRDDIR=""$(realpath initrd)"" - -export CFLAGS="-fPIC -Wno-error -O3 -Wno-array-bounds -Wno-int-conversion -Wno-incompatible-pointer-types -Wno-implicit-function-declaration -fno-omit-frame-pointer -ggdb3 -fno-inline-functions-called-once -fno-optimize-sibling-calls -fno-omit-frame-pointer" -export CXXFLAGS="$CFLAGS" - -cd tools/pkg/$1 -sh pkg.sh "$INITRDDIR" -cd ../../../../ - -mkdir -p tools/base/boot -sudo tar -cf tools/base/boot/initrd.tar -C initrd . diff --git a/clone-submodules.sh b/clone-submodules.sh deleted file mode 100644 index db81188..0000000 --- a/clone-submodules.sh +++ /dev/null @@ -1,2 +0,0 @@ -cd kernel/src/lib -git clone https://github.com/uACPI/uACPI.git --depth=1
\ No newline at end of file diff --git a/kernel/.gitignore b/kernel/.gitignore index 02b03b6..d620100 100644 --- a/kernel/.gitignore +++ b/kernel/.gitignore @@ -1,9 +1,13 @@ /compile_commands.json /.cache +/.deps-obtained /freestnd-c-hdrs /freestnd-cxx-hdrs /cc-runtime -/src/limine.h -/bin -/obj - +/limine-protocol +/bin-* +/obj-* +/nanoprintf +/uacpi +/flanterm +/stb
\ No newline at end of file diff --git a/kernel/GNUmakefile b/kernel/GNUmakefile index 81cd633..3061328 100644 --- a/kernel/GNUmakefile +++ b/kernel/GNUmakefile @@ -1,25 +1,52 @@ -# Nuke built-in rules and variables. -MAKEFLAGS += -rR +# Nuke built-in rules. .SUFFIXES: # This is the name that our final executable will have. # Change as needed. override OUTPUT := kernel +# Target architecture to build for. Default to x86_64. +ARCH := x86_64 + # Install prefix; /usr/local is a good, standard default pick. PREFIX := /usr/local +# Check if the architecture is supported. +ifeq ($(filter $(ARCH),aarch64 loongarch64 riscv64 x86_64),) + $(error Architecture $(ARCH) not supported) +endif + +# User controllable toolchain and toolchain prefix. +TOOLCHAIN := +TOOLCHAIN_PREFIX := +ifneq ($(TOOLCHAIN),) + ifeq ($(TOOLCHAIN_PREFIX),) + TOOLCHAIN_PREFIX := $(TOOLCHAIN)- + endif +endif + # User controllable C compiler command. -CC := cc +ifneq ($(TOOLCHAIN_PREFIX),) + CC := $(TOOLCHAIN_PREFIX)gcc +else + CC := cc +endif # User controllable C++ compiler command. -CXX := c++ +CXX := $(TOOLCHAIN_PREFIX)c++ # User controllable linker command. -LD := ld +LD := $(TOOLCHAIN_PREFIX)ld + +# Defaults overrides for variables if using "llvm" as toolchain. +ifeq ($(TOOLCHAIN),llvm) + CC := clang + CXX := clang++ + LD := ld.lld +endif # User controllable C flags. -CFLAGS := -g -pipe -Iinclude -Isrc/lib/Flanterm/src -Isrc/lib/uACPI/include -O3 -w +CFLAGS := -g -O3 -pipe -Werror -Wall # User controllable C++ flags. We default to same as C flags. CXXFLAGS := $(CFLAGS) @@ -27,74 +54,137 @@ CXXFLAGS := $(CFLAGS) # User controllable C/C++ preprocessor flags. We set none by default. CPPFLAGS := -# User controllable nasm flags. -NASMFLAGS := -F dwarf -g +ifeq ($(ARCH),x86_64) + # User controllable nasm flags. + NASMFLAGS := -g +endif # User controllable linker flags. We set none by default. LDFLAGS := # Ensure the dependencies have been obtained. -ifneq ($(shell ( test '$(MAKECMDGOALS)' = clean || test '$(MAKECMDGOALS)' = distclean ); echo $$?),0) - ifeq ($(shell ( ! test -d freestnd-c-hdrs || ! test -d freestnd-cxx-hdrs || ! test -d cc-runtime ); echo $$?),0) +ifneq ($(filter-out clean distclean,$(MAKECMDGOALS)),) + ifeq ($(wildcard .deps-obtained),) $(error Please run the ./get-deps script first) endif endif # Check if CC is Clang. -override CC_IS_CLANG := $(shell ! $(CC) --version 2>/dev/null | grep 'clang' >/dev/null 2>&1; echo $$?) +override CC_IS_CLANG := $(shell ! $(CC) --version 2>/dev/null | grep -q '^Target: '; echo $$?) # Check if CXX is Clang. -override CXX_IS_CLANG := $(shell ! $(CXX) --version 2>/dev/null | grep 'clang' >/dev/null 2>&1; echo $$?) - -# If the C compiler is Clang, set the target as needed. -ifeq ($(CC_IS_CLANG),1) - override CC += \ - -target x86_64-unknown-none -endif - -# Likewise for the C++ compiler. -ifeq ($(CXX_IS_CLANG),1) - override CXX += \ - -target x86_64-unknown-none -endif +override CXX_IS_CLANG := $(shell ! $(CXX) --version 2>/dev/null | grep -q '^Target: '; echo $$?) # Internal flags shared by both C and C++ compilers. override SHARED_FLAGS := \ + -Wall \ + -Wextra \ -nostdinc \ -ffreestanding \ -fno-stack-protector \ -fno-stack-check \ -fno-lto \ - -fno-PIC \ + -fno-PIC -I uacpi/include \ -ffunction-sections \ - -fdata-sections \ - -m64 \ - -march=x86-64 \ - -mno-80387 \ - -mno-mmx \ - -mno-sse \ - -mno-sse2 \ - -mno-red-zone \ - -mcmodel=kernel + -fdata-sections # Internal C/C++ preprocessor flags that should not be changed by the user. override CPPFLAGS_C := \ -I src \ - -isystem freestnd-c-hdrs/x86_64/include \ + -I limine-protocol/include -I flanterm/src -I nanoprintf -I stb -I src/klibc/c \ + -isystem freestnd-c-hdrs/$(ARCH)/include \ $(CPPFLAGS) \ - -DLIMINE_API_REVISION=3 \ -MMD \ -MP # Internal C++ only preprocessor flags. override CPPFLAGS_CXX := \ - -I src \ - -isystem freestnd-c-hdrs/x86_64/include \ - -isystem freestnd-cxx-hdrs/x86_64/include \ - $(CPPFLAGS) \ - -DLIMINE_API_REVISION=3 \ - -MMD \ - -MP + $(CPPFLAGS_C) \ + -isystem freestnd-cxx-hdrs/$(ARCH)/include + +ifeq ($(ARCH),x86_64) + # Internal nasm flags that should not be changed by the user. + override NASMFLAGS := \ + $(patsubst -g,-g -F dwarf,$(NASMFLAGS)) \ + -Wall +endif + +# Architecture specific internal flags. +ifeq ($(ARCH),x86_64) + ifeq ($(CC_IS_CLANG),1) + override CC += \ + -target x86_64-unknown-none-elf + endif + ifeq ($(CXX_IS_CLANG),1) + override CXX += \ + -target x86_64-unknown-none-elf + endif + override SHARED_FLAGS += \ + -m64 \ + -march=x86-64 \ + -mabi=sysv \ + -mno-80387 \ + -mno-mmx \ + -mno-sse \ + -mno-sse2 \ + -mno-red-zone \ + -mcmodel=kernel + override LDFLAGS += \ + -m elf_x86_64 + override NASMFLAGS := \ + -f elf64 \ + $(NASMFLAGS) +endif +ifeq ($(ARCH),aarch64) + ifeq ($(CC_IS_CLANG),1) + override CC += \ + -target aarch64-unknown-none-elf + endif + ifeq ($(CXX_IS_CLANG),1) + override CXX += \ + -target aarch64-unknown-none-elf + endif + override SHARED_FLAGS += \ + -mcpu=generic \ + -march=armv8-a+nofp+nosimd \ + -mgeneral-regs-only + override LDFLAGS += \ + -m aarch64elf +endif +ifeq ($(ARCH),riscv64) + ifeq ($(CC_IS_CLANG),1) + override CC += \ + -target riscv64-unknown-none-elf + endif + ifeq ($(CXX_IS_CLANG),1) + override CXX += \ + -target riscv64-unknown-none-elf + endif + override SHARED_FLAGS += \ + -march=rv64imac_zicsr_zifencei \ + -mabi=lp64 \ + -mno-relax + override LDFLAGS += \ + -m elf64lriscv \ + --no-relax +endif +ifeq ($(ARCH),loongarch64) + ifeq ($(CC_IS_CLANG),1) + override CC += \ + -target loongarch64-unknown-none-elf + endif + ifeq ($(CXX_IS_CLANG),1) + override CXX += \ + -target loongarch64-unknown-none-elf + endif + override SHARED_FLAGS += \ + -march=loongarch64 \ + -mabi=lp64s \ + -mfpu=none \ + -msimd=none + override LDFLAGS += \ + -m elf64loongarch +endif # Internal C flags that should not be changed by the user. override CFLAGS += \ @@ -103,81 +193,90 @@ override CFLAGS += \ # Internal C++ flags that should not be changed by the user. override CXXFLAGS += \ - -std=gnu++23 \ + -std=c++26 -Wno-c23-extensions \ -fno-rtti \ -fno-exceptions \ $(SHARED_FLAGS) -# Internal nasm flags that should not be changed by the user. -override NASMFLAGS += \ - -Wall \ - -f elf64 - # Internal linker flags that should not be changed by the user. override LDFLAGS += \ - -m elf_x86_64 \ - -T linker.ld - -# Use "find" to glob all *.c, *.cpp, *.S, and *.asm files in the tree and obtain the -# object and header dependency file names. -override SRCFILES := $(shell find -L src cc-runtime/src -type f | LC_ALL=C sort) + -nostdlib \ + -static \ + -z max-page-size=0x1000 \ + --gc-sections \ + -T linker-scripts/$(ARCH).lds + +# Use "find" to glob all *.c, *.cpp, *.S, and *.asm files in the tree +# (except the src/arch/* directories, as those are gonna be added +# in the next step). +override SRCFILES := $(shell find -L src cc-runtime/src flanterm/src uacpi/source -type f -not -path 'src/arch/*' 2>/dev/null | LC_ALL=C sort) +# Add architecture specific files, if they exist. +override SRCFILES += $(shell find -L src/arch/$(ARCH) -type f 2>/dev/null | LC_ALL=C sort) +# Obtain the object and header dependencies file names. override CFILES := $(filter %.c,$(SRCFILES)) override CXXFILES := $(filter %.cpp,$(SRCFILES)) override ASFILES := $(filter %.S,$(SRCFILES)) +ifeq ($(ARCH),x86_64) override NASMFILES := $(filter %.asm,$(SRCFILES)) -override OBJ := $(addprefix obj/,$(CFILES:.c=.c.o) $(CXXFILES:.cpp=.cpp.o) $(ASFILES:.S=.S.o) $(NASMFILES:.asm=.asm.o)) -override HEADER_DEPS := $(addprefix obj/,$(CFILES:.c=.c.d) $(CXXFILES:.cpp=.cpp.d) $(ASFILES:.S=.S.d)) +endif +override OBJ := $(addprefix obj-$(ARCH)/,$(CFILES:.c=.c.o) $(CXXFILES:.cpp=.cpp.o) $(ASFILES:.S=.S.o)) +ifeq ($(ARCH),x86_64) +override OBJ += $(addprefix obj-$(ARCH)/,$(NASMFILES:.asm=.asm.o)) +endif +override HEADER_DEPS := $(addprefix obj-$(ARCH)/,$(CFILES:.c=.c.d) $(CXXFILES:.cpp=.cpp.d) $(ASFILES:.S=.S.d)) # Default target. This must come first, before header dependencies. .PHONY: all -all: bin/$(OUTPUT) +all: bin-$(ARCH)/$(OUTPUT) # Include header dependencies. -include $(HEADER_DEPS) # Link rules for the final executable. -bin/$(OUTPUT): GNUmakefile linker.ld $(OBJ) - mkdir -p "$$(dirname $@)" - $(LD) $(OBJ) $(LDFLAGS) -o $@ +bin-$(ARCH)/$(OUTPUT): GNUmakefile linker-scripts/$(ARCH).lds $(OBJ) + mkdir -p "$(dir $@)" + $(LD) $(LDFLAGS) $(OBJ) -o $@ # Compilation rules for *.c files. -obj/%.c.o: %.c GNUmakefile - mkdir -p "$$(dirname $@)" +obj-$(ARCH)/%.c.o: %.c GNUmakefile + mkdir -p "$(dir $@)" $(CC) $(CFLAGS) $(CPPFLAGS_C) -c $< -o $@ # Compilation rules for *.cpp files. -obj/%.cpp.o: %.cpp GNUmakefile - mkdir -p "$$(dirname $@)" +obj-$(ARCH)/%.cpp.o: %.cpp GNUmakefile + mkdir -p "$(dir $@)" $(CXX) $(CXXFLAGS) $(CPPFLAGS_CXX) -c $< -o $@ # Compilation rules for *.S files. -obj/%.S.o: %.S GNUmakefile - mkdir -p "$$(dirname $@)" +obj-$(ARCH)/%.S.o: %.S GNUmakefile + mkdir -p "$(dir $@)" $(CC) $(CFLAGS) $(CPPFLAGS_C) -c $< -o $@ +ifeq ($(ARCH),x86_64) # Compilation rules for *.asm (nasm) files. -obj/%.asm.o: %.asm GNUmakefile - mkdir -p "$$(dirname $@)" +obj-$(ARCH)/%.asm.o: %.asm GNUmakefile + mkdir -p "$(dir $@)" nasm $(NASMFLAGS) $< -o $@ +endif # Remove object files and the final executable. .PHONY: clean clean: - rm -rf bin obj + rm -rf bin-$(ARCH) obj-$(ARCH) # Remove everything built and generated including downloaded dependencies. .PHONY: distclean -distclean: clean - rm -rf freestnd-c-hdrs freestnd-cxx-hdrs cc-runtime src/limine.h +distclean: + rm -rf bin-* obj-* .deps-obtained .cache compile_commands.json freestnd-c-hdrs freestnd-cxx-hdrs cc-runtime limine-protocol # Install the final built executable to its final on-root location. .PHONY: install install: all install -d "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)" - install -m 644 bin/$(OUTPUT) "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)/" + install -m 644 bin-$(ARCH)/$(OUTPUT) "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)/$(OUTPUT)-$(ARCH)" # Try to undo whatever the "install" target did. .PHONY: uninstall uninstall: - rm -f "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)/$(OUTPUT)" + rm -f "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)/$(OUTPUT)-$(ARCH)" -rmdir "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)" diff --git a/kernel/get-deps b/kernel/get-deps index d93b434..503a9a6 100755 --- a/kernel/get-deps +++ b/kernel/get-deps @@ -1,6 +1,6 @@ #! /bin/sh -set -ex +set -e srcdir="$(dirname "$0")" test -z "$srcdir" && srcdir=. @@ -11,160 +11,61 @@ clone_repo_commit() { if test -d "$2/.git"; then git -C "$2" reset --hard git -C "$2" clean -fd - if ! git -C "$2" checkout $3; then + if ! git -C "$2" -c advice.detachedHead=false checkout $3; then rm -rf "$2" fi else if test -d "$2"; then - set +x - echo "error: '$2' is not a Git repository" + echo "error: '$2' is not a Git repository" 1>&2 exit 1 fi fi if ! test -d "$2"; then git clone $1 "$2" - if ! git -C "$2" checkout $3; then + if ! git -C "$2" -c advice.detachedHead=false checkout $3; then rm -rf "$2" exit 1 fi fi } -download_by_hash() { - DOWNLOAD_COMMAND="curl -Lo" - if ! command -v "${DOWNLOAD_COMMAND%% *}" >/dev/null 2>&1; then - DOWNLOAD_COMMAND="wget -O" - if ! command -v "${DOWNLOAD_COMMAND%% *}" >/dev/null 2>&1; then - set +x - echo "error: Neither curl nor wget found" - exit 1 - fi - fi - SHA256_COMMAND="sha256sum" - if ! command -v "${SHA256_COMMAND%% *}" >/dev/null 2>&1; then - SHA256_COMMAND="sha256" - if ! command -v "${SHA256_COMMAND%% *}" >/dev/null 2>&1; then - set +x - echo "error: Cannot find sha256(sum) command" - exit 1 - fi - fi - if ! test -f "$2" || ! $SHA256_COMMAND "$2" | grep $3 >/dev/null 2>&1; then - rm -f "$2" - mkdir -p "$2" && rm -rf "$2" - $DOWNLOAD_COMMAND "$2" $1 - if ! $SHA256_COMMAND "$2" | grep $3 >/dev/null 2>&1; then - set +x - echo "error: Cannot download file '$2' by hash" - echo "incorrect hash:" - $SHA256_COMMAND "$2" - rm -f "$2" - exit 1 - fi - fi -} +rm -f .deps-obtained clone_repo_commit \ - https://codeberg.org/osdev/freestnd-c-hdrs.git \ + https://codeberg.org/OSDev/freestnd-c-hdrs.git \ freestnd-c-hdrs \ - 4039f438fb1dc1064d8e98f70e1cf122f91b763b + 5e11c3da645d8f203e93dc23703b14a15c5b7afc clone_repo_commit \ - https://codeberg.org/osdev/freestnd-cxx-hdrs.git \ + https://codeberg.org/OSDev/freestnd-cxx-hdrs.git \ freestnd-cxx-hdrs \ - 85096df5361a4d7ef2ce46947e555ec248c2858e + 9d6a92ab19a57140f1e3ecc6668014d7f46094b6 clone_repo_commit \ - https://codeberg.org/osdev/cc-runtime.git \ + https://codeberg.org/OSDev/cc-runtime.git \ cc-runtime \ dae79833b57a01b9fd3e359ee31def69f5ae899b -download_by_hash \ - https://github.com/limine-bootloader/limine/raw/4687a182be23939c2d9f15db970382dc353ed956/limine.h \ - src/limine.h \ - 6879e626f34c1be25ac2f72bf43b083fc2b53887280bb0fcdaee790e258c6974 -#! /bin/sh - -set -ex - -srcdir="$(dirname "$1")" -test -z "$srcdir" && srcdir=. - -cd "$srcdir" - -clone_repo_commit() { - if test -d "$2/.git"; then - git -C "$2" reset --hard - git -C "$2" clean -fd - if ! git -C "$2" checkout $3; then - rm -rf "$2" - fi - else - if test -d "$2"; then - set +x - echo "error: '$2' is not a Git repository" - exit 1 - fi - fi - if ! test -d "$2"; then - git clone $1 "$2" - if ! git -C "$2" checkout $3; then - rm -rf "$2" - exit 1 - fi - fi -} - -download_by_hash() { - DOWNLOAD_COMMAND="curl -Lo" - if ! command -v "${DOWNLOAD_COMMAND%% *}" >/dev/null 2>&1; then - DOWNLOAD_COMMAND="wget -O" - if ! command -v "${DOWNLOAD_COMMAND%% *}" >/dev/null 2>&1; then - set +x - echo "error: Neither curl nor wget found" - exit 1 - fi - fi - SHA256_COMMAND="sha256sum" - if ! command -v "${SHA256_COMMAND%% *}" >/dev/null 2>&1; then - SHA256_COMMAND="sha256" - if ! command -v "${SHA256_COMMAND%% *}" >/dev/null 2>&1; then - set +x - echo "error: Cannot find sha256(sum) command" - exit 1 - fi - fi - if ! test -f "$2" || ! $SHA256_COMMAND "$2" | grep $3 >/dev/null 2>&1; then - rm -f "$2" - mkdir -p "$2" && rm -rf "$2" - $DOWNLOAD_COMMAND "$2" $1 - if ! $SHA256_COMMAND "$2" | grep $3 >/dev/null 2>&1; then - set +x - echo "error: Cannot download file '$2' by hash" - echo "incorrect hash:" - $SHA256_COMMAND "$2" - rm -f "$2" - exit 1 - fi - fi -} +clone_repo_commit \ + https://codeberg.org/Limine/limine-protocol.git \ + limine-protocol \ + 068b6481557db836e41bf644382367f8dee76d21 clone_repo_commit \ - https://codeberg.org/osdev/freestnd-c-hdrs.git \ - freestnd-c-hdrs \ - 4039f438fb1dc1064d8e98f70e1cf122f91b763b + https://codeberg.org/Mintsuki/Flanterm.git \ + flanterm \ + 26f631fcc15bb7faea83572213cae5a0287fc3de clone_repo_commit \ - https://codeberg.org/osdev/freestnd-cxx-hdrs.git \ - freestnd-cxx-hdrs \ - 85096df5361a4d7ef2ce46947e555ec248c2858e + https://github.com/charlesnicholson/nanoprintf.git \ + nanoprintf \ + 47af8e576556d7be9621f431e442123eccc056d3 clone_repo_commit \ - https://codeberg.org/osdev/cc-runtime.git \ - cc-runtime \ - dae79833b57a01b9fd3e359ee31def69f5ae899b + https://github.com/uACPI/uACPI.git \ + uacpi \ + e05715b2e6a3ae913aecdb86f4fd2dba30304e45 + +touch .deps-obtained -download_by_hash \ - https://github.com/limine-bootloader/limine/raw/4687a182be23939c2d9f15db970382dc353ed956/limine.h \ - src/limine.h \ - 6879e626f34c1be25ac2f72bf43b083fc2b53887280bb0fcdaee790e258c6974 +printf "\nDependencies obtained successfully.\n" diff --git a/kernel/include/arch/x86_64/cpu/data.hpp b/kernel/include/arch/x86_64/cpu/data.hpp deleted file mode 100644 index c803468..0000000 --- a/kernel/include/arch/x86_64/cpu/data.hpp +++ /dev/null @@ -1,51 +0,0 @@ - -#include <cstdint> - -#pragma once - -#include <etc/assembly.hpp> -#include <etc/libc.hpp> - -#include <arch/x86_64/interrupts/idt.hpp> -#include <arch/x86_64/scheduling.hpp> - -typedef struct { - std::uint64_t user_stack; - std::uint64_t kernel_stack; - std::uint64_t timer_ist_stack; - int last_sys; - std::uint64_t lapic_block; - struct { - std::uint16_t cpu_id; - } smp; - struct { - std::uint64_t freq; - } tsc; - struct { - int_frame_t* temp_ctx; - int_frame_t sys_ctx; - arch::x86_64::process_t* proc; - arch::x86_64::process_queue_run_list_t* next; - } temp; -} cpudata_t; - -namespace arch { - namespace x86_64 { - namespace cpu { - - inline static cpudata_t* fixdata() { - std::uint64_t cpudata = __rdmsr(0xC0000101); - } - - inline static cpudata_t* data() { - std::uint64_t cpudata = __rdmsr(0xC0000101); - if(!cpudata) { - cpudata = (std::uint64_t)new cpudata_t; - memset((void*)cpudata,0,sizeof(cpudata_t)); - __wrmsr(0xC0000101,cpudata); - } - return (cpudata_t*)cpudata; - } - }; - }; -};
\ No newline at end of file diff --git a/kernel/include/arch/x86_64/cpu/gdt.hpp b/kernel/include/arch/x86_64/cpu/gdt.hpp deleted file mode 100644 index 4ffe780..0000000 --- a/kernel/include/arch/x86_64/cpu/gdt.hpp +++ /dev/null @@ -1,79 +0,0 @@ - -#include <cstdint> - -#pragma once - -typedef struct __attribute__((packed)) { - std::uint16_t size; - std::uint64_t base; -} gdt_pointer_t; - -typedef struct __attribute__((packed)) { - std::uint16_t limit; - std::uint16_t baselow16; - std::uint8_t basemid8; - std::uint8_t access; - std::uint8_t granularity; - std::uint8_t basehigh8; -} gdt_entry_t; - -typedef struct __attribute__((packed)) { - std::uint16_t length; - std::uint16_t baselow16; - std::uint8_t basemid8; - std::uint8_t flags0; - std::uint8_t flags1; - std::uint8_t basehigh8; - std::uint32_t baseup32; - std::uint32_t reserved; -} tss_entry_t; - -typedef struct __attribute__((packed)) { - std::uint32_t reserved0; - std::uint64_t rsp[3]; - std::uint64_t reserved1; - std::uint64_t ist[7]; - std::uint32_t reserved2; - std::uint32_t reserved3; - std::uint16_t reserved4; - std::uint16_t iopb_offsset; -} tss_t; - -typedef struct __attribute__((packed)) { - gdt_entry_t zero; - gdt_entry_t _64bitcode; - gdt_entry_t _64bitdata; - gdt_entry_t usercode; - gdt_entry_t userdata; - tss_entry_t tss; -} gdt_t; - -extern "C" void loadtss(); -extern "C" void loadgdt(void* gdtr); - -namespace arch { - namespace x86_64 { - namespace cpu { - class gdt { - private: - gdt_t gdt_obj; - gdt_pointer_t gdtr; - public: - - void LoadTSS() { - loadtss(); - } - - void LoadGDT() { - loadgdt(&gdtr); - } - - static void init(); - - gdt() { - init(); - } - }; - }; - }; -};
\ No newline at end of file diff --git a/kernel/include/arch/x86_64/cpu/lapic.hpp b/kernel/include/arch/x86_64/cpu/lapic.hpp deleted file mode 100644 index 350edac..0000000 --- a/kernel/include/arch/x86_64/cpu/lapic.hpp +++ /dev/null @@ -1,68 +0,0 @@ - -#include <cstdint> - -#pragma once - -#include <generic/mm/paging.hpp> -#include <drivers/tsc.hpp> - -#include <drivers/hpet.hpp> - -#include <generic/time.hpp> - -#include <etc/logging.hpp> - -#include <etc/assembly.hpp> -#include <etc/etc.hpp> - -extern "C" void setwp(); - -namespace arch { - namespace x86_64 { - namespace cpu { - class lapic { - - static inline std::uint64_t base() { - return (std::uint64_t)Other::toVirt(__rdmsr(0x1B) & 0xFFFFF000); - } - - static inline std::uint32_t read(std::uint32_t reg) { - return *(volatile std::uint32_t*)(base() + reg); - } - - static inline void write(std::uint32_t reg,std::uint32_t value) { - *(volatile std::uint32_t*)(base() + reg) = value; - } - - public: - - static inline std::uint32_t id() { - return read(0x20) >> 24; - } - - static inline void eoi() { - write(0xB0,0); - } - - static inline void tick(std::uint64_t tick) { - write(0x380,tick); - } - - static inline std::uint64_t init(std::uint32_t us) { - __wrmsr(0x1B,__rdmsr(0x1B)); - memory::paging::kernelmap(0,__rdmsr(0x1B) & 0xFFFFF000); - write(0xf0,0xff | 0x100); - write(0x3e0,1); - write(0x320,32 | (1 << 16)); - write(0x380,0xFFFFFFFF); - time::sleep(us); - std::uint64_t ticks = 0xFFFFFFFF - read(0x390); - write(0x320, 32 | (1 << 17)); - write(0x3e0,1); - write(0x380,0); - return ticks; - } - }; - }; - }; -};
\ No newline at end of file diff --git a/kernel/include/arch/x86_64/cpu/smp.hpp b/kernel/include/arch/x86_64/cpu/smp.hpp deleted file mode 100644 index e98992a..0000000 --- a/kernel/include/arch/x86_64/cpu/smp.hpp +++ /dev/null @@ -1,14 +0,0 @@ - -#include <cstdint> - -namespace arch { - namespace x86_64 { - namespace cpu { - class mp { - public: - static void init(); - static void sync(std::uint8_t id); - }; - } - } -}
\ No newline at end of file diff --git a/kernel/include/arch/x86_64/cpu/sse.hpp b/kernel/include/arch/x86_64/cpu/sse.hpp deleted file mode 100644 index 6b21d60..0000000 --- a/kernel/include/arch/x86_64/cpu/sse.hpp +++ /dev/null @@ -1,37 +0,0 @@ - -#include <cstdint> - -#pragma once - -#define DEFAULT_SSE_FLAGS ((1 << 9) | (1 << 10) | (1 << 1)) -#define SSE_XSAVE_SUPPORT (1 << 26) -#define SSE_XSAVE_CR4 (1 << 18) - -#define SSE_CONTROL_DEFAULT ((1 << 0) | (1 << 1)) - -#define SSE_CHECK_AND_SET(bit) \ -if(a & bit) \ - sse_control |= bit; - -typedef struct { - std::uint16_t dumb0; - std::uint32_t dumb1; - std::uint16_t dumb2; - std::uint64_t dumb3; - std::uint64_t dumb4; - std::uint32_t dumb5; -} __attribute__((packed)) fpu_head_t; - -namespace arch { - namespace x86_64 { - namespace cpu { - class sse { - public: - static void init(); - static std::uint64_t size(); - static void save(std::uint8_t* buf); - static void load(std::uint8_t* buf); - }; - } - } -}
\ No newline at end of file diff --git a/kernel/include/arch/x86_64/interrupts/idt.hpp b/kernel/include/arch/x86_64/interrupts/idt.hpp deleted file mode 100644 index 529913f..0000000 --- a/kernel/include/arch/x86_64/interrupts/idt.hpp +++ /dev/null @@ -1,63 +0,0 @@ - -#include <cstdint> - -#pragma once - -typedef struct { - std::uint16_t low; - std::uint16_t cs; - std::uint8_t ist; - std::uint8_t attr; - std::uint16_t mid; - std::uint32_t high; - std::uint32_t reserved0; -} __attribute__((packed)) idt_entry_t; - -typedef struct { - std::uint16_t limit; - std::uint64_t base; -} __attribute__((packed)) idtr_t; - -typedef struct { - std::uint64_t cr3; - std::uint64_t rax; - std::uint64_t rbx; - std::uint64_t rcx; - std::uint64_t rdx; - std::uint64_t rsi; - std::uint64_t rdi; - std::uint64_t rbp; - std::uint64_t r8; - std::uint64_t r9; - std::uint64_t r10; - std::uint64_t r11; - std::uint64_t r12; - std::uint64_t r13; - std::uint64_t r14; - std::uint64_t r15; - std::uint64_t vec; - std::uint64_t err_code; - std::uint64_t rip; - std::uint64_t cs; - std::uint64_t rflags; - std::uint64_t rsp; - std::uint64_t ss; -} int_frame_t; - -extern "C" void ignoreStub(); - -namespace arch { - namespace x86_64 { - namespace interrupts { - class idt { - public: - static void init(); - static void set_entry(std::uint64_t base,std::uint8_t vec,std::uint8_t flags,std::uint8_t ist); - static std::uint8_t alloc(); - - static void load(); - }; - }; - }; -}; - diff --git a/kernel/include/arch/x86_64/interrupts/irq.hpp b/kernel/include/arch/x86_64/interrupts/irq.hpp deleted file mode 100644 index 4003184..0000000 --- a/kernel/include/arch/x86_64/interrupts/irq.hpp +++ /dev/null @@ -1,28 +0,0 @@ - -#include <cstdint> - -#pragma once - -#define IRQ_TYPE_OTHER 0 -#define IRQ_TYPE_LEGACY 1 -#define IRQ_TYPE_MSI 2 -#define IRQ_TYPE_LEGACY_USERSPACE 3 - -typedef struct { - void (*func)(void* arg); - void* arg; - int irq; - char is_userspace; -} irq_t; - -namespace arch { - namespace x86_64 { - namespace interrupts { - class irq { - public: - static std::uint8_t create(std::uint16_t irq,std::uint8_t type,void (*func)(void* arg),void* arg,std::uint64_t flags); - static void reset(); - }; - }; - }; -};
\ No newline at end of file diff --git a/kernel/include/arch/x86_64/interrupts/pic.hpp b/kernel/include/arch/x86_64/interrupts/pic.hpp deleted file mode 100644 index 81d65ed..0000000 --- a/kernel/include/arch/x86_64/interrupts/pic.hpp +++ /dev/null @@ -1,107 +0,0 @@ - -#include <etc/assembly.hpp> -#include <drivers/io.hpp> -#include <cstdint> - -#include <arch/x86_64/interrupts/irq.hpp> - -#pragma once - -#define PIC1 0x20 -#define PIC2 0xA0 -#define PIC1_COMMAND PIC1 -#define PIC1_DATA (PIC1+1) -#define PIC2_COMMAND PIC2 -#define PIC2_DATA (PIC2+1) -#define ICW1_ICW4 0x01 -#define ICW1_SINGLE 0x02 -#define ICW1_INTERVAL4 0x04 -#define ICW1_LEVEL 0x08 -#define ICW1_INIT 0x10 - -#define ICW4_8086 0x01 -#define ICW4_AUTO 0x02 -#define ICW4_BUF_SLAVE 0x08 -#define ICW4_BUF_MASTER 0x0C -#define ICW4_SFNM 0x10 - -#define CASCADE_IRQ 2 - -namespace arch { - namespace x86_64 { - namespace interrupts { - class pic { - public: - static inline void eoi(std::uint8_t irq) { - drivers::io io; - if(irq >= 8) - io.outb(PIC2_COMMAND,0x20); - io.outb(PIC1_COMMAND,0x20); - - } - - static inline void disable() { - drivers::io io; - io.outb(PIC1_DATA, 0xff); - io.outb(PIC2_DATA, 0xff); - arch::x86_64::interrupts::irq::reset(); - } - - static inline void init() { - drivers::io io; - io.outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); - io.wait(); - io.outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); - io.wait(); - io.outb(PIC1_DATA, 0x20); - io.wait(); - io.outb(PIC2_DATA, 0x28); - io.wait(); - io.outb(PIC1_DATA, 1 << CASCADE_IRQ); - io.wait(); - io.outb(PIC2_DATA, 2); - io.wait(); - - io.outb(PIC1_DATA, ICW4_8086); - io.wait(); - io.outb(PIC2_DATA, ICW4_8086); - io.wait(); - - io.outb(PIC1_DATA, 0); - io.outb(PIC2_DATA, 0); - } - - static inline void mask(std::uint8_t irq) { - drivers::io io; - std::uint16_t port; - std::uint8_t value; - - if(irq < 8) { - port = PIC1_DATA; - } else { - port = PIC2_DATA; - irq -= 8; - } - value = io.inb(port) | (1 << irq); - io.outb(port, value); - } - - static inline void clear(std::uint8_t irq) { - drivers::io io; - std::uint16_t port; - std::uint8_t value; - - if(irq < 8) { - port = PIC1_DATA; - } else { - port = PIC2_DATA; - irq -= 8; - } - value = io.inb(port) & ~(1 << irq); - io.outb(port, value); - } - - }; - }; - }; -};
\ No newline at end of file diff --git a/kernel/include/arch/x86_64/interrupts/pit.hpp b/kernel/include/arch/x86_64/interrupts/pit.hpp deleted file mode 100644 index 1fc7377..0000000 --- a/kernel/include/arch/x86_64/interrupts/pit.hpp +++ /dev/null @@ -1,18 +0,0 @@ - -#include <cstdint> - -#pragma once - -#define PIT_FREQUENCY 1193182 - -namespace arch { - namespace x86_64 { - namespace interrupts { - class pit { - public: - static void init(); - static void sleep(std::uint32_t ms); - }; - }; - }; -};
\ No newline at end of file diff --git a/kernel/include/arch/x86_64/scheduling.hpp b/kernel/include/arch/x86_64/scheduling.hpp deleted file mode 100644 index 90e0336..0000000 --- a/kernel/include/arch/x86_64/scheduling.hpp +++ /dev/null @@ -1,460 +0,0 @@ - -#include <cstdint> - -#pragma once - -#include <arch/x86_64/syscalls/signal.hpp> - -#include <arch/x86_64/interrupts/idt.hpp> -#include <generic/vfs/vfs.hpp> - -#include <etc/logging.hpp> - -#include <generic/locks/spinlock.hpp> - -#include <atomic> - -#define PROCESS_STATE_NONE 0 -#define PROCESS_STATE_KILLED 1 -#define PROCESS_STATE_RUNNING 2 -#define PROCESS_STATE_ZOMBIE 3 - -#define WNOHANG 1 /* Don't block waiting. */ -#define WUNTRACED 2 /* Report status of stopped children. */ - -#define MIN2(a, b) ((a) < (b) ? (a) : (b)) -#define MAX2(a, b) ((a) > (b) ? (a) : (b)) - -extern "C" void yield(); - -#define PREPARE_SIGNAL(proc) if(proc->sig->is_not_empty_sigset(&proc->current_sigset) && 1) -#define PROCESS_SIGNAL(proc) yield(); - -typedef struct { - unsigned char e_ident[16]; - uint16_t e_type; - uint16_t e_machine; - uint32_t e_version; - uint64_t e_entry; - uint64_t e_phoff; - uint64_t e_shoff; - uint32_t e_flags; - uint16_t e_ehsize; - uint16_t e_phentsize; - uint16_t e_phnum; - uint16_t e_shentsize; - uint16_t e_shnum; - uint16_t e_shstrndx; -} __attribute__((packed)) elfheader_t; - -typedef struct { - uint32_t p_type; - uint32_t p_flags; - uint64_t p_offset; - uint64_t p_vaddr; - uint64_t p_paddr; - uint64_t p_filesz; - uint64_t p_memsz; - uint64_t p_align; -} __attribute__((packed)) elfprogramheader_t; - -typedef struct { - std::uint64_t interp_entry; - std::uint64_t real_entry; - std::uint64_t phdr; - std::uint64_t phnum; - std::uint64_t phentsize; - int status; - std::uint64_t interp_base; - std::uint64_t base; -} elfloadresult_t; - -#define REG_R8 0 -#define REG_R9 1 -#define REG_R10 2 -#define REG_R11 3 -#define REG_R12 4 -#define REG_R13 5 -#define REG_R14 6 -#define REG_R15 7 -#define REG_RDI 8 -#define REG_RSI 9 -#define REG_RBP 10 -#define REG_RBX 11 -#define REG_RDX 12 -#define REG_RAX 13 -#define REG_RCX 14 -#define REG_RSP 15 -#define REG_RIP 16 -#define REG_EFL 17 -#define REG_CSGSFS 18 -#define REG_ERR 19 -#define REG_TRAPNO 20 -#define REG_OLDMASK 21 -#define REG_CR2 22 - -inline void mcontext_to_int_frame(mcontext_t* out, int_frame_t* src) { - src->r8 = out->gregs[REG_R8]; - src->r9 = out->gregs[REG_R9]; - src->r10 = out->gregs[REG_R10]; - src->r11 = out->gregs[REG_R11]; - src->r12 = out->gregs[REG_R12]; - src->r13 = out->gregs[REG_R13]; - src->r14 = out->gregs[REG_R14]; - src->r15 = out->gregs[REG_R15]; - src->rdi = out->gregs[REG_RDI]; - src->rsi = out->gregs[REG_RSI]; - src->rbp = out->gregs[REG_RBP]; - src->rbx = out->gregs[REG_RBX]; - src->rdx = out->gregs[REG_RDX]; - src->rax = out->gregs[REG_RAX]; - src->rcx = out->gregs[REG_RCX]; - src->rsp = out->gregs[REG_RSP]; - src->rip = out->gregs[REG_RIP]; - src->rflags = out->gregs[REG_EFL]; - src->cs = out->gregs[REG_CSGSFS]; // todo: implement SMEP - src->ss = out->gregs[REG_ERR]; // why not - if(src->cs > 0x30) { - Log::SerialDisplay(LEVEL_MESSAGE_FAIL,"broken src->cs for mcontext to int frame"); - asm volatile("hlt"); - } -} - -inline void int_frame_to_mcontext(int_frame_t* src, mcontext_t* out) { - out->gregs[REG_R8] = src->r8; - out->gregs[REG_R9] = src->r9; - out->gregs[REG_R10] = src->r10; - out->gregs[REG_R11] = src->r11; - out->gregs[REG_R12] = src->r12; - out->gregs[REG_R13] = src->r13; - out->gregs[REG_R14] = src->r14; - out->gregs[REG_R15] = src->r15; - out->gregs[REG_RDI] = src->rdi; - out->gregs[REG_RSI] = src->rsi; - out->gregs[REG_RBP] = src->rbp; - out->gregs[REG_RBX] = src->rbx; - out->gregs[REG_RDX] = src->rdx; - out->gregs[REG_RAX] = src->rax; - out->gregs[REG_RCX] = src->rcx; - out->gregs[REG_RSP] = src->rsp; - out->gregs[REG_RIP] = src->rip; - out->gregs[REG_EFL] = src->rflags; - out->gregs[REG_CSGSFS] = src->cs; - out->gregs[REG_ERR] = src->ss; - if(!src->cs > 0x30) { - Log::SerialDisplay(LEVEL_MESSAGE_FAIL,"broken src->cs for int frame to mcontext"); - asm volatile("hlt"); - } - - /* Other registers must be untouched (not implemented) */ -} - -enum ELF_Type { - PT_NULL, - PT_LOAD, - PT_DYNAMIC, - PT_INTERP, - PT_NOTE, - PT_SHLIB, - PT_PHDR, - PT_LOPROC=0x70000000, //reserved - PT_HIPROC=0x7FFFFFFF //reserved -}; - -typedef enum { - ET_NONE = 0, - ET_REL = 1, - ET_EXEC = 2, - ET_DYN = 3, - ET_CORE = 4, - ET_LOPROC = 0xff00, - ET_HIPROC = 0xffff -} obj_type_t; - -typedef enum { - AT_NULL = 0, - AT_IGNORE = 1, - AT_EXECFD = 2, - AT_PHDR = 3, - AT_PHENT = 4, - AT_PHNUM = 5, - AT_PAGESZ = 6, - AT_BASE = 7, - AT_FLAGS = 8, - AT_ENTRY = 9, - AT_NOTELF = 10, - AT_UID = 11, - AT_EUID = 12, - AT_GID = 13, - AT_EGID = 14, - AT_PLATFORM = 15, - AT_HWCAP = 16, - AT_CLKTCK = 17, - AT_SECURE = 23, - AT_BASE_PLATFORM = 24, - AT_RANDOM = 25, - AT_HWCAP2 = 26, - AT_RSEQ_FEATURE_SIZE = 27, - AT_RSEQ_ALIGN = 28, - AT_HWCAP3 = 29, - AT_HWCAP4 = 30, - AT_EXECFN = 31 -} auxv_t; - -extern "C" void schedulingScheduleAndChangeStack(std::uint64_t stack, int_frame_t* ctx); -extern "C" void schedulingSchedule(int_frame_t* ctx); -extern "C" void schedulingEnter(); -extern "C" void schedulingEnd(int_frame_t* ctx); - -typedef struct { - int64_t d_tag; - union { - uint64_t d_val; - uint64_t d_ptr; - } d_un; -} Elf64_Dyn; - -#define DT_NULL 0 -#define DT_NEEDED 1 -#define DT_STRTAB 5 -#define DT_SYMTAB 6 -#define DT_STRSZ 10 - -typedef uint64_t u64; - -# define CSIGNAL 0x000000ff /* Signal mask to be sent at exit. */ -# define CLONE_VM 0x00000100 /* Set if VM shared between processes. */ -# define CLONE_FS 0x00000200 /* Set if fs info shared between processes. */ -# define CLONE_FILES 0x00000400 /* Set if open files shared between processes. */ -# define CLONE_SIGHAND 0x00000800 /* Set if signal handlers shared. */ -# define CLONE_PIDFD 0x00001000 /* Set if a pidfd should be placed - in parent. */ -# define CLONE_PTRACE 0x00002000 /* Set if tracing continues on the child. */ -# define CLONE_VFORK 0x00004000 /* Set if the parent wants the child to - wake it up on mm_release. */ -# define CLONE_PARENT 0x00008000 /* Set if we want to have the same - parent as the cloner. */ -# define CLONE_THREAD 0x00010000 /* Set to add to same thread group. */ -# define CLONE_NEWNS 0x00020000 /* Set to create new namespace. */ -# define CLONE_SYSVSEM 0x00040000 /* Set to shared SVID SEM_UNDO semantics. */ -# define CLONE_SETTLS 0x00080000 /* Set TLS info. */ -# define CLONE_PARENT_SETTID 0x00100000 /* Store TID in userlevel buffer - before MM copy. */ -# define CLONE_CHILD_CLEARTID 0x00200000 /* Register exit futex and memory - location to clear. */ -# define CLONE_DETACHED 0x00400000 /* Create clone detached. */ -# define CLONE_UNTRACED 0x00800000 /* Set if the tracing process can't - force CLONE_PTRACE on this clone. */ -# define CLONE_CHILD_SETTID 0x01000000 /* Store TID in userlevel buffer in - the child. */ -# define CLONE_NEWCGROUP 0x02000000 /* New cgroup namespace. */ -# define CLONE_NEWUTS 0x04000000 /* New utsname group. */ -# define CLONE_NEWIPC 0x08000000 /* New ipcs. */ -# define CLONE_NEWUSER 0x10000000 /* New user namespace. */ -# define CLONE_NEWPID 0x20000000 /* New pid namespace. */ -# define CLONE_NEWNET 0x40000000 /* New network namespace. */ -# define CLONE_IO 0x80000000 /* Clone I/O context. */ - -struct clone_args { - u64 flags; /* Flags bit mask */ - u64 pidfd; /* Where to store PID file descriptor - (int *) */ - u64 child_tid; /* Where to store child TID, - in child's memory (pid_t *) */ - u64 parent_tid; /* Where to store child TID, - in parent's memory (pid_t *) */ - u64 exit_signal; /* Signal to deliver to parent on - child termination */ - u64 stack; /* Pointer to lowest byte of stack */ - u64 stack_size; /* Size of stack */ - u64 tls; /* Location of new TLS */ - u64 set_tid; /* Pointer to a pid_t array - (since Linux 5.5) */ - u64 set_tid_size; /* Number of elements in set_tid - (since Linux 5.5) */ - u64 cgroup; /* File descriptor for target cgroup - of child (since Linux 5.7) */ -}; - -struct stimeval { - long long tv_sec; /* seconds */ - long long tv_usec; /* microseconds */ -}; - - -struct itimerval { - struct stimeval it_interval; /* следующее значение */ - struct stimeval it_value; /* текущее значение */ -}; - -#define ITIMER_REAL 0 -#define ITIMER_VIRTUAL 1 -#define ITIMER_PROF 2 - -namespace arch { - namespace x86_64 { - - struct sigset_list { - int sig; - sigset_t sigset; - sigset_list* next; - }; - - typedef struct process { - std::uint32_t id; - std::uint8_t status; - std::uint8_t waitpid_state; - - std::uint64_t original_cr3; - int_frame_t ctx; - int_frame_t sig_ctx; - - int_frame_t* sys_ctx; - - std::atomic<int> target_cpu; - - std::uint64_t fs_base; - - locks::spinlock lock; - locks::spinlock kill_lock; /* Never should be setup by not kill() function */ - - locks::spinlock _3rd_kill_lock; - locks::spinlock futex_lock; - - locks::spinlock fd_lock; - - itimerval itimer; - std::int64_t next_alarm; - - itimerval vitimer; - std::int64_t virt_timer; - - itimerval proftimer; - std::int64_t prof_timer; - - sigset_t current_sigset; - sigset_t temp_sigset; - int is_restore_sigset; - - void* sig_handlers[36]; - void* ret_handlers[36]; - int sig_flags[36]; - - std::atomic<int> is_execd; - - sigset_t sigsets[36]; - stack_t altstack; - - std::uint8_t is_sig_real; - std::uint32_t alloc_fd; - std::uint32_t* fd_ptr; - - std::uint64_t old_stack; - - int is_shared_fd; - - std::uint32_t reversedforid; - std::uint32_t* vmm_id; - - userspace_fd_t* fd_pool; - vfs::passingfd_manager* pass_fd; - signalmanager* sig; - - sigtrace* sigtrace_obj; - - int is_cloexec; - - void* fd; - - char* vmm_start; - char* vmm_end; - - char* sse_ctx; - char* cwd; - char* name; - - int sys; - - int prio; - - std::uint64_t ts; - - int exit_code; - int is_cloned; - std::uint64_t* original_cr3_pointer; - - std::uint64_t time_start; - - std::uint64_t futex; - std::uint64_t syscall_stack; - std::uint64_t user_stack; - - std::uint64_t create_timestamp; - std::uint64_t exit_timestamp; - - std::uint64_t thread_group; // just parent pid - - std::uint32_t parent_id; - std::uint32_t exit_signal; - - int* tidptr; - int uid; - - int debug0; - int debug1; - - int is_debug; - - int sex_abort; - - struct process* next; - - } process_t; - - inline void update_time(itimerval* itimer, std::int64_t* output, int is_tsc) { - if(itimer->it_value.tv_sec != 0 || itimer->it_value.tv_usec != 0) { - *output = (itimer->it_value.tv_usec) + (itimer->it_value.tv_sec * (1000*1000)) + (is_tsc ? drivers::tsc::currentus() : 0); - } else if(itimer->it_interval.tv_sec != 0 || itimer->it_interval.tv_usec != 0) { - *output = (itimer->it_interval.tv_usec) + (itimer->it_interval.tv_sec * (1000*1000)) + (is_tsc ? drivers::tsc::currentus() : 0); - } - } - - inline sigset_t* get_sigset_from_list(process_t* proc, int sig) { - - return 0; - } - - inline void free_sigset_from_list(process_t* proc) { - return; - } - -static_assert(sizeof(process_t) < 4096,"process_t is bigger than page size"); - - typedef struct process_queue_run_list { - struct process_queue_run_list* next; - process_t* proc; - char is_used; - } process_queue_run_list_t; - - class scheduling { - public: - static void init(); - static process_t* create(); - static process_t* fork(process_t* proc,int_frame_t* ctx); - static process_t* clone(process_t* proc,int_frame_t* ctx); - static process_t* clone3(process_t* proc, clone_args* clarg, int_frame_t* ctx); - static process_t* by_pid(int pid); - static void create_kernel_thread(void (*func)(void*),void* arg); - static void kill(process_t* proc); - static void wakeup(process_t* proc); - static int futexwake(process_t* proc, int* lock, int num_to_wake); - static void futexwait(process_t* proc, int* lock, int val, int* original_lock, std::uint64_t ts); - static int loadelf(process_t* proc,char* path,char** argv,char** envp,int free_mem); - static process_t* head_proc_(); - - static void sigreturn(process_t* proc); - - }; - } -} - diff --git a/kernel/include/arch/x86_64/syscalls/futex.hpp b/kernel/include/arch/x86_64/syscalls/futex.hpp deleted file mode 100644 index 8b13789..0000000 --- a/kernel/include/arch/x86_64/syscalls/futex.hpp +++ /dev/null @@ -1 +0,0 @@ - diff --git a/kernel/include/arch/x86_64/syscalls/shm.hpp b/kernel/include/arch/x86_64/syscalls/shm.hpp deleted file mode 100644 index af7bc7f..0000000 --- a/kernel/include/arch/x86_64/syscalls/shm.hpp +++ /dev/null @@ -1,42 +0,0 @@ - -#include <cstdint> - -typedef long time_t; -typedef unsigned short ushort; - -#define IPC_RMID 0 -#define IPC_SET 1 -#define IPC_STAT 2 -#define IPC_INFO 3 - -struct ipc_perm { - std::uint32_t key; - ushort uid; - ushort gid; - ushort cuid; - ushort cgid; - ushort mode; - ushort seq; -}; - - -struct shmid_ds { - struct ipc_perm shm_perm; - int shm_segsz; - time_t shm_atime; - time_t shm_dtime; - time_t shm_ctime; - unsigned short shm_cpid; - unsigned short shm_lpid; - short shm_nattch; -}; - -typedef struct shm_seg { - std::uint32_t key; - std::uint32_t id; - std::uint64_t phys; - std::uint64_t len; - int is_pending_rm; - struct shmid_ds ctl; - struct shm_seg* next; -} shm_seg_t;
\ No newline at end of file diff --git a/kernel/include/arch/x86_64/syscalls/signal.hpp b/kernel/include/arch/x86_64/syscalls/signal.hpp deleted file mode 100644 index 26589c7..0000000 --- a/kernel/include/arch/x86_64/syscalls/signal.hpp +++ /dev/null @@ -1,288 +0,0 @@ - -#include <arch/x86_64/interrupts/idt.hpp> -#include <cstdint> - -#include <etc/list.hpp> - -#pragma once - -void signal_ret(); - -typedef long clock_t; - -union sigval { - int sival_int; - void *sival_ptr; -}; - -typedef uint32_t __uint32_t; -typedef uint64_t __uint64_t; -typedef uint16_t __uint16_t; -typedef int pid_t; -typedef int uid_t; - - - - -#define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) -typedef struct -{ - unsigned long long __val; -} __sigset_t; - -typedef __sigset_t sigset_t; - -void signal_ret_sigmask(sigset_t* sigmask); - -#define __sigmask(sig) \ - (1UL << (((sig) - 1) % 64)) - -/* Return the word index for SIG. */ -static inline int -__sigword (int sig) -{ - return (sig - 1) / 64; -} - -static inline int -__sigismember (sigset_t *set, int sig) -{ - return (set->__val & (1 << (sig - 1))) ? 1 : 0; -} - - -struct siginfo_t { - int si_signo; /* Номер сигнала */ - int si_errno; /* Значение errno */ - int si_code; /* Код сигнала */ - pid_t si_pid; /* Идентификатор процесса, пославшего сигнал */ - uid_t si_uid; /* Реальный идентификатор пользователя процесса, пославшего сигнал */ - int si_status; /* Выходное значение или номер сигнала */ - clock_t si_utime; /* Занятое пользователем время */ - clock_t si_stime; /* Использованное системное время */ - sigval si_value; /* Значение сигнала */ - int si_int; /* Сигнал POSIX.1b */ - void * si_ptr; /* Сигнал POSIX.1b */ - void * si_addr; /* Адрес в памяти, приводящий к ошибке */ - int si_band; /* Общее событие */ - int si_fd; /* Описатель файла */ -}; - -# define __ctx(fld) fld - -struct _libc_fpxreg -{ - unsigned short int __ctx(significand)[4]; - unsigned short int __ctx(exponent); - unsigned short int __glibc_reserved1[3]; -}; - -typedef struct { - void *ss_sp; /* Base address of stack */ - int ss_flags; /* Flags */ - size_t ss_size; /* Number of bytes in stack */ - } stack_t; - - -struct _libc_xmmreg -{ - __uint32_t __ctx(element)[4]; -}; - -struct _libc_fpstate -{ - /* 64-bit FXSAVE format. */ - __uint16_t __ctx(cwd); - __uint16_t __ctx(swd); - __uint16_t __ctx(ftw); - __uint16_t __ctx(fop); - __uint64_t __ctx(rip); - __uint64_t __ctx(rdp); - __uint32_t __ctx(mxcsr); - __uint32_t __ctx(mxcr_mask); - struct _libc_fpxreg _st[8]; - struct _libc_xmmreg _xmm[16]; - __uint32_t __glibc_reserved1[24]; -}; - -#define __NGREG 23 - -#define __pollution(n) n - -struct _fpxreg { - unsigned short __pollution(significand)[4]; - unsigned short __pollution(exponent); - unsigned short __padding[3]; -}; - -struct _xmmreg { - uint32_t __pollution(element)[4]; -}; - -struct _fpstate { - uint16_t __pollution(cwd); - uint16_t __pollution(swd); - uint16_t __pollution(ftw); - uint16_t __pollution(fop); - uint64_t __pollution(rip); - uint64_t __pollution(rdp); - uint32_t __pollution(mxcsr); - uint32_t __pollution(mxcr_mask); - struct _fpxreg _st[8]; - struct _xmmreg _xmm[16]; - uint32_t __padding[24]; -}; - -typedef struct { - unsigned long __pollution(gregs)[__NGREG]; - struct _fpstate *__pollution(fpregs); - unsigned long __reserved1[8]; -} mcontext_t; - -/* Structure to describe FPU registers. */ -typedef struct _libc_fpstate *fpregset_t; - -struct sigtrace { - mcontext_t* mctx; - sigset_t sigset; - void* fpu_state; - struct sigtrace* next; -}; - -struct sigaction - { - /* Signal handler. */ -#if 1 - union - { - /* Used if SA_SIGINFO is not set. */ - void (*sa_handler)(int); - /* Used if SA_SIGINFO is set. */ - void (*sa_sigaction) (int, siginfo_t *, void *); - } - __sigaction_handler; -# define sa_handler __sigaction_handler.sa_handler -# define sa_sigaction __sigaction_handler.sa_sigaction -#else - __sighandler_t sa_handler; -#endif - - /* Additional set of signals to be blocked. */ - sigset_t sa_mask; - - /* Special flags. */ - int sa_flags; - - /* Restore handler. */ - void (*sa_restorer) (void); - }; - -typedef struct { - std::uint16_t sig; -} pending_signal_t; - -class signalmanager { -private: - pending_signal_t* sigs = 0; - Lists::Bitmap* bitmap = 0; - int size = 0; - int total_size = 0; - locks::spinlock lock; - - int allocate() { - for(int i = 0; i < 128; i++) { - if(!this->bitmap->test(i)) - return i; - } - return -1; - } - - int find_free() { - for(int i = 0; i < 128; i++) { - if(this->bitmap->test(i)) - return i; - } - return -1; - } - -public: - - signalmanager() { - this->total_size = 128; - sigs = new pending_signal_t[this->total_size]; - memset(sigs,0,sizeof(pending_signal_t) * this->total_size); - bitmap = new Lists::Bitmap(this->total_size); - } - - ~signalmanager() { - delete (void*)this->sigs; - delete (void*)this->bitmap; - } - - int pop(pending_signal_t* out) { - this->lock.lock(); - int idx = find_free(); - if(idx == -1) { this->lock.unlock(); - return -1; } - memcpy(out,&sigs[idx],sizeof(pending_signal_t)); - this->bitmap->clear(idx); - this->lock.unlock(); - return 0; - } - - int push(pending_signal_t* src) { - this->lock.lock(); - int idx = allocate(); - if(idx == -1) { this->lock.unlock(); - return -1; } - memcpy(&sigs[idx],src,sizeof(pending_signal_t)); - this->bitmap->set(idx); - this->lock.unlock(); - return 0; - } - - int is_not_empty_sigset(sigset_t* sigsetz) { - this->lock.lock(); - - // ban sigset signals :p - for(int i = 0; i < 128; i++) { - if(this->bitmap->test(i) && !__sigismember(sigsetz,sigs[i].sig)) { - this->lock.unlock(); // great there's unbanned pending signal - return 1; - } - } - - this->lock.unlock(); - return 0; - } - - int popsigset(pending_signal_t* out, sigset_t* sigsetz) { - this->lock.lock(); - int idx = -1; - for(int i = 0; i < 128; i++) { - if(this->bitmap->test(i) && (sigs[i].sig == 9 || !__sigismember(sigsetz,sigs[i].sig))) { - idx = i; - break; - } - } - if(idx == -1) { - this->lock.unlock(); - return -1; - } - - memcpy(out,&sigs[idx],sizeof(pending_signal_t)); - this->bitmap->clear(idx); - this->lock.unlock(); - return 0; - } - - int is_not_empty() { - this->lock.lock(); - int idx = find_free(); - if(idx == -1) { this->lock.unlock(); - return 0; } - this->lock.unlock(); - return 1; - } - -};
\ No newline at end of file diff --git a/kernel/include/arch/x86_64/syscalls/sockets.hpp b/kernel/include/arch/x86_64/syscalls/sockets.hpp deleted file mode 100644 index 9da8461..0000000 --- a/kernel/include/arch/x86_64/syscalls/sockets.hpp +++ /dev/null @@ -1,156 +0,0 @@ - -#include <cstdint> - -#include <generic/vfs/vfs.hpp> -#include <generic/locks/spinlock.hpp> - -#pragma once - -typedef unsigned short sa_family_t; - -#define PF_UNSPEC 0 -#define PF_LOCAL 1 -#define PF_UNIX PF_LOCAL -#define PF_FILE PF_LOCAL -#define PF_INET 2 -#define PF_AX25 3 -#define PF_IPX 4 -#define PF_APPLETALK 5 -#define PF_NETROM 6 -#define PF_BRIDGE 7 -#define PF_ATMPVC 8 -#define PF_X25 9 -#define PF_INET6 10 -#define PF_ROSE 11 -#define PF_DECnet 12 -#define PF_NETBEUI 13 -#define PF_SECURITY 14 -#define PF_KEY 15 -#define PF_NETLINK 16 -#define PF_ROUTE PF_NETLINK -#define PF_PACKET 17 -#define PF_ASH 18 -#define PF_ECONET 19 -#define PF_ATMSVC 20 -#define PF_RDS 21 -#define PF_SNA 22 -#define PF_IRDA 23 -#define PF_PPPOX 24 -#define PF_WANPIPE 25 -#define PF_LLC 26 -#define PF_IB 27 -#define PF_MPLS 28 -#define PF_CAN 29 -#define PF_TIPC 30 -#define PF_BLUETOOTH 31 -#define PF_IUCV 32 -#define PF_RXRPC 33 -#define PF_ISDN 34 -#define PF_PHONET 35 -#define PF_IEEE802154 36 -#define PF_CAIF 37 -#define PF_ALG 38 -#define PF_NFC 39 -#define PF_VSOCK 40 -#define PF_KCM 41 -#define PF_QIPCRTR 42 -#define PF_SMC 43 -#define PF_XDP 44 -#define PF_MAX 45 - -#define AF_UNSPEC PF_UNSPEC -#define AF_LOCAL PF_LOCAL -#define AF_UNIX AF_LOCAL -#define AF_FILE AF_LOCAL -#define AF_INET PF_INET -#define AF_AX25 PF_AX25 -#define AF_IPX PF_IPX -#define AF_APPLETALK PF_APPLETALK -#define AF_NETROM PF_NETROM -#define AF_BRIDGE PF_BRIDGE -#define AF_ATMPVC PF_ATMPVC -#define AF_X25 PF_X25 -#define AF_INET6 PF_INET6 -#define AF_ROSE PF_ROSE -#define AF_DECnet PF_DECnet -#define AF_NETBEUI PF_NETBEUI -#define AF_SECURITY PF_SECURITY -#define AF_KEY PF_KEY -#define AF_NETLINK PF_NETLINK -#define AF_ROUTE PF_ROUTE -#define AF_PACKET PF_PACKET -#define AF_ASH PF_ASH -#define AF_ECONET PF_ECONET -#define AF_ATMSVC PF_ATMSVC -#define AF_RDS PF_RDS -#define AF_SNA PF_SNA -#define AF_IRDA PF_IRDA -#define AF_PPPOX PF_PPPOX -#define AF_WANPIPE PF_WANPIPE -#define AF_LLC PF_LLC -#define AF_IB PF_IB -#define AF_MPLS PF_MPLS -#define AF_CAN PF_CAN -#define AF_TIPC PF_TIPC -#define AF_BLUETOOTH PF_BLUETOOTH -#define AF_IUCV PF_IUCV -#define AF_RXRPC PF_RXRPC -#define AF_ISDN PF_ISDN -#define AF_PHONET PF_PHONET -#define AF_IEEE802154 PF_IEEE802154 -#define AF_CAIF PF_CAIF -#define AF_ALG PF_ALG -#define AF_NFC PF_NFC -#define AF_VSOCK PF_VSOCK -#define AF_KCM PF_KCM -#define AF_QIPCRTR PF_QIPCRTR -#define AF_SMC PF_SMC -#define AF_XDP PF_XDP -#define AF_MAX PF_MAX - -struct sockaddr { - sa_family_t sa_family; - char sa_data[14]; -}; - -struct sockaddr_un { - sa_family_t sun_family; - char sun_path[108]; -}; - -typedef struct socket_pending_obj { - locks::spinlock is_accepted; - userspace_fd_t* son; - struct socket_pending_obj* next; -} socket_pending_obj_t; - -class socket_controller { -private: - -public: - socket_controller() { - - } -}; - -typedef struct socket_node { - char path[128]; - uint64_t vars[8]; - char is_used; - std::atomic<uint64_t> socket_counter; - socket_pending_obj_t* pending_list; - struct socket_node* next; -} socket_node_t; - -class sockets { -public: - static char is_exists(char* path); - static int bind(userspace_fd_t* fd, struct sockaddr_un* path); - static int connect(userspace_fd_t* fd, struct sockaddr_un* path); - static int accept(userspace_fd_t* fd, struct sockaddr_un* path); - static void init(); - - static socket_node_t* find(char* path); - - -};
\ No newline at end of file diff --git a/kernel/include/arch/x86_64/syscalls/syscalls.hpp b/kernel/include/arch/x86_64/syscalls/syscalls.hpp deleted file mode 100644 index 1cfd6bb..0000000 --- a/kernel/include/arch/x86_64/syscalls/syscalls.hpp +++ /dev/null @@ -1,539 +0,0 @@ - -#include <cstdint> - -#pragma once - -#include <generic/mm/paging.hpp> - -#include <arch/x86_64/interrupts/idt.hpp> -#include <arch/x86_64/scheduling.hpp> -#include <etc/bootloaderinfo.hpp> -#include <etc/libc.hpp> - -#include <generic/mm/vmm.hpp> -#include <etc/etc.hpp> - -#include <arch/x86_64/cpu/data.hpp> - -inline void copy_in_userspace(arch::x86_64::process_t* proc,void* dest, void* src, std::uint64_t size) { - - void* ddest = 0; - void* ssrc = 0; - - ddest = dest; - ssrc = src; - - memcpy(ddest,ssrc,size); -} - -inline void copy_in_userspace_string(arch::x86_64::process_t* proc,void* dest, void* src, std::uint64_t size) { - - void* ddest = 0; - void* ssrc = 0; - - ddest = dest; - ssrc = src; - - memcpy(ddest,ssrc,strlen((char*)ssrc) > size ? size : strlen((char*)ssrc)); -} - -inline void zero_in_userspace(arch::x86_64::process_t* proc,void* buf, std::uint64_t size) { - - void* bbuf; - - bbuf = buf; - - memset(bbuf,0,size); -} - -class syscall_safe { -public: - - static inline int is_safe(std::uint64_t ptr) { - if(ptr >= BootloaderInfo::AccessHHDM()) - return 0; - return 1; - } - - static inline int is_safe(void* ptr) { - if((std::uint64_t)ptr >= BootloaderInfo::AccessHHDM()) - return 0; - return 1; - } - - static inline int is_safe(std::uint64_t ptr,std::uint64_t size) { - if(ptr + size >= BootloaderInfo::AccessHHDM()) - return 0; - return 1; - } - - static inline int is_safe(void* ptr,std::uint64_t size) { - if((std::uint64_t)ptr + size >= BootloaderInfo::AccessHHDM()) - return 0; - return 1; - } - -}; - -#define SYSCALL_IS_SAFEA(x,sz) \ - if(!syscall_safe::is_safe(x,sz)) \ - return {0,EFAULT,0}; - -#define SYSCALL_IS_SAFEZ(x,sz) \ - if(!syscall_safe::is_safe(x,sz)) \ - return -EFAULT; - -#define SYSCALL_IS_SAFEB(x,sz) \ - if(!syscall_safe::is_safe(x,sz)) \ - return {0,EFAULT,0}; - -inline arch::x86_64::process_t* __proc_get() { - arch::x86_64::process_t* proc = arch::x86_64::cpu::data()->temp.proc; - return proc; -} - -#define CURRENT_PROC __proc_get() -#define FIND_FD(x) vfs::fdmanager::search(proc,x) - -#define SYSCALL_DISABLE_PREEMPT() asm volatile("cli"); -#define SYSCALL_ENABLE_PREEMPT() asm volatile("sti"); - -typedef struct { - std::int8_t is_rdx_ret; - std::int32_t ret; - std::int64_t ret_val; -} syscall_ret_t; - -#define STAR_MSR 0xC0000081 -#define LSTAR 0xC0000082 -#define STAR_MASK 0xC0000084 -#define EFER 0xC0000080 - -#define MAP_FAILED ((void *)(-1)) -#define MAP_FILE 0x00 -#define MAP_SHARED 0x01 -#define MAP_PRIVATE 0x02 -#define MAP_FIXED 0x10 -#define MAP_ANON 0x20 -#define MAP_ANONYMOUS 0x20 - -#define F_DUPFD 0 -#define F_GETFD 1 -#define F_SETFD 2 -#define F_GETFL 3 -#define F_SETFL 4 - -extern "C" void syscall_handler(); - -struct wiovec { -void *iov_base; -size_t iov_len; -}; - -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 -#define FUTEX_FD 2 -#define FUTEX_REQUEUE 3 -#define FUTEX_CMP_REQUEUE 4 -#define FUTEX_WAKE_OP 5 -#define FUTEX_LOCK_PI 6 -#define FUTEX_UNLOCK_PI 7 -#define FUTEX_TRYLOCK_PI 8 -#define FUTEX_WAIT_BITSET 9 -#define FUTEX_WAKE_BITSET 10 -#define FUTEX_WAIT_REQUEUE_PI 11 -#define FUTEX_CMP_REQUEUE_PI 12 -#define FUTEX_LOCK_PI2 13 - -#define FUTEX_PRIVATE_FLAG 128 -#define FUTEX_CLOCK_REALTIME 256 - -#define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME) - -extern "C" { - -/* File,Pipes and etc. */ -long long sys_access(char* path, int mode); -long long sys_faccessat(int dirfd, char* path, int mode, int flags); -long long sys_openat(int dirfd, const char* path, int flags, int_frame_t* ctx); -long long sys_fstat(int fd, void* out); -long long sys_ioctl(int fd, unsigned long request, void *arg); -long long sys_write(int fd, const void *buf, size_t count); -long long sys_writev(int fd, wiovec* vec, unsigned long vlen); -long long sys_read(int fd, void *buf, size_t count); -long long sys_lseek(int fd, long offset, int whence); -long long sys_dup2(int fd, int newfd); -long long sys_newfstatat(int fd, char* path, void* out, int_frame_t* ctx); -long long sys_dup(int fd); -long long sys_pipe2(int* fildes, int flags); -long long sys_pipe(int* fildes); -long long sys_close(int fd); - -long long sys_umask(int mask); - -long long sys_symlink(char* old, char* path); -long long sys_symlinkat(char* old, int dirfd, char* path); - -long long sys_pread(int fd, void *buf, size_t count, int_frame_t* ctx); - -long long sys_getdents64(int fd, char* buf, size_t count); - -#define __FD_SETSIZE 1024 - -typedef long int __fd_mask; - -/* Some versions of <linux/posix_types.h> define this macros. */ -#undef __NFDBITS -/* It's easier to assume 8-bit bytes than to get CHAR_BIT. */ -#define __NFDBITS (8 * (int) sizeof (__fd_mask)) -#define __FD_ELT(d) ((d) / __NFDBITS) -#define __FD_MASK(d) ((__fd_mask) (1UL << ((d) % __NFDBITS))) - -/* fd_set for select and pselect. */ -typedef struct - { - /* XPG4.2 requires this member name. Otherwise avoid the name - from the global namespace. */ -#ifdef __USE_XOPEN - __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; -# define __FDS_BITS(set) ((set)->fds_bits) -#else - __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS]; -# define __FDS_BITS(set) ((set)->__fds_bits) -#endif - } fd_set; - -/* We don't use `memset' because this would require a prototype and - the array isn't too big. */ -#define __FD_ZERO(s) \ - do { \ - unsigned int __i; \ - fd_set *__arr = (s); \ - for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \ - __FDS_BITS (__arr)[__i] = 0; \ - } while (0) -#define __FD_SET(d, s) \ - ((void) (__FDS_BITS (s)[__FD_ELT(d)] |= __FD_MASK(d))) -#define __FD_CLR(d, s) \ - ((void) (__FDS_BITS (s)[__FD_ELT(d)] &= ~__FD_MASK(d))) -#define __FD_ISSET(d, s) \ - ((__FDS_BITS (s)[__FD_ELT (d)] & __FD_MASK (d)) != 0) - - -#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp) -#define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp) -#define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp) -#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp) - -long long sys_pselect6(int num_fds, fd_set* read_set, fd_set* write_set, int_frame_t* ctx); -syscall_ret_t sys_create_dev(std::uint64_t requestandnum, char* slave_path, char* master_path); -syscall_ret_t sys_create_ioctl(char* path, std::uint64_t write_and_read_req, std::uint32_t size); -syscall_ret_t sys_setupmmap(char* path, std::uint64_t addr, std::uint64_t size, int_frame_t* ctx); - -syscall_ret_t sys_setup_tty(char* path); -syscall_ret_t sys_isatty(int fd); - -syscall_ret_t sys_ptsname(int fd, void* out, int max_size); - -syscall_ret_t sys_setup_ring_bytelen(char* path, int bytelen); -syscall_ret_t sys_read_dir(int fd, void* buffer); - -long long sys_fcntl(int fd, int request, std::uint64_t arg, int_frame_t* ctx); - -long long sys_chdir(char* path); -long long sys_fchdir(int fd); - -long long sys_poll(struct pollfd *fds, int count, int timeout, int_frame_t* ctx); -long long sys_readlinkat(int dirfd, const char* path, void* buffer, int_frame_t* ctx); - -long long sys_readlink(char* path, void* buffer, int max_size); - -long long sys_link(char* old_path, char* new_path); -long long sys_linkat(int oldfd, char* old_path, int newfd, int_frame_t* ctx); - -long long sys_mkdirat(int dirfd, char* path, int mode); -long long sys_mkdir(char* path, int mode); - -long long sys_chmod(char* path, int mode); - -syscall_ret_t sys_ttyname(int fd, char *buf, size_t size); -long long sys_rename(char* old, char* newp); - -syscall_ret_t sys_eventfd_create(unsigned int initval, int flags); -syscall_ret_t sys_getentropy(char* buffer, std::uint64_t len); - -long long sys_pwrite(int fd, void* buf, std::uint64_t n, int_frame_t* ctx); -long long sys_fstatfs(int fd, struct statfs *buf); - -long long sys_statfs(char* path, struct statfs* buf); - -long long sys_fchmod(int fd, int mode); -long long sys_fchmodat(int dirfd, const char* path, int mode, int_frame_t* ctx); -long long sys_fchmodat2(int dirfd, const char* path, int mode, int_frame_t* ctx); - -long long sys_renameat(int olddir, char* old, int newdir, int_frame_t* ctx); -long long sys_statx(int dirfd, const char *path, int flag, int_frame_t* ctx); - -/* Process */ - -long long sys_mmap(std::uint64_t hint, std::uint64_t size, unsigned long prot, int_frame_t* ctx); -long long sys_free(void *pointer, size_t size); -long long sys_exit(int status); - -long long sys_exit_group(int status); - -long long sys_set_tid_address(int* tidptr); - -long long sys_arch_prctl(int option, unsigned long* addr); -long long sys_brk(); - -long long sys_mprotect(std::uint64_t start, size_t len, std::uint64_t prot); -long long sys_futex(int* uaddr, int op, uint32_t val, int_frame_t* ctx); - -#define RLIMIT_CPU 0 /* CPU time in sec */ -#define RLIMIT_FSIZE 1 /* Maximum filesize */ -#define RLIMIT_DATA 2 /* max data size */ -#define RLIMIT_STACK 3 /* max stack size */ -#define RLIMIT_CORE 4 /* max core file size */ - -#ifndef RLIMIT_RSS -# define RLIMIT_RSS 5 /* max resident set size */ -#endif - -#ifndef RLIMIT_NPROC -# define RLIMIT_NPROC 6 /* max number of processes */ -#endif - -#ifndef RLIMIT_NOFILE -# define RLIMIT_NOFILE 7 /* max number of open files */ -#endif - -#ifndef RLIMIT_MEMLOCK -# define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ -#endif - -#ifndef RLIMIT_AS -# define RLIMIT_AS 9 /* address space limit */ -#endif - -#define RLIMIT_LOCKS 10 /* maximum file locks held */ -#define RLIMIT_SIGPENDING 11 /* max number of pending signals */ -#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */ -#define RLIMIT_NICE 13 /* max nice prio allowed to raise to - 0-39 for nice level 19 .. -20 */ -#define RLIMIT_RTPRIO 14 /* maximum realtime priority */ -#define RLIMIT_RTTIME 15 /* timeout for RT tasks in us */ -#define RLIM_NLIMITS 16 - -/* - * SuS says limits have to be unsigned. - * Which makes a ton more sense anyway. - * - * Some architectures override this (for compatibility reasons): - */ -#ifndef RLIM_INFINITY -# define RLIM_INFINITY (~0UL) -#endif - -struct rlimit64 { - std::uint64_t rlim_cur; - std::uint64_t rlim_max; -}; - -long long sys_clone3(clone_args* clargs, size_t size, int c, int_frame_t* ctx); -long long sys_prlimit64(int pid, int res, rlimit64* new_rlimit, int_frame_t* ctx); - -syscall_ret_t sys_iopl(int a, int b ,int c , int_frame_t* ctx); - -syscall_ret_t sys_fork(int D, int S, int d, int_frame_t* ctx); - -syscall_ret_t sys_access_framebuffer(void* out); - -long long sys_exec(char* path, char** argv, char** envp, int_frame_t* ctx); - -long long sys_getpid(); -long long sys_getppid(); -long long sys_getpgrp(); - -long long sys_setpgid(int pid, int pgid); -long long sys_getpgid(int pid); - -syscall_ret_t sys_gethostname(void* buffer, std::uint64_t bufsize); - -long long sys_getcwd(void* buffer, std::uint64_t bufsize); - -long long sys_wait4(int pid,int* status,int flags); - -syscall_ret_t sys_sleep(long us); - -syscall_ret_t sys_alloc_dma(std::uint64_t size); -syscall_ret_t sys_free_dma(std::uint64_t phys); - -syscall_ret_t sys_map_phys(std::uint64_t phys, std::uint64_t flags, std::uint64_t size); - -syscall_ret_t sys_timestamp(); - -syscall_ret_t sys_mkfifoat(int dirfd, const char *path, int mode); - -syscall_ret_t sys_enabledebugmode(); - -long long sys_clone(unsigned long clone_flags, unsigned long newsp, int *parent_tidptr, int_frame_t* ctx); -syscall_ret_t sys_breakpoint(int num, int b, int c, int_frame_t* ctx); - -long long sys_getpriority(int which, int who); -long long sys_setpriority(int which, int who, int prio); - -syscall_ret_t sys_yield(); -syscall_ret_t sys_printdebuginfo(int pid); -syscall_ret_t sys_enabledebugmodepid(int pid); - -syscall_ret_t sys_dmesg(char* buf,std::uint64_t count); - -long long sys_getuid(); - -long long sys_getresuid(int* ruid, int* euid, int *suid); - -long long sys_setuid(int uid); - -long long sys_kill(int pid, int sig); -long long sys_tgkill(int tgid, int tid, int sig); - -/* Futex */ -syscall_ret_t sys_futex_wait(int* pointer, int excepted, struct timespec* ts); -syscall_ret_t sys_futex_wake(int* pointer); - -/* Socket */ -long long sys_socket(int family, int type, int protocol); - -long long sys_bind(int fd, struct sockaddr_un* path, int len); -long long sys_accept(int fd, struct sockaddr_un* path, int* zlen); -long long sys_connect(int fd, struct sockaddr_un* path, int len); - -long long sys_listen(int fd, int backlog); -long long sys_sendto(int s, void* msg, size_t len); - -syscall_ret_t sys_copymemory(void* src, void* dest, int len); - -syscall_ret_t sys_socketpair(int domain, int type_and_flags, int proto); -long long sys_getsockname(int fd, struct sockaddr_un* path, int* len); - -long long sys_getsockopt(int fd, int layer, int number, int_frame_t* ctx); - -long long sys_msg_recv(int fd, struct msghdr *hdr, int flags); -syscall_ret_t sys_msg_send(int fd, struct msghdr* hdr, int flags); - -long long sys_shutdown(int sockfd, int how); - -/* Shm stuff */ - -syscall_ret_t sys_shmctl(int shmid, int cmd, struct shmid_ds *buf); -syscall_ret_t sys_shmat(int shmid, std::uint64_t hint, int shmflg); -syscall_ret_t sys_shmget(int key, size_t size, int shmflg); -syscall_ret_t sys_shmdt(std::uint64_t base); - -/* Signals */ - -typedef unsigned long __cpu_mask; - -#define __CPU_SETSIZE 1024 -#define __NCPUBITS (8 * sizeof(__cpu_mask)) - -typedef struct { - __cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS]; -} cpu_set_t; - -long long sys_pause(); - -long long sys_sigaction(int signum, struct sigaction* hnd, struct sigaction* old, int_frame_t* ctx); -long long sys_sigprocmask(int how, const sigset_t *set, sigset_t *oldset, int_frame_t* ctx); - -typedef int pid_t; - -syscall_ret_t sys_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask); - -syscall_ret_t sys_cpucount(); - -syscall_ret_t sys_pathstat(char* path, void* out, int flags, int_frame_t* ctx); - -long long sys_alarm(int seconds); -long long sys_setitimer(int which, itimerval* val, itimerval* old); -long long sys_getitimer(int which, itimerval* val); - -long long sys_sigsuspend(sigset_t* sigset, size_t size); -long long sys_sigaltstack(stack_t* new_stack, stack_t* old); - -long long sys_unlink(char* path); -long long sys_unlinkat(int dirfd, const char* path, int flags); - -/* Misc */ - -struct __kernel_timespec { - std::uint64_t tv_sec; /* seconds */ - long long tv_nsec; /* nanoseconds */ -}; - -typedef int clockid_t; - -struct timeval { - long long tv_sec; /* seconds */ - long long tv_usec; /* microseconds */ -}; - - -long long sys_getrandom(char *buf, size_t count, unsigned int flags); -long long sys_clock_gettime(clockid_t which_clock, struct __kernel_timespec *tp); -long long sys_gettimeofday(timeval* tv, void* tz); -long long sys_time(std::uint64_t* t); - -long long sys_nanosleep(int clock, int flags, timespec* rqtp, int_frame_t* ctx); - -#define TIMER_ABSTIME 0x01 - -struct old_utsname { - char sysname[65]; - char nodename[65]; - char release[65]; - char version[65]; - char machine[65]; -}; - -long long sys_uname(old_utsname* uname); - -struct sysinfo { - long uptime; /* Количество секунд, прошедшее с загрузки системы */ - unsigned long loads[3]; /* средняя одно-, пяти-, и пятнадцатиминутная загруженность системы */ - unsigned long totalram; /* Общий объем доступной оперативной памяти */ - unsigned long freeram; /* Объем свободной памяти */ - unsigned long sharedram; /* Объем разделяемой памяти */ - unsigned long bufferram; /* Объем памяти, использованной под буферы */ - unsigned long totalswap; /* Общий объем области подкачки */ - unsigned long freeswap; /* Объем свободного пространства в области подкачки */ - unsigned short procs; /* Текущее количество процессов */ - unsigned long totalhigh; /* Общий объем верхней памяти */ - unsigned long freehigh; /* Объем свободной верхней памяти */ - unsigned int mem_unit; /* Объем единицы памяти в байтах */ - char _f[20-2*sizeof(long)-sizeof(int)]; /* Дополнение структуры для libc5 */ -}; - -long long sys_sysinfo(sysinfo* info); - -} - -struct pollfd { - int fd; - short events; - short revents; -}; - -namespace arch { - namespace x86_64 { - typedef struct { - int syscall_num; - void* syscall_func; - } syscall_item_t; - class syscall { - public: - static void init(); - }; - } -} diff --git a/kernel/include/config.hpp b/kernel/include/config.hpp deleted file mode 100644 index 9298390..0000000 --- a/kernel/include/config.hpp +++ /dev/null @@ -1,9 +0,0 @@ - -#pragma once - -#define KHEAP_SIZE (1024*1024*16) -#define KERNEL_STACK_SIZE (1024*256) -#define SYSCALL_STACK_SIZE (1024*64) -#define USERSPACE_PIPE_SIZE (1024*64) -#define DIRECTORY_LIST_SIZE 4096 -#define USERSPACE_STACK_SIZE (1024*1024*8)
\ No newline at end of file diff --git a/kernel/include/drivers/acpi.hpp b/kernel/include/drivers/acpi.hpp deleted file mode 100644 index ed288c6..0000000 --- a/kernel/include/drivers/acpi.hpp +++ /dev/null @@ -1,8 +0,0 @@ - -#include <cstdint> -namespace drivers { - class acpi { - public: - static void init(); - }; -};
\ No newline at end of file diff --git a/kernel/include/drivers/cmos.hpp b/kernel/include/drivers/cmos.hpp deleted file mode 100644 index 049b43e..0000000 --- a/kernel/include/drivers/cmos.hpp +++ /dev/null @@ -1,99 +0,0 @@ - -#include <cstdint> -#include <drivers/io.hpp> - -#pragma once - -#define CMOS_ADDRESS 0x70 -#define CMOS_DATA 0x71 -#define CMOS_SECONDS 0x00 -#define CMOS_MINUTES 0x02 -#define CMOS_HOURS 0x04 -#define CMOS_DAY 0x07 -#define CMOS_MONTH 0x08 -#define CMOS_YEAR 0x09 - -namespace drivers { - class cmos { - public: - static inline std::uint8_t cmos_read(std::uint8_t reg) { - drivers::io io; - io.outb(CMOS_ADDRESS, reg); - return io.inb(CMOS_DATA); - } - - static inline std::uint8_t bcd_to_binary(std::uint8_t bcd) { - return (bcd & 0x0F) + ((bcd / 16) * 10); - } - - static std::uint8_t second() { - uint8_t seconds = cmos_read(CMOS_SECONDS); - return bcd_to_binary(seconds); - } - - static std::uint8_t minute() { - uint8_t minutes = cmos_read(CMOS_MINUTES); - return bcd_to_binary(minutes); - } - - static std::uint8_t hour() { - uint8_t hours = cmos_read(CMOS_HOURS); - return bcd_to_binary(hours); - } - - static std::uint8_t day() { - uint8_t day = cmos_read(CMOS_DAY); - return bcd_to_binary(day); - } - - static std::uint8_t month() { - uint8_t month = cmos_read(CMOS_MONTH); - return bcd_to_binary(month); - } - - static std::uint16_t year() { - uint8_t year = cmos_read(CMOS_YEAR); - return 2000 + bcd_to_binary(year); - } - }; -}; - -inline bool isLeapYear(int year) { - return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); -} - -inline int daysInMonth(int month, int year) { - int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - if (month == 2 && isLeapYear(year)) { - return 29; - } - return days[month - 1]; -} - -inline static uint64_t getUnixTime() { - int year = drivers::cmos::year(); - int month = drivers::cmos::month(); - int day = drivers::cmos::day(); - int hour = drivers::cmos::hour(); - int minute = drivers::cmos::minute(); - int second = drivers::cmos::second(); - - long long daysSinceEpoch = 0; - for (int y = 1970; y < year; ++y) { - daysSinceEpoch += isLeapYear(y) ? 366 : 365; - } - - for (int m = 1; m < month; ++m) { - daysSinceEpoch += daysInMonth(m, year); - } - - daysSinceEpoch += (day - 1); - - long long secondsSinceEpoch = daysSinceEpoch * 86400; - - secondsSinceEpoch += hour * 3600; - secondsSinceEpoch += minute * 60; - secondsSinceEpoch += second; - - return secondsSinceEpoch; -}
\ No newline at end of file diff --git a/kernel/include/drivers/hpet.hpp b/kernel/include/drivers/hpet.hpp deleted file mode 100644 index 1646928..0000000 --- a/kernel/include/drivers/hpet.hpp +++ /dev/null @@ -1,13 +0,0 @@ - -#include <cstdint> - -#pragma once - -namespace drivers { - class hpet { - public: - static void init(); - static void sleep(std::uint64_t us); - static std::uint64_t nanocurrent(); - }; -}
\ No newline at end of file diff --git a/kernel/include/drivers/io.hpp b/kernel/include/drivers/io.hpp deleted file mode 100644 index 3af3832..0000000 --- a/kernel/include/drivers/io.hpp +++ /dev/null @@ -1,59 +0,0 @@ - -#include <cstdint> - -#pragma once - -namespace drivers { - class io { - private: - public: - io() { - - } - - inline void outb(std::uint16_t port, std::uint8_t val) { - __asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port) : "memory"); - } - - inline void outw(std::uint16_t port, std::uint16_t val) { - __asm__ volatile ("outw %0, %1" : : "a"(val), "Nd"(port) : "memory"); - } - - inline void outd(std::uint16_t port, std::uint32_t val) { - __asm__ volatile ("outl %0, %1" : : "a"(val), "Nd"(port) : "memory"); - } - - inline std::uint8_t inb(std::uint16_t port) { - std::uint8_t ret; - __asm__ volatile ("inb %1, %0" - : "=a"(ret) - : "Nd"(port) - : "memory"); - return ret; - } - - inline std::uint16_t inw(std::uint16_t port) { - std::uint16_t ret; - __asm__ volatile ("inw %1, %0" - : "=a"(ret) - : "Nd"(port) - : "memory"); - return ret; - } - - inline std::uint32_t ind(std::uint16_t port) { - std::uint32_t ret; - __asm__ volatile ("inl %1, %0" - : "=a"(ret) - : "Nd"(port) - : "memory"); - return ret; - } - - - inline void wait() { - outb(0x80,0); - } - - }; -};
\ No newline at end of file diff --git a/kernel/include/drivers/ioapic.hpp b/kernel/include/drivers/ioapic.hpp deleted file mode 100644 index ca74ec6..0000000 --- a/kernel/include/drivers/ioapic.hpp +++ /dev/null @@ -1,30 +0,0 @@ - -#include <cstdint> - -#pragma once - -#include <etc/etc.hpp> - -namespace drivers { - class ioapic { - public: - - static inline void write(std::uint64_t base, std::uint32_t reg,std::uint32_t value) { - std::uint64_t virt = (std::uint64_t)Other::toVirt(base); - *(volatile std::uint32_t*)virt = reg; - *(volatile std::uint32_t*)(virt + 0x10) = value; - } - - static inline std::uint32_t read(std::uint64_t base, std::uint32_t reg) { - std::uint64_t virt = (std::uint64_t)Other::toVirt(base); - *(volatile std::uint32_t*)virt = reg; - return *(volatile std::uint32_t*)(virt + 0x10); - } - - static void init(); - static void set(std::uint8_t vec,std::uint8_t irq,std::uint64_t flags,std::uint64_t lapic); - static void mask(std::uint8_t irq); - static void unmask(std::uint8_t irq); - - }; -};
\ No newline at end of file diff --git a/kernel/include/drivers/kvmtimer.hpp b/kernel/include/drivers/kvmtimer.hpp deleted file mode 100644 index d0695c3..0000000 --- a/kernel/include/drivers/kvmtimer.hpp +++ /dev/null @@ -1,25 +0,0 @@ - -#include <cstdint> - -#pragma once - -struct pvclock_vcpu_time_info { - std::uint32_t version; - std::uint32_t pad0; - std::uint64_t tsc_timestamp; - std::uint64_t system_time; - std::uint32_t tsc_to_system_mul; - std::int8_t tsc_shift; - std::uint8_t flags; - std::uint8_t pad[2]; -}; - -namespace drivers { - class kvmclock { - public: - static void init(); - static void sleep(std::uint64_t us); - - static std::uint64_t currentnano(); - }; -};
\ No newline at end of file diff --git a/kernel/include/drivers/pci.hpp b/kernel/include/drivers/pci.hpp deleted file mode 100644 index 3d946fb..0000000 --- a/kernel/include/drivers/pci.hpp +++ /dev/null @@ -1,72 +0,0 @@ - -#include <cstdint> -#include <drivers/io.hpp> - - -#pragma once - -/* Copypasted from old kernel :) */ - -typedef struct { - std::uint16_t vendorID; - std::uint16_t deviceID; - std::uint16_t command; - std::uint16_t status; - std::uint8_t revisionID; - std::uint8_t progIF; - std::uint8_t subclass; - std::uint8_t _class; - std::uint8_t cacheLineSize; - std::uint8_t latencyTimer; - std::uint8_t headerType; - std::uint8_t bist; - std::uint32_t bar0; - std::uint32_t bar1; - std::uint32_t bar2; - std::uint32_t bar3; - std::uint32_t bar4; - std::uint32_t bar5; - std::uint32_t cardbusCISPointer; - std::uint16_t subsystemVendorID; - std::uint16_t subsystemID; - std::uint32_t expansionROMBaseAddress; - std::uint8_t capabilitiesPointer; - std::uint8_t reserved0; - std::uint16_t reserved1; - std::uint32_t reserved2; - std::uint8_t irq; - std::uint8_t interruptPIN; - std::uint8_t minGrant; - std::uint8_t maxLatency; -} __attribute__((packed)) pci_t; - -typedef struct pci_cap { - std::uint8_t id; - std::uint8_t off; - std::uint8_t bus; - std::uint8_t num; - std::uint8_t func; - std::uint16_t venID; - std::uint16_t devID; - std::uint8_t data[32]; - struct pci_cap* next; -} __attribute__((packed)) pci_cap_t; - -typedef struct { - int used; - std::uint8_t _class; - std::uint8_t subclass; - void (*pcidrv)(pci_t, std::uint8_t, std::uint8_t, std::uint8_t); -} __attribute__((packed)) pci_driver_t; - -#define PCI_BAR_MASK ((1 << 0) | (1 << 1)) - -namespace drivers { - class pci { - public: - static void initworkspace(); - static void reg(void (*pcidrv)(pci_t, std::uint8_t, std::uint8_t, std::uint8_t), std::uint8_t _class, std::uint8_t subclass); - static std::uint32_t in(std::int8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset, std::uint8_t bytewidth); - static void out(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset, std::uint32_t value, std::uint8_t bytewidth); - }; -};
\ No newline at end of file diff --git a/kernel/include/drivers/ps2.hpp b/kernel/include/drivers/ps2.hpp deleted file mode 100644 index 13e184c..0000000 --- a/kernel/include/drivers/ps2.hpp +++ /dev/null @@ -1,19 +0,0 @@ - -namespace drivers { - - #define PS2_DATA 0x60 - #define PS2_STATUS 0x64 - #define PS2_CMD 0x64 - #define CMD_DISABLE_MOUSE 0xA7 - #define CMD_DISABLE_KEYBOARD 0xAD - #define CMD_READ_CONFIG 0x20 - #define CMD_WRITE_CONFIG 0x60 - #define CMD_SELF_TEST 0xAA - #define CMD_ENABLE_MOUSE 0xA8 - #define CMD_ENABLE_KEYBOARD 0xAE - - class ps2 { - public: - static void init(); - }; -};
\ No newline at end of file diff --git a/kernel/include/drivers/serial.hpp b/kernel/include/drivers/serial.hpp deleted file mode 100644 index f6c93a5..0000000 --- a/kernel/include/drivers/serial.hpp +++ /dev/null @@ -1,53 +0,0 @@ - -#include <cstdint> -#include <cstddef> - -#include <drivers/io.hpp> - -#pragma once - - -#define DEFAULT_SERIAL_PORT 0x3F8 - -typedef struct { - std::uint16_t port; - std::uint8_t is_init; -} serial_mapping_t; - -namespace drivers { - class serial { -private: - std::uint16_t target_port; - std::uint8_t is_possible; -public: - - static void init(uint16_t port); - static std::uint8_t is_init(uint16_t port); - - serial(uint16_t port) { - target_port = port; - if(!is_init(port)) - init(port); - } - - void send(std::uint8_t data) { - drivers::io io; - while((io.inb(target_port + 5) & 0x20) == 0); - io.outb(target_port,data); - } - - void write(std::uint8_t* data,std::size_t len) { - //return; - for(std::size_t i = 0; i < len; i++) { - send(data[i]); - } - } - - std::uint8_t fetch() { - drivers::io io; - while((io.inb(target_port + 5) & 1) == 0); - return io.inb(target_port); - } - - }; -};
\ No newline at end of file diff --git a/kernel/include/drivers/tsc.hpp b/kernel/include/drivers/tsc.hpp deleted file mode 100644 index 4aeaaa4..0000000 --- a/kernel/include/drivers/tsc.hpp +++ /dev/null @@ -1,16 +0,0 @@ - -#include <cstdint> -#include <arch/x86_64/interrupts/pit.hpp> - -#pragma once - -namespace drivers { - class tsc { - public: - static void init(); - static void cpuinit(); - static void sleep(std::uint64_t us); - static std::uint64_t currentnano(); - static std::uint64_t currentus(); - }; -};
\ No newline at end of file diff --git a/kernel/include/drivers/xhci.hpp b/kernel/include/drivers/xhci.hpp deleted file mode 100644 index a1043d4..0000000 --- a/kernel/include/drivers/xhci.hpp +++ /dev/null @@ -1,700 +0,0 @@ -#include <stdint.h> - -#pragma once - -#define XHCI_RESET_TIMEOUT 1000 - -typedef struct { - unsigned char buttons; - unsigned char x; - unsigned char y; - unsigned char z; -} __attribute__((packed)) mouse_packet_t; - -typedef struct { - uint32_t maxslots : 8; - uint32_t maxintrs : 11; - uint32_t reserved1 : 5; - uint32_t maxports : 8; -} __attribute__((packed)) hcsparams1_t; - -typedef struct { - uint32_t ist : 4; - uint32_t erstmax : 4; - uint32_t reserved1 : 13; - uint32_t max_scratchpad_hi : 5; - uint32_t spr : 1; - uint32_t max_scratchpad_lo : 5; -} __attribute__((packed)) hcsparams2_t; - -typedef struct { - uint32_t _64bitcap : 1; - uint32_t bnc : 1; - uint32_t contextsize : 1; - uint32_t portpowercontrol : 1; - uint32_t portindicator : 1; - uint32_t lhrc : 1; - uint32_t ltc : 1; - uint32_t nss : 1; - uint32_t pae : 1; - uint32_t spc : 1; - uint32_t sec : 1; - uint32_t cfc : 1; - uint32_t max_psa_size : 4; - uint32_t xECP : 16; -} __attribute__((packed)) hccparams1_t; - -typedef struct { - uint8_t caplength; - uint8_t reserved; - uint16_t hciversion; - hcsparams1_t hcsparams1; - hcsparams2_t hcsparams2; - uint32_t hcsparams3; - hccparams1_t hccparams1; - uint32_t dboff; - uint32_t rtsoff; - uint32_t hccparms2; -} xhci_cap_regs_t; - -typedef struct { - uint32_t usbcmd; - uint32_t usbsts; - uint32_t pagesize; - uint32_t reserved1[2]; - uint32_t dnctrl; - uint64_t crcr; - uint32_t reserved2[4]; - uint64_t dcbaap; - uint32_t config; -} xhci_op_regs_t; - -#define XHCI_USBCMD_RS (1 << 0) -#define XHCI_USBCMD_HOSTCONTROLLERREST (1 << 1) -#define XHCI_USB_SPEED_FULL_SPEED 1 -#define XHCI_USB_SPEED_LOW_SPEED 2 -#define XHCI_USB_SPEED_HIGH_SPEED 3 -#define XHCI_USB_SPEED_SUPER_SPEED 4 -#define XHCI_USB_SPEED_SUPER_SPEED_PLUS 5 - -typedef struct { - uint32_t portsc; - uint32_t portpmsc; - uint32_t portli; -} xhci_port_regs_t; - -typedef struct { - uint64_t erst_segment : 3; - uint64_t event_busy : 1; - uint64_t event_ring_pointer : 60; -} xhci_erdp_t; - -typedef struct { - uint32_t iman; - uint32_t imod; - uint32_t erstsz; - uint32_t reserved0; - uint64_t erstba; - union { - xhci_erdp_t erdp; - uint64_t erdp_val; - }; -} IR_t; - -typedef struct { - uint32_t mfindex; - uint32_t reserved1[7]; - IR_t int_regs[1024]; -} xhci_runtime_regs_t; - -typedef struct { - uint64_t base; - uint32_t size; - uint32_t reserved0; -} xhci_erst_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t nexttrb : 1; - uint32_t interruptonshort : 1; - uint32_t nosnoop : 1; - uint32_t chain : 1; - uint32_t intoncompletion : 1; - uint32_t immediate : 1; - uint32_t reserved1 : 2; - uint32_t blockeventint : 1; - uint32_t type : 6; - uint32_t reserved2 : 16; -} xhci_trb_info_t; - -typedef struct { - uint64_t base; - union { - struct { - uint32_t reserved0 : 24; - uint32_t ret_code : 8; - }; - uint32_t status; - }; - union { - xhci_trb_info_t info_s; - uint32_t info; - }; -} xhci_trb_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t reserved1 : 9; - uint32_t type : 6; - uint32_t vfid : 8; - uint32_t slotid : 8; -} xhci_slot_info_trb_t; - -typedef struct { - uint64_t base; - uint32_t CCP : 24; - uint32_t ret_code : 8; - union { - xhci_slot_info_trb_t info_s; - uint32_t info; - }; -} xhci_slot_trb_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t reserved0 : 8; - uint32_t bsr : 1; - uint32_t type : 6; - uint8_t reserved1; - uint8_t slotid; -} xhci_set_addr_info_trb_t; - -typedef struct { - uint64_t base; - uint32_t status; - union { - xhci_set_addr_info_trb_t info_s; - uint32_t info; - }; -} xhci_set_addr_trb_t; - -typedef struct { - uint8_t cycle; - uint16_t trb_limit; - uint64_t queue; - uint64_t phys; - xhci_trb_t* trb; -} xhci_command_ring_ctx_t; - -typedef struct { - uint16_t trb_limit; - uint64_t queue; - uint8_t cycle; - volatile IR_t* father; - xhci_trb_t* trb; - xhci_erst_t* table; -} xhci_event_ring_ctx_t; - -typedef struct { - uint16_t trb_limit; - uint64_t queue; - uint8_t cycle; - uint32_t slot; - uint64_t phys; - xhci_trb_t* trb; -} xhci_port_ring_ctx_t; - -typedef struct { - uint32_t D; - uint32_t A; - uint32_t reserved0[5]; - uint8_t configvalue; - uint8_t interfacenum; - uint8_t altsetting; - uint8_t reserved1; -} __attribute__((packed)) xhci_input_control_ctx_t; - -typedef struct { - uint32_t D; - uint32_t A; - uint32_t reserved0[5]; - uint8_t configvalue; - uint8_t interfacenum; - uint8_t altsetting; - uint8_t reserved1; - uint32_t align[8]; -} __attribute__((packed)) xhci_input_control_ctx64_t; - -typedef struct { - uint32_t routestring : 20; - uint8_t speed : 4; - uint8_t reserved0 : 1; - uint8_t multitt : 1; - uint8_t hub : 1; - uint8_t contextentries : 5; - uint16_t maxexitlat; - uint8_t porthubnum; - uint8_t numofports; - uint8_t parenthubslot; - uint8_t parentportnum; - uint8_t thinktime : 2; - uint8_t reserved1 : 4; - uint16_t irtarget : 10; - uint8_t address; - uint32_t reserved2 : 19; - uint8_t slotstate : 5; - uint32_t reserved3[4]; -} __attribute__((packed)) xhci_slot_ctx_t; - -typedef struct { - uint32_t routestring : 20; - uint8_t speed : 4; - uint8_t reserved0 : 1; - uint8_t multitt : 1; - uint8_t hub : 1; - uint8_t contextentries : 5; - uint16_t maxexitlat; - uint8_t porthubnum; - uint8_t numofports; - uint8_t parenthubslot; - uint8_t parentportnum; - uint8_t thinktime : 2; - uint8_t reserved1 : 4; - uint16_t irtarget : 10; - uint8_t address; - uint32_t reserved2 : 19; - uint8_t slotstate : 5; - uint32_t reserved3[4]; - uint32_t align[8]; -} __attribute__((packed)) xhci_slot_ctx64_t; - -typedef struct { - uint32_t state : 3; - uint32_t reserved0 : 5; - uint32_t mult : 2; - uint32_t maxprimarystreams : 5; - uint32_t linear : 1; - uint32_t interval : 8; - uint32_t some_shit_with_long_name : 8; - uint32_t reserved1 : 1; - uint32_t cerr : 2; - uint32_t endpointtype : 3; - uint32_t reserved2 : 1; - uint32_t hid : 1; - uint32_t maxburstsize : 8; - uint32_t maxpacketsize : 16; - uint64_t base; - uint16_t averagetrblen; - uint16_t some_shit_with_long_name_lo; - uint32_t align[3]; -} __attribute__((packed)) xhci_endpoint_ctx_t; - -typedef struct { - uint32_t state : 3; - uint32_t reserved0 : 5; - uint32_t mult : 2; - uint32_t maxprimarystreams : 5; - uint32_t linear : 1; - uint32_t interval : 8; - uint32_t some_shit_with_long_name : 8; - uint32_t reserved1 : 1; - uint32_t cerr : 2; - uint32_t endpointtype : 3; - uint32_t reserved2 : 1; - uint32_t hid : 1; - uint32_t maxburstsize : 8; - uint32_t maxpacketsize : 16; - uint64_t base; - uint16_t averagetrblen; - uint16_t some_shit_with_long_name_lo; - uint32_t align[11]; -} __attribute__((packed)) xhci_endpoint_ctx64_t; - -typedef struct { - xhci_input_control_ctx_t input_ctx; - xhci_slot_ctx_t slot; - xhci_endpoint_ctx_t ep0; - xhci_endpoint_ctx_t ep[30]; -} __attribute__((packed)) xhci_input_ctx_t; - -typedef struct { - xhci_input_control_ctx64_t input_ctx; - xhci_slot_ctx64_t slot; - xhci_endpoint_ctx64_t ep0; - xhci_endpoint_ctx64_t ep[30]; -} __attribute__((packed)) xhci_input_ctx64_t; - -typedef struct { - uint8_t len; - uint8_t type; -} xhci_usb_descriptor_header; - -typedef struct { - xhci_usb_descriptor_header head; - uint16_t usb; - uint8_t deviceclass; - uint8_t devicesubclass; - uint8_t protocol; - uint8_t maxpacketsize; - uint16_t vendor; - uint16_t product0; - uint16_t device; - uint8_t manufacter; - uint8_t product1; - uint8_t serialnum; - uint8_t numconfigs; -} xhci_usb_descriptor_t; - -typedef struct { - xhci_usb_descriptor_header head; - uint16_t lang[128]; -} xhci_lang_descriptor_t; - -typedef struct { - xhci_usb_descriptor_header head; - uint16_t str[128]; -} xhci_string_descriptor_t; - -typedef struct { - xhci_usb_descriptor_header head; - uint16_t len; - uint8_t numinterfaces; - uint8_t configval; - uint8_t config; - uint8_t attributes; - uint8_t maxpower; - uint8_t data[1024]; -} xhci_config_descriptor_t; - -typedef struct { - uint8_t desctype; - uint8_t desclen; -} xhci_hid_sub_desc; - -typedef struct { - xhci_usb_descriptor_header head; - uint16_t hid; - uint8_t country; - uint8_t numdesc; - xhci_hid_sub_desc desc[1024]; -} xhci_hid_descriptor_t; - -typedef struct { - xhci_usb_descriptor_header head; - uint8_t endpointaddr; - uint8_t attributes; - uint16_t maxpacketsize; - uint8_t interval; -} xhci_endpoint_descriptor_t; - -typedef struct { - xhci_usb_descriptor_header head; - uint8_t num; - uint8_t altsetting; - uint8_t numendpoints; - uint8_t interclass; - uint8_t intersubclass; - uint8_t protocol; - uint8_t interface; -} xhci_interface_descriptor_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t reserved0 : 8; - uint32_t deconfigure : 1; - uint32_t type : 6; - uint32_t reserved1 : 8; - uint32_t slot : 8; -} xhci_configure_endpoints_info_trb_t; - -typedef struct { - uint64_t base; - uint32_t status; - union { - xhci_configure_endpoints_info_trb_t info_s; - uint32_t info; - }; -} xhci_configure_endpoints_trb_t; - -typedef struct xhci_device { - uint64_t xhci_phys_base; - uint64_t xhci_virt_base; - uint64_t* dcbaa; - uint16_t calculated_scratchpad_count; - volatile xhci_cap_regs_t* cap; - volatile xhci_op_regs_t* op; - volatile xhci_port_regs_t* port; - volatile xhci_runtime_regs_t* runtime; - uint32_t* doorbell; - xhci_command_ring_ctx_t* com_ring; - xhci_event_ring_ctx_t* event_ring; - - uint32_t max_ports; - - uint8_t usb3ports[64]; - - struct xhci_device* next; -} __attribute__((packed)) xhci_device_t; - -typedef struct xhci_interface { - uint8_t type; - void* data; - - uint64_t len; - void* buffer; - - xhci_interface* next; -} xhci_interface_t; - -#define USB_TYPE_KEYBOARD 4 -#define USB_TYPE_MOUSE 3 - -typedef struct xhci_usb_device { - xhci_port_ring_ctx_t* transfer_ring; - xhci_usb_descriptor_t* desc; - xhci_config_descriptor_t* config; - xhci_device_t* dev; - xhci_input_ctx_t* input_ctx; - xhci_port_ring_ctx_t* ep_ctx[30]; - uint64_t phys_buffers[30]; - uint8_t* buffers[30]; - uint8_t main_ep; - uint16_t buffers_need_size[30]; - uint8_t doorbell_values[30]; - xhci_interface_t* interface; - struct xhci_usb_device* next; - uint64_t phys_input_ctx; - uint32_t slotid; - uint32_t portnum; - uint32_t type; - uint8_t _is64byte; - mouse_packet_t last_pack; - int evdev_num; - uint8_t add_buffer[8]; -} xhci_usb_device_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t reserved0 : 1; - uint32_t eventdata : 1; - uint32_t reserved1 : 7; - uint32_t type : 6; - uint32_t ep_id : 5; - uint32_t reserved2 : 3; - uint32_t slot : 8; -} xhci_done_info_trb_t; - -typedef struct { - uint64_t base; - struct { - uint32_t seek : 24; - uint32_t ret_code : 8; - }; - union { - xhci_done_info_trb_t info_s; - uint32_t info; - }; -} xhci_done_trb_t; - -typedef struct { - union { - struct { - uint8_t id; - uint8_t nextcap; - uint16_t info; - }; - uint32_t full; - }; -} xhci_ext_cap_t; - -typedef struct { - union { - struct { - uint8_t id; - uint8_t nextcap; - uint8_t minor; - uint8_t major; - }; - uint32_t firsthalf; - }; - - uint32_t name; - - union { - struct { - uint8_t portoffset; - uint8_t portcount; - uint8_t protocoldefine; - uint8_t protocolspeedid; - }; - uint32_t thirdhalf; - }; - - union { - struct { - uint8_t slottype : 4; - uint32_t reserved0 : 28; - }; - uint32_t fourhalf; - }; -} xhci_usb_cap_t; - -typedef struct { - uint8_t type; - uint8_t request; - uint16_t value; - uint16_t index; - uint16_t len; -} xhci_usb_command_t; - -typedef struct { - xhci_usb_command_t command; - uint32_t len : 17; - uint32_t reserved0 : 5; - uint32_t target : 10; - uint32_t cycle : 1; - uint32_t reserved1 : 4; - uint32_t intoncomp : 1; - uint32_t imdata : 1; - uint32_t reserved2 : 3; - uint32_t type : 6; - uint32_t trt : 2; - uint32_t reserved3 : 14; -} xhci_setupstage_trb_t; - -typedef struct { - uint64_t data; - uint32_t len : 17; - uint32_t tdsize : 5; - uint32_t target : 10; - uint32_t cycle : 1; - uint32_t evnexttrb : 1; - uint32_t intrshortpacket : 1; - uint32_t nosnoop : 1; - uint32_t chain : 1; - uint32_t introncomp : 1; - uint32_t imdata : 1; - uint32_t reserved0 : 3; - uint32_t type : 6; - uint32_t direction : 1; - uint32_t reserved1 : 15; -} xhci_datastage_trb_t; - -typedef struct { - uint64_t base; - uint32_t reserved0 : 22; - uint32_t target : 10; - uint32_t cycle : 1; - uint32_t evnext : 1; - uint32_t reserved1 : 2; - uint32_t chain : 1; - uint32_t intoncomp : 1; - uint32_t reserved2 : 3; - uint32_t blockevent : 1; - uint32_t type : 6; - uint32_t reserved3 : 16; -} xhci_eventdata_trb_t; - -typedef struct { - uint64_t reserved0; - uint32_t reserved1 : 22; - uint32_t target : 10; - uint32_t cycle : 1; - uint32_t evnext : 1; - uint32_t reserved2 : 2; - uint32_t chain : 1; - uint32_t intoncomp : 1; - uint32_t reserved3 : 4; - uint32_t type : 6; - uint32_t direction : 1; - uint32_t reserved4 : 15; -} xhci_statusstage_trb_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t ent : 1; - uint32_t isp : 1; - uint32_t nosnoop : 1; - uint32_t chain : 1; - uint32_t ioc : 1; - uint32_t imdata : 1; - uint32_t reserved0 : 2; - uint32_t bei : 1; - uint32_t type : 6; - uint32_t dir : 1; - uint32_t reserved1 : 15; -} xhci_normal_info_trb_t; - -typedef struct { - uint64_t base; - uint32_t trbtransferlen : 17; - uint32_t tdsize : 5; - uint32_t target : 10; - union { - xhci_normal_info_trb_t info_s; - uint32_t info; - }; -} xhci_normal_trb_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t reserved0 : 9; - uint32_t type : 6; - uint32_t reserved1 : 16; -} xhci_port_change_info_t; - -typedef struct { - struct { - uint32_t reserved0 : 24; - uint32_t port : 8; - }; - uint32_t status; - union { - xhci_port_change_info_t info_s; - uint32_t info; - }; -} xhci_port_change_trb_t; - -typedef struct xhci_hid_driver { - void (*func)(xhci_usb_device_t* usbdev,xhci_done_trb_t* trb); - int type; - struct xhci_hid_driver* next; -} xhci_hid_driver_t; - -#define XHCI_ENDPOINTTYPE_ISOCHRONOUS_OUT 1 -#define XHCI_ENDPOINTTYPE_BULK_OUT 2 -#define XHCI_ENDPOINTTYPE_INTERRUPT_OUT 3 -#define XHCI_ENDPOINTTYPE_ISOCHRONOUS_IN 5 -#define XHCI_ENDPOINTTYPE_BULK_IN 6 -#define XHCI_ENDPOINTTYPE_INTERRUPT_IN 7 -#define TRB_NORMAL_TYPE 1 -#define TRB_SETUPSTAGE_TYPE 2 -#define TRB_DATASTAGE_TYPE 3 -#define TRB_STATUSSTAGE_TYPE 4 -#define TRB_ISOCH_TYPE 5 -#define TRB_LINK_TYPE 6 -#define TRB_EVENTDATA_TYPE 7 -#define TRB_NOOP_TYPE 8 -#define TRB_ENABLESLOTCOMMAND_TYPE 9 -#define TRB_DISABLESLOTCOMMAND_TYPE 10 -#define TRB_ADDRESSDEVICECOMMAND_TYPE 11 -#define TRB_CONFIGUREENDPOINTCOMMAND_TYPE 12 -#define TRB_EVALUATECONTEXTCOMMAND_TYPE 13 -#define TRB_RESETENDPOINTCOMMAND_TYPE 14 -#define TRB_STOPENDPOINTCOMMAND_TYPE 15 -#define TRB_SETTRDEQPOINTERCOMMAND_TYPE 16 -#define TRB_RESETDEVICECOMMAND_TYPE 17 -#define TRB_FORCEEVENTCOMMAND_TYPE 18 -#define TRB_NEGBANDWIDTHCOMMAND_TYPE 19 -#define TRB_SETLATENCYCOMMAND_TYPE 20 -#define TRB_GETPORTBANDWIDTHCOMMAND_TYPE 21 -#define TRB_FORCEHEADERCOMMAND_TYPE 22 -#define TRB_NOOPCOMMAND_TYPE 23 -#define TRB_TRANSFEREVENT_TYPE 32 -#define TRB_COMMANDCOMPLETIONEVENT_TYPE 33 -#define TRB_PORTSTATUSCHANGEEVENT_TYPE 34 -#define TRB_HOSTCONTROLLEREVENT_TYPE 37 -#define TRB_DEVICENOTIFICATIONEVENT_TYPE 38 -#define TRB_MFINDEXWARPEVENT_TYPE 39 - -int xhci_init();
\ No newline at end of file diff --git a/kernel/include/etc/assembly.hpp b/kernel/include/etc/assembly.hpp deleted file mode 100644 index 851ac8f..0000000 --- a/kernel/include/etc/assembly.hpp +++ /dev/null @@ -1,51 +0,0 @@ - -#include <cstdint> - -#pragma once - -inline std::uint64_t __rdmsr(std::uint32_t msr) { - std::uint32_t lo, hi; - __asm__ volatile ("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr)); - return ((std::uint64_t)hi << 32) | lo; -} - -inline void __wrmsr(std::uint32_t msr, std::uint64_t value) { - std::uint32_t lo = (uint32_t)(value & 0xFFFFFFFF); - std::uint32_t hi = (uint32_t)(value >> 32); - __asm__ volatile ("wrmsr" : : "c"(msr), "a"(lo), "d"(hi)); -} - -inline void __nop() { - __asm__ volatile ("nop"); -} - -inline void __cli() { - __asm__ volatile ("cli"); -} - -inline void __sti() { - __asm__ volatile ("sti"); -} - -inline void __hlt() { - __asm__ volatile ("hlt"); -} - -inline void __invlpg(unsigned long long virt) { - __asm__ volatile ("invlpg (%0)" : : "r" (virt) : "memory"); -} - -inline void __cpuid(int code, int code2, std::uint32_t *a, std::uint32_t *b, std::uint32_t *c , std::uint32_t *d) { - __asm__ volatile("cpuid":"=a"(*a),"=b"(*b),"=c"(*c),"=d"(*d):"a"(code),"c"(code2)); -} - -inline int __cpuid_string(int code, std::uint32_t where[4]) { - __asm__ volatile("cpuid":"=a"(*where),"=b"(*(where+1)),"=c"(*(where+2)),"=d"(*(where+3)):"a"(code)); - return (int)where[0]; -} - -inline std::uint64_t __rdtsc() { - unsigned int hi, lo; - __asm__ volatile ("rdtsc" : "=a"(lo), "=d"(hi)); - return ((uint64_t)hi << 32) | lo; -}
\ No newline at end of file diff --git a/kernel/include/etc/bootloaderinfo.hpp b/kernel/include/etc/bootloaderinfo.hpp deleted file mode 100644 index b3d1ca8..0000000 --- a/kernel/include/etc/bootloaderinfo.hpp +++ /dev/null @@ -1,16 +0,0 @@ - -#pragma once - -#include <cstdint> -#include <limine.h> - -class BootloaderInfo { -public: - static struct limine_framebuffer* AccessFramebuffer(); - static std::uint64_t AccessHHDM(); - static std::uint64_t AccessRSDP(); - static struct limine_memmap_response* AccessMemoryMap(); - static struct limine_executable_address_response* AccessKernel(); - static struct LIMINE_MP(response)* AccessMP(); - static struct limine_module_response* AccessInitrd(); -};
\ No newline at end of file diff --git a/kernel/include/etc/errno.hpp b/kernel/include/etc/errno.hpp deleted file mode 100644 index b066d1c..0000000 --- a/kernel/include/etc/errno.hpp +++ /dev/null @@ -1,167 +0,0 @@ - -#pragma once - -#define EPERM 1 -#define ENOENT 2 -#define ESRCH 3 -#define EINTR 4 -#define EIO 5 -#define ENXIO 6 -#define E2BIG 7 -#define ENOEXEC 8 -#define EBADF 9 -#define ECHILD 10 -#define EAGAIN 11 -#define ENOMEM 12 -#define EACCES 13 -#define EFAULT 14 -#define ENOTBLK 15 -#define EBUSY 16 -#define EEXIST 17 -#define EXDEV 18 -#define ENODEV 19 -#define ENOTDIR 20 -#define EISDIR 21 -#define EINVAL 22 -#define ENFILE 23 -#define EMFILE 24 -#define ENOTTY 25 -#define ETXTBSY 26 -#define EFBIG 27 -#define ENOSPC 28 -#define ESPIPE 29 -#define EROFS 30 -#define EMLINK 31 -#define EPIPE 32 -#define EDOM 33 -#define ERANGE 34 -#define EDEADLK 35 -#define ENAMETOOLONG 36 -#define ENOLCK 37 -#define ENOSYS 38 -#define ENOTEMPTY 39 -#define ELOOP 40 -#define EWOULDBLOCK EAGAIN -#define ENOMSG 42 -#define EIDRM 43 -#define ECHRNG 44 -#define EL2NSYNC 45 -#define EL3HLT 46 -#define EL3RST 47 -#define ELNRNG 48 -#define EUNATCH 49 -#define ENOCSI 50 -#define EL2HLT 51 -#define EBADE 52 -#define EBADR 53 -#define EXFULL 54 -#define ENOANO 55 -#define EBADRQC 56 -#define EBADSLT 57 -#define EDEADLOCK EDEADLK -#define EBFONT 59 -#define ENOSTR 60 -#define ENODATA 61 -#define ETIME 62 -#define ENOSR 63 -#define ENONET 64 -#define ENOPKG 65 -#define EREMOTE 66 -#define ENOLINK 67 -#define EADV 68 -#define ESRMNT 69 -#define ECOMM 70 -#define EPROTO 71 -#define EMULTIHOP 72 -#define EDOTDOT 73 -#define EBADMSG 74 -#define EOVERFLOW 75 -#define ENOTUNIQ 76 -#define EBADFD 77 -#define EREMCHG 78 -#define ELIBACC 79 -#define ELIBBAD 80 -#define ELIBSCN 81 -#define ELIBMAX 82 -#define ELIBEXEC 83 -#define EILSEQ 84 -#define ERESTART 85 -#define ESTRPIPE 86 -#define EUSERS 87 -#define ENOTSOCK 88 -#define EDESTADDRREQ 89 -#define EMSGSIZE 90 -#define EPROTOTYPE 91 -#define ENOPROTOOPT 92 -#define EPROTONOSUPPORT 93 -#define ESOCKTNOSUPPORT 94 -#define EOPNOTSUPP 95 -#define ENOTSUP EOPNOTSUPP -#define EPFNOSUPPORT 96 -#define EAFNOSUPPORT 97 -#define EADDRINUSE 98 -#define EADDRNOTAVAIL 99 -#define ENETDOWN 100 -#define ENETUNREACH 101 -#define ENETRESET 102 -#define ECONNABORTED 103 -#define ECONNRESET 104 -#define ENOBUFS 105 -#define EISCONN 106 -#define ENOTCONN 107 -#define ESHUTDOWN 108 -#define ETOOMANYREFS 109 -#define ETIMEDOUT 110 -#define ECONNREFUSED 111 -#define EHOSTDOWN 112 -#define EHOSTUNREACH 113 -#define EALREADY 114 -#define EINPROGRESS 115 -#define ESTALE 116 -#define EUCLEAN 117 -#define ENOTNAM 118 -#define ENAVAIL 119 -#define EISNAM 120 -#define EREMOTEIO 121 -#define EDQUOT 122 -#define ENOMEDIUM 123 -#define EMEDIUMTYPE 124 -#define ECANCELED 125 -#define ENOKEY 126 -#define EKEYEXPIRED 127 -#define EKEYREVOKED 128 -#define EKEYREJECTED 129 -#define EOWNERDEAD 130 -#define ENOTRECOVERABLE 131 -#define ERFKILL 132 -#define EHWPOISON 133 - -#define SIGHUP 1 -#define SIGQUIT 3 -#define SIGTRAP 5 -#define SIGIOT SIGABRT -#define SIGBUS 7 -#define SIGKILL 9 -#define SIGUSR1 10 -#define SIGUSR2 12 -#define SIGPIPE 13 -#define SIGALRM 14 -#define SIGSTKFLT 16 -#define SIGCHLD 17 -#define SIGCONT 18 -#define SIGSTOP 19 -#define SIGABRT 6 -#define SIGTSTP 20 -#define SIGTTIN 21 -#define SIGTTOU 22 -#define SIGURG 23 -#define SIGXCPU 24 -#define SIGXFSZ 25 -#define SIGVTALRM 26 -#define SIGPROF 27 -#define SIGWINCH 28 -#define SIGPOLL 29 -#define SIGSYS 31 -#define SIGUNUSED SIGSYS -#define SIGCANCEL 32 -#define SIGTIMER 33
\ No newline at end of file diff --git a/kernel/include/etc/etc.hpp b/kernel/include/etc/etc.hpp deleted file mode 100644 index 2bc5235..0000000 --- a/kernel/include/etc/etc.hpp +++ /dev/null @@ -1,49 +0,0 @@ - -#pragma once - -#include <etc/bootloaderinfo.hpp> -#include <cstdint> - -#define ALIGNUP(VALUE,c) ((VALUE + c - 1) & ~(c - 1)) -#define ALIGNDOWN(VALUE,c) ((VALUE / c) * c) -#define ALIGNPAGEUP(VALUE) (ALIGNUP(VALUE,4096)) -#define PAGE_SIZE 4096 - -static inline uint64_t get_rflags() { - uint64_t rflags; - - __asm__ volatile ( - "pushfq\n\t" - "popq %0" - : "=r"(rflags) - : - : "memory" - ); - return rflags; -} - -static inline int is_sti() { - std::uint64_t eflags = get_rflags(); - return (eflags & (1 << 9)) != 0; -} - -class Other { -public: - static void ConstructorsInit(); - - static inline std::uint64_t toPhys(void* addr) { - uint64_t hhdm = BootloaderInfo::AccessHHDM(); - return (uint64_t)addr - hhdm; - } - - static inline void* toVirt(uint64_t phys) { - uint64_t hhdm = BootloaderInfo::AccessHHDM(); - return (void*)(phys + hhdm); - } - - static inline std::uint64_t toPhys(std::uint64_t addr) { - uint64_t hhdm = BootloaderInfo::AccessHHDM(); - return (uint64_t)addr - hhdm; - } - -};
\ No newline at end of file diff --git a/kernel/include/etc/hash.hpp b/kernel/include/etc/hash.hpp deleted file mode 100644 index 0c0f7ec..0000000 --- a/kernel/include/etc/hash.hpp +++ /dev/null @@ -1,21 +0,0 @@ - -#include <cstdint> -#include <generic/mm/pmm.hpp> -#include <etc/libc.hpp> - -#pragma once - -#define FNV_OFFSET 14695981039346656037UL -#define FNV_PRIME 1099511628211UL - -static inline std::uint64_t hash_fnv1(const char* key) { - std::uint64_t hash = FNV_OFFSET; - for (const char* p = key; *p; p++) { - hash ^= (std::uint64_t)(unsigned char)(*p); - hash *= FNV_PRIME; - } - return hash; -} - -#include <cstddef> -#include <cstdint> diff --git a/kernel/include/etc/libc.hpp b/kernel/include/etc/libc.hpp deleted file mode 100644 index 4eaaddf..0000000 --- a/kernel/include/etc/libc.hpp +++ /dev/null @@ -1,302 +0,0 @@ - -// simple libc basic memory implementations - -#pragma once - -#include <stdint.h> -#include <stddef.h> -#include <generic/mm/heap.hpp> - -static inline void* memcpy(void* dest, const void* src, size_t n) { - if (n == 0) return dest; - - void* ret = dest; - - __asm__ volatile ( - "cld\n" - "rep movsb\n" - : "+D" (dest), "+S" (src), "+c" (n) - : - : "memory" - ); - - return ret; -} - -// used from glibc -typedef unsigned long long op_t; -#define OPSIZ 8 -typedef char byte; - -inline void * __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns"))) memset (void *dstpp, int c, size_t len) -{ - long int dstp = (long int) dstpp; - - if (len >= 8) - { - size_t xlen; - op_t cccc; - - cccc = (unsigned char) c; - cccc |= cccc << 8; - cccc |= cccc << 16; - if (OPSIZ > 4) - /* Do the shift in two steps to avoid warning if long has 32 bits. */ - cccc |= (cccc << 16) << 16; - - /* There are at least some bytes to set. - No need to test for LEN == 0 in this alignment loop. */ - while (dstp % OPSIZ != 0) - { - ((byte *) dstp)[0] = c; - dstp += 1; - len -= 1; - } - - /* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */ - xlen = len / (OPSIZ * 8); - while (xlen > 0) - { - ((op_t *) dstp)[0] = cccc; - ((op_t *) dstp)[1] = cccc; - ((op_t *) dstp)[2] = cccc; - ((op_t *) dstp)[3] = cccc; - ((op_t *) dstp)[4] = cccc; - ((op_t *) dstp)[5] = cccc; - ((op_t *) dstp)[6] = cccc; - ((op_t *) dstp)[7] = cccc; - dstp += 8 * OPSIZ; - xlen -= 1; - } - len %= OPSIZ * 8; - - /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */ - xlen = len / OPSIZ; - while (xlen > 0) - { - ((op_t *) dstp)[0] = cccc; - dstp += OPSIZ; - xlen -= 1; - } - len %= OPSIZ; - } - - /* Write the last few bytes. */ - while (len > 0) - { - ((byte *) dstp)[0] = c; - dstp += 1; - len -= 1; - } - - return dstpp; -} - -#define zeromem(x) memset(x,0,sizeof(*x)) - -inline void *memmove(void *dest, const void *src, size_t n) { - uint8_t *pdest = static_cast<uint8_t *>(dest); - const uint8_t *psrc = static_cast<const uint8_t *>(src); - - if (src > dest) { - for (size_t i = 0; i < n; i++) { - pdest[i] = psrc[i]; - } - } else if (src < dest) { - for (size_t i = n; i > 0; i--) { - pdest[i-1] = psrc[i-1]; - } - } - - return dest; -} - -inline int memcmp(const void *s1, const void *s2, size_t n) { - const uint8_t *p1 = static_cast<const uint8_t *>(s1); - const uint8_t *p2 = static_cast<const uint8_t *>(s2); - - for (size_t i = 0; i < n; i++) { - if (p1[i] != p2[i]) { - return p1[i] < p2[i] ? -1 : 1; - } - } - - return 0; -} - - - -inline char* strcat(char* dest, const char* src) { - - char* ptr = dest; - while(*ptr != '\0') { - ptr++; - } - - while(*src != '\0') { - *ptr = *src; - ptr++; - src++; - } - - *ptr = '\0'; - - return dest; -} - -inline int strlen (const char *str) -{ - const char *char_ptr; - const unsigned long int *longword_ptr; - unsigned long int longword, himagic, lomagic; - - /* Handle the first few characters by reading one character at a time. - Do this until CHAR_PTR is aligned on a longword boundary. */ - for (char_ptr = str; ((unsigned long int) char_ptr - & (sizeof (longword) - 1)) != 0; - ++char_ptr) - if (*char_ptr == '\0') - return char_ptr - str; - - /* All these elucidatory comments refer to 4-byte longwords, - but the theory applies equally well to 8-byte longwords. */ - - longword_ptr = (unsigned long int *) char_ptr; - - /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits - the "holes." Note that there is a hole just to the left of - each byte, with an extra at the end: - - bits: 01111110 11111110 11111110 11111111 - bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD - - The 1-bits make sure that carries propagate to the next 0-bit. - The 0-bits provide holes for carries to fall into. */ - himagic = 0x80808080L; - lomagic = 0x01010101L; - if (sizeof (longword) > 4) - { - /* 64-bit version of the magic. */ - /* Do the shift in two steps to avoid a warning if long has 32 bits. */ - himagic = ((himagic << 16) << 16) | himagic; - lomagic = ((lomagic << 16) << 16) | lomagic; - } - - /* Instead of the traditional loop which tests each character, - we will test a longword at a time. The tricky part is testing - if *any of the four* bytes in the longword in question are zero. */ - for (;;) - { - longword = *longword_ptr++; - - if (((longword - lomagic) & ~longword & himagic) != 0) - { - /* Which of the bytes was the zero? If none of them were, it was - a misfire; continue the search. */ - - const char *cp = (const char *) (longword_ptr - 1); - - if (cp[0] == 0) - return cp - str; - if (cp[1] == 0) - return cp - str + 1; - if (cp[2] == 0) - return cp - str + 2; - if (cp[3] == 0) - return cp - str + 3; - if (sizeof (longword) > 4) - { - if (cp[4] == 0) - return cp - str + 4; - if (cp[5] == 0) - return cp - str + 5; - if (cp[6] == 0) - return cp - str + 6; - if (cp[7] == 0) - return cp - str + 7; - } - } - } -} -inline void* malloc(size_t size) { - return memory::heap::malloc(size); -} - -inline void free(void* p) { - memory::heap::free(p); -} - -#define strcpy(dest,src) memcpy(dest,src,strlen(src) + 1) - -inline int strcmp(const char *s1, const char *s2) { - const unsigned long *w1 = (const unsigned long *)s1; - const unsigned long *w2 = (const unsigned long *)s2; - const unsigned long himagic = 0x8080808080808080UL; - const unsigned long lomagic = 0x0101010101010101UL; - - while (1) { - unsigned long word1 = *w1++; - unsigned long word2 = *w2++; - - unsigned long diff = word1 ^ word2; - unsigned long zeros = (word1 - lomagic) & ~word1 & himagic; - - if (diff != 0 || zeros != 0) { - const char *c1 = (const char *)(w1 - 1); - const char *c2 = (const char *)(w2 - 1); - - do { - unsigned char ch1 = *c1++; - unsigned char ch2 = *c2++; - if (ch1 != ch2) return ch1 - ch2; - if (ch1 == 0) break; - } while (1); - - return 0; - } - } -} -inline int strncmp(const char *s1, const char *s2, size_t n) { - size_t i = 0; - while (i < n && s1[i] && (s1[i] == s2[i])) { - i++; - } - if (i == n) return 0; - return (unsigned char)s1[i] - (unsigned char)s2[i]; -} - -inline char *strchr(const char *s, int c) { - while (*s) { - if (*s == (char)c) return (char *)s; - s++; - } - return NULL; -} - -char *strtok(char *str, const char *delim); - -inline char* strdup(const char *s) { - size_t len = 0; - while (s[len]) len++; - - char *copy = (char *)malloc(len + 1); - if (!copy) return NULL; - - for (size_t i = 0; i <= len; i++) { - copy[i] = s[i]; - } - return copy; -} - -inline char* strrchr(const char* str, int ch) { - char* last_occurrence = 0; - - while (*str) { - if (*str == ch) { - last_occurrence = (char*)str; - } - str++; - } - - return last_occurrence; -}
\ No newline at end of file diff --git a/kernel/include/etc/list.hpp b/kernel/include/etc/list.hpp deleted file mode 100644 index d8059da..0000000 --- a/kernel/include/etc/list.hpp +++ /dev/null @@ -1,219 +0,0 @@ -#include <cstdint> -#include <atomic> -#include <generic/locks/spinlock.hpp> -#include <etc/libc.hpp> -#include <etc/etc.hpp> - -#include <etc/logging.hpp> - -#pragma once - -namespace Lists { - - typedef struct list_object { - std::uint64_t value; - std::uint8_t is_used; - std::uint64_t next_list_object; /* Pointer to next list_object */ - } __attribute__((packed)) list_object_t; - - class Bitmap { - private: - public: - - std::uint8_t* pool; - std::uint32_t pool_size; - - Bitmap(std::uint32_t size) { - pool_size = (ALIGNUP(size,8) / 8) + 1; - pool = (std::uint8_t*)malloc(pool_size); - memset(pool,0,pool_size); - } - - std::uint8_t test(std::uint32_t idx) { - return pool[ALIGNDOWN(idx,8) / 8] & (1 << (idx - ALIGNDOWN(idx,8))); - } - - void clear(std::uint32_t idx) { - pool[ALIGNDOWN(idx,8) / 8] &= ~(1 << (idx - ALIGNDOWN(idx,8))); - } - - void set(std::uint32_t idx) { - pool[ALIGNDOWN(idx,8) / 8] |= (1 << (idx - ALIGNDOWN(idx,8))); - } - - }; - - class List { - private: - - locks::spinlock* list_lock; - - std::uint8_t is_lock_possible; - - static std::uint64_t normalize(std::uint64_t value) { - return value; - } - - static Lists::list_object_t* iterate(Lists::list_object_t* last) { - return (Lists::list_object_t*)normalize(last->next_list_object); - } - - Lists::list_object_t* find_free() { - Lists::list_object_t* current = list; - while(current) { - if(!current->is_used) - return current; - current = iterate(current); - } - return 0; - } - - public: - Lists::list_object_t* list; - - void lock() { - list_lock->lock(); - } - - void unlock() { - list_lock->unlock(); - } - - void insert(std::uint64_t value) { - list_lock->lock(); - - Lists::list_object_t* new_list = find_free(); - - if(!new_list) { - new_list = new Lists::list_object_t; - new_list->next_list_object = (std::uint64_t)list; - list = new_list; - } - - new_list->is_used = 1; - new_list->value = value; - - list_lock->unlock(); - } - - void remove(std::uint64_t value) { - list_lock->lock(); - - Lists::list_object_t* current = list; - - while(current) { - if(current->value == value) { - current->is_used = 0; - current->value = 0; - } - current = iterate(current); - } - - list_lock->unlock(); - } - - List() { - list = new Lists::list_object_t; - list_lock = new locks::spinlock(); - } - }; - - typedef struct { - std::uint32_t cycle; - std::uint64_t value1; - - } ring_obj_t; - - typedef struct { - ring_obj_t* objs; - int bytelen; - int tail; - int size; - int cycle; - } ring_buffer_t; - - - class Ring { - private: - public: - ring_buffer_t ring; - - locks::spinlock ring_lock; - - std::uint64_t read_counter = 0; - std::uint64_t write_counter = 0; - - void send(std::uint64_t value1) { - ring_lock.lock(); - ring.objs[ring.tail].cycle = ring.cycle; - ring.objs[ring.tail].value1 = value1; - - read_counter++; - - if (++ring.tail == ring.size) { - ring.tail = 0; - ring.cycle = !ring.cycle; - } - ring_lock.unlock(); - } - - int setup_bytelen(int len) { - ring.bytelen = len; - return len; - } - - int isnotempty(int* queue0, char* cycle0) { - char cycle = *cycle0; - int queue = *queue0; - while (ring.objs[queue].cycle == cycle) { - return 1; - queue = queue + 1; - if (queue == ring.size) { - queue = 0; - cycle = !(cycle); - } - } - return 0; - } - - int receivevals(void* out, int id, int max, std::uint8_t* cycle, std::uint32_t* queue) { - ring_lock.lock(); - int len = 0; - while (ring.objs[*queue].cycle == *cycle && len * ring.bytelen < max) { - if (ring.bytelen == 1) { - ((char*)out)[len] = ring.objs[*queue].value1 & 0xFF; - } else if (ring.bytelen == 2) { - ((short*)out)[len] = ring.objs[*queue].value1 & 0xFFFF; - } else if (ring.bytelen == 4) { - ((int*)out)[len] = ring.objs[*queue].value1 & 0xFFFFFFFF; - } else if (ring.bytelen == 8) { - ((long long*)out)[len] = ring.objs[*queue].value1; - } - *queue = *queue + 1; - if (*queue == ring.size) { - *queue = 0; - *cycle = !(*cycle); - } - len++; - } - ring_lock.unlock(); - return len * ring.bytelen; - } - - Ring(std::size_t size_elements) { - ring.objs = new ring_obj_t[size_elements]; - ring.size = size_elements; - ring.tail = 0; - ring.cycle = 1; - ring.bytelen = 0; - ring_lock.unlock(); - memset(ring.objs, 0, sizeof(ring_obj_t) * size_elements); - } - - ~Ring() { - delete[] ring.objs; - } - - }; - -};
\ No newline at end of file diff --git a/kernel/include/etc/logging.hpp b/kernel/include/etc/logging.hpp deleted file mode 100644 index 47ea251..0000000 --- a/kernel/include/etc/logging.hpp +++ /dev/null @@ -1,64 +0,0 @@ - -#pragma once - -#define LEVEL_MESSAGE_OK 0 -#define LEVEL_MESSAGE_FAIL 1 -#define LEVEL_MESSAGE_WARN 2 -#define LEVEL_MESSAGE_INFO 3 - -#include <flanterm.h> -#include <flanterm_backends/fb.h> - -#include <cstdarg> - -int __snprintf(char *buffer, size_t bufsz, char const *fmt, va_list vlist); -int __printfbuf(char* buffer, size_t bufsf, char const* fmt, ...); - -struct winsizez { - unsigned short ws_row; - unsigned short ws_col; - unsigned short ws_xpixel; -/* unused */ - unsigned short ws_ypixel; -/* unused */ -}; - -class Log { -private: - struct flanterm_context* ft_ctx0; -public: - - void Setup(struct flanterm_context* ft_ctx) { - ft_ctx0 = ft_ctx; - } - - void Write(char* buffer, int len) { - flanterm_write(ft_ctx0,buffer,len); - } - - static void Raw(char* msg,...); - static void Init(); - static void RawDisp(char* buffer, int len); - static void Display(int level,char* msg,...); - static void SerialDisplay(int level,char* msg,...); - static winsizez GetDimensions(); -}; - -void dmesg0(char* msg,...); -std::uint64_t dmesg_bufsize(); - -void dmesg_read(char* buffer,std::uint64_t count); - -#include <drivers/tsc.hpp> - -void panic_wrap(const char* msg, ...); - -#define assert(cond, msg,...) if(!(cond)) panic_wrap("Failed assert at %s:%s:%d \"" msg "\"\n" , __FILE__ ,__FUNCTION__, __LINE__ , ##__VA_ARGS__) - -#define printf(fmt,...) if(1) Log::Raw(fmt, ##__VA_ARGS__) - -#define dmesg(fmt,...) if(1) dmesg0("[%llu] %s: " fmt "\n", drivers::tsc::currentus() ,__FUNCTION__, ##__VA_ARGS__) -#define BREAKPOINT() Log::Display(LEVEL_MESSAGE_INFO,"breakpoint %s:%d\n ",__FILE__,__LINE__) - -#define DEBUG(is_enabled,fmt,...) if(is_enabled) Log::SerialDisplay(LEVEL_MESSAGE_INFO,"[%llu] %s: " fmt "\n", drivers::tsc::currentus() ,__FUNCTION__, ##__VA_ARGS__) -#define STUB(is_enabled) if(is_enabled) Log::SerialDisplay(LEVEL_MESSAGE_INFO, "%s() is a stub !\n", __FUNCTION__)
\ No newline at end of file diff --git a/kernel/include/generic/locks/spinlock.hpp b/kernel/include/generic/locks/spinlock.hpp deleted file mode 100644 index d8b1b28..0000000 --- a/kernel/include/generic/locks/spinlock.hpp +++ /dev/null @@ -1,50 +0,0 @@ - -#include <cstdint> -#include <atomic> - -#pragma once - -#include <etc/logging.hpp> -#include <etc/assembly.hpp> - -extern "C" void yield0(); - -namespace locks { - class spinlock { - private: - volatile std::atomic_flag flag = ATOMIC_FLAG_INIT; - char is_cli = 0; - public: - spinlock() { - - } - - void lock() { - while(flag.test_and_set(std::memory_order_acquire)) { - asm volatile("nop"); - - } - } - - void enable_scheduling_optimization() { - is_cli = 1; - } - - std::uint8_t test_and_set() { - return flag.test_and_set(std::memory_order_acquire); - } - - void nowaitlock() { - flag.test_and_set(std::memory_order_acquire); - } - - void unlock() { - flag.clear(std::memory_order_release); - } - - std::uint8_t test() { - return flag.test(); - } - - }; -};
\ No newline at end of file diff --git a/kernel/include/generic/mm/heap.hpp b/kernel/include/generic/mm/heap.hpp deleted file mode 100644 index 6a49a91..0000000 --- a/kernel/include/generic/mm/heap.hpp +++ /dev/null @@ -1,23 +0,0 @@ - -#include <cstdint> -#include <cstddef> - -#pragma once - -typedef struct heap_block { - std::uint32_t size; - std::uint8_t is_free; - struct heap_block* next; -} heap_block_t; - -namespace memory { - class heap { - public: - static void init(); - static void free(void* ptr); - static void* malloc(std::uint32_t size); - - static void lock(); - static void unlock(); - }; -};
\ No newline at end of file diff --git a/kernel/include/generic/mm/paging.hpp b/kernel/include/generic/mm/paging.hpp deleted file mode 100644 index 0cb5a19..0000000 --- a/kernel/include/generic/mm/paging.hpp +++ /dev/null @@ -1,61 +0,0 @@ - -#include <cstdint> -#include <etc/assembly.hpp> - -#pragma once - -#define PTE_MASK_VALUE 0x000ffffffffff000 - -#define PTE_PRESENT (1 << 0) -#define PTE_RW (1 << 1) -#define PTE_USER (1 << 2) -#define PTE_WC ((1 << 7) | (1 << 3)) -#define PTE_MMIO (1ull << 4) - -#define PTE_INDEX(address,bit) ((address & (uint64_t)0x1FF << bit) >> bit) - -typedef struct alwaysmapped { - std::uint64_t phys; - std::uint64_t len; - struct alwaysmapped* next; -} alwaysmapped_t; - -namespace memory { - - inline void pat(std::uint8_t index, std::uint8_t type) { - std::uint64_t pat = __rdmsr(0x277); - pat &= ~(0xFFULL << (index * 8)); - pat |= ((std::uint64_t)type << (index * 8)); - __wrmsr(0x277, pat); - } - - class paging { - public: - static void init(); - static void map(std::uint64_t cr3,std::uint64_t phys,std::uint64_t virt,std::uint64_t flags); - static void mapid(std::uint64_t cr3,std::uint64_t phys,std::uint64_t virt,std::uint64_t flags,std::uint32_t id); - static void maprange(std::uint64_t cr3,std::uint64_t phys,std::uint64_t virt,std::uint64_t len,std::uint64_t flags); - static void* maprangeret(std::uint64_t phys,std::uint64_t len,std::uint64_t flags); - static void zerorange(std::uint64_t cr3,std::uint64_t virt,std::uint64_t len); - static void destroyrange(std::uint64_t cr3, std::uint64_t virt, std::uint64_t len); - static void duplicaterangeifexists(std::uint64_t src_cr3, std::uint64_t dest_cr3, std::uint64_t virt, std::uint64_t len, std::uint64_t flags); - static void maprangeid(std::uint64_t cr3,std::uint64_t phys,std::uint64_t virt,std::uint64_t len,std::uint64_t flags, std::uint32_t id); - static void mapentry(std::uint64_t cr3,std::uint8_t type,std::uint64_t add_flags); - static void mapkernel(std::uint64_t cr3,std::uint32_t id); - static void* kernelmap(std::uint64_t cr3,std::uint64_t phys); - static void enablekernel(); - static void enablepaging(std::uint64_t cr3); - static void alwaysmappedadd(std::uint64_t phys, std::uint64_t len); - static void alwaysmappedmap(std::uint64_t cr3,std::uint32_t id); - static std::uint64_t kernelget(); - - static void destroy(std::uint64_t cr3); - - static void change(std::uint64_t cr3, std::uint64_t virt, std::uint64_t flags); - - static void changerange(std::uint64_t cr3, std::uint64_t virt, std::uint64_t len , std::uint64_t flags); - - - }; - -};
\ No newline at end of file diff --git a/kernel/include/generic/mm/pmm.hpp b/kernel/include/generic/mm/pmm.hpp deleted file mode 100644 index c6dfbfa..0000000 --- a/kernel/include/generic/mm/pmm.hpp +++ /dev/null @@ -1,103 +0,0 @@ - -#include <cstdint> -#include <cstddef> - -#include <etc/libc.hpp> - -#pragma once - -#define LEVEL_TO_SIZE(level) (1U << (level)) -#define MAX_LEVEL 32 - -typedef struct buddy_info { - union { - struct { - std::uint16_t level : 8; - std::uint16_t is_was_splitted : 1; - std::uint16_t is_splitted : 1; - std::uint16_t is_free : 1; - std::uint16_t split_x : 1; - }; - std::uint16_t buddy_info_raw; - }; - struct buddy_info* parent; - struct buddy_info* twin; - std::uint32_t id; - std::uint64_t phys; -} __attribute__((packed)) buddy_info_t; - -typedef struct { - buddy_info_t* first; - buddy_info_t* second; -} buddy_split_t; - -typedef struct { - uint64_t buddy_queue; - uint64_t total_size; - buddy_info_t* mem; -} __attribute__((packed)) buddy_t; - -typedef struct { - std::uint64_t virt; - std::uint64_t real_size; //optimization for tmpfs -} alloc_t; - - -namespace memory { - - class buddy { - private: - static buddy_info_t* split_maximum(buddy_info_t* blud, std::uint64_t size); - static buddy_info_t* put(std::uint64_t phys, std::uint8_t level); - static buddy_split_t split(buddy_info_t* info); - static void merge(buddy_info_t* budy); - public: - static void init(); - static int free(std::uint64_t phys); - static void fullfree(std::uint32_t id); - static alloc_t alloc_ext(std::size_t size); - static std::int64_t alloc(std::size_t size); - static std::int64_t allocid(std::size_t size, std::uint32_t id); - }; - - class freelist { - public: - static int free(std::uint64_t phys); - static std::int64_t alloc(); - }; - - namespace pmm { - - - class _physical { - public: - static void init(); - static void free(std::uint64_t phys); - static void fullfree(std::uint32_t id); - static alloc_t alloc_ext(std::size_t size); - static std::int64_t alloc(std::size_t size); - static std::int64_t allocid(std::size_t size, std::uint32_t id); - - static void lock(); - static void unlock(); - - }; - class _virtual { - public: - static void free(void* virt); - static void* alloc(std::size_t size); - - static inline void* realloc(void* virt, std::size_t old_size, std::size_t new_size) { - void* new_virt = alloc(new_size); - memcpy(new_virt,virt,old_size); - free(virt); - return new_virt; - } - - }; - class helper { - public: - static std::uint64_t alloc_kernel_stack(std::size_t size); - }; - }; -};
\ No newline at end of file diff --git a/kernel/include/generic/mm/vmm.hpp b/kernel/include/generic/mm/vmm.hpp deleted file mode 100644 index 5a352c1..0000000 --- a/kernel/include/generic/mm/vmm.hpp +++ /dev/null @@ -1,919 +0,0 @@ - -#include <cstdint> - -#pragma once - -#include <arch/x86_64/scheduling.hpp> - -#include <etc/libc.hpp> -#include <etc/etc.hpp> - -#include <generic/mm/paging.hpp> -#include <generic/mm/pmm.hpp> -#include <arch/x86_64/syscalls/shm.hpp> - -#include <drivers/cmos.hpp> - -#include <config.hpp> - -#include <etc/assembly.hpp> - -#include <etc/logging.hpp> - -void shm_rm(shm_seg_t* seg); - -typedef struct vmm_obj { - uint64_t base; - uint64_t phys; - uint64_t len; - uint64_t flags; - - int pthread_count; - - uint8_t is_shared; - uint8_t is_mapped; - - uint8_t is_free; - uint8_t is_lazy_alloc; - uint8_t is_lazy_allocated; - - uint8_t is_even_need_to_free; - - int* how_much_connected; // used for sharedmem - locks::spinlock lock; - - uint64_t src_len; - - shm_seg_t* shm; - - struct vmm_obj* next; -} __attribute__((packed)) vmm_obj_t; - -extern std::int64_t __memory_paging_getphys(std::uint64_t cr3, std::uint64_t virt); - -namespace memory { - class vmm { - public: - - inline static void initproc(arch::x86_64::process_t* proc) { - vmm_obj_t* start = new vmm_obj_t; - vmm_obj_t* end = new vmm_obj_t; - start->is_mapped = 1; - end->is_mapped = 1; - zeromem(start); - zeromem(end); - start->len = 4096; - start->next = end; - start->pthread_count = 1; - end->base = (std::uint64_t)Other::toVirt(0) - 4096; - end->next = start; - proc->vmm_start = (char*)start; - proc->vmm_end = (char*)end; - } - - inline static vmm_obj_t* find_free(vmm_obj_t* start, std::uint64_t len) { - return 0; - } - - inline static vmm_obj_t* v_alloc(vmm_obj_t* start,std::uint64_t len) { - vmm_obj_t* current = start->next; - vmm_obj_t* prev = start; - uint64_t found = 0; - - uint64_t align_length = ALIGNUP(len,4096); - len = align_length; - - vmm_obj_t* top = find_free(start,len); - if(top) { - top->is_lazy_alloc = 0; - top->is_lazy_allocated = 0; - top->is_free = 0; - top->is_shared = 0; - top->is_mapped = 0; - return top; - } - - while(current) { - - if(prev) { - - uint64_t prev_end = (prev->base + prev->len); - if(current->base - prev_end >= align_length) { - - vmm_obj_t* vmm_new = new vmm_obj_t; - vmm_new->base = prev_end; - vmm_new->len = align_length; - vmm_new->is_lazy_alloc = 0; - vmm_new->is_lazy_allocated = 0; - vmm_new->is_shared = 0; - vmm_new->is_free = 0; - prev->next = vmm_new; - vmm_new->next = current; - - vmm_new->is_mapped = 0; - - return vmm_new; - } - } - - prev = current; - current = current->next; - } - - return 0; - } - - inline static vmm_obj_t* nlgetlen(arch::x86_64::process_t* proc, std::uint64_t addr) { - asm volatile("cli"); // bug if they are enabled - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - - while (current) { - - if (addr >= current->base && addr < current->base + current->len) { - return current; - } - - if (current->base == (std::uint64_t)Other::toVirt(0) - 4096) - break; - - current = current->next; - } - return 0; - } - - inline static vmm_obj_t* old_v_find(vmm_obj_t* start, std::uint64_t base, std::uint64_t len) { - vmm_obj_t* current = start->next; - vmm_obj_t* prev = start; - uint64_t found = 0; - - uint64_t align_length = ALIGNUP(len,4096); - - vmm_obj_t* vmm_new = new vmm_obj_t; - - while(current) { - - if(prev) { - - uint64_t prev_end = (prev->base + prev->len); - uint64_t current_end = base + len; - - if(current->base == base) { - delete (void*)vmm_new; - vmm_new = current; - break; - } - - if(current->base >= current_end && prev_end <= base) { - - vmm_new->base = base; - vmm_new->len = align_length; - - vmm_new->is_lazy_alloc = 0; - vmm_new->is_lazy_allocated = 0; - vmm_new->is_shared = 0; - - prev->next = vmm_new; - vmm_new->next = current; - - break; - - } - } - - prev = current; - current = current->next; - } - - return vmm_new; - } - - inline static void invtlb(arch::x86_64::process_t* proc ,std::uint64_t base, std::uint64_t len) { - std::uint64_t sz_in_pages = len / 4096; - if(sz_in_pages == 0) - sz_in_pages = 1; - - if(sz_in_pages > 500) { - // at this point just reload cr3 - memory::paging::enablepaging(proc->original_cr3); - } else { - for(std::uint64_t i = 0;i < len; i += PAGE_SIZE) { - __invlpg(base + i); - } - } - } - - inline static vmm_obj_t* v_find(arch::x86_64::process_t* proc, vmm_obj_t* start, std::uint64_t base, std::uint64_t len, int is_fixed) { - vmm_obj_t* current = start->next; - vmm_obj_t* prev = start; - uint64_t found = 0; - - vmm_obj_t* before = nlgetlen(proc,base - 4096); - vmm_obj_t* after = nlgetlen(proc,base + len + 4096); - len = ALIGNUP(len, 4096); - - if(before) { - if(before->base == 0) - before = 0; - } - - if(after) { - if(after->base == (std::uint64_t)Other::toVirt(0) - 4096) { - after = 0; - } - } - -again: - current = start->next; - prev = start; - - if(before == after && before != 0 && after != 0) { - - if(before->is_mapped || before->shm) { - memory::paging::zerorange(proc->original_cr3, before->base,before->len); - if(before->shm) { - before->shm->ctl.shm_dtime = getUnixTime(); - before->shm->ctl.shm_lpid = proc->id; - before->shm->ctl.shm_nattch--; - memory::paging::zerorange(proc->original_cr3,(std::uint64_t)before->base,before->len); - - if(before->shm->ctl.shm_nattch == 0 && before->shm->is_pending_rm) { - shm_rm(before->shm); - } - - before->shm = 0; - } - } - - vmm_obj_t* split = new vmm_obj_t; - memset(split,0,sizeof(vmm_obj_t)); - memcpy(split,before,sizeof(vmm_obj_t)); - split->len = (before->base + before->len) - (base + len); - split->base = base + len; - split->next = before->next; - before->next = split; - split->src_len = split->len; - before->len = before->len - (len + split->len); - before->src_len = before->len; - current = split->next; - if(before->how_much_connected) { - split->how_much_connected = new int; - *split->how_much_connected = *before->how_much_connected; - } - goto end; - } else { - while(current) { - if(prev) { - - if(current == before && before != 0) { - if(before->base + before->len > base) { - if(before->is_mapped || before->shm) { - memory::paging::zerorange(proc->original_cr3, before->base,before->len); - if(before->shm) { - before->shm->ctl.shm_dtime = getUnixTime(); - before->shm->ctl.shm_lpid = proc->id; - before->shm->ctl.shm_nattch--; - memory::paging::zerorange(proc->original_cr3,(std::uint64_t)before->base,before->len); - - if(before->shm->ctl.shm_nattch == 0 && before->shm->is_pending_rm) { - shm_rm(before->shm); - } - - before->shm = 0; - } - } - before->len -= ((before->base + before->len) - base); - before->src_len = before->len; - } - } else { - - if(current->base >= base && current->base < (base + len)) { - if(current->is_mapped || current->shm) { - memory::paging::zerorange(proc->original_cr3, current->base,current->len); - if(current->shm) { - current->shm->ctl.shm_dtime = getUnixTime(); - current->shm->ctl.shm_lpid = proc->id; - current->shm->ctl.shm_nattch--; - memory::paging::zerorange(proc->original_cr3,(std::uint64_t)current->base,current->len); - - if(current->shm->ctl.shm_nattch == 0 && current->shm->is_pending_rm) { - shm_rm(current->shm); - } - - current->shm = 0; - } - } - std::uint64_t sz = ((base + len) - current->base) > current->len ? current->len : current->len - ((current->base + current->len) - (base + len)); - current->len -= sz; - current->base += sz; - current->src_len = current->len; - if(current->len == 0) { - prev->next = current->next; - if(current->how_much_connected) - delete (void*)current->how_much_connected; - delete (void*)current; - current = prev->next; - } - } - } - - if(current->base == (std::uint64_t)Other::toVirt(0) - 4096) - break; - } - - prev = current; - current = current->next; - } - } - -end: - - memory::paging::destroyrange(proc->original_cr3, base, len); - memory::paging::zerorange(proc->original_cr3, base, len); - - vmm_obj_t* vmm_new = new vmm_obj_t; - - current = start->next; - prev = start; - - while(current) { - if(prev) { - uint64_t prev_end = (prev->base + prev->len); - uint64_t current_end = base + len; - - if(current->base == base) { - asm volatile("ud2"); - delete vmm_new; - vmm_new = current; - break; - } - - //DEBUG(1,"0x%p 0x%p 0x%p 0x%p",current->base,current_end,prev_end,base); - - if(current->base >= current_end && prev_end <= base) { - vmm_new->base = base; - vmm_new->len = len; - vmm_new->is_lazy_alloc = 0; - vmm_new->is_lazy_allocated = 0; - vmm_new->is_shared = 0; - - prev->next = vmm_new; - vmm_new->next = current; - break; - } - - if(current->base == (std::uint64_t)Other::toVirt(0) - 4096) - assert(0, "help !"); - } - - prev = current; - current = current->next; - } - - return vmm_new; - } - - inline static void* map(arch::x86_64::process_t* proc, std::uint64_t base, std::uint64_t length, std::uint64_t flags) { - asm volatile("cli"); // bug if they are enabled - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - current->lock.lock(); - - while(current) { - - if(current->phys == base) { ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); - return (void*)current->base; } - - if(current->base == (std::uint64_t)Other::toVirt(0) - 4096) - break; - - current = current->next; - } - - current = (vmm_obj_t*)proc->vmm_start; - vmm_obj_t* new_vmm = v_alloc(current,length); - new_vmm->flags = flags; - new_vmm->phys = base; - new_vmm->src_len = length; - new_vmm->is_mapped = 1; - paging::maprangeid(proc->original_cr3,base,new_vmm->base,length,flags,*proc->vmm_id); - ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); - return (void*)new_vmm->base; - } - - inline static void* custom_map(arch::x86_64::process_t* proc, std::uint64_t virt, std::uint64_t phys, std::uint64_t length, std::uint64_t flags, int is_fixed) { - asm volatile("cli"); // bug if they are enabled - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - current->lock.lock(); - void* new_virt = mark(proc,virt,phys,length,flags,0,is_fixed); - paging::maprangeid(proc->original_cr3,phys,(std::uint64_t)virt,length,flags,*proc->vmm_id); - current->lock.unlock(); - vmm_obj_t* new_vmm = get(proc,virt); - new_vmm->is_mapped = 1; - new_vmm->src_len = length; - - ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); - - return (void*)virt; - } - - inline static std::uint64_t shm_map(arch::x86_64::process_t* proc, shm_seg_t* shm, std::uint64_t base) { - - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - current->lock.lock(); - - if(base == 0) { - vmm_obj_t* new_vmm = v_alloc(current,shm->len); - new_vmm->flags = PTE_PRESENT | PTE_RW | PTE_USER; - new_vmm->phys = shm->phys; - new_vmm->src_len = shm->len; - new_vmm->is_mapped = 1; - new_vmm->shm = shm; - paging::maprangeid(proc->original_cr3,shm->phys,new_vmm->base,shm->len,PTE_PRESENT | PTE_RW | PTE_USER,*proc->vmm_id); - new_vmm->shm->ctl.shm_atime = getUnixTime(); - new_vmm->shm->ctl.shm_lpid = proc->id; - new_vmm->shm->ctl.shm_nattch++; - ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); - return (std::uint64_t)new_vmm->base; - } else { - - void* new_virt = mark(proc,base,shm->phys,shm->len,PTE_PRESENT | PTE_RW | PTE_USER,0,0); - paging::maprangeid(proc->original_cr3,shm->phys,(std::uint64_t)base,shm->len,PTE_PRESENT | PTE_RW | PTE_USER,*proc->vmm_id); - current->lock.unlock(); - vmm_obj_t* new_vmm = get(proc,base); - new_vmm->is_mapped = 1; - new_vmm->src_len = shm->len; - new_vmm->shm = shm; - - new_vmm->shm->ctl.shm_atime = getUnixTime(); - new_vmm->shm->ctl.shm_lpid = proc->id; - new_vmm->shm->ctl.shm_nattch++; - ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); - return (std::uint64_t)base; - } - - ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); - return 0; - } - - inline static void* oldmark(arch::x86_64::process_t* proc, std::uint64_t base, std::uint64_t phys, std::uint64_t length, std::uint64_t flags, int is_shared, int is_fixed) { - asm volatile("cli"); // bug if they are enabled - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - vmm_obj_t* new_vmm = old_v_find(current,base,length); - new_vmm->flags = flags; - new_vmm->phys = phys; - new_vmm->src_len = length; - new_vmm->base = base; - new_vmm->is_mapped = 0; - new_vmm->is_free = 0; - new_vmm->len = ALIGNUP(length,4096); - new_vmm->is_shared = is_shared; - return (void*)new_vmm->base; - } - - inline static void* mark(arch::x86_64::process_t* proc, std::uint64_t base, std::uint64_t phys, std::uint64_t length, std::uint64_t flags, int is_shared, int is_fixed) { - asm volatile("cli"); // bug if they are enabled - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - vmm_obj_t* new_vmm = v_find(proc,current,base,length,is_fixed); - new_vmm->flags = flags; - new_vmm->phys = phys; - new_vmm->src_len = length; - new_vmm->base = base; - new_vmm->is_mapped = 0; - new_vmm->is_free = 0; - new_vmm->len = ALIGNUP(length,4096); - new_vmm->is_shared = is_shared; - return (void*)new_vmm->base; - } - - inline static vmm_obj_t* get(arch::x86_64::process_t* proc, std::uint64_t base) { - asm volatile("cli"); // bug if they are enabled - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - current->lock.lock(); - - while(current) { - - if(current->base == base) { ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); - return current; } - - if(current->base == (std::uint64_t)Other::toVirt(0) - 4096) - break; - - current = current->next; - } - ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); - return 0; - } - - inline static vmm_obj_t* nolockgetlen(arch::x86_64::process_t* proc, std::uint64_t addr) { - asm volatile("cli"); // bug if they are enabled - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - - while (current) { - - if (addr >= current->base && addr < current->base + current->len) { - return current; - } - - if (current->base == (std::uint64_t)Other::toVirt(0) - 4096) - break; - - current = current->next; - } - return 0; - } - - - inline static vmm_obj_t* getlen(arch::x86_64::process_t* proc, std::uint64_t addr) { - asm volatile("cli"); // bug if they are enabled - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - current->lock.lock(); - - while (current) { - - if (addr >= current->base && addr < current->base + current->len) { - ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); - return current; - } - - if (current->base == (std::uint64_t)Other::toVirt(0) - 4096) - break; - - current = current->next; - } - ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); - return 0; - } - - inline static void clone(arch::x86_64::process_t* dest_proc, arch::x86_64::process_t* src_proc) { - asm volatile("cli"); // bug if they are enabled - vmm_obj_t* current = (vmm_obj_t*)src_proc->vmm_start; - current->lock.lock(); - - arch::x86_64::process_t* proc = dest_proc; - - proc->ctx.cr3 = memory::pmm::_physical::alloc(4096); - proc->original_cr3 = proc->ctx.cr3; - std::uint64_t cr3 = proc->ctx.cr3; - - for(int i = 255; i < 512; i++) { - std::uint64_t* virt_usrcr3 = (std::uint64_t*)Other::toVirt(proc->ctx.cr3); - std::uint64_t* virt_kercr3 = (std::uint64_t*)Other::toVirt(memory::paging::kernelget()); - virt_usrcr3[i] = virt_kercr3[i]; - } - - if(dest_proc && src_proc) { - - vmm_obj_t* src_current = (vmm_obj_t*)src_proc->vmm_start; - - while(src_current) { - - uint64_t phys; - - if(!src_current->is_free && src_current->base != 0 && src_current->base != (std::uint64_t)Other::toVirt(0) - 4096) { - - if(!src_current->is_lazy_allocated && !src_current->is_lazy_alloc && src_current->phys) { - if(src_current->is_shared) { - *src_current->how_much_connected = *src_current->how_much_connected + 1; - phys = src_current->phys; - } else { - if(src_current->src_len <= 4096 && !src_current->is_mapped) - phys = memory::pmm::_physical::alloc(4096); - else if(src_current->src_len > 4096 && !src_current->is_mapped) - phys = memory::pmm::_physical::alloc(src_current->src_len); - else if(src_current->is_mapped) - phys = src_current->phys; - - if(!src_current->is_mapped) - memcpy((void*)Other::toVirt(phys),(void*)Other::toVirt(src_current->phys),src_current->len); - } - memory::paging::maprangeid(cr3,phys,src_current->base,src_current->len,src_current->flags,*proc->vmm_id); - } else { - phys = 0; - memory::paging::duplicaterangeifexists(src_proc->original_cr3,dest_proc->original_cr3,src_current->base,src_current->len,src_current->flags); - } - - oldmark(dest_proc,src_current->base,phys,src_current->src_len,src_current->flags,src_current->is_shared,1); - get(dest_proc,src_current->base)->is_mapped = src_current->is_mapped; - - get(dest_proc,src_current->base)->is_lazy_alloc = src_current->is_lazy_alloc; - get(dest_proc,src_current->base)->is_lazy_allocated = src_current->is_lazy_allocated; - - } - - if(src_current->base == (std::uint64_t)Other::toVirt(0) - 4096) - break; - - src_current = src_current->next; - } - - } - ((vmm_obj_t*)src_proc->vmm_start)->lock.unlock(); - } - - inline static void reload(arch::x86_64::process_t* proc) { - asm volatile("cli"); // bug if they are enabled - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - if(proc->ctx.cr3 && proc->original_cr3) { /* We should free all paging memory */ - memory::pmm::_physical::fullfree(*proc->vmm_id); - memory::pmm::_physical::free(proc->original_cr3); - } - proc->ctx.cr3 = memory::pmm::_physical::alloc(4096); - proc->original_cr3 = proc->ctx.cr3; - std::uint64_t cr3 = proc->ctx.cr3; - - for(int i = 255; i < 512; i++) { - std::uint64_t* virt_usrcr3 = (std::uint64_t*)Other::toVirt(proc->ctx.cr3); - std::uint64_t* virt_kercr3 = (std::uint64_t*)Other::toVirt(memory::paging::kernelget()); - virt_usrcr3[i] = virt_kercr3[i]; - } - - //memory::paging::mapkernel(cr3,*proc->vmm_id); - //memory::paging::alwaysmappedmap(cr3,*proc->vmm_id); - //memory::paging::maprangeid(cr3,Other::toPhys(proc->syscall_stack),(std::uint64_t)proc->syscall_stack,SYSCALL_STACK_SIZE,PTE_USER | PTE_PRESENT | PTE_RW,*proc->vmm_id); - while(current) { - - if(current->phys) { - memory::paging::maprangeid(cr3,current->phys,current->base,current->len,current->flags,*proc->vmm_id); - } - - if(current->base == (std::uint64_t)Other::toVirt(0) - 4096) - break; - - current = current->next; - } - } - - inline static void modify(arch::x86_64::process_t* proc, std::uint64_t dest_base, std::uint64_t new_phys) { - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - while (current) - { - - if(current->base == dest_base) { - - current->phys = new_phys; - memory::paging::maprangeid(proc->original_cr3,current->phys,current->base,current->len,current->flags,*proc->vmm_id); - - return; - - } - - current = current->next; - } - } - - inline static void unmap(arch::x86_64::process_t* proc, std::uint64_t base, std::uint64_t len) { - vmm_obj_t* start = (vmm_obj_t*)proc->vmm_start; - vmm_obj_t* current = start->next; - vmm_obj_t* prev = start; - uint64_t found = 0; - - vmm_obj_t* before = nlgetlen(proc,base - 4096); - vmm_obj_t* after = nlgetlen(proc,base + len + 4096); - len = ALIGNUP(len, 4096); - - if(before) { - if(before->base == 0) - before = 0; - } - - if(after) { - if(after->base == (std::uint64_t)Other::toVirt(0) - 4096) { - after = 0; - } - } - -again: - current = start->next; - prev = start; - - if(before == after && before != 0 && after != 0) { - - if(before->is_mapped || before->shm) { - memory::paging::zerorange(proc->original_cr3, before->base,before->len); - if(before->shm) { - before->shm->ctl.shm_dtime = getUnixTime(); - before->shm->ctl.shm_lpid = proc->id; - before->shm->ctl.shm_nattch--; - memory::paging::zerorange(proc->original_cr3,(std::uint64_t)before->base,before->len); - - if(before->shm->ctl.shm_nattch == 0 && before->shm->is_pending_rm) { - shm_rm(before->shm); - } - - before->shm = 0; - } - } - - vmm_obj_t* split = new vmm_obj_t; - memset(split,0,sizeof(vmm_obj_t)); - memcpy(split,before,sizeof(vmm_obj_t)); - split->len = (before->base + before->len) - (base + len); - split->base = base + len; - split->next = before->next; - before->next = split; - split->src_len = split->len; - before->len = before->len - (len + split->len); - before->src_len = before->len; - current = split->next; - if(before->how_much_connected) { - split->how_much_connected = new int; - *split->how_much_connected = *before->how_much_connected; - } - goto end; - } else { - while(current) { - if(prev) { - - if(current == before && before != 0) { - if(before->base + before->len > base) { - if(before->is_mapped || before->shm) { - memory::paging::zerorange(proc->original_cr3, before->base,before->len); - if(before->shm) { - before->shm->ctl.shm_dtime = getUnixTime(); - before->shm->ctl.shm_lpid = proc->id; - before->shm->ctl.shm_nattch--; - memory::paging::zerorange(proc->original_cr3,(std::uint64_t)before->base,before->len); - - if(before->shm->ctl.shm_nattch == 0 && before->shm->is_pending_rm) { - shm_rm(before->shm); - } - - before->shm = 0; - } - } - before->len -= ((before->base + before->len) - base); - before->src_len = before->len; - } - } else { - - if(current->base >= base && current->base < (base + len)) { - if(current->is_mapped || current->shm) { - memory::paging::zerorange(proc->original_cr3, current->base,current->len); - if(current->shm) { - current->shm->ctl.shm_dtime = getUnixTime(); - current->shm->ctl.shm_lpid = proc->id; - current->shm->ctl.shm_nattch--; - memory::paging::zerorange(proc->original_cr3,(std::uint64_t)current->base,current->len); - - if(current->shm->ctl.shm_nattch == 0 && current->shm->is_pending_rm) { - shm_rm(current->shm); - } - - current->shm = 0; - } - } - std::uint64_t sz = ((base + len) - current->base) > current->len ? current->len : current->len - ((current->base + current->len) - (base + len)); - current->len -= sz; - current->base += sz; - current->src_len = current->len; - if(current->len == 0) { - prev->next = current->next; - if(current->how_much_connected) - delete (void*)current->how_much_connected; - delete (void*)current; - current = prev->next; - } - } - } - - if(current->base == (std::uint64_t)Other::toVirt(0) - 4096) - break; - } - - prev = current; - current = current->next; - } - } - -end: - - memory::paging::destroyrange(proc->original_cr3, base, len); - memory::paging::zerorange(proc->original_cr3, base, len); - - } - - inline static void free(arch::x86_64::process_t* proc) { - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - - current->lock.lock(); - current->pthread_count--; - - if(current->pthread_count != 0) { current->lock.unlock(); - return; } - - if(!current) - return; - - vmm_obj_t* next = current->next; - - while (current) - { - next = current->next; - current->next = 0; - - if(current->base == (std::uint64_t)Other::toVirt(0) - 4096) - next = 0; - - if(!current->is_free) { - if(current->base != 0 && current->base != (std::uint64_t)Other::toVirt(0) - 4096) { - if(!current->is_lazy_allocated && !current->is_lazy_alloc) { - if(!current->is_mapped && !current->is_shared && !current->is_lazy_alloc) { - memory::pmm::_physical::free(current->phys); - } else if(current->is_shared && !current->is_mapped) { - if(*current->how_much_connected == 1) { - memory::pmm::_physical::free(current->phys); - delete (void*)current->how_much_connected; - } else - *current->how_much_connected = *current->how_much_connected - 1; - } - } else { - memory::paging::destroyrange(proc->original_cr3,current->base,current->len); - } - } - } - - delete current; - - if(!next) - break; - - current = next; - } - - memory::paging::destroy(proc->original_cr3); - - proc->original_cr3 = 0; - - proc->vmm_start = 0; - - } - - inline static void* alloc(arch::x86_64::process_t* proc, std::uint64_t len, std::uint64_t flags, int is_shared) { - return lazy_alloc(proc,len,flags,0); - } - - inline static void* lazy_alloc(arch::x86_64::process_t* proc, std::uint64_t len, std::uint64_t flags, int is_shared) { - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - current->lock.lock(); - vmm_obj_t* new_vmm = v_alloc(current,len); - new_vmm->flags = flags; - new_vmm->src_len = len; - new_vmm->is_mapped = 0; - new_vmm->is_lazy_alloc = 1; - new_vmm->is_lazy_allocated = 1; - new_vmm->phys = 0; - memory::paging::zerorange(proc->original_cr3,(std::uint64_t)new_vmm->base,new_vmm->len); - ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); - return (void*)new_vmm->base; - } - - inline static void invmapping(arch::x86_64::process_t* proc, std::uint64_t base, std::uint64_t len) { - for(std::uint64_t i = 0; i < len; i += PAGE_SIZE) { - if(__memory_paging_getphys(proc->original_cr3,base + i) == -1) { - std::uint64_t new_phys = memory::pmm::_physical::alloc(4096); - memory::paging::map(proc->original_cr3,new_phys,base + i,PTE_PRESENT | PTE_RW | PTE_USER); - } - } - } - - inline static vmm_obj_t* changemem(arch::x86_64::process_t* proc, std::uint64_t flags) { - asm volatile("cli"); // bug if they are enabled - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - current->lock.lock(); - - while (current) { - - if (current->base == (std::uint64_t)Other::toVirt(0) - 4096) - break; - - if(current->base != 0) { - memory::paging::changerange(proc->original_cr3,current->base,current->len,flags | ((current->flags) & ~(PTE_RW))); - } - - current = current->next; - } - ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); - return 0; - } - - inline static void* customalloc(arch::x86_64::process_t* proc, std::uint64_t virt, std::uint64_t len, std::uint64_t flags, int is_shared, int is_fixed) { - asm volatile("cli"); // bug if they are enabled - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - current->lock.lock(); - void* new_virt = mark(proc,virt,0,len,flags,is_shared,is_fixed); - current->lock.unlock(); - vmm_obj_t* new_vmm = get(proc,(std::uint64_t)new_virt); - if(is_shared) { - new_vmm->is_shared = 1; - new_vmm->how_much_connected = new int; - } - new_vmm->is_lazy_alloc = 1; - new_vmm->is_lazy_allocated = 1; - new_vmm->src_len = len; - - ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); - - return (void*)new_virt; - } - - }; -}
\ No newline at end of file diff --git a/kernel/include/generic/time.hpp b/kernel/include/generic/time.hpp deleted file mode 100644 index ab56856..0000000 --- a/kernel/include/generic/time.hpp +++ /dev/null @@ -1,18 +0,0 @@ - -/* It will connect all timers together */ - -#include <cstdint> - -#pragma once - -#define TSC_TIMER 0 -#define KVM_TIMER 1 -#define HPET_TIMER 2 - -class time { -public: - - static std::uint64_t counter(); - - static void sleep(std::uint64_t us); -};
\ No newline at end of file diff --git a/kernel/include/generic/vfs/devfs.hpp b/kernel/include/generic/vfs/devfs.hpp deleted file mode 100644 index 690fa93..0000000 --- a/kernel/include/generic/vfs/devfs.hpp +++ /dev/null @@ -1,265 +0,0 @@ - -#include <cstdint> -#include <generic/vfs/vfs.hpp> -#include <etc/list.hpp> - -#pragma once - -#define DEVFS_PACKET_CREATE_DEV 1 -#define DEVFS_PACKET_READ_READRING 2 -#define DEVFS_PACKET_WRITE_READRING 3 -#define DEVFS_PACKET_READ_WRITERING 4 -#define DEVFS_PACKET_WRITE_WRITERING 5 -#define DEVFS_PACKET_CREATE_IOCTL 6 -#define DEVFS_PACKET_SIZE_IOCTL 7 -#define DEVFS_PACKET_IOCTL 8 -#define DEVFS_ENABLE_PIPE 9 -#define DEVFS_SETUP_MMAP 10 -#define DEVFS_PACKET_CREATE_PIPE_DEV 11 -#define DEVFS_PACKET_ISATTY 12 -#define DEVFS_PACKET_SETUPTTY 13 -#define DEVFS_GETSLAVE_BY_MASTER 14 -#define DEVFS_PACKET_SETUP_RING_SIZE 15 -#define devfs_packet_get_num 16 - -typedef unsigned int __u32; -typedef unsigned short __u16; - -struct fb_fix_screeninfo { - char id[16]; /* identification string eg "TT Builtin" */ - unsigned long smem_start; /* Start of frame buffer mem */ - /* (physical address) */ - __u32 smem_len; /* Length of frame buffer mem */ - __u32 type; /* see FB_TYPE_* */ - __u32 type_aux; /* Interleave for interleaved Planes */ - __u32 visual; /* see FB_VISUAL_* */ - __u16 xpanstep; /* zero if no hardware panning */ - __u16 ypanstep; /* zero if no hardware panning */ - __u16 ywrapstep; /* zero if no hardware ywrap */ - __u32 line_length; /* length of a line in bytes */ - unsigned long mmio_start; /* Start of Memory Mapped I/O */ - /* (physical address) */ - __u32 mmio_len; /* Length of Memory Mapped I/O */ - __u32 accel; /* Indicate to driver which */ - /* specific chip/card we have */ - __u16 capabilities; /* see FB_CAP_* */ - __u16 reserved[2]; /* Reserved for future compatibility */ -}; - -/* Interpretation of offset for color fields: All offsets are from the right, - * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you - * can use the offset as right argument to <<). A pixel afterwards is a bit - * stream and is written to video memory as that unmodified. - * - * For pseudocolor: offset and length should be the same for all color - * components. Offset specifies the position of the least significant bit - * of the palette index in a pixel value. Length indicates the number - * of available palette entries (i.e. # of entries = 1 << length). - */ -struct fb_bitfield { - __u32 offset; /* beginning of bitfield */ - __u32 length; /* length of bitfield */ - __u32 msb_right; /* != 0 : Most significant bit is */ - /* right */ -}; - -#define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */ -#define FB_NONSTD_REV_PIX_IN_B 2 /* order of pixels in each byte is reversed */ - -#define FB_ACTIVATE_NOW 0 /* set values immediately (or vbl)*/ -#define FB_ACTIVATE_NXTOPEN 1 /* activate on next open */ -#define FB_ACTIVATE_TEST 2 /* don't set, round up impossible */ -#define FB_ACTIVATE_MASK 15 - /* values */ -#define FB_ACTIVATE_VBL 16 /* activate values on next vbl */ -#define FB_CHANGE_CMAP_VBL 32 /* change colormap on vbl */ -#define FB_ACTIVATE_ALL 64 /* change all VCs on this fb */ -#define FB_ACTIVATE_FORCE 128 /* force apply even when no change*/ -#define FB_ACTIVATE_INV_MODE 256 /* invalidate videomode */ -#define FB_ACTIVATE_KD_TEXT 512 /* for KDSET vt ioctl */ - -#define FB_ACCELF_TEXT 1 /* (OBSOLETE) see fb_info.flags and vc_mode */ - -#define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */ -#define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */ -#define FB_SYNC_EXT 4 /* external sync */ -#define FB_SYNC_COMP_HIGH_ACT 8 /* composite sync high active */ -#define FB_SYNC_BROADCAST 16 /* broadcast video timings */ - /* vtotal = 144d/288n/576i => PAL */ - /* vtotal = 121d/242n/484i => NTSC */ -#define FB_SYNC_ON_GREEN 32 /* sync on green */ - -#define FB_VMODE_NONINTERLACED 0 /* non interlaced */ -#define FB_VMODE_INTERLACED 1 /* interlaced */ -#define FB_VMODE_DOUBLE 2 /* double scan */ -#define FB_VMODE_ODD_FLD_FIRST 4 /* interlaced: top line first */ -#define FB_VMODE_MASK 255 - -#define FB_VMODE_YWRAP 256 /* ywrap instead of panning */ -#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */ -#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */ - -/* - * Display rotation support - */ -#define FB_ROTATE_UR 0 -#define FB_ROTATE_CW 1 -#define FB_ROTATE_UD 2 -#define FB_ROTATE_CCW 3 - -#define PICOS2KHZ(a) (1000000000UL/(a)) -#define KHZ2PICOS(a) (1000000000UL/(a)) - -struct fb_var_screeninfo { - __u32 xres; /* visible resolution */ - __u32 yres; - __u32 xres_virtual; /* virtual resolution */ - __u32 yres_virtual; - __u32 xoffset; /* offset from virtual to visible */ - __u32 yoffset; /* resolution */ - - __u32 bits_per_pixel; /* guess what */ - __u32 grayscale; /* 0 = color, 1 = grayscale, */ - /* >1 = FOURCC */ - struct fb_bitfield red; /* bitfield in fb mem if true color, */ - struct fb_bitfield green; /* else only length is significant */ - struct fb_bitfield blue; - struct fb_bitfield transp; /* transparency */ - - __u32 nonstd; /* != 0 Non standard pixel format */ - - __u32 activate; /* see FB_ACTIVATE_* */ - - __u32 height; /* height of picture in mm */ - __u32 width; /* width of picture in mm */ - - __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */ - - /* Timing: All values in pixclocks, except pixclock (of course) */ - __u32 pixclock; /* pixel clock in ps (pico seconds) */ - __u32 left_margin; /* time from sync to picture */ - __u32 right_margin; /* time from picture to sync */ - __u32 upper_margin; /* time from sync to picture */ - __u32 lower_margin; - __u32 hsync_len; /* length of horizontal sync */ - __u32 vsync_len; /* length of vertical sync */ - __u32 sync; /* see FB_SYNC_* */ - __u32 vmode; /* see FB_VMODE_* */ - __u32 rotate; /* angle we rotate counter clockwise */ - __u32 colorspace; /* colorspace for FOURCC-based modes */ - __u32 reserved[4]; /* Reserved for future compatibility */ -}; - -struct winsize { - unsigned short ws_row; - unsigned short ws_col; - unsigned short ws_xpixel; -/* unused */ - unsigned short ws_ypixel; -/* unused */ -}; - -#define TCGETS 0x5401 -#define TCSETS 0x5402 -#define TIOCGWINSZ 0x5413 -#define TIOCSWINSZ 0x5414 - -namespace vfs { - - typedef struct { - std::uint64_t is_pipe : 1; - std::uint64_t is_pipe_rw : 1; - } __attribute__((packed)) devfs_pipe_p_t; - - typedef struct { - union { - struct { - std::uint8_t request; - std::uint8_t* cycle; - std::uint32_t* queue; - std::uint32_t size; - std::uint64_t value; - }; - struct { - std::uint8_t request; - std::uint64_t ioctlreq; - std::uint64_t arg; - } ioctl; - struct { - std::uint8_t request; - std::uint32_t writereg; - std::uint32_t readreg; - std::uint32_t size; - std::uint64_t pointer; - } create_ioctl; - struct { - std::uint8_t request; - std::uint8_t pipe_target; - std::uint64_t pipe_pointer; - } enable_pipe; - struct { - std::uint8_t request; - std::uint64_t dma_addr; - std::uint64_t size; - std::uint64_t flags; - } setup_mmap; - }; - } __attribute__((packed)) devfs_packet_t; /* User-Kernel interaction packet */ - - typedef struct { - std::uint32_t read_req; - std::uint32_t write_req; - std::uint32_t size; - void* pointer_to_struct; - } __attribute__((packed)) devfs_ioctl_packet_t; - - typedef struct devfs_node { - devfs_pipe_p_t open_flags; - union { - struct { - Lists::Ring* readring; - Lists::Ring* writering; - }; - struct { - pipe* readpipe; - pipe* writepipe; - }; - }; - devfs_ioctl_packet_t ioctls[32]; - std::uint64_t pipe0; - std::uint64_t mmap_base; - std::uint64_t mmap_size; - std::uint64_t mmap_flags; - std::int32_t dev_num; - - int show_num; - std::int8_t is_tty; - - std::int64_t (*read)(userspace_fd_t* fd, void* buffer, std::uint64_t count); - std::int64_t (*write)(userspace_fd_t* fd, void* buffer, std::uint64_t size); - - std::int64_t (*slave_write)(userspace_fd_t* fd, void* buffer, std::uint64_t size); - - std::int32_t (*ioctl)(userspace_fd_t* fd, unsigned long req, void *arg, int *res); - std::int32_t (*open)(userspace_fd_t* fd, char* path); - int mode; - int is_dir; - - int pgrp; - std::uint64_t ino; - - termios_t* term_flags; - - struct devfs_node* next; - char masterpath[256]; - char slavepath[256]; - } devfs_node_t; - - static_assert(sizeof(devfs_node_t) < 4096,"devfs_node_t is higher than fucking page size"); - - class devfs { - public: - static void mount(vfs_node_t* node); - static std::int64_t send_packet(char* path,devfs_packet_t* packet); - }; -}; diff --git a/kernel/include/generic/vfs/evdev.hpp b/kernel/include/generic/vfs/evdev.hpp deleted file mode 100644 index 32e8d1d..0000000 --- a/kernel/include/generic/vfs/evdev.hpp +++ /dev/null @@ -1,259 +0,0 @@ - -#include <cstdint> -#include <generic/vfs/vfs.hpp> -#include <generic/vfs/devfs.hpp> -#include <etc/list.hpp> - -#pragma once - -#define EVDEV_TYPE_MOUSE 1 -#define EVDEV_TYPE_KEYBOARD 2 - -typedef int __s32; - -struct evdevtimeval { - long long tv_sec; /* seconds */ - long long tv_usec; /* microseconds */ -}; - -#include <etc/list.hpp> - -struct input_event { - struct evdevtimeval time; -#define input_event_sec time.tv_sec -#define input_event_usec time.tv_usec - __u16 type; - __u16 code; - __s32 value; -}; - - -#define BTN_MOUSE 0x110 -#define BTN_LEFT 0x110 -#define BTN_RIGHT 0x111 -#define BTN_MIDDLE 0x112 -#define BTN_SIDE 0x113 -#define BTN_EXTRA 0x114 -#define BTN_FORWARD 0x115 -#define BTN_BACK 0x116 -#define BTN_TASK 0x117 - -#include <cstdint> -#include <atomic> -#include <generic/locks/spinlock.hpp> -#include <etc/libc.hpp> -#include <etc/etc.hpp> - -#include <etc/logging.hpp> - -#pragma once - -typedef struct { - std::uint32_t cycle; - input_event evdev_ev; - -} zring_obj_t; - -typedef struct { - zring_obj_t* objs; - int bytelen; - int tail; - int size; - int cycle; -} zring_buffer_t; - -#define _IOC_NONE 0U -#define _IOC_WRITE 1U -#define _IOC_READ 2U - -#define _IOC_NRBITS 8 -#define _IOC_TYPEBITS 8 -#define _IOC_SIZEBITS 14 -#define _IOC_DIRBITS 2 - -#define _IOC_NRMASK ((1 << _IOC_NRBITS) - 1) -#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS) - 1) -#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS) - 1) -#define _IOC_DIRMASK ((1 << _IOC_DIRBITS) - 1) - -#define _IOC_NRSHIFT 0 -#define _IOC_TYPESHIFT (_IOC_NRSHIFT + _IOC_NRBITS) -#define _IOC_SIZESHIFT (_IOC_TYPESHIFT + _IOC_TYPEBITS) -#define _IOC_DIRSHIFT (_IOC_SIZESHIFT + _IOC_SIZEBITS) - -#define _IOC(dir, type, nr, size) \ - (((dir) << _IOC_DIRSHIFT) | \ - ((type) << _IOC_TYPESHIFT) | \ - ((nr) << _IOC_NRSHIFT) | \ - ((size) << _IOC_SIZESHIFT)) - -#define _IO(type, nr) _IOC(_IOC_NONE, (type), (nr), 0) -#define _IOR(type, nr, size) _IOC(_IOC_READ, (type), (nr), sizeof(size)) -#define _IOW(type, nr, size) _IOC(_IOC_WRITE, (type), (nr), sizeof(size)) -#define _IOWR(type, nr, size) _IOC(_IOC_READ | _IOC_WRITE, (type), (nr), sizeof(size)) - -#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) -#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) -#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) -#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) - -#define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) - -#define EVIOCGVERSION _IOR('E', 0x01, int) -#define EVIOCGID _IOR('E', 0x02, struct input_id) -#define EVIOCGREP _IOR('E', 0x03, int[2]) -#define EVIOCSREP _IOW('E', 0x03, int[2]) -#define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) -#define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) -#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) -#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) -#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) -#define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len) -#define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len) -#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) -#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) -#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) -#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) -#define EVIOCGBIT(ev, len) _IOC(_IOC_READ, 'E', 0x20 + (ev), len) -#define EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo) -#define EVIOCSABS(abs) _IOW('E', 0x40 + (abs), struct input_absinfo) -#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) -#define EVIOCRMFF _IOW('E', 0x81, int) -#define EVIOCGEFFECTS _IOR('E', 0x84, int) -#define EVIOCGRAB _IOW('E', 0x90, int) -#define EVIOCREVOKE _IOW('E', 0x91, int) -#define EVIOCSMASK _IOW('E', 0x92, struct input_mask) - -#define EV_MAX 0x1f -#define KEY_MAX 0x2ff -#define REL_MAX 0x0f -#define ABS_MAX 0x3f -#define MSC_MAX 0x07 -#define LED_MAX 0x0f -#define SND_MAX 0x07 -#define FF_MAX 0x7f -#define SW_MAX 0x0f - -#define EV_SYN 0x00 -#define EV_KEY 0x01 -#define EV_REL 0x02 -#define EV_ABS 0x03 -#define EV_MSC 0x04 -#define EV_SW 0x05 -#define EV_LED 0x11 -#define EV_SND 0x12 -#define EV_REP 0x14 -#define EV_FF 0x15 -#define EV_PWR 0x16 -#define EV_FF_STATUS 0x17 -#define EV_MAX 0x1f -#define EV_CNT (EV_MAX+1) - -#define BTN_MOUSE 0x110 -#define BTN_LEFT 0x110 -#define BTN_RIGHT 0x111 -#define BTN_MIDDLE 0x112 -#define BTN_SIDE 0x113 -#define BTN_EXTRA 0x114 -#define BTN_FORWARD 0x115 -#define BTN_BACK 0x116 -#define BTN_TASK 0x117 - -class evdev_modif_ring { - private: - public: - zring_buffer_t ring; - - locks::spinlock ring_lock; - - std::uint64_t read_counter = 0; - std::uint64_t write_counter = 0; - - void send(input_event ev) { - ring_lock.lock(); - ring.objs[ring.tail].cycle = ring.cycle; - ring.objs[ring.tail].evdev_ev = ev; - - read_counter++; - - if (++ring.tail == ring.size) { - ring.tail = 0; - ring.cycle = !ring.cycle; - } - ring_lock.unlock(); - } - - int setup_bytelen(int len) { - ring.bytelen = len; - return len; - } - - int isnotempty(int* queue0, char* cycle0) { - char cycle = *cycle0; - int queue = *queue0; - while (ring.objs[queue].cycle == cycle) { - return 1; - queue = queue + 1; - if (queue == ring.size) { - queue = 0; - cycle = !(cycle); - } - } - return 0; - } - - int receivevals(void* out, int max, std::uint8_t* cycle, std::uint32_t* queue) { - ring_lock.lock(); - int len = 0; - while (ring.objs[*queue].cycle == *cycle && len * ring.bytelen < max) { - - ((input_event*)out)[len] = ring.objs[*queue].evdev_ev; - *queue = *queue + 1; - if (*queue == ring.size) { - *queue = 0; - *cycle = !(*cycle); - } - len++; - } - ring_lock.unlock(); - return len * ring.bytelen; - } - - evdev_modif_ring(std::size_t size_elements) { - ring.objs = new zring_obj_t[size_elements]; - ring.size = size_elements; - ring.tail = 0; - ring.cycle = 1; - ring.bytelen = sizeof(input_event); - ring_lock.unlock(); - memset(ring.objs, 0, sizeof(zring_obj_t) * size_elements); - } - - ~evdev_modif_ring() { - delete[] ring.objs; - } - -}; - -namespace vfs { - - struct evdev_node { - int num; - int type; - - Lists::Bitmap* ev_bitmap; - evdev_modif_ring* main_ring; - - char path[64]; // internal build device - char name[2048]; // device name - - evdev_node* next; - }; - - class evdev { - public: - static int create(char* name, int type); - static void submit(int num, input_event event); - static void mount(vfs_node_t* node); - }; -};
\ No newline at end of file diff --git a/kernel/include/generic/vfs/fd.hpp b/kernel/include/generic/vfs/fd.hpp deleted file mode 100644 index a6f0eab..0000000 --- a/kernel/include/generic/vfs/fd.hpp +++ /dev/null @@ -1,260 +0,0 @@ - -#include <generic/vfs/vfs.hpp> -#include <arch/x86_64/scheduling.hpp> - -#include <etc/list.hpp> - -#include <cstdint> - -#pragma once - -namespace vfs { - class fdmanager { - private: - arch::x86_64::process_t* proc = 0; - public: - - userspace_fd_t* fd_list = 0; - std::uint64_t used_counter = 0; - - fdmanager(arch::x86_64::process_t* proc) { - this->proc = proc; - this->used_counter++; - } - - int find_min_free_index() { - int max_index = -1; - - userspace_fd_t* current = fd_list; - while(current) { - if(current->index > max_index) { - max_index = current->index; - } - current = current->next; - } - - if(max_index < 3) { - return 3; - } - - bool used_indices[max_index + 2]; - memset(used_indices, 0, max_index + 2); - - current = fd_list; - while(current) { - if(current->index >= 0 && current->index <= max_index && - current->state != USERSPACE_FD_STATE_UNUSED) { - used_indices[current->index] = true; - } - current = current->next; - } - - int free_index = 3; - for(; free_index <= max_index + 1; free_index++) { - if(!used_indices[free_index]) { - break; - } - } - - return free_index; - } - - void close(int idx) { - proc->fd_lock.lock(); - fdmanager* fd = (fdmanager*)proc->fd; - userspace_fd_t* current = fd->fd_list; - userspace_fd_t* prev = 0; - while(current) { - if(current->index == idx && current->state != USERSPACE_FD_STATE_UNUSED) { //proc->fd_lock.unlock(); - break; } - prev = current; - current = current->next; - } - - if(!current) { - - proc->fd_lock.unlock(); - return; - } - - if(current == fd->fd_list) - fd->fd_list = current->next; - else if(prev) - prev->next = current->next; - - // current->next = 0; - // memory::pmm::_virtual::free((void*)current); - - proc->fd_lock.unlock(); - } - - int create() { - proc->fd_lock.lock(); - userspace_fd_t* current = fd_list; - while(current) { - if(current->state == USERSPACE_FD_STATE_UNUSED && current->index > 2) - break; - current = current->next; - } - - if(!current) { - current = (userspace_fd_t*)memory::pmm::_virtual::alloc(4096); - memset(current,0,sizeof(userspace_fd_t)); - current->next = fd_list; - fd_list = current; - while(1) { - if(search(proc,*proc->fd_ptr)) { - *proc->fd_ptr = *proc->fd_ptr + 1; - } else - break; - } - current->index = *proc->fd_ptr; - *proc->fd_ptr = *proc->fd_ptr + 1; - } - - current->state = USERSPACE_FD_STATE_FILE; - current->read_counter = -1; - current->write_counter = -1; - current->can_be_closed = 0; - current->is_cached_path = 0; - current->is_debug = 0; - current->is_cloexec = 0; - current->pid = proc->id; - current->uid = proc->uid; - - proc->fd_lock.unlock(); - return current->index; - } - - void free() { - proc->fd_lock.lock(); - this->used_counter--; - if(this->used_counter == 0) { - userspace_fd_t* fd = this->fd_list; - while(fd) { - if(!fd->can_be_closed) { - if(fd->state == USERSPACE_FD_STATE_PIPE) - fd->pipe->close(fd->pipe_side); - else if(fd->state == USERSPACE_FD_STATE_FILE || fd->state == USERSPACE_FD_STATE_SOCKET) - vfs::vfs::close(fd); - else if(fd->state == USERSPACE_FD_STATE_EVENTFD) - fd->eventfd->close(); - } - userspace_fd_t* next = fd->next; - memory::pmm::_virtual::free((void*)fd); - fd = next; - } - proc->fd_lock.unlock(); - delete this; - return; - } - proc->fd_lock.unlock(); - } - - void duplicate(fdmanager* dest) { - userspace_fd_t* fd = this->fd_list; - while(fd) { - userspace_fd_t* newfd = (userspace_fd_t*)memory::pmm::_virtual::alloc(4096); - memcpy(newfd,fd,sizeof(userspace_fd_t)); - - if(newfd->state == USERSPACE_FD_STATE_PIPE) { - newfd->pipe->create(newfd->pipe_side); - } else if(newfd->state == USERSPACE_FD_STATE_EVENTFD) - newfd->eventfd->create(); - - newfd->next = dest->fd_list; - dest->fd_list = newfd; - fd = fd->next; - } - - } - - void cloexec() { - userspace_fd_t* fd = this->fd_list; - while(fd) { - userspace_fd_t* fd_s = fd; - if(fd_s->is_cloexec) { - if(fd_s->state == USERSPACE_FD_STATE_PIPE) { - fd_s->pipe->close(fd_s->pipe_side); - } else if(fd_s->state == USERSPACE_FD_STATE_FILE || fd_s->state == USERSPACE_FD_STATE_SOCKET) - vfs::vfs::close(fd_s); - else if(fd_s->state == USERSPACE_FD_STATE_EVENTFD) - fd_s->eventfd->close(); - - if(!fd_s->is_a_tty && fd_s->index > 2) - fd_s->state = USERSPACE_FD_STATE_UNUSED; - } - fd = fd->next; - } - } - - inline static int create(arch::x86_64::process_t* proc) { - - fdmanager* fd = (fdmanager*)proc->fd; - return fd->create(); - - } - - inline static userspace_fd_t* searchlowest(arch::x86_64::process_t* proc,std::uint32_t idx) { - - if(!proc) - return 0; - - fdmanager* fd = (fdmanager*)proc->fd; - userspace_fd_t* current = fd->fd_list; - userspace_fd_t* lowest = 0; - - while(current) { - if(current->state == USERSPACE_FD_STATE_UNUSED || current->can_be_closed) { - if(!lowest) - lowest = current; - if(current->index < lowest->index) - lowest = current; - } - current = current->next; - } - - return lowest; - } - - inline static userspace_fd_t* searchlowestfrom(arch::x86_64::process_t* proc,std::uint32_t idx) { - - if(!proc) - return 0; - - fdmanager* fd = (fdmanager*)proc->fd; - userspace_fd_t* current = fd->fd_list; - userspace_fd_t* lowest = 0; - - while(current) { - if(current->state == USERSPACE_FD_STATE_UNUSED || current->can_be_closed) { - if(!lowest && current->index >= idx) - lowest = current; - else if(current->index < lowest->index && current->index >= idx) - lowest = current; - } - current = current->next; - } - - return lowest; - } - - inline static userspace_fd_t* search(arch::x86_64::process_t* proc,std::uint32_t idx) { - - if(!proc) - return 0; - - //proc->fd_lock.lock(); - - fdmanager* fd = (fdmanager*)proc->fd; - userspace_fd_t* current = fd->fd_list; - while(current) { - if(current->index == idx && current->state != USERSPACE_FD_STATE_UNUSED) { //proc->fd_lock.unlock(); - return current; } - current = current->next; - } - //proc->fd_lock.unlock(); - return 0; - } - }; -}
\ No newline at end of file diff --git a/kernel/include/generic/vfs/tmpfs.hpp b/kernel/include/generic/vfs/tmpfs.hpp deleted file mode 100644 index ea83096..0000000 --- a/kernel/include/generic/vfs/tmpfs.hpp +++ /dev/null @@ -1,47 +0,0 @@ - -#include <generic/vfs/vfs.hpp> -#include <cstdint> - -#pragma once - -#define TMPFS_TYPE_NONE 0 -#define TMPFS_TYPE_FILE 1 -#define TMPFS_TYPE_DIRECTORY 2 -#define TMPFS_TYPE_SYMLINK 3 - -namespace vfs { - - typedef struct tmpfs_node { - std::uint64_t id; - std::uint64_t size; - std::uint64_t busy; - std::uint64_t vars[8]; - std::uint8_t type; - - std::uint64_t create_time; - std::uint64_t access_time; - - std::uint8_t is_non_allocated; - - std::uint8_t* content; - std::uint64_t real_size; // real size in ram (optimization) - struct tmpfs_node* next; - - int is_request_unlink; - - std::uint64_t path_hash; - char name[2048]; - } tmpfs_node_t; - - class tmpfs { - public: - static void mount(vfs_node_t* node); - }; -}; - -#define NODE_POOL_BLOCK_SIZE (16 * 1024 * 1024) - -struct NodePoolBlock { - vfs::tmpfs_node_t* block; - NodePoolBlock* next; -}; diff --git a/kernel/include/generic/vfs/ustar.hpp b/kernel/include/generic/vfs/ustar.hpp deleted file mode 100644 index 6e29c29..0000000 --- a/kernel/include/generic/vfs/ustar.hpp +++ /dev/null @@ -1,29 +0,0 @@ - -#include <cstdint> - -namespace vfs { - - typedef struct { - char file_name[100]; - char file_mode[8]; - char owner_id[8]; - char group_id[8]; - char file_size[12]; - char last_modific[12]; - char checksum[8]; - char type; - char name_linked[100]; - char ustar[6]; - char ustar_ver[2]; - char owner_name[32]; - char group_name[32]; - char dev_major_num[8]; - char dev_minor_num[8]; - char filename_prefix[155]; - } __attribute__((packed)) ustar_header_t; - - class ustar { - public: - static void copy(); - }; -};
\ No newline at end of file diff --git a/kernel/include/generic/vfs/vfs.hpp b/kernel/include/generic/vfs/vfs.hpp deleted file mode 100644 index 883bf04..0000000 --- a/kernel/include/generic/vfs/vfs.hpp +++ /dev/null @@ -1,1147 +0,0 @@ - -#include <cstdint> -#include <atomic> - -#pragma once - -#include <config.hpp> - -#include <generic/mm/pmm.hpp> -#include <generic/locks/spinlock.hpp> -#include <etc/libc.hpp> - -extern "C" void yield(); - -#include <etc/logging.hpp> - -#include <etc/errno.hpp> -#include <etc/list.hpp> - -#include <algorithm> - -#define USERSPACE_FD_STATE_UNUSED 0 -#define USERSPACE_FD_STATE_FILE 1 -#define USERSPACE_FD_STATE_PIPE 2 -#define USERSPACE_FD_STATE_SOCKET 3 -#define USERSPACE_FD_STATE_SOCKETPAIR 4 // unused maybe in future -#define USERSPACE_FD_STATE_EVENTFD 5 - -#define VFS_TYPE_NONE 0 -#define VFS_TYPE_FILE 1 -#define VFS_TYPE_DIRECTORY 2 -#define VFS_TYPE_SYMLINK 3 - -#define CS8 0000060 -#define ECHO 0000010 /* Enable echo. */ -#define IGNBRK 0000001 /* Ignore break condition. */ -#define BRKINT 0000002 /* Signal interrupt on break. */ -#define IGNPAR 0000004 /* Ignore characters with parity errors. */ -#define PARMRK 0000010 /* Mark parity and framing errors. */ -#define INPCK 0000020 /* Enable input parity check. */ -#define ISTRIP 0000040 /* Strip 8th bit off characters. */ -#define INLCR 0000100 /* Map NL to CR on input. */ -#define IGNCR 0000200 /* Ignore CR. */ -#define ICRNL 0000400 /* Map CR to NL on input. */ -#define OPOST 0000001 /* Post-process output. */ - -#define ICANON 0000002 -#define VMIN 6 - -#define S_IRWXU 0700 -#define S_IRUSR 0400 -#define S_IWUSR 0200 -#define S_IXUSR 0100 -#define S_IRWXG 070 -#define S_IRGRP 040 -#define S_IWGRP 020 -#define S_IXGRP 010 -#define S_IRWXO 07 -#define S_IROTH 04 -#define S_IWOTH 02 -#define S_IXOTH 01 -#define S_ISUID 04000 -#define S_ISGID 02000 -#define S_ISVTX 01000 - -/* open/fcntl. */ -#define O_ACCMODE 0003 -#define O_RDONLY 00 -#define O_WRONLY 01 -#define O_RDWR 02 -#ifndef O_CREAT -# define O_CREAT 0100 /* Not fcntl. */ -#endif -#ifndef O_EXCL -# define O_EXCL 0200 /* Not fcntl. */ -#endif -#ifndef O_NOCTTY -# define O_NOCTTY 0400 /* Not fcntl. */ -#endif -#ifndef O_TRUNC -# define O_TRUNC 01000 /* Not fcntl. */ -#endif -#ifndef O_APPEND -# define O_APPEND 02000 -#endif -#ifndef O_NONBLOCK -# define O_NONBLOCK 04000 -#endif -#ifndef O_NDELAY -# define O_NDELAY O_NONBLOCK -#endif -#ifndef O_SYNC -# define O_SYNC 04010000 -#endif -#define O_FSYNC O_SYNC -#ifndef O_ASYNC -# define O_ASYNC 020000 -#endif -#ifndef __O_LARGEFILE -# define __O_LARGEFILE 0100000 -#endif - -#ifndef __O_DIRECTORY -# define __O_DIRECTORY 0200000 -#endif -#ifndef __O_NOFOLLOW -# define __O_NOFOLLOW 0400000 -#endif -#ifndef __O_CLOEXEC -# define __O_CLOEXEC 02000000 -#endif -#ifndef __O_DIRECT -# define __O_DIRECT 040000 -#endif -#ifndef __O_NOATIME -# define __O_NOATIME 01000000 -#endif -#ifndef __O_PATH -# define __O_PATH 010000000 -#endif -#ifndef __O_DSYNC -# define __O_DSYNC 010000 -#endif -#ifndef __O_TMPFILE -# define __O_TMPFILE (020000000 | __O_DIRECTORY) -#endif - -#define PIPE_SIDE_WRITE 1 -#define PIPE_SIDE_READ 2 - - -typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; - -#define NCCS 19 - -#define TCGETS2 0x802c542a -#define TCSETS2 0x402c542b -#define TCSETSW2 0x402c542c -#define TCSETSF2 0x402c542d - -typedef struct { - tcflag_t c_iflag; - tcflag_t c_oflag; - tcflag_t c_cflag; - tcflag_t c_lflag; - cc_t c_line; - cc_t c_cc[NCCS]; - speed_t ibaud; - speed_t obaud; -} __attribute__((packed)) termios_t; - -typedef struct { - tcflag_t c_iflag; - tcflag_t c_oflag; - tcflag_t c_cflag; - tcflag_t c_lflag; - cc_t c_line; - cc_t c_cc[NCCS]; -} __attribute__((packed)) termiosold_t; - -void __vfs_symlink_resolve(char* path, char* out); -char * __vfs__strtok(char **next,char *str, const char *delim); - -#define EFD_SEMAPHORE 1 -#define EFD_NONBLOCK O_NONBLOCK - -struct ucred { - int pid; - int uid; - int gid; -}; - -namespace vfs { - - class eventfd { - private: - int used = 0; - public: - locks::spinlock lock; - std::uint64_t buffer = 0; - int flags = 0; - - eventfd(int init, int flags) { - this->buffer = init; - this->flags = flags; - } - - void create() { - used++; - } - - void close() { - used--; - if(used == 0) - delete this; - } - - std::int64_t write(std::uint64_t val) { - this->lock.lock(); - std::uint64_t future = buffer + val; - if(future >= (0xFFFFFFFFFFFFFFFF - 1)) { - if(flags & EFD_NONBLOCK) { - this->lock.unlock(); - return -EAGAIN; - } else { - while(future >= (0xFFFFFFFFFFFFFFFF - 1)) { - this->lock.unlock(); - yield(); - this->lock.lock(); - future = buffer + val; - } - } - } - buffer += val; - this->lock.unlock(); - return 8; - } - - std::int64_t read(std::uint64_t* val) { - this->lock.lock(); - if(this->buffer == 0) { - if(this->flags & EFD_NONBLOCK) { - this->lock.unlock(); - return -EAGAIN; - } - - while(this->buffer == 0) { - this->lock.unlock(); - yield(); - this->lock.lock(); - } - } - *val = this->buffer; - if(this->flags & EFD_SEMAPHORE) - this->buffer--; - else - this->buffer = 0; - this->lock.unlock(); - return 8; - } - - ~eventfd() { - - } - - }; - - // same as fdpassmanager but ucred - class ucred_manager { - private: - struct ucred* fds = 0; - Lists::Bitmap* bitmap = 0; - int fd_size = 0; - int current_ptr = 0; - - int allocate() { - for(int i = 0; i < 64; i++) { - if(!this->bitmap->test(i)) - return i; - } - return -1; - } - - int find_free() { - for(int i = 0; i < 64; i++) { - if(this->bitmap->test(i)) - return i; - } - return -1; - } - - public: - - locks::spinlock lock; - - ucred_manager() { - this->fd_size = 64; // default to 16 passing fds - this->fds = new struct ucred[this->fd_size]; - this->bitmap = new Lists::Bitmap(this->fd_size); - } - - ~ucred_manager() { - delete (void*)this->fds; - delete (void*)this->bitmap; - } - - int pop(struct ucred* out) { - this->lock.lock(); - int idx = find_free(); - if(idx == -1) { this->lock.unlock(); - return -1; } - memcpy(out,&fds[idx],sizeof(struct ucred)); - this->bitmap->clear(idx); - this->lock.unlock(); - return 0; - } - - int push(struct ucred* src) { - this->lock.lock(); - int idx = allocate(); - if(idx == -1) { this->lock.unlock(); - return -1; } - memcpy(&fds[idx],src,sizeof(struct ucred)); - this->bitmap->set(idx); - this->lock.unlock(); - return 0; - } - - }; - - - class pipe { - private: - - std::uint64_t read_ptr = 0; - - std::atomic_flag is_received = ATOMIC_FLAG_INIT; - std::atomic_flag is_n_closed = ATOMIC_FLAG_INIT; - - - int is_was_writed_ever = 0; - - public: - - char* buffer; - - locks::spinlock lock; - - std::atomic_flag is_closed = ATOMIC_FLAG_INIT; - - std::uint64_t total_size = 0; - std::atomic<std::int64_t> size = 0; - std::int64_t write_counter = 0; - std::int64_t read_counter = 0; - - std::uint32_t connected_to_pipe = 0; - std::uint32_t connected_to_pipe_write = 0; - std::uint64_t flags = 0; - - std::uint32_t zero_message_count = 0; - - int is_closed_socket = 0; - - int tty_ret = 0; - termios_t* ttyflags = 0; - - void* fd_pass = 0; - ucred_manager* ucred_pass = 0; - - pipe(std::uint64_t flags) { - this->buffer = (char*)memory::pmm::_virtual::alloc(USERSPACE_PIPE_SIZE); - this->total_size = USERSPACE_PIPE_SIZE; - this->size = 0; - this->connected_to_pipe = 2; /* syscall which creates pipe should create 2 fds too */ - this->connected_to_pipe_write = 1; - this->flags = flags; - - this->is_closed.clear(std::memory_order_release); - - } - - void set_tty_ret() { - tty_ret = 1; - } - - void fifoclose() { - this->lock.lock(); - this->is_received.clear(); - this->is_closed.test_and_set(); - this->lock.unlock(); - } - - void close(std::uint8_t side) { - this->lock.lock(); - this->connected_to_pipe--; - - if(side == PIPE_SIDE_WRITE) { - this->connected_to_pipe_write--; - if(this->connected_to_pipe_write == 0) { - this->is_received.clear(); - this->is_closed.test_and_set(std::memory_order_acquire); - } - } - - this->lock.unlock(); - - if(this->connected_to_pipe == 0) { - delete this; - } - } - - void create(std::uint8_t side) { - this->lock.lock(); - this->connected_to_pipe++; - if(side == PIPE_SIDE_WRITE) - this->connected_to_pipe_write++; - this->lock.unlock(); - } - - std::uint64_t force_write(const char* src_buffer, std::uint64_t count) { - if (this->size + count > this->total_size) { - count = this->total_size - this->size; - } - this->size += count; - memcpy(this->buffer + (this->size - count), src_buffer, count); - return count; - } - - std::uint64_t write(const char* src_buffer, std::uint64_t count,int id) { - - std::uint64_t written = 0; - - if(count == 0) { - this->lock.lock(); - this->zero_message_count = 1; - this->lock.unlock(); - return 0; - } - - while (written < count) { - this->lock.lock(); - - std::uint64_t space_left = this->total_size - this->size; - if (space_left == 0) { - this->lock.unlock(); - yield(); - continue; - } - - uint64_t old_size = this->size; - - std::uint64_t to_write = (count - written) < space_left ? (count - written) : space_left; - if(to_write < 0) - to_write = 0; - - - force_write(src_buffer + written, to_write); - - written += to_write; - this->read_counter++; - - this->lock.unlock(); - } - return written; - } - - std::uint64_t nolock_write(const char* src_buffer, std::uint64_t count,int id) { - - std::uint64_t written = 0; - - if(count == 0) { - this->zero_message_count = 1; - return 0; - } - - while (written < count) { - - std::uint64_t space_left = this->total_size - this->size; - - uint64_t old_size = this->size; - - std::uint64_t to_write = (count - written) < space_left ? (count - written) : space_left; - if(to_write < 0) - to_write = 0; - - - force_write(src_buffer + written, to_write); - - written += to_write; - this->read_counter++; - - } - return written; - } - - std::uint64_t ttyread(std::int64_t* read_count, char* dest_buffer, std::uint64_t count, int is_block) { - - std::uint64_t read_bytes = 0; - int tries = 0; - - while (true) { - this->lock.lock(); - - if (this->size == 0) { - if (this->is_closed.test(std::memory_order_acquire)) { - this->lock.unlock(); - return 0; - } - if (flags & O_NONBLOCK || is_block) { - this->lock.unlock(); - return 0; - } - if(ttyflags) { - if(!(ttyflags->c_lflag & ICANON) && ttyflags->c_cc[VMIN] == 0) { - this->lock.unlock(); - return 0; - } - } - this->lock.unlock(); - yield(); - continue; - } - - if(ttyflags) { - if(!(ttyflags->c_lflag & ICANON)) { - if(this->size < ttyflags->c_cc[VMIN]) { - this->lock.unlock(); - return 0; - } - } - } - - if(ttyflags) { - if(ttyflags->c_lflag & ICANON) { - if(!tty_ret) { - this->lock.unlock(); - yield(); - continue; - } - } - } - - read_bytes = (count < (std::uint64_t)this->size) ? count : (std::uint64_t)this->size; - memcpy(dest_buffer, this->buffer, read_bytes); - memmove(this->buffer, this->buffer + read_bytes, this->size - read_bytes); - this->size -= read_bytes; - - this->write_counter++; - - if(this->size <= 0) { - - tty_ret = 0; - } else - this->read_counter++; - - this->lock.unlock(); - break; - } - return read_bytes; - } - - std::int64_t read(std::int64_t* read_count, char* dest_buffer, std::uint64_t count, int is_block) { - - std::uint64_t read_bytes = 0; - int tries = 0; - - while (true) { - this->lock.lock(); - - if (this->size == 0) { - - if (this->is_closed.test(std::memory_order_acquire)) { - this->lock.unlock(); - return 0; - } - - if(this->is_closed_socket) { - this->lock.unlock(); - return 0; - } - - if (flags & O_NONBLOCK || is_block) { - this->lock.unlock(); - return -11; - } - this->lock.unlock(); - yield(); - continue; - } - - read_bytes = (count < (std::uint64_t)this->size) ? count : (std::uint64_t)this->size; - memcpy(dest_buffer, this->buffer, read_bytes); - memmove(this->buffer, this->buffer + read_bytes, this->size - read_bytes); - this->size -= read_bytes; - - this->write_counter++; - - if(this->size <= 0) { - - tty_ret = 0; - } else - this->read_counter++; - - this->lock.unlock(); - break; - } - return read_bytes; - } - - - - ~pipe() { - memory::pmm::_virtual::free(this->buffer); - if(ucred_pass) - delete (void*)ucred_pass; - } - - }; - -}; - -#define POLLIN 0x0001 -#define POLLPRI 0x0002 -#define POLLOUT 0x0004 -#define POLLERR 0x0008 -#define POLLHUP 0x0010 -#define POLLNVAL 0x0020 -#define POLLRDNORM 0x0040 -#define POLLRDBAND 0x0080 -#define POLLWRNORM 0x0100 -#define POLLWRBAND 0x0200 -#define POLLRDHUP 0x2000 - -#define USERSPACE_FD_OTHERSTATE_MASTER 1 -#define USERSPACE_FD_OTHERSTATE_SLAVE 2 - -char * __vfs__strtok(char **next,char *str, const char *delim); - -/* It should be restored in dup2 syscall when oldfd is 0 */ -typedef struct { - std::int32_t index; - std::uint8_t state; - std::uint8_t pipe_side; - vfs::pipe* pipe; -} userspace_old_fd_t; - -enum - { - DT_UNKNOWN = 0, -# define DT_UNKNOWN DT_UNKNOWN - DT_FIFO = 1, -# define DT_FIFO DT_FIFO - DT_CHR = 2, -# define DT_CHR DT_CHR - DT_DIR = 4, -# define DT_DIR DT_DIR - DT_BLK = 6, -# define DT_BLK DT_BLK - DT_REG = 8, -# define DT_REG DT_REG - DT_LNK = 10, -# define DT_LNK DT_LNK - DT_SOCK = 12, -# define DT_SOCK DT_SOCK - DT_WHT = 14 -# define DT_WHT DT_WHT - }; - -struct linux_dirent64 { - long long d_ino; - long long d_off; - unsigned short d_reclen; - unsigned char d_type; - char d_name[]; -}; - -typedef struct userspace_fd { - std::uint64_t offset; - std::uint64_t flags; - std::int32_t index; - std::uint8_t state; - std::uint8_t pipe_side; - - std::uint64_t rv0; - int rv1; - - int pid; - int uid; - - int is_cloexec; - - std::uint8_t can_be_closed; - - std::uint8_t is_listen; - vfs::pipe* read_socket_pipe; - vfs::pipe* write_socket_pipe; - - int socket_pid; - int socket_uid; - - std::uint8_t is_a_tty; - - std::uint8_t other_state; - - std::uint32_t queue; - std::uint8_t cycle; - - std::uint32_t mode; - - std::int64_t write_counter; - std::int64_t read_counter; - - void* binded_socket; - - int is_cached_path; - int is_debug; - - vfs::eventfd* eventfd; - - vfs::pipe* pipe; - char path[2048]; - - struct userspace_fd* old_state; - struct userspace_fd* next; /* Should be changed in fork() */ - -} userspace_fd_t; - - - -static_assert(sizeof(userspace_fd_t) < 4096,"userspace_fd size is bigger than page size"); - -namespace vfs { - - class passingfd_manager { - private: - userspace_fd_t* fds = 0; - Lists::Bitmap* bitmap = 0; - int fd_size = 0; - int current_ptr = 0; - - int allocate() { - for(int i = 0; i < 16; i++) { - if(!this->bitmap->test(i)) - return i; - } - return -1; - } - - int find_free() { - for(int i = 0; i < 16; i++) { - if(this->bitmap->test(i)) - return i; - } - return -1; - } - - public: - - locks::spinlock lock; - - passingfd_manager() { - this->fd_size = 16; // default to 16 passing fds - this->fds = new userspace_fd_t[this->fd_size]; - this->bitmap = new Lists::Bitmap(this->fd_size); - } - - ~passingfd_manager() { - delete (void*)this->fds; - delete (void*)this->bitmap; - } - - int pop(userspace_fd_t* out) { - this->lock.lock(); - int idx = find_free(); - if(idx == -1) { this->lock.unlock(); - return -1; } - memcpy(out,&fds[idx],sizeof(userspace_fd_t)); - this->bitmap->clear(idx); - this->lock.unlock(); - return 0; - } - - int push(userspace_fd_t* src) { - this->lock.lock(); - int idx = allocate(); - if(idx == -1) { this->lock.unlock(); - return -1; } - memcpy(&fds[idx],src,sizeof(userspace_fd_t)); - this->bitmap->set(idx); - this->lock.unlock(); - return 0; - } - - }; - - class fd { - public: - /* Just helper function for non userspace usage */ - static inline void fill(userspace_fd_t* fd,char* name) { - memcpy(fd->path,name,strlen(name)); - } - }; -}; - -#define __MLIBC_DIRENT_BODY std::uint64_t d_ino; \ - std::uint64_t d_off; \ - std::uint16_t d_reclen; \ - std::uint8_t d_type; \ - char d_name[1024]; - -#define AT_FDCWD -100 -#define AT_SYMLINK_NOFOLLOW 0x100 -#define AT_REMOVEDIR 0x200 -#define AT_SYMLINK_FOLLOW 0x400 -#define AT_EACCESS 0x200 -#define AT_NO_AUTOMOUNT 0x800 -#define AT_EMPTY_PATH 0x1000 - -#define S_IFMT 0x0F000 -#define S_IFBLK 0x06000 -#define S_IFCHR 0x02000 -#define S_IFIFO 0x01000 -#define S_IFREG 0x08000 -#define S_IFDIR 0x04000 -#define S_IFLNK 0x0A000 -#define S_IFSOCK 0x0C000 - -#define TMPFS_VAR_CHMOD 0 -#define TMPFS_VAR_UNLINK 1 -#define DEVFS_VAR_ISATTY 2 - -typedef long time_t; -struct timespec { - time_t tv_sec; - long tv_nsec; -}; - -typedef long long __mlibc_int64; -typedef unsigned int __mlibc_uint32; -typedef unsigned short __mlibc_uint16; -typedef unsigned long long __mlibc_uint64; - -struct statx_timestamp { - __mlibc_int64 tv_sec; - __mlibc_uint32 tv_nsec; - __mlibc_uint32 __padding; -}; - -#define STATX_TYPE 0x1 -#define STATX_MODE 0x2 -#define STATX_NLINK 0x4 -#define STATX_UID 0x8 -#define STATX_GID 0x10 -#define STATX_ATIME 0x20 -#define STATX_MTIME 0x40 -#define STATX_CTIME 0x80 -#define STATX_INO 0x100 -#define STATX_SIZE 0x200 -#define STATX_BLOCKS 0x400 -#define STATX_BASIC_STATS 0x7ff -#define STATX_BTIME 0x800 -#define STATX_MNT_ID 0x1000 -#define STATX_DIOALIGN 0x2000 -#define STATX_ALL 0xfff - -#define STATX_ATTR_COMPRESSED 0x4 -#define STATX_ATTR_IMMUTABLE 0x10 -#define STATX_ATTR_APPEND 0x20 -#define STATX_ATTR_NODUMP 0x40 -#define STATX_ATTR_ENCRYPTED 0x800 -#define STATX_ATTR_AUTOMOUNT 0x1000 -#define STATX_ATTR_MOUNT_ROOT 0x2000 -#define STATX_ATTR_VERITY 0x100000 -#define STATX_ATTR_DAX 0x200000 - -typedef struct statx { - __mlibc_uint32 stx_mask; - - __mlibc_uint32 stx_blksize; - __mlibc_uint64 stx_attributes; - __mlibc_uint32 stx_nlink; - __mlibc_uint32 stx_uid; - __mlibc_uint32 stx_gid; - __mlibc_uint16 stx_mode; - __mlibc_uint16 __padding; - __mlibc_uint64 stx_ino; - __mlibc_uint64 stx_size; - __mlibc_uint64 stx_blocks; - __mlibc_uint64 stx_attributes_mask; - - struct statx_timestamp stx_atime; - struct statx_timestamp stx_btime; - struct statx_timestamp stx_ctime; - struct statx_timestamp stx_mtime; - - __mlibc_uint32 stx_rdev_major; - __mlibc_uint32 stx_rdev_minor; - __mlibc_uint32 stx_dev_major; - __mlibc_uint32 stx_dev_minor; - - __mlibc_uint64 stx_mnt_id; - __mlibc_uint32 stx_dio_mem_align; - __mlibc_uint32 stx_dio_offset_align; - - __mlibc_uint64 __padding1[12]; -} statx_t; - -namespace vfs { - - static inline std::uint64_t resolve_count(char* str,std::uint64_t sptr,char delim) { - char* current = str; - std::uint16_t att = 0; - std::uint64_t ptr = sptr; - std::uint64_t ptr_count = 0; - while(current[ptr] != delim) { - if(att > 1024) - return 0; - att++; - - if(ptr != 0) { - ptr_count++; - ptr--; - } - } - return ptr; - } - - - static inline int normalize_path(const char* src, char* dest, std::uint64_t dest_size) { - if (!src ||!dest || dest_size < 2) return -1; - std::uint64_t j = 0; - int prev_slash = 0; - for (std::uint64_t i = 0; src[i] && j < dest_size - 1; i++) { - if (src[i] == '/') { - if (!prev_slash) { - dest[j++] = '/'; - prev_slash = 1; - } - } else { - dest[j++] = src[i]; - prev_slash = 0; - } - } - - if (j > 1 && dest[j-1] == '/') j--; - if (j >= dest_size) { - dest[0] = '\0'; - return -1; - } - dest[j] = '\0'; - return 0; - } - - /* I'll use path resolver from my old kernel */ - static inline void resolve_path(const char* inter0,const char* base, char *result, char spec, char is_follow_symlinks) { - char* next = 0; - char buffer2_in_stack[2048]; - char inter[2048]; - char* buffer = 0; - char* final_buffer = (char*)buffer2_in_stack; - std::uint64_t ptr = strlen((char*)base); - char is_first = 1; - char is_full = 0; - - memcpy(inter,inter0,strlen(inter0) + 1); - - if(strlen((char*)inter) == 1 && inter[0] == '.') { - memcpy(result,base,strlen((char*)base) + 1); - if(result[0] == '\0') { - result[0] = '/'; - result[1] = '\0'; - } - return; - } - - if(!strcmp(inter,"/")) { - memcpy(result,inter,strlen((char*)inter) + 1); - if(result[0] == '\0') { - result[0] = '/'; - result[1] = '\0'; - } - return; - } - - if(inter[0] == '/') { - ptr = 0; - is_full = 1; - } else { - memcpy(final_buffer,base,strlen((char*)base) + 1); - } - - if(spec) - is_first = 0; - - if(!strcmp(base,"/")) - is_first = 0; - - buffer = __vfs__strtok(&next,(char*)inter,"/"); - while(buffer) { - - if(is_first && !is_full) { - std::uint64_t mm = resolve_count(final_buffer,ptr,'/'); - - if(ptr < mm) { - final_buffer[0] = '/'; - final_buffer[1] = '\0'; - ptr = 1; - continue; - } - - ptr = mm; - final_buffer[ptr] = '\0'; - is_first = 0; - } - - if(!strcmp(buffer,"..")) { - std::uint64_t mm = resolve_count(final_buffer,ptr,'/'); - - if(!strcmp(final_buffer,"/\0")) { - buffer = __vfs__strtok(&next,0,"/"); - continue; - } - - - if(ptr < mm) { - final_buffer[0] = '/'; - final_buffer[1] = '\0'; - ptr = 1; - continue; - } - - ptr = mm; - final_buffer[ptr] = '\0'; - - - - } else if(strcmp(buffer,"./") && strcmp(buffer,".")) { - - final_buffer[ptr] = '/'; - ptr++; - - std::uint64_t mm = 0; - mm = strlen(buffer); - memcpy((char*)((std::uint64_t)final_buffer + ptr),buffer,mm); - ptr += mm; - final_buffer[ptr] = '\0'; - } - - buffer = __vfs__strtok(&next,0,"/"); - } - normalize_path(final_buffer,result,2048); - - if(result[0] == '\0') { - result[0] = '/'; - result[1] = '\0'; - } - - - } - - typedef struct { - __MLIBC_DIRENT_BODY; - } dirent_t; - - - - typedef struct { - unsigned long st_dev; - unsigned long st_ino; - unsigned long st_nlink; - unsigned int st_mode; - unsigned int st_uid; - unsigned int st_gid; - unsigned int __pad0; - unsigned long st_rdev; - long st_size; - long st_blksize; - long st_blocks; - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - long __unused[3]; - } __attribute__((packed)) stat_t; - - typedef struct { - - /* yes fd contain only full path, but char* path is relative to fs path, for example full path /dev/hi/l will be /hi/l */ - std::int32_t (*open) (userspace_fd_t* fd, char* path ); /* its used if fs decide to change some fd flags */ - std::int64_t (*write) (userspace_fd_t* fd, char* path, void* buffer, std::uint64_t size ); - std::int64_t (*read) (userspace_fd_t* fd, char* path, void* buffer, std::uint64_t count ); - std::int32_t (*stat) (userspace_fd_t* fd, char* path, stat_t* out ); - std::int32_t (*var) (userspace_fd_t* fd, char* path, std::uint64_t value, std::uint8_t request ); - std::int32_t (*ls) (userspace_fd_t* fd, char* path, dirent_t* out ); - std::int32_t (*remove) (userspace_fd_t* fd, char* path ); - std::int32_t (*ioctl) (userspace_fd_t* fd, char* path, unsigned long req, void *arg, int *res ); - std::int32_t (*mmap) (userspace_fd_t* fd, char* path, std::uint64_t* outp, std::uint64_t* outsz, std::uint64_t* outflags ); - std::int32_t (*create) (char* path, std::uint8_t type ); - std::int32_t (*touch) (char* path, int mode ); - - std::int32_t (*statx) (userspace_fd_t* fd, char* path, int flags, int mask, statx_t* out); - - std::int64_t (*poll) (userspace_fd_t* fd, char* path, int request); - - std::int32_t (*readlink) (char* path, char* out, std::uint32_t out_len); - std::int32_t (*rename) (char* path, char* new_path); - - std::int32_t (*unlink) (userspace_fd_t* fd, char* path); - - void (*opt_create_and_write)(char* path, int type, char* content, std::uint64_t content_len, int chmod); - - void (*close)(userspace_fd_t* fd, char* path); - - char path[2048]; - } vfs_node_t; - - typedef struct fifo_node { - pipe* main_pipe; - char path[2048]; - char is_used; - struct fifo_node* next; - } fifo_node_t; - - class vfs { - public: - static void init(); - - static std::int32_t open (userspace_fd_t* fd ); - static std::int64_t write (userspace_fd_t* fd, void* buffer, std::uint64_t size ); - static std::int64_t read (userspace_fd_t* fd, void* buffer, std::uint64_t count ); - static std::int32_t stat (userspace_fd_t* fd, stat_t* out ); - static std::int32_t nosym_stat (userspace_fd_t* fd, stat_t* out ); - static std::int32_t var (userspace_fd_t* fd, std::uint64_t value, std::uint8_t request ); - static std::int32_t ls (userspace_fd_t* fd, dirent_t* out ); - static std::int32_t remove (userspace_fd_t* fd ); - static std::int64_t ioctl (userspace_fd_t* fd, unsigned long req, void *arg, int *res ); - static std::int32_t mmap (userspace_fd_t* fd, std::uint64_t* outp, std::uint64_t* outsz, std::uint64_t* outflags); - - static std::int64_t poll(userspace_fd_t* fd, int operation_type); - - static void close(userspace_fd_t* fd); - - static std::int32_t create (char* path, std::uint8_t type ); - static std::int32_t touch (char* path, int mode ); - - - static std::int32_t rename (char* path, char* new_path); - static std::int32_t readlink(char* path, char* out, std::uint32_t out_len); /* Lock-less, vfs lock should be already locked */ - - static std::uint32_t create_fifo(char* path); - - static std::int32_t statx(userspace_fd_t* fd, int flags, int mask, statx_t* out); - static std::int32_t extern_readlink(char* path, char* out, std::uint32_t out_len); - - static std::int32_t unlink(userspace_fd_t* fd); - - static void opt_create_and_write(char* path, int type, char* content, std::uint64_t content_len, int chmod); - - static void unlock(); - static void lock(); - - }; - -}; - -void __vfs_symlink_resolve(char* path, char* out);
\ No newline at end of file diff --git a/kernel/include/lib/nanoprintf.h b/kernel/include/lib/nanoprintf.h deleted file mode 100644 index a415ad9..0000000 --- a/kernel/include/lib/nanoprintf.h +++ /dev/null @@ -1,1203 +0,0 @@ -/* nanoprintf v0.5.5: a tiny embeddable printf replacement written in C. - https://github.com/charlesnicholson/nanoprintf - charles.nicholson+nanoprintf@gmail.com - dual-licensed under 0bsd and unlicense, take your pick. see eof for details. */ - -#ifndef NPF_H_INCLUDED -#define NPF_H_INCLUDED - -#include <stdarg.h> -#include <stddef.h> - -// Define this to fully sandbox nanoprintf inside of a translation unit. -#ifdef NANOPRINTF_VISIBILITY_STATIC - #define NPF_VISIBILITY static -#else - #define NPF_VISIBILITY extern -#endif - -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) - #define NPF_PRINTF_ATTR(FORMAT_INDEX, VARGS_INDEX) \ - __attribute__((format(printf, FORMAT_INDEX, VARGS_INDEX))) -#else - #define NPF_PRINTF_ATTR(FORMAT_INDEX, VARGS_INDEX) -#endif - -// Public API - -#ifdef __cplusplus -#define NPF_RESTRICT -extern "C" { -#else -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -#define NPF_RESTRICT restrict -#else -#define NPF_RESTRICT -#endif -#endif - -// The npf_ functions all return the number of bytes required to express the -// fully-formatted string, not including the null terminator character. -// The npf_ functions do not return negative values, since the lack of 'l' length -// modifier support makes encoding errors impossible. - -NPF_VISIBILITY int npf_snprintf(char * NPF_RESTRICT buffer, - size_t bufsz, - const char * NPF_RESTRICT format, - ...) NPF_PRINTF_ATTR(3, 4); - -NPF_VISIBILITY int npf_vsnprintf(char * NPF_RESTRICT buffer, - size_t bufsz, - char const * NPF_RESTRICT format, - va_list vlist) NPF_PRINTF_ATTR(3, 0); - -typedef void (*npf_putc)(int c, void *ctx); -NPF_VISIBILITY int npf_pprintf(npf_putc pc, - void * NPF_RESTRICT pc_ctx, - char const * NPF_RESTRICT format, - ...) NPF_PRINTF_ATTR(3, 4); - -NPF_VISIBILITY int npf_vpprintf(npf_putc pc, - void * NPF_RESTRICT pc_ctx, - char const * NPF_RESTRICT format, - va_list vlist) NPF_PRINTF_ATTR(3, 0); - -#ifdef __cplusplus -} -#endif - -#endif // NPF_H_INCLUDED - -/* The implementation of nanoprintf begins here, to be compiled only if - NANOPRINTF_IMPLEMENTATION is defined. In a multi-file library what follows would - be nanoprintf.c. */ - -#ifdef NANOPRINTF_IMPLEMENTATION - -#ifndef NPF_IMPLEMENTATION_INCLUDED -#define NPF_IMPLEMENTATION_INCLUDED - -#include <limits.h> -#include <stdint.h> - -// The conversion buffer must fit at least UINT64_MAX in octal format with the leading '0'. -#ifndef NANOPRINTF_CONVERSION_BUFFER_SIZE - #define NANOPRINTF_CONVERSION_BUFFER_SIZE 23 -#endif -#if NANOPRINTF_CONVERSION_BUFFER_SIZE < 23 - #error The size of the conversion buffer must be at least 23 bytes. -#endif - -// Pick reasonable defaults if nothing's been configured. -#if !defined(NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_ALT_FORM_FLAG) - #define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1 - #define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 1 - #define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 1 - #define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 0 - #define NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS 1 - #define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 0 - #define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 0 - #define NANOPRINTF_USE_ALT_FORM_FLAG 1 -#endif - -// If anything's been configured, everything must be configured. -#ifndef NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS - #error NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif -#ifndef NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS - #error NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif -#ifndef NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS - #error NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif -#ifndef NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS - #error NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif -#ifndef NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS - #error NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif -#ifndef NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS - #error NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif -#ifndef NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS - #error NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif - -// Ensure flags are compatible. -#if (NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1) && \ - (NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 0) - #error Precision format specifiers must be enabled if float support is enabled. -#endif - -// intmax_t / uintmax_t require stdint from c99 / c++11 -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - #ifndef _MSC_VER - #ifdef __cplusplus - #if __cplusplus < 201103L - #error large format specifier support requires C++11 or later. - #endif - #else - #if __STDC_VERSION__ < 199409L - #error nanoprintf requires C99 or later. - #endif - #endif - #endif -#endif - -// Figure out if we can disable warnings with pragmas. -#ifdef __clang__ - #define NPF_CLANG 1 - #define NPF_GCC_PAST_4_6 0 -#else - #define NPF_CLANG 0 - #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6))) - #define NPF_GCC_PAST_4_6 1 - #else - #define NPF_GCC_PAST_4_6 0 - #endif -#endif - -#if NPF_CLANG || NPF_GCC_PAST_4_6 - #define NPF_HAVE_GCC_WARNING_PRAGMAS 1 -#else - #define NPF_HAVE_GCC_WARNING_PRAGMAS 0 -#endif - -#if NPF_HAVE_GCC_WARNING_PRAGMAS - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wunused-function" - #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" - #ifdef __cplusplus - #pragma GCC diagnostic ignored "-Wold-style-cast" - #endif - #pragma GCC diagnostic ignored "-Wpadded" - #pragma GCC diagnostic ignored "-Wfloat-equal" - #if NPF_CLANG - #pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" - #pragma GCC diagnostic ignored "-Wcovered-switch-default" - #pragma GCC diagnostic ignored "-Wdeclaration-after-statement" - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - #ifndef __APPLE__ - #pragma GCC diagnostic ignored "-Wunsafe-buffer-usage" - #endif - #elif NPF_GCC_PAST_4_6 - #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" - #endif -#endif - -#ifdef _MSC_VER - #pragma warning(push) - #pragma warning(disable:4619) // there is no warning number 'number' - // C4619 has to be disabled first! - #pragma warning(disable:4127) // conditional expression is constant - #pragma warning(disable:4505) // unreferenced local function has been removed - #pragma warning(disable:4514) // unreferenced inline function has been removed - #pragma warning(disable:4701) // potentially uninitialized local variable used - #pragma warning(disable:4706) // assignment within conditional expression - #pragma warning(disable:4710) // function not inlined - #pragma warning(disable:4711) // function selected for inline expansion - #pragma warning(disable:4820) // padding added after struct member - #pragma warning(disable:5039) // potentially throwing function passed to extern C function - #pragma warning(disable:5045) // compiler will insert Spectre mitigation for memory load - #pragma warning(disable:5262) // implicit switch fall-through - #pragma warning(disable:26812) // enum type is unscoped -#endif - -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) - #define NPF_NOINLINE __attribute__((noinline)) - #define NPF_FORCE_INLINE inline __attribute__((always_inline)) -#elif defined(_MSC_VER) - #define NPF_NOINLINE __declspec(noinline) - #define NPF_FORCE_INLINE inline __forceinline -#else - #define NPF_NOINLINE - #define NPF_FORCE_INLINE -#endif - -#if (NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1) || \ - (NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1) -enum { - NPF_FMT_SPEC_OPT_NONE, - NPF_FMT_SPEC_OPT_LITERAL, - NPF_FMT_SPEC_OPT_STAR, -}; -#endif - -enum { - NPF_FMT_SPEC_LEN_MOD_NONE, -#if NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS == 1 - NPF_FMT_SPEC_LEN_MOD_SHORT, // 'h' - NPF_FMT_SPEC_LEN_MOD_CHAR, // 'hh' -#endif - NPF_FMT_SPEC_LEN_MOD_LONG, // 'l' - NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE, // 'L' -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - NPF_FMT_SPEC_LEN_MOD_LARGE_LONG_LONG, // 'll' - NPF_FMT_SPEC_LEN_MOD_LARGE_INTMAX, // 'j' - NPF_FMT_SPEC_LEN_MOD_LARGE_SIZET, // 'z' - NPF_FMT_SPEC_LEN_MOD_LARGE_PTRDIFFT, // 't' -#endif -}; - -enum { - NPF_FMT_SPEC_CONV_NONE, - NPF_FMT_SPEC_CONV_PERCENT, // '%' - NPF_FMT_SPEC_CONV_CHAR, // 'c' - NPF_FMT_SPEC_CONV_STRING, // 's' - NPF_FMT_SPEC_CONV_SIGNED_INT, // 'i', 'd' -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 - NPF_FMT_SPEC_CONV_BINARY, // 'b' -#endif - NPF_FMT_SPEC_CONV_OCTAL, // 'o' - NPF_FMT_SPEC_CONV_HEX_INT, // 'x', 'X' - NPF_FMT_SPEC_CONV_UNSIGNED_INT, // 'u' - NPF_FMT_SPEC_CONV_POINTER, // 'p' -#if NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS == 1 - NPF_FMT_SPEC_CONV_WRITEBACK, // 'n' -#endif -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - NPF_FMT_SPEC_CONV_FLOAT_DEC, // 'f', 'F' - NPF_FMT_SPEC_CONV_FLOAT_SCI, // 'e', 'E' - NPF_FMT_SPEC_CONV_FLOAT_SHORTEST, // 'g', 'G' - NPF_FMT_SPEC_CONV_FLOAT_HEX, // 'a', 'A' -#endif -}; - -typedef struct npf_format_spec { -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - int field_width; -#endif -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - int prec; - uint8_t prec_opt; -#endif -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - uint8_t field_width_opt; - char left_justified; // '-' - char leading_zero_pad; // '0' -#endif - char prepend; // ' ' or '+' -#if NANOPRINTF_USE_ALT_FORM_FLAG == 1 - char alt_form; // '#' -#endif - char case_adjust; // 'a' - 'A' , or 0 (must be non-negative to work) - uint8_t length_modifier; - uint8_t conv_spec; -} npf_format_spec_t; - -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 0 - typedef long npf_int_t; - typedef unsigned long npf_uint_t; -#else - typedef intmax_t npf_int_t; - typedef uintmax_t npf_uint_t; -#endif - -typedef struct npf_bufputc_ctx { - char *dst; - size_t len; - size_t cur; -} npf_bufputc_ctx_t; - -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - typedef char npf_size_is_ptrdiff[(sizeof(size_t) == sizeof(ptrdiff_t)) ? 1 : -1]; - typedef ptrdiff_t npf_ssize_t; - typedef size_t npf_uptrdiff_t; -#endif - -#ifdef _MSC_VER - #include <intrin.h> -#endif - -#define NPF_MIN(x, y) ((x) <= (y) ? (x) : (y)) -#define NPF_MAX(x, y) ((x) >= (y) ? (x) : (y)) - -static int npf_parse_format_spec(char const *format, npf_format_spec_t *out_spec) { - char const *cur = format; - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - out_spec->left_justified = 0; - out_spec->leading_zero_pad = 0; -#endif - out_spec->case_adjust = 'a' - 'A'; // lowercase - out_spec->prepend = 0; -#if NANOPRINTF_USE_ALT_FORM_FLAG == 1 - out_spec->alt_form = 0; -#endif - - while (*++cur) { // cur points at the leading '%' character - switch (*cur) { // Optional flags -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - case '-': out_spec->left_justified = '-'; out_spec->leading_zero_pad = 0; continue; - case '0': out_spec->leading_zero_pad = !out_spec->left_justified; continue; -#endif - case '+': out_spec->prepend = '+'; continue; - case ' ': if (out_spec->prepend == 0) { out_spec->prepend = ' '; } continue; -#if NANOPRINTF_USE_ALT_FORM_FLAG == 1 - case '#': out_spec->alt_form = '#'; continue; -#endif - default: break; - } - break; - } - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - out_spec->field_width = 0; - out_spec->field_width_opt = NPF_FMT_SPEC_OPT_NONE; - if (*cur == '*') { - out_spec->field_width_opt = NPF_FMT_SPEC_OPT_STAR; - ++cur; - } else { - while ((*cur >= '0') && (*cur <= '9')) { - out_spec->field_width_opt = NPF_FMT_SPEC_OPT_LITERAL; - out_spec->field_width = (out_spec->field_width * 10) + (*cur++ - '0'); - } - } -#endif - -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->prec = 0; - out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; - if (*cur == '.') { - ++cur; - if (*cur == '*') { - out_spec->prec_opt = NPF_FMT_SPEC_OPT_STAR; - ++cur; - } else { - if (*cur == '-') { - ++cur; - } else { - out_spec->prec_opt = NPF_FMT_SPEC_OPT_LITERAL; - } - while ((*cur >= '0') && (*cur <= '9')) { - out_spec->prec = (out_spec->prec * 10) + (*cur++ - '0'); - } - } - } -#endif - - uint_fast8_t tmp_conv = NPF_FMT_SPEC_CONV_NONE; - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_NONE; - switch (*cur++) { // Length modifier -#if NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS == 1 - case 'h': - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_SHORT; - if (*cur == 'h') { - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_CHAR; - ++cur; - } - break; -#endif - case 'l': - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LONG; -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - if (*cur == 'l') { - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_LONG_LONG; - ++cur; - } -#endif - break; -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - case 'L': out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE; break; -#endif -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - case 'j': out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_INTMAX; break; - case 'z': out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_SIZET; break; - case 't': out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_PTRDIFFT; break; -#endif - default: --cur; break; - } - - switch (*cur++) { // Conversion specifier - case '%': out_spec->conv_spec = NPF_FMT_SPEC_CONV_PERCENT; -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; - out_spec->prec = 0; -#endif - break; - - case 'c': out_spec->conv_spec = NPF_FMT_SPEC_CONV_CHAR; -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; - out_spec->prec = 0; -#endif - break; - - case 's': out_spec->conv_spec = NPF_FMT_SPEC_CONV_STRING; - break; - - case 'i': - case 'd': tmp_conv = NPF_FMT_SPEC_CONV_SIGNED_INT; goto finish; - case 'o': tmp_conv = NPF_FMT_SPEC_CONV_OCTAL; goto finish; - case 'u': tmp_conv = NPF_FMT_SPEC_CONV_UNSIGNED_INT; goto finish; - case 'X': out_spec->case_adjust = 0; - case 'x': tmp_conv = NPF_FMT_SPEC_CONV_HEX_INT; goto finish; - finish: - out_spec->conv_spec = (uint8_t)tmp_conv; -#if (NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1) && \ - (NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1) - if (out_spec->prec_opt != NPF_FMT_SPEC_OPT_NONE) { out_spec->leading_zero_pad = 0; } -#endif - break; - -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - case 'F': out_spec->case_adjust = 0; - case 'f': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_DEC; - if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { out_spec->prec = 6; } - break; - - case 'E': out_spec->case_adjust = 0; - case 'e': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_SCI; - if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { out_spec->prec = 6; } - break; - - case 'G': out_spec->case_adjust = 0; - case 'g': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_SHORTEST; - if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { out_spec->prec = 6; } - break; - - case 'A': out_spec->case_adjust = 0; - case 'a': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_HEX; - if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { out_spec->prec = 6; } - break; -#endif - -#if NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS == 1 - case 'n': - // todo: reject string if flags or width or precision exist - out_spec->conv_spec = NPF_FMT_SPEC_CONV_WRITEBACK; -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; -#endif - break; -#endif - - case 'p': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_POINTER; -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; -#endif - break; - -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 - case 'B': - out_spec->case_adjust = 0; - case 'b': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_BINARY; - break; -#endif - - default: return 0; - } - - return (int)(cur - format); -} - -static NPF_NOINLINE int npf_utoa_rev( - npf_uint_t val, char *buf, uint_fast8_t base, char case_adj) { - uint_fast8_t n = 0; - do { - int_fast8_t const d = (int_fast8_t)(val % base); - *buf++ = (char)(((d < 10) ? '0' : ('A' - 10 + case_adj)) + d); - ++n; - val /= base; - } while (val); - return (int)n; -} - -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - -#include <float.h> - -#if (DBL_MANT_DIG <= 11) && (DBL_MAX_EXP <= 16) - typedef uint_fast16_t npf_double_bin_t; - typedef int_fast8_t npf_ftoa_exp_t; -#elif (DBL_MANT_DIG <= 24) && (DBL_MAX_EXP <= 128) - typedef uint_fast32_t npf_double_bin_t; - typedef int_fast8_t npf_ftoa_exp_t; -#elif (DBL_MANT_DIG <= 53) && (DBL_MAX_EXP <= 1024) - typedef uint_fast64_t npf_double_bin_t; - typedef int_fast16_t npf_ftoa_exp_t; -#else - #error Unsupported width of the double type. -#endif - -// The floating point conversion code works with an unsigned integer type of any size. -#ifndef NANOPRINTF_CONVERSION_FLOAT_TYPE - #define NANOPRINTF_CONVERSION_FLOAT_TYPE unsigned int -#endif -typedef NANOPRINTF_CONVERSION_FLOAT_TYPE npf_ftoa_man_t; - -#if (NANOPRINTF_CONVERSION_BUFFER_SIZE <= UINT_FAST8_MAX) && (UINT_FAST8_MAX <= INT_MAX) - typedef uint_fast8_t npf_ftoa_dec_t; -#else - typedef int npf_ftoa_dec_t; -#endif - -enum { - NPF_DOUBLE_EXP_MASK = DBL_MAX_EXP * 2 - 1, - NPF_DOUBLE_EXP_BIAS = DBL_MAX_EXP - 1, - NPF_DOUBLE_MAN_BITS = DBL_MANT_DIG - 1, - NPF_DOUBLE_BIN_BITS = sizeof(npf_double_bin_t) * CHAR_BIT, - NPF_DOUBLE_SIGN_POS = sizeof(double) * CHAR_BIT - 1, - NPF_FTOA_MAN_BITS = sizeof(npf_ftoa_man_t) * CHAR_BIT, - NPF_FTOA_SHIFT_BITS = - ((NPF_FTOA_MAN_BITS < DBL_MANT_DIG) ? NPF_FTOA_MAN_BITS : DBL_MANT_DIG) - 1 -}; - -/* Generally, floating-point conversion implementations use - grisu2 (https://bit.ly/2JgMggX) and ryu (https://bit.ly/2RLXSg0) algorithms, - which are mathematically exact and fast, but require large lookup tables. - - This implementation was inspired by Wojciech Muła's (zdjęcia@garnek.pl) - algorithm (http://0x80.pl/notesen/2015-12-29-float-to-string.html) and - extended further by adding dynamic scaling and configurable integer width by - Oskars Rubenis (https://github.com/Okarss). */ - -static NPF_FORCE_INLINE npf_double_bin_t npf_double_to_int_rep(double f) { - // Union-cast is UB pre-C11 and in all C++; the compiler optimizes the code below. - npf_double_bin_t bin; - char const *src = (char const *)&f; - char *dst = (char *)&bin; - for (uint_fast8_t i = 0; i < sizeof(f); ++i) { dst[i] = src[i]; } - return bin; -} - -static int npf_ftoa_rev(char *buf, npf_format_spec_t const *spec, double f) { - char const *ret = NULL; - npf_double_bin_t bin = npf_double_to_int_rep(f); - - // Unsigned -> signed int casting is IB and can raise a signal but generally doesn't. - npf_ftoa_exp_t exp = - (npf_ftoa_exp_t)((npf_ftoa_exp_t)(bin >> NPF_DOUBLE_MAN_BITS) & NPF_DOUBLE_EXP_MASK); - - bin &= ((npf_double_bin_t)0x1 << NPF_DOUBLE_MAN_BITS) - 1; - if (exp == (npf_ftoa_exp_t)NPF_DOUBLE_EXP_MASK) { // special value - ret = (bin) ? "NAN" : "FNI"; - goto exit; - } - if (spec->prec > (NANOPRINTF_CONVERSION_BUFFER_SIZE - 2)) { goto exit; } - if (exp) { // normal number - bin |= (npf_double_bin_t)0x1 << NPF_DOUBLE_MAN_BITS; - } else { // subnormal number - ++exp; - } - exp = (npf_ftoa_exp_t)(exp - NPF_DOUBLE_EXP_BIAS); - - uint_fast8_t carry; carry = 0; - npf_ftoa_dec_t end, dec; dec = (npf_ftoa_dec_t)spec->prec; - if (dec -#if NANOPRINTF_USE_ALT_FORM_FLAG == 1 - || spec->alt_form -#endif - ) { - buf[dec++] = '.'; - } - - { // Integer part - npf_ftoa_man_t man_i; - - if (exp >= 0) { - int_fast8_t shift_i = - (int_fast8_t)((exp > NPF_FTOA_SHIFT_BITS) ? (int)NPF_FTOA_SHIFT_BITS : exp); - npf_ftoa_exp_t exp_i = (npf_ftoa_exp_t)(exp - shift_i); - shift_i = (int_fast8_t)(NPF_DOUBLE_MAN_BITS - shift_i); - man_i = (npf_ftoa_man_t)(bin >> shift_i); - - if (exp_i) { - if (shift_i) { - carry = (bin >> (shift_i - 1)) & 0x1; - } - exp = NPF_DOUBLE_MAN_BITS; // invalidate the fraction part - } - - // Scale the exponent from base-2 to base-10. - for (; exp_i; --exp_i) { - if (!(man_i & ((npf_ftoa_man_t)0x1 << (NPF_FTOA_MAN_BITS - 1)))) { - man_i = (npf_ftoa_man_t)(man_i << 1); - man_i = (npf_ftoa_man_t)(man_i | carry); carry = 0; - } else { - if (dec >= NANOPRINTF_CONVERSION_BUFFER_SIZE) { goto exit; } - buf[dec++] = '0'; - carry = (((uint_fast8_t)(man_i % 5) + carry) > 2); - man_i /= 5; - } - } - } else { - man_i = 0; - } - end = dec; - - do { // Print the integer - if (end >= NANOPRINTF_CONVERSION_BUFFER_SIZE) { goto exit; } - buf[end++] = (char)('0' + (char)(man_i % 10)); - man_i /= 10; - } while (man_i); - } - - { // Fraction part - npf_ftoa_man_t man_f; - npf_ftoa_dec_t dec_f = (npf_ftoa_dec_t)spec->prec; - - if (exp < NPF_DOUBLE_MAN_BITS) { - int_fast8_t shift_f = (int_fast8_t)((exp < 0) ? -1 : exp); - npf_ftoa_exp_t exp_f = (npf_ftoa_exp_t)(exp - shift_f); - npf_double_bin_t bin_f = - bin << ((NPF_DOUBLE_BIN_BITS - NPF_DOUBLE_MAN_BITS) + shift_f); - - // This if-else statement can be completely optimized at compile time. - if (NPF_DOUBLE_BIN_BITS > NPF_FTOA_MAN_BITS) { - man_f = (npf_ftoa_man_t)(bin_f >> ((unsigned)(NPF_DOUBLE_BIN_BITS - - NPF_FTOA_MAN_BITS) % - NPF_DOUBLE_BIN_BITS)); - carry = (uint_fast8_t)((bin_f >> ((unsigned)(NPF_DOUBLE_BIN_BITS - - NPF_FTOA_MAN_BITS - 1) % - NPF_DOUBLE_BIN_BITS)) & 0x1); - } else { - man_f = (npf_ftoa_man_t)((npf_ftoa_man_t)bin_f - << ((unsigned)(NPF_FTOA_MAN_BITS - - NPF_DOUBLE_BIN_BITS) % NPF_FTOA_MAN_BITS)); - carry = 0; - } - - // Scale the exponent from base-2 to base-10 and prepare the first digit. - for (uint_fast8_t digit = 0; dec_f && (exp_f < 4); ++exp_f) { - if ((man_f > ((npf_ftoa_man_t)-4 / 5)) || digit) { - carry = (uint_fast8_t)(man_f & 0x1); - man_f = (npf_ftoa_man_t)(man_f >> 1); - } else { - man_f = (npf_ftoa_man_t)(man_f * 5); - if (carry) { man_f = (npf_ftoa_man_t)(man_f + 3); carry = 0; } - if (exp_f < 0) { - buf[--dec_f] = '0'; - } else { - ++digit; - } - } - } - man_f = (npf_ftoa_man_t)(man_f + carry); - carry = (exp_f >= 0); - dec = 0; - } else { - man_f = 0; - } - - if (dec_f) { - // Print the fraction - for (;;) { - buf[--dec_f] = (char)('0' + (char)(man_f >> (NPF_FTOA_MAN_BITS - 4))); - man_f = (npf_ftoa_man_t)(man_f & ~((npf_ftoa_man_t)0xF << (NPF_FTOA_MAN_BITS - 4))); - if (!dec_f) { break; } - man_f = (npf_ftoa_man_t)(man_f * 10); - } - man_f = (npf_ftoa_man_t)(man_f << 4); - } - if (exp < NPF_DOUBLE_MAN_BITS) { - carry &= (uint_fast8_t)(man_f >> (NPF_FTOA_MAN_BITS - 1)); - } - } - - // Round the number - for (; carry; ++dec) { - if (dec >= NANOPRINTF_CONVERSION_BUFFER_SIZE) { goto exit; } - if (dec >= end) { buf[end++] = '0'; } - if (buf[dec] == '.') { continue; } - carry = (buf[dec] == '9'); - buf[dec] = (char)(carry ? '0' : (buf[dec] + 1)); - } - - return (int)end; -exit: - if (!ret) { ret = "RRE"; } - uint_fast8_t i; - for (i = 0; ret[i]; ++i) { buf[i] = (char)(ret[i] + spec->case_adjust); } - return -(int)i; -} - -#endif // NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS - -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 -static int npf_bin_len(npf_uint_t u) { - // Return the length of the binary string format of 'u', preferring intrinsics. - if (!u) { return 1; } - -#ifdef _MSC_VER // Win64, use _BSR64 for everything. If x86, use _BSR when non-large. - #ifdef _M_X64 - #define NPF_HAVE_BUILTIN_CLZ - #define NPF_CLZ _BitScanReverse64 - #elif NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 0 - #define NPF_HAVE_BUILTIN_CLZ - #define NPF_CLZ _BitScanReverse - #endif - #ifdef NPF_HAVE_BUILTIN_CLZ - unsigned long idx; - NPF_CLZ(&idx, u); - return (int)(idx + 1); - #endif -#elif NPF_CLANG || NPF_GCC_PAST_4_6 - #define NPF_HAVE_BUILTIN_CLZ - #if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - #define NPF_CLZ(X) ((sizeof(long long) * CHAR_BIT) - (size_t)__builtin_clzll(X)) - #else - #define NPF_CLZ(X) ((sizeof(long) * CHAR_BIT) - (size_t)__builtin_clzl(X)) - #endif - return (int)NPF_CLZ(u); -#endif - -#ifndef NPF_HAVE_BUILTIN_CLZ - int n; - for (n = 0; u; ++n, u >>= 1); // slow but small software fallback - return n; -#else - #undef NPF_HAVE_BUILTIN_CLZ - #undef NPF_CLZ -#endif -} -#endif - -static void npf_bufputc(int c, void *ctx) { - npf_bufputc_ctx_t *bpc = (npf_bufputc_ctx_t *)ctx; - if (bpc->cur < bpc->len) { bpc->dst[bpc->cur++] = (char)c; } -} - -static void npf_bufputc_nop(int c, void *ctx) { (void)c; (void)ctx; } - -typedef struct npf_cnt_putc_ctx { - npf_putc pc; - void *ctx; - int n; -} npf_cnt_putc_ctx_t; - -static void npf_putc_cnt(int c, void *ctx) { - npf_cnt_putc_ctx_t *pc_cnt = (npf_cnt_putc_ctx_t *)ctx; - ++pc_cnt->n; - pc_cnt->pc(c, pc_cnt->ctx); // sibling-call optimization -} - -#define NPF_PUTC(VAL) do { npf_putc_cnt((int)(VAL), &pc_cnt); } while (0) - -#define NPF_EXTRACT(MOD, CAST_TO, EXTRACT_AS) \ - case NPF_FMT_SPEC_LEN_MOD_##MOD: val = (CAST_TO)va_arg(args, EXTRACT_AS); break - -#define NPF_WRITEBACK(MOD, TYPE) \ - case NPF_FMT_SPEC_LEN_MOD_##MOD: *(va_arg(args, TYPE *)) = (TYPE)pc_cnt.n; break - -int npf_vpprintf(npf_putc pc, void *pc_ctx, char const *format, va_list args) { - npf_format_spec_t fs; - char const *cur = format; - npf_cnt_putc_ctx_t pc_cnt; - pc_cnt.pc = pc; - pc_cnt.ctx = pc_ctx; - pc_cnt.n = 0; - - while (*cur) { - int const fs_len = (*cur != '%') ? 0 : npf_parse_format_spec(cur, &fs); - if (!fs_len) { NPF_PUTC(*cur++); continue; } - cur += fs_len; - - // Extract star-args immediately -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - if (fs.field_width_opt == NPF_FMT_SPEC_OPT_STAR) { - fs.field_width = va_arg(args, int); - if (fs.field_width < 0) { - fs.field_width = -fs.field_width; - fs.left_justified = 1; - } - } -#endif -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - if (fs.prec_opt == NPF_FMT_SPEC_OPT_STAR) { - fs.prec = va_arg(args, int); - if (fs.prec < 0) { fs.prec_opt = NPF_FMT_SPEC_OPT_NONE; } - } -#endif - - union { char cbuf_mem[NANOPRINTF_CONVERSION_BUFFER_SIZE]; npf_uint_t binval; } u; - char *cbuf = u.cbuf_mem, sign_c = 0; - int cbuf_len = 0; - char need_0x = 0; -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - int field_pad = 0; - char pad_c = 0; -#endif -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - int prec_pad = 0; -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - uint_fast8_t zero = 0; -#endif -#endif - - // Extract and convert the argument to string, point cbuf at the text. - switch (fs.conv_spec) { - case NPF_FMT_SPEC_CONV_PERCENT: - *cbuf = '%'; - cbuf_len = 1; - break; - - case NPF_FMT_SPEC_CONV_CHAR: - *cbuf = (char)va_arg(args, int); - cbuf_len = (*cbuf) ? 1 : 0; - break; - - case NPF_FMT_SPEC_CONV_STRING: { - cbuf = va_arg(args, char *); -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - for (char const *s = cbuf; - ((fs.prec_opt == NPF_FMT_SPEC_OPT_NONE) || (cbuf_len < fs.prec)) && cbuf && *s; - ++s, ++cbuf_len); -#else - for (char const *s = cbuf; cbuf && *s; ++s, ++cbuf_len); // strlen -#endif - } break; - - case NPF_FMT_SPEC_CONV_SIGNED_INT: { - npf_int_t val = 0; - switch (fs.length_modifier) { - NPF_EXTRACT(NONE, int, int); -#if NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS == 1 - NPF_EXTRACT(SHORT, short, int); - NPF_EXTRACT(CHAR, signed char, int); -#endif - NPF_EXTRACT(LONG, long, long); -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - NPF_EXTRACT(LARGE_LONG_LONG, long long, long long); - NPF_EXTRACT(LARGE_INTMAX, intmax_t, intmax_t); - NPF_EXTRACT(LARGE_SIZET, npf_ssize_t, npf_ssize_t); - NPF_EXTRACT(LARGE_PTRDIFFT, ptrdiff_t, ptrdiff_t); -#endif - default: break; - } - - sign_c = (val < 0) ? '-' : fs.prepend; - -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - zero = !val; -#endif - // special case, if prec and value are 0, skip - if (!val && (fs.prec_opt != NPF_FMT_SPEC_OPT_NONE) && !fs.prec) { - cbuf_len = 0; - } else -#endif - { - npf_uint_t uval = (npf_uint_t)val; - if (val < 0) { uval = 0 - uval; } - cbuf_len = npf_utoa_rev(uval, cbuf, 10, fs.case_adjust); - } - } break; - -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 - case NPF_FMT_SPEC_CONV_BINARY: -#endif - case NPF_FMT_SPEC_CONV_OCTAL: - case NPF_FMT_SPEC_CONV_HEX_INT: - case NPF_FMT_SPEC_CONV_UNSIGNED_INT: - case NPF_FMT_SPEC_CONV_POINTER: { - npf_uint_t val = 0; - - if (fs.conv_spec == NPF_FMT_SPEC_CONV_POINTER) { - val = (npf_uint_t)(uintptr_t)va_arg(args, void *); - } else { - switch (fs.length_modifier) { - NPF_EXTRACT(NONE, unsigned, unsigned); -#if NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS == 1 - NPF_EXTRACT(SHORT, unsigned short, unsigned); - NPF_EXTRACT(CHAR, unsigned char, unsigned); -#endif - NPF_EXTRACT(LONG, unsigned long, unsigned long); -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - NPF_EXTRACT(LARGE_LONG_LONG, unsigned long long, unsigned long long); - NPF_EXTRACT(LARGE_INTMAX, uintmax_t, uintmax_t); - NPF_EXTRACT(LARGE_SIZET, size_t, size_t); - NPF_EXTRACT(LARGE_PTRDIFFT, npf_uptrdiff_t, npf_uptrdiff_t); -#endif - default: break; - } - } - -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - zero = !val; -#endif - if (!val && (fs.prec_opt != NPF_FMT_SPEC_OPT_NONE) && !fs.prec) { - // Zero value and explicitly-requested zero precision means "print nothing". -#if NANOPRINTF_USE_ALT_FORM_FLAG == 1 - if ((fs.conv_spec == NPF_FMT_SPEC_CONV_OCTAL) && fs.alt_form) { - fs.prec = 1; // octal special case, print a single '0' - } -#endif - } else -#endif -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 - if (fs.conv_spec == NPF_FMT_SPEC_CONV_BINARY) { - cbuf_len = npf_bin_len(val); u.binval = val; - } else -#endif - { - uint_fast8_t const base = (fs.conv_spec == NPF_FMT_SPEC_CONV_OCTAL) ? - 8u : ((fs.conv_spec == NPF_FMT_SPEC_CONV_UNSIGNED_INT) ? 10u : 16u); - cbuf_len = npf_utoa_rev(val, cbuf, base, fs.case_adjust); - } - -#if NANOPRINTF_USE_ALT_FORM_FLAG == 1 - if (val && fs.alt_form && (fs.conv_spec == NPF_FMT_SPEC_CONV_OCTAL)) { - cbuf[cbuf_len++] = '0'; // OK to add leading octal '0' immediately. - } - - if (val && fs.alt_form) { // 0x or 0b but can't write it yet. - if ((fs.conv_spec == NPF_FMT_SPEC_CONV_HEX_INT) || - (fs.conv_spec == NPF_FMT_SPEC_CONV_POINTER)) { need_0x = 'X'; } -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 - else if (fs.conv_spec == NPF_FMT_SPEC_CONV_BINARY) { need_0x = 'B'; } -#endif - if (need_0x) { need_0x = (char)(need_0x + fs.case_adjust); } - } -#endif - } break; - -#if NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS == 1 - case NPF_FMT_SPEC_CONV_WRITEBACK: - switch (fs.length_modifier) { - NPF_WRITEBACK(NONE, int); -#if NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS == 1 - NPF_WRITEBACK(SHORT, short); - NPF_WRITEBACK(CHAR, signed char); -#endif - NPF_WRITEBACK(LONG, long); -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - NPF_WRITEBACK(LARGE_LONG_LONG, long long); - NPF_WRITEBACK(LARGE_INTMAX, intmax_t); - NPF_WRITEBACK(LARGE_SIZET, npf_ssize_t); - NPF_WRITEBACK(LARGE_PTRDIFFT, ptrdiff_t); -#endif - default: break; - } break; -#endif - -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - case NPF_FMT_SPEC_CONV_FLOAT_DEC: - case NPF_FMT_SPEC_CONV_FLOAT_SCI: - case NPF_FMT_SPEC_CONV_FLOAT_SHORTEST: - case NPF_FMT_SPEC_CONV_FLOAT_HEX: { - double val; - if (fs.length_modifier == NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE) { - val = (double)va_arg(args, long double); - } else { - val = va_arg(args, double); - } - - sign_c = (npf_double_to_int_rep(val) >> NPF_DOUBLE_SIGN_POS) ? '-' : fs.prepend; -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - zero = (val == 0.); -#endif - cbuf_len = npf_ftoa_rev(cbuf, &fs, val); - if (cbuf_len < 0) { // negative means text (not number), so ignore the '0' flag - cbuf_len = -cbuf_len; -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - fs.leading_zero_pad = 0; -#endif - } - } break; -#endif - default: break; - } - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - // Compute the field width pad character - if (fs.field_width_opt != NPF_FMT_SPEC_OPT_NONE) { - if (fs.leading_zero_pad) { -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - if ((fs.prec_opt != NPF_FMT_SPEC_OPT_NONE) && !fs.prec && zero) { - pad_c = ' '; - } else -#endif - { pad_c = '0'; } - } else { pad_c = ' '; } - } -#endif - - // Compute the number of bytes to truncate or '0'-pad. -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - if (fs.conv_spec != NPF_FMT_SPEC_CONV_STRING) { -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - // float precision is after the decimal point - if ((fs.conv_spec != NPF_FMT_SPEC_CONV_FLOAT_DEC) && - (fs.conv_spec != NPF_FMT_SPEC_CONV_FLOAT_SCI) && - (fs.conv_spec != NPF_FMT_SPEC_CONV_FLOAT_SHORTEST) && - (fs.conv_spec != NPF_FMT_SPEC_CONV_FLOAT_HEX)) -#endif - { prec_pad = NPF_MAX(0, fs.prec - cbuf_len); } - } -#endif - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - // Given the full converted length, how many pad bytes? - field_pad = fs.field_width - cbuf_len - !!sign_c; - if (need_0x) { field_pad -= 2; } -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - field_pad -= prec_pad; -#endif - field_pad = NPF_MAX(0, field_pad); - - // Apply right-justified field width if requested - if (!fs.left_justified && pad_c) { // If leading zeros pad, sign goes first. - if (pad_c == '0') { - if (sign_c) { NPF_PUTC(sign_c); sign_c = 0; } - // Pad byte is '0', write '0x' before '0' pad chars. - if (need_0x) { NPF_PUTC('0'); NPF_PUTC(need_0x); } - } - while (field_pad-- > 0) { NPF_PUTC(pad_c); } - // Pad byte is ' ', write '0x' after ' ' pad chars but before number. - if ((pad_c != '0') && need_0x) { NPF_PUTC('0'); NPF_PUTC(need_0x); } - } else -#endif - { if (need_0x) { NPF_PUTC('0'); NPF_PUTC(need_0x); } } // no pad, '0x' requested. - - // Write the converted payload - if (fs.conv_spec == NPF_FMT_SPEC_CONV_STRING) { - for (int i = 0; cbuf && (i < cbuf_len); ++i) { NPF_PUTC(cbuf[i]); } - } else { - if (sign_c) { NPF_PUTC(sign_c); } -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - while (prec_pad-- > 0) { NPF_PUTC('0'); } // int precision leads. -#endif -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 - if (fs.conv_spec == NPF_FMT_SPEC_CONV_BINARY) { - while (cbuf_len) { NPF_PUTC('0' + ((u.binval >> --cbuf_len) & 1)); } - } else -#endif - { while (cbuf_len-- > 0) { NPF_PUTC(cbuf[cbuf_len]); } } // payload is reversed - } - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - if (fs.left_justified && pad_c) { // Apply left-justified field width - while (field_pad-- > 0) { NPF_PUTC(pad_c); } - } -#endif - } - - return pc_cnt.n; -} - -#undef NPF_PUTC -#undef NPF_EXTRACT -#undef NPF_WRITEBACK - -int npf_pprintf(npf_putc pc, - void * NPF_RESTRICT pc_ctx, - char const * NPF_RESTRICT format, - ...) { - va_list val; - va_start(val, format); - int const rv = npf_vpprintf(pc, pc_ctx, format, val); - va_end(val); - return rv; -} - -int npf_snprintf(char * NPF_RESTRICT buffer, - size_t bufsz, - const char * NPF_RESTRICT format, - ...) { - va_list val; - va_start(val, format); - int const rv = npf_vsnprintf(buffer, bufsz, format, val); - va_end(val); - return rv; -} - -int npf_vsnprintf(char * NPF_RESTRICT buffer, - size_t bufsz, - char const * NPF_RESTRICT format, - va_list vlist) { - npf_bufputc_ctx_t bufputc_ctx; - bufputc_ctx.dst = buffer; - bufputc_ctx.len = bufsz; - bufputc_ctx.cur = 0; - - npf_putc const pc = buffer ? npf_bufputc : npf_bufputc_nop; - int const n = npf_vpprintf(pc, &bufputc_ctx, format, vlist); - - if (buffer && bufsz) { -#ifdef NANOPRINTF_SNPRINTF_SAFE_EMPTY_STRING_ON_OVERFLOW - buffer[(n < 0 || (unsigned)n >= bufsz) ? 0 : n] = '\0'; -#else - buffer[n < 0 ? 0 : NPF_MIN((unsigned)n, bufsz - 1)] = '\0'; -#endif - } - - return n; -} - -#if NPF_HAVE_GCC_WARNING_PRAGMAS - #pragma GCC diagnostic pop -#endif - -#ifdef _MSC_VER - #pragma warning(pop) -#endif - -#endif // NPF_IMPLEMENTATION_INCLUDED -#endif // NANOPRINTF_IMPLEMENTATION - -/* - nanoprintf is dual-licensed under both the "Unlicense" and the - "Zero-Clause BSD" (0BSD) licenses. The intent of this dual-licensing - structure is to make nanoprintf as consumable as possible in as many - environments / countries / companies as possible without any - encumberances. - - The text of the two licenses follows below: - - ============================== UNLICENSE ============================== - - This is free and unencumbered software released into the public domain. - - Anyone is free to copy, modify, publish, use, compile, sell, or - distribute this software, either in source code form or as a compiled - binary, for any purpose, commercial or non-commercial, and by any - means. - - In jurisdictions that recognize copyright laws, the author or authors - of this software dedicate any and all copyright interest in the - software to the public domain. We make this dedication for the benefit - of the public at large and to the detriment of our heirs and - successors. We intend this dedication to be an overt act of - relinquishment in perpetuity of all present and future rights to this - software under copyright law. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - For more information, please refer to <http://unlicense.org> - - ================================ 0BSD ================================= - - Copyright (C) 2019- by Charles Nicholson <charles.nicholson+nanoprintf@gmail.com> - - Permission to use, copy, modify, and/or distribute this software for - any purpose with or without fee is hereby granted. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ diff --git a/kernel/include/limine.h b/kernel/include/limine.h deleted file mode 100644 index 6de7dcd..0000000 --- a/kernel/include/limine.h +++ /dev/null @@ -1,754 +0,0 @@ -/* BSD Zero Clause License */ - -/* Copyright (C) 2022-2025 mintsuki and contributors. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef LIMINE_H -#define LIMINE_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdint.h> - -/* Misc */ - -#ifdef LIMINE_NO_POINTERS -# define LIMINE_PTR(TYPE) uint64_t -#else -# define LIMINE_PTR(TYPE) TYPE -#endif - -#ifndef LIMINE_API_REVISION -# define LIMINE_API_REVISION 0 -#endif - -#if LIMINE_API_REVISION > 3 -# error "limine.h API revision unsupported" -#endif - -#ifdef __GNUC__ -# define LIMINE_DEPRECATED __attribute__((__deprecated__)) -# define LIMINE_DEPRECATED_IGNORE_START \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -# define LIMINE_DEPRECATED_IGNORE_END \ - _Pragma("GCC diagnostic pop") -#else -# define LIMINE_DEPRECATED -# define LIMINE_DEPRECATED_IGNORE_START -# define LIMINE_DEPRECATED_IGNORE_END -#endif - -#define LIMINE_REQUESTS_START_MARKER \ - uint64_t limine_requests_start_marker[4] = { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \ - 0x785c6ed015d3e316, 0x181e920a7852b9d9 }; -#define LIMINE_REQUESTS_END_MARKER \ - uint64_t limine_requests_end_marker[2] = { 0xadc0e0531bb10d03, 0x9572709f31764c62 }; - -#define LIMINE_REQUESTS_DELIMITER LIMINE_REQUESTS_END_MARKER - -#define LIMINE_BASE_REVISION(N) \ - uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }; - -#define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0) - -#define LIMINE_LOADED_BASE_REV_VALID (limine_base_revision[1] != 0x6a7b384944536bdc) -#define LIMINE_LOADED_BASE_REVISION (limine_base_revision[1]) - -#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b - -struct limine_uuid { - uint32_t a; - uint16_t b; - uint16_t c; - uint8_t d[8]; -}; - -#define LIMINE_MEDIA_TYPE_GENERIC 0 -#define LIMINE_MEDIA_TYPE_OPTICAL 1 -#define LIMINE_MEDIA_TYPE_TFTP 2 - -struct limine_file { - uint64_t revision; - LIMINE_PTR(void *) address; - uint64_t size; - LIMINE_PTR(char *) path; -#if LIMINE_API_REVISION >= 3 - LIMINE_PTR(char *) string; -#else - LIMINE_PTR(char *) cmdline; -#endif - uint32_t media_type; - uint32_t unused; - uint32_t tftp_ip; - uint32_t tftp_port; - uint32_t partition_index; - uint32_t mbr_disk_id; - struct limine_uuid gpt_disk_uuid; - struct limine_uuid gpt_part_uuid; - struct limine_uuid part_uuid; -}; - -/* Boot info */ - -#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 } - -struct limine_bootloader_info_response { - uint64_t revision; - LIMINE_PTR(char *) name; - LIMINE_PTR(char *) version; -}; - -struct limine_bootloader_info_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_bootloader_info_response *) response; -}; - -/* Executable command line */ - -#define LIMINE_EXECUTABLE_CMDLINE_REQUEST { LIMINE_COMMON_MAGIC, 0x4b161536e598651e, 0xb390ad4a2f1f303a } - -struct limine_executable_cmdline_response { - uint64_t revision; - LIMINE_PTR(char *) cmdline; -}; - -struct limine_executable_cmdline_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_executable_cmdline_response *) response; -}; - -/* Firmware type */ - -#define LIMINE_FIRMWARE_TYPE_REQUEST { LIMINE_COMMON_MAGIC, 0x8c2f75d90bef28a8, 0x7045a4688eac00c3 } - -#define LIMINE_FIRMWARE_TYPE_X86BIOS 0 -#define LIMINE_FIRMWARE_TYPE_UEFI32 1 -#define LIMINE_FIRMWARE_TYPE_UEFI64 2 -#define LIMINE_FIRMWARE_TYPE_SBI 3 - -struct limine_firmware_type_response { - uint64_t revision; - uint64_t firmware_type; -}; - -struct limine_firmware_type_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_firmware_type_response *) response; -}; - -/* Stack size */ - -#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d } - -struct limine_stack_size_response { - uint64_t revision; -}; - -struct limine_stack_size_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_stack_size_response *) response; - uint64_t stack_size; -}; - -/* HHDM */ - -#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b } - -struct limine_hhdm_response { - uint64_t revision; - uint64_t offset; -}; - -struct limine_hhdm_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_hhdm_response *) response; -}; - -/* Framebuffer */ - -#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b } - -#define LIMINE_FRAMEBUFFER_RGB 1 - -struct limine_video_mode { - uint64_t pitch; - uint64_t width; - uint64_t height; - uint16_t bpp; - uint8_t memory_model; - uint8_t red_mask_size; - uint8_t red_mask_shift; - uint8_t green_mask_size; - uint8_t green_mask_shift; - uint8_t blue_mask_size; - uint8_t blue_mask_shift; -}; - -struct limine_framebuffer { - LIMINE_PTR(void *) address; - uint64_t width; - uint64_t height; - uint64_t pitch; - uint16_t bpp; - uint8_t memory_model; - uint8_t red_mask_size; - uint8_t red_mask_shift; - uint8_t green_mask_size; - uint8_t green_mask_shift; - uint8_t blue_mask_size; - uint8_t blue_mask_shift; - uint8_t unused[7]; - uint64_t edid_size; - LIMINE_PTR(void *) edid; - /* Response revision 1 */ - uint64_t mode_count; - LIMINE_PTR(struct limine_video_mode **) modes; -}; - -struct limine_framebuffer_response { - uint64_t revision; - uint64_t framebuffer_count; - LIMINE_PTR(struct limine_framebuffer **) framebuffers; -}; - -struct limine_framebuffer_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_framebuffer_response *) response; -}; - -/* Terminal */ - -#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 } - -#define LIMINE_TERMINAL_CB_DEC 10 -#define LIMINE_TERMINAL_CB_BELL 20 -#define LIMINE_TERMINAL_CB_PRIVATE_ID 30 -#define LIMINE_TERMINAL_CB_STATUS_REPORT 40 -#define LIMINE_TERMINAL_CB_POS_REPORT 50 -#define LIMINE_TERMINAL_CB_KBD_LEDS 60 -#define LIMINE_TERMINAL_CB_MODE 70 -#define LIMINE_TERMINAL_CB_LINUX 80 - -#define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1)) -#define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2)) -#define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3)) -#define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4)) - -/* Response revision 1 */ -#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10)) -#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11)) - -#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0) -#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1) -#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2) -#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3) -#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4) -#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5) -#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6) -#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7) - -LIMINE_DEPRECATED_IGNORE_START - -struct LIMINE_DEPRECATED limine_terminal; - -typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t); -typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t); - -struct LIMINE_DEPRECATED limine_terminal { - uint64_t columns; - uint64_t rows; - LIMINE_PTR(struct limine_framebuffer *) framebuffer; -}; - -struct LIMINE_DEPRECATED limine_terminal_response { - uint64_t revision; - uint64_t terminal_count; - LIMINE_PTR(struct limine_terminal **) terminals; - LIMINE_PTR(limine_terminal_write) write; -}; - -struct LIMINE_DEPRECATED limine_terminal_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_terminal_response *) response; - LIMINE_PTR(limine_terminal_callback) callback; -}; - -LIMINE_DEPRECATED_IGNORE_END - -/* Paging mode */ - -#define LIMINE_PAGING_MODE_REQUEST { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a } - -#if defined (__x86_64__) || defined (__i386__) -#define LIMINE_PAGING_MODE_X86_64_4LVL 0 -#define LIMINE_PAGING_MODE_X86_64_5LVL 1 -#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_X86_64_4LVL -#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL -#elif defined (__aarch64__) -#define LIMINE_PAGING_MODE_AARCH64_4LVL 0 -#define LIMINE_PAGING_MODE_AARCH64_5LVL 1 -#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_AARCH64_4LVL -#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL -#elif defined (__riscv) && (__riscv_xlen == 64) -#define LIMINE_PAGING_MODE_RISCV_SV39 0 -#define LIMINE_PAGING_MODE_RISCV_SV48 1 -#define LIMINE_PAGING_MODE_RISCV_SV57 2 -#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_RISCV_SV39 -#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48 -#elif defined (__loongarch__) && (__loongarch_grlen == 64) -#define LIMINE_PAGING_MODE_LOONGARCH64_4LVL 0 -#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_LOONGARCH64_4LVL -#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_LOONGARCH64_4LVL -#else -#error Unknown architecture -#endif - -struct limine_paging_mode_response { - uint64_t revision; - uint64_t mode; -}; - -struct limine_paging_mode_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_paging_mode_response *) response; - uint64_t mode; - uint64_t max_mode; - uint64_t min_mode; -}; - -/* 5-level paging */ - -#define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 } - -LIMINE_DEPRECATED_IGNORE_START - -struct LIMINE_DEPRECATED limine_5_level_paging_response { - uint64_t revision; -}; - -struct LIMINE_DEPRECATED limine_5_level_paging_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_5_level_paging_response *) response; -}; - -LIMINE_DEPRECATED_IGNORE_END - -/* MP */ - -#if LIMINE_API_REVISION >= 1 -# define LIMINE_MP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 } -# define LIMINE_MP(TEXT) limine_mp_##TEXT -#else -# define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 } -# define LIMINE_MP(TEXT) limine_smp_##TEXT -#endif - -struct LIMINE_MP(info); - -typedef void (*limine_goto_address)(struct LIMINE_MP(info) *); - -#if defined (__x86_64__) || defined (__i386__) - -#if LIMINE_API_REVISION >= 1 -# define LIMINE_MP_X2APIC (1 << 0) -#else -# define LIMINE_SMP_X2APIC (1 << 0) -#endif - -struct LIMINE_MP(info) { - uint32_t processor_id; - uint32_t lapic_id; - uint64_t reserved; - LIMINE_PTR(limine_goto_address) goto_address; - uint64_t extra_argument; -}; - -struct LIMINE_MP(response) { - uint64_t revision; - uint32_t flags; - uint32_t bsp_lapic_id; - uint64_t cpu_count; - LIMINE_PTR(struct LIMINE_MP(info) **) cpus; -}; - -#elif defined (__aarch64__) - -struct LIMINE_MP(info) { - uint32_t processor_id; - uint32_t reserved1; - uint64_t mpidr; - uint64_t reserved; - LIMINE_PTR(limine_goto_address) goto_address; - uint64_t extra_argument; -}; - -struct LIMINE_MP(response) { - uint64_t revision; - uint64_t flags; - uint64_t bsp_mpidr; - uint64_t cpu_count; - LIMINE_PTR(struct LIMINE_MP(info) **) cpus; -}; - -#elif defined (__riscv) && (__riscv_xlen == 64) - -struct LIMINE_MP(info) { - uint64_t processor_id; - uint64_t hartid; - uint64_t reserved; - LIMINE_PTR(limine_goto_address) goto_address; - uint64_t extra_argument; -}; - -struct LIMINE_MP(response) { - uint64_t revision; - uint64_t flags; - uint64_t bsp_hartid; - uint64_t cpu_count; - LIMINE_PTR(struct LIMINE_MP(info) **) cpus; -}; - -#elif defined (__loongarch__) && (__loongarch_grlen == 64) - -struct LIMINE_MP(info) { - uint64_t reserved; -}; - -struct LIMINE_MP(response) { - uint64_t cpu_count; - LIMINE_PTR(struct LIMINE_MP(info) **) cpus; -}; - -#else -#error Unknown architecture -#endif - -struct LIMINE_MP(request) { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct LIMINE_MP(response) *) response; - uint64_t flags; -}; - -/* Memory map */ - -#define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 } - -#define LIMINE_MEMMAP_USABLE 0 -#define LIMINE_MEMMAP_RESERVED 1 -#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2 -#define LIMINE_MEMMAP_ACPI_NVS 3 -#define LIMINE_MEMMAP_BAD_MEMORY 4 -#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5 -#if LIMINE_API_REVISION >= 2 -# define LIMINE_MEMMAP_EXECUTABLE_AND_MODULES 6 -#else -# define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 -#endif -#define LIMINE_MEMMAP_FRAMEBUFFER 7 - -struct limine_memmap_entry { - uint64_t base; - uint64_t length; - uint64_t type; -}; - -struct limine_memmap_response { - uint64_t revision; - uint64_t entry_count; - LIMINE_PTR(struct limine_memmap_entry **) entries; -}; - -struct limine_memmap_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_memmap_response *) response; -}; - -/* Entry point */ - -#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a } - -typedef void (*limine_entry_point)(void); - -struct limine_entry_point_response { - uint64_t revision; -}; - -struct limine_entry_point_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_entry_point_response *) response; - LIMINE_PTR(limine_entry_point) entry; -}; - -/* Executable File */ - -#if LIMINE_API_REVISION >= 2 -# define LIMINE_EXECUTABLE_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } -#else -# define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } -#endif - -#if LIMINE_API_REVISION >= 2 -struct limine_executable_file_response { -#else -struct limine_kernel_file_response { -#endif - uint64_t revision; -#if LIMINE_API_REVISION >= 2 - LIMINE_PTR(struct limine_file *) executable_file; -#else - LIMINE_PTR(struct limine_file *) kernel_file; -#endif -}; - -#if LIMINE_API_REVISION >= 2 -struct limine_executable_file_request { -#else -struct limine_kernel_file_request { -#endif - uint64_t id[4]; - uint64_t revision; -#if LIMINE_API_REVISION >= 2 - LIMINE_PTR(struct limine_executable_file_response *) response; -#else - LIMINE_PTR(struct limine_kernel_file_response *) response; -#endif -}; - -/* Module */ - -#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee } - -#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0) -#define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1) - -struct limine_internal_module { - LIMINE_PTR(const char *) path; -#if LIMINE_API_REVISION >= 3 - LIMINE_PTR(const char *) string; -#else - LIMINE_PTR(const char *) cmdline; -#endif - uint64_t flags; -}; - -struct limine_module_response { - uint64_t revision; - uint64_t module_count; - LIMINE_PTR(struct limine_file **) modules; -}; - -struct limine_module_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_module_response *) response; - - /* Request revision 1 */ - uint64_t internal_module_count; - LIMINE_PTR(struct limine_internal_module **) internal_modules; -}; - -/* RSDP */ - -#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c } - -struct limine_rsdp_response { - uint64_t revision; -#if LIMINE_API_REVISION >= 1 - uint64_t address; -#else - LIMINE_PTR(void *) address; -#endif -}; - -struct limine_rsdp_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_rsdp_response *) response; -}; - -/* SMBIOS */ - -#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee } - -struct limine_smbios_response { - uint64_t revision; -#if LIMINE_API_REVISION >= 1 - uint64_t entry_32; - uint64_t entry_64; -#else - LIMINE_PTR(void *) entry_32; - LIMINE_PTR(void *) entry_64; -#endif -}; - -struct limine_smbios_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_smbios_response *) response; -}; - -/* EFI system table */ - -#define LIMINE_EFI_SYSTEM_TABLE_REQUEST { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc } - -struct limine_efi_system_table_response { - uint64_t revision; -#if LIMINE_API_REVISION >= 1 - uint64_t address; -#else - LIMINE_PTR(void *) address; -#endif -}; - -struct limine_efi_system_table_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_efi_system_table_response *) response; -}; - -/* EFI memory map */ - -#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 } - -struct limine_efi_memmap_response { - uint64_t revision; - LIMINE_PTR(void *) memmap; - uint64_t memmap_size; - uint64_t desc_size; - uint64_t desc_version; -}; - -struct limine_efi_memmap_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_efi_memmap_response *) response; -}; - -/* Date at boot */ - -#if LIMINE_API_REVISION >= 3 -# define LIMINE_DATE_AT_BOOT_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 } -#else -# define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 } -#endif - -#if LIMINE_API_REVISION >= 3 -struct limine_date_at_boot_response { -#else -struct limine_boot_time_response { -#endif - uint64_t revision; -#if LIMINE_API_REVISION >= 3 - int64_t timestamp; -#else - int64_t boot_time; -#endif -}; - -#if LIMINE_API_REVISION >= 3 -struct limine_date_at_boot_request { -#else -struct limine_boot_time_request { -#endif - uint64_t id[4]; - uint64_t revision; -#if LIMINE_API_REVISION >= 3 - LIMINE_PTR(struct limine_date_at_boot_response *) response; -#else - LIMINE_PTR(struct limine_boot_time_response *) response; -#endif -}; - -/* Executable address */ - -#if LIMINE_API_REVISION >= 2 -# define LIMINE_EXECUTABLE_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } -#else -# define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } -#endif - -#if LIMINE_API_REVISION >= 2 -struct limine_executable_address_response { -#else -struct limine_kernel_address_response { -#endif - uint64_t revision; - uint64_t physical_base; - uint64_t virtual_base; -}; - -#if LIMINE_API_REVISION >= 2 -struct limine_executable_address_request { -#else -struct limine_kernel_address_request { -#endif - uint64_t id[4]; - uint64_t revision; -#if LIMINE_API_REVISION >= 2 - LIMINE_PTR(struct limine_executable_address_response *) response; -#else - LIMINE_PTR(struct limine_kernel_address_response *) response; -#endif -}; - -/* Device Tree Blob */ - -#define LIMINE_DTB_REQUEST { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 } - -struct limine_dtb_response { - uint64_t revision; - LIMINE_PTR(void *) dtb_ptr; -}; - -struct limine_dtb_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_dtb_response *) response; -}; - -/* RISC-V Boot Hart ID */ - -#define LIMINE_RISCV_BSP_HARTID_REQUEST { LIMINE_COMMON_MAGIC, 0x1369359f025525f9, 0x2ff2a56178391bb6 } - -struct limine_riscv_bsp_hartid_response { - uint64_t revision; - uint64_t bsp_hartid; -}; - -struct limine_riscv_bsp_hartid_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_riscv_bsp_hartid_response *) response; -}; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/linker-scripts/aarch64.lds b/kernel/linker-scripts/aarch64.lds new file mode 100644 index 0000000..64f581e --- /dev/null +++ b/kernel/linker-scripts/aarch64.lds @@ -0,0 +1,88 @@ +/* Tell the linker that we want an aarch64 ELF64 output file */ +OUTPUT_FORMAT(elf64-littleaarch64) + +/* We want the symbol kmain to be our entry point */ +ENTRY(kmain) + +/* Define the program headers we want so the bootloader gives us the right */ +/* MMU permissions; this also allows us to exert more control over the linking */ +/* process. */ +PHDRS +{ + limine_requests PT_LOAD; + text PT_LOAD; + rodata PT_LOAD; + data PT_LOAD; +} + +SECTIONS +{ + /* We want to 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; + + kernel_start = .; + + /* Define a section to contain the Limine requests and assign it to its own PHDR */ + .limine_requests : { + KEEP(*(.limine_requests_start)) + KEEP(*(.limine_requests)) + KEEP(*(.limine_requests_end)) + } :limine_requests + + /* Move to the next memory page for .text */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .text : { + *(.text .text.*) + } :text + + /* Move to the next memory page for .rodata */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .rodata : { + *(.rodata .rodata.*) + } :rodata + + /* Add a .note.gnu.build-id output section in case a build ID flag is added to the */ + /* linker command. */ + .note.gnu.build-id : { + *(.note.gnu.build-id) + } :rodata + + /* C++ is a language that allows for global constructors. In order to obtain the */ + /* address of the ".init_array" section we need to define a symbol for it. */ + .init_array : { + __init_array = .; + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP(*(.init_array .ctors)) + __init_array_end = .; + } :rodata + + /* Move to the next memory page for .data */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .data : { + *(.data .data.*) + } :data + + /* 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 + + /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ + /DISCARD/ : { + *(.eh_frame*) + *(.note .note.*) + } + + kernel_end = .; + +} diff --git a/kernel/linker-scripts/loongarch64.lds b/kernel/linker-scripts/loongarch64.lds new file mode 100644 index 0000000..55dff3a --- /dev/null +++ b/kernel/linker-scripts/loongarch64.lds @@ -0,0 +1,87 @@ +/* Tell the linker that we want a loongarch64 ELF64 output file */ +OUTPUT_FORMAT(elf64-loongarch) + +/* We want the symbol kmain to be our entry point */ +ENTRY(kmain) + +/* Define the program headers we want so the bootloader gives us the right */ +/* MMU permissions; this also allows us to exert more control over the linking */ +/* process. */ +PHDRS +{ + limine_requests PT_LOAD; + text PT_LOAD; + rodata PT_LOAD; + data PT_LOAD; +} + +SECTIONS +{ + /* We want to 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; + + kernel_start = .; + + /* Define a section to contain the Limine requests and assign it to its own PHDR */ + .limine_requests : { + KEEP(*(.limine_requests_start)) + KEEP(*(.limine_requests)) + KEEP(*(.limine_requests_end)) + } :limine_requests + + /* Move to the next memory page for .text */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .text : { + *(.text .text.*) + } :text + + /* Move to the next memory page for .rodata */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .rodata : { + *(.rodata .rodata.*) + } :rodata + + /* Add a .note.gnu.build-id output section in case a build ID flag is added to the */ + /* linker command. */ + .note.gnu.build-id : { + *(.note.gnu.build-id) + } :rodata + + /* C++ is a language that allows for global constructors. In order to obtain the */ + /* address of the ".init_array" section we need to define a symbol for it. */ + .init_array : { + __init_array = .; + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP(*(.init_array .ctors)) + __init_array_end = .; + } :rodata + + /* Move to the next memory page for .data */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .data : { + *(.data .data.*) + } :data + + /* 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 + + /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ + /DISCARD/ : { + *(.eh_frame*) + *(.note .note.*) + } + + kernel_end = .; +} diff --git a/kernel/linker-scripts/riscv64.lds b/kernel/linker-scripts/riscv64.lds new file mode 100644 index 0000000..51b6330 --- /dev/null +++ b/kernel/linker-scripts/riscv64.lds @@ -0,0 +1,92 @@ +/* Tell the linker that we want a riscv64 ELF64 output file */ +OUTPUT_FORMAT(elf64-littleriscv) + +/* We want the symbol kmain to be our entry point */ +ENTRY(kmain) + +/* Define the program headers we want so the bootloader gives us the right */ +/* MMU permissions; this also allows us to exert more control over the linking */ +/* process. */ +PHDRS +{ + limine_requests PT_LOAD; + text PT_LOAD; + rodata PT_LOAD; + data PT_LOAD; +} + +SECTIONS +{ + /* We want to 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; + + kernel_start = .; + + /* Define a section to contain the Limine requests and assign it to its own PHDR */ + .limine_requests : { + KEEP(*(.limine_requests_start)) + KEEP(*(.limine_requests)) + KEEP(*(.limine_requests_end)) + } :limine_requests + + /* Move to the next memory page for .text */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .text : { + *(.text .text.*) + } :text + + /* Move to the next memory page for .rodata */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .rodata : { + *(.rodata .rodata.*) + *(.srodata .srodata.*) + *(.sdata2 .sdata2.*) + } :rodata + + /* Add a .note.gnu.build-id output section in case a build ID flag is added to the */ + /* linker command. */ + .note.gnu.build-id : { + *(.note.gnu.build-id) + } :rodata + + /* C++ is a language that allows for global constructors. In order to obtain the */ + /* address of the ".init_array" section we need to define a symbol for it. */ + .init_array : { + __init_array = .; + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP(*(.init_array .ctors)) + __init_array_end = .; + } :rodata + + /* Move to the next memory page for .data */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .data : { + *(.data .data.*) + *(.sdata .sdata.*) + } :data + + /* 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.*) + *(.sbss .sbss.*) + *(COMMON) + } :data + + /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ + /DISCARD/ : { + *(.eh_frame*) + *(.note .note.*) + } + + kernel_end = .; + +} diff --git a/kernel/linker.ld b/kernel/linker-scripts/x86_64.lds index ff02735..147f151 100644 --- a/kernel/linker.ld +++ b/kernel/linker-scripts/x86_64.lds @@ -33,19 +33,25 @@ SECTIONS } :limine_requests /* Move to the next memory page for .text */ - . = ALIGN(4K); + . = ALIGN(CONSTANT(MAXPAGESIZE)); .text : { *(.text .text.*) } :text /* Move to the next memory page for .rodata */ - . = ALIGN(4K); + . = ALIGN(CONSTANT(MAXPAGESIZE)); .rodata : { *(.rodata .rodata.*) } :rodata + /* Add a .note.gnu.build-id output section in case a build ID flag is added to the */ + /* linker command. */ + .note.gnu.build-id : { + *(.note.gnu.build-id) + } :rodata + /* C++ is a language that allows for global constructors. In order to obtain the */ /* address of the ".init_array" section we need to define a symbol for it. */ .init_array : { @@ -56,7 +62,7 @@ SECTIONS } :rodata /* Move to the next memory page for .data */ - . = ALIGN(4K); + . = ALIGN(CONSTANT(MAXPAGESIZE)); .data : { *(.data .data.*) @@ -71,11 +77,12 @@ SECTIONS *(COMMON) } :data - kernel_end = .; - /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ /DISCARD/ : { *(.eh_frame*) *(.note .note.*) } + + kernel_end = .; + } diff --git a/kernel/src/arch/aarch64/aarch64.cpp b/kernel/src/arch/aarch64/aarch64.cpp new file mode 100644 index 0000000..25486dd --- /dev/null +++ b/kernel/src/arch/aarch64/aarch64.cpp @@ -0,0 +1,54 @@ + +#include <cstdint> +#include <generic/arch.hpp> + +namespace arch { + [[gnu::weak]] void disable_interrupts() { + asm volatile("msr daifset, #2"); + } + + [[gnu::weak]] void enable_interrupts() { + asm volatile("msr daifclr, #2"); + } + + [[gnu::weak]] void wait_for_interrupt() { + asm volatile("wfi"); + } + + [[gnu::weak]] void hcf() { + disable_interrupts(); + while(true) { + wait_for_interrupt(); + } + } + + [[gnu::weak]] void tlb_flush(std::uintptr_t hint, std::uintptr_t len) { + if (len / PAGE_SIZE > 256 || len == 0) { + asm volatile("tlbi alle1\n" "dsb ish\n" "isb\n" : : : "memory"); + } else { + for (std::uintptr_t i = 0; i < len; i += PAGE_SIZE) { + std::uintptr_t addr = hint + i; + asm volatile("tlbi vae1, %0\n" : : "r"(addr) : "memory"); + } + + asm volatile("dsb ish\n" "isb\n" : : : "memory"); + } + } + + [[gnu::weak]] void pause() { + asm volatile("isb"); + } + + [[gnu::weak]] const char* name() { + return "aarch64"; + } + + [[gnu::weak]] int level_paging() { + return 4; + } + + [[gnu::weak]] void init(int stage) { + (void)stage; + } + +}
\ No newline at end of file diff --git a/kernel/src/arch/aarch64/paging.cpp b/kernel/src/arch/aarch64/paging.cpp new file mode 100644 index 0000000..69ecd4b --- /dev/null +++ b/kernel/src/arch/aarch64/paging.cpp @@ -0,0 +1,148 @@ +#include <cstdint> +#include <generic/arch.hpp> +#include <generic/bootloader/bootloader.hpp> +#include <generic/hhdm.hpp> +#include <generic/pmm.hpp> +#include <utils/gobject.hpp> + +#define PTE_MASK_VALUE 0x0000fffffffff000 +#define PTE_PRESENT (1 << 0) +#define PTE_RW (0) +#define PTE_AF (1 << 10) +#define PTE_4K (1 << 1) +#define PTE_USER (1 << 6) +#define PTE_WC (1 << 2) +#define LVL_PG_MASK PTE_MASK_VALUE + +int level_to_index(std::uintptr_t virt, int level) { + switch (level) { + case 0: return PTE_INDEX(virt, 39); + case 1: return PTE_INDEX(virt, 30); + case 2: return PTE_INDEX(virt, 21); + case 3: return PTE_INDEX(virt, 12); + default: return 0; + } + return 0; +} + +int64_t* __paging_next_level_noalloc(std::uint64_t* table, std::uint16_t idx) { + if (!(table[idx] & PTE_PRESENT)) + return (int64_t*) -1; + return (int64_t*) ((table[idx] & LVL_PG_MASK) + etc::hhdm()); +} + +std::int64_t __memory_paging_getphys(std::uint64_t* table, std::uint64_t virt, int level) { + if (!table && (std::int64_t) table == -1) + return -1; + int max_level = bootloader::bootloader->is_5_level_paging() ? 4 : 3; + if (max_level == level) { + return (table[level_to_index(virt, level)] & PTE_PRESENT) ? table[level_to_index(virt, level)] & LVL_PG_MASK : -1; + } else + return __memory_paging_getphys((std::uint64_t*) __paging_next_level_noalloc(table, level_to_index(virt, level)), virt, level + 1); + return -1; +} + +uint64_t* aarch64_paging_next_level(std::uint64_t* table, std::uint16_t idx, std::uint64_t flags) { + if (!(table[idx] & PTE_PRESENT)) + table[idx] = pmm::freelist::alloc_4k() | flags; + return (uint64_t*) ((table[idx] & LVL_PG_MASK) + etc::hhdm()); +} + +std::uint64_t convert_flags(std::uint64_t flags) { + std::uint64_t result = 0; + if (flags & PAGING_NC) + result |= 0; + if (flags & PAGING_PRESENT) + result |= PTE_PRESENT | PTE_AF; + if (flags & PAGING_RW) + result |= PTE_RW; + if (flags & PAGING_USER) + result |= PTE_USER; + if (flags & PAGING_WC) + result |= PTE_WC; + return result; +} + +void aarch64_map_page(std::uintptr_t root, std::uintptr_t phys, std::uintptr_t virt, std::uint32_t flags) { + std::uint64_t* cr30 = (std::uint64_t*) (root + etc::hhdm()); + std::uint64_t new_flags = PTE_PRESENT | PTE_RW | PTE_4K; + if (PTE_INDEX(virt, 39) < 256) + new_flags |= PTE_USER; + uint64_t* pml3 = aarch64_paging_next_level(cr30, PTE_INDEX(virt, 39), new_flags); + uint64_t* pml2 = aarch64_paging_next_level(pml3, PTE_INDEX(virt, 30), new_flags); + uint64_t* pml = aarch64_paging_next_level(pml2, PTE_INDEX(virt, 21), new_flags); + pml[PTE_INDEX(virt, 12)] = phys | flags | PTE_4K; +} + + +namespace arch { + [[gnu::weak]] void enable_paging(std::uintptr_t root) { + asm volatile("msr ttbr0_el1, %0" : : "r"(root) : "memory"); + if (root == gobject::kernel_root) { + asm volatile("msr ttbr1_el1, %0" : : "r"(root) : "memory"); + asm volatile("dsb ish; tlbi vmalle1; dsb ish; isb" : : : "memory"); + } else { + asm volatile("dsb ish; tlbi vmalle1; dsb ish; isb" : : : "memory"); + } + } + + + [[gnu::weak]] void map_page(std::uintptr_t root, std::uint64_t phys, std::uintptr_t virt, int flags) { + aarch64_map_page(root,phys,virt,convert_flags(flags)); + } + + [[gnu::weak]] std::uint64_t get_phys_from_page(std::uintptr_t root, std::uintptr_t virt) { + return __memory_paging_getphys((std::uint64_t*)(root + etc::hhdm()),virt,0); + } + + [[gnu::weak]] void destroy_root(std::uintptr_t root, int level) { + std::uint64_t* table = (std::uint64_t*) (root + etc::hhdm()); + if (bootloader::bootloader->is_5_level_paging()) { + if (level != 4) { + if (level == 0) { + for (int i = 0; i < 256; i++) { + if (table[i] & PTE_PRESENT) { + destroy_root(table[i] & PTE_MASK_VALUE, level + 1); + } + } + } else { + for (int i = 0; i < 512; i++) { + if (table[i] & PTE_PRESENT) { + destroy_root(table[i] & PTE_MASK_VALUE, level + 1); + } + } + } + } + + if (level != 0) + pmm::freelist::free(root); + } else { + if (level != 3) { + if (level == 0) { + for (int i = 0; i < 256; i++) { + if (table[i] & PTE_PRESENT) { + destroy_root(table[i] & PTE_MASK_VALUE, level + 1); + } + } + } else { + for (int i = 0; i < 512; i++) { + if (table[i] & PTE_PRESENT) { + destroy_root(table[i] & PTE_MASK_VALUE, level + 1); + } + } + } + } + + if (level != 0) + pmm::freelist::free(root); + } + } + + [[gnu::weak]] void copy_higher_half(std::uintptr_t root, std::uintptr_t src_root) { + std::uint64_t* virt_rootcr3 = (std::uint64_t*) (root + etc::hhdm()); + std::uint64_t* virt_srccr3 = (std::uint64_t*) (src_root + etc::hhdm()); + for (int i = 255; i < 512; i++) { + virt_rootcr3[i] = virt_srccr3[i]; + } + } +};
\ No newline at end of file diff --git a/kernel/src/arch/riscv64/features.hpp b/kernel/src/arch/riscv64/features.hpp new file mode 100644 index 0000000..7da036a --- /dev/null +++ b/kernel/src/arch/riscv64/features.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include <klibc/stdio.hpp> +#include <cstdint> + +namespace riscv64 { + +#define SATP64_MODE 0xF000000000000000 +#define PAGING_3LEVEL 8 +#define PAGING_4LEVEL 9 +#define PAGING_5LEVEL 10 + + inline int level_paging = 0; + inline int raw_level_paging = 0; + + static inline int get_paging_level() { + if (level_paging == 0) { + std::uint64_t satp_value = 0; + asm volatile("csrr %0, satp" : "=r"(satp_value)); + std::uint64_t current_mode = (satp_value & SATP64_MODE) >> 60; + + raw_level_paging = current_mode; + + switch (current_mode) { + case PAGING_3LEVEL: riscv64::level_paging = 3; break; + case PAGING_4LEVEL: riscv64::level_paging = 4; break; + case PAGING_5LEVEL: riscv64::level_paging = 5; break; + default: klibc::printf("Unsupported level paging for riscv64 ! (%d)\n", current_mode); return 0; + }; + } + return riscv64::level_paging; + } +}; // namespace riscv64 diff --git a/kernel/src/arch/riscv64/paging.cpp b/kernel/src/arch/riscv64/paging.cpp new file mode 100644 index 0000000..bea9c5c --- /dev/null +++ b/kernel/src/arch/riscv64/paging.cpp @@ -0,0 +1,163 @@ +#include <cstdint> +#include <generic/arch.hpp> +#include <generic/bootloader/bootloader.hpp> +#include <generic/hhdm.hpp> +#include <generic/pmm.hpp> +#include <arch/riscv64/features.hpp> + +#define PTE_MASK_VALUE (0x003ffffffffffc00) +#define PTE_PRESENT (1 << 0) +#define PTE_RW ((1 << 1) | (1 << 2) | (1 << 3)) +#define PTE_USER (1 << 4) +#define PTE_WC (0) +#define PTE_MMIO (0) +#define PTE_ACCESSED (1 << 6) +#define PTE_DIRTY (1 << 7) +#define LVL_PG_MASK PTE_MASK_VALUE + + +int level_to_index(std::uintptr_t virt, int level) { + if (riscv64::get_paging_level() == 5) { + switch (level) { + case 0: return PTE_INDEX(virt, 48); + case 1: return PTE_INDEX(virt, 39); + case 2: return PTE_INDEX(virt, 30); + case 3: return PTE_INDEX(virt, 21); + case 4: return PTE_INDEX(virt, 12); + default: return 0; + } + } else if (riscv64::get_paging_level() == 4) { + switch (level) { + case 0: return PTE_INDEX(virt, 39); + case 1: return PTE_INDEX(virt, 30); + case 2: return PTE_INDEX(virt, 21); + case 3: return PTE_INDEX(virt, 12); + default: return 0; + } + } else if (riscv64::get_paging_level() == 3) { + switch (level) { + case 0: return PTE_INDEX(virt, 30); + case 1: return PTE_INDEX(virt, 21); + case 2: return PTE_INDEX(virt, 12); + default: return 0; + } + } + return 0; +} + +std::uint64_t extract_ppn(std::uint64_t masked_table) { + return masked_table >> 10; +} + +std::uint64_t make_pte(std::uint64_t ppn) { + return ppn << 10; +} + +int64_t* __paging_next_level_noalloc(std::uint64_t* table, std::uint16_t idx) { + if (!(table[idx] & PTE_PRESENT)) + return (int64_t*) -1; + return (int64_t*)((extract_ppn(table[idx] & PTE_MASK_VALUE) << 12) + etc::hhdm()); +} + + +std::int64_t __memory_paging_getphys(std::uint64_t* table, std::uint64_t virt, int level) { + if (!table && (std::int64_t) table == -1) + return -1; + int max_level = riscv64::get_paging_level() - 1; + if (max_level == level) { + return (table[level_to_index(virt, level)] & PTE_PRESENT) ? (extract_ppn(table[level_to_index(virt, level)] & LVL_PG_MASK) << 12) : -1; + } else + return __memory_paging_getphys((std::uint64_t*) __paging_next_level_noalloc(table, level_to_index(virt, level)), virt, level + 1); + return -1; +} + +uint64_t* riscv64_paging_next_level(std::uint64_t* table, std::uint16_t idx) { + if (!(table[idx] & PTE_PRESENT)) + table[idx] = (make_pte(pmm::freelist::alloc_4k() >> 12)) | PTE_PRESENT; + return (uint64_t*) ((extract_ppn(table[idx] & PTE_MASK_VALUE) << 12) + etc::hhdm()); +} + +std::uint64_t convert_flags(std::uint64_t flags) { + std::uint64_t result = 0; + if (flags & PAGING_NC) + result |= PTE_MMIO; + if (flags & PAGING_PRESENT) + result |= PTE_PRESENT; + if (flags & PAGING_RW) + result |= PTE_RW; + if (flags & PAGING_USER) + result |= PTE_USER; + if (flags & PAGING_WC) + result |= PTE_WC; + result |= PTE_ACCESSED | PTE_DIRTY; + return result; +} + + +void riscv64_map_page(std::uintptr_t root, std::uint64_t phys, std::uintptr_t virt, std::uint32_t flags) { + if (riscv64::get_paging_level() == 4) { + std::uint64_t* l_root = (std::uint64_t*) (root + etc::hhdm()); + uint64_t* l1 = riscv64_paging_next_level(l_root, PTE_INDEX(virt, 39)); + uint64_t* l2 = riscv64_paging_next_level(l1, PTE_INDEX(virt, 30)); + uint64_t* l3 = riscv64_paging_next_level(l2, PTE_INDEX(virt, 21)); + l3[PTE_INDEX(virt, 12)] = (make_pte(phys >> 12)) | flags; + } else if (riscv64::get_paging_level() == 3) { + std::uint64_t* l_root = (std::uint64_t*) (root + etc::hhdm()); + uint64_t* l2 = riscv64_paging_next_level(l_root, PTE_INDEX(virt, 30)); + uint64_t* l3 = riscv64_paging_next_level(l2, PTE_INDEX(virt, 21)); + l3[PTE_INDEX(virt, 12)] = (make_pte(phys >> 12)) | flags; + } else if (riscv64::get_paging_level() == 5) { + std::uint64_t* l_root = (std::uint64_t*) (root + etc::hhdm()); + uint64_t* l0 = riscv64_paging_next_level(l_root, PTE_INDEX(virt, 48)); + uint64_t* l1 = riscv64_paging_next_level(l0, PTE_INDEX(virt, 39)); + uint64_t* l2 = riscv64_paging_next_level(l1, PTE_INDEX(virt, 30)); + uint64_t* l3 = riscv64_paging_next_level(l2, PTE_INDEX(virt, 21)); + l3[PTE_INDEX(virt, 12)] = (make_pte(phys >> 12)) | flags; + } +} + +namespace arch { + [[gnu::weak]] void enable_paging(std::uintptr_t root) { + std::uint64_t mode_root = (root >> 12) | ((std::uint64_t) riscv64::raw_level_paging << 60); + asm volatile("csrw satp, %0" : : "r"(mode_root) : "memory"); + asm volatile("sfence.vma"); + } + + [[gnu::weak]] void map_page(std::uintptr_t root, std::uint64_t phys, std::uintptr_t virt, int flags) { + riscv64_map_page(root,phys,virt,convert_flags(flags)); + } + + [[gnu::weak]] std::uint64_t get_phys_from_page(std::uintptr_t root, std::uintptr_t virt) { + return __memory_paging_getphys((std::uint64_t*)(root + etc::hhdm()),virt,0); + } + + [[gnu::weak]] void destroy_root(std::uintptr_t root, int level) { + std::uint64_t* table = (std::uint64_t*) (root + etc::hhdm()); + if (level != riscv64::get_paging_level() - 1) { + if (level == 0) { + for (int i = 0; i < 256; i++) { + if (table[i] & PTE_PRESENT) { + destroy_root(table[i] & PTE_MASK_VALUE, level + 1); + } + } + } else { + for (int i = 0; i < 512; i++) { + if (table[i] & PTE_PRESENT) { + destroy_root(table[i] & PTE_MASK_VALUE, level + 1); + } + } + } + + if (level != 0) + pmm::freelist::free(root); + } + } + + [[gnu::weak]] void copy_higher_half(std::uintptr_t root, std::uintptr_t src_root) { + std::uint64_t* virt_rootcr3 = (std::uint64_t*) (root + etc::hhdm()); + std::uint64_t* virt_srccr3 = (std::uint64_t*) (src_root + etc::hhdm()); + for (int i = 255; i < 512; i++) { + virt_rootcr3[i] = virt_srccr3[i]; + } + } +};
\ No newline at end of file diff --git a/kernel/src/arch/riscv64/riscv64.cpp b/kernel/src/arch/riscv64/riscv64.cpp new file mode 100644 index 0000000..2db83bf --- /dev/null +++ b/kernel/src/arch/riscv64/riscv64.cpp @@ -0,0 +1,56 @@ + +#include <cstdint> +#include <generic/arch.hpp> +#include <arch/riscv64/features.hpp> + +namespace arch { + [[gnu::weak]] void disable_interrupts() { + asm volatile("csrc sstatus, %0" : : "r"(1 << 1)); + } + + [[gnu::weak]] void enable_interrupts() { + asm volatile("csrs sstatus, %0" : : "r"(1 << 1)); + } + + [[gnu::weak]] void wait_for_interrupt() { + asm volatile("wfi"); + } + + [[gnu::weak]] void hcf() { + disable_interrupts(); + while(true) { + wait_for_interrupt(); + } + } + + [[gnu::weak]] void pause() { +#ifdef __riscv_zihintpause + asm volatile("pause"); +#else + asm volatile("nop"); +#endif + } + + [[gnu::weak]] void tlb_flush(std::uintptr_t hint, std::uintptr_t len) { + if (len / PAGE_SIZE > 256 || len == 0) { + asm volatile("sfence.vma"); + } else { + for (std::uintptr_t i = 0; i < len; i += PAGE_SIZE) { + asm volatile("sfence.vma %0" : : "r"(hint + i) : "memory"); + } + } + } + + [[gnu::weak]] const char* name() { + return "riscv64"; + } + + [[gnu::weak]] int level_paging() { + return riscv64::get_paging_level(); + } + + [[gnu::weak]] void init(int stage) { + (void)stage; + } + +}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/asm/scheduling.asm b/kernel/src/arch/x86_64/asm/scheduling.asm deleted file mode 100644 index 2e67154..0000000 --- a/kernel/src/arch/x86_64/asm/scheduling.asm +++ /dev/null @@ -1,121 +0,0 @@ - -extern schedulingSchedule -global schedulingEnter -global schedulingEnd -global yield - -yield: - pop rax - mov rdx, rsp - mov rsp,[gs:16] - push qword 0 - push rdx - pushfq - push qword 0x08 - push qword rax - jmp schedulingEnter - -global yield0 - -yield0: - sti - pause - cli - pop rax - mov rdx, rsp - mov rsp,[gs:16] - push qword 0 - push rdx - pushfq - push qword 0x08 - push qword rax - jmp schedulingEnter - - -schedulingEnter: - cli - push qword 0 - push qword 0 - push r15 - push r14 - push r13 - push r12 - push r11 - push r10 - push r9 - push r8 - push rbp - push rdi - push rsi - push rdx - push rcx - push rbx - push rax - mov rax,cr3 - push rax - mov rdi,rsp - jmp schedulingSchedule - -global schedulingScheduleSaveAndChangeStack -schedulingScheduleSaveAndChangeStack: - cli - mov rsi,rsp - pop rdx - mov rsp,rdi - - push 0x10 - push rsi - pushfq - push 0x08 - push rdx - - push qword 0 - push qword 0 - push r15 - push r14 - push r13 - push r12 - push r11 - push r10 - push r9 - push r8 - push rbp - push rdi - push rsi - push rdx - push rcx - push rbx - push rax - mov rax,cr3 - push rax - mov rdi,rsp - jmp schedulingSchedule - - -global schedulingScheduleAndChangeStack -schedulingScheduleAndChangeStack: - mov rsp,rdi - mov rdi,rsi - jmp schedulingSchedule - -schedulingEnd: - mov rsp,rdi - pop rax - mov cr3,rax - pop rax - pop rbx - pop rcx - pop rdx - pop rsi - pop rdi - pop rbp - pop r8 - pop r9 - pop r10 - pop r11 - pop r12 - pop r13 - pop r14 - pop r15 - add rsp,16 - iretq
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/asm/syscall.asm b/kernel/src/arch/x86_64/asm/syscall.asm deleted file mode 100644 index 34b1058..0000000 --- a/kernel/src/arch/x86_64/asm/syscall.asm +++ /dev/null @@ -1,56 +0,0 @@ - - -global syscall_handler -extern syscall_handler_c -syscall_handler: - swapgs - mov qword [gs:0],rsp - mov rsp, qword [gs:8] - push qword (0x18 | 3) - push qword [gs:0] - push qword r11 - push qword (0x20 | 3) - push qword rcx - push qword 0 - push qword 0 - push r15 - push r14 - push r13 - push r12 - push r11 - push r10 - push r9 - push r8 - push rbp - push rdi - push rsi - push rdx - push rcx - push rbx - push rax - mov rax,cr3 - push rax - mov rdi,rsp - call syscall_handler_c - pop rax - pop rax - pop rbx - pop rcx - pop rdx - pop rsi - pop rdi - pop rbp - pop r8 - pop r9 - pop r10 - pop r11 - pop r12 - pop r13 - pop r14 - pop r15 - cli - mov rsp, qword [gs:0] - swapgs - o64 sysret - -section .rodata diff --git a/kernel/src/arch/x86_64/assembly.hpp b/kernel/src/arch/x86_64/assembly.hpp new file mode 100644 index 0000000..4a9bda4 --- /dev/null +++ b/kernel/src/arch/x86_64/assembly.hpp @@ -0,0 +1,30 @@ +#include <cstdint> + +namespace assembly { + inline std::uint64_t rdmsr(std::uint32_t msr) { + std::uint32_t lo, hi; + __asm__ volatile ("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr)); + return ((std::uint64_t)hi << 32) | lo; + } + + inline void wrmsr(std::uint32_t msr, std::uint64_t value) { + std::uint32_t lo = (uint32_t)(value & 0xFFFFFFFF); + std::uint32_t hi = (uint32_t)(value >> 32); + __asm__ volatile ("wrmsr" : : "c"(msr), "a"(lo), "d"(hi)); + } + + inline void cpuid(int code, int code2, std::uint32_t *a, std::uint32_t *b, std::uint32_t *c , std::uint32_t *d) { + __asm__ volatile("cpuid":"=a"(*a),"=b"(*b),"=c"(*c),"=d"(*d):"a"(code),"c"(code2)); + } + + inline int cpuid_string(int code, std::uint32_t where[4]) { + __asm__ volatile("cpuid":"=a"(*where),"=b"(*(where+1)),"=c"(*(where+2)),"=d"(*(where+3)):"a"(code)); + return (int)where[0]; + } + + inline std::uint64_t rdtsc() { + unsigned int hi, lo; + __asm__ volatile ("rdtsc" : "=a"(lo), "=d"(hi)); + return ((uint64_t)hi << 32) | lo; + } +};
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/cpu/asm/gdt.asm b/kernel/src/arch/x86_64/cpu/gdt.asm index 312735f..796e892 100644 --- a/kernel/src/arch/x86_64/cpu/asm/gdt.asm +++ b/kernel/src/arch/x86_64/cpu/gdt.asm @@ -1,5 +1,5 @@ -global loadgdt -loadgdt: +global load_gdt +load_gdt: lgdt [rdi] mov ax,0 mov ds,ax @@ -13,8 +13,8 @@ loadgdt: push rdi retfq -global loadtss -loadtss: +global load_tss +load_tss: mov ax,0x28 ltr ax ret
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/cpu/gdt.cpp b/kernel/src/arch/x86_64/cpu/gdt.cpp index b83b166..dd406f2 100644 --- a/kernel/src/arch/x86_64/cpu/gdt.cpp +++ b/kernel/src/arch/x86_64/cpu/gdt.cpp @@ -1,14 +1,14 @@ - #include <cstdint> -#include <generic/mm/pmm.hpp> -#include <generic/mm/paging.hpp> -#include <generic/mm/heap.hpp> -#include <arch/x86_64/cpu/data.hpp> +#include <generic/heap.hpp> #include <arch/x86_64/cpu/gdt.hpp> -#include <etc/libc.hpp> -#include <config.hpp> +#include <generic/pmm.hpp> +#include <generic/hhdm.hpp> +#include <klibc/stdio.hpp> +#include <arch/x86_64/cpu_local.hpp> + +#define KERNEL_STACK_SIZE 32 * 1024 -gdt_t original_gdt = { +x86_64::gdt::gdt_t original_gdt = { {0,0,0,0,0,0}, /* 0x0 Null */ {0,0,0,0x9a,0xa2,0}, /* 0x08 64 bit code */ {0,0,0,0x92,0xa0,0}, /* just align user data and user code */ @@ -17,36 +17,35 @@ gdt_t original_gdt = { {0x68,0,0,0x89,0x20,0,0,0} /* 0x28 tss */ }; -void arch::x86_64::cpu::gdt::init() { - arch::x86_64::cpu::gdt* new_gdt = (arch::x86_64::cpu::gdt*)memory::heap::malloc(sizeof(arch::x86_64::cpu::gdt)); +void x86_64::gdt::init() { + gdt_t* new_gdt = new gdt_t; tss_t* tss = new tss_t; - - /* For optimizations kheap doesn't zero memory */ - memset(&new_gdt->gdt_obj,0,sizeof(gdt_t)); - memset(tss,0,sizeof(tss_t)); - memcpy(&new_gdt->gdt_obj,&original_gdt,sizeof(gdt_t)); + gdt_pointer_t* gdtr = new gdt_pointer_t; + klibc::memcpy(new_gdt,&original_gdt,sizeof(gdt_t)); - tss->rsp[0] = memory::pmm::helper::alloc_kernel_stack(KERNEL_STACK_SIZE); - tss->ist[0] = memory::pmm::helper::alloc_kernel_stack(KERNEL_STACK_SIZE); /* Exceptions */ - tss->ist[1] = memory::pmm::helper::alloc_kernel_stack(KERNEL_STACK_SIZE); /* Timer */ - tss->ist[2] = memory::pmm::helper::alloc_kernel_stack(KERNEL_STACK_SIZE); /* IRQ Layout */ - tss->ist[3] = memory::pmm::helper::alloc_kernel_stack(KERNEL_STACK_SIZE); /* For ignorestub */ + tss->rsp[0] = (std::uint64_t)(pmm::buddy::alloc(KERNEL_STACK_SIZE).phys + etc::hhdm()); + tss->ist[0] = (std::uint64_t)(pmm::buddy::alloc(KERNEL_STACK_SIZE).phys + etc::hhdm()); /* Exceptions */ + tss->ist[1] = (std::uint64_t)(pmm::buddy::alloc(KERNEL_STACK_SIZE).phys + etc::hhdm()); /* Timer */ + tss->ist[2] = (std::uint64_t)(pmm::buddy::alloc(KERNEL_STACK_SIZE).phys + etc::hhdm()); /* IRQ Layout */ + tss->ist[3] = (std::uint64_t)(pmm::buddy::alloc(KERNEL_STACK_SIZE).phys + etc::hhdm()); /* For ignorestub */ tss->iopb_offsset = sizeof(tss_t); - new_gdt->gdt_obj.tss.baselow16 = (std::uint64_t)tss & 0xFFFF; - new_gdt->gdt_obj.tss.basemid8 = ((std::uint64_t)tss >> 16) & 0xFF; - new_gdt->gdt_obj.tss.basehigh8 = ((std::uint64_t)tss >> 24) & 0xFF; - new_gdt->gdt_obj.tss.baseup32 = (std::uint64_t)tss >> 32; + new_gdt->tss.baselow16 = (std::uint64_t)tss & 0xFFFF; + new_gdt->tss.basemid8 = ((std::uint64_t)tss >> 16) & 0xFF; + new_gdt->tss.basehigh8 = ((std::uint64_t)tss >> 24) & 0xFF; + new_gdt->tss.baseup32 = (std::uint64_t)tss >> 32; + + gdtr->size = sizeof(gdt_t) - 1; + gdtr->base = (std::uint64_t)new_gdt; - new_gdt->gdtr.size = sizeof(gdt_t) - 1; - new_gdt->gdtr.base = (std::uint64_t)&new_gdt->gdt_obj; + load_gdt(gdtr); + load_tss(); - new_gdt->LoadGDT(); - new_gdt->LoadTSS(); + x86_64::restore_cpu_data(); + auto cpudata = x86_64::cpu_data(); + cpudata->timer_ist_stack = (std::uint64_t)(pmm::buddy::alloc(KERNEL_STACK_SIZE).phys + etc::hhdm()); - /* Also i want to init cpu data too */ - auto cpudata = arch::x86_64::cpu::data(); - cpudata->timer_ist_stack = memory::pmm::helper::alloc_kernel_stack(KERNEL_STACK_SIZE); + klibc::printf("GDT: tss->rsp0 0x%p tss->ist0 0x%p\r\n",tss->rsp[0],tss->ist[0],tss->ist[1],tss->ist[2],tss->ist[3],cpudata->timer_ist_stack); }
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/cpu/gdt.hpp b/kernel/src/arch/x86_64/cpu/gdt.hpp new file mode 100644 index 0000000..c71609e --- /dev/null +++ b/kernel/src/arch/x86_64/cpu/gdt.hpp @@ -0,0 +1,56 @@ +#pragma once +#include <cstdint> + +namespace x86_64 { + namespace gdt { + + typedef struct __attribute__((packed)) { + std::uint16_t size; + std::uint64_t base; + } gdt_pointer_t; + + typedef struct __attribute__((packed)) { + std::uint16_t limit; + std::uint16_t baselow16; + std::uint8_t basemid8; + std::uint8_t access; + std::uint8_t granularity; + std::uint8_t basehigh8; + } gdt_entry_t; + + typedef struct __attribute__((packed)) { + std::uint16_t length; + std::uint16_t baselow16; + std::uint8_t basemid8; + std::uint8_t flags0; + std::uint8_t flags1; + std::uint8_t basehigh8; + std::uint32_t baseup32; + std::uint32_t reserved; + } tss_entry_t; + + typedef struct __attribute__((packed)) { + std::uint32_t reserved0; + std::uint64_t rsp[3]; + std::uint64_t reserved1; + std::uint64_t ist[7]; + std::uint32_t reserved2; + std::uint32_t reserved3; + std::uint16_t reserved4; + std::uint16_t iopb_offsset; + } tss_t; + + typedef struct __attribute__((packed)) { + gdt_entry_t zero; + gdt_entry_t _64bitcode; + gdt_entry_t _64bitdata; + gdt_entry_t usercode; + gdt_entry_t userdata; + tss_entry_t tss; + } gdt_t; + + extern "C" void load_gdt(void* gdtr); + extern "C" void load_tss(); + void init(); + } +};
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/interrupts/asm/idt.asm b/kernel/src/arch/x86_64/cpu/idt.asm index deb0164..78bed7e 100644 --- a/kernel/src/arch/x86_64/interrupts/asm/idt.asm +++ b/kernel/src/arch/x86_64/cpu/idt.asm @@ -194,7 +194,7 @@ irqStub: push rax mov rdi,rsp xor rbp,rbp - call irqHandler + nop pop rax mov cr3,rax pop rax diff --git a/kernel/src/arch/x86_64/interrupts/idt.cpp b/kernel/src/arch/x86_64/cpu/idt.cpp index 12fff62..f1765ce 100644 --- a/kernel/src/arch/x86_64/interrupts/idt.cpp +++ b/kernel/src/arch/x86_64/cpu/idt.cpp @@ -1,28 +1,22 @@ #include <cstdint> -#include <arch/x86_64/interrupts/idt.hpp> -#include <arch/x86_64/cpu/lapic.hpp> -#include <etc/libc.hpp> -#include <etc/list.hpp> +#include <arch/x86_64/cpu/idt.hpp> +#include <utils/bitmap.hpp> +#include <klibc/stdio.hpp> -#include <etc/logging.hpp> - -using namespace Lists; -using namespace arch::x86_64::interrupts; - -idt_entry_t idt_entries[255]; -Bitmap* idt_bitmap; -idtr_t idtr; +x86_64::idt::idt_entry_t idt_entries[255]; +utils::bitmap* idt_bitmap; +x86_64::idt::idtr_t idtr; extern "C" void* isrTable[]; extern "C" void ignoreStubC() { - arch::x86_64::cpu::lapic::eoi(); + } -void arch::x86_64::interrupts::idt::init() { - memset(idt_entries,0,sizeof(idt_entries)); - idt_bitmap = new Bitmap(255); +void x86_64::idt::init() { + klibc::memset(idt_entries,0,sizeof(idt_entries)); + idt_bitmap = new utils::bitmap(255); idtr.base = (std::uint64_t)idt_entries; idtr.limit = (std::uint16_t)sizeof(idt_entry_t) * 256 - 1; @@ -40,11 +34,11 @@ void arch::x86_64::interrupts::idt::init() { load(); } -void arch::x86_64::interrupts::idt::load() { +void x86_64::idt::load() { __asm__ volatile ("lidt %0" : : "m"(idtr)); } -void arch::x86_64::interrupts::idt::set_entry(std::uint64_t base,std::uint8_t vec,std::uint8_t flags,std::uint8_t ist) { +void x86_64::idt::set_entry(std::uint64_t base,std::uint8_t vec,std::uint8_t flags,std::uint8_t ist) { idt_entry_t* descriptor = &idt_entries[vec]; descriptor->low = (std::uint64_t)base & 0xFFFF; @@ -59,7 +53,7 @@ void arch::x86_64::interrupts::idt::set_entry(std::uint64_t base,std::uint8_t ve } -std::uint8_t arch::x86_64::interrupts::idt::alloc() { +std::uint8_t x86_64::idt::alloc() { for(int i = 0;i < 255;i++) { if(!idt_bitmap->test(i)) { idt_bitmap->set(i); diff --git a/kernel/src/arch/x86_64/cpu/idt.hpp b/kernel/src/arch/x86_64/cpu/idt.hpp new file mode 100644 index 0000000..f386e86 --- /dev/null +++ b/kernel/src/arch/x86_64/cpu/idt.hpp @@ -0,0 +1,56 @@ +#pragma once +#include <cstdint> + +namespace x86_64 { + namespace idt { + typedef struct { + std::uint16_t low; + std::uint16_t cs; + std::uint8_t ist; + std::uint8_t attr; + std::uint16_t mid; + std::uint32_t high; + std::uint32_t reserved0; + } __attribute__((packed)) idt_entry_t; + + typedef struct { + std::uint16_t limit; + std::uint64_t base; + } __attribute__((packed)) idtr_t; + + typedef struct { + std::uint64_t cr3; + std::uint64_t rax; + std::uint64_t rbx; + std::uint64_t rcx; + std::uint64_t rdx; + std::uint64_t rsi; + std::uint64_t rdi; + std::uint64_t rbp; + std::uint64_t r8; + std::uint64_t r9; + std::uint64_t r10; + std::uint64_t r11; + std::uint64_t r12; + std::uint64_t r13; + std::uint64_t r14; + std::uint64_t r15; + std::uint64_t vec; + std::uint64_t err_code; + std::uint64_t rip; + std::uint64_t cs; + std::uint64_t rflags; + std::uint64_t rsp; + std::uint64_t ss; + } int_frame_t; + + + extern "C" void ignoreStub(); + + void init(); + void set_entry(std::uint64_t base,std::uint8_t vec,std::uint8_t flags,std::uint8_t ist); + std::uint8_t alloc(); + void load(); + + }; +};
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/cpu/smp.cpp b/kernel/src/arch/x86_64/cpu/smp.cpp deleted file mode 100644 index a06f4c5..0000000 --- a/kernel/src/arch/x86_64/cpu/smp.cpp +++ /dev/null @@ -1,88 +0,0 @@ - -#include <cstdint> - -#include <arch/x86_64/cpu/smp.hpp> -#include <generic/time.hpp> - -#include <arch/x86_64/cpu/data.hpp> - -#include <arch/x86_64/cpu/gdt.hpp> -#include <arch/x86_64/cpu/lapic.hpp> -#include <arch/x86_64/interrupts/idt.hpp> -#include <generic/mm/paging.hpp> - -#include <generic/locks/spinlock.hpp> -#include <etc/bootloaderinfo.hpp> - -#include <drivers/tsc.hpp> - -#include <arch/x86_64/syscalls/syscalls.hpp> - -#include <arch/x86_64/cpu/sse.hpp> - -#include <etc/logging.hpp> - -#include <etc/libc.hpp> - -#include <limine.h> - -#include <drivers/io.hpp> - -#include <atomic> - -using namespace arch::x86_64::cpu; - -int balance_how_much_cpus = 1; - -int how_much_cpus = 1; -std::atomic<int> temp_how_much_cpus[12]; - -locks::spinlock mp_lock; - -void mp::sync(std::uint8_t id) { - if(how_much_cpus != 1) { - temp_how_much_cpus[id].fetch_add(1, std::memory_order_acq_rel); - while (how_much_cpus != temp_how_much_cpus[id].load(std::memory_order_acquire)) { - asm volatile("nop"); - } - time::sleep(1000*1000); // perform 1 second sleep - temp_how_much_cpus[id].store(0, std::memory_order_release); - } -} - -void __mp_bootstrap(struct LIMINE_MP(info)* smp_info) { - mp_lock.lock(); - memory::paging::enablekernel(); - arch::x86_64::interrupts::idt::load(); - arch::x86_64::cpu::gdt::init(); - drivers::tsc::init(); - - arch::x86_64::cpu::data()->smp.cpu_id = balance_how_much_cpus++; - - arch::x86_64::cpu::data()->lapic_block = arch::x86_64::cpu::lapic::init(15000); - arch::x86_64::cpu::sse::init(); - arch::x86_64::syscall::init(); - Log::Display(LEVEL_MESSAGE_OK,"Cpu %d is online \n",arch::x86_64::cpu::data()->smp.cpu_id); - arch::x86_64::cpu::lapic::tick(arch::x86_64::cpu::data()->lapic_block); - mp_lock.unlock(); - setwp(); - mp::sync(0); - mp::sync(1); - asm volatile("sti"); - while(1) { - asm volatile("hlt"); - } -} - -void mp::init() { - struct LIMINE_MP(response)* mp_info = BootloaderInfo::AccessMP(); - - how_much_cpus = mp_info->cpu_count; - - memset(temp_how_much_cpus,0,4*12); - for(std::uint16_t i = 0;i < mp_info->cpu_count;i++) { - if(mp_info->bsp_lapic_id != i) { - mp_info->cpus[i]->goto_address = __mp_bootstrap; - } - } -}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/cpu/sse.cpp b/kernel/src/arch/x86_64/cpu/sse.cpp deleted file mode 100644 index d36e245..0000000 --- a/kernel/src/arch/x86_64/cpu/sse.cpp +++ /dev/null @@ -1,120 +0,0 @@ - -#include <cstdint> -#include <arch/x86_64/cpu/sse.hpp> - -#include <etc/assembly.hpp> -#include <etc/logging.hpp> - -std::uint64_t __sse_size = 0; -char __sse_is_initializied = 0; -char __sse_legacy_save = 0; - -std::uint64_t __sse_cr4_read() { - uint64_t val; - asm volatile("mov %%cr4, %0" : "=r"(val)); - return val; -} - -void __sse_cr4_write(std::uint64_t val) { - asm volatile("mov %0, %%cr4" : : "r"(val) : "memory"); -} - -std::uint64_t __sse_cr0_read() { - uint64_t val; - asm volatile("mov %%cr0, %0" : "=r"(val)); - return val; -} - -void __sse_cr0_write(std::uint64_t val) { - asm volatile("mov %0, %%cr0" : : "r"(val) : "memory"); -} - - -void __sse_xsetbv(std::uint64_t val) { - asm volatile("xsetbv" : : "a"(val), "d"(val >> 32),"c"(0) : "memory"); -} - -std::uint64_t __sse_xgetbv() { - uint32_t a,d; - asm volatile("xgetbv" : "=a"(a),"=d"(d) : "c"(0) : "memory"); - return ((std::uint64_t)d << 32) | a; -} - -void __sse_xsave(void* buf) { - std::uint64_t xcr0 = __sse_xgetbv(); - asm volatile("xsave (%0)" :: "r"(buf), "a"(xcr0 & 0xFFFFFFFF), "d"(xcr0 >> 32), "c"(0): "memory"); -} - -void __sse_xrstor(void* buf) { - std::uint64_t xcr0 = __sse_xgetbv(); - asm volatile("xrstor (%0)" :: "r"(buf), "a"(xcr0 & 0xFFFFFFFF), "d"(xcr0 >> 32), "c"(0): "memory"); -} - -using namespace arch::x86_64::cpu; - -void sse::init() { - uint32_t a,b,c,d; - __cpuid(1,0,&a,&b,&c,&d); - if(!__sse_is_initializied) { - if(c & SSE_XSAVE_SUPPORT) { - __cpuid(13,0,&a,&b,&c,&d); - __sse_legacy_save = 0; - __sse_size = c; - } else { - __sse_legacy_save = 1; - __sse_size = 512; - } - __sse_is_initializied = 1; - } - std::uint64_t cr4 = __sse_cr4_read(); - - cr4 |= DEFAULT_SSE_FLAGS; - - std::uint64_t cr0 = __sse_cr0_read(); - - cr0 &= ~(1 << 2); - cr0 |= (1 << 1); - - __sse_cr0_write(cr0); - - std::uint64_t sse_control = 0; - - __sse_cr4_write(cr4); - - __cpuid(1,0,&a,&b,&c,&d); - if(c & SSE_XSAVE_SUPPORT) - cr4 |= SSE_XSAVE_CR4; - else - return; - - __sse_cr4_write(cr4); - - __cpuid(13,0,&a,&b,&c,&d); - - sse_control |= SSE_CONTROL_DEFAULT; - SSE_CHECK_AND_SET((1 << 2)); - SSE_CHECK_AND_SET((1 << 9)); - SSE_CHECK_AND_SET((0b11 < 3)); - SSE_CHECK_AND_SET((0b11 < 17)) - SSE_CHECK_AND_SET((0b111 < 5)); - - __sse_xsetbv(sse_control); -} - -std::uint64_t sse::size() { - return __sse_size; -} - -void sse::save(std::uint8_t* buf) { - if(__sse_legacy_save) - asm volatile("fxsave (%0)" : : "r"(buf)); - else - __sse_xsave(buf); -} - -void sse::load(std::uint8_t* buf) { - if(__sse_legacy_save) - asm volatile("fxrstor (%0)" : : "r"(buf)); - else - __sse_xrstor(buf); -}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/cpu_local.hpp b/kernel/src/arch/x86_64/cpu_local.hpp new file mode 100644 index 0000000..13bca71 --- /dev/null +++ b/kernel/src/arch/x86_64/cpu_local.hpp @@ -0,0 +1,45 @@ + +#include <cstdint> + +#pragma once + +#include <arch/x86_64/cpu_local.hpp> +#include <arch/x86_64/assembly.hpp> +#include <klibc/string.hpp> +#include <klibc/stdio.hpp> +#include <generic/arch.hpp> + +typedef struct { + std::uint64_t user_stack; + std::uint64_t kernel_stack; + std::uint64_t timer_ist_stack; + std::uint64_t tsc_freq; +} cpudata_t; + +namespace x86_64 { + + inline std::uint64_t cpu_data_const = 0; + + inline static void init_cpu_data() { + std::uint64_t cpudata = assembly::rdmsr(0xC0000101); + if(!cpudata) { + cpudata = (std::uint64_t)new cpudata_t; + cpu_data_const = cpudata; + klibc::memset((void*)cpudata,0,sizeof(cpudata_t)); + assembly::wrmsr(0xC0000101,cpudata); + } + } + + inline static void restore_cpu_data() { + assembly::wrmsr(0xC0000101,cpu_data_const); + } + + inline static cpudata_t* cpu_data() { + std::uint64_t cpudata = assembly::rdmsr(0xC0000101); + if(!cpudata) { + klibc::printf("cpudata: fdgkldfglfkdfdjnbdff\r\n"); + arch::hcf(); + } + return (cpudata_t*)cpudata; + } +}; diff --git a/kernel/src/arch/x86_64/drivers/hpet.cpp b/kernel/src/arch/x86_64/drivers/hpet.cpp new file mode 100644 index 0000000..152f0d9 --- /dev/null +++ b/kernel/src/arch/x86_64/drivers/hpet.cpp @@ -0,0 +1,58 @@ +#include <cstdint> +#include <drivers/acpi.hpp> +#include <utils/gobject.hpp> +#include <generic/time.hpp> +#include <generic/arch.hpp> +#include <arch/x86_64/drivers/hpet.hpp> +#include <klibc/stdio.hpp> +#include <uacpi/uacpi.h> +#include <uacpi/tables.h> +#include <uacpi/status.h> +#include <uacpi/acpi.h> +#include <generic/hhdm.hpp> +#include <generic/paging.hpp> + +std::uint64_t hpet_base,hpet_clock_nano; +std::uint8_t hpet_is_32_bit = 0; + +std::uint64_t __hpet_timestamp() { + return hpet_is_32_bit ? *(volatile uint32_t*)(hpet_base + 0xf0) : *(volatile uint64_t*)(hpet_base + 0xf0); +} + +void drivers::hpet::init() { + uacpi_table hpet; + uacpi_status ret = uacpi_table_find_by_signature("HPET",&hpet); + if(ret != UACPI_STATUS_OK) { + klibc::printf("HPET: hpet is not detected with status %d\r\n",ret); + return; + } + + struct acpi_hpet* hpet_table = ((struct acpi_hpet*)hpet.virt_addr); + hpet_base = (std::uint64_t)(hpet_table->address.address + etc::hhdm()); + paging::map_range(gobject::kernel_root,hpet_table->address.address,hpet_table->address.address + etc::hhdm(),PAGE_SIZE,PAGING_PRESENT | PAGING_RW); + + *(volatile std::uint64_t*)(hpet_base + 0x10) |= 1; + hpet_is_32_bit = (*(volatile uint64_t*)hpet_base & (1 << 13)) ? 0 : 1; + hpet_clock_nano = (*(volatile uint32_t*)(hpet_base + 4)) / 1000000; + hpet_timer* new_hpet_inst = new hpet_timer; + time::setup_timer(new_hpet_inst); + klibc::printf("HPET: Detected %s hpet, current timestamp in nano %lli (hpet_base 0x%p)\r\n",hpet_is_32_bit ? "32 bit" : "64 bit", new_hpet_inst->current_nano(),hpet_base); +} + +namespace drivers { + void hpet_timer::sleep(std::uint64_t us) { + std::uint64_t start = __hpet_timestamp(); + std::uint64_t conv = us * 1000; + while((__hpet_timestamp() - start) * hpet_clock_nano < conv) + asm volatile("nop"); + } + + + std::uint64_t hpet_timer::current_nano() { + return __hpet_timestamp() * hpet_clock_nano; + } + + int hpet_timer::get_priority() { + return 10; + } +};
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/drivers/hpet.hpp b/kernel/src/arch/x86_64/drivers/hpet.hpp new file mode 100644 index 0000000..b8f2b29 --- /dev/null +++ b/kernel/src/arch/x86_64/drivers/hpet.hpp @@ -0,0 +1,18 @@ +#pragma once +#include <cstdint> +#include <generic/time.hpp> + +namespace drivers { + + class hpet_timer final : public time::generic_timer { + public: + int get_priority() override; + std::uint64_t current_nano() override; + void sleep(std::uint64_t us) override; + }; + + class hpet { + public: + static void init(); + }; +};
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/drivers/io.hpp b/kernel/src/arch/x86_64/drivers/io.hpp new file mode 100644 index 0000000..5314124 --- /dev/null +++ b/kernel/src/arch/x86_64/drivers/io.hpp @@ -0,0 +1,40 @@ +#pragma once +#include <cstdint> + +namespace x86_64 { + namespace io { + inline void outb(std::uint16_t port, std::uint8_t val) { + __asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port) : "memory"); + } + + inline void outw(std::uint16_t port, std::uint16_t val) { + __asm__ volatile("outw %0, %1" : : "a"(val), "Nd"(port) : "memory"); + } + + inline void outd(std::uint16_t port, std::uint32_t val) { + __asm__ volatile("outl %0, %1" : : "a"(val), "Nd"(port) : "memory"); + } + + inline std::uint8_t inb(std::uint16_t port) { + std::uint8_t ret; + __asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port) : "memory"); + return ret; + } + + inline std::uint16_t inw(std::uint16_t port) { + std::uint16_t ret; + __asm__ volatile("inw %1, %0" : "=a"(ret) : "Nd"(port) : "memory"); + return ret; + } + + inline std::uint32_t ind(std::uint16_t port) { + std::uint32_t ret; + __asm__ volatile("inl %1, %0" : "=a"(ret) : "Nd"(port) : "memory"); + return ret; + } + + inline void wait() { + outb(0x80, 0); + } + }; +}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/drivers/pci.hpp b/kernel/src/arch/x86_64/drivers/pci.hpp new file mode 100644 index 0000000..4474997 --- /dev/null +++ b/kernel/src/arch/x86_64/drivers/pci.hpp @@ -0,0 +1,42 @@ +#include <arch/x86_64/drivers/io.hpp> +#include <cstdint> + +namespace x86_64 { + namespace pci { + inline std::uint32_t pci_read_config32(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset) { + std::uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset); + x86_64::io::outd(0xCF8, address); + return x86_64::io::ind(0xCFC); + } + + inline std::uint16_t pci_read_config16(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset) { + std::uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset & 0xfc); + x86_64::io::outd(0xCF8, address); + return (std::uint16_t)((x86_64::io::ind(0xCFC) >> ((offset & 2) * 8)) & 0xffff); + } + + inline std::uint8_t pci_read_config8(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset) { + std::uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset); + x86_64::io::outd(0xCF8, address); + return (std::uint8_t)((x86_64::io::ind(0xCFC) >> ((offset & 3) * 8)) & 0xff); + } + + inline void pci_write_config32(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset, std::uint32_t value) { + std::uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset); + x86_64::io::outd(0xCF8, address); + x86_64::io::outd(0xCFC, value); + } + + inline void pci_write_config16(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset, std::uint32_t value) { + uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset & 0xfc); + x86_64::io::outd(0xCF8, address); + x86_64::io::outd(0xCFC,(x86_64::io::ind(0xCFC) & ~(0xffff << ((offset & 2) * 8))) | (value << ((offset & 2) * 8))); + } + + inline void pci_write_config8(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset, std::uint8_t value) { + std::uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset & 0xfc); + x86_64::io::outd(0xCF8, address); + x86_64::io::outd(0xCFC, ((x86_64::io::ind(0xCFC) & ~(0xFF << (offset & 3))) | (value << ((offset & 3) * 8)))); + } + }; +};
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/drivers/tsc.cpp b/kernel/src/arch/x86_64/drivers/tsc.cpp new file mode 100644 index 0000000..fbb6fad --- /dev/null +++ b/kernel/src/arch/x86_64/drivers/tsc.cpp @@ -0,0 +1,113 @@ +#define BILLION 1000000000UL +#include <cstdint> +#include <drivers/acpi.hpp> +#include <arch/x86_64/drivers/tsc.hpp> +#include <arch/x86_64/cpu_local.hpp> +#include <utils/gobject.hpp> +#include <klibc/stdio.hpp> + +#include <generic/arch.hpp> + +static inline uint64_t rdtsc() { + uint32_t lo, hi; + __asm__ volatile ("rdtsc" : "=a"(lo), "=d"(hi)); + return ((uint64_t)hi << 32) | lo; +} + +void drivers::tsc::init() { + + if(time::timer == nullptr) { + klibc::printf("TSC: Can't initialize without timer !\n"); + } + + uint64_t tsc_start, tsc_end; + std::uint64_t time_start,time_end; + + tsc_start = rdtsc(); + time_start = time::timer->current_nano(); + + time::timer->sleep(100000); + + tsc_end = rdtsc(); + time_end = time::timer->current_nano(); + + uint64_t time_ns = time_end - time_start; + uint64_t tsc_diff = tsc_end - tsc_start; + + uint64_t tsc_freq; + + if (tsc_diff > UINT64_MAX / BILLION) { + uint64_t tsc_high = tsc_diff >> 32; + uint64_t tsc_low = tsc_diff & 0xFFFFFFFF; + + uint64_t temp_high = (tsc_high * BILLION) >> 32; + uint64_t temp_low = (tsc_high * BILLION) << 32; + if (temp_low < (tsc_high * BILLION)) temp_high++; + + uint64_t temp = temp_low + tsc_low * BILLION; + if (temp < tsc_low * BILLION) temp_high++; + + tsc_freq = (temp / time_ns + (temp_high / time_ns)) << 32; + } else { + tsc_freq = (tsc_diff * BILLION) / time_ns; + } + + x86_64::cpu_data()->tsc_freq = tsc_freq; + + klibc::printf("TSC: TSC Frequency is %llu\r\n", tsc_freq); + drivers::tsc_timer* tsc_timer = new drivers::tsc_timer; + time::setup_timer(tsc_timer); +} + +namespace drivers { + void tsc_timer::sleep(std::uint64_t us) { + std::uint64_t current = this->current_nano(); + std::uint64_t end_ns = us * 1000; + std::uint64_t target = current + end_ns; + + while(this->current_nano() < target) { + arch::pause(); + } + } + + std::uint64_t tsc_timer::current_nano() { + std::uint64_t freq = x86_64::cpu_data()->tsc_freq; + + if(freq == 0) { // redirect to previous timer + if(time::previous_timer) { + return time::previous_timer->current_nano(); + } else { + klibc::printf("TSC: Trying to get current nano timestamp without any timer from non calibrated tsc !\n"); + return 0; + } + } + + uint32_t lo, hi; + asm volatile ("rdtsc" : "=a"(lo), "=d"(hi)); + std::uint64_t tsc_v = ((uint64_t)hi << 32) | lo; + + if (tsc_v > UINT64_MAX / BILLION) { + uint64_t high = tsc_v >> 32; + uint64_t low = tsc_v & 0xFFFFFFFF; + + uint64_t high_part = (high * BILLION) / freq; + uint64_t high_rem = (high * BILLION) % freq; + + uint64_t low_part = (low * BILLION) / freq; + uint64_t low_rem = (low * BILLION) % freq; + + uint64_t result = (high_part << 32) + low_part; + + uint64_t total_rem = (high_rem << 32) + low_rem; + result += total_rem / freq; + + return result; + } else { + return (tsc_v * BILLION) / freq; + } + } + + int tsc_timer::get_priority() { + return 9999999; // undertale reference + } +}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/drivers/tsc.hpp b/kernel/src/arch/x86_64/drivers/tsc.hpp new file mode 100644 index 0000000..0ac44bd --- /dev/null +++ b/kernel/src/arch/x86_64/drivers/tsc.hpp @@ -0,0 +1,19 @@ +#pragma once +#include <cstdint> +#include <generic/time.hpp> + +namespace drivers { + + class tsc_timer final : public time::generic_timer { + public: + int get_priority() override; + std::uint64_t current_nano() override; + void sleep(std::uint64_t us) override; + }; + + class tsc { + public: + static void init(); + static void init_bsp(); + }; +};
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/interrupts/irq.cpp b/kernel/src/arch/x86_64/interrupts/irq.cpp deleted file mode 100644 index 7b7c5d4..0000000 --- a/kernel/src/arch/x86_64/interrupts/irq.cpp +++ /dev/null @@ -1,94 +0,0 @@ - -#include <cstdint> -#include <arch/x86_64/interrupts/irq.hpp> -#include <arch/x86_64/interrupts/idt.hpp> -#include <arch/x86_64/interrupts/pic.hpp> -#include <arch/x86_64/cpu/lapic.hpp> -#include <generic/mm/paging.hpp> -#include <drivers/ioapic.hpp> -#include <etc/libc.hpp> - -#include <generic/vfs/vfs.hpp> - -#include <etc/logging.hpp> - -irq_t irq_table[255]; -std::uint16_t irq_ptr = 0; - -std::uint8_t is_legacy_pic = 1; - -extern "C" void* irqTable[]; - -extern "C" void irqHandler(int_frame_t* ctx) { - - if(ctx->cs != 0x08) - asm volatile("swapgs"); - - memory::paging::enablekernel(); - if(!irq_table[ctx->vec - 1].is_userspace) - irq_table[ctx->vec - 1].func(irq_table[ctx->vec - 1].arg); - else { - - if(irq_table[ctx->vec - 1].irq == 1) { // irq 12 and irq 1 are connected together - drivers::ioapic::mask(12); - } else if(irq_table[ctx->vec - 1].irq == 12) { - drivers::ioapic::mask(1); - } else - drivers::ioapic::mask(irq_table[ctx->vec - 1].irq); /* Mask */ - - userspace_fd_t fd; - fd.is_cached_path = 0; - memset(fd.path,0,sizeof(fd.path)); - __printfbuf(fd.path,sizeof(fd.path),"/dev/masterirq%d",irq_table[ctx->vec - 1].irq); - - char i = 1; - int status = vfs::vfs::write(&fd,&i,1); - } - - arch::x86_64::cpu::lapic::eoi(); - - if(ctx->cs & 3) - ctx->ss |= 3; - - if(ctx->ss & 3) - ctx->cs |= 3; - - if(ctx->cs == 0x20) - ctx->cs |= 3; - - if(ctx->ss == 0x18) - ctx->ss |= 3; - - if(ctx->cs != 0x08) - asm volatile("swapgs"); - -} - -void arch::x86_64::interrupts::irq::reset() { - irq_ptr = 0; - memset(irq_table,0,sizeof(irq_table)); -} - -std::uint8_t arch::x86_64::interrupts::irq::create(std::uint16_t irq,std::uint8_t type,void (*func)(void* arg),void* arg,std::uint64_t flags) { - uint8_t entry = 0; - - if(!is_legacy_pic) { - entry = arch::x86_64::interrupts::idt::alloc(); - arch::x86_64::interrupts::idt::set_entry((std::uint64_t)irqTable[entry - 0x20],entry,0x8E,3); - if(type == IRQ_TYPE_LEGACY_USERSPACE) - irq_table[irq_ptr].is_userspace = 1; - - drivers::ioapic::set(entry,irq,0,arch::x86_64::cpu::lapic::id()); - } else { - arch::x86_64::interrupts::idt::set_entry((std::uint64_t)irqTable[irq],irq + 0x20,0x8E,3); - irq_table[irq].arg = arg; - - irq_table[irq].func = func; - return irq + 0x20; - } - - irq_table[irq_ptr].arg = arg; - irq_table[irq_ptr].irq = irq; - irq_table[irq_ptr++].func = func; - return entry; -}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/interrupts/panic.cpp b/kernel/src/arch/x86_64/interrupts/panic.cpp deleted file mode 100644 index 237d03a..0000000 --- a/kernel/src/arch/x86_64/interrupts/panic.cpp +++ /dev/null @@ -1,216 +0,0 @@ -#include <cstdint> -#include <arch/x86_64/interrupts/idt.hpp> -#include <etc/logging.hpp> - -#include <arch/x86_64/cpu/data.hpp> - -#include <generic/locks/spinlock.hpp> - -#include <etc/bootloaderinfo.hpp> -#include <generic/mm/vmm.hpp> - -#include <arch/x86_64/scheduling.hpp> - -#include <generic/vfs/fd.hpp> - -#include <generic/mm/paging.hpp> - -typedef struct stackframe { - struct stackframe* rbp; - uint64_t rip; -} __attribute__((packed)) stackframe_t; - -int is_panic = 0; -int last_sys = 0; -extern std::int64_t __memory_paging_getphys(std::uint64_t cr3, std::uint64_t virt); - -void panic(int_frame_t* ctx, const char* msg) { - - memory::paging::enablekernel(); - if(is_panic) - asm volatile("hlt"); - - if(ctx) { - if(ctx->cs != 0x08) - asm volatile("swapgs"); - } - - arch::x86_64::process_t* proc = arch::x86_64::cpu::data()->temp.proc; - if(proc && 1 && ctx) { - uint64_t cr2; - asm volatile("mov %%cr2, %0" : "=r"(cr2) : : "memory"); - - vmm_obj_t* current1 = (vmm_obj_t*)proc->vmm_start; - current1->lock.unlock(); - - vmm_obj_t* obj = memory::vmm::getlen(proc,ctx->rip); - - - if(ctx->vec == 14) { - vmm_obj_t* obj0 = memory::vmm::getlen(proc,cr2); - - if(proc && cr2 == 0 && proc->sigtrace_obj && ctx->err_code == 0x14) { - arch::x86_64::scheduling::sigreturn(proc); - } - - if(obj0) { - if(obj0->is_lazy_alloc && !obj0->is_free) { - - if(__memory_paging_getphys(proc->original_cr3,cr2) == -1) { - std::uint64_t new_phys = memory::pmm::_physical::alloc(4096); - memory::paging::map(proc->original_cr3,new_phys,ALIGNDOWN(cr2,4096),obj0->flags); - } - - if(ctx->cs & 3) - ctx->ss |= 3; - - if(ctx->ss & 3) - ctx->cs |= 3; - - if(ctx->cs == 0x20) - ctx->cs |= 3; - - if(ctx->ss == 0x18) - ctx->ss |= 3; - - if(ctx->cs != 0x08) - asm volatile("swapgs"); - - schedulingEnd(ctx); - } else if(!obj0->is_free && cr2 > 0x1000) { - Log::SerialDisplay(LEVEL_MESSAGE_WARN,"tlb invalid :( 0x%p is_mapped %d phys 0x%p base 0x%p ",cr2,obj0->is_mapped,obj0->phys,obj0->base); - memory::paging::maprange(proc->original_cr3,obj0->phys,obj0->base,obj0->len,obj0->flags); - if(ctx->cs & 3) - ctx->ss |= 3; - - if(ctx->ss & 3) - ctx->cs |= 3; - - if(ctx->cs == 0x20) - ctx->cs |= 3; - - if(ctx->ss == 0x18) - ctx->ss |= 3; - - if(ctx->cs != 0x08) - asm volatile("swapgs"); - - schedulingEnd(ctx); - } else if(1) { - Log::SerialDisplay(LEVEL_MESSAGE_INFO,"aaa\n"); - } - } - - } - - Log::Display(LEVEL_MESSAGE_FAIL,"process %d (%s) fired cpu exception with vec %d, rip 0x%p (offset 0x%p), cr2 0x%p, error code 0x%p, lastsys %d, rdx 0x%p rbp 0x%p\n",proc->id,proc->name,ctx->vec,ctx->rip,ctx->rip - 0x41400000,cr2,ctx->err_code,proc->sys,ctx->rdx,ctx->rbp); - - Log::Raw("RAX: 0x%016llX RBX: 0x%016llX RDX: 0x%016llX RCX: 0x%016llX RDI: 0x%016llX\n" - "RSI: 0x%016llX R8: 0x%016llX R9: 0x%016llX R10: 0x%016llX R11: 0x%016llX\n" - "R12: 0x%016llX R13: 0x%016llX R14: 0x%016llX R15: 0x%016llX RBP: 0x%016llX\n" - "RSP: 0x%016llX CR2: 0x%016llX CR3: 0x%016llX\n" - "CPU: %d Vec: %d Err: %d Last Syscall: %d cs %d\n", - ctx->rax, ctx->rbx, ctx->rdx, ctx->rcx, ctx->rdi, - ctx->rsi, ctx->r8, ctx->r9, ctx->r10, ctx->r11, - ctx->r12, ctx->r13, ctx->r14, ctx->r15, ctx->rbp, - ctx->rsp, cr2, ctx->cr3, - arch::x86_64::cpu::data()->smp.cpu_id, ctx->vec, ctx->err_code,arch::x86_64::cpu::data()->last_sys,ctx->cs); - - vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; - - while(1) { - - Log::SerialDisplay(LEVEL_MESSAGE_INFO,"Memory 0x%p-0x%p (with offset rip 0x%p)\n",current->base,current->base + current->len, ctx->rip - current->base); - - if (current->base == (std::uint64_t)Other::toVirt(0) - 4096) - break; - - current = current->next; - - } - - asm volatile("hlt"); - - stackframe_t* rbp = (stackframe_t*)ctx->rbp; - - memory::paging::enablepaging(ctx->cr3); - Log::SerialDisplay(LEVEL_MESSAGE_INFO,"[0] - 0x%016llX (current rip)\n",ctx->rip); - for (int i = 1; i < 10 && rbp; ++i) { - std::uint64_t ret_addr = rbp->rip; - Log::SerialDisplay(LEVEL_MESSAGE_INFO,"[%d] - 0x%016llX\n", i, ret_addr); - rbp = (stackframe_t*)rbp->rbp; - } - memory::paging::enablekernel(); - - arch::x86_64::scheduling::kill(proc); - - if(1) - memory::vmm::free(proc); - - vfs::fdmanager* fd = (vfs::fdmanager*)proc->fd; - fd->free(); - - memory::pmm::_virtual::free(proc->cwd); - memory::pmm::_virtual::free(proc->name); - memory::pmm::_virtual::free(proc->sse_ctx); - - arch::x86_64::scheduling::kill(proc); - schedulingSchedule(0); - } - - int_frame_t test_ctx = {0}; - - if(!ctx) - ctx = &test_ctx; - - is_panic = 1; - - extern locks::spinlock log_lock; - log_lock.unlock(); - - uint64_t cr2; - asm volatile("mov %%cr2, %0" : "=r"(cr2) : : "memory"); - - Log::Display(LEVEL_MESSAGE_FAIL,R"EOF( - - ) - ( /( ( ( - )\()) ( ) ( ( ( ( )\ ) ( ) )\ ) -((_)\ )( ( /( ( )\))( ))\ )\ ( (()/( ))\( /( (()/( __ - ((_)(()\ )(_)) )\ )((_))\ /((_) ((_))\ ((_))((_)(_)) ((_)) _ / / - / _ \ ((_|(_)_ _(_/( (()(_|_)) (_|(_) _| (_))((_)_ _| | (_) | -| (_) | '_/ _` | ' \)) _` |/ -_) | (_-< / _` / -_) _` / _` | _| | - \___/|_| \__,_|_||_|\__, |\___| |_/__/ \__,_\___\__,_\__,_| (_)\_\ - |___/ - - )EOF"); - - Log::Raw("Kernel panic\n\nReason: %s\n",msg); - Log::Raw("RAX: 0x%016llX RBX: 0x%016llX RDX: 0x%016llX RCX: 0x%016llX RDI: 0x%016llX\n" - "RSI: 0x%016llX R8: 0x%016llX R9: 0x%016llX R10: 0x%016llX R11: 0x%016llX\n" - "R12: 0x%016llX R13: 0x%016llX R14: 0x%016llX R15: 0x%016llX RBP: 0x%016llX\n" - "RSP: 0x%016llX CR2: 0x%016llX CR3: 0x%016llX\n" - "CPU: %d Vec: %d Err: %d Last Syscall: %d cs: %p ss: %p\n", - ctx->rax, ctx->rbx, ctx->rdx, ctx->rcx, ctx->rdi, - ctx->rsi, ctx->r8, ctx->r9, ctx->r10, ctx->r11, - ctx->r12, ctx->r13, ctx->r14, ctx->r15, ctx->rbp, - ctx->rsp, cr2, ctx->cr3, - arch::x86_64::cpu::data()->smp.cpu_id, ctx->vec, ctx->err_code,arch::x86_64::cpu::data()->last_sys,ctx->cs,ctx->ss); - Log::Raw("\n Stacktrace\n\n"); - - stackframe_t* rbp = (stackframe_t*)ctx->rbp; - - Log::Raw("[0] - 0x%016llX (current rip)\n",ctx->rip); - for (int i = 1; i < 5 && rbp; ++i) { - std::uint64_t ret_addr = rbp->rip; - Log::Raw("[%d] - 0x%016llX\n", i, ret_addr); - rbp = (stackframe_t*)rbp->rbp; - } - - - asm volatile("hlt"); -} - -extern "C" void CPUKernelPanic(int_frame_t* ctx) { - panic(ctx,"\"cpu exception\""); -}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/interrupts/pit.cpp b/kernel/src/arch/x86_64/interrupts/pit.cpp deleted file mode 100644 index 5154537..0000000 --- a/kernel/src/arch/x86_64/interrupts/pit.cpp +++ /dev/null @@ -1,31 +0,0 @@ - -#include <cstdint> -#include <arch/x86_64/interrupts/pic.hpp> -#include <arch/x86_64/interrupts/irq.hpp> -#include <arch/x86_64/interrupts/pit.hpp> -#include <drivers/hpet.hpp> - -using namespace arch::x86_64::interrupts; - -std::uint64_t pit_counter = 0; - -void __pit_int_handler(void *arg) { - pit_counter++; -} - -void arch::x86_64::interrupts::pit::init() { - drivers::io io; - std::uint8_t entry = irq::create(0,IRQ_TYPE_LEGACY,__pit_int_handler,0,0); - std::uint32_t div = PIT_FREQUENCY / 1000; - io.outb(0x43, 0x36); - io.outb(0x40,div & 0xFF); - io.outb(0x40,(div >> 8) & 0xFF); - - pic::clear(0); - -} - -/* idk why but pit sleep is broken on modern hw, redirect to hpet */ -void arch::x86_64::interrupts::pit::sleep(std::uint32_t ms) { - drivers::hpet::sleep(ms); -}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/paging.cpp b/kernel/src/arch/x86_64/paging.cpp new file mode 100644 index 0000000..3437889 --- /dev/null +++ b/kernel/src/arch/x86_64/paging.cpp @@ -0,0 +1,161 @@ +#include <cstdint> +#include <generic/arch.hpp> +#include <generic/bootloader/bootloader.hpp> +#include <generic/hhdm.hpp> +#include <generic/pmm.hpp> + +#define PTE_MASK_VALUE_5 0x000ffffffffffff000 +#define PTE_MASK_VALUE 0x000ffffffffff000 +#define PTE_PRESENT (1 << 0) +#define PTE_RW (1 << 1) +#define PTE_USER (1 << 2) +#define PTE_WC ((1 << 7) | (1 << 3)) +#define PTE_MMIO (1ull << 4) +#define LVL_PG_MASK (bootloader::bootloader->is_5_level_paging() ? PTE_MASK_VALUE_5 : PTE_MASK_VALUE) + +int level_to_index(std::uintptr_t virt, int level) { + if(bootloader::bootloader->is_5_level_paging()) { + switch (level) { + case 0: return PTE_INDEX(virt, 48); + case 1: return PTE_INDEX(virt, 39); + case 2: return PTE_INDEX(virt, 30); + case 3: return PTE_INDEX(virt, 21); + case 4: return PTE_INDEX(virt, 12); + default: return 0; + } + } else { + switch (level) { + case 0: return PTE_INDEX(virt, 39); + case 1: return PTE_INDEX(virt, 30); + case 2: return PTE_INDEX(virt, 21); + case 3: return PTE_INDEX(virt, 12); + default: return 0; + } + } + return 0; +} + +int64_t* __paging_next_level_noalloc(std::uint64_t* table, std::uint16_t idx) { + if (!(table[idx] & PTE_PRESENT)) + return (int64_t*) -1; + return (int64_t*) ((table[idx] & LVL_PG_MASK) + etc::hhdm()); +} + +std::int64_t __memory_paging_getphys(std::uint64_t* table, std::uint64_t virt, int level) { + if (!table && (std::int64_t) table == -1) + return -1; + int max_level = bootloader::bootloader->is_5_level_paging() ? 4 : 3; + if (max_level == level) { + return (table[level_to_index(virt, level)] & PTE_PRESENT) ? table[level_to_index(virt, level)] & LVL_PG_MASK : -1; + } else + return __memory_paging_getphys((std::uint64_t*) __paging_next_level_noalloc(table, level_to_index(virt, level)), virt, level + 1); + return -1; +} + +uint64_t* x86_64_paging_next_level(std::uint64_t* table, std::uint16_t idx, std::uint64_t flags) { + if (!(table[idx] & PTE_PRESENT)) + table[idx] = pmm::freelist::alloc_4k() | flags; + return (uint64_t*) ((table[idx] & LVL_PG_MASK) + etc::hhdm()); +} + +std::uint64_t convert_flags(std::uint64_t flags) { + std::uint64_t result = 0; + if (flags & PAGING_NC) + result |= PTE_MMIO; + if (flags & PAGING_PRESENT) + result |= PTE_PRESENT; + if (flags & PAGING_RW) + result |= PTE_RW; + if (flags & PAGING_USER) + result |= PTE_USER; + if (flags & PAGING_WC) + result |= PTE_WC; + return result; +} + +void x86_64_map_page(std::uintptr_t root, std::uintptr_t phys, std::uintptr_t virt, std::uint32_t flags) { + std::uint64_t* cr30 = (std::uint64_t*) (root + etc::hhdm()); + std::uint64_t new_flags = PTE_PRESENT | PTE_RW; + if (bootloader::bootloader->is_5_level_paging()) { + if (PTE_INDEX(virt, 48) < 256) + new_flags |= PTE_USER; + uint64_t* pml4 = x86_64_paging_next_level(cr30, PTE_INDEX(virt, 48), new_flags); + uint64_t* pml3 = x86_64_paging_next_level(pml4, PTE_INDEX(virt, 39), new_flags); + uint64_t* pml2 = x86_64_paging_next_level(pml3, PTE_INDEX(virt, 30), new_flags); + uint64_t* pml = x86_64_paging_next_level(pml2, PTE_INDEX(virt, 21), new_flags); + pml[PTE_INDEX(virt, 12)] = phys | flags; + } else { + if (PTE_INDEX(virt, 39) < 256) + new_flags |= PTE_USER; + uint64_t* pml3 = x86_64_paging_next_level(cr30, PTE_INDEX(virt, 39), new_flags); + uint64_t* pml2 = x86_64_paging_next_level(pml3, PTE_INDEX(virt, 30), new_flags); + uint64_t* pml = x86_64_paging_next_level(pml2, PTE_INDEX(virt, 21), new_flags); + pml[PTE_INDEX(virt, 12)] = phys | flags; + } +} + + +namespace arch { + [[gnu::weak]] void enable_paging(std::uintptr_t root) { + asm volatile("mov %0, %%cr3" : : "r"(root) : "memory"); + } + + [[gnu::weak]] void map_page(std::uintptr_t root, std::uint64_t phys, std::uintptr_t virt, int flags) { + x86_64_map_page(root,phys,virt,convert_flags(flags)); + } + + [[gnu::weak]] std::uint64_t get_phys_from_page(std::uintptr_t root, std::uintptr_t virt) { + return __memory_paging_getphys((std::uint64_t*)(root + etc::hhdm()),virt,0); + } + + [[gnu::weak]] void destroy_root(std::uintptr_t root, int level) { + std::uint64_t* table = (std::uint64_t*) (root + etc::hhdm()); + if (bootloader::bootloader->is_5_level_paging()) { + if (level != 4) { + if (level == 0) { + for (int i = 0; i < 256; i++) { + if (table[i] & PTE_PRESENT) { + destroy_root(table[i] & PTE_MASK_VALUE, level + 1); + } + } + } else { + for (int i = 0; i < 512; i++) { + if (table[i] & PTE_PRESENT) { + destroy_root(table[i] & PTE_MASK_VALUE, level + 1); + } + } + } + } + + if (level != 0) + pmm::freelist::free(root); + } else { + if (level != 3) { + if (level == 0) { + for (int i = 0; i < 256; i++) { + if (table[i] & PTE_PRESENT) { + destroy_root(table[i] & PTE_MASK_VALUE, level + 1); + } + } + } else { + for (int i = 0; i < 512; i++) { + if (table[i] & PTE_PRESENT) { + destroy_root(table[i] & PTE_MASK_VALUE, level + 1); + } + } + } + } + + if (level != 0) + pmm::freelist::free(root); + } + } + + [[gnu::weak]] void copy_higher_half(std::uintptr_t root, std::uintptr_t src_root) { + std::uint64_t* virt_rootcr3 = (std::uint64_t*) (root + etc::hhdm()); + std::uint64_t* virt_srccr3 = (std::uint64_t*) (src_root + etc::hhdm()); + for (int i = 255; i < 512; i++) { + virt_rootcr3[i] = virt_srccr3[i]; + } + } +};
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/scheduling.cpp b/kernel/src/arch/x86_64/scheduling.cpp deleted file mode 100644 index 13f4300..0000000 --- a/kernel/src/arch/x86_64/scheduling.cpp +++ /dev/null @@ -1,1103 +0,0 @@ - -#include <cstdint> -#include <arch/x86_64/scheduling.hpp> -#include <generic/vfs/vfs.hpp> - -#include <arch/x86_64/cpu/sse.hpp> - -#include <generic/locks/spinlock.hpp> - -#include <generic/mm/pmm.hpp> -#include <generic/mm/vmm.hpp> - -#include <arch/x86_64/cpu/data.hpp> -#include <arch/x86_64/interrupts/idt.hpp> -#include <arch/x86_64/cpu/lapic.hpp> - -#include <generic/vfs/fd.hpp> - -#include <etc/libc.hpp> -#include <etc/list.hpp> - -#include <generic/time.hpp> - -#include <etc/logging.hpp> - -#include <atomic> - -#include <etc/errno.hpp> - -#include <config.hpp> - -arch::x86_64::process_t* head_proc; -std::uint32_t id_ptr = 0; - -locks::spinlock process_lock; - -#define PUT_STACK(dest,value) *--dest = value; -#define PUT_STACK_STRING(dest,string) memcpy(dest,string,strlen(string)); - - -uint64_t __elf_get_length(char** arr) { - uint64_t counter = 0; - - while(arr[counter]) { - counter++; - char* t = (char*)(arr[counter - 1]); - if(*t == '\0') - return counter - 1; // invalid - } - - return counter; -} - -uint64_t __stack_memcpy(std::uint64_t stack, void* src, uint64_t len) { - std::uint64_t _stack = stack; - _stack -= 8; - _stack -= ALIGNUP(len,8); - memcpy((void*)_stack,src,len); - return (std::uint64_t)_stack; -} - -uint64_t* __elf_copy_to_stack(char** arr,uint64_t* stack,char** out, uint64_t len) { - - uint64_t* temp_stack = stack; - - for(uint64_t i = 0;i < len; i++) { - temp_stack -= ALIGNUP(strlen(arr[i]),8); - PUT_STACK_STRING(temp_stack,arr[i]) - out[i] = (char*)temp_stack; - PUT_STACK(temp_stack,0); - } - - return temp_stack; - -} - -uint64_t* __elf_copy_to_stack_without_out(uint64_t* arr,uint64_t* stack,uint64_t len) { - - uint64_t* _stack = stack; - - for(uint64_t i = 0;i < len;i++) { - PUT_STACK(_stack,arr[i]); - } - - return _stack; - -} - -elfloadresult_t __scheduling_load_elf(arch::x86_64::process_t* proc, std::uint8_t* base) { - elfheader_t* head = (elfheader_t*)base; - elfprogramheader_t* current_head; - std::uint64_t elf_base = UINT64_MAX; - std::uint64_t size = 0; - std::uint64_t phdr = 0; - - std::uint64_t highest_addr = 0; - char interp_path[2048]; - - char ELF[4] = {0x7F,'E','L','F'}; - if(strncmp((const char*)head->e_ident,ELF,4)) { - return {0,0,0,0,0,ENOENT}; - } - - elfloadresult_t elfload; - elfload.real_entry = head->e_entry; - elfload.interp_entry = head->e_entry; - elfload.phnum = head->e_phnum; - elfload.phentsize = head->e_phentsize; - - if(head->e_type != ET_DYN) { - for(int i = 0; i < head->e_phnum; i++) { - current_head = (elfprogramheader_t*)((uint64_t)base + head->e_phoff + head->e_phentsize*i); - if (current_head->p_type == PT_LOAD) { - elf_base = MIN2(elf_base, ALIGNDOWN(current_head->p_vaddr, PAGE_SIZE)); - highest_addr = MAX2(highest_addr, ALIGNUP(current_head->p_vaddr + current_head->p_memsz, PAGE_SIZE)); - } - } - } - - for(int i = 0;i < head->e_phnum; i++) { - uint64_t start = 0, end = 0; - current_head = (elfprogramheader_t*)((uint64_t)base + head->e_phoff + head->e_phentsize*i); - - if(current_head->p_type == PT_PHDR) { - phdr = current_head->p_vaddr; - elfload.phdr = phdr; - } - - if (current_head->p_type == PT_LOAD) { - end = current_head->p_vaddr - elf_base + current_head->p_memsz; - size = MAX2(size, end); - } - } - - void* elf_vmm; - - DEBUG(1,"proc cr3 0x%p",proc->original_cr3); - - size = ALIGNPAGEUP(size); - - if(head->e_type != ET_DYN) { - assert(!(memory::vmm::getlen(proc,elf_base)),"memory 0x%p is not avaiable !",elf_base); - elf_vmm = memory::vmm::customalloc(proc, elf_base , size, PTE_PRESENT | PTE_RW | PTE_USER, 0,1); - assert((std::uint64_t)elf_vmm == elf_base,"0x%p is not equal 0x%p",elf_vmm,elf_base); - elfload.base = (uint64_t)elf_base; - } else { - elf_vmm = memory::vmm::alloc(proc, size, PTE_PRESENT | PTE_RW | PTE_USER, 0); - elfload.base = (uint64_t)elf_vmm; - } - - memory::vmm::invmapping(proc,(std::uint64_t)elf_vmm,size); - - uint8_t* allocated_elf = (uint8_t*)elf_vmm; - - memory::paging::enablepaging(proc->original_cr3); - - for(int i = 0;i < head->e_phnum; i++) { - uint64_t dest = 0; - current_head = (elfprogramheader_t*)((uint64_t)base + head->e_phoff + head->e_phentsize*i); - - if(current_head->p_type == PT_LOAD) { - if(head->e_type != ET_DYN) { - dest = ((current_head->p_vaddr) - elf_base) + (std::uint64_t)allocated_elf; - DEBUG(1,"load seg 0x%p to 0x%p (0x%p)",current_head->p_vaddr,current_head->p_vaddr + current_head->p_memsz,current_head->p_vaddr + current_head->p_filesz); - } else { - dest = (uint64_t)allocated_elf + current_head->p_vaddr; - } - - memset((void*)dest, 0, current_head->p_memsz); - memcpy((void*)dest, (void*)((uint64_t)base + current_head->p_offset), current_head->p_filesz); - } else if(current_head->p_type == PT_INTERP) { - vfs::stat_t stat; - userspace_fd_t fd; - zeromem(&fd); - zeromem(&stat); - - memcpy(fd.path, (char*)((uint64_t)base + current_head->p_offset), strlen((char*)((uint64_t)base + current_head->p_offset))); - int status = vfs::vfs::stat(&fd, &stat); - if(status) { memory::paging::enablekernel(); - DEBUG(1,"unknown interp path %s (ENOENT)",(char*)((uint64_t)base + current_head->p_offset)); - return {0,0,0,0,0,ENOENT}; - } - - char* inter = (char*)memory::pmm::_virtual::alloc(stat.st_size); - vfs::vfs::read(&fd, inter, stat.st_size); - memory::paging::enablekernel(); - elfloadresult_t interpload = __scheduling_load_elf(proc, (std::uint8_t*)inter); - memory::paging::enablepaging(proc->original_cr3); - memory::pmm::_virtual::free(inter); - - elfload.interp_base = interpload.base; - elfload.interp_entry = interpload.real_entry; - } - } - - if(head->e_type != ET_DYN) { - if(phdr) { - elfload.phdr = phdr; - DEBUG(1,"phdr 0x%p",phdr); - } - } else { - if(phdr) { - phdr += (uint64_t)elf_vmm; - elfload.phdr = phdr; - } - elfload.real_entry = (uint64_t)elf_vmm + head->e_entry; - } - - if(proc->is_debug) { - uint64_t strtab_offset = 0; - uint64_t strtab_addr = 0; - uint64_t strtab_size = 0; - - elfprogramheader_t* phdrz =0; - - if(head->e_type != ET_DYN) { - phdrz = (elfprogramheader_t*)(phdr); - } else - phdrz = (elfprogramheader_t*)((phdr)); - elfprogramheader_t* dynamic_phdr = NULL; - - if(phdrz) { - for (int i = 0; i < head->e_phnum; i++) { - DEBUG(1,"phdr type %d",phdrz[i].p_type); - if (phdrz[i].p_type == PT_DYNAMIC) { - dynamic_phdr = &phdrz[i]; - break; - } - } - } - - if (dynamic_phdr == NULL) { - DEBUG(1, "DYNAMIC segment not found"); - //goto end; - } else { - Elf64_Dyn* dyn; - if(head->e_type != ET_DYN) - dyn = (Elf64_Dyn *)((char *)allocated_elf + (dynamic_phdr->p_vaddr - elf_base)); - else - dyn = (Elf64_Dyn *)((char *)allocated_elf + (dynamic_phdr->p_vaddr)); - uint64_t dyn_size = dynamic_phdr->p_filesz / sizeof(Elf64_Dyn); - - for (uint64_t i = 0; i < dyn_size; i++) { - if (dyn[i].d_tag == DT_NULL) { - break; - } - - if (dyn[i].d_tag == DT_STRTAB) { - strtab_addr = dyn[i].d_un.d_ptr; - } else if (dyn[i].d_tag == DT_STRSZ) { - strtab_size = dyn[i].d_un.d_val; - } - } - - if (strtab_addr == 0) { - DEBUG(1, ".dynstr string table not found"); - //goto end; - } - - for (int i = 0; i < head->e_phnum; i++) { - if (phdrz[i].p_type == PT_LOAD) { - uint64_t vaddr = phdrz[i].p_vaddr; - uint64_t memsz = phdrz[i].p_memsz; - uint64_t offset = phdrz[i].p_offset; - - if (strtab_addr >= vaddr && strtab_addr < vaddr + memsz) { - strtab_offset = offset + (strtab_addr - vaddr); - break; - } - } - } - - if (strtab_offset == 0) { - DEBUG(1, "Could not find string table offset in file"); - //goto end; - } - - char *strtab = (char *)allocated_elf + strtab_offset; - int dep_count = 0; - - DEBUG(1, "proc %d libraries", proc->id); - - // Теперь ищем зависимости - for (uint64_t i = 0; i < dyn_size; i++) { - if (dyn[i].d_tag == DT_NULL) { - break; - } - - if (dyn[i].d_tag == DT_NEEDED) { - uint64_t str_offset = dyn[i].d_un.d_val; - - if (str_offset < strtab_size) { - DEBUG(1, " %s", strtab + str_offset); - dep_count++; - } else { - DEBUG(1, " [Error: string offset out of bounds]"); - } - } - } - - if (dep_count == 0) { - DEBUG(1, " (no dependencies found)"); - } - } - } - -end: - elfload.base = (std::uint64_t)elf_vmm; - elfload.status = 0; - memory::paging::enablekernel(); - return elfload; -} - -std::atomic<std::uint64_t> znext = 0; -std::uint64_t __zrand() { - uint64_t t = __rdtsc(); - return t * (++znext); -} - -int arch::x86_64::scheduling::loadelf(process_t* proc,char* path,char** argv,char** envp, int free_mem) { - vfs::stat_t stat; - userspace_fd_t fd; - zeromem(&fd); - zeromem(&stat); - - memcpy(fd.path,path,strlen(path)); - - memcpy(proc->name,path,strlen(path) + 1); - - int status = vfs::vfs::stat(&fd,&stat); - if(status) { - return status; - } - - char* inter = (char*)memory::pmm::_virtual::alloc(stat.st_size); - - vfs::vfs::read(&fd,inter,stat.st_size); - elfloadresult_t elfload = __scheduling_load_elf(proc,(std::uint8_t*)inter); - - memory::pmm::_virtual::free(inter); - if(elfload.status != 0) - return elfload.status; - - proc->ctx.rsp = (std::uint64_t)memory::vmm::alloc(proc,USERSPACE_STACK_SIZE,PTE_PRESENT | PTE_USER | PTE_RW,0) + USERSPACE_STACK_SIZE - 4096; - - memory::vmm::invmapping(proc,proc->ctx.rsp - (4096 * 10),4096 * 10); - std::uint64_t* _stack = (std::uint64_t*)proc->ctx.rsp; - - std::uint64_t random_data_aux = (std::uint64_t)memory::vmm::alloc(proc,4096,PTE_PRESENT | PTE_USER | PTE_RW,0); - memory::vmm::invmapping(proc,random_data_aux,4096); - - std::uint64_t auxv_stack[] = {(std::uint64_t)elfload.real_entry,AT_ENTRY,elfload.phdr,AT_PHDR,elfload.phentsize,AT_PHENT,elfload.phnum,AT_PHNUM,4096,AT_PAGESZ,0,AT_SECURE,random_data_aux,AT_RANDOM,4096,51,elfload.interp_base,AT_BASE}; - std::uint64_t argv_length = __elf_get_length(argv); - std::uint64_t envp_length = __elf_get_length(envp); - - memory::paging::enablepaging(proc->ctx.cr3); - - std::uint64_t* randaux = (std::uint64_t*)random_data_aux; - randaux[0] = __zrand(); - randaux[1] = __zrand(); - - char** stack_argv = (char**)memory::heap::malloc(8 * (argv_length + 1)); - char** stack_envp = (char**)memory::heap::malloc(8 * (envp_length + 1)); - - memset(stack_argv,0,8 * (argv_length + 1)); - memset(stack_envp,0,8 * (envp_length + 1)); - - _stack = __elf_copy_to_stack(argv,_stack,stack_argv,argv_length); - - for(int i = 0; i < argv_length / 2; ++i) { - char* tmp = stack_argv[i]; - stack_argv[i] = stack_argv[argv_length - 1 - i]; - stack_argv[argv_length - 1 - i] = tmp; - } - - _stack = __elf_copy_to_stack(envp,_stack,stack_envp,envp_length); - - PUT_STACK(_stack,0); - - _stack = __elf_copy_to_stack_without_out(auxv_stack,_stack,sizeof(auxv_stack) / 8); - PUT_STACK(_stack,0); - - _stack = __elf_copy_to_stack_without_out((uint64_t*)stack_envp,_stack,envp_length); - PUT_STACK(_stack,0); - - _stack = __elf_copy_to_stack_without_out((uint64_t*)stack_argv,_stack,argv_length); - PUT_STACK(_stack,argv_length); - - memory::paging::enablekernel(); - - proc->ctx.rsp = (std::uint64_t)_stack; - proc->ctx.rip = elfload.interp_entry; - - memory::heap::free(stack_argv); - memory::heap::free(stack_envp); - - return 0; -} - -void arch::x86_64::scheduling::wakeup(process_t* proc) { - proc->lock.unlock(); /* Just clear */ -} - -arch::x86_64::process_t* arch::x86_64::scheduling::by_pid(int pid) { - process_t* proc = head_proc_(); - while(proc) { - if(proc->id == pid) { - return proc; } - proc = proc->next; - } - return 0; -} - -arch::x86_64::process_t* arch::x86_64::scheduling::clone3(process_t* proc, clone_args* clarg, int_frame_t* ctx) { - process_t* nproc = create(); - - memcpy(&nproc->ctx,ctx,sizeof(int_frame_t)); - - if(clarg->flags & CLONE_VM) { - memory::vmm::free(nproc); - nproc->ctx.cr3 = ctx->cr3; - nproc->original_cr3 = ctx->cr3; - nproc->vmm_end = proc->vmm_end; - nproc->vmm_start = proc->vmm_start; - nproc->reversedforid = *proc->vmm_id; - nproc->vmm_id = &nproc->reversedforid; - - vmm_obj_t* start = (vmm_obj_t*)proc->vmm_start; - start->lock.lock(); - start->pthread_count++; - start->lock.unlock(); - - - } else { - memory::vmm::clone(nproc,proc); - } - - nproc->is_cloned = 1; - nproc->uid = proc->uid; - - if(clarg->flags & CLONE_PARENT) { - nproc->parent_id = proc->parent_id; - } else { - nproc->parent_id = proc->id; - } - - if(clarg->flags & CLONE_THREAD) { - nproc->thread_group = proc->thread_group; - } else { - nproc->thread_group = nproc->id; - } - - if(clarg->tls) { - nproc->fs_base = clarg->tls; - } else { - nproc->fs_base = proc->fs_base; - } - - nproc->exit_signal = clarg->exit_signal; - - if(clarg->stack) { - nproc->ctx.rsp = clarg->stack; - } - - memcpy(nproc->sigsets,proc->sigsets,sizeof(proc->sigsets)); - - memcpy(&nproc->current_sigset,&proc->current_sigset,sizeof(proc->current_sigset)); - memcpy(nproc->ret_handlers,proc->ret_handlers,sizeof(proc->ret_handlers)); - memcpy(nproc->sig_handlers,proc->sig_handlers,sizeof(proc->sig_handlers)); - - memset(nproc->cwd,0,4096); - memset(nproc->name,0,4096); - memcpy(nproc->cwd,proc->cwd,strlen(proc->cwd)); - memcpy(nproc->name,proc->name,strlen(proc->name)); - - memcpy(nproc->sse_ctx,proc->sse_ctx,arch::x86_64::cpu::sse::size()); - - if(clarg->flags & CLONE_FILES) { - nproc->is_shared_fd = 1; - nproc->fd_ptr = proc->fd_ptr; - nproc->fd = proc->fd; - - vfs::fdmanager* fd = (vfs::fdmanager*)proc->fd; - - proc->fd_lock.lock(); - fd->used_counter++; - proc->fd_lock.unlock(); - } else { - *nproc->fd_ptr = *proc->fd_ptr; - nproc->fd_ptr = &nproc->alloc_fd; - - vfs::fdmanager* fd = (vfs::fdmanager*)proc->fd; - fd->duplicate((vfs::fdmanager*)nproc->fd); - } - nproc->ctx.cr3 = nproc->original_cr3; - return nproc; -} - -arch::x86_64::process_t* arch::x86_64::scheduling::clone(process_t* proc,int_frame_t* ctx) { - process_t* nproc = create(); - memory::vmm::free(nproc); - - nproc->is_cloned = 1; - nproc->ctx.cr3 = ctx->cr3; - nproc->original_cr3 = ctx->cr3; - nproc->uid = proc->uid; - - nproc->vmm_end = proc->vmm_end; - nproc->vmm_start = proc->vmm_start; - - nproc->parent_id = proc->id; - nproc->fs_base = proc->fs_base; - nproc->reversedforid = *proc->vmm_id; - nproc->vmm_id = &nproc->reversedforid; - - memcpy(&nproc->current_sigset,&proc->current_sigset,sizeof(proc->current_sigset)); - memcpy(nproc->ret_handlers,proc->ret_handlers,sizeof(proc->ret_handlers)); - memcpy(nproc->sig_handlers,proc->sig_handlers,sizeof(proc->sig_handlers)); - - memset(nproc->cwd,0,4096); - memset(nproc->name,0,4096); - memcpy(nproc->cwd,proc->cwd,strlen(proc->cwd)); - memcpy(nproc->name,proc->name,strlen(proc->name)); - - memcpy(nproc->sse_ctx,proc->sse_ctx,arch::x86_64::cpu::sse::size()); - - nproc->is_shared_fd = 1; - nproc->fd_ptr = proc->fd_ptr; - nproc->fd = proc->fd; - - vfs::fdmanager* fd = (vfs::fdmanager*)proc->fd; - - proc->fd_lock.lock(); - fd->used_counter++; - proc->fd_lock.unlock(); - - // userspace_fd_t* fd = proc->fd; - // while(fd) { - // userspace_fd_t* newfd = new userspace_fd_t; - // memcpy(newfd,fd,sizeof(userspace_fd_t)); - - // if(newfd->state == USERSPACE_FD_STATE_PIPE) { - // newfd->pipe->create(newfd->pipe_side); - // } else if(newfd->state == USERSPACE_FD_STATE_EVENTFD) - // newfd->eventfd->create(); - - // newfd->next = nproc->fd; - // nproc->fd = newfd; - // fd = fd->next; - // } - - memcpy(&nproc->ctx,ctx,sizeof(int_frame_t)); - - return nproc; -} - -arch::x86_64::process_t* arch::x86_64::scheduling::fork(process_t* proc,int_frame_t* ctx) { - process_t* nproc = create(); - memory::vmm::clone(nproc,proc); - - nproc->parent_id = proc->id; - nproc->fs_base = proc->fs_base; - nproc->uid = proc->uid; - - memcpy(nproc->sigsets,proc->sigsets,sizeof(proc->sigsets)); - - memcpy(&nproc->current_sigset,&proc->current_sigset,sizeof(proc->current_sigset)); - memcpy(nproc->ret_handlers,proc->ret_handlers,sizeof(proc->ret_handlers)); - memcpy(nproc->sig_handlers,proc->sig_handlers,sizeof(proc->sig_handlers)); - - memset(nproc->cwd,0,4096); - memset(nproc->name,0,4096); - memcpy(nproc->cwd,proc->cwd,strlen(proc->cwd)); - memcpy(nproc->name,proc->name,strlen(proc->name)); - - memcpy(nproc->sse_ctx,proc->sse_ctx,arch::x86_64::cpu::sse::size()); - - *nproc->fd_ptr = *proc->fd_ptr; - nproc->fd_ptr = &nproc->alloc_fd; - - vfs::fdmanager* fd = (vfs::fdmanager*)proc->fd; - fd->duplicate((vfs::fdmanager*)nproc->fd); - - memcpy(&nproc->ctx,ctx,sizeof(int_frame_t)); - nproc->ctx.cr3 = nproc->original_cr3; - - return nproc; -} -void arch::x86_64::scheduling::kill(process_t* proc) { - proc->kill_lock.nowaitlock(); - proc->lock.nowaitlock(); - proc->status = PROCESS_STATE_ZOMBIE; - proc->is_execd = 1; - proc->exit_timestamp = time::counter(); - free_sigset_from_list(proc); - delete proc->pass_fd; -} - -void __scheduling_balance_cpus() { - int cpu_ptr = 0; - arch::x86_64::process_t* proc = head_proc; - extern int how_much_cpus; - while(proc) { - if(!proc->kill_lock.test()) { - proc->target_cpu.store(cpu_ptr++,std::memory_order_release); - //Log::SerialDisplay(LEVEL_MESSAGE_INFO,"cpu %d to proc %s (%d) cpu_count %d\n",cpu_ptr,proc->name,proc->id,how_much_cpus); - if(cpu_ptr == how_much_cpus) - cpu_ptr = 0; - } - proc = proc->next; - } -} - -arch::x86_64::process_t* arch::x86_64::scheduling::create() { - process_t* proc = (process_t*)memory::pmm::_virtual::alloc(4096); - - proc->cwd = (char*)memory::pmm::_virtual::alloc(4096); - proc->name = (char*)memory::pmm::_virtual::alloc(4096); - proc->sse_ctx = (char*)memory::pmm::_virtual::alloc(arch::x86_64::cpu::sse::size()); - - proc->syscall_stack = (std::uint64_t)memory::pmm::_virtual::alloc(SYSCALL_STACK_SIZE); - - fpu_head_t* head = (fpu_head_t*)proc->sse_ctx; - head->dumb5 = 0b0001111110000000; - - proc->ctx.cs = 0x20 | 3; - proc->ctx.ss = 0x18 | 3; - proc->ctx.rflags = (1 << 9); - proc->status = PROCESS_STATE_RUNNING; - proc->lock.nowaitlock(); - proc->kill_lock.unlock(); - proc->fd_ptr = &proc->alloc_fd; - - proc->thread_group = proc->id; - - *proc->fd_ptr = 3; - - proc->is_debug = 0; - proc->next_alarm = -1; - proc->virt_timer = -1; - proc->prof_timer = -1; - - proc->sig = new signalmanager; - - vfs::fdmanager* z = new vfs::fdmanager(proc); - proc->fd = (void*)z; - - proc->next = head_proc; - head_proc = proc; - - - proc->id = id_ptr++; - proc->vmm_id = &proc->id; - - proc->pass_fd = new vfs::passingfd_manager; - - memory::vmm::initproc(proc); - memory::vmm::reload(proc); - - proc->create_timestamp = time::counter(); - - __scheduling_balance_cpus(); - - return proc; -} - -locks::spinlock futex_lock; - -int arch::x86_64::scheduling::futexwake(process_t* proc, int* lock, int num_to_wake) { - process_t* proc0 = head_proc; - futex_lock.lock(); - int nums = 0; - while(proc0) { - // if process vmm is same then they are connected - if(((proc->vmm_start == proc0->vmm_start)) && proc0->futex == (std::uint64_t)lock) { - proc0->futex = 0; - proc0->futex_lock.unlock(); - num_to_wake--; - DEBUG(proc->is_debug,"futex_wakeup proccess %d from proc %d, futex 0x%p",proc0->id,proc->id,lock); - nums++; - } else if((proc0->futex == (std::uint64_t)lock || proc->futex == (std::uint64_t)lock)) { - DEBUG(proc->is_debug,"same futex 0x%p but calling proc %d is not connected to proc %d",lock,proc->id,proc0->id); - } - proc0 = proc0->next; - } - futex_lock.unlock(); - return nums; -} - -void arch::x86_64::scheduling::futexwait(process_t* proc, int* lock, int val, int* original_lock,std::uint64_t ts) { - futex_lock.lock(); - int lock_val = *lock; - proc->futex_lock.lock(); - proc->futex = (std::uint64_t)original_lock; - proc->ts = ts; - futex_lock.unlock(); -} -int l = 0; - - -#define SIG_DFL 0 -#define SIG_IGN 1 - -extern "C" void schedulingSchedule(int_frame_t* ctx) { - extern int is_panic; - - if(ctx) { - if(ctx->cs != 0x08) - asm volatile("swapgs"); - } - - if(is_panic == 1) - asm volatile("hlt"); - -scheduleagain: - arch::x86_64::process_t* current = arch::x86_64::cpu::data()->temp.proc; - - cpudata_t* data = arch::x86_64::cpu::data(); - - if(ctx) { - if(current) { - if(!current->kill_lock.test() && !current->_3rd_kill_lock.test()) { - current->ctx = *ctx; - current->fs_base = __rdmsr(0xC0000100); - arch::x86_64::cpu::sse::save((std::uint8_t*)current->sse_ctx); - current->user_stack = data->user_stack; /* Only user stack should be saved */ - - if(current->time_start) { - // it wants something - std::uint64_t delta = drivers::tsc::currentus() - current->time_start; - if(current->virt_timer > 0) { - current->virt_timer -= current->virt_timer > delta ? delta : current->virt_timer; - } - - if(current->prof_timer > 0) { - current->prof_timer -= current->prof_timer > delta ? delta : current->prof_timer; - } - - current->time_start = 0; - - } - - } - } - } - - if(current) { - if(current->_3rd_kill_lock.test() && !current->kill_lock.test()) { - memory::paging::enablekernel(); - arch::x86_64::scheduling::kill(current); - - if(1) - memory::vmm::free(current); - - vfs::fdmanager* fd = (vfs::fdmanager*)current->fd; - fd->free(); - - memory::pmm::_virtual::free(current->cwd); - memory::pmm::_virtual::free(current->name); - memory::pmm::_virtual::free(current->sse_ctx); - } else - current->lock.unlock(); - - current = current->next; - } - - ctx = 0; - - int current_cpu = data->smp.cpu_id; - - while (true) { - while (current) { - - if (!current->kill_lock.test() && current->id != 0 && 1) { - - if(1) { // signals are only for user mode, or they must be handled by process itself - if(!current->lock.test_and_set()) { - - // real alarm timer - if(current->next_alarm != -1 && current->sig) { - if(drivers::tsc::currentus() >= current->next_alarm) { - // alarm !!! - pending_signal_t alarm_sig; - alarm_sig.sig = SIGALRM; - current->next_alarm = -1; - if(current->itimer.it_interval.tv_sec != 0 || current->itimer.it_interval.tv_usec != 0) { - std::uint64_t offs = current->itimer.it_interval.tv_sec * 1000 * 1000; - offs += current->itimer.it_interval.tv_usec; - current->next_alarm = drivers::tsc::currentus() + offs; - } - current->sig->push(&alarm_sig); - } - } - - if(current->virt_timer != -1 && current->sig) { - if(current->virt_timer == 0) { - // alarm !!! - pending_signal_t alarm_sig; - alarm_sig.sig = SIGVTALRM; - current->virt_timer = -1; - if(current->vitimer.it_interval.tv_sec != 0 || current->vitimer.it_interval.tv_usec != 0) { - std::uint64_t offs = current->vitimer.it_interval.tv_sec * 1000 * 1000; - offs += current->vitimer.it_interval.tv_usec; - current->virt_timer = offs; - } - current->sig->push(&alarm_sig); - } - } - - if(current->prof_timer != -1 && current->sig) { - if(current->prof_timer == 0) { - // alarm !!! - pending_signal_t alarm_sig; - alarm_sig.sig = SIGPROF; - current->prof_timer = -1; - if(current->proftimer.it_interval.tv_sec != 0 || current->proftimer.it_interval.tv_usec != 0) { - std::uint64_t offs = current->proftimer.it_interval.tv_sec * 1000 * 1000; - offs += current->proftimer.it_interval.tv_usec; - current->prof_timer = offs; - } - current->sig->push(&alarm_sig); - } - } - - if(!ctx) { - int_frame_t temp_ctx; - ctx = &temp_ctx; - } - - int is_possible = 1; - if(current->ctx.cs == 0x08) { - is_possible = 0; - } - - if(is_possible) { - pending_signal_t new_sig; - int status = current->sig->popsigset(&new_sig,¤t->current_sigset); - if(status != -1) { - - if((std::uint64_t)current->sig_handlers[new_sig.sig] == SIG_IGN || (std::uint64_t)current->sig_handlers[new_sig.sig] == SIG_DFL || new_sig.sig == SIGKILL) { - // sig is blocked, push it back - if(current->sig_handlers[new_sig.sig] == SIG_DFL) { - switch(new_sig.sig) { - case SIGCHLD: - case SIGCONT: - case SIGURG: - case SIGWINCH: - break; //ignore - case SIGSTOP: - case SIGTSTP: - case SIGTTIN: - case SIGTTOU: - Log::SerialDisplay(LEVEL_MESSAGE_WARN,"unimplemented process stop to proc %d, sig %d\n",current->id,new_sig.sig); - break; - - default: { - char* vm_start = current->vmm_start; - arch::x86_64::process_t* currentz = arch::x86_64::scheduling::head_proc_(); - memory::paging::enablekernel(); - DEBUG(1,"sig kill %d",new_sig.sig); - while(currentz) { - if(currentz->vmm_start == vm_start) { - currentz->exit_code = status; - arch::x86_64::scheduling::kill(currentz); - - if(1) - memory::vmm::free(currentz); - - vfs::fdmanager* fd = (vfs::fdmanager*)currentz->fd; - fd->free(); - - memory::pmm::_virtual::free(currentz->cwd); - memory::pmm::_virtual::free(currentz->name); - memory::pmm::_virtual::free(currentz->sse_ctx); - } - currentz = currentz->next; - } - goto scheduleagain; - } - }; - } - - } else { - - if(current->is_restore_sigset) { - // syscall requested restore sigset - memcpy(¤t->current_sigset,¤t->temp_sigset,sizeof(sigset_t)); - current->is_restore_sigset = 0; - } - - sigtrace new_sigtrace; - - mcontext_t temp_mctx = {0}; - int_frame_to_mcontext(¤t->ctx,&temp_mctx); - - memory::paging::enablepaging(current->original_cr3); - - std::uint64_t* new_stack = 0; - - if(!current->sigtrace_obj) { - new_stack = (std::uint64_t*)(current->altstack.ss_sp == 0 ? current->ctx.rsp - 8 : (std::uint64_t)current->altstack.ss_sp); - } else { - new_stack = (std::uint64_t*)(current->ctx.rsp - 8); - } - - --new_stack; - - new_stack = (std::uint64_t*)__stack_memcpy((std::uint64_t)new_stack,&temp_mctx,sizeof(mcontext_t)); - - new_sigtrace.mctx = (mcontext_t*)new_stack; - --new_stack; - - siginfo_t siginfo; - memset(&siginfo,0,sizeof(siginfo)); - - new_stack = (std::uint64_t*)__stack_memcpy((std::uint64_t)new_stack,&siginfo,sizeof(siginfo_t)); - std::uint64_t siginfoz = (std::uint64_t)new_stack; - - --new_stack; - - new_sigtrace.next = current->sigtrace_obj; - - new_sigtrace.sigset = current->current_sigset; - - new_stack = (std::uint64_t*)__stack_memcpy((std::uint64_t)new_stack,&new_sigtrace,sizeof(sigtrace)); - - sigtrace* new_sigstrace_u = (sigtrace*)new_stack; - - new_stack = (std::uint64_t*)__stack_memcpy((std::uint64_t)new_stack,current->sse_ctx,arch::x86_64::cpu::sse::size()); - - new_sigstrace_u->fpu_state = (void*)new_stack; - current->sigtrace_obj = new_sigstrace_u; - - --new_stack; - *--new_stack = (std::uint64_t)current->ret_handlers[new_sig.sig]; - - // now setup new registers and stack - - current->ctx.rdi = new_sig.sig; - current->ctx.rsi = 0; - current->ctx.rdx = 0; - current->ctx.rsp = (std::uint64_t)new_stack; - current->ctx.rip = (std::uint64_t)current->sig_handlers[new_sig.sig]; - current->ctx.cs = 0x20 | 3; - current->ctx.ss = 0x18 | 3; - current->ctx.rflags = (1 << 9); - - memcpy(ctx, ¤t->ctx, sizeof(int_frame_t)); - - __wrmsr(0xC0000100, current->fs_base); - arch::x86_64::cpu::sse::load((std::uint8_t*)current->sse_ctx); - - if(ctx->cs & 3) - ctx->ss |= 3; - - if(ctx->ss & 3) - ctx->cs |= 3; - - if(ctx->cs == 0x20) - ctx->cs |= 3; - - if(ctx->ss == 0x18) - ctx->ss |= 3; - - data->kernel_stack = current->syscall_stack + SYSCALL_STACK_SIZE; - data->user_stack = current->user_stack; - data->temp.proc = current; - - int prio_div = current->prio < 0 ? (current->prio * -1) : 1; - prio_div++; - - if(current->virt_timer != -1 || current->prof_timer != -1) { - // it will request for time - - current->time_start = drivers::tsc::currentus(); - } - - arch::x86_64::cpu::lapic::eoi(); - - if(ctx->cs != 0x08) - asm volatile("swapgs"); - schedulingEnd(ctx); - } - - } - } - - memcpy(ctx, ¤t->ctx, sizeof(int_frame_t)); - - __wrmsr(0xC0000100, current->fs_base); - arch::x86_64::cpu::sse::load((std::uint8_t*)current->sse_ctx); - - if(ctx->cs & 3) - ctx->ss |= 3; - - if(ctx->ss & 3) - ctx->cs |= 3; - - if(ctx->cs == 0x20) - ctx->cs |= 3; - - if(ctx->ss == 0x18) - ctx->ss |= 3; - - data->kernel_stack = current->syscall_stack + SYSCALL_STACK_SIZE; - data->user_stack = current->user_stack; - data->temp.proc = current; - - int prio_div = current->prio < 0 ? (current->prio * -1) : 1; - prio_div++; - - if(current->virt_timer != -1 || current->prof_timer != -1) { - // it will request for time - current->time_start = drivers::tsc::currentus(); - } - - - arch::x86_64::cpu::lapic::eoi(); - - if(ctx->cs != 0x08) - asm volatile("swapgs"); - - schedulingEnd(ctx); - } - } - } - current = current->next; - } - current = head_proc; - } -} - -void arch::x86_64::scheduling::create_kernel_thread(void (*func)(void*), void* arg) { - process_t* proc = (process_t*)memory::pmm::_virtual::alloc(4096); - - proc->cwd = (char*)memory::pmm::_virtual::alloc(4096); - proc->name = (char*)memory::pmm::_virtual::alloc(4096); - proc->sse_ctx = (char*)memory::pmm::_virtual::alloc(arch::x86_64::cpu::sse::size()); - - proc->syscall_stack = (std::uint64_t)memory::pmm::_virtual::alloc(SYSCALL_STACK_SIZE); - - fpu_head_t* head = (fpu_head_t*)proc->sse_ctx; - head->dumb5 = 0b0001111110000000; - - proc->ctx.cs = 0x08; - proc->ctx.ss = 0; - proc->ctx.rflags = (1 << 9); - proc->ctx.rsp = proc->syscall_stack + (SYSCALL_STACK_SIZE - 4096); - proc->ctx.rip = (std::uint64_t)func; - proc->ctx.rdi = (std::uint64_t)arg; - proc->ctx.cr3 = memory::paging::kernelget(); - proc->original_cr3 = memory::paging::kernelget(); - proc->status = PROCESS_STATE_RUNNING; - proc->lock.nowaitlock(); - proc->kill_lock.unlock(); - - proc->id = id_ptr++; - - proc->next = head_proc; - head_proc = proc; - - proc->create_timestamp = time::counter(); - - __scheduling_balance_cpus(); - - wakeup(proc); - - return; -} - -arch::x86_64::process_t* arch::x86_64::scheduling::head_proc_() { - return head_proc; -} - -void arch::x86_64::scheduling::init() { - process_t* main_proc = create(); - main_proc->kill_lock.nowaitlock(); - arch::x86_64::interrupts::idt::set_entry((std::uint64_t)schedulingEnter,32,0x8E,2); -} - -void arch::x86_64::scheduling::sigreturn(process_t* proc) { // pop values from stack - sigtrace* st = proc->sigtrace_obj; - memory::paging::enablepaging(proc->original_cr3); - if(!st) - return; - mcontext_t* mctx = st->mctx; - proc->current_sigset = st->sigset; - mcontext_to_int_frame(mctx,&proc->ctx); - proc->ctx.cr3 = proc->original_cr3; - proc->ctx.cs = 0x20 | 3; - proc->ctx.ss = 0x18 | 3; - proc->ctx.rflags |= (1 << 9); - memcpy(proc->sse_ctx,st->fpu_state,arch::x86_64::cpu::sse::size()); - proc->sigtrace_obj = st->next; - //DEBUG(1,"returning from sig to rip 0x%p, proc %d",proc->ctx.rip,proc->id); - memory::paging::enablekernel(); - - if(proc->ctx.cs != 0x08) - asm volatile("swapgs"); - - schedulingEnd(&proc->ctx); - __builtin_unreachable(); -}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscalls/file.cpp b/kernel/src/arch/x86_64/syscalls/file.cpp deleted file mode 100644 index 18e1ab3..0000000 --- a/kernel/src/arch/x86_64/syscalls/file.cpp +++ /dev/null @@ -1,2737 +0,0 @@ - -#include <arch/x86_64/syscalls/syscalls.hpp> -#include <generic/vfs/vfs.hpp> - -#include <generic/mm/vmm.hpp> - -#include <arch/x86_64/cpu/data.hpp> -#include <arch/x86_64/scheduling.hpp> - -#include <generic/mm/pmm.hpp> - -#include <generic/vfs/fd.hpp> - -#include <generic/vfs/devfs.hpp> - -#include <drivers/tsc.hpp> - -#include <etc/etc.hpp> -#include <etc/errno.hpp> - -#include <etc/logging.hpp> - -#include <arch/x86_64/syscalls/sockets.hpp> - -#include <cstdint> - -long long sys_access(char* path, int mode) { - SYSCALL_IS_SAFEZ(path,4096); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - char first_path[2048]; - memset(first_path,0,2048); - if(0) - memcpy(first_path,vfs::fdmanager::search(proc,0)->path,strlen(vfs::fdmanager::search(proc,0)->path)); - else if(1 && proc->cwd) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - userspace_fd_t fd; - memset(&fd,0,sizeof(userspace_fd_t)); - memcpy(fd.path,result,strlen(result) + 1); - - vfs::stat_t stat; - int status = vfs::vfs::stat(&fd,&stat); - return status; -} - -long long sys_faccessat(int dirfd, char* path, int mode, int flags) { - SYSCALL_IS_SAFEZ(path,4096); - - if(!path) - return -EINVAL; - - arch::x86_64::process_t* proc = CURRENT_PROC; - - char first_path[2048]; - memset(first_path,0,2048); - if(dirfd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD && proc->cwd) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - userspace_fd_t fd; - memset(&fd,0,sizeof(userspace_fd_t)); - memcpy(fd.path,result,strlen(result) + 1); - - vfs::stat_t stat; - int status = 0; - - if(flags & AT_SYMLINK_NOFOLLOW) - status = vfs::vfs::nosym_stat(&fd,&stat); - else - status = vfs::vfs::stat(&fd,&stat); - - return status; -} - -long long sys_openat(int dirfd, const char* path, int flags, int_frame_t* ctx) { - SYSCALL_IS_SAFEZ((void*)path,0); - if(!path) - return -EFAULT; - - arch::x86_64::process_t* proc = CURRENT_PROC; - - std::uint32_t mode = ctx->r10; - - char first_path[2048]; - memset(first_path,0,2048); - if(dirfd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD && proc->cwd) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - DEBUG(proc->is_debug,"Trying to open %s, %s + %s from proc %d",result,first_path,path,proc->id); - - if(result[0] == '\0') { - result[0] = '/'; - result[1] = '\0'; - } - - int new_fd = vfs::fdmanager::create(proc); - - userspace_fd_t* new_fd_s = vfs::fdmanager::search(proc,new_fd); - memset(new_fd_s->path,0,2048); - memcpy(new_fd_s->path,result,strlen(result)); - - new_fd_s->offset = 0; - new_fd_s->queue = 0; - new_fd_s->pipe = 0; - new_fd_s->pipe_side = 0; - new_fd_s->cycle = 0; - new_fd_s->is_a_tty = 0; - new_fd_s->flags = flags; // copy flags - - if(flags & O_CREAT) - vfs::vfs::touch(new_fd_s->path, mode); - - new_fd_s->mode = mode; - - std::uint64_t start = drivers::tsc::currentnano(); - std::int32_t status = vfs::vfs::open(new_fd_s); - - if(status != 0) { - new_fd_s->state = USERSPACE_FD_STATE_UNUSED; - DEBUG(proc->is_debug,"Failed to open %s (%d:%s + %s) from proc %d, is_creat %d, is_trunc %d, flags %d (%s)",result,dirfd,first_path,path,proc->id,flags & O_CREAT,flags & O_TRUNC,flags,proc->name); - return -status; - } - - vfs::stat_t stat; - std::int32_t stat_status = vfs::vfs::stat(new_fd_s,&stat); - - if(stat_status == 0) - if(flags & __O_DIRECTORY) - if(!(stat.st_mode & S_IFDIR)) { - new_fd_s->state = USERSPACE_FD_STATE_UNUSED; - return -ENOTDIR; - } - - if(flags & O_TRUNC) - vfs::vfs::write(new_fd_s,(void*)"\0",1); - - if(flags & O_APPEND) - new_fd_s->offset = stat.st_size; - - if(status != 0) { - vfs::fdmanager* fdm = (vfs::fdmanager*)proc->fd; - fdm->close(new_fd_s->index); - } - - std::uint64_t end = drivers::tsc::currentnano(); - DEBUG(0,"open takes %llu time, status %d, %s",end - start,status,new_fd_s->path); - - if(status != 0) - DEBUG(proc->is_debug,"Failed to open %s (%s + %s) from proc %d",result,first_path,path,proc->id); - - new_fd_s->offset = 0; - - DEBUG(proc->is_debug,"Open %s (%d) from proc %d",result,new_fd,proc->id); - - return status == 0 ? new_fd : -status; -} - -typedef struct stackframe { - struct stackframe* rbp; - uint64_t rip; -} __attribute__((packed)) stackframe_t; - -long long sys_pread(int fd, void *buf, size_t count, int_frame_t* ctx) { - - std::uint64_t off = ctx->r10; - SYSCALL_IS_SAFEZ(buf,count); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - userspace_fd_t* fd_sz = vfs::fdmanager::search(proc,fd); - if(!fd_sz) - return -EBADF; - - userspace_fd_t fd_ss = *fd_sz; - fd_ss.offset = off; - - userspace_fd_t* fd_s = &fd_ss; - - if(fd_s->can_be_closed) - fd_s->can_be_closed = 0; - - DEBUG(proc->is_debug,"Trying to read %s (fd %d) with state %d from proc %d, pipe 0x%p (%s) count %lli",fd_s->path,fd,fd_s->state,proc->id,fd_s->pipe,proc->name,count); - - char* temp_buffer = (char*)buf; - std::int64_t bytes_read; - if(fd_s->state == USERSPACE_FD_STATE_FILE) - bytes_read = vfs::vfs::read(fd_s,temp_buffer,count); - else if(fd_s->state == USERSPACE_FD_STATE_PIPE && fd_s->pipe) { - if(fd_s->pipe_side != PIPE_SIDE_READ) - return -EBADF; - - proc->debug1 = fd_s->pipe->lock.test(); - - bytes_read = fd_s->pipe->read(&fd_s->read_counter,temp_buffer,count,(fd_s->flags & O_NONBLOCK) ? 1 : 0); - - if(bytes_read == -EAGAIN && (fd_s->pipe->flags & O_NONBLOCK || fd_s->flags & O_NONBLOCK) && !fd_s->pipe->is_closed.test()) - return -EAGAIN; - - } else if(fd_s->state == USERSPACE_FD_STATE_SOCKET) { - - if(!fd_s->write_socket_pipe || !fd_s->read_socket_pipe) - return -EFAULT; - - if(fd_s->other_state == USERSPACE_FD_OTHERSTATE_MASTER) { - bytes_read = fd_s->write_socket_pipe->read(&fd_s->read_counter,temp_buffer,count,(fd_s->flags & O_NONBLOCK) ? 1 : 0); - } else { - bytes_read = fd_s->read_socket_pipe->read(&fd_s->read_counter,temp_buffer,count,(fd_s->flags & O_NONBLOCK) ? 1 : 0); - } - - if(bytes_read == -EAGAIN) - return -EAGAIN; - - if(bytes_read == 0) - return 0; - - } else if(fd_s->state == USERSPACE_FD_STATE_EVENTFD) { - if(count != 8) - return -EINVAL; - std::uint64_t* _8sizebuf = (std::uint64_t*)buf; - bytes_read = fd_s->eventfd->read(_8sizebuf); - } else - return -EBADF; - - return bytes_read; -} - -long long sys_read(int fd, void *buf, size_t count) { - SYSCALL_IS_SAFEZ(buf,count); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return -EBADF; - - if(fd_s->can_be_closed) - fd_s->can_be_closed = 0; - - DEBUG(proc->is_debug,"Trying to read %s (fd %d) with state %d from proc %d, pipe 0x%p (%s) count %lli",fd_s->path,fd,fd_s->state,proc->id,fd_s->pipe,proc->name,count); - - char* temp_buffer = (char*)buf; - std::int64_t bytes_read; - if(fd_s->state == USERSPACE_FD_STATE_FILE) { - bytes_read = vfs::vfs::read(fd_s,temp_buffer,count); - - } - else if(fd_s->state == USERSPACE_FD_STATE_PIPE && fd_s->pipe) { - if(fd_s->pipe_side != PIPE_SIDE_READ) - return -EBADF; - - proc->debug1 = fd_s->pipe->lock.test(); - - bytes_read = fd_s->pipe->read(&fd_s->read_counter,temp_buffer,count,(fd_s->flags & O_NONBLOCK) ? 1 : 0); - - if(bytes_read == -EAGAIN && (fd_s->pipe->flags & O_NONBLOCK || fd_s->flags & O_NONBLOCK) && !fd_s->pipe->is_closed.test()) - return -EAGAIN; - - } else if(fd_s->state == USERSPACE_FD_STATE_SOCKET) { - - if(!fd_s->write_socket_pipe || !fd_s->read_socket_pipe) - return -EFAULT; - - if(fd_s->other_state == USERSPACE_FD_OTHERSTATE_MASTER) { - bytes_read = fd_s->write_socket_pipe->read(&fd_s->read_counter,temp_buffer,count,(fd_s->flags & O_NONBLOCK) ? 1 : 0); - } else { - bytes_read = fd_s->read_socket_pipe->read(&fd_s->read_counter,temp_buffer,count,(fd_s->flags & O_NONBLOCK) ? 1 : 0); - } - - if(bytes_read == -EAGAIN) - return -EAGAIN; - - if(bytes_read == 0) - return 0; - - } else if(fd_s->state == USERSPACE_FD_STATE_EVENTFD) { - if(count != 8) - return -EINVAL; - std::uint64_t* _8sizebuf = (std::uint64_t*)buf; - bytes_read = fd_s->eventfd->read(_8sizebuf); - } else - return -EBADF; - - return bytes_read; -} - -long long sys_writev(int fd, wiovec* vec, unsigned long vlen) { - SYSCALL_IS_SAFEZ(vec,vlen * sizeof(wiovec)); - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) { - DEBUG(1,"fail write fd %d from proc %d, proc->fd is 0x%p, %s\n",fd,proc->id,proc->fd,vec[0].iov_base); - return -EBADF; - } - - if(fd_s->can_be_closed) - fd_s->can_be_closed = 0; - - std::uint64_t full_bytes_written = 0; - - for(unsigned long i = 0;i < vlen;i++) { - wiovec cur_vec = vec[i]; - char* temp_buffer = (char*)cur_vec.iov_base; - std::uint64_t count = cur_vec.iov_len; - std::int64_t bytes_written; - - DEBUG(proc->is_debug,"Writing %s with content %s fd %d state %d from proc %d count %d writ sock 0x%p",fd_s->state == USERSPACE_FD_STATE_FILE ? fd_s->path : "Not file",temp_buffer,fd,fd_s->state,proc->id,count,fd_s->write_socket_pipe); - - if(fd_s->state == USERSPACE_FD_STATE_FILE) - bytes_written = vfs::vfs::write(fd_s,temp_buffer,count); - else if(fd_s->state == USERSPACE_FD_STATE_PIPE) { - if(fd_s->pipe_side != PIPE_SIDE_WRITE) - return -EBADF; - bytes_written = fd_s->pipe->write(temp_buffer,count,proc->id); - } else if(fd_s->state == USERSPACE_FD_STATE_SOCKET) { - - if(!fd_s->write_socket_pipe || !fd_s->read_socket_pipe) - return -EFAULT; - - if(fd_s->other_state == USERSPACE_FD_OTHERSTATE_MASTER) { - bytes_written = fd_s->read_socket_pipe->write(temp_buffer,count,proc->id); - } else { - bytes_written = fd_s->write_socket_pipe->write(temp_buffer,count,proc->id); - } - - if(bytes_written == 0) - return 0; - - } else if(fd_s->state == USERSPACE_FD_STATE_EVENTFD) { - if(count != 8) - return -EINVAL; - std::uint64_t* _8sizebuf = (std::uint64_t*)temp_buffer; - bytes_written = fd_s->eventfd->write(*_8sizebuf); - } else - return -EBADF; - full_bytes_written += bytes_written; - } - - return full_bytes_written; -} - -long long sys_write(int fd, const void *buf, size_t count) { - SYSCALL_IS_SAFEZ((void*)buf,count); - - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) { - DEBUG(proc->is_debug,"fail write fd %d from proc %d, proc->fd is 0x%p\n",fd,proc->id,proc->fd); - return -EBADF; - } - - if(fd_s->can_be_closed) - fd_s->can_be_closed = 0; - - char* temp_buffer = (char*)buf; - - const char* _0 = "Content view is disabled in files"; - DEBUG(proc->is_debug,"Writing %s with content %s fd %d state %d from proc %d count %d writ sock 0x%p",fd_s->state == USERSPACE_FD_STATE_FILE ? fd_s->path : "Not file",buf,fd,fd_s->state,proc->id,count,fd_s->write_socket_pipe); - - if(0) { - Log::SerialDisplay(LEVEL_MESSAGE_INFO,"%s off %lli, new off %lli\n",buf,fd_s->offset,fd_s->offset + count); - } - - std::int64_t bytes_written; - if(fd_s->state == USERSPACE_FD_STATE_FILE) - bytes_written = vfs::vfs::write(fd_s,temp_buffer,count); - else if(fd_s->state == USERSPACE_FD_STATE_PIPE) { - if(fd_s->pipe_side != PIPE_SIDE_WRITE) - return -EBADF; - bytes_written = fd_s->pipe->write(temp_buffer,count,proc->id); - } else if(fd_s->state == USERSPACE_FD_STATE_SOCKET) { - - if(!fd_s->write_socket_pipe || !fd_s->read_socket_pipe) - return -EFAULT; - - if(fd_s->other_state == USERSPACE_FD_OTHERSTATE_MASTER) { - bytes_written = fd_s->read_socket_pipe->write(temp_buffer,count,proc->id); - } else { - bytes_written = fd_s->write_socket_pipe->write(temp_buffer,count,proc->id); - } - - if(bytes_written == 0) - return 0; - - } else if(fd_s->state == USERSPACE_FD_STATE_EVENTFD) { - if(count != 8) - return -EINVAL; - std::uint64_t* _8sizebuf = (std::uint64_t*)buf; - bytes_written = fd_s->eventfd->write(*_8sizebuf); - } else - return -EBADF; - - - return bytes_written; -} - -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 - -long long sys_sendto(int s, void* msg, size_t len) { - return sys_write(s,msg,len); -} - -long long sys_lseek(int fd, long offset, int whence) { - arch::x86_64::process_t* proc = CURRENT_PROC; - - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - DEBUG(proc->is_debug,"lseek fd %d offset %lli, whence %d",fd,offset,whence); - - if(!fd_s) - return -EBADF; - - if(fd_s->state == USERSPACE_FD_STATE_PIPE || fd_s->is_a_tty) - return 0; - - switch (whence) - { - case SEEK_SET: - fd_s->offset = offset; - break; - - case SEEK_CUR: - fd_s->offset += offset; - break; - - case SEEK_END: { - vfs::stat_t stat; - int res = vfs::vfs::stat(fd_s,&stat); - - if(res != 0) { - return -res; - } - - fd_s->offset = stat.st_size + offset; - break; - } - - default: - return -EINVAL; - } - - return fd_s->offset; - -} - -long long sys_close(int fd) { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - if(!fd_s && fd > 2) - return -EBADF; - else if(fd < 3 && !fd_s) - return 0; // ignoring - - if(fd_s->state != USERSPACE_FD_STATE_SOCKET) { - DEBUG(proc->is_debug,"closing %d from proc %d pipe 0x%p",fd,proc->id,fd_s->pipe); - } else - DEBUG(proc->is_debug,"closing unix socket %d connected to proc %d from proc %d",fd,fd_s->socket_pid,proc->id); - - if(fd_s->can_be_closed) - return -EBADF; - - proc->fd_lock.lock(); - - if(fd < 3) - fd_s->can_be_closed = 1; - - if(fd_s->state == USERSPACE_FD_STATE_PIPE) { - fd_s->pipe->close(fd_s->pipe_side); - } else if(fd_s->state == USERSPACE_FD_STATE_FILE || fd_s->state == USERSPACE_FD_STATE_SOCKET) - vfs::vfs::close(fd_s); - else if(fd_s->state == USERSPACE_FD_STATE_EVENTFD) - fd_s->eventfd->close(); - - if(!fd_s->is_a_tty && fd_s->index > 2) - fd_s->state = USERSPACE_FD_STATE_UNUSED; - - proc->fd_lock.unlock(); - - return 0; -} - -long long sys_fstat(int fd, void* out) { - int flags = 0; - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - assert(sizeof(vfs::stat_t) == 144,"omg"); - - SYSCALL_IS_SAFEZ(out,4096); - memset(out,0,sizeof(vfs::stat_t)); - - if(!fd_s) - return -EBADF; - - if(!out) - return -EBADF; - - DEBUG(proc->is_debug,"Trying to fstat %s (fd %d) from proc %d",fd_s->path,fd,proc->id); - - if(fd_s->state == USERSPACE_FD_STATE_FILE) { - - vfs::stat_t stat; - int status; - if(flags & AT_SYMLINK_NOFOLLOW) { - status = vfs::vfs::nosym_stat(fd_s,&stat); - } - else - status = vfs::vfs::stat(fd_s,&stat); - if(status != 0) - return -status; - copy_in_userspace(proc,out,&stat,sizeof(vfs::stat_t)); - } else { - vfs::stat_t stat; - memset(&stat,0,sizeof(vfs::stat_t)); - if(fd_s->state == USERSPACE_FD_STATE_SOCKET) - stat.st_mode |= S_IFSOCK; - else if(fd_s->state == USERSPACE_FD_STATE_PIPE) - stat.st_mode |= S_IFIFO; - copy_in_userspace(proc,out,&stat,sizeof(vfs::stat_t)); - return 0; - } - //DEBUG(1,"ret ino %d",((vfs::stat_t*)out)->st_ino); - return 0; -} - - -long long sys_newfstatat(int fd, char* path, void* out, int_frame_t* ctx) { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_sz = vfs::fdmanager::search(proc,fd); - userspace_fd_t fd_tt; - userspace_fd_t* fd_s = &fd_tt; - - memset(out,0,sizeof(vfs::stat_t)); - - int flags = ctx->r10; - - if(!fd_sz && fd != -100) - return -EBADF; - - if(flags & AT_EMPTY_PATH && !path) { - if(!fd_sz) - return -EBADF; - fd_s = fd_sz; - } else { - - if(!path) - return -EINVAL; - - char first_path[2048]; - memset(first_path,0,2048); - if(fd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,fd)->path,strlen(vfs::fdmanager::search(proc,fd)->path)); - else if(fd == AT_FDCWD && proc->cwd) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - memset(&fd_tt,0,sizeof(userspace_fd_t)); - memcpy(fd_tt.path,result,strlen(result) + 1); - fd_tt.state = USERSPACE_FD_STATE_FILE; - } - - if(!out) - return -EINVAL; - - DEBUG(proc->is_debug,"Trying to newfstatat %s (fd %d), state %d from proc %d",fd_s->path,fd,proc->id); - - if(fd_s->state == USERSPACE_FD_STATE_FILE) { - - vfs::stat_t stat; - int status; - if(flags & AT_SYMLINK_NOFOLLOW) { - status = vfs::vfs::nosym_stat(fd_s,&stat); - } - else - status = vfs::vfs::stat(fd_s,&stat); - //DEBUG(1,"status %d\n",status); - if(status != 0) - return -status; - copy_in_userspace(proc,out,&stat,sizeof(vfs::stat_t)); - } else { - vfs::stat_t stat; - memset(&stat,0,sizeof(vfs::stat_t)); - if(fd_s->state == USERSPACE_FD_STATE_SOCKET) - stat.st_mode |= S_IFSOCK; - else if(fd_s->state == USERSPACE_FD_STATE_PIPE) - stat.st_mode |= S_IFIFO; - copy_in_userspace(proc,out,&stat,sizeof(vfs::stat_t)); - return 0; - } - //DEBUG(1,"ret ino %d",((vfs::stat_t*)out)->st_ino); - return 0; -} - -syscall_ret_t sys_pathstat(char* path, void* out, int flags, int_frame_t* ctx) { - SYSCALL_IS_SAFEA(path,4096); - if(!path) - return {0,EINVAL,0}; - - if(!out) - return {0,EINVAL,0}; - - arch::x86_64::process_t* proc = CURRENT_PROC; - - char first_path[2048]; - memset(first_path,0,2048); - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - if(result[0] == '\0') { - result[0] = '/'; - result[1] = '\0'; - } - - userspace_fd_t fd_s; - memcpy(fd_s.path,result,strlen(result) + 1); - fd_s.is_cached_path = 0; - - DEBUG(proc->is_debug,"Trying to stat %s from proc %d",result,proc->id); - - vfs::stat_t stat; - - memset(&stat,0,sizeof(vfs::stat_t)); - - int status; - if(flags & AT_SYMLINK_NOFOLLOW) { - status = vfs::vfs::nosym_stat(&fd_s,&stat); - } - else - status = vfs::vfs::stat(&fd_s,&stat); - if(status != 0) - return {0,status,0}; - copy_in_userspace(proc,out,&stat,sizeof(vfs::stat_t)); - - return {0,0,0}; -} - -long long sys_pipe(int* fildes) { - return sys_pipe2(fildes,0); -} - -long long sys_pipe2(int* fildes, int flags) { - - if(!fildes) - return -EINVAL; - - SYSCALL_IS_SAFEZ(fildes,4096); - - arch::x86_64::process_t* proc = CURRENT_PROC; - int read_fd = vfs::fdmanager::create(proc); - int write_fd = vfs::fdmanager::create(proc); - userspace_fd_t* fd1 = vfs::fdmanager::search(proc,read_fd); - userspace_fd_t* fd2 = vfs::fdmanager::search(proc,write_fd); - - vfs::pipe* new_pipe = new vfs::pipe(flags); - fd1->pipe_side = PIPE_SIDE_READ; - fd2->pipe_side = PIPE_SIDE_WRITE; - - fd1->pipe = new_pipe; - fd2->pipe = new_pipe; - - fd1->state = USERSPACE_FD_STATE_PIPE; - fd2->state = USERSPACE_FD_STATE_PIPE; - - fd1->is_cloexec = (flags & __O_CLOEXEC) ? 1 : 0; - fd2->is_cloexec = (flags & __O_CLOEXEC) ? 1 : 0; - - DEBUG(proc->is_debug,"Creating pipe %d-%d from proc %d, cloexec: %d (flags %d)",read_fd,write_fd,proc->id,flags & __O_CLOEXEC,flags); - - fildes[0] = read_fd; - fildes[1] = write_fd; - - return 0; -} - -long long sys_dup(int fd) { - int flags = 0; - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - if(!fd_s) - return -EBADF; - - proc->fd_lock.lock(); - - int i = 0; - userspace_fd_t* nfd_s = vfs::fdmanager::searchlowest(proc,0); - - if(!nfd_s) { - proc->fd_lock.unlock(); - int new_fd = vfs::fdmanager::create(proc); - nfd_s = vfs::fdmanager::search(proc,new_fd); - i = 1; - } - - DEBUG(proc->is_debug,"dup from %d to %d",fd,nfd_s->index); - - nfd_s->cycle = fd_s->cycle; - nfd_s->offset = fd_s->offset; - nfd_s->state = fd_s->state; - nfd_s->other_state = fd_s->other_state; - nfd_s->pipe = fd_s->pipe; - nfd_s->pipe_side = fd_s->pipe_side; - nfd_s->queue = fd_s->queue; - nfd_s->is_a_tty = fd_s->is_a_tty; - nfd_s->read_counter = fd_s->read_counter; - nfd_s->write_counter = fd_s->write_counter; - nfd_s->can_be_closed = 0; - nfd_s->write_socket_pipe = fd_s->write_socket_pipe; - nfd_s->read_socket_pipe = fd_s->read_socket_pipe; - nfd_s->eventfd = fd_s->eventfd; - nfd_s->flags = fd_s->flags; - - memcpy(nfd_s->path,fd_s->path,sizeof(fd_s->path)); - - if(nfd_s->state == USERSPACE_FD_STATE_PIPE) - nfd_s->pipe->create(nfd_s->pipe_side); - else if(nfd_s->state == USERSPACE_FD_STATE_EVENTFD) - nfd_s->eventfd->create(); - - if(i == 0) - proc->fd_lock.unlock(); - - return nfd_s->index; -} - -long long sys_dup2(int fd, int newfd) { - int flags = 0; - arch::x86_64::process_t* proc = CURRENT_PROC; - - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - if(!fd_s) - return -EBADF; - - userspace_fd_t* nfd_s = vfs::fdmanager::search(proc,newfd); - if(!nfd_s) { - int t = vfs::fdmanager::create(proc); - nfd_s = vfs::fdmanager::search(proc,t); - } else { - if(nfd_s->state == USERSPACE_FD_STATE_PIPE) - nfd_s->pipe->close(nfd_s->pipe_side); - else if(nfd_s->state == USERSPACE_FD_STATE_EVENTFD) - nfd_s->eventfd->close(); - } - - nfd_s->index = newfd; - nfd_s->cycle = fd_s->cycle; - nfd_s->offset = fd_s->offset; - nfd_s->state = fd_s->state; - nfd_s->other_state = fd_s->other_state; - nfd_s->pipe = fd_s->pipe; - nfd_s->pipe_side = fd_s->pipe_side; - nfd_s->queue = fd_s->queue; - nfd_s->is_a_tty = fd_s->is_a_tty; - nfd_s->write_counter = fd_s->write_counter; - nfd_s->read_counter = fd_s->read_counter; - nfd_s->can_be_closed = fd_s->can_be_closed; - nfd_s->read_socket_pipe = fd_s->read_socket_pipe; - nfd_s->write_socket_pipe = fd_s->write_socket_pipe; - nfd_s->eventfd = fd_s->eventfd; - nfd_s->flags = fd_s->flags; - nfd_s->is_cloexec = (flags & __O_CLOEXEC) ? 1 : 0; - - if(nfd_s->state == USERSPACE_FD_STATE_PIPE) - nfd_s->pipe->create(nfd_s->pipe_side); - else if(nfd_s->state == USERSPACE_FD_STATE_EVENTFD) - nfd_s->eventfd->create(); - - DEBUG(proc->is_debug,"dup2 from %d to %d from proc %d\n",fd,newfd,proc->id); - - memcpy(nfd_s->path,fd_s->path,sizeof(fd_s->path)); - - return nfd_s->index; -} - -syscall_ret_t sys_create_dev(std::uint64_t requestandnum, char* slave_path, char* master_path) { - char slave[256]; - char master[256]; - memset(slave,0,sizeof(slave)); - memset(master,0,sizeof(master)); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - copy_in_userspace_string(proc,slave,slave_path,256); - copy_in_userspace_string(proc,master,master_path,256); - - vfs::devfs_packet_t packet; - packet.size = requestandnum & 0xFFFFFFFF; - packet.request = (uint32_t)(requestandnum >> 32); - packet.value = (std::uint64_t)&master[0]; - - vfs::devfs::send_packet(slave,&packet); - return {0,0,0}; -} - -long long sys_ioctl(int fd, unsigned long request, void *arg) { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - if(!fd_s) - return -EBADF; - - DEBUG(proc->is_debug,"ioctl fd %d (%s) req 0x%p arg 0x%p\n",fd,fd_s->path,request,arg); - - int res = 0; - - SYSCALL_IS_SAFEZ((void*)arg,4096); - - std::int64_t ret = vfs::vfs::ioctl(fd_s,request,(void*)arg,&res); - - return ret != 0 ? -ret : 0; -} - -syscall_ret_t sys_create_ioctl(char* path, std::uint64_t write_and_read_req, std::uint32_t size) { - - std::int32_t read_req = write_and_read_req & 0xFFFFFFFF; - std::int32_t write_req = (uint32_t)(write_and_read_req >> 32); - - char path0[256]; - memset(path0,0,256); - - arch::x86_64::process_t* proc = CURRENT_PROC; - copy_in_userspace_string(proc,path0,path,256); - - vfs::devfs_packet_t packet; - packet.create_ioctl.readreg = read_req; - packet.create_ioctl.writereg = write_req; - packet.create_ioctl.request = DEVFS_PACKET_CREATE_IOCTL; - packet.create_ioctl.size = size; - packet.create_ioctl.pointer = (std::uint64_t)memory::pmm::_virtual::alloc(size); - vfs::devfs::send_packet(path0,&packet); - - return {0,0,0}; -} - -syscall_ret_t sys_setup_tty(char* path) { - - char path0[256]; - memset(path0,0,256); - - arch::x86_64::process_t* proc = CURRENT_PROC; - copy_in_userspace_string(proc,path0,path,256); - - vfs::devfs_packet_t packet; - packet.request = DEVFS_PACKET_SETUPTTY; - vfs::devfs::send_packet(path0,&packet); - - return {0,0,0}; -} - -syscall_ret_t sys_isatty(int fd) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return {0,EBADF,0}; - - if(fd_s->state == USERSPACE_FD_STATE_PIPE || fd_s->state == USERSPACE_FD_STATE_SOCKET) - return {0,ENOTTY,0}; - - int ret = vfs::vfs::var(fd_s,0,DEVFS_VAR_ISATTY); - - DEBUG(proc->is_debug,"sys_isatty %s fd %d ret %d",fd_s->path,fd,ret); - - fd_s->is_a_tty = ret == 0 ? 1 : 0; - - return {0,ret != 0 ? ENOTTY : 0,0}; -} - -syscall_ret_t sys_setupmmap(char* path, std::uint64_t addr, std::uint64_t size, int_frame_t* ctx) { - std::uint64_t flags = ctx->r8; - - char path0[256]; - memset(path0,0,256); - - arch::x86_64::process_t* proc = CURRENT_PROC; - copy_in_userspace_string(proc,path0,path,256); - - vfs::devfs_packet_t packet; - packet.request = DEVFS_SETUP_MMAP; - packet.setup_mmap.dma_addr = addr; - packet.setup_mmap.size = size; - packet.setup_mmap.flags = flags; - - vfs::devfs::send_packet(path0,&packet); - - return {0,0,0}; - -} - -syscall_ret_t sys_ptsname(int fd, void* out, int max_size) { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return {0,EBADF,0}; - - char buffer[256]; - memset(buffer,0,256); - - vfs::devfs_packet_t packet; - packet.value = (std::uint64_t)buffer; - packet.request = DEVFS_GETSLAVE_BY_MASTER; - - vfs::devfs::send_packet(fd_s->path + 4,&packet); - - if(strlen(buffer) >= max_size) - return {0,ERANGE,0}; - - char buffer2[256]; - memset(buffer2,0,256); - - __printfbuf(buffer2,256,"/dev%s",buffer); - zero_in_userspace(proc,out,max_size); - copy_in_userspace(proc,out,buffer2,strlen(buffer2)); - - return {0,0,0}; -} - -syscall_ret_t sys_setup_ring_bytelen(char* path, int bytelen) { - char path0[256]; - memset(path0,0,256); - - arch::x86_64::process_t* proc = CURRENT_PROC; - copy_in_userspace_string(proc,path0,path,256); - - vfs::devfs_packet_t packet; - packet.request = DEVFS_PACKET_SETUP_RING_SIZE; - packet.size = bytelen; - - vfs::devfs::send_packet(path0,&packet); - - return {0,0,0}; -} - -syscall_ret_t sys_read_dir(int fd, void* buffer) { - - SYSCALL_IS_SAFEA(buffer,4096); - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return {0,EBADF,0}; - - vfs::dirent_t dirent; - memset(&dirent,0,sizeof(vfs::dirent_t)); - - int status = vfs::vfs::ls(fd_s,&dirent); - - copy_in_userspace(proc,buffer,&dirent,sizeof(vfs::dirent_t)); - return {1,status,dirent.d_reclen}; - -} - -long long __fcntl_dup_fd(int fd, int is_cloexec, int lowest, int_frame_t* ctx) { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - if(!fd_s) - return -EBADF; - - proc->fd_lock.lock(); - - int i = 0; - userspace_fd_t* nfd_s = vfs::fdmanager::searchlowestfrom(proc,lowest); - - if(!nfd_s) { - proc->fd_lock.unlock(); - int new_fd = vfs::fdmanager::create(proc); - nfd_s = vfs::fdmanager::search(proc,new_fd); - i = 1; - } - - DEBUG(proc->is_debug,"dup from %d to %d",fd,nfd_s->index); - - nfd_s->cycle = fd_s->cycle; - nfd_s->offset = fd_s->offset; - nfd_s->state = fd_s->state; - nfd_s->other_state = fd_s->other_state; - nfd_s->pipe = fd_s->pipe; - nfd_s->pipe_side = fd_s->pipe_side; - nfd_s->queue = fd_s->queue; - nfd_s->is_a_tty = fd_s->is_a_tty; - nfd_s->read_counter = fd_s->read_counter; - nfd_s->write_counter = fd_s->write_counter; - nfd_s->can_be_closed = 0; - nfd_s->write_socket_pipe = fd_s->write_socket_pipe; - nfd_s->read_socket_pipe = fd_s->read_socket_pipe; - nfd_s->eventfd = fd_s->eventfd; - nfd_s->flags = fd_s->flags; - - memcpy(nfd_s->path,fd_s->path,sizeof(fd_s->path)); - - if(nfd_s->state == USERSPACE_FD_STATE_PIPE) - nfd_s->pipe->create(nfd_s->pipe_side); - else if(nfd_s->state == USERSPACE_FD_STATE_EVENTFD) - nfd_s->eventfd->create(); - - if(i == 0) - proc->fd_lock.unlock(); - - return nfd_s->index; -} - -#define F_DUPFD_CLOEXEC 1030 -#define F_GETFD 1 -#define F_SETFD 2 - -long long sys_fcntl(int fd, int request, std::uint64_t arg, int_frame_t* ctx) { - - arch::x86_64::process_t* pproc = CURRENT_PROC; - - DEBUG(pproc->is_debug,"fcntl fd %d req %d arg 0x%p from proc %d",fd,request,arg,pproc->id); - int is_cloexec = 0; - switch(request) { - case F_DUPFD_CLOEXEC: - is_cloexec = 1; - case F_DUPFD: { - long long r = __fcntl_dup_fd(fd,is_cloexec,arg,ctx); - DEBUG(pproc->is_debug,"return fd %d from dup fcntl from proc %d",r,pproc->id); - return r; - } - - case F_GETFD: { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return -EBADF; - return fd_s->is_cloexec; - } - - case F_SETFD: { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return -EBADF; - - fd_s->is_cloexec = arg & 1; - return 0; - } - - case F_GETFL: { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return -EBADF; - - return (fd_s->flags & ~(O_RDONLY | O_WRONLY)) | O_RDWR; - } - - case F_SETFL: { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - if(!fd_s) - return -EBADF; - - fd_s->flags &= ~(O_APPEND | O_ASYNC | O_NONBLOCK | O_RDONLY | O_RDWR | O_WRONLY); - fd_s->flags |= (arg & (O_APPEND | O_ASYNC | O_NONBLOCK | O_RDONLY | O_RDWR | O_WRONLY)); - if(fd_s->state == USERSPACE_FD_STATE_EVENTFD) { - fd_s->eventfd->flags &= ~(O_NONBLOCK); - fd_s->eventfd->flags |= (arg & O_NONBLOCK); - } - - return 0; - } - - default: { - Log::SerialDisplay(LEVEL_MESSAGE_WARN,"Unsupported fcntl %d arg 0x%p to fd %d from proc %d\n",request,arg,fd,pproc->id); - return 0; - } - } - return -EINVAL; -} - -long long sys_chdir(char* path) { - arch::x86_64::process_t* proc = CURRENT_PROC; - SYSCALL_IS_SAFEZ(path,4096); - - if(!path) - return -EINVAL; - - int dirfd = AT_FDCWD; - - char first_path[2048]; - memset(first_path,0,2048); - if(dirfd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - userspace_fd_t fd_s; - memset(&fd_s,0,sizeof(userspace_fd_t)); - memcpy(fd_s.path,result,strlen(result) + 1); - - vfs::stat_t stat; - int ret = vfs::vfs::stat(&fd_s,&stat); - - if(ret != 0) - return -ret; - - if(!(stat.st_mode & S_IFDIR)) - return -ENOTDIR; - - memcpy(proc->cwd,result,strlen(result) + 1); - return 0; -} - -long long sys_fchdir(int fd) { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return -EBADF; - - vfs::stat_t stat; - int ret = vfs::vfs::stat(fd_s,&stat); - - if(ret != 0) - return -ret; - - if(!(stat.st_mode & S_IFDIR)) - return -ENOTDIR; - - memset(proc->cwd,0,4096); - memcpy(proc->cwd,fd_s->path,2048); - - return 0; - -} - -syscall_ret_t sys_mkfifoat(int dirfd, const char *path, int mode) { - SYSCALL_IS_SAFEA((void*)path,0); - - arch::x86_64::process_t* proc = CURRENT_PROC; - char first_path[2048]; - memset(first_path,0,2048); - if(dirfd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - userspace_fd_t new_fd_s; - new_fd_s.is_cached_path = 0; - memset(new_fd_s.path,0,2048); - memcpy(new_fd_s.path,result,strlen(result)); - - vfs::stat_t stat; - - if(vfs::vfs::stat(&new_fd_s,&stat) == 0) - return {0,EEXIST,0}; - - int status = vfs::vfs::create_fifo(result); - - - return {0,status,0}; -} - -void poll_to_str(int event, char* out) { - const char* result = "Undefined"; - if(event & POLLIN && event & POLLOUT) { - result = "POLLIN and POLLOUT"; - } else if(event & POLLIN) { - result = "POLLIN"; - } else if(event & POLLOUT) { - result = "POLLOUT"; - } - memcpy(out,result,strlen(result) + 1); -} - -long long sys_poll(struct pollfd *fds, int count, int timeout, int_frame_t* ctx) { - if(ctx->rax != 270) { // ban returning efault from pselect - SYSCALL_IS_SAFEZ((void*)fds,0); - } - - if(!fds) - return -EINVAL; - - arch::x86_64::process_t* proc = CURRENT_PROC; - proc->debug0 = count; - proc->debug1 = timeout; - - struct pollfd* fd = fds; - - int total_events = 0; - - userspace_fd_t* cached_fds[count]; - - for(int i = 0;i < count; i++) { - fd[i].revents = 0; - } - - for(int i = 0;i < count; i++) { - userspace_fd_t* fd0 = vfs::fdmanager::search(proc,fd[i].fd); - - cached_fds[i] = fd0; - - fd[i].revents = 0; - - - if(!fd0) { return -EBADF;} - - if(fd[i].events & POLLIN) - total_events++; - - if(fd[i].events & POLLOUT) { - - total_events++; - } - - char out[64]; - if(proc->is_debug) { - poll_to_str(fd[i].events,out); - - DEBUG(1,"Trying to poll %s (%d) timeout %d event %s with state %d is_listen %d from proc %d (%s)",fd0->state == USERSPACE_FD_STATE_FILE ? fd0->path : "Not file",fd0->index,timeout,out,fd0->state,fd0->is_listen,proc->id,proc->name); - - } - } - - int num_events = 0; - - int success = true; - int something_bad = 0; - - int retry = 0; - - int is_first = 1; - - if(timeout == -1) { - while(success) { - - for(int i = 0;i < count; i++) { - userspace_fd_t* fd0 = cached_fds[i]; - if(fd[i].events & POLLIN) { - - if(fd0->state == USERSPACE_FD_STATE_SOCKET && !fd0->is_listen && fd0->write_socket_pipe && fd0->read_socket_pipe) { - int if_pollin = 0; - - if(fd0->other_state == USERSPACE_FD_OTHERSTATE_MASTER) { - if_pollin = fd0->write_socket_pipe->size.load() > 0 ? 1 : 0; - } else { - if_pollin = fd0->read_socket_pipe->size.load() > 0 ? 1 : 0; - } - if(if_pollin) { - //DEBUG(fd0->index == 18 || fd0->index == 19 || fd0->index == 20,"polin done fd %d writ sock 0x%p pip 0x%p",fd0->index,fd0->write_socket_pipe,fd0->pipe); - num_events++; - fd[i].revents |= POLLIN; - } - - if(fd0->write_socket_pipe->is_closed.test() && !if_pollin) { - num_events++; - fd[i].revents |= POLLHUP; - } - } else if(fd0->state == USERSPACE_FD_STATE_SOCKET && fd0->is_listen && fd0->binded_socket) { - if(fd0->read_counter == -1) - fd0->read_counter = 0; - socket_node_t* nod = (socket_node_t*)fd0->binded_socket; - if(nod->socket_counter > (std::uint64_t)fd0->read_counter) { - fd0->read_counter++; - num_events++; - fd[i].revents |= POLLIN; - } - } else if(fd0->state == USERSPACE_FD_STATE_PIPE) { - if(fd0->pipe_side != PIPE_SIDE_READ) - continue; - if(fd0->pipe->size.load() > 0) { - num_events++; - fd[i].revents |= POLLIN; - } - } else if(fd0->state == USERSPACE_FD_STATE_EVENTFD) { - fd0->eventfd->lock.lock(); - if(fd0->eventfd->buffer > 0) { - num_events++; - fd[i].revents |= POLLIN; - } - fd0->eventfd->lock.unlock(); - } else { - - std::int64_t ret = vfs::vfs::poll(fd0,POLLIN); - if(ret != 0) { - num_events++; - fd[i].revents |= POLLIN; - } - } - } - - if(fd[i].events & POLLOUT) { - if(fd0->state == USERSPACE_FD_STATE_SOCKET && fd0->write_socket_pipe && fd0->read_socket_pipe && !fd0->is_listen) { - int is_pollout = 0; - if(fd0->other_state == USERSPACE_FD_OTHERSTATE_MASTER) { - if(fd0->read_socket_pipe->size.load() < fd0->read_socket_pipe->total_size) - is_pollout = 1; - } else { - if(fd0->write_socket_pipe->size.load() < fd0->write_socket_pipe->total_size) - is_pollout = 1; - } - - if(is_pollout) { - num_events++; - fd[i].revents |= POLLOUT; - } - } else if(fd0->state == USERSPACE_FD_STATE_EVENTFD) { - fd0->eventfd->lock.lock(); - if(fd0->eventfd->buffer <= (0xFFFFFFFFFFFFFFFF - 1)) { - num_events++; - fd[i].revents |= POLLOUT; - } - fd0->eventfd->lock.unlock(); - } else if(fd0->state == USERSPACE_FD_STATE_PIPE) { - if(fd0->pipe_side != PIPE_SIDE_READ) - continue; - if(fd0->pipe->size.load() < fd0->pipe->total_size) { - num_events++; - fd[i].revents |= POLLOUT; - } - } else { - std::int64_t ret = vfs::vfs::poll(fd0,POLLOUT); - - if(ret != 0) { - num_events++; - fd[i].revents |= POLLOUT; - } - } - - } - - - - if(num_events) - success = false; - } - - if(success) - yield(); - asm volatile("pause"); - } - } else { - int tries = 0; - std::uint64_t current_timestamp = drivers::tsc::currentus(); - std::uint64_t end_timestamp = (current_timestamp + (timeout * 1000)); - while(drivers::tsc::currentus() < end_timestamp && success) { - for(int i = 0;i < count; i++) { - userspace_fd_t* fd0 = cached_fds[i]; - if(fd[i].events & POLLIN) { - //std::int64_t ret = vfs::vfs::poll(fd0,POLLIN); - if(fd[i].events & POLLIN) { - - if(fd0->state == USERSPACE_FD_STATE_SOCKET && !fd0->is_listen && fd0->write_socket_pipe && fd0->read_socket_pipe) { - int if_pollin = 0; - - if(fd0->other_state == USERSPACE_FD_OTHERSTATE_MASTER) { - if_pollin = fd0->write_socket_pipe->size.load() > 0 ? 1 : 0; - } else { - if_pollin = fd0->read_socket_pipe->size.load() > 0 ? 1 : 0; - } - if(if_pollin) { - //DEBUG(fd0->index == 18 || fd0->index == 19 || fd0->index == 20,"polin done fd %d writ sock 0x%p pip 0x%p",fd0->index,fd0->write_socket_pipe,fd0->pipe); - num_events++; - fd[i].revents |= POLLIN; - } - - if(fd0->write_socket_pipe->is_closed.test() && !if_pollin) { - num_events++; - fd[i].revents |= POLLHUP; - } - - } else if(fd0->state == USERSPACE_FD_STATE_SOCKET && fd0->is_listen && fd0->binded_socket) { - if(fd0->read_counter == -1) - fd0->read_counter = 0; - - socket_node_t* nod = (socket_node_t*)fd0->binded_socket; - if(nod->socket_counter > (std::uint64_t)fd0->read_counter) { - fd0->read_counter++; - num_events++; - fd[i].revents |= POLLIN; - } - } else if(fd0->state == USERSPACE_FD_STATE_PIPE) { - if(fd0->pipe->size.load() > 0) { - num_events++; - fd[i].revents |= POLLIN; - } - } else if(fd0->state == USERSPACE_FD_STATE_EVENTFD) { - fd0->eventfd->lock.lock(); - if(fd0->eventfd->buffer > 0) { - num_events++; - fd[i].revents |= POLLIN; - } - fd0->eventfd->lock.unlock(); - } else { - - std::int64_t ret = vfs::vfs::poll(fd0,POLLIN); - - if(ret != 0) { - num_events++; - fd[i].revents |= POLLIN; - } - } - } - - } - - if(fd[i].events & POLLOUT) { - if(fd0->state == USERSPACE_FD_STATE_SOCKET) { - int is_pollout = 0; - if(fd0->other_state == USERSPACE_FD_OTHERSTATE_MASTER) { - if(fd0->read_socket_pipe->size.load() < fd0->read_socket_pipe->total_size) - is_pollout = 1; - } else { - if(fd0->write_socket_pipe->size.load() < fd0->write_socket_pipe->total_size) - is_pollout = 1; - } - - if(is_pollout) { - num_events++; - fd[i].revents |= POLLOUT; - } - } else if(fd0->state == USERSPACE_FD_STATE_EVENTFD) { - fd0->eventfd->lock.lock(); - if(fd0->eventfd->buffer <= (0xFFFFFFFFFFFFFFFF - 1)) { - num_events++; - fd[i].revents |= POLLOUT; - } - fd0->eventfd->lock.unlock(); - } else if(fd0->state == USERSPACE_FD_STATE_PIPE) { - if(fd0->pipe->size < fd0->pipe->total_size) { - num_events++; - fd[i].revents |= POLLOUT; - } - } else { - std::int64_t ret = vfs::vfs::poll(fd0,POLLOUT); - if(ret != 0) { - num_events++; - fd[i].revents |= POLLOUT; - } - } - - } - - if(num_events) - success = false; - // w - } - - if(timeout == 0) - break; - - std::uint64_t start = drivers::tsc::currentus(); - if(drivers::tsc::currentus() < end_timestamp && success) { - yield(); - std::uint64_t now = drivers::tsc::currentus(); - } - - } - } - - DEBUG(proc->is_debug,"%d from proc %d num_ev %d",timeout,proc->id,num_events); - //copy_in_userspace(proc,fds,fd,count * sizeof(struct pollfd)); - return num_events; - - -} - -long long sys_pselect6(int num_fds, fd_set* read_set, fd_set* write_set, int_frame_t* ctx) { - fd_set* except_set = (fd_set*)ctx->r10; - timespec* timeout = (timespec*)ctx->r8; - sigset_t* sigmask = (sigset_t*)ctx->r9; - - arch::x86_64::process_t* proc = CURRENT_PROC; - - DEBUG(proc->is_debug,"Trying to pselect num_fds %d, read_set 0x%p, write_set 0x%p, except_set 0x%p, timeout 0x%p from proc %d",num_fds,read_set,write_set,except_set,timeout,proc->id); - - SYSCALL_IS_SAFEZ(read_set,4096); - SYSCALL_IS_SAFEZ(write_set,4096); - SYSCALL_IS_SAFEZ(except_set,4096); - SYSCALL_IS_SAFEZ(timeout,4096); - - pollfd fds[num_fds]; - memset(fds,0,sizeof(fds)); - - int actual_count = 0; - - for(int fd = 0; fd < num_fds; ++fd) { - short events = 0; - if(read_set && FD_ISSET(fd, read_set)) { - events |= POLLIN; - } - - if(write_set && FD_ISSET(fd, write_set)) { - events |= POLLOUT; - } - - if(except_set && FD_ISSET(fd, except_set)) { - events |= POLLIN; - } - - if(events) { - fds[actual_count].fd = fd; - fds[actual_count].events = events; - fds[actual_count].revents = 0; - actual_count++; - } - } - - long long num; - - if(timeout) { - num = sys_poll(fds, actual_count, (timeout->tv_sec * 1000) + (timeout->tv_nsec / (1000 * 1000)), ctx); - } else { - num = sys_poll(fds, actual_count, -1, ctx); - } - - DEBUG(proc->is_debug,"pselect6 to poll status %lli",num); - - if(num < 0) - return num; - - #define READ_SET_POLLSTUFF (POLLIN | POLLHUP | POLLERR) - #define WRITE_SET_POLLSTUFF (POLLOUT | POLLERR) - #define EXCEPT_SET_POLLSTUFF (POLLPRI) - - int return_count = 0; - for(int fd = 0; fd < actual_count; ++fd) { - int events = fds[fd].events; - if((events & POLLIN) && (fds[fd].revents & READ_SET_POLLSTUFF) == 0) { - FD_CLR(fds[fd].fd, read_set); - events &= ~POLLIN; - } - - if((events & POLLOUT) && (fds[fd].revents & WRITE_SET_POLLSTUFF) == 0) { - FD_CLR(fds[fd].fd, write_set); - events &= ~POLLOUT; - } - - if(events) - return_count++; - } - return return_count; -} - -long long sys_readlinkat(int dirfd, const char* path, void* buffer, int_frame_t* ctx) { - std::size_t max_size = ctx->r10; - - SYSCALL_IS_SAFEZ((void*)path,4096); - SYSCALL_IS_SAFEZ((void*)buffer,max_size); - - if(!path || !buffer || !max_size) - return -EINVAL; - - arch::x86_64::process_t* proc = CURRENT_PROC; - - if(!vfs::fdmanager::search(proc,dirfd) && dirfd != AT_FDCWD) { DEBUG(1,"AAA %d\n",dirfd); - return -EBADF; } - - - char first_path[2048]; - memset(first_path,0,2048); - if(dirfd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - char readlink_buf[2048]; - memset(readlink_buf,0,2048); - vfs::vfs::lock(); - int ret = vfs::vfs::extern_readlink(result,readlink_buf,2048); - vfs::vfs::unlock(); - - if(ret != 0) { - return -ret; - } - - copy_in_userspace(proc,buffer,readlink_buf, strlen(readlink_buf) > max_size ? max_size : strlen(readlink_buf)); - - return (int64_t)(strlen(readlink_buf) > max_size ? max_size : strlen(readlink_buf)); -} - -long long sys_readlink(char* path, void* buffer, int max_size) { - - int dirfd = AT_FDCWD; - - SYSCALL_IS_SAFEZ((void*)path,4096); - SYSCALL_IS_SAFEZ((void*)buffer,max_size); - - if(!path || !buffer || !max_size) - return -EINVAL; - - arch::x86_64::process_t* proc = CURRENT_PROC; - - char first_path[2048]; - memset(first_path,0,2048); - if(dirfd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - char readlink_buf[2048]; - memset(readlink_buf,0,2048); - vfs::vfs::lock(); - int ret = vfs::vfs::extern_readlink(result,readlink_buf,2048); - vfs::vfs::unlock(); - - if(ret != 0) { - return -ret; - } - - copy_in_userspace(proc,buffer,readlink_buf, strlen(readlink_buf) > max_size ? max_size : strlen(readlink_buf)); - - return (int64_t)(strlen(readlink_buf) > max_size ? max_size : strlen(readlink_buf)); -} - -long long sys_link(char* old_path, char* new_path) { - - SYSCALL_IS_SAFEZ((void*)old_path,2048); - SYSCALL_IS_SAFEZ((void*)new_path,2048); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - if(!old_path || !new_path) - return -EINVAL; - - char first_path[2048]; - memset(first_path,0,2048); - if(0) - memcpy(first_path,vfs::fdmanager::search(proc,0)->path,strlen(vfs::fdmanager::search(proc,0)->path)); - else if(1) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)old_path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - char first_path2[2048]; - memset(first_path2,0,2048); - if(0) - memcpy(first_path2,vfs::fdmanager::search(proc,0)->path,strlen(vfs::fdmanager::search(proc,0)->path)); - else if(1) - memcpy(first_path2,proc->cwd,strlen(proc->cwd)); - - char kpath2[2048]; - memset(kpath2,0,2048); - copy_in_userspace_string(proc,kpath2,(void*)new_path,2048); - - char result2[2048]; - memset(result2,0,2048); - vfs::resolve_path(kpath2,first_path2,result2,1,0); - - int ret = vfs::vfs::create(result2,VFS_TYPE_SYMLINK); - - if(ret != 0) - return ret; - - userspace_fd_t fd; - fd.is_cached_path = 0; - fd.offset = 0; - memset(fd.path,0,2048); - memcpy(fd.path,result2,strlen(result2)); - - ret = vfs::vfs::write(&fd,result,2047); - - return 0; - -} - -long long sys_linkat(int oldfd, char* old_path, int newfd, int_frame_t* ctx) { - - char* new_path = (char*)ctx->r10; - - SYSCALL_IS_SAFEZ((void*)old_path,2048); - SYSCALL_IS_SAFEZ((void*)new_path,2048); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - if(!old_path || !new_path) - return -EINVAL; - - char first_path[2048]; - memset(first_path,0,2048); - if(oldfd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,oldfd)->path,strlen(vfs::fdmanager::search(proc,oldfd)->path)); - else if(oldfd == AT_FDCWD) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)old_path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - char first_path2[2048]; - memset(first_path2,0,2048); - if(oldfd >= 0) - memcpy(first_path2,vfs::fdmanager::search(proc,newfd)->path,strlen(vfs::fdmanager::search(proc,newfd)->path)); - else if(oldfd == AT_FDCWD) - memcpy(first_path2,proc->cwd,strlen(proc->cwd)); - - char kpath2[2048]; - memset(kpath2,0,2048); - copy_in_userspace_string(proc,kpath2,(void*)new_path,2048); - - char result2[2048]; - memset(result2,0,2048); - vfs::resolve_path(kpath2,first_path2,result2,1,0); - - int ret = vfs::vfs::create(result2,VFS_TYPE_SYMLINK); - - if(ret != 0) - return ret; - - userspace_fd_t fd; - fd.is_cached_path = 0; - fd.offset = 0; - memset(fd.path,0,2048); - memcpy(fd.path,result2,strlen(result2)); - - ret = vfs::vfs::write(&fd,result,2047); - - return 0; - -} - -long long sys_symlink(char* old, char* path) { - return sys_symlinkat(old,AT_FDCWD,path); -} - -long long sys_symlinkat(char* old, int dirfd, char* path) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - - SYSCALL_IS_SAFEZ(old,4096); - SYSCALL_IS_SAFEZ(path,4096); - - if(!old || !path) - return -EINVAL; - - char first_path[2048]; - memset(first_path,0,2048); - if(dirfd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - if(old[0] == '\0') - return -EINVAL; - - int ret = vfs::vfs::create(result,VFS_TYPE_SYMLINK); - - if(ret != 0) - return ret; - - userspace_fd_t fd; - fd.is_cached_path = 0; - fd.offset = 0; - memset(fd.path,0,2048); - memcpy(fd.path,result,strlen(result)); - - ret = vfs::vfs::write(&fd,old,strlen(old) + 1); - - DEBUG(1,"%s (%s) to %s\n",result,path,old); - - return 0; - -} - -long long sys_mkdir(char* path, int mode) { - return sys_mkdirat(AT_FDCWD,path,mode); -} - -long long sys_mkdirat(int dirfd, char* path, int mode) { - SYSCALL_IS_SAFEZ((void*)path,4096); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - char first_path[2048]; - memset(first_path,0,2048); - if(dirfd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - int ret = vfs::vfs::create(result,VFS_TYPE_DIRECTORY); - - //DEBUG(1,"mkdir %s %d\n",result,ret); - - userspace_fd_t fd; - fd.is_cached_path = 0; - memcpy(fd.path,result,2048); - - vfs::vfs::var(&fd,mode,TMPFS_VAR_CHMOD | (1 << 7)); - return ret; -} - -long long sys_unlink(char* path) { - return sys_unlinkat(AT_FDCWD,path,0); -} - -long long sys_unlinkat(int dirfd, const char* path, int flags) { - SYSCALL_IS_SAFEZ((void*)path,4096); - if(!path) - return -EINVAL; - - arch::x86_64::process_t* proc = CURRENT_PROC; - - char first_path[2048]; - memset(first_path,0,2048); - if(dirfd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD && proc->cwd) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - userspace_fd_t fd; - fd.is_cached_path = 0; - memset(&fd,0,sizeof(fd)); - memcpy(fd.path,result,2048); - - return vfs::vfs::unlink(&fd); -} - -long long sys_chmod(char* path, int mode) { - SYSCALL_IS_SAFEZ((void*)path,0); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - if(!path) - return -EINVAL; - - char first_path[2048]; - memset(first_path,0,2048); - if(0) - memcpy(first_path,vfs::fdmanager::search(proc,0)->path,strlen(vfs::fdmanager::search(proc,0)->path)); - else if(1) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - userspace_fd_t fd; - fd.is_cached_path = 0; - memset(&fd,0,sizeof(fd)); - memcpy(fd.path,result,2048); - - uint64_t value; - int ret = vfs::vfs::var(&fd,(uint64_t)&value,TMPFS_VAR_CHMOD); - - if(ret != 0) - return -ret; - - ret = vfs::vfs::var(&fd,value | mode, TMPFS_VAR_CHMOD | (1 << 7)); - - - - return -ret; -} - -long long sys_fchmod(int fd, int mode) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return -EBADF; - - uint64_t value; - int ret = vfs::vfs::var(fd_s,(uint64_t)&value,TMPFS_VAR_CHMOD); - - if(ret != 0) - return -ret; - - ret = vfs::vfs::var(fd_s,value | mode, TMPFS_VAR_CHMOD | (1 << 7)); - - return -ret; -} - -long long sys_fchmodat(int dirfd, const char* path, int mode, int_frame_t* ctx) { - SYSCALL_IS_SAFEZ((void*)path,4096); - if(!path) - return -EFAULT; - - arch::x86_64::process_t* proc = CURRENT_PROC; - - char first_path[2048]; - memset(first_path,0,2048); - if(dirfd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD && proc->cwd) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - - userspace_fd_t fd; - fd.is_cached_path = 0; - memset(&fd,0,sizeof(fd)); - memcpy(fd.path,result,2048); - - uint64_t value; - int ret = vfs::vfs::var(&fd,(uint64_t)&value,TMPFS_VAR_CHMOD); - - if(ret != 0) - return -ret; - - DEBUG(proc->is_debug,"chmodz %s %d\n",path,mode); - - ret = vfs::vfs::var(&fd,value | mode, TMPFS_VAR_CHMOD | (1 << 7)); - - return -ret; - -} - -long long sys_fchmodat2(int dirfd, const char* path, int mode, int_frame_t* ctx) { - - int flags = ctx->r10 & 0xffffffff; - - SYSCALL_IS_SAFEZ((void*)path,4096); - if(!path) - return -EFAULT; - - arch::x86_64::process_t* proc = CURRENT_PROC; - - userspace_fd_t* fd_sz = vfs::fdmanager::search(proc,dirfd); - userspace_fd_t fd_tt; - userspace_fd_t* fd_s = &fd_tt; - - if(!fd_sz && dirfd != -100) - return -EBADF; - - if(flags & AT_EMPTY_PATH && !path) { - if(!fd_sz) - return -EBADF; - fd_s = fd_sz; - } else { - - if(!path) - return -EINVAL; - - char first_path[2048]; - memset(first_path,0,2048); - if(dirfd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD && proc->cwd) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - memset(&fd_tt,0,sizeof(userspace_fd_t)); - memcpy(fd_tt.path,result,strlen(result) + 1); - fd_tt.state = USERSPACE_FD_STATE_FILE; - } - - - uint64_t value; - int ret = vfs::vfs::var(fd_s,(uint64_t)&value,TMPFS_VAR_CHMOD); - - if(ret != 0) - return -ret; - - DEBUG(proc->is_debug,"chmodz %s %d\n",path,mode); - - ret = vfs::vfs::var(fd_s,value | mode, TMPFS_VAR_CHMOD | (1 << 7)); - - return -ret; - -} - -syscall_ret_t sys_ttyname(int fd, char *buf, size_t size) { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return {0,EBADF,0}; - - if(!buf) - return {0,EINVAL,0}; - - SYSCALL_IS_SAFEA(buf,2048); - - int ret = vfs::vfs::var(fd_s,0,DEVFS_VAR_ISATTY); - - fd_s->is_a_tty = ret == 0 ? 1 : 0; - - if(!fd_s->is_a_tty) - return {0,ENOTTY,0}; - - zero_in_userspace(proc,buf,size); - if(strlen(fd_s->path) > size) - return {0,ERANGE,0}; - - copy_in_userspace(proc,buf,fd_s->path,strlen(fd_s->path)); - return {0,0,0}; -} - -long long sys_renameat(int olddir, char* old, int newdir, int_frame_t* ctx) { - char* newp = (char*)ctx->r10; - SYSCALL_IS_SAFEZ((void*)old,0); - SYSCALL_IS_SAFEZ((void*)newp,0); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - int dirfd = olddir; - - char old_built[2048]; - memset(old_built,0,2048); - if(dirfd >= 0) - memcpy(old_built,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD && proc->cwd) - memcpy(old_built,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)old,2048); - - char old_path_resolved[2048]; - memset(old_path_resolved,0,2048); - vfs::resolve_path(kpath,old_built,old_path_resolved,1,0); - - dirfd = newdir; - - char new_built[2048]; - memset(new_built,0,2048); - if(dirfd >= 0) - memcpy(new_built,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD && proc->cwd) - memcpy(new_built,proc->cwd,strlen(proc->cwd)); - - char kzpath[2048]; - memset(kzpath,0,2048); - copy_in_userspace_string(proc,kzpath,(void*)newp,2048); - - char new_path_resolved[2048]; - memset(new_path_resolved,0,2048); - vfs::resolve_path(kzpath,new_built,new_path_resolved,1,0); - - int status = vfs::vfs::rename(old_path_resolved,new_path_resolved); - - return status; -} - -long long sys_rename(char* old, char* newp) { - SYSCALL_IS_SAFEZ((void*)old,4096); - SYSCALL_IS_SAFEZ((void*)newp,4096); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - char first_path[2048]; - memset(first_path,0,2048); - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)old,2048); - char old_path[2048]; - memset(old_path,0,2048); - vfs::resolve_path(kpath,first_path,old_path,1,0); - if(old_path[0] == '\0') { - old_path[0] = '/'; - old_path[1] = '\0'; - } - - memset(first_path,0,2048); - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)newp,2048); - char new_path[2048]; - memset(new_path,0,2048); - vfs::resolve_path(kpath,first_path,new_path,1,0); - if(new_path[0] == '\0') { - new_path[0] = '/'; - new_path[1] = '\0'; - } - - int status = vfs::vfs::rename(old_path,new_path); - - return status; -} - -typedef __SIZE_TYPE__ __mlibc_size; - -struct iovec { - void *iov_base; - __mlibc_size iov_len; -}; - -typedef unsigned socklen_t; - -struct msghdr { - void *msg_name; - socklen_t msg_namelen; - struct iovec *msg_iov; -#if __INTPTR_WIDTH__ == 64 && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - int __pad0; -#endif - int msg_iovlen; -#if __INTPTR_WIDTH__ == 64 && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - int __pad0; -#endif - void *msg_control; -#if __INTPTR_WIDTH__ == 64 && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - int __pad1; -#endif - socklen_t msg_controllen; -#if __INTPTR_WIDTH__ == 64 && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - int __pad1; -#endif - int msg_flags; -}; - -struct cmsghdr { -#if __INTPTR_WIDTH__ == 64 && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - int __pad; -#endif - socklen_t cmsg_len; -#if __INTPTR_WIDTH__ == 64 && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - int __pad; -#endif - int cmsg_level; - int cmsg_type; -}; - -#define SOL_SOCKET 1 - -#define SCM_RIGHTS 1 -#define SCM_CREDENTIALS 2 - -#define __CMSG_ALIGN(s) (((s) + __alignof__(size_t) - 1) & \ - ~(__alignof__(size_t) - 1)) - -#if defined(_DEFAULT_SOURCE) -#define CMSG_ALIGN(s) __CMSG_ALIGN(s) -#endif /* defined(_DEFAULT_SOURCE) */ - -/* Basic macros to return content and padding size of a control message. */ -#define CMSG_LEN(s) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + (s)) -#define CMSG_SPACE(s) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + __CMSG_ALIGN(s)) - -/* Provides access to the data of a control message. */ -#define CMSG_DATA(c) ((unsigned char *)(c) + __CMSG_ALIGN(sizeof(struct cmsghdr))) - -#define __MLIBC_CMSG_NEXT(c) ((char *)(c) + __CMSG_ALIGN((c)->cmsg_len)) -#define __MLIBC_MHDR_LIMIT(m) ((char *)(m)->msg_control + (m)->msg_controllen) - -/* For parsing control messages only. */ -/* Returns a pointer to the first header or nullptr if there is none. */ -#define CMSG_FIRSTHDR(m) ((size_t)(m)->msg_controllen <= sizeof(struct cmsghdr) \ - ? (struct cmsghdr *)0 : (struct cmsghdr *) (m)->msg_control) - -/* For parsing control messages only. */ -/* Returns a pointer to the next header or nullptr if there is none. */ -#define CMSG_NXTHDR(m, c) \ - ((c)->cmsg_len < sizeof(struct cmsghdr) || \ - (std::int64_t)(sizeof(struct cmsghdr) + __CMSG_ALIGN((c)->cmsg_len)) \ - >= __MLIBC_MHDR_LIMIT(m) - (char *)(c) \ - ? (struct cmsghdr *)0 : (struct cmsghdr *)__MLIBC_CMSG_NEXT(c)) - -syscall_ret_t sys_msg_send(int fd, struct msghdr* hdr, int flags) { - struct msghdr* msg = hdr; - SYSCALL_IS_SAFEA(hdr,sizeof(struct msghdr)); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return {1,EBADF,0}; - - vfs::pipe* target_pipe = fd_s->other_state == USERSPACE_FD_OTHERSTATE_MASTER ? fd_s->read_socket_pipe : fd_s->write_socket_pipe; - if(!target_pipe) - return {1,EBADF,0}; - - std::uint64_t total_size = 0; - for (int i = 0; i < hdr->msg_iovlen; i++) { - SYSCALL_IS_SAFEA(hdr->msg_iov[i].iov_base,hdr->msg_iov[i].iov_len); - total_size += hdr->msg_iov[i].iov_len; - } - - if(total_size > target_pipe->total_size) - return {1,EMSGSIZE,0}; - - target_pipe->lock.lock(); - std::uint64_t space_left = target_pipe->total_size - target_pipe->size; - target_pipe->lock.unlock(); - while(space_left < total_size) { - yield(); - target_pipe->lock.lock(); - space_left = target_pipe->total_size - target_pipe->size; - target_pipe->lock.unlock(); - } - - target_pipe->lock.lock(); - - struct cmsghdr *cmsg = 0; - - for (cmsg = CMSG_FIRSTHDR(msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(msg, cmsg)) { - Log::SerialDisplay(LEVEL_MESSAGE_FAIL,"hello %d\n",cmsg->cmsg_type); - - if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { - DEBUG(1,"scm\n"); - int new_fd = 0; - memcpy(&new_fd, CMSG_DATA(cmsg), sizeof(int)); - - userspace_fd_t* fd_s1 = vfs::fdmanager::search(proc,new_fd); - - if(!fd_s1) { - break; - } - - proc->pass_fd->push(fd_s1); - target_pipe->fd_pass = (void*)proc->pass_fd; // transfer - - } else if(cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) { - target_pipe->ucred_pass->push((struct ucred*)CMSG_DATA(cmsg)); - } - } - - std::int64_t total_written = 0; - - for (int i = 0; i < hdr->msg_iovlen; i++) { - std::int64_t sent_bytes = target_pipe->nolock_write((const char*)hdr->msg_iov[i].iov_base,hdr->msg_iov[i].iov_len,0); - if(sent_bytes < 0) { - target_pipe->lock.unlock(); - return {1,+sent_bytes,0}; - } - total_written += sent_bytes; - if (sent_bytes < hdr->msg_iov[i].iov_len) { - break; - } - } - - DEBUG(proc->is_debug,"msg_send fd %d total_written %lli flags %d from proc %d\n",fd,total_written,flags,proc->id); - - target_pipe->lock.unlock(); - return {1,0,total_written}; -} - -long long sys_msg_recv(int fd, struct msghdr *hdr, int flags) { - struct msghdr* msg = hdr; - SYSCALL_IS_SAFEZ(hdr,4096); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return -EBADF; - - vfs::pipe* target_pipe = fd_s->other_state == USERSPACE_FD_OTHERSTATE_MASTER ? fd_s->write_socket_pipe : fd_s->read_socket_pipe; - if(!target_pipe) - return -EBADF; - - std::uint64_t total_size = 0; - for (int i = 0; i < hdr->msg_iovlen; i++) { - SYSCALL_IS_SAFEZ(hdr->msg_iov[i].iov_base,hdr->msg_iov[i].iov_len); - total_size += hdr->msg_iov[i].iov_len; - } - - std::int64_t total_read = 0; - - for (int i = 0; i < hdr->msg_iovlen; i++) { - std::int64_t recv_bytes = 0; - recv_bytes = target_pipe->read(&fd_s->read_counter,(char*)hdr->msg_iov[i].iov_base,hdr->msg_iov[i].iov_len,((fd_s->flags & O_NONBLOCK) ? 1 : 0)); - if(recv_bytes == -EAGAIN) { - return -EAGAIN; - } else if(recv_bytes == -EAGAIN) - break; // just dont continue - total_read += recv_bytes; - } - - socklen_t new_msglen = 0; - socklen_t src_msglen = hdr->msg_controllen; - - struct cmsghdr* cmsg = 0; - - target_pipe->lock.lock(); - for (cmsg = CMSG_FIRSTHDR(msg); - cmsg != 0; - cmsg = CMSG_NXTHDR(msg, cmsg)) { - if (1) { - int *fd_ptr = (int *) CMSG_DATA(cmsg); - userspace_fd_t fd_s1; - memset(&fd_s1,0,sizeof(userspace_fd_t)); - vfs::passingfd_manager* pasfd = (vfs::passingfd_manager*)target_pipe->fd_pass; - if(pasfd != 0) { - if(pasfd->pop(&fd_s1) == 0) { - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = 24; - new_msglen += 24; - int new_fd = vfs::fdmanager::create(proc); - userspace_fd_t* nfd_s = vfs::fdmanager::search(proc,new_fd); - - nfd_s->cycle = fd_s1.cycle; - nfd_s->offset = fd_s1.offset; - nfd_s->state = fd_s1.state; - nfd_s->other_state = fd_s1.other_state; - nfd_s->pipe = fd_s1.pipe; - nfd_s->pipe_side = fd_s1.pipe_side; - nfd_s->queue = fd_s1.queue; - nfd_s->is_a_tty = fd_s1.is_a_tty; - nfd_s->read_counter = fd_s1.read_counter; - nfd_s->write_counter = fd_s1.write_counter; - nfd_s->can_be_closed = 0; - nfd_s->write_socket_pipe = fd_s1.write_socket_pipe; - nfd_s->read_socket_pipe = fd_s1.read_socket_pipe; - nfd_s->eventfd = fd_s1.eventfd; - nfd_s->flags = fd_s1.flags; - - memcpy(nfd_s->path,fd_s1.path,sizeof(fd_s1.path)); - - memcpy(CMSG_DATA(cmsg), &new_fd, sizeof(int)); - if(nfd_s->state == USERSPACE_FD_STATE_PIPE) - nfd_s->pipe->create(nfd_s->pipe_side); - else if(nfd_s->state == USERSPACE_FD_STATE_EVENTFD) - nfd_s->eventfd->create(); - } - } else { - // fd pass is more important than ucred - if(target_pipe->ucred_pass->pop((struct ucred*)CMSG_DATA(cmsg)) == 0) { - DEBUG(1,"ucred pass"); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_CREDENTIALS; - cmsg->cmsg_len = 28; - new_msglen += 28; - } - } - - } - } - - if(new_msglen != 0) { - target_pipe->fd_pass = 0; // clear - target_pipe->lock.unlock(); - } else - target_pipe->lock.unlock(); - - target_pipe->lock.unlock(); - hdr->msg_controllen = new_msglen; - - DEBUG(proc->is_debug,"msg_recv fd %d total_read %lli flags %d from proc %d, controllen %d srclen %d\n",fd,total_read,flags,proc->id,hdr->msg_controllen,src_msglen); - return total_read; -} - -syscall_ret_t sys_eventfd_create(unsigned int initval, int flags) { - arch::x86_64::process_t* proc = CURRENT_PROC; - - int new_fd = vfs::fdmanager::create(proc); - - userspace_fd_t* new_fd_s = vfs::fdmanager::search(proc,new_fd); - memset(new_fd_s->path,0,2048); - - new_fd_s->offset = 0; - new_fd_s->queue = 0; - new_fd_s->pipe = 0; - new_fd_s->pipe_side = 0; - new_fd_s->cycle = 0; - new_fd_s->is_a_tty = 0; - - new_fd_s->state = USERSPACE_FD_STATE_EVENTFD; - new_fd_s->eventfd = new vfs::eventfd(initval,flags); - - new_fd_s->eventfd->create(); - - DEBUG(proc->is_debug,"Creating eventfd %d from proc %d, proc->fd 0x%p",new_fd,proc->id,proc->fd); - - return {1,0,new_fd}; -} - -std::uint64_t nextz = 2; - -std::uint64_t __rand0() { - uint64_t t = __rdtsc(); - return t * (++nextz); -} - -syscall_ret_t sys_getentropy(char* buffer, std::uint64_t len) { - SYSCALL_IS_SAFEA(buffer,256); - if(!buffer) - return {0,EFAULT,0}; - - if(len > 256) - return {0,EIO,0}; - - for(std::uint64_t i = 0; i < len; i++) { - ((char*)buffer)[i] = __rand0() & 0xFF; - } - - return {0,0,0}; -} - -long long sys_pwrite(int fd, void* buf, std::uint64_t n, int_frame_t* ctx) { - std::uint64_t off = ctx->r10; - SYSCALL_IS_SAFEZ(buf,n); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - std::uint64_t count = n; - - userspace_fd_t* fd_sz = vfs::fdmanager::search(proc,fd); - if(!fd_sz) - return -EBADF; - - userspace_fd_t fd_ss = *fd_sz; - fd_ss.offset = off; - - userspace_fd_t* fd_s = &fd_ss; - - if(fd_s->can_be_closed) - fd_s->can_be_closed = 0; - - char* temp_buffer = (char*)buf; - - const char* _0 = "Content view is disabled in files"; - DEBUG(proc->is_debug && fd != 1 && fd != 2,"Writing %s with content %s fd %d state %d from proc %d count %d writ sock 0x%p",fd_s->state == USERSPACE_FD_STATE_FILE ? fd_s->path : "Not file",buf,fd,fd_s->state,proc->id,count,fd_s->write_socket_pipe); - - if(fd == 1) { - //Log::SerialDisplay(LEVEL_MESSAGE_INFO,"%s\n",buf); - } - - std::int64_t bytes_written; - if(fd_s->state == USERSPACE_FD_STATE_FILE) - bytes_written = vfs::vfs::write(fd_s,temp_buffer,count); - else if(fd_s->state == USERSPACE_FD_STATE_PIPE) { - if(fd_s->pipe_side != PIPE_SIDE_WRITE) - return -EBADF; - bytes_written = fd_s->pipe->write(temp_buffer,count,proc->id); - } else if(fd_s->state == USERSPACE_FD_STATE_SOCKET) { - - if(!fd_s->write_socket_pipe || !fd_s->read_socket_pipe) - return -EFAULT; - - if(fd_s->other_state == USERSPACE_FD_OTHERSTATE_MASTER) { - bytes_written = fd_s->read_socket_pipe->write(temp_buffer,count,proc->id); - } else { - bytes_written = fd_s->write_socket_pipe->write(temp_buffer,count,proc->id); - } - - if(bytes_written == 0) - return 0; - - } else if(fd_s->state == USERSPACE_FD_STATE_EVENTFD) { - if(count != 8) - return -EINVAL; - std::uint64_t* _8sizebuf = (std::uint64_t*)buf; - bytes_written = fd_s->eventfd->write(*_8sizebuf); - } else - return -EBADF; - - - return bytes_written; - -} - -typedef struct __mlibc_fsid { - int __val[2]; -} fsid_t; - -typedef std::uint64_t fsblkcnt_t; -typedef std::uint64_t fsfilcnt_t; - -/* WARNING: keep `statfs` and `statfs64` in sync or bad things will happen! */ -struct statfs { - unsigned long f_type; - unsigned long f_bsize; - fsblkcnt_t f_blocks; - fsblkcnt_t f_bfree; - fsblkcnt_t f_bavail; - fsfilcnt_t f_files; - fsfilcnt_t f_ffree; - fsid_t f_fsid; - unsigned long f_namelen; - unsigned long f_frsize; - unsigned long f_flags; - unsigned long __f_spare[4]; -}; - -long long sys_statfs(char* path, struct statfs* buf) { - SYSCALL_IS_SAFEZ(path,4096); - SYSCALL_IS_SAFEZ(buf,4096); - arch::x86_64::process_t* proc = CURRENT_PROC; - - if(!path || !buf) - return -EINVAL; - - buf->f_type = 0xEF53; // just default to ext2 - buf->f_bsize = 4096; - buf->f_blocks = 0; - buf->f_bfree = 0; - buf->f_bavail = 0; - - extern std::uint64_t __tmpfs_ptr_id; - - buf->f_files = __tmpfs_ptr_id; - buf->f_ffree = 0xffffffffffffffff - __tmpfs_ptr_id; - buf->f_fsid = {0,0}; - buf->f_namelen = 2048; - buf->f_frsize = 0; - buf->f_flags = 0; - - return 0; -} - -long long sys_fstatfs(int fd, struct statfs *buf) { - SYSCALL_IS_SAFEZ(buf,4096); - arch::x86_64::process_t* proc = CURRENT_PROC; - - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return -EBADF; - - buf->f_type = 0xEF53; // just default to ext2 - buf->f_bsize = 4096; - buf->f_blocks = 0; - buf->f_bfree = 0; - buf->f_bavail = 0; - - extern std::uint64_t __tmpfs_ptr_id; - - buf->f_files = __tmpfs_ptr_id; - buf->f_ffree = 0xffffffffffffffff - __tmpfs_ptr_id; - buf->f_fsid = {0,0}; - buf->f_namelen = 2048; - buf->f_frsize = 0; - buf->f_flags = 0; - - return 0; - -} - -long long sys_statx(int dirfd, const char *path, int flag, int_frame_t* ctx) { - SYSCALL_IS_SAFEZ((void*)path,4096); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - std::uint32_t mask = ctx->r10 & 0xFFFFFFFF; - statx_t* out = (statx_t*)ctx->r8; - - userspace_fd_t* fd_sz = vfs::fdmanager::search(proc,dirfd); - userspace_fd_t fd_tt; - userspace_fd_t* fd_s = &fd_tt; - - int flags = ctx->r10; - - if(!fd_sz && dirfd != -100) - return -EBADF; - - if(flags & AT_EMPTY_PATH && !path) { - if(!fd_sz) - return -EBADF; - fd_s = fd_sz; - } else { - - if(!path) - return -EINVAL; - - char first_path[2048]; - memset(first_path,0,2048); - if(dirfd >= 0) - memcpy(first_path,vfs::fdmanager::search(proc,dirfd)->path,strlen(vfs::fdmanager::search(proc,dirfd)->path)); - else if(dirfd == AT_FDCWD && proc->cwd) - memcpy(first_path,proc->cwd,strlen(proc->cwd)); - - char kpath[2048]; - memset(kpath,0,2048); - copy_in_userspace_string(proc,kpath,(void*)path,2048); - - char result[2048]; - memset(result,0,2048); - vfs::resolve_path(kpath,first_path,result,1,0); - memset(&fd_tt,0,sizeof(userspace_fd_t)); - memcpy(fd_tt.path,result,strlen(result) + 1); - } - - DEBUG(proc->is_debug,"trying to statx %s\n",path); - return vfs::vfs::statx(fd_s,flag,mask,out); -} - -long long sys_getdents64(int fd, char* buf, size_t count) { - SYSCALL_IS_SAFEZ(buf,count); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - if(!fd_s) - return -EBADF; - - if(!buf) - return -EINVAL; - - DEBUG(proc->is_debug,"getdents64 fd %d buf 0x%p, count %lli",fd,buf,count); - - memset(buf,0,count); - - std::uint64_t off = 0; - while(1) { - vfs::dirent_t dirent = {0}; - int status = vfs::vfs::ls(fd_s,&dirent); - if(status < 0) { - DEBUG(proc->is_debug,"getdents64 fail status %d",status); - return -status; - } - - if(dirent.d_reclen == 0) { - break; - } - - std::uint64_t built_size = strlen(dirent.d_name) + sizeof(linux_dirent64) + 1; - if(built_size > count - off) - break; - - linux_dirent64* dirent64 = (linux_dirent64*)(buf + off); - dirent64->d_ino = dirent.d_ino; - dirent64->d_type = dirent.d_type; - dirent64->d_off = 0; - dirent64->d_reclen = strlen(dirent.d_name) + sizeof(linux_dirent64) + 1; - memcpy(dirent64->d_name,dirent.d_name,strlen(dirent.d_name) + 1); - off += dirent64->d_reclen; - - } - return off; -} - -long long sys_umask(int mask) { - return 0; -}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscalls/futex.cpp b/kernel/src/arch/x86_64/syscalls/futex.cpp deleted file mode 100644 index 3d3352f..0000000 --- a/kernel/src/arch/x86_64/syscalls/futex.cpp +++ /dev/null @@ -1,132 +0,0 @@ - -#include <cstdint> -#include <arch/x86_64/syscalls/syscalls.hpp> -#include <arch/x86_64/syscalls/signal.hpp> -#include <arch/x86_64/cpu/data.hpp> -#include <arch/x86_64/scheduling.hpp> -#include <generic/vfs/vfs.hpp> -#include <drivers/tsc.hpp> - -#include <generic/locks/spinlock.hpp> - -locks::spinlock futex_lock2; - -long long sys_futex(int* uaddr, int op, uint32_t val, int_frame_t* ctx) { - int operation = op & FUTEX_CMD_MASK; - int flags = op & (FUTEX_CLOCK_REALTIME | FUTEX_PRIVATE_FLAG); - - arch::x86_64::process_t* proc = arch::x86_64::cpu::data()->temp.proc; - - struct timespec* ts = (struct timespec*)ctx->r10; - - DEBUG(proc->is_debug,"futex op %d, val %d, uaddr 0x%p, flags %d, raw_op %d",operation,val,uaddr,flags,op); - - switch(operation) { - case FUTEX_WAIT: { - - SYSCALL_IS_SAFEZ(uaddr,4096); - - int v = 0; - v = ((std::atomic<int>*)uaddr)->load(); - - if(v != val) - return -EAGAIN; - - std::uint64_t t = 0; - if(ts) { - t = (ts->tv_sec * (1000 * 1000)) + (ts->tv_nsec / 1000); - t += drivers::tsc::currentus(); - } - - DEBUG(proc->is_debug,"Waiting for futex, pointer: 0x%p excepted: %d, pointer_value %d in proc %d, ts->tv_nsec %lli ts->tv_sec %lli",uaddr,val,v,proc->id,ts != nullptr ? ts->tv_nsec : 0, ts != nullptr ? ts->tv_sec : 0); - - arch::x86_64::scheduling::futexwait(proc,&v,val,uaddr,t); - - futex_lock2.unlock(); - yield(); - - while(proc->futex_lock.test()) { - if(ts) { - if(proc->ts < drivers::tsc::currentus()) { - proc->futex_lock.unlock(); - return -ETIMEDOUT; - } - } - - PREPARE_SIGNAL(proc) { - proc->futex_lock.unlock(); - signal_ret(); - } - - yield(); - } - - return 0; - }; - case FUTEX_WAKE: { - int c = arch::x86_64::scheduling::futexwake(proc,uaddr,val); - return c; - } - default: - Log::SerialDisplay(LEVEL_MESSAGE_FAIL,"unsupported futex op %d\n",op); - return 0; - }; - return 0; -} - -// syscall_ret_t sys_futex_wait(int* pointer, int excepted, struct timespec* ts) { - -// futex_lock2.lock(); -// int v = 0; -// v = ((std::atomic<int>*)pointer)->load(); - -// if(v != excepted) { -// futex_lock2.unlock(); -// return {0,EAGAIN,0}; -// } - -// arch::x86_64::process_t* proc = arch::x86_64::cpu::data()->temp.proc; - -// std::uint64_t t = 0; -// if(ts) { -// t = (ts->tv_sec * (1000 * 1000)) + (ts->tv_nsec / 1000); -// t += drivers::tsc::currentus(); -// } - - - -// int copied_pointer_val = v; -// DEBUG(0,"Waiting for futex, pointer: 0x%p excepted: %d, pointer_value %d in proc %d, ts->tv_nsec %lli ts->tv_sec %lli",pointer,excepted,copied_pointer_val,proc->id,ts != nullptr ? ts->tv_nsec : 0, ts != nullptr ? ts->tv_sec : 0); - -// arch::x86_64::scheduling::futexwait(proc,&copied_pointer_val,excepted,pointer,t); - -// futex_lock2.unlock(); -// yield(); - -// while(proc->futex_lock.test()) { -// if(ts) { -// if(proc->ts < drivers::tsc::currentus()) { -// proc->futex_lock.unlock(); -// return {0,ETIMEDOUT,0}; -// } -// } - -// PREPARE_SIGNAL(proc) { -// proc->futex_lock.unlock(); -// signal_ret(); -// } - -// yield(); -// } - -// return {0,0,0}; -// } - -// syscall_ret_t sys_futex_wake(int* pointer) { -// futex_lock2.lock(); -// arch::x86_64::process_t* proc = arch::x86_64::cpu::data()->temp.proc; -// DEBUG(0,"Wakeup futex with pointer 0x%p in proc %d",pointer,proc->id); -// int c = arch::x86_64::scheduling::futexwake(proc,pointer); -// futex_lock2.unlock(); -// return {0,0,0}; -// } diff --git a/kernel/src/arch/x86_64/syscalls/misc.cpp b/kernel/src/arch/x86_64/syscalls/misc.cpp deleted file mode 100644 index d8ca1ac..0000000 --- a/kernel/src/arch/x86_64/syscalls/misc.cpp +++ /dev/null @@ -1,158 +0,0 @@ - - -#include <arch/x86_64/syscalls/syscalls.hpp> -#include <generic/vfs/vfs.hpp> - -#include <arch/x86_64/cpu/data.hpp> -#include <arch/x86_64/scheduling.hpp> - -#include <generic/mm/pmm.hpp> -#include <generic/mm/vmm.hpp> - -#include <generic/vfs/fd.hpp> - -#include <etc/assembly.hpp> -#include <etc/logging.hpp> - -#include <drivers/cmos.hpp> - -#include <drivers/tsc.hpp> - -#include <etc/errno.hpp> - -#include <drivers/hpet.hpp> - -#include <drivers/kvmtimer.hpp> - -#include <generic/time.hpp> - -#include <generic/vfs/vfs.hpp> - -#include <etc/bootloaderinfo.hpp> - -std::atomic<std::uint64_t> zznext = 0; -std::uint64_t __zzrand() { - uint64_t t = __rdtsc(); - return t * (++zznext); -} - -long long sys_getrandom(char *buf, size_t count, unsigned int flags) { - if(!buf) - return -EINVAL; - for(std::uint64_t i = 0;i < count;i++) { - buf[i] = __zzrand() & 0xFF; - } - return 0; -} - -# define CLOCK_REALTIME 0 -/* Monotonic system-wide clock. */ -# define CLOCK_MONOTONIC 1 -/* High-resolution timer from the CPU. */ -# define CLOCK_PROCESS_CPUTIME_ID 2 -/* Thread-specific CPU-time clock. */ -# define CLOCK_THREAD_CPUTIME_ID 3 -/* Monotonic system-wide clock, not adjusted for frequency scaling. */ -# define CLOCK_MONOTONIC_RAW 4 -/* Identifier for system-wide realtime clock, updated only on ticks. */ -# define CLOCK_REALTIME_COARSE 5 -/* Monotonic system-wide clock, updated only on ticks. */ -# define CLOCK_MONOTONIC_COARSE 6 -/* Monotonic system-wide clock that includes time spent in suspension. */ -# define CLOCK_BOOTTIME 7 -/* Like CLOCK_REALTIME but also wakes suspended system. */ -# define CLOCK_REALTIME_ALARM 8 -/* Like CLOCK_BOOTTIME but also wakes suspended system. */ -# define CLOCK_BOOTTIME_ALARM 9 -/* Like CLOCK_REALTIME but in International Atomic Time. */ -# define CLOCK_TAI 11 - -std::atomic<std::uint64_t> clk_mnt_sync = 0; - -long long sys_clock_gettime(clockid_t which_clock, struct __kernel_timespec *tp) { - switch(which_clock) { - case CLOCK_TAI: - case CLOCK_REALTIME_COARSE: - case CLOCK_REALTIME: - tp->tv_sec = getUnixTime(); - tp->tv_nsec = 0; - return 0; - case CLOCK_THREAD_CPUTIME_ID: - case CLOCK_PROCESS_CPUTIME_ID: - case CLOCK_BOOTTIME: - case CLOCK_MONOTONIC_COARSE: - case CLOCK_MONOTONIC_RAW: - case CLOCK_MONOTONIC: - std::uint64_t ts = drivers::tsc::currentnano(); - tp->tv_sec = ts / 1000000000; - tp->tv_nsec = ts % 1000000000; - return 0; - }; - return -EINVAL; -} - -long long sys_gettimeofday(timeval* tv, void* tz) { // tz unused - std::uint64_t ts = drivers::tsc::currentnano(); - if(tv) { - tv->tv_sec = getUnixTime(); - tv->tv_usec = (ts % 1000000000LL) / 1000LL; - } - return 0; -} - -long long sys_uname(old_utsname* uname) { - - if(!uname) - return -EINVAL; - - memset(uname,0,sizeof(old_utsname)); - - memcpy(uname->sysname,"Orange",sizeof("Orange")); - memcpy(uname->nodename,"orange-pc",sizeof("orange-pc")); - memcpy(uname->machine,"x86_64",sizeof("x86_64")); - - return 0; - -} - -long long sys_time(std::uint64_t* t) { - SYSCALL_IS_SAFEZ(t,4096); - std::uint64_t time = getUnixTime(); - if(t) - *t = time; - return time; -} - -long long sys_nanosleep(int clock, int flags, timespec* rqtp, int_frame_t* ctx) { - timespec* rmtp = (timespec*)ctx->r10; - std::uint64_t us = (rqtp->tv_nsec / 1000) + (rqtp->tv_sec * 1000000); - arch::x86_64::process_t* proc = CURRENT_PROC; - if(1) { // tsc sleep - std::uint64_t current = drivers::tsc::currentnano(); - std::uint64_t end = us * 1000; - while((drivers::tsc::currentnano() - current) < end) { - if((drivers::tsc::currentnano() - current) < 15000) { - asm volatile("pause"); - } else - yield(); - PREPARE_SIGNAL(proc) { - std::uint64_t ns = us * 1000; - rmtp->tv_sec = ns / 1000000000; - rmtp->tv_nsec = ns % 1000000000; - signal_ret(); - } - } - } - return 0; -} - -long long sys_sysinfo(sysinfo* info) { - SYSCALL_IS_SAFEZ(info,4096); - - if(!info) - return -EINVAL; - - info->uptime = drivers::tsc::currentus() / (1000 * 1000); - - return 0; -}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscalls/process.cpp b/kernel/src/arch/x86_64/syscalls/process.cpp deleted file mode 100644 index 473a0bf..0000000 --- a/kernel/src/arch/x86_64/syscalls/process.cpp +++ /dev/null @@ -1,1081 +0,0 @@ - -#include <arch/x86_64/syscalls/syscalls.hpp> -#include <generic/vfs/vfs.hpp> - -#include <arch/x86_64/cpu/data.hpp> -#include <arch/x86_64/scheduling.hpp> - -#include <generic/mm/pmm.hpp> -#include <generic/mm/vmm.hpp> - -#include <generic/vfs/fd.hpp> - -#include <etc/assembly.hpp> -#include <etc/logging.hpp> - -#include <drivers/cmos.hpp> - -#include <drivers/tsc.hpp> - -#include <etc/errno.hpp> - -#include <drivers/hpet.hpp> - -#include <drivers/kvmtimer.hpp> - -#include <generic/time.hpp> - -#include <generic/vfs/vfs.hpp> - -#include <etc/bootloaderinfo.hpp> - -syscall_ret_t sys_tcb_set(std::uint64_t fs) { - arch::x86_64::process_t* proc = CURRENT_PROC; - proc->fs_base = fs; - __wrmsr(0xC0000100,fs); - DEBUG(proc->is_debug,"Setting tcb %p to proc %d",fs,proc->id); - return {0,0,0}; -} - -syscall_ret_t sys_libc_log(const char* msg) { - arch::x86_64::process_t* proc = CURRENT_PROC; - char buffer[2048]; - memset(buffer,0,2048); - copy_in_userspace_string(proc,buffer,(void*)msg,2048); - DEBUG(proc->is_debug,"%s from proc %d",buffer,proc->id); - - return {0,0,0}; -} - -long long sys_exit_group(int status) { - cpudata_t* cpdata = arch::x86_64::cpu::data(); - arch::x86_64::process_t* proc = CURRENT_PROC; - DEBUG(1,"Process %d exited with status %d (exit_group)",proc->id,status); - char* vm_start = proc->vmm_start; - arch::x86_64::process_t* current = arch::x86_64::scheduling::head_proc_(); - memory::paging::enablekernel(); - DEBUG(proc->is_debug,"a"); - while(current) { - if(proc->id == current->id) { - current->exit_code = 0; - current->is_execd = 1; - - DEBUG(proc->is_debug,"sh %d",current->id); - arch::x86_64::scheduling::kill(current); - - if(1) - memory::vmm::free(current); - - vfs::fdmanager* fd = (vfs::fdmanager*)current->fd; - fd->free(); - - memory::pmm::_virtual::free(current->cwd); - memory::pmm::_virtual::free(current->name); - memory::pmm::_virtual::free(current->sse_ctx); - cpdata->temp.temp_ctx = 0; - } else if(proc->vmm_start == current->vmm_start && proc->thread_group == current->thread_group) { - // send sigkill - if(current->sig) { - pending_signal_t sig; - sig.sig = SIGKILL; - current->sig->push(&sig); - } - } - current = current->next; - } - schedulingScheduleAndChangeStack(arch::x86_64::cpu::data()->timer_ist_stack,0); - __builtin_unreachable(); -} - -long long sys_exit(int status) { - - cpudata_t* cpdata = arch::x86_64::cpu::data(); - - arch::x86_64::process_t* proc = CURRENT_PROC; - proc->exit_code = status; - - if(proc->tidptr) { - *proc->tidptr = 0; - arch::x86_64::scheduling::futexwake(proc,proc->tidptr,1); - } - - - memory::paging::enablekernel(); - - DEBUG(1,"Process %s (%d) exited with code %d sys %d",proc->name,proc->id,status,proc->sys); - - if(proc->is_debug) - assert(1,"debug: proc exit status is not 0"); - - if(proc->exit_signal != 0) { - arch::x86_64::process_t* target_proc = arch::x86_64::scheduling::by_pid(proc->parent_id); - if(target_proc) { - pending_signal_t pend_sig; - pend_sig.sig = proc->exit_signal; - target_proc->sig->push(&pend_sig); - } - } - - arch::x86_64::scheduling::kill(proc); - - if(1) - memory::vmm::free(proc); - - vfs::fdmanager* fd = (vfs::fdmanager*)proc->fd; - fd->free(); - - proc->is_execd = 1; - - memory::pmm::_virtual::free(proc->cwd); - memory::pmm::_virtual::free(proc->name); - memory::pmm::_virtual::free(proc->sse_ctx); - cpdata->temp.temp_ctx = 0; - schedulingScheduleAndChangeStack(arch::x86_64::cpu::data()->timer_ist_stack,0); - __builtin_unreachable(); -} - -locks::spinlock mmap_lock; // memory access should be locked anyway - -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -/* 0x10 reserved for arch-specific use */ -/* 0x20 reserved for arch-specific use */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -// unimplemented just return errors if not valid -long long sys_mprotect(std::uint64_t start, size_t len, std::uint64_t prot) { - arch::x86_64::process_t* proc = CURRENT_PROC; - if(!start) - return -EINVAL; - - vmm_obj_t* vmm_ = memory::vmm::getlen(proc,start); - - if(!vmm_) - return -EINVAL; - - DEBUG(proc->is_debug,"trying to mprotect 0x%p",start); - - std::uint64_t new_flags = PTE_USER | PTE_PRESENT; - new_flags |= (prot & PROT_WRITE) ? PTE_RW : 0; - - return 0; -} - -long long sys_prlimit64(int pid, int res, rlimit64* new_rlimit, int_frame_t* ctx) { - rlimit64* old_rlimit = (rlimit64*)ctx->r10; - - if(new_rlimit || !old_rlimit) - return 0; - - switch(res) { - case RLIMIT_NOFILE: - old_rlimit->rlim_cur = 512*1024; - old_rlimit->rlim_max = 512*1024; - return 0; - case RLIMIT_STACK: - old_rlimit->rlim_cur = USERSPACE_STACK_SIZE; - old_rlimit->rlim_max = USERSPACE_STACK_SIZE; - return 0; - case RLIMIT_NPROC: - old_rlimit->rlim_cur = 0xffffffff; - old_rlimit->rlim_max = 0xffffffff; - return 0; - case RLIMIT_AS: - case RLIMIT_LOCKS: - case RLIMIT_MEMLOCK: - case RLIMIT_CPU: - case RLIMIT_RSS: - case RLIMIT_FSIZE: - case RLIMIT_DATA: - old_rlimit->rlim_cur = RLIM_INFINITY; - old_rlimit->rlim_max = RLIM_INFINITY; - return 0; - case RLIMIT_CORE: - old_rlimit->rlim_cur = 0; - old_rlimit->rlim_max = 0; - return 0; - default: - return -EINVAL; - } - return 0; -} - -long long sys_mmap(std::uint64_t hint, std::uint64_t size, unsigned long prot, int_frame_t* ctx) { - - std::uint64_t flags = ctx->r10; - int fd0 = ctx->r8; - std::uint64_t off = ctx->r9; - - size = ALIGNPAGEUP(size); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - DEBUG(proc->is_debug,"trying to mmap 0x%p-0x%p sz %lli, prot %lli, flags %lli fd %d off %lli from proc %d, is fixed %d",hint,hint + size,size,prot,flags,fd0,off,proc->id,flags & MAP_FIXED); - - if(flags & MAP_ANONYMOUS) { - - std::uint64_t new_hint = hint; - int is_shared = (flags & MAP_SHARED) ? 1 : 0; - - if(is_shared) { - DEBUG(1,"shared mem\n"); - asm volatile("hlt"); - } - - if(!new_hint) { - new_hint = (std::uint64_t)memory::vmm::lazy_alloc(proc,size,PTE_PRESENT | PTE_USER | PTE_RW,0); - } else - memory::vmm::customalloc(proc,new_hint,size,PTE_PRESENT | PTE_RW | PTE_USER,0,flags & MAP_FIXED); - - memory::vmm::invtlb(proc,new_hint,size); - - DEBUG(proc->is_debug,"return 0x%p",new_hint); - return (std::int64_t)new_hint; - } else { - - std::uint64_t mmap_base = 0; - std::uint64_t mmap_size = 0; - std::uint64_t mmap_flags = 0; - userspace_fd_t* fd = vfs::fdmanager::search(proc,fd0); - if(!fd) { - return -EBADF; } - - int status = vfs::vfs::mmap(fd,&mmap_base,&mmap_size,&mmap_flags); - - if(status == ENOSYS) { - // try to fix this and read whole file - std::int64_t old_offset = fd->offset; - fd->offset = off; - - vfs::stat_t stat; - std::int32_t stat_status = vfs::vfs::stat(fd,&stat); - - if(!(stat.st_mode & S_IFREG)) { - return -EFAULT; } - - std::uint64_t new_hint_hint; - - if(!hint) { - new_hint_hint = (std::uint64_t)memory::vmm::lazy_alloc(proc,size,PTE_PRESENT | PTE_USER | PTE_RW,0); - memory::vmm::invmapping(proc,new_hint_hint,size); - } else { - new_hint_hint = (std::uint64_t)memory::vmm::customalloc(proc,hint,size,PTE_PRESENT | PTE_USER | PTE_RW,0,flags & MAP_FIXED); - memory::vmm::invmapping(proc,new_hint_hint,size); - } - - memory::vmm::invtlb(proc,new_hint_hint,size); - - vfs::vfs::read(fd,(void*)new_hint_hint,size <= 0 ? stat.st_size : size); - fd->offset = old_offset; - - DEBUG(proc->is_debug,"returna 0x%p, is_fixed %d",new_hint_hint,flags & 0x100000); - - return (std::int64_t)new_hint_hint; - - } - - if(status != 0) { - return -status; } - - std::uint64_t new_hint_hint = (std::uint64_t)memory::vmm::map(proc,mmap_base,mmap_size,PTE_PRESENT | PTE_USER | PTE_RW | mmap_flags); - memory::vmm::invtlb(proc,new_hint_hint,mmap_size); - - return (std::int64_t)new_hint_hint; - } -} - -long long sys_free(void *pointer, size_t size) { - arch::x86_64::process_t* proc = CURRENT_PROC; - memory::vmm::unmap(proc,(std::uint64_t)pointer,size); - memory::vmm::invtlb(proc,(std::uint64_t)pointer,size); - - return 0; -} - -long long sys_set_tid_address(int* tidptr) { - SYSCALL_IS_SAFEZ((void*)tidptr,4096); - - arch::x86_64::process_t* proc = CURRENT_PROC; - proc->tidptr = tidptr; - - return 0; -} - -typedef struct stackframe { - struct stackframe* rbp; - uint64_t rip; -} __attribute__((packed)) stackframe_t; - -syscall_ret_t sys_fork(int D, int S, int d, int_frame_t* ctx) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - - arch::x86_64::process_t* new_proc = arch::x86_64::scheduling::fork(proc,ctx); - new_proc->ctx.rax = 0; - new_proc->ctx.rdx = 0; - - arch::x86_64::scheduling::wakeup(new_proc); - - DEBUG(proc->is_debug,"Fork from proc %d, new proc %d",proc->id,new_proc->id); - new_proc->is_debug = proc->is_debug; - if(proc->is_debug) { - stackframe_t* rbp = (stackframe_t*)ctx->rbp; - Log::SerialDisplay(LEVEL_MESSAGE_INFO,"[0] - 0x%016llX (current rip)\n",ctx->rip); - for (int i = 1; i < 10 && rbp; ++i) { - std::uint64_t ret_addr = rbp->rip; - Log::SerialDisplay(LEVEL_MESSAGE_INFO,"[%d] - 0x%016llX (0x%016llX)\n", i, ret_addr,ret_addr - memory::vmm::getlen(proc,ret_addr)->base); - rbp = (stackframe_t*)rbp->rbp; - } - } - - return {1,0,new_proc->id}; -} - -/* Just give full io access to userspace */ -syscall_ret_t sys_iopl(int a, int b ,int c , int_frame_t* ctx) { - ctx->r11 |= (1 << 12) | (1 << 13); - return {0,0,0}; -} - -syscall_ret_t sys_access_framebuffer(void* out) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - - struct limine_framebuffer temp; - memcpy(&temp,BootloaderInfo::AccessFramebuffer(),sizeof(struct limine_framebuffer)); - temp.address = (void*)((std::uint64_t)temp.address - BootloaderInfo::AccessHHDM()); - copy_in_userspace(proc,out,&temp,sizeof(struct limine_framebuffer)); - - return {0,0,0}; -} - -std::uint64_t __elf_get_length2(char** arr) { - std::uint64_t counter = 0; - - while(arr[counter]) - counter++; - - return counter; -} - -long long sys_exec(char* path, char** argv, char** envp, int_frame_t* ctx) { - - if(!path || !argv || !envp) - return -EINVAL; - - cpudata_t* cpdata = arch::x86_64::cpu::data(); - - SYSCALL_IS_SAFEZ(path,4096); - SYSCALL_IS_SAFEZ(argv,4096); - SYSCALL_IS_SAFEZ(envp,4096); - - std::uint64_t argv_length = 0; - std::uint64_t envp_length = 0; - - arch::x86_64::process_t* proc = arch::x86_64::cpu::data()->temp.proc; - - argv_length = __elf_get_length2((char**)argv); - envp_length = __elf_get_length2((char**)envp); - - char** argv0 = (char**)memory::heap::malloc(8 * (argv_length + 3)); - char** envp0 = (char**)memory::heap::malloc(8 * (envp_length + 1)); - - memset(argv0,0,8 * (envp_length + 2)); - memset(envp0,0,8 * (envp_length + 1)); - - char stack_path[2048]; - - memset(stack_path,0,2048); - - for(int i = 0;i < argv_length; i++) { - - char* str = argv[i]; - - char* new_str = (char*)memory::heap::malloc(strlen(str) + 1); - - memcpy(new_str,str,strlen(str)); - - argv0[i] = new_str; - - } - - for(int i = 0;i < envp_length; i++) { - - char* str = envp[i]; - - char* new_str = (char*)memory::heap::malloc(strlen(str) + 1); - - memcpy(new_str,str,strlen(str)); - - envp0[i] = new_str; - - } - - copy_in_userspace_string(proc,stack_path,path,2048); - - char result[2048]; - vfs::resolve_path(stack_path,proc->cwd,result,1,0); - - vfs::stat_t stat; - - userspace_fd_t fd; - fd.is_cached_path = 0; - memset(fd.path,0,2048); - memcpy(fd.path,result,strlen(result)); - - int status = vfs::vfs::stat(&fd,&stat); - - if(status != 0) - return -status; - - vfs::fdmanager* fd_m = (vfs::fdmanager*)proc->fd; - fd_m->cloexec(); - - memset(proc->ret_handlers,0,sizeof(proc->ret_handlers)); - memset(proc->sig_handlers,0,sizeof(proc->sig_handlers)); - arch::x86_64::free_sigset_from_list(proc); - - DEBUG(proc->is_debug,"Exec file %s from proc %d",fd.path,proc->id); - if(1) { - for(int i = 0;i < argv_length;i++) { - DEBUG(proc->is_debug,"Argv %d: %s",i,argv0[i]); - } - } - - if(status == 0) { - if((stat.st_mode & S_IXUSR) && (stat.st_mode & S_IFREG)) { - - proc->fs_base = 0; - - memory::paging::enablekernel(); - memory::vmm::free(proc); - - memory::vmm::initproc(proc); - - memset(&proc->ctx,0,sizeof(int_frame_t)); - - memory::vmm::reload(proc); - - proc->ctx.cs = 0x20 | 3; - proc->ctx.ss = 0x18 | 3; - - proc->ctx.rflags = (1 << 9); - - status = arch::x86_64::scheduling::loadelf(proc,result,argv0,envp0,0); - if(status == 0) { - - for(int i = 0;i < argv_length; i++) { - memory::heap::free(argv0[i]); - } - - for(int i = 0;i < envp_length; i++) { - memory::heap::free(envp0[i]); - } - - memory::heap::free(argv0); - memory::heap::free(envp0); - - proc->is_execd = 1; - - cpdata->temp.temp_ctx = 0; - schedulingScheduleAndChangeStack(arch::x86_64::cpu::data()->timer_ist_stack,0); - __builtin_unreachable(); - } - - // maybe sh ? - char interp[2048]; - memset(interp,0,2048); - - int i = 0; - memcpy(interp,"/bin/sh",strlen("/bin/sh")); - - userspace_fd_t test; - test.is_cached_path = 0; - test.offset = 0; - memset(test.path,0,2048); - memcpy(test.path,result,strlen(result)); - - - - char first; - status = vfs::vfs::read(&test,&first,1); - if(status > 0) { - if(first == '!') { - memset(interp,0,2048); - while(1) { - int c = vfs::vfs::read(&test,&first,1); - if(c && c != '\n') - interp[i++] = c; - if(c && c == '\n') - break; - } - } - argv_length++; - memcpy(&argv0[2], argv0,sizeof(std::uint64_t) * argv_length); - char* t1 = (char*)malloc(2048); - memset(t1,0,2048); - memcpy(t1,interp,strlen(interp)); - char* t2 = (char*)malloc(2048); - memset(t2,0,2048); - memcpy(t2,result,strlen(result)); - argv0[0] = t1; - argv0[1] = t2; - - DEBUG(1,"interp %s to %s",argv0[0],argv0[1]); - - status = arch::x86_64::scheduling::loadelf(proc,interp,argv0,envp0,0); - free((void*)t1); - free((void*)t2); - - if(status == 0) { - - for(int i = 0;i < argv_length; i++) { - memory::heap::free(argv0[i]); - } - - for(int i = 0;i < envp_length; i++) { - memory::heap::free(envp0[i]); - } - - memory::heap::free(argv0); - memory::heap::free(envp0); - - proc->is_execd = 1; - - cpdata->temp.temp_ctx = 0; - schedulingScheduleAndChangeStack(arch::x86_64::cpu::data()->timer_ist_stack,0); - __builtin_unreachable(); - } - - } - - } - } - - - - for(int i = 0;i < argv_length; i++) { - memory::heap::free(argv0[i]); - } - - for(int i = 0;i < envp_length; i++) { - memory::heap::free(envp0[i]); - } - - memory::heap::free(argv0); - memory::heap::free(envp0); - - proc->exit_code = -1; - proc->is_execd = 1; - - cpdata->temp.temp_ctx = 0; - arch::x86_64::scheduling::kill(proc); - schedulingScheduleAndChangeStack(arch::x86_64::cpu::data()->timer_ist_stack,0); - __builtin_unreachable(); -} - -long long sys_getpid() { - arch::x86_64::process_t* proc = CURRENT_PROC; - return proc->id; -} - -long long sys_getppid() { - arch::x86_64::process_t* proc = CURRENT_PROC; - return proc->parent_id; -} - -syscall_ret_t sys_gethostname(void* buffer, std::uint64_t bufsize) { - - if(!buffer) - return {0,EINVAL,0}; - - SYSCALL_IS_SAFEA(buffer,bufsize); - - const char* default_hostname = "orange-pc"; - arch::x86_64::process_t* proc = CURRENT_PROC; - - zero_in_userspace(proc,buffer,bufsize); - copy_in_userspace(proc,buffer,(void*)default_hostname,strlen(default_hostname)); - - return {0,0,0}; -} - -long long sys_getcwd(void* buffer, std::uint64_t bufsize) { - - SYSCALL_IS_SAFEZ(buffer,bufsize); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - zero_in_userspace(proc,buffer,bufsize); - - char buffer0[4096]; - memcpy(buffer0,proc->cwd,4096); - - copy_in_userspace(proc,buffer,buffer0,strlen((const char*)buffer0) > bufsize ? bufsize : strlen((const char*)buffer0)); - - return 0; -} - -long long sys_wait4(int pid,int* status,int flags) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - - arch::x86_64::process_t* current = arch::x86_64::scheduling::head_proc_(); - - DEBUG(proc->is_debug,"Trying to waitpid with pid %d from proc %d",pid,proc->id); - - if(pid < -1 || pid == 0) - return -EINVAL; - - SYSCALL_IS_SAFEZ(status,4096); - - int success = 0; - - std::uint64_t current_timestamp = time::counter(); - std::uint64_t ns = 1000 * 1000 * 1000; - - if(pid == -1) { - while (current) - { - if(current->parent_id == proc->id && (current->status = PROCESS_STATE_ZOMBIE || current->status == PROCESS_STATE_RUNNING) && current->waitpid_state != 2) { - current->waitpid_state = 1; - success = 1; - } - current = current->next; - } - } else if(pid > 0) { - while (current) - { - if(current->parent_id == proc->id && (current->status = PROCESS_STATE_ZOMBIE || current->status == PROCESS_STATE_RUNNING) && current->id == pid && current->waitpid_state != 2) { - current->waitpid_state = 1; - success = 1; - break; - } - current = current->next; - } - } - - if(!success) - return -ECHILD; - - int parent_id = proc->id; - - current = arch::x86_64::scheduling::head_proc_(); - while(1) { - while (current) - { - if(current) { - if(current->parent_id == parent_id && current->kill_lock.test() && current->waitpid_state == 1 && current->id != 0) { - current->waitpid_state = 2; - std::int64_t bro = (std::int64_t)(((std::uint64_t)current->exit_code) << 32) | current->id; - current->status = PROCESS_STATE_KILLED; - DEBUG(proc->is_debug,"Waitpid done pid %d from proc %d",pid,proc->id); - if(status) - *status = current->exit_code; - return bro; - } - } - current = current->next; - } - - if(flags & WNOHANG) { - arch::x86_64::process_t* pro = arch::x86_64::scheduling::head_proc_(); - while(pro) { - if(pro->parent_id == parent_id && proc->waitpid_state == 1) - proc->waitpid_state = 0; - pro = pro->next; - } - DEBUG(proc->is_debug,"Waitpid return WNOHAND from proc %d",proc->id); - return 0; - } - signal_ret(); - yield(); - current = arch::x86_64::scheduling::head_proc_(); - } - -} - -syscall_ret_t sys_sleep(long us) { - - std::uint64_t current = drivers::tsc::currentnano(); - std::uint64_t end = us * 1000; - while((drivers::tsc::currentnano() - current) < end) { - if((drivers::tsc::currentnano() - current) < 15000) { - asm volatile("pause"); - } else - yield(); - signal_ret(); - } - return {0,0,0}; -} - -syscall_ret_t sys_alloc_dma(std::uint64_t size) { - return {1,0,memory::pmm::_physical::alloc(size)}; -} - -syscall_ret_t sys_free_dma(std::uint64_t phys) { - memory::pmm::_physical::free(phys); - return {0,0,0}; -} - -syscall_ret_t sys_map_phys(std::uint64_t phys, std::uint64_t flags, std::uint64_t size) { - arch::x86_64::process_t* proc = CURRENT_PROC; - return {1,0,(std::int64_t)memory::vmm::map(proc,phys,size,PTE_PRESENT | PTE_USER | PTE_RW | flags)}; -} - -std::uint64_t timestamp = 0; - -syscall_ret_t sys_timestamp() { - timestamp = drivers::tsc::currentnano() > timestamp ? drivers::tsc::currentnano() : timestamp; - return {1,0,(std::int64_t)timestamp}; -} - -syscall_ret_t sys_enabledebugmode() { - arch::x86_64::process_t* proc = CURRENT_PROC; - proc->is_debug = !proc->is_debug; - DEBUG(proc->is_debug,"Enabling/Disabling debug mode for proc %d",proc->id); - return {0,0,0}; -} - -syscall_ret_t sys_enabledebugmodepid(int pid) { - arch::x86_64::process_t* proc = arch::x86_64::scheduling::head_proc_(); - while(proc) { - if(proc->id == pid) - break; - proc = proc->next; - } - if(!proc) - return {0,ECHILD}; - - DEBUG(proc->is_debug,"Enabling/Disabling debug mode for proc %d",proc->id); - proc->is_debug = !proc->is_debug; - return {0,0,0}; -} - -syscall_ret_t sys_printdebuginfo(int pid) { - arch::x86_64::process_t* proc = arch::x86_64::scheduling::head_proc_(); - while(proc) { - if(proc->id == pid) - break; - proc = proc->next; - } - if(!proc) - return {0,ECHILD}; - - DEBUG(1,"Process %d rip is 0x%p debug0 %d debug1 %d, sys %d",proc->id,proc->ctx.rip,proc->debug0,proc->debug1,proc->sys); - stackframe_t* rbp = (stackframe_t*)proc->ctx.rbp; - Log::SerialDisplay(LEVEL_MESSAGE_INFO,"[0] - 0x%016llX (current rip)\n",proc->ctx.rip); - for (int i = 1; i < 10 && rbp; ++i) { - std::uint64_t ret_addr = rbp->rip; - Log::SerialDisplay(LEVEL_MESSAGE_INFO,"[%d] - 0x%016llX (0x%016llX)\n", i, ret_addr,0); - rbp = (stackframe_t*)rbp->rbp; - } - return {0,0,0}; -} - - -long long sys_clone3(clone_args* clargs, size_t size, int c, int_frame_t* ctx) { - // size is ignored - arch::x86_64::process_t* proc = CURRENT_PROC; - - arch::x86_64::process_t* new_proc = arch::x86_64::scheduling::clone3(proc,clargs,ctx); - new_proc->ctx.rax = 0; - - arch::x86_64::scheduling::wakeup(new_proc); - - DEBUG(proc->is_debug,"clone3 from proc %d, new proc %d (new syscall_stack: 0x%p) %s, parent tid 0x%p , child tid 0x%p, pidfd 0x%p %s",proc->id,new_proc->id,new_proc->syscall_stack,clargs->flags & CLONE_VM ? "CLONEVM" : "NOCLONEVM",clargs->parent_tid,clargs->child_tid,clargs->pidfd,clargs->flags & CLONE_VFORK ? "VFORK" : "NOVFORK"); - new_proc->is_debug = proc->is_debug; - - if(clargs->flags & CLONE_VFORK) { - while(1) { - if(new_proc->is_execd == 1) - break; - yield(); - } - } - - return new_proc->id; -} - -// convert clone to clone3 -long long sys_clone(unsigned long clone_flags, unsigned long newsp, int *parent_tidptr, int_frame_t* ctx) { - std::uint64_t child_tidptr = ctx->r10; - std::uint64_t tls = ctx->r8; - clone_args arg = {0}; - arg.flags = clone_flags; - arg.stack = newsp; - arg.parent_tid = (std::uint64_t)parent_tidptr; - arg.tls = tls; - arg.child_tid = child_tidptr; - return sys_clone3(&arg,sizeof(clone_args),0,ctx); -} - -syscall_ret_t sys_breakpoint(int num, int b, int c, int_frame_t* ctx) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - if(proc->is_debug) { - Log::SerialDisplay(LEVEL_MESSAGE_INFO,"breakpoint 0x%p\n",num); - stackframe_t* rbp = (stackframe_t*)ctx->rbp; - Log::SerialDisplay(LEVEL_MESSAGE_INFO,"[0] - 0x%016llX (current rip)\n",ctx->rip); - for (int i = 1; i < 10 && rbp; ++i) { - std::uint64_t ret_addr = rbp->rip; - Log::SerialDisplay(LEVEL_MESSAGE_INFO,"[%d] - 0x%016llX (0x%016llX)\n", i, ret_addr,ret_addr - memory::vmm::getlen(proc,ret_addr)->base); - rbp = (stackframe_t*)rbp->rbp; - } - } - return {0,0,0}; -} - -syscall_ret_t sys_copymemory(void* src, void* dest, int len) { - arch::x86_64::process_t* proc = CURRENT_PROC; - copy_in_userspace(proc,dest,src,len); - return {0,0,0}; -} - -#define PRIO_PROCESS 1 -#define PRIO_PGRP 2 -#define PRIO_USER 3 - -long long sys_setpriority(int which, int who, int prio) { - arch::x86_64::process_t* proc = CURRENT_PROC; - if(which == PRIO_PROCESS) { - - arch::x86_64::process_t* need_proc = arch::x86_64::scheduling::head_proc_(); - while(need_proc) { - if(need_proc->id == who) - break; - need_proc = need_proc->next; - } - - if(!need_proc) - return -ESRCH; - - DEBUG(proc->is_debug,"Setpriority %d to proc %d (who %d) which %d from proc %d",prio,need_proc->id,who,which,proc->id); - need_proc->prio = prio; - - } else - return -ENOSYS; - return 0; -} - -long long sys_getpriority(int which, int who) { - int prio = 0; - if(which == 0) { // PRIO_PROCESS - arch::x86_64::process_t* proc = CURRENT_PROC; - - arch::x86_64::process_t* need_proc = arch::x86_64::scheduling::head_proc_(); - while(need_proc) { - if(need_proc->id == who) - break; - need_proc = need_proc->next; - } - - if(!need_proc) - return -ESRCH; - prio = need_proc->prio; - DEBUG(proc->is_debug,"Getpriority %d to proc %d (who %d) from proc %d",prio,need_proc->id,who,proc->id); - } else - return -ENOSYS; - return prio; -} - -syscall_ret_t sys_yield() { - yield(); - return {0,0,0}; -} - -syscall_ret_t sys_dmesg(char* buf,std::uint64_t count) { - SYSCALL_IS_SAFEA(buf,count); - arch::x86_64::process_t* proc = CURRENT_PROC; - - if(!buf) { - return {1,0,(std::int64_t)dmesg_bufsize()}; - } - - vmm_obj_t* vmm_object = memory::vmm::getlen(proc,(std::uint64_t)buf); - uint64_t need_phys = vmm_object->phys + ((std::uint64_t)buf - vmm_object->base); - - std::uint64_t offset_start = (std::uint64_t)buf - vmm_object->base; - std::uint64_t end = vmm_object->base + vmm_object->len; - - char* temp_buffer = (char*)Other::toVirt(need_phys); - memset(temp_buffer,0,count); - - dmesg_read(temp_buffer,count); - - return {1,0,0}; -} - -long long sys_getuid() { - arch::x86_64::process_t* proc = CURRENT_PROC; - return proc->uid; -} - -long long sys_getpgrp() { - arch::x86_64::process_t* proc = CURRENT_PROC; - return proc->thread_group; -} - -long long sys_setpgid(int pid, int pgid) { - arch::x86_64::process_t* proc = CURRENT_PROC; - if(pid > 0) { - proc = arch::x86_64::scheduling::by_pid(pid); - if(!proc) - return -ESRCH; - } - proc->thread_group = pgid; - return 0; -} - -long long sys_getpgid(int pid) { - arch::x86_64::process_t* proc = CURRENT_PROC; - if(pid > 0) { - proc = arch::x86_64::scheduling::by_pid(pid); - if(!proc) - return -ESRCH; - } - return proc->thread_group; -} - -long long sys_getresuid(int* ruid, int* euid, int *suid) { - - SYSCALL_IS_SAFEZ(ruid,4096); - SYSCALL_IS_SAFEZ(euid,4096); - SYSCALL_IS_SAFEZ(suid,4096); - - if(!ruid || !euid || !suid) - return -EINVAL; - - *ruid = sys_getuid(); - *euid = sys_getuid(); - *suid = sys_getuid(); - return 0; -} - -long long sys_setuid(int uid) { - arch::x86_64::process_t* proc = CURRENT_PROC; - if(proc->uid > 1000) - return -EPERM; - proc->uid = uid; - return 0; -} - -// used from mlibc source, why not - -#define CHAR_BIT 8 -#define CPU_MASK_BITS (CHAR_BIT * sizeof(__cpu_mask)) - -std::uint64_t __mlibc_cpu_alloc_size(int num_cpus) { - /* calculate the (unaligned) remainder that doesn't neatly fit in one __cpu_mask; 0 or 1 */ - std::uint64_t remainder = ((num_cpus % CPU_MASK_BITS) + CPU_MASK_BITS - 1) / CPU_MASK_BITS; - return sizeof(__cpu_mask) * (num_cpus / CPU_MASK_BITS + remainder); -} - -#define CPU_ALLOC_SIZE(n) __mlibc_cpu_alloc_size((n)) - -void __mlibc_cpu_zero(const std::uint64_t setsize, cpu_set_t *set) { - memset(set, 0, CPU_ALLOC_SIZE(setsize)); -} - -void __mlibc_cpu_set(const int cpu, const std::uint64_t setsize, cpu_set_t *set) { - if(cpu >= static_cast<int>(setsize * CHAR_BIT)) { - return; - } - - unsigned char *ptr = reinterpret_cast<unsigned char *>(set); - std::uint64_t off = cpu / CHAR_BIT; - std::uint64_t mask = 1 << (cpu % CHAR_BIT); - - ptr[off] |= mask; -} - -#define CPU_ZERO_S(setsize, set) __mlibc_cpu_zero((setsize), (set)) -#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t), set) -#define CPU_SET_S(cpu, setsize, set) __mlibc_cpu_set((cpu), (setsize), (set)) -#define CPU_SET(cpu, set) CPU_SET_S(cpu, sizeof(cpu_set_t), set) - -void __fill_cpu_set(cpu_set_t* cpuset) { - - extern int how_much_cpus; - - CPU_ZERO(cpuset); - - for(int i = 0; i < how_much_cpus; i++) { - CPU_SET(i, cpuset); - } -} - -syscall_ret_t sys_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask) { - - arch::x86_64::process_t* proc = 0; - - if(cpusetsize > sizeof(cpu_set_t)) - cpusetsize = sizeof(cpu_set_t); - - SYSCALL_IS_SAFEA(mask,cpusetsize); - if(!mask) - return {0,EINVAL,0}; - - if(pid == 0) { - proc = CURRENT_PROC; - } else if(pid > 0) { - proc = arch::x86_64::scheduling::by_pid(pid); - if(!proc) - return {0,ESRCH,0}; - } else - return {0,EINVAL,0}; - - cpu_set_t temp_set; - memset(&temp_set,0,sizeof(cpu_set_t)); - - __fill_cpu_set(&temp_set); - - memset(mask,0,cpusetsize); - memcpy(mask,&temp_set,cpusetsize); - - return {0,0,0}; -} - -syscall_ret_t sys_cpucount() { - extern int how_much_cpus; - return {0,how_much_cpus,0}; -} - -long long sys_brk() { - return 0; -} - -#define ARCH_SET_GS 0x1001 -#define ARCH_SET_FS 0x1002 -#define ARCH_GET_FS 0x1003 -#define ARCH_GET_GS 0x1004 - -#define ARCH_GET_CPUID 0x1011 -#define ARCH_SET_CPUID 0x1012 - -long long sys_arch_prctl(int option, unsigned long* addr) { - if(!addr) - return -EINVAL; - - arch::x86_64::process_t* proc = CURRENT_PROC; - - switch(option) { - case ARCH_SET_FS: - proc->fs_base = (std::uint64_t)addr; - __wrmsr(0xC0000100,(std::uint64_t)addr); - return 0; - case ARCH_GET_FS: - SYSCALL_IS_SAFEZ(addr,4096); - *addr = proc->fs_base; - return 0; - default: - Log::SerialDisplay(LEVEL_MESSAGE_FAIL,"unsupported arch_prctl option %p, addr 0x%p, shit %d\n",option,addr,0); - return -EINVAL; - }; - - return 0; -}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscalls/shm.cpp b/kernel/src/arch/x86_64/syscalls/shm.cpp deleted file mode 100644 index 7c2a278..0000000 --- a/kernel/src/arch/x86_64/syscalls/shm.cpp +++ /dev/null @@ -1,224 +0,0 @@ - -#include <arch/x86_64/syscalls/syscalls.hpp> -#include <generic/vfs/vfs.hpp> - -#include <arch/x86_64/cpu/data.hpp> -#include <arch/x86_64/scheduling.hpp> - -#include <generic/mm/pmm.hpp> -#include <generic/mm/vmm.hpp> - -#include <generic/vfs/fd.hpp> - -#include <etc/assembly.hpp> -#include <etc/logging.hpp> - -#include <drivers/cmos.hpp> - -#include <etc/libc.hpp> - -#include <drivers/tsc.hpp> - -#include <etc/errno.hpp> - -#include <drivers/hpet.hpp> -#include <drivers/kvmtimer.hpp> -#include <generic/time.hpp> -#include <generic/vfs/vfs.hpp> - -#include <etc/bootloaderinfo.hpp> -#include <generic/locks/spinlock.hpp> - -static_assert(sizeof(shm_seg_t) < 4096, "shm_seg is bigger than page size !"); - -locks::spinlock shm_lock; -shm_seg_t* shm_head; - -int shm_id_ptr = 0; - -shm_seg_t* shm_find_by_key(int key) { - shm_seg_t* current = shm_head; - while(current) { - if(current->key == key) - return current; - } - return 0; -} - -shm_seg_t* shm_find(int id) { - shm_seg_t* current = shm_head; - while(current) { - if(current->id == id) - return current; - } - return 0; -} - -void shm_rm(shm_seg_t* seg) { - shm_seg_t* prev = shm_head; - while(prev) { - if(prev->next == seg) - break; - prev = prev->next; - } - - if(shm_head == seg) - shm_head = seg->next; - else if(prev) - prev->next = seg->next; - - memory::pmm::_physical::free(seg->phys); - delete (void*)seg; -} - -shm_seg_t* shm_create(int key, size_t size) { - shm_seg_t* new_seg = new shm_seg_t; - memset(new_seg,0,sizeof(shm_seg_t)); - new_seg->next = shm_head; - shm_head = new_seg; - new_seg->key = key; - new_seg->id = shm_id_ptr++; - new_seg->len = size; - new_seg->phys = memory::pmm::_physical::alloc(new_seg->len); - return new_seg; -} - -#define IPC_CREAT 01000 -#define IPC_EXCL 02000 -#define IPC_NOWAIT 04000 - -syscall_ret_t sys_shmget(int key, size_t size, int shmflg) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - std::uint64_t src_size = size; - - if(size < 4096) { - size = 4096; - } else { - size = ALIGNUP(size,4096); - } - - shm_lock.lock(); - - shm_seg_t* seg = shm_find_by_key(key); - - shm_lock.unlock(); - - if(seg && ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL))) - return {1,EEXIST,0}; - - if(!seg && !(shmflg & IPC_CREAT)) - return {1,ENOENT,0}; - - shm_lock.lock(); - - if(shmflg & IPC_CREAT) { - seg = shm_create(key,size); - seg->ctl.shm_segsz = src_size; - seg->ctl.shm_ctime = getUnixTime(); - seg->ctl.shm_cpid = proc->id; - seg->ctl.shm_perm.cuid = proc->uid; - seg->ctl.shm_perm.uid = proc->uid; - seg->ctl.shm_perm.mode = shmflg & 0x1FF; - } - - DEBUG(proc->is_debug,"Creating/getting shm for proc %d, id %d, size %lli, src_size %d, shmflg %d",proc->id,seg->id,size,src_size,shmflg); - - shm_lock.unlock(); - - return {1,0,seg->id}; -} - -// inline static void* map(arch::x86_64::process_t* proc, std::uint64_t base, std::uint64_t length, std::uint64_t flags) { - -// inline static void* custom_map(arch::x86_64::process_t* proc, std::uint64_t virt, std::uint64_t phys, std::uint64_t length, std::uint64_t flags) { - -syscall_ret_t sys_shmat(int shmid, std::uint64_t hint, int shmflg) { - - shm_lock.lock(); - - shm_seg_t* seg = shm_find(shmid); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - if(!seg) { shm_lock.unlock(); - return {1,EINVAL,0}; } - - std::uint64_t new_hint = hint; - - new_hint = memory::vmm::shm_map(proc,seg,hint); - - memory::paging::enablepaging(proc->original_cr3); // try to reset tlb - - DEBUG(proc->is_debug,"Attaching shm %d to 0x%p, shmflg %d from proc %d",shmid,new_hint,shmflg,proc->id); - - shm_lock.unlock(); - return {1,0,new_hint}; -} - -syscall_ret_t sys_shmdt(std::uint64_t base) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - - shm_lock.lock(); - vmm_obj_t* vmm_new = memory::vmm::getlen(proc,base); - - if(!vmm_new) { shm_lock.unlock(); - return {0,EINVAL,0}; } - - if(!vmm_new->shm) { - shm_lock.unlock(); - return {0,EINVAL,0}; - } - - shm_seg_t* seg = vmm_new->shm; - //memory::vmm::unmap(proc,vmm_new->base); - - DEBUG(proc->is_debug,"Removing shm %d, base 0x%p from proc %d",seg->id,base,proc->id); - - shm_lock.unlock(); - return {0,0,0}; -} - -syscall_ret_t sys_shmctl(int shmid, int cmd, struct shmid_ds *buf) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - - shm_lock.lock(); - - shm_seg_t* seg = shm_find(shmid); - - if(!seg) { shm_lock.unlock(); - return {0,EINVAL,0}; } - - if(!buf) { shm_lock.unlock(); - return {0,EINVAL,0}; - } - - switch(cmd) { - case IPC_RMID: { - seg->is_pending_rm = 1; - if(seg->ctl.shm_nattch == 0 && seg->is_pending_rm) { - shm_rm(seg); - } - break; - } - case IPC_STAT: - memcpy(buf,&seg->ctl,sizeof(shmid_ds)); - break; - case IPC_SET: - seg->ctl.shm_perm.uid = buf->shm_perm.uid; - seg->ctl.shm_perm.gid = buf->shm_perm.gid; - seg->ctl.shm_ctime = getUnixTime(); - seg->ctl.shm_perm.mode = buf->shm_perm.mode; - break; - default: - Log::SerialDisplay(LEVEL_MESSAGE_WARN,"Unknown shmctl cmd %d for id %d from proc %d\n",cmd,shmid,proc->id); - break; - } - - DEBUG(proc->is_debug,"shmctl id %d cmd %d buf 0x%p from proc %d\n",shmid,cmd,buf,proc->id); - - shm_lock.unlock(); - return {0,0,0}; -}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscalls/signal.cpp b/kernel/src/arch/x86_64/syscalls/signal.cpp deleted file mode 100644 index f156c79..0000000 --- a/kernel/src/arch/x86_64/syscalls/signal.cpp +++ /dev/null @@ -1,304 +0,0 @@ - -#include <arch/x86_64/syscalls/syscalls.hpp> -#include <generic/vfs/vfs.hpp> - -#include <arch/x86_64/cpu/data.hpp> -#include <arch/x86_64/scheduling.hpp> - -#include <generic/mm/pmm.hpp> -#include <generic/mm/vmm.hpp> - -#include <generic/vfs/fd.hpp> - -#include <etc/assembly.hpp> -#include <etc/logging.hpp> - -#include <drivers/cmos.hpp> - -#include <etc/libc.hpp> - -#include <drivers/tsc.hpp> - -#include <etc/errno.hpp> - -#include <drivers/hpet.hpp> -#include <drivers/kvmtimer.hpp> -#include <generic/time.hpp> -#include <generic/vfs/vfs.hpp> - -#include <etc/bootloaderinfo.hpp> -#include <generic/locks/spinlock.hpp> - -syscall_ret_t sys_orangesigreturn(mcontext_t* mctx, int b, int c, int_frame_t* ctx) { - // is_sig_real - arch::x86_64::process_t* proc = CURRENT_PROC; - mcontext_to_int_frame(mctx,&proc->ctx); - proc->ctx.cs = 0x20 | 3; - proc->ctx.ss = 0x18 | 3; - proc->ctx.rflags |= (1 << 9); - DEBUG(1,"endsig from proc %d rip 0x%p",proc->id,proc->ctx.rip); - schedulingScheduleAndChangeStack(arch::x86_64::cpu::data()->timer_ist_stack,0); - __builtin_unreachable(); -} - -syscall_ret_t sys_orangedefaulthandler(void* handler) { - return {0,ENOSYS,0}; - arch::x86_64::process_t* proc = CURRENT_PROC; - - DEBUG(proc->is_debug,"Setup default handler 0x%p from proc %d\n",handler,proc->id); - - return {0,0,0}; -} - -long long sys_pause() { - arch::x86_64::process_t* proc = CURRENT_PROC; - - while(1) { - signal_ret(); - yield(); - } - - return 0; -} - -long long sys_tgkill(int tgid, int tid, int sig) { - return sys_kill(tid,sig); -} - -long long sys_kill(int pid, int sig) { - arch::x86_64::process_t* proc = CURRENT_PROC; - arch::x86_64::process_t* target_proc = arch::x86_64::scheduling::by_pid(pid); - - DEBUG(1,"Trying to kill %d with sig %d from proc %d\n",pid,sig,proc->id); - - if(!target_proc) - return -ESRCH; - - if(pid == 0 && pid < 0) - return 0; // not implemented - - if(!(proc->uid == 0 || proc->uid == target_proc->uid)) - return -EPERM; - - switch(sig) { - case SIGKILL: - target_proc->exit_code = 137; - target_proc->_3rd_kill_lock.nowaitlock(); - break; - case SIGTSTP: - case SIGTTIN: - case SIGTTOU: - case SIGSTOP: - if(target_proc->id == proc->id) // shit - yield(); - return 0; - default: - pending_signal_t pend_sig; - pend_sig.sig = sig; - target_proc->sig->push(&pend_sig); - - DEBUG(1,"%d 0x%p",target_proc->id == proc->id,proc->sig_handlers[sig]); - - if(target_proc->id == proc->id) // shit - signal_ret(); - - return 0; - } - - if(target_proc->id == proc->id) // shit - signal_ret(); - - return 0; -} - -long long sys_sigaction(int signum, struct sigaction* hnd, struct sigaction* old, int_frame_t* ctx) { - arch::x86_64::process_t* proc = CURRENT_PROC; - SYSCALL_IS_SAFEZ(hnd,4096); - SYSCALL_IS_SAFEZ(old,4096); - - DEBUG(proc->is_debug,"sigaction signum %d from proc %d with 0x%p",signum,proc->id,0); - - if(ctx->r10 != sizeof(sigset_t)) { - DEBUG(proc->is_debug,"unsupported len %d for sigset sig %d from proc %d (linux dont support this)",ctx->r10,signum,proc->id); - return -EINVAL; - } - - if(signum >= 36) - return -EINVAL; - - void* old_hnd = proc->sig_handlers[signum]; - void* old_rest = proc->ret_handlers[signum]; - if(old) { - memset(old,0,sizeof(struct sigaction)); - old->sa_handler = (void (*)(int))old_hnd; - old->sa_restorer = (void (*)())old_rest; - old->sa_flags = proc->sig_flags[signum]; - memcpy(&old->sa_mask,&proc->sigsets[signum],sizeof(sigset_t)); - } - - if(hnd) { - DEBUG(proc->is_debug,"sigaction %d, restorer 0x%p, handler 0x%p",signum,hnd->sa_restorer,hnd->sa_handler); - proc->ret_handlers[signum] = (void*)hnd->sa_restorer; - proc->sig_handlers[signum] = (void*)hnd->sa_handler; - proc->sig_flags[signum] = hnd->sa_flags; - memcpy(&proc->sigsets[signum],&hnd->sa_mask,sizeof(sigset_t)); - } - - return 0; - -} - -#define SIG_BLOCK 0 /* Block signals. sigset_t *unewset size_t sigsetsize */ -#define SIG_UNBLOCK 1 /* Unblock signals. */ -#define SIG_SETMASK 2 /* Set the set of blocked signals. */ - -long long sys_alarm(int seconds) { - arch::x86_64::process_t* proc = CURRENT_PROC; - std::uint64_t t = proc->next_alarm; - if(seconds != 0) { - proc->next_alarm = drivers::tsc::currentus() + (seconds * (1000*1000)); - DEBUG(proc->is_debug,"alarm to %lli (%d seconds)",proc->next_alarm,seconds); - } else { - proc->next_alarm = 0; - } - if(t == 0) - return 0; - else { - t -= drivers::tsc::currentus(); - return (t / (1000 * 1000)) < 0 ? 0 : t / (1000 * 1000); - } - return 0; -} - -long long sys_sigprocmask(int how, const sigset_t *set, sigset_t *oldset, int_frame_t* ctx) { - arch::x86_64::process_t* proc = CURRENT_PROC; - SYSCALL_IS_SAFEZ((void*)set,4096); - SYSCALL_IS_SAFEZ(oldset,4096); - - if(ctx->r10 != sizeof(sigset_t)) { - DEBUG(proc->is_debug,"unsupported sigset len %d when normal is %d (even linux dont support this)",ctx->r10,sizeof(sigset_t)); - return 0; - } - - DEBUG(proc->is_debug,"sigprocmask 0x%p old 0x%p, size %lli",set,oldset,ctx->r10); - - if(oldset) { - memcpy(oldset,&proc->current_sigset,sizeof(sigset_t)); - } - - if(set) { - memcpy(&proc->current_sigset,set,sizeof(sigset_t)); - } - - return 0; -} - - - -long long sys_setitimer(int which, itimerval* val, itimerval* old) { - arch::x86_64::process_t* proc = CURRENT_PROC; - - SYSCALL_IS_SAFEZ(val,4096); - SYSCALL_IS_SAFEZ(old,4096); - - if(!val) - return -EINVAL; - - itimerval oldv = {0}; - std::uint64_t ns = 0; - switch(which) { - case ITIMER_REAL: - oldv = proc->itimer; - proc->itimer = *val; - arch::x86_64::update_time(&proc->itimer,&proc->next_alarm,1); - break; - case ITIMER_PROF: - oldv = proc->proftimer; - proc->proftimer = *val; - arch::x86_64::update_time(&proc->proftimer,&proc->prof_timer,0); - break; - case ITIMER_VIRTUAL: - oldv = proc->vitimer; - proc->vitimer = *val; - arch::x86_64::update_time(&proc->vitimer,&proc->virt_timer,0); - break; - default: - return -EINVAL; - } - - if(old) - *old = oldv; - - return 0; -} - -long long sys_getitimer(int which, itimerval* val) { - arch::x86_64::process_t* proc = CURRENT_PROC; - - SYSCALL_IS_SAFEZ(val,4096); - - if(!val) - return -EINVAL; - - std::uint64_t ns = 0; - switch(which) { - case ITIMER_REAL: - *val = proc->itimer; - ns = (proc->next_alarm - drivers::tsc::currentus()) * 1000; - val->it_value.tv_sec = ns / 1000000000; - val->it_value.tv_usec = (ns % 1000000000) / 1000; - return 0; - case ITIMER_PROF: - *val = proc->proftimer; - ns = (proc->prof_timer) * 1000; - val->it_value.tv_sec = ns / 1000000000; - val->it_value.tv_usec = (ns % 1000000000) / 1000; - return 0; - case ITIMER_VIRTUAL: - *val = proc->vitimer; - ns = (proc->virt_timer) * 1000; - val->it_value.tv_sec = ns / 1000000000; - val->it_value.tv_usec = (ns % 1000000000) / 1000; - return 0; - default: - return -EINVAL; - } - return -EINVAL; -} - -// same as sys_pause but wait for signals -long long sys_sigsuspend(sigset_t* sigset, size_t size) { - - if(size != sizeof(sigset_t)) - return -EINVAL; - - if(!sigset) - return -EINVAL; - - SYSCALL_IS_SAFEZ(sigset,4096); - - arch::x86_64::process_t* proc = CURRENT_PROC; - - while(1) { - signal_ret_sigmask(sigset); - yield(); - } - - return 0; -} - -long long sys_sigaltstack(stack_t* new_stack, stack_t* old) { - arch::x86_64::process_t* proc = CURRENT_PROC; - SYSCALL_IS_SAFEZ(new_stack,4096); - SYSCALL_IS_SAFEZ(old,4096); - - if(old) { - *old = proc->altstack; - } - - if(new_stack) { - proc->altstack = *new_stack; - } - - return 0; -}
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscalls/sockets.cpp b/kernel/src/arch/x86_64/syscalls/sockets.cpp deleted file mode 100644 index f5c28af..0000000 --- a/kernel/src/arch/x86_64/syscalls/sockets.cpp +++ /dev/null @@ -1,467 +0,0 @@ - -#include <arch/x86_64/syscalls/syscalls.hpp> -#include <arch/x86_64/syscalls/sockets.hpp> - -#include <generic/vfs/vfs.hpp> - -#include <generic/vfs/fd.hpp> - -#include <generic/locks/spinlock.hpp> - -#include <etc/errno.hpp> - -#include <cstdint> - -locks::spinlock socket_spinlock; -socket_node_t* head = 0; - -char is_socket_init = 0; - -socket_node_t* find_node(struct sockaddr_un* path) { - socket_node_t* current = head; - while(current) { - if(!memcmp(current->path,path->sun_path,sizeof(path->sun_path))) { - return current; - } - current = current->next; - } - return 0; -} - -socket_node_t* sockets::find(char* path) { - socket_node_t* current = head; - int is_abstract = 0; - if(path[0] == '\0') {// abstract path - path += 1; - is_abstract = 1; - } - while(current) { - if(!strcmp(is_abstract == 1 ? current->path + 1 : current->path,path)) { - return current; - } - current = current->next; - } - return 0; -} - -socket_node_t* find_node_str(char* path) { - return sockets::find(path); -} - -char sockets::is_exists(char* path) { - - if(!is_socket_init) - return 0; - - socket_node_t* node = find_node_str(path); - if(!node) - return 0; - return 1; -} - -int sockets::bind(userspace_fd_t* fd, struct sockaddr_un* path) { - - if(!fd || !path) - return -EINVAL; - - if(path->sun_family != AF_UNIX) - return -ENOSYS; - - memset(fd->path,0,2048); - memcpy(fd->path,path->sun_path,sizeof(path->sun_path)); - - vfs::stat_t stat; - if(vfs::vfs::stat(fd,&stat) == 0) /* Check is there vfs object with some name */ - return -EEXIST; - - socket_spinlock.lock(); - - if(find_node(path)) { socket_spinlock.unlock(); - return -EEXIST; } - - socket_node_t* new_node = new socket_node_t; - memset(new_node->path,0,128); - memcpy(new_node->path,path->sun_path,108); - new_node->is_used = 1; - new_node->socket_counter = 0; - new_node->next = head; - - fd->binded_socket = (void*)new_node; - head = new_node; - socket_spinlock.unlock(); - - return 0; - -} - -int sockets::connect(userspace_fd_t* fd, struct sockaddr_un* path) { - - if(!fd || !path) - return -EINVAL; - - if(path->sun_family != AF_UNIX) - return -ENOSYS; - - //socket_spinlock.lock(); - - socket_node_t* node = find_node(path); - if(!node) { //socket_spinlock.unlock(); - return -ENOENT; } - - socket_pending_obj_t* pending = new socket_pending_obj_t; - pending->son = fd; - pending->next = node->pending_list; - pending->is_accepted.unlock(); - node->pending_list = pending; - - memcpy(fd->path,node->path,sizeof(node->path)); - - node->socket_counter++; - - while(!pending->is_accepted.test()) { yield(); } - - //socket_spinlock.unlock(); - return 0; -} - -int sockets::accept(userspace_fd_t* fd, struct sockaddr_un* path) { - if(!fd) - return -EINVAL; - - arch::x86_64::process_t* proc = CURRENT_PROC; - - socket_spinlock.lock(); - - socket_node_t* node = find_node_str(fd->path); - if(!node) { socket_spinlock.unlock(); - return -ENOENT; } - - socket_pending_obj_t* pending_connections = node->pending_list; - while(1) { - while(pending_connections) { - if(!pending_connections->is_accepted.test()) { - int new_fd = vfs::fdmanager::create(proc); - - userspace_fd_t* new_fd_s = vfs::fdmanager::search(proc,new_fd); - memset(new_fd_s->path,0,2048); - memcpy(new_fd_s->path,fd->path,strlen(fd->path)); - - new_fd_s->offset = 0; - new_fd_s->queue = 0; - new_fd_s->pipe = 0; - new_fd_s->pipe_side = 0; - new_fd_s->cycle = 0; - new_fd_s->is_a_tty = 0; - new_fd_s->is_cached_path = 0; - - new_fd_s->state = USERSPACE_FD_STATE_SOCKET; - new_fd_s->other_state = USERSPACE_FD_OTHERSTATE_MASTER; // master - writes to read pipe and reads from write pipe - - pending_connections->son->other_state = USERSPACE_FD_OTHERSTATE_SLAVE; - - new_fd_s->read_socket_pipe = new vfs::pipe(0); - new_fd_s->write_socket_pipe = new vfs::pipe(0); - - new_fd_s->read_socket_pipe->create(PIPE_SIDE_READ); - new_fd_s->read_socket_pipe->create(PIPE_SIDE_WRITE); - new_fd_s->write_socket_pipe->create(PIPE_SIDE_READ); - new_fd_s->write_socket_pipe->create(PIPE_SIDE_WRITE); - - new_fd_s->read_socket_pipe->ucred_pass = new vfs::ucred_manager; - new_fd_s->write_socket_pipe->ucred_pass = new vfs::ucred_manager; - - new_fd_s->socket_pid = pending_connections->son->pid; - new_fd_s->socket_uid = pending_connections->son->uid; - - pending_connections->son->read_socket_pipe = new_fd_s->read_socket_pipe; - pending_connections->son->write_socket_pipe = new_fd_s->write_socket_pipe; - - //Log::SerialDisplay(LEVEL_MESSAGE_INFO,"together fd %d fd2 %d\n",pending_connections->son->index,new_fd_s->index); - - if(path) - memcpy(path->sun_path,node->path,sizeof(path->sun_path)); - - pending_connections->is_accepted.test_and_set(); - - socket_spinlock.unlock(); - return new_fd_s->index; - - } - pending_connections = pending_connections->next; - } - socket_spinlock.unlock(); - yield(); - socket_spinlock.lock(); - pending_connections = node->pending_list; - } - - return -EFAULT; -} - -void sockets::init() { - is_socket_init = 1; - socket_spinlock.unlock(); -} - -long long sys_connect(int fd, struct sockaddr_un* path, int len) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - if(!fd_s) - return -EBADF; - - if(!path) - return -EINVAL; - - DEBUG(1,"Trying to connect to socket %s (fd %d) from proc %d",path->sun_path,fd,proc->id); - - int status = sockets::connect(fd_s,path); - - DEBUG(proc->is_debug,"Socket is connected %s from proc %d, status %d",path->sun_path,proc->id,status); - - return status; -} - -long long sys_bind(int fd, struct sockaddr_un* path, int len) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - if(!path) - return -EINVAL; - - if(!fd_s) - return -EBADF; - - struct sockaddr_un spath = *path; - - DEBUG(proc->is_debug,"Binding socket from fd %d to %s from proc %d",fd,spath.sun_path + 1,proc->id); - - int status = sockets::bind(fd_s,&spath); - - memcpy(fd_s->path,spath.sun_path,sizeof(spath.sun_path)); - - return status; -} - -long long sys_accept(int fd, struct sockaddr_un* path, int* zlen) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - if(!zlen) - return -EINVAL; - - SYSCALL_IS_SAFEZ(zlen,4096); - - int len = sizeof(sockaddr_un); - - struct sockaddr_un spath; - - if(path) { - memset(&spath,0,sizeof(spath)); - copy_in_userspace(proc,&spath,path,len > sizeof(spath) ? sizeof(spath) : len); - } - - if(!fd_s) - return -EBADF; - - - DEBUG(proc->is_debug,"Accepting socket %s on fd %d from proc %d, path %s",fd_s->path + 1,fd,proc->id,spath.sun_path); - - int status = sockets::accept(fd_s,path != 0 ? &spath : 0); - - if(path) - copy_in_userspace(proc,path,&spath,len > sizeof(spath) ? sizeof(spath) : len); - - return status; -} - -#define SOCK_NONBLOCK 04000 -#define SOCK_CLOEXEC 02000000 -#define SOCK_STREAM 1 -#define SOCK_DGRAM 2 - -long long sys_socket(int family, int type, int protocol) { - arch::x86_64::process_t* proc = CURRENT_PROC; - - if(family != AF_UNIX) - return -EINVAL; // only unix socekts fo rnow - - std::uint8_t socket_type = type & 0xFF; - - if(socket_type != SOCK_STREAM) { - Log::SerialDisplay(LEVEL_MESSAGE_WARN,"Tried to open non SOCK_STREAM socket which not implemented (socket type %d)\n",socket_type); - //return {1,ENOSYS,0}; - } - - int new_fd = vfs::fdmanager::create(proc); - - userspace_fd_t* new_fd_s = vfs::fdmanager::search(proc,new_fd); - memset(new_fd_s->path,0,2048); - - new_fd_s->offset = 0; - new_fd_s->queue = 0; - new_fd_s->pipe = 0; - new_fd_s->pipe_side = 0; - new_fd_s->cycle = 0; - new_fd_s->is_a_tty = 0; - new_fd_s->is_listen = 0; - new_fd_s->flags = (type & SOCK_NONBLOCK) ? O_NONBLOCK : 0; - - new_fd_s->state = USERSPACE_FD_STATE_SOCKET; - - DEBUG(proc->is_debug,"Creating socket on fd %d from proc %d",new_fd,proc->id); - - return new_fd; -} - -long long sys_listen(int fd, int backlog) { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - if(!fd_s) - return -EBADF; - - if(fd_s->state == USERSPACE_FD_STATE_SOCKET) { - if(!fd_s->read_socket_pipe) { // not connected - fd_s->is_listen = 1; - } - } else - return -ENOTSOCK; - - return 0; -} - -syscall_ret_t sys_socketpair(int domain, int type_and_flags, int proto) { - - arch::x86_64::process_t* proc = CURRENT_PROC; - int read_fd = vfs::fdmanager::create(proc); - int write_fd = vfs::fdmanager::create(proc); - userspace_fd_t* fd1 = vfs::fdmanager::search(proc,read_fd); - userspace_fd_t* fd2 = vfs::fdmanager::search(proc,write_fd); - - vfs::pipe* first = new vfs::pipe(0); - vfs::pipe* second = new vfs::pipe(0); - - fd1->read_socket_pipe = first; - fd2->write_socket_pipe = first; - fd1->write_socket_pipe = second; - fd2->read_socket_pipe = second; - - fd1->other_state = USERSPACE_FD_OTHERSTATE_MASTER; - fd2->other_state = USERSPACE_FD_OTHERSTATE_MASTER; - - fd1->read_socket_pipe->create(PIPE_SIDE_READ); - fd1->read_socket_pipe->create(PIPE_SIDE_WRITE); - fd1->write_socket_pipe->create(PIPE_SIDE_READ); - fd1->write_socket_pipe->create(PIPE_SIDE_WRITE); - - fd1->state = USERSPACE_FD_STATE_SOCKET; - fd2->state = USERSPACE_FD_STATE_SOCKET; - - DEBUG(proc->is_debug,"Creating socketpair %d:%d from proc %d",read_fd,write_fd,proc->id); - - return {1,read_fd,write_fd}; -} - -long long sys_getsockname(int fd, struct sockaddr_un* path, int* len) { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - if(!fd_s) - return -EBADF; - - if(path) { - path->sun_family = AF_UNIX; - memcpy(path->sun_path,fd_s->path,strlen(fd_s->path) + 1); - *len = strlen(fd_s->path); - return 0; - } else - return -EINVAL; - return 0; -} - -#define SO_PEERCRED 17 - -long long sys_getsockopt(int fd, int layer, int number, int_frame_t* ctx) { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); - - if(!fd_s) - return -EBADF; - - void* buffer = (void*)ctx->r10; - - int* optlen = (int*)ctx->r8; - - SYSCALL_IS_SAFEZ(buffer,4096); - SYSCALL_IS_SAFEZ(optlen,4096); - - if(!buffer) - return -EINVAL; - - if(fd_s->state != USERSPACE_FD_STATE_SOCKET || !fd_s->read_socket_pipe) - return -EBADF; - - switch(number) { - - case SO_PEERCRED: { - struct ucred* cred = (struct ucred*)buffer; - cred->pid = fd_s->socket_pid; - cred->uid = fd_s->socket_uid; - cred->gid = 0; // not implemented - - if(optlen) - *optlen = sizeof(struct ucred); - - return 0; - }; - - default: { - return -ENOSYS; - }; - - } - - return 0; - -} - -#define SHUT_RD 0 -#define SHUT_WR 1 -#define SHUT_RDWR 2 - -long long sys_shutdown(int sockfd, int how) { - arch::x86_64::process_t* proc = CURRENT_PROC; - userspace_fd_t* fd_s = vfs::fdmanager::search(proc,sockfd); - - if(!fd_s) - return -EBADF; - - if(fd_s->state != USERSPACE_FD_STATE_SOCKET) - return -ENOTSOCK; - - if(fd_s->is_listen || fd_s->read_socket_pipe == 0) - return -ENOTCONN; - - switch(how) { - case SHUT_RD: - case SHUT_RDWR: - fd_s->read_socket_pipe->lock.lock(); - fd_s->write_socket_pipe->lock.lock(); - fd_s->read_socket_pipe->is_closed.test_and_set(); - fd_s->write_socket_pipe->is_closed.test_and_set(); - fd_s->read_socket_pipe->lock.unlock(); - fd_s->write_socket_pipe->lock.unlock(); - DEBUG(proc->is_debug,"shutdown %d from proc %d",sockfd,proc->id); - break; - case SHUT_WR: - return -ENOSYS; - default: - return -EINVAL; - } - - return 0; -} diff --git a/kernel/src/arch/x86_64/syscalls/syscalls.cpp b/kernel/src/arch/x86_64/syscalls/syscalls.cpp deleted file mode 100644 index 927297a..0000000 --- a/kernel/src/arch/x86_64/syscalls/syscalls.cpp +++ /dev/null @@ -1,269 +0,0 @@ - -#include <cstdint> -#include <arch/x86_64/syscalls/syscalls.hpp> - -#include <etc/assembly.hpp> -#include <etc/logging.hpp> - -#include <generic/locks/spinlock.hpp> - -#include <generic/vfs/fd.hpp> - -#include <arch/x86_64/scheduling.hpp> -#include <arch/x86_64/cpu/data.hpp> - -#include <arch/x86_64/syscalls/signal.hpp> - -#include <etc/errno.hpp> - -extern "C" syscall_ret_t sys_hello(int a, int b ,int c) { - DEBUG(1,"hello"); - return {0,0,0}; -} - -void signal_ret_sigmask(sigset_t* sigmask) { - // it can be only called from syscall - cpudata_t* cpdata = arch::x86_64::cpu::data(); - - if(!cpdata) - return; - - arch::x86_64::process_t* proc = cpdata->temp.proc; - if(!proc) - return; - - if(proc->sig->is_not_empty_sigset(sigmask) && 1) { - - memcpy(&proc->temp_sigset,&proc->current_sigset,sizeof(sigset_t)); - memcpy(&proc->current_sigset,sigmask,sizeof(sigset_t)); - proc->is_restore_sigset = 1; - - proc->ctx = *proc->sys_ctx; - proc->ctx.rax = -EINTR; - schedulingScheduleAndChangeStack(arch::x86_64::cpu::data()->timer_ist_stack,0); - __builtin_unreachable(); - - } - - return; - -} - -void signal_ret() { - // it can be only called from syscall - cpudata_t* cpdata = arch::x86_64::cpu::data(); - - if(!cpdata) - return; - - arch::x86_64::process_t* proc = cpdata->temp.proc; - if(!proc) - return; - - PREPARE_SIGNAL(proc) { - - - - proc->ctx = *proc->sys_ctx; - proc->ctx.rax = -EINTR; - schedulingScheduleAndChangeStack(arch::x86_64::cpu::data()->timer_ist_stack,0); - __builtin_unreachable(); - - } - - return; - -} - -long long sys_stub() { - return -ENOSYS; -} - -long long sys_zero_stub() { - return 0; -} - -arch::x86_64::syscall_item_t sys_table[] = { - {12,(void*)sys_zero_stub}, // brk - {21,(void*)sys_access}, - {257,(void*)sys_openat}, - {5,(void*)sys_fstat}, - {3,(void*)sys_close}, - {0,(void*)sys_read}, - {20,(void*)sys_writev}, - {231,(void*)sys_exit_group}, - {262,(void*)sys_newfstatat}, - {9,(void*)sys_mmap}, - {17,(void*)sys_pread}, - {158,(void*)sys_arch_prctl}, - {202,(void*)sys_futex}, - {218,(void*)sys_set_tid_address}, - {273,(void*)sys_stub}, - {334,(void*)sys_stub}, - {10,(void*)sys_mprotect}, - {302,(void*)sys_prlimit64}, - {318,(void*)sys_getrandom}, - {228,(void*)sys_clock_gettime}, - {16,(void*)sys_ioctl}, - {11,(void*)sys_free}, - {8,(void*)sys_lseek}, - {33,(void*)sys_dup2}, - {13,(void*)sys_sigaction}, - {14,(void*)sys_sigprocmask}, - {28,(void*)sys_zero_stub}, - {435,(void*)sys_clone3}, - {203,(void*)sys_zero_stub}, - {1,(void*)sys_write}, - {59,(void*)sys_exec}, - {18,(void*)sys_pwrite}, - {27,(void*)sys_stub}, - {7,(void*)sys_poll}, - {72,(void*)sys_fcntl}, - {102,(void*)sys_getuid}, - {104,(void*)sys_zero_stub}, // get_gid - {107,(void*)sys_getuid}, // get_euid, - {108,(void*)sys_zero_stub}, // get_egid - {96,(void*)sys_gettimeofday}, - {63,(void*)sys_uname}, - {79,(void*)sys_getcwd}, - {39,(void*)sys_getpid}, - {110,(void*)sys_getppid}, - {62,(void*)sys_kill}, - {34,(void*)sys_pause}, - {105,(void*)sys_setuid}, - {60,(void*)sys_exit}, - {111,(void*)sys_getpgrp}, - {56,(void*)sys_clone}, - {61,(void*)sys_wait4}, - {41,(void*)sys_socket}, - {42,(void*)sys_connect}, - {50,(void*)sys_listen}, - {44,(void*)sys_sendto}, - {32,(void*)sys_dup2}, - {109,(void*)sys_setpgid}, // set pgid todo - {201,(void*)sys_time}, - {217,(void*)sys_getdents64}, - {80,(void*)sys_chdir}, - {81,(void*)sys_fchdir}, - {332,(void*)sys_statx}, - {267,(void*)sys_readlinkat}, - {89,(void*)sys_readlink}, - {258,(void*)sys_mkdirat}, - {83,(void*)sys_mkdir}, - {293,(void*)sys_pipe2}, - {86,(void*)sys_link}, - {265,(void*)sys_linkat}, - {22,(void*)sys_pipe}, - {88,(void*)sys_symlink}, - {266,(void*)sys_symlinkat}, - {82,(void*)sys_rename}, - {264,(void*)sys_renameat}, - {316,(void*)sys_renameat}, - {221,(void*)sys_stub}, - {90,(void*)sys_chmod}, - {91,(void*)sys_fchmod}, - {268,(void*)sys_fchmodat}, - {452,(void*)sys_fchmodat2}, - {326,(void*)sys_stub}, - {285,(void*)sys_stub}, - {77,(void*)sys_stub}, // todo implement ftrunc - {95,(void*)sys_umask}, - {230,(void*)sys_nanosleep}, - {55,(void*)sys_getsockopt}, - {49,(void*)sys_bind}, - {229,(void*)sys_stub}, //clock_getres - {48,(void*)sys_shutdown}, - {106,(void*)sys_zero_stub}, // set_gid - {157,(void*)sys_stub}, // prctl - {141,(void*)sys_setpriority}, - {140,(void*)sys_getpriority}, - {98,(void*)sys_stub}, // getrusage - {37,(void*)sys_alarm}, - {38,(void*)sys_setitimer}, - {36,(void*)sys_getitimer}, - {130,(void*)sys_sigsuspend}, - {52,(void*)sys_stub}, // get peername - {51,(void*)sys_getsockname}, - {47,(void*)sys_msg_recv}, - {43,(void*)sys_accept}, - {186,(void*)sys_getpid}, - {234,(void*)sys_tgkill}, // tgkill - {99,(void*)sys_sysinfo}, - {439,(void*)sys_faccessat}, - {334,(void*)sys_faccessat}, - {118,(void*)sys_getresuid}, - {120,(void*)sys_zero_stub}, // getgid - {122,(void*)sys_zero_stub}, // setfsuid - {123,(void*)sys_zero_stub}, // setfsgid - {121,(void*)sys_getpgid}, - {270,(void*)sys_pselect6}, - {137,(void*)sys_statfs}, - {138,(void*)sys_fstatfs}, - {74,(void*)sys_zero_stub}, // fsync - {144,(void*)sys_zero_stub}, // setscheduler - {131,(void*)sys_sigaltstack}, - {25,(void*)sys_stub}, // mremap - {87,(void*)sys_unlink}, - {263,(void*)sys_unlinkat} -}; - -arch::x86_64::syscall_item_t* __syscall_find(int rax) { - for(int i = 0; i < sizeof(sys_table) / sizeof(arch::x86_64::syscall_item_t);i++) { - if(sys_table[i].syscall_num == rax) - return &sys_table[i]; - } - Log::SerialDisplay(LEVEL_MESSAGE_WARN,"unknown syscall %d",rax); - return 0; // without it there will be ub -} - -extern "C" void syscall_handler_c(int_frame_t* ctx) { - - arch::x86_64::syscall_item_t* item = __syscall_find(ctx->rax); - - if(!item) { - assert(0,"unimplemented syscall %d !\n",ctx->rax); - ctx->rax = -ENOSYS; - return; - } - - - - cpudata_t* cpdata = arch::x86_64::cpu::data(); - arch::x86_64::process_t* proc = cpdata->temp.proc; - proc->old_stack = ctx->rsp; - - if(1) - proc->sys = ctx->rax; - - extern int last_sys; - last_sys = ctx->rax; - - DEBUG(0,"sys %d from %d rdi 0x%p, rsi %lli",ctx->rax,proc->id,ctx->rdi,ctx->rsi); - - //DEBUG(1,"sys %d from %d rip 0x%p, min_free_fd %d",ctx->rax,proc->id,ctx->rip,vfs::fdmanager::min_free(proc)); - - proc->sys_ctx = ctx; - - long long (*sys)(std::uint64_t D, std::uint64_t S, std::uint64_t d, int_frame_t* frame) = (long long (*)(std::uint64_t, std::uint64_t, std::uint64_t, int_frame_t*))item->syscall_func; - long long ret = sys(ctx->rdi,ctx->rsi,ctx->rdx,ctx); - ctx->rax = ret; - - if(proc->is_debug) - DEBUG(ret < 0,"sys %d failed with code %lli",item->syscall_num,ctx->rax); - - //DEBUG(1,"sys %d ret %d",item->syscall_num,ctx->rax); - - cpdata->temp.temp_ctx = 0; - - proc->sys_ctx = 0; - - return; -} - -void arch::x86_64::syscall::init() { - __wrmsr(STAR_MSR,(0x08ull << 32) | (0x10ull << 48)); - __wrmsr(LSTAR,(uint64_t)syscall_handler); - __wrmsr(STAR_MASK,(1 << 9)); // syscalls will enable interrupts when gs is swapped + stack is saved - __wrmsr(EFER,__rdmsr(EFER) | 1); -} - diff --git a/kernel/src/arch/x86_64/x86_64.cpp b/kernel/src/arch/x86_64/x86_64.cpp new file mode 100644 index 0000000..e45d336 --- /dev/null +++ b/kernel/src/arch/x86_64/x86_64.cpp @@ -0,0 +1,120 @@ + +#include <cstdint> +#include <generic/arch.hpp> +#include <generic/bootloader/bootloader.hpp> +#include <arch/x86_64/drivers/hpet.hpp> +#include <arch/x86_64/cpu_local.hpp> +#include <arch/x86_64/drivers/tsc.hpp> +#include <arch/x86_64/cpu/gdt.hpp> +#include <arch/x86_64/cpu/idt.hpp> +#include <klibc/stdio.hpp> + +typedef struct stackframe { + struct stackframe* rbp; + uint64_t rip; +} __attribute__((packed)) stackframe_t; + +void print_regs(x86_64::idt::int_frame_t* ctx) { + uint64_t cr2; + asm volatile("mov %%cr2, %0" : "=r"(cr2) : : "memory"); + klibc::printf("Kernel panic\n\nReason: %s\n\r","cpu exception"); + klibc::printf("RAX: 0x%016llX RBX: 0x%016llX RDX: 0x%016llX RCX: 0x%016llX RDI: 0x%016llX\n\r" + "RSI: 0x%016llX R8: 0x%016llX R9: 0x%016llX R10: 0x%016llX R11: 0x%016llX\n\r" + "R12: 0x%016llX R13: 0x%016llX R14: 0x%016llX R15: 0x%016llX RBP: 0x%016llX\n\r" + "RSP: 0x%016llX CR2: 0x%016llX CR3: 0x%016llX\n\r" + "Vec: %d Err: %d cs: %p ss: %p\n\r", + ctx->rax, ctx->rbx, ctx->rdx, ctx->rcx, ctx->rdi, + ctx->rsi, ctx->r8, ctx->r9, ctx->r10, ctx->r11, + ctx->r12, ctx->r13, ctx->r14, ctx->r15, ctx->rbp, + ctx->rsp, cr2, ctx->cr3, ctx->vec, ctx->err_code, ctx->cs,ctx->ss); + klibc::printf("\n\r Stacktrace\n\r\n\r"); + + stackframe_t* rbp = (stackframe_t*)ctx->rbp; + + klibc::printf("[0] - 0x%016llX (current rip)\n\r",ctx->rip); + for (int i = 1; i < 5 && rbp; ++i) { + std::uint64_t ret_addr = rbp->rip; + klibc::printf("[%d] - 0x%016llX\n\r", i, ret_addr); + rbp = (stackframe_t*)rbp->rbp; + } + +} + +std::uint8_t gaster[] = { +#embed "src/gaster.txt" +}; + +void print_ascii_art() { + klibc::printf("%s\n",gaster); +} + +extern "C" void CPUKernelPanic(x86_64::idt::int_frame_t* frame) { + print_ascii_art(); + print_regs(frame); + arch::hcf(); +} + +namespace arch { + [[gnu::weak]] void disable_interrupts() { + asm volatile("cli"); + } + + [[gnu::weak]] void enable_interrupts() { + asm volatile("sti"); + } + + [[gnu::weak]] void wait_for_interrupt() { + asm volatile("hlt"); + } + + [[gnu::weak]] void hcf() { + disable_interrupts(); + while(true) { + wait_for_interrupt(); + } + } + + [[gnu::weak]] void pause() { + asm volatile("pause"); + } + + [[gnu::weak]] void tlb_flush(std::uintptr_t hint, std::uintptr_t len) { + if (len / PAGE_SIZE > 256 || len == 0) { + std::uint64_t cr3 = 0; + asm volatile("mov %%cr3, %0" : "=r"(cr3) : : "memory"); + asm volatile("mov %0, %%cr3" : : "r"(cr3) : "memory"); + } else { + for (std::uintptr_t i = 0; i < len; i += PAGE_SIZE) { + asm volatile("invlpg (%0)" : : "b"(hint + i) : "memory"); + } + } + } + + [[gnu::weak]] const char* name() { + return "x86_64"; + } + + [[gnu::weak]] int level_paging() { + return bootloader::bootloader->is_5_level_paging() ? 5 : 4; + } + + [[gnu::weak]] void init(int stage) { + switch(stage) { + case ARCH_INIT_EARLY: + x86_64::init_cpu_data(); + drivers::hpet::init(); + drivers::tsc::init(); + return; + case ARCH_INIT_COMMON: + x86_64::gdt::init(); + x86_64::idt::init(); + return; + } + } + + [[gnu::weak]] void panic(char* msg) { + print_ascii_art(); + klibc::printf("Panic with message \"%s\"",msg); + } + +}
\ No newline at end of file diff --git a/kernel/src/bg.bmp b/kernel/src/bg.bmp Binary files differnew file mode 100644 index 0000000..4709edd --- /dev/null +++ b/kernel/src/bg.bmp diff --git a/kernel/src/drivers/acpi.cpp b/kernel/src/drivers/acpi.cpp index 61a4366..e0ab5ee 100644 --- a/kernel/src/drivers/acpi.cpp +++ b/kernel/src/drivers/acpi.cpp @@ -1,570 +1,29 @@ - #include <cstdint> #include <drivers/acpi.hpp> - -#include <etc/bootloaderinfo.hpp> +#include <uacpi/uacpi.h> +#include <uacpi/acpi.h> #include <uacpi/types.h> #include <uacpi/platform/arch_helpers.h> -#include <generic/mm/paging.hpp> -#include <generic/mm/heap.hpp> -#include <generic/mm/pmm.hpp> #include <uacpi/kernel_api.h> #include <uacpi/uacpi.h> - -#include <arch/x86_64/cpu/data.hpp> - -#include <drivers/io.hpp> - -#include <generic/locks/spinlock.hpp> - -#include <arch/x86_64/interrupts/irq.hpp> - -#include <drivers/ioapic.hpp> - -#include <drivers/pci.hpp> -#include <drivers/io.hpp> - -#include <drivers/tsc.hpp> -#include <drivers/hpet.hpp> - -#include <arch/x86_64/cpu/lapic.hpp> - -#include <etc/logging.hpp> - -#include <etc/etc.hpp> - #include <uacpi/utilities.h> #include <uacpi/event.h> +#include <uacpi/uacpi.h> +#include <uacpi/event.h> -#include <generic/time.hpp> - -extern std::uint64_t __hpet_counter(); - -extern int how_much_cpus; - -void drivers::acpi::init() { +void acpi::init_tables() { +#if defined(__x86_64__) uacpi_status ret = uacpi_initialize(0); - - drivers::hpet::init(); - Log::Display(LEVEL_MESSAGE_OK,"HPET initializied\n"); - - drivers::tsc::init(); - Log::Display(LEVEL_MESSAGE_OK,"TSC initializied\n"); - - drivers::ioapic::init(); - Log::Display(LEVEL_MESSAGE_OK,"IOAPIC initializied\n"); - - arch::x86_64::cpu::data()->lapic_block = arch::x86_64::cpu::lapic::init(15000); - - ret = uacpi_namespace_load(); - - ret = uacpi_set_interrupt_model(UACPI_INTERRUPT_MODEL_IOAPIC); - - ret = uacpi_namespace_initialize(); - ret = uacpi_finalize_gpe_initialization(); - -} - -#ifdef __cplusplus -extern "C" { -#endif - -// Returns the PHYSICAL address of the RSDP structure via *out_rsdp_address. -uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *out_rsdp_address) { - *out_rsdp_address = BootloaderInfo::AccessRSDP(); - return UACPI_STATUS_OK; -} - -/* - * Map a physical memory range starting at 'addr' with length 'len', and return - * a virtual address that can be used to access it. - * - * NOTE: 'addr' may be misaligned, in this case the host is expected to round it - * down to the nearest page-aligned boundary and map that, while making - * sure that at least 'len' bytes are still mapped starting at 'addr'. The - * return value preserves the misaligned offset. - * - * Example for uacpi_kernel_map(0x1ABC, 0xF00): - * 1. Round down the 'addr' we got to the nearest page boundary. - * Considering a PAGE_SIZE of 4096 (or 0x1000), 0x1ABC rounded down - * is 0x1000, offset within the page is 0x1ABC - 0x1000 => 0xABC - * 2. Requested 'len' is 0xF00 bytes, but we just rounded the address - * down by 0xABC bytes, so add those on top. 0xF00 + 0xABC => 0x19BC - * 3. Round up the final 'len' to the nearest PAGE_SIZE boundary, in - * this case 0x19BC is 0x2000 bytes (2 pages if PAGE_SIZE is 4096) - * 4. Call the VMM to map the aligned address 0x1000 (from step 1) - * with length 0x2000 (from step 3). Let's assume the returned - * virtual address for the mapping is 0xF000. - * 5. Add the original offset within page 0xABC (from step 1) to the - * resulting virtual address 0xF000 + 0xABC => 0xFABC. Return it - * to uACPI. - */ -void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len) { - extern std::uint64_t kernel_cr3; - memory::paging::maprange(kernel_cr3,addr,(std::uint64_t)Other::toVirt(addr),len,PTE_PRESENT | PTE_RW); - return Other::toVirt(addr); -} - -/* - * Unmap a virtual memory range at 'addr' with a length of 'len' bytes. - * - * NOTE: 'addr' may be misaligned, see the comment above 'uacpi_kernel_map'. - * Similar steps to uacpi_kernel_map can be taken to retrieve the - * virtual address originally returned by the VMM for this mapping - * as well as its true length. - */ -void uacpi_kernel_unmap(void *addr, uacpi_size len) { - asm volatile("nop"); -} - -#ifndef UACPI_FORMATTED_LOGGING -void uacpi_kernel_log(uacpi_log_level lvl, const uacpi_char* msg) { - Log::Display(LEVEL_MESSAGE_INFO,"UACPI: %s",msg); -} -#else -UACPI_PRINTF_DECL(2, 3) -void uacpi_kernel_log(uacpi_log_level, const uacpi_char*, ...); -void uacpi_kernel_vlog(uacpi_log_level, const uacpi_char*, uacpi_va_list); + (void)ret; #endif - -/* - * Only the above ^^^ API may be used by early table access and - * UACPI_BAREBONES_MODE. - */ -#ifndef UACPI_BAREBONES_MODE - -/* - * Convenience initialization/deinitialization hooks that will be called by - * uACPI automatically when appropriate if compiled-in. - */ -#ifdef UACPI_KERNEL_INITIALIZATION -/* - * This API is invoked for each initialization level so that appropriate parts - * of the host kernel and/or glue code can be initialized at different stages. - * - * uACPI API that triggers calls to uacpi_kernel_initialize and the respective - * 'current_init_lvl' passed to the hook at that stage: - * 1. uacpi_initialize() -> UACPI_INIT_LEVEL_EARLY - * 2. uacpi_namespace_load() -> UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED - * 3. (start of) uacpi_namespace_initialize() -> UACPI_INIT_LEVEL_NAMESPACE_LOADED - * 4. (end of) uacpi_namespace_initialize() -> UACPI_INIT_LEVEL_NAMESPACE_INITIALIZED - */ -uacpi_status uacpi_kernel_initialize(uacpi_init_level current_init_lvl); -void uacpi_kernel_deinitialize(void); -#endif - -/* - * Open a PCI device at 'address' for reading & writing. - * - * Note that this must be able to open any arbitrary PCI device, not just those - * detected during kernel PCI enumeration, since the following pattern is - * relatively common in AML firmware: - * Device (THC0) - * { - * // Device at 00:10.06 - * Name (_ADR, 0x00100006) // _ADR: Address - * - * OperationRegion (THCR, PCI_Config, Zero, 0x0100) - * Field (THCR, ByteAcc, NoLock, Preserve) - * { - * // Vendor ID field in the PCI configuration space - * VDID, 32 - * } - * - * // Check if the device at 00:10.06 actually exists, that is reading - * // from its configuration space returns something other than 0xFFs. - * If ((VDID != 0xFFFFFFFF)) - * { - * // Actually create the rest of the device's body if it's present - * // in the system, otherwise skip it. - * } - * } - * - * The handle returned via 'out_handle' is used to perform IO on the - * configuration space of the device. - */ -uacpi_status uacpi_kernel_pci_device_open( - uacpi_pci_address address, uacpi_handle *out_handle -) { - uacpi_pci_address* pci = new uacpi_pci_address; - *pci = address; - *out_handle = (uacpi_handle)pci; - return UACPI_STATUS_OK; -} - -void uacpi_kernel_pci_device_close(uacpi_handle hnd) { - delete (void*)hnd; -} - -/* - * Read & write the configuration space of a previously open PCI device. - */ -uacpi_status uacpi_kernel_pci_read8( - uacpi_handle device, uacpi_size offset, uacpi_u8 *value -) { - uacpi_pci_address* pci = (uacpi_pci_address*)device; - *value = drivers::pci::in(pci->bus,pci->device,pci->function,offset,1); - return UACPI_STATUS_OK; } -uacpi_status uacpi_kernel_pci_read16( - uacpi_handle device, uacpi_size offset, uacpi_u16 *value -) { - uacpi_pci_address* pci = (uacpi_pci_address*)device; - *value = drivers::pci::in(pci->bus,pci->device,pci->function,offset,2); - return UACPI_STATUS_OK; -} - -uacpi_status uacpi_kernel_pci_read32( - uacpi_handle device, uacpi_size offset, uacpi_u32 *value -) { - uacpi_pci_address* pci = (uacpi_pci_address*)device; - *value = drivers::pci::in(pci->bus,pci->device,pci->function,offset,4); - return UACPI_STATUS_OK; -} - -uacpi_status uacpi_kernel_pci_write8( - uacpi_handle device, uacpi_size offset, uacpi_u8 value -) { - uacpi_pci_address* pci = (uacpi_pci_address*)device; - drivers::pci::out(pci->bus,pci->device,pci->function,offset,value,1); - return UACPI_STATUS_OK; -} -uacpi_status uacpi_kernel_pci_write16( - uacpi_handle device, uacpi_size offset, uacpi_u16 value -) { - uacpi_pci_address* pci = (uacpi_pci_address*)device; - drivers::pci::out(pci->bus,pci->device,pci->function,offset,value,2); - return UACPI_STATUS_OK; -} -uacpi_status uacpi_kernel_pci_write32( - uacpi_handle device, uacpi_size offset, uacpi_u32 value -) { - uacpi_pci_address* pci = (uacpi_pci_address*)device; - drivers::pci::out(pci->bus,pci->device,pci->function,offset,value,4); - return UACPI_STATUS_OK; -} - -/* - * Map a SystemIO address at [base, base + len) and return a kernel-implemented - * handle that can be used for reading and writing the IO range. - * - * NOTE: The x86 architecture uses the in/out family of instructions - * to access the SystemIO address space. - */ -typedef struct { - uint64_t base; - uint64_t len; -} __attribute__((packed)) uacpi_io_struct_t; - -uacpi_status uacpi_kernel_io_map( - uacpi_io_addr base, uacpi_size len, uacpi_handle *out_handle -) { - uacpi_io_struct_t* iomap = new uacpi_io_struct_t; - iomap->base = base; - iomap->len = len; - *out_handle = (uacpi_handle*)iomap; - return UACPI_STATUS_OK; -} -void uacpi_kernel_io_unmap(uacpi_handle handle) { - delete (void*)handle; -} - -/* - * Read/Write the IO range mapped via uacpi_kernel_io_map - * at a 0-based 'offset' within the range. - * - * NOTE: - * The x86 architecture uses the in/out family of instructions - * to access the SystemIO address space. - * - * You are NOT allowed to break e.g. a 4-byte access into four 1-byte accesses. - * Hardware ALWAYS expects accesses to be of the exact width. - */ -uacpi_status uacpi_kernel_io_read8( - uacpi_handle hnd, uacpi_size offset, uacpi_u8 *out_value -) { - drivers::io io; - *out_value = io.inb(*(std::uint16_t*)hnd + offset); - return UACPI_STATUS_OK; -} -uacpi_status uacpi_kernel_io_read16( - uacpi_handle hnd, uacpi_size offset, uacpi_u16 *out_value -) { - drivers::io io; - *out_value = io.inw(*(std::uint16_t*)hnd + offset); - return UACPI_STATUS_OK; -} -uacpi_status uacpi_kernel_io_read32( - uacpi_handle hnd, uacpi_size offset, uacpi_u32 *out_value -) { - drivers::io io; - *out_value = io.ind(*(std::uint16_t*)hnd + offset); - return UACPI_STATUS_OK; -} - -uacpi_status uacpi_kernel_io_write8( - uacpi_handle hnd, uacpi_size offset, uacpi_u8 in_value -) { - drivers::io io; - io.outb(*(std::uint16_t*)hnd + offset,in_value); - return UACPI_STATUS_OK; -} -uacpi_status uacpi_kernel_io_write16( - uacpi_handle hnd, uacpi_size offset, uacpi_u16 in_value -) { - drivers::io io; - io.outw(*(std::uint16_t*)hnd + offset,in_value); - return UACPI_STATUS_OK; -} -uacpi_status uacpi_kernel_io_write32( - uacpi_handle hnd, uacpi_size offset, uacpi_u32 in_value -) { - drivers::io io; - io.outd(*(std::uint16_t*)hnd + offset,in_value); - return UACPI_STATUS_OK; -} - -/* - * Allocate a block of memory of 'size' bytes. - * The contents of the allocated memory are unspecified. - */ -void *uacpi_kernel_alloc(uacpi_size size) { - return memory::heap::malloc(size); -} - -#ifdef UACPI_NATIVE_ALLOC_ZEROED -/* - * Allocate a block of memory of 'size' bytes. - * The returned memory block is expected to be zero-filled. - */ -void *uacpi_kernel_alloc_zeroed(uacpi_size size); -#endif - -/* - * Free a previously allocated memory block. - * - * 'mem' might be a NULL pointer. In this case, the call is assumed to be a - * no-op. - * - * An optionally enabled 'size_hint' parameter contains the size of the original - * allocation. Note that in some scenarios this incurs additional cost to - * calculate the object size. - */ -#ifndef UACPI_SIZED_FREES -void uacpi_kernel_free(void *mem) { - memory::heap::free(mem); -} -#else -void uacpi_kernel_free(void *mem, uacpi_size size_hint); -#endif - -/* - * Returns the number of nanosecond ticks elapsed since boot, - * strictly monotonic. - */ -uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void) { - return drivers::tsc::currentnano(); -} - -/* - * Spin for N microseconds. - */ -void uacpi_kernel_stall(uacpi_u8 usec) { - drivers::tsc::sleep(usec); -} - -/* - * Sleep for N milliseconds. - */ -void uacpi_kernel_sleep(uacpi_u64 msec) { - drivers::tsc::sleep(msec * 1000); -} - -/* - * Create/free an opaque non-recursive kernel mutex object. - */ -uacpi_handle uacpi_kernel_create_mutex(void) { - locks::spinlock* lock = new locks::spinlock; - return (uacpi_handle)lock; -} - -void uacpi_kernel_free_mutex(uacpi_handle hnd) { - delete (void*)hnd; -} - -/* - * Create/free an opaque kernel (semaphore-like) event object. - */ -uacpi_handle uacpi_kernel_create_event(void) { - return (uacpi_handle)1; -} - -void uacpi_kernel_free_event(uacpi_handle) { - asm volatile("nop"); -} - -/* - * Returns a unique identifier of the currently executing thread. - * - * The returned thread id cannot be UACPI_THREAD_ID_NONE. - */ -uacpi_thread_id uacpi_kernel_get_thread_id(void) { - return 0; -} - -/* - * Try to acquire the mutex with a millisecond timeout. - * - * The timeout value has the following meanings: - * 0x0000 - Attempt to acquire the mutex once, in a non-blocking manner - * 0x0001...0xFFFE - Attempt to acquire the mutex for at least 'timeout' - * milliseconds - * 0xFFFF - Infinite wait, block until the mutex is acquired - * - * The following are possible return values: - * 1. UACPI_STATUS_OK - successful acquire operation - * 2. UACPI_STATUS_TIMEOUT - timeout reached while attempting to acquire (or the - * single attempt to acquire was not successful for - * calls with timeout=0) - * 3. Any other value - signifies a host internal error and is treated as such - */ -uacpi_status uacpi_kernel_acquire_mutex(uacpi_handle lock, uacpi_u16) { - locks::spinlock* slock = (locks::spinlock*)lock; - slock->lock(); - return UACPI_STATUS_OK; -} - -void uacpi_kernel_release_mutex(uacpi_handle lock) { - locks::spinlock* slock = (locks::spinlock*)lock; - slock->unlock(); -} - -/* - * Try to wait for an event (counter > 0) with a millisecond timeout. - * A timeout value of 0xFFFF implies infinite wait. - * - * The internal counter is decremented by 1 if wait was successful. - * - * A successful wait is indicated by returning UACPI_TRUE. - */ -uacpi_bool uacpi_kernel_wait_for_event(uacpi_handle, uacpi_u16) { - return 1; -} - -/* - * Signal the event object by incrementing its internal counter by 1. - * - * This function may be used in interrupt contexts. - */ -void uacpi_kernel_signal_event(uacpi_handle) { - asm volatile("nop"); -} - -/* - * Reset the event counter to 0. - */ -void uacpi_kernel_reset_event(uacpi_handle) { - asm volatile("nop"); -} - -/* - * Handle a firmware request. - * - * Currently either a Breakpoint or Fatal operators. - */ -uacpi_status uacpi_kernel_handle_firmware_request(uacpi_firmware_request*) { - return UACPI_STATUS_OK; -} - -/* - * Install an interrupt handler at 'irq', 'ctx' is passed to the provided - * handler for every invocation. - * - * 'out_irq_handle' is set to a kernel-implemented value that can be used to - * refer to this handler from other API. - */ - -uacpi_status uacpi_kernel_install_interrupt_handler( - uacpi_u32 irq, uacpi_interrupt_handler base, uacpi_handle ctx, - uacpi_handle *out_irq_handle -) { - std::uint8_t vec = arch::x86_64::interrupts::irq::create(irq,IRQ_TYPE_LEGACY,(void (*)(void*))base,0,0); - *out_irq_handle = (uacpi_handle)vec; - return UACPI_STATUS_OK; -} - -/* - * Uninstall an interrupt handler. 'irq_handle' is the value returned via - * 'out_irq_handle' during installation. - */ -uacpi_status uacpi_kernel_uninstall_interrupt_handler( - uacpi_interrupt_handler, uacpi_handle irq_handle -) { - asm volatile("nop"); - return UACPI_STATUS_OK; -} - -/* - * Create/free a kernel spinlock object. - * - * Unlike other types of locks, spinlocks may be used in interrupt contexts. - */ -uacpi_handle uacpi_kernel_create_spinlock(void) { - locks::spinlock* lock = new locks::spinlock; - return (uacpi_handle)lock; -} - -void uacpi_kernel_free_spinlock(uacpi_handle hnd) { - delete (void*)hnd; -} - -/* - * Lock/unlock helpers for spinlocks. - * - * These are expected to disable interrupts, returning the previous state of cpu - * flags, that can be used to possibly re-enable interrupts if they were enabled - * before. - * - * Note that lock is infalliable. - */ -uacpi_cpu_flags uacpi_kernel_lock_spinlock(uacpi_handle hnd) { - locks::spinlock* lock = (locks::spinlock*)hnd; - lock->lock(); - return UACPI_STATUS_OK; -} - -void uacpi_kernel_unlock_spinlock(uacpi_handle hnd, uacpi_cpu_flags) { - locks::spinlock* lock = (locks::spinlock*)hnd; - lock->unlock(); -} - -/* - * Schedules deferred work for execution. - * Might be invoked from an interrupt context. - */ -uacpi_status uacpi_kernel_schedule_work( - uacpi_work_type, uacpi_work_handler, uacpi_handle ctx -) { - asm volatile("nop"); - return UACPI_STATUS_OK; -} - -/* - * Waits for two types of work to finish: - * 1. All in-flight interrupts installed via uacpi_kernel_install_interrupt_handler - * 2. All work scheduled via uacpi_kernel_schedule_work - * - * Note that the waits must be done in this order specifically. - */ -uacpi_status uacpi_kernel_wait_for_work_completion(void) { - asm volatile("nop"); - return UACPI_STATUS_OK; -} - -#endif // !UACPI_BAREBONES_MODE - -#ifdef __cplusplus -} +void acpi::full_init() { +#if defined(__x86_64__) + uacpi_namespace_load(); + uacpi_namespace_initialize(); + uacpi_finalize_gpe_initialization(); + uacpi_set_interrupt_model(UACPI_INTERRUPT_MODEL_IOAPIC); #endif +}
\ No newline at end of file diff --git a/kernel/src/drivers/acpi.hpp b/kernel/src/drivers/acpi.hpp new file mode 100644 index 0000000..db53e7f --- /dev/null +++ b/kernel/src/drivers/acpi.hpp @@ -0,0 +1,7 @@ +#pragma once +#include <cstdint> + +namespace acpi { + void init_tables(); + void full_init(); +}
\ No newline at end of file diff --git a/kernel/src/drivers/hpet.cpp b/kernel/src/drivers/hpet.cpp deleted file mode 100644 index 20e92b8..0000000 --- a/kernel/src/drivers/hpet.cpp +++ /dev/null @@ -1,52 +0,0 @@ - -#include <cstdint> -#include <drivers/hpet.hpp> - -#include <arch/x86_64/interrupts/pit.hpp> - -std::uint64_t hpet_base,hpet_clock_nano; -std::uint8_t hpet_is_32_bit = 0; - -#include <uacpi/uacpi.h> -#include <uacpi/tables.h> -#include <uacpi/status.h> -#include <uacpi/acpi.h> - -#include <etc/logging.hpp> - -#include <generic/mm/paging.hpp> - -#include <generic/time.hpp> - -#include <etc/etc.hpp> - -std::uint64_t __hpet_timestamp() { - return hpet_is_32_bit ? *(volatile uint32_t*)(hpet_base + 0xf0) : *(volatile uint64_t*)(hpet_base + 0xf0); -} - -std::uint64_t drivers::hpet::nanocurrent() { - return __hpet_timestamp() * hpet_clock_nano; -} - -extern std::uint16_t KERNEL_GOOD_TIMER; - -void drivers::hpet::init() { - uacpi_table hpet; - uacpi_status ret = uacpi_table_find_by_signature("HPET",&hpet); - assert(ret == UACPI_STATUS_OK,"HPET required to get working orange"); - struct acpi_hpet* hpet_table = ((struct acpi_hpet*)hpet.virt_addr); - hpet_base = (std::uint64_t)Other::toVirt(hpet_table->address.address); - memory::paging::kernelmap(0,hpet_table->address.address); - - *(volatile std::uint64_t*)(hpet_base + 0x10) |= 1; - hpet_is_32_bit = (*(volatile uint64_t*)hpet_base & (1 << 13)) ? 0 : 1; - hpet_clock_nano = (*(volatile uint32_t*)(hpet_base + 4)) / 1000000; - -} - -void drivers::hpet::sleep(std::uint64_t us) { - std::uint64_t start = __hpet_timestamp(); - std::uint64_t conv = us * 1000; - while((__hpet_timestamp() - start) * hpet_clock_nano < conv) - asm volatile("nop"); -} diff --git a/kernel/src/drivers/ioapic.cpp b/kernel/src/drivers/ioapic.cpp deleted file mode 100644 index 8f73cf9..0000000 --- a/kernel/src/drivers/ioapic.cpp +++ /dev/null @@ -1,120 +0,0 @@ - -#include <cstdint> -#include <generic/mm/paging.hpp> -#include <drivers/ioapic.hpp> - -#include <arch/x86_64/interrupts/pic.hpp> -#include <etc/logging.hpp> - -#include <uacpi/acpi.h> -#include <uacpi/uacpi.h> -#include <uacpi/status.h> -#include <uacpi/tables.h> - -struct acpi_madt_ioapic apics[24]; -struct acpi_madt_interrupt_source_override iso[24]; -std::uint8_t apic_ent, iso_ent; -extern std::uint8_t is_legacy_pic; - -void drivers::ioapic::init() { - apic_ent = 0; iso_ent = 0; - struct uacpi_table apic_table; - uacpi_status ret = uacpi_table_find_by_signature(ACPI_MADT_SIGNATURE,&apic_table); - if(ret != UACPI_STATUS_OK) - return; // ignore just use pic later - else { - arch::x86_64::interrupts::pic::disable(); - - is_legacy_pic = 0; - } - - struct acpi_madt* apic = (struct acpi_madt*)apic_table.virt_addr; - struct acpi_entry_hdr* current = (struct acpi_entry_hdr*)apic->entries; - while(1) { - - if((std::uint64_t)current >= (std::uint64_t)apic->entries + apic->hdr.length - sizeof(acpi_madt)) - break; - - switch (current->type) - { - case ACPI_MADT_ENTRY_TYPE_IOAPIC: { - struct acpi_madt_ioapic* cur_ioapic = (acpi_madt_ioapic*)current; - memory::paging::kernelmap(0,cur_ioapic->address); - apics[apic_ent++] = *cur_ioapic; - break; - } - case ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE: { - struct acpi_madt_interrupt_source_override* cur_iso = (struct acpi_madt_interrupt_source_override*)current; - iso[iso_ent++] = *cur_iso; - break; - } - } - current = (acpi_entry_hdr*)((std::uint64_t)current + current->length); - - } -} - -void drivers::ioapic::set(std::uint8_t vec,std::uint8_t irq,std::uint64_t flags,std::uint64_t lapic) { - struct acpi_madt_ioapic* apic; - struct acpi_madt_interrupt_source_override* ciso; - std::uint8_t is_found_iso = 0; - for(std::uint8_t i = 0;i < iso_ent;i++) { - ciso = &iso[i]; - if(ciso->source == irq) { - is_found_iso = 1; - break; - } - } - - std::uint64_t calc_flags = (lapic << 56) | flags | (vec & 0xFF); - if(is_found_iso) { - char pol = (ciso->flags & 0b11) == 0b11 ? 1 : 0; - char mode = ((ciso->flags >> 2) & 0b11) == 0b11 ? 1 : 0; - calc_flags = (lapic << 56) | (mode << 15) | (pol << 13) | (vec & 0xff) | flags; - } - - for(std::uint8_t i = 0;i < apic_ent; i++) { - apic = &apics[i]; - std::uint32_t ver = read(apic->address,1); - std::uint32_t max = ver >> 16; - if(apic->gsi_base <= irq && apic->gsi_base + max > irq) - break; - } - - std::uint32_t irqreg = ((irq - apic->gsi_base) * 2) + 0x10; - write(apic->address,irqreg,(std::uint32_t)calc_flags); - write(apic->address,irqreg + 1,(std::uint32_t)((std::uint64_t)calc_flags >> 32)); - -} - -void drivers::ioapic::mask(std::uint8_t irq) { - struct acpi_madt_ioapic* apic; - struct acpi_madt_interrupt_source_override* ciso; - - for(std::uint8_t i = 0;i < apic_ent; i++) { - apic = &apics[i]; - std::uint32_t ver = read(apic->address,1); - std::uint32_t max = ver >> 16; - if(apic->gsi_base <= irq && apic->gsi_base + max > irq) - break; - } - - std::uint32_t irqreg = ((irq - apic->gsi_base) * 2) + 0x10; - write(apic->address,irqreg,(std::uint32_t)read(apic->address,irqreg) | (1 << 16)); -} - -void drivers::ioapic::unmask(std::uint8_t irq) { - struct acpi_madt_ioapic* apic; - struct acpi_madt_interrupt_source_override* ciso; - - for(std::uint8_t i = 0;i < apic_ent; i++) { - apic = &apics[i]; - std::uint32_t ver = read(apic->address,1); - std::uint32_t max = ver >> 16; - if(apic->gsi_base <= irq && apic->gsi_base + max > irq) - break; - } - - std::uint32_t irqreg = ((irq - apic->gsi_base) * 2) + 0x10; - write(apic->address,irqreg,(std::uint32_t)read(apic->address,irqreg) & ~(1 << 16)); -}
\ No newline at end of file diff --git a/kernel/src/drivers/kvmtimer.cpp b/kernel/src/drivers/kvmtimer.cpp deleted file mode 100644 index 302e03d..0000000 --- a/kernel/src/drivers/kvmtimer.cpp +++ /dev/null @@ -1,54 +0,0 @@ - -#include <cstdint> - -#include <drivers/kvmtimer.hpp> -#include <generic/time.hpp> -#include <etc/assembly.hpp> -#include <etc/etc.hpp> - -#include <etc/logging.hpp> - -#include <generic/mm/pmm.hpp> - -struct pvclock_vcpu_time_info* kvmclock_info; - -extern std::uint16_t KERNEL_GOOD_TIMER; - -void drivers::kvmclock::init() { - - std::uint32_t a,b,c,d; - - __cpuid(0x40000000,0,&a,&b,&c,&d); - if(b != 0x4b4d564b || d != 0x4d || c != 0x564b4d56) - return; - - __cpuid(0x40000001,0,&a,&b,&c,&d); - if(!(a & (1 << 3))) - return; - - KERNEL_GOOD_TIMER = KVM_TIMER; - - kvmclock_info = (struct pvclock_vcpu_time_info*)memory::pmm::_virtual::alloc(4096); - - __wrmsr(0x4b564d01,(std::uint64_t)Other::toPhys(kvmclock_info) | 1); - Log::Display(LEVEL_MESSAGE_OK,"KVMClock initializied\n"); - -} - -void drivers::kvmclock::sleep(std::uint64_t us) { - std::uint64_t start = currentnano(); - std::uint64_t conv = us * 1000; - while((currentnano() - start) < conv) - asm volatile("nop"); -} - -std::uint64_t drivers::kvmclock::currentnano() { - std::uint64_t time0 = __rdtsc() - kvmclock_info->tsc_timestamp; - if(kvmclock_info->tsc_shift >= 0) - time0 <<= kvmclock_info->tsc_shift; - else - time0 >>= -kvmclock_info->tsc_shift; - time0 = (time0 * kvmclock_info->tsc_to_system_mul) >> 32; - time0 = time0 + kvmclock_info->system_time; - return time0; -}
\ No newline at end of file diff --git a/kernel/src/drivers/pci.cpp b/kernel/src/drivers/pci.cpp deleted file mode 100644 index 8167b07..0000000 --- a/kernel/src/drivers/pci.cpp +++ /dev/null @@ -1,137 +0,0 @@ - -#include <cstdint> -#include <drivers/io.hpp> - -#include <drivers/pci.hpp> - -char pci_spinlock = 0; - -pci_driver_t pci_drivers[256]; - -std::uint32_t pci_read_config32(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset) { - drivers::io io; - std::uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset); - io.outd(0xCF8, address); - return io.ind(0xCFC); -} - -std::uint16_t pci_read_config16(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset) { - drivers::io io; - std::uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset & 0xfc); - io.outd(0xCF8, address); - return (std::uint16_t)((io.ind(0xCFC) >> ((offset & 2) * 8)) & 0xffff); -} - -std::uint8_t pci_read_config8(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset) { - drivers::io io; - std::uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset); - io.outd(0xCF8, address); - return (std::uint8_t)((io.ind(0xCFC) >> ((offset & 3) * 8)) & 0xff); -} - -void pci_write_config32(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset, std::uint32_t value) { - drivers::io io; - std::uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset); - io.outd(0xCF8, address); - io.outd(0xCFC, value); -} - -void pci_write_config16(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset, std::uint32_t value) { - drivers::io io; - uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset & 0xfc); - io.outd(0xCF8, address); - io.outd(0xCFC,(io.ind(0xCFC) & ~(0xffff << ((offset & 2) * 8))) | (value << ((offset & 2) * 8))); -} - -void pci_write_config8(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset, std::uint8_t value) { - drivers::io io; - std::uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset & 0xfc); - io.outd(0xCF8, address); - io.outd(0xCFC, ((io.ind(0xCFC) & ~(0xFF << (offset & 3))) | (value << ((offset & 3) * 8)))); -} - -std::uint32_t drivers::pci::in(std::int8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset, std::uint8_t bytewidth) { - uint32_t value = 0; - switch(bytewidth) { - case 1: - value = pci_read_config8(bus,num,function,offset); - break; - case 2: - value = pci_read_config16(bus,num,function,offset); - break; - case 4: - value = pci_read_config32(bus,num,function,offset); - break; - default: - break; - } - - return value; - -} - -void drivers::pci::out(std::uint8_t bus, std::uint8_t num, std::uint8_t function, std::uint8_t offset, std::uint32_t value, std::uint8_t bytewidth) { - switch(bytewidth) { - case 1: - pci_write_config8(bus,num,function,offset,(std::uint8_t)value); - break; - case 2: - pci_write_config16(bus,num,function,offset,(std::uint16_t)value); - break; - case 4: - pci_write_config32(bus,num,function,offset,(std::uint32_t)value); - break; - default: - break; - } -} - -pci_t __pci_load(std::uint8_t bus, std::uint8_t num, std::uint8_t function) { - pci_t pciData; - std::uint16_t *p = (std::uint16_t *)&pciData; - for (std::uint8_t i = 0; i < 32; i++) { - p[i] = pci_read_config16(bus, num, function, i * 2); - } - return pciData; -} - -void drivers::pci::reg(void (*pcidrv)(pci_t, std::uint8_t, std::uint8_t, std::uint8_t), std::uint8_t _class, std::uint8_t subclass) { - for (std::uint16_t i = 0; i < 256; i++) { - if (!pci_drivers[i].used) { - pci_drivers[i].used = true; - pci_drivers[i]._class = _class; - pci_drivers[i].subclass = subclass; - pci_drivers[i].pcidrv = pcidrv; - } - } -} - -void __pci_launch(pci_t pci, std::uint8_t bus, std::uint8_t device, std::uint8_t function) { - for (std::uint16_t i = 0; i < 256; i++) { - if (pci_drivers[i].used && pci_drivers[i]._class == pci._class && pci_drivers[i].subclass == pci.subclass) { - pci_drivers[i].pcidrv(pci, bus, device, function); - return; - } - } -} - -void drivers::pci::initworkspace() { - pci_t c_pci; - for (std::uint16_t bus = 0; bus < 256; bus++) { - c_pci = __pci_load(bus, 0, 0); - if (c_pci.vendorID != 0xFFFF) { - for (std::uint8_t device = 0; device < 32; device++) { - c_pci = __pci_load(bus, device, 0); - if (c_pci.vendorID != 0xFFFF) { - __pci_launch(c_pci, bus, device, 0); - for (std::uint8_t function = 1; function < 8; function++) { - pci_t pci = __pci_load(bus, device, function); - if (pci.vendorID != 0xFFFF) { - __pci_launch(pci, bus, device, function); - } - } - } - } - } - } -}
\ No newline at end of file diff --git a/kernel/src/drivers/ps2.cpp b/kernel/src/drivers/ps2.cpp deleted file mode 100644 index a0f5dbf..0000000 --- a/kernel/src/drivers/ps2.cpp +++ /dev/null @@ -1,326 +0,0 @@ -#include <drivers/tsc.hpp> -#include <generic/mm/paging.hpp> -#include <generic/mm/pmm.hpp> -#include <generic/mm/heap.hpp> -#include <generic/vfs/vfs.hpp> -#include <etc/etc.hpp> -#include <etc/logging.hpp> - -#include <drivers/pci.hpp> -#include <generic/vfs/evdev.hpp> - -#include <arch/x86_64/scheduling.hpp> -#include <drivers/ps2.hpp> - -#include <etc/assembly.hpp> -#include <drivers/io.hpp> - -void ps2_wait_write() { - drivers::io io; - while (io.inb(PS2_STATUS) & (1 << 1)); -} - -void ps2_wait_read() { - drivers::io io; - while (!(io.inb(PS2_STATUS) & (1 << 0))); -} - -void ps2_writecmddata(char cmd, char data) { - drivers::io io; - ps2_wait_write(); - io.wait(); - io.outb(PS2_STATUS, cmd); - io.wait(); - io.outb(PS2_DATA, data); -} - -void ps2_writecmd(char cmd) { - drivers::io io; - ps2_wait_write(); - io.outb(PS2_STATUS, cmd); -} - -void ps2_writedata(char cmd) { - drivers::io io; - ps2_wait_write(); - io.outb(PS2_DATA, cmd); -} - -char ps2_not_empty() { - drivers::io io; - return (io.inb(PS2_STATUS) & 1) == 0; -} - -int ps2_is_timeout = 0; - -char ps2_read_data() { - drivers::io io; - int timeout = 0; - while(ps2_not_empty()) { - if(timeout++ == 100) { - ps2_is_timeout = 1; - return 0; - } - drivers::tsc::sleep(100); - } - return io.inb(PS2_DATA); -} - -void ps2_flush() { - drivers::io io; - while(io.inb(PS2_STATUS) & (1 << 0)) { - io.inb(PS2_DATA); - } -} - -#define STATUS 0x64 -#define COMMAND 0x64 -#define DATA 0x60 -#define RESEND 0xFE -#define ACK 0xFA -#define ECHO 0xEE - -void ps2_writeport(uint8_t port, uint8_t cmd) { - if(port == 2) - ps2_writecmd(0xD4); - - ps2_writedata(cmd); -} - -static inline char ps2_wait() { - drivers::io io; - return (io.inb(0x64) & 1) == 0; -} - -uint8_t ps2_readtimeout() { - drivers::io io; - int timeout = 100; - while(ps2_wait() && --timeout > 0) drivers::tsc::sleep(100); - if(timeout <= 0) - return 0; - return io.inb(0x60); -} - -void ps2_enableport(uint8_t port) { - ps2_writeport(port,0xF4); - int retry = 0; - while(1) { - uint8_t response = ps2_readtimeout(); - if(!response) - break; - else if(response == ACK) - break; - else if(response == RESEND) { - if(++retry == 10) - break; - ps2_writeport(port,0xF4); - } - } - ps2_flush(); -} - -#define MOUSE_LB (1 << 0) -#define MOUSE_RB (1 << 1) -#define MOUSE_MB (1 << 2) -#define MOUSE_B4 (1 << 3) -#define MOUSE_B5 (1 << 4) - -/* -input0_fd = open("/dev/masterps2keyboard",O_RDWR); - mouse_fd = open("/dev/mastermouse",O_RDWR); -*/ - -#define REL_X 0x00 -#define REL_Y 0x01 -#define REL_Z 0x02 -#define REL_RX 0x03 -#define REL_RY 0x04 -#define REL_RZ 0x05 -#define REL_HWHEEL 0x06 -#define REL_DIAL 0x07 -#define REL_WHEEL 0x08 -#define REL_MISC 0x09 - -typedef struct { - unsigned char buttons; - unsigned char x; - unsigned char y; - unsigned char z; -} __attribute__((packed)) mouse_packet_t; - -int mouse_evdev = 0; -int kbd_evdev = 0; - -mouse_packet_t last_pack = {0}; - -void ps2_process(void* arg) { - int mouse_seq = 0; - drivers::io io; - if(1) { - - uint8_t mouse_buffer[4] = {0,0,0,0}; - - while(1) { - - if(1) { - - int val = 1; - - uint8_t status = io.inb(0x64); - while(status & 1) { - int data = io.inb(DATA); - - if(status & (1 << 5)) { - mouse_buffer[mouse_seq++] = data; - - if(mouse_seq == 3) { - mouse_packet_t packet = {0,0,0,0}; - - packet.x = mouse_buffer[1] - (mouse_buffer[0] & 0x10 ? 0x100 : 0); - packet.y = mouse_buffer[2] - (mouse_buffer[0] & 0x20 ? 0x100 : 0); - packet.z = (mouse_buffer[3] & 0x7) * (mouse_buffer[3] & 0x8 ? -1 : 1); - - packet.buttons |= (mouse_buffer[0] & 1) ? MOUSE_LB : 0; - packet.buttons |= (mouse_buffer[0] & 2) ? MOUSE_RB : 0; - packet.buttons |= (mouse_buffer[0] & 4) ? MOUSE_MB : 0; - - packet.buttons |= (mouse_buffer[0] & 0x10) ? MOUSE_B4 : 0; - packet.buttons |= (mouse_buffer[0] & 0x20) ? MOUSE_B5 : 0; - - userspace_fd_t fd; - memset(&fd,0,sizeof(userspace_fd_t)); - memcpy(fd.path,"/dev/mastermouse",strlen("/dev/mastermouse")); - fd.is_cached_path = 1; - - asm volatile("cli"); - std::uint64_t current_nano = drivers::tsc::currentnano(); - input_event ev; - ev.time.tv_sec = current_nano / 1000000000; - ev.time.tv_usec = (current_nano & 1000000000) / 1000; - if(packet.x) { - ev.code = REL_X; - ev.type = 2; - ev.value = (packet.x & 0x80) ? (packet.x | 0xFFFFFF00) : packet.x; - vfs::evdev::submit(mouse_evdev,ev); - } - - if(packet.y) { - ev.code = REL_Y; - ev.type = 2; - ev.value = (packet.y & 0x80) ? (packet.y | 0xFFFFFF00) : packet.y; - vfs::evdev::submit(mouse_evdev,ev); - } - - if(packet.z) { - ev.code = REL_Z; - ev.type = 2; - ev.value = (packet.z & 0x80) ? (packet.z | 0xFFFFFF00) : packet.z; - vfs::evdev::submit(mouse_evdev,ev); - } - - if((packet.buttons & MOUSE_LB) && !(last_pack.buttons & MOUSE_LB)) { - ev.code = 272; - ev.type = 1; - ev.value = 1; - vfs::evdev::submit(mouse_evdev,ev); - } else if(!(packet.buttons & MOUSE_LB) && (last_pack.buttons & MOUSE_LB)) { - ev.code = 272; - ev.type = 1; - ev.value = 0; - vfs::evdev::submit(mouse_evdev,ev); - } - - if((packet.buttons & MOUSE_RB) && !(last_pack.buttons & MOUSE_RB)) { - ev.code = 273; - ev.type = 1; - ev.value = 1; - vfs::evdev::submit(mouse_evdev,ev); - } else if(!(packet.buttons & MOUSE_RB) && (last_pack.buttons & MOUSE_RB)) { - ev.code = 273; - ev.type = 1; - ev.value = 0; - vfs::evdev::submit(mouse_evdev,ev); - } - - if((packet.buttons & MOUSE_MB) && !(last_pack.buttons & MOUSE_MB)) { - ev.code = 274; - ev.type = 1; - ev.value = 1; - vfs::evdev::submit(mouse_evdev,ev); - } else if(!(packet.buttons & MOUSE_MB) && (last_pack.buttons & MOUSE_MB)) { - ev.code = 274; - ev.type = 1; - ev.value = 0; - vfs::evdev::submit(mouse_evdev,ev); - } - - asm volatile("sti"); - - last_pack = packet; - - mouse_seq = 0; - - } - - } else { - userspace_fd_t fd; - memset(&fd,0,sizeof(userspace_fd_t)); - memcpy(fd.path,"/dev/masterps2keyboard",strlen("/dev/masterps2keyboard")); - fd.is_cached_path = 1; - - std::uint64_t current_nano = drivers::tsc::currentnano(); - - asm volatile("cli"); - input_event ev; - ev.time.tv_sec = current_nano / 1000000000; - ev.time.tv_usec = (current_nano & 1000000000) / 1000; - ev.type = 1; - ev.code = data & ~(1 << 7); - ev.value = (data & (1 << 7)) ? 0 : 1; - vfs::evdev::submit(kbd_evdev,ev); - vfs::vfs::write(&fd,&data,1); - asm volatile("sti"); - } - - status = io.inb(0x64); - } - asm volatile("cli"); - yield(); - asm volatile("sti"); - } - } - } -} - -void drivers::ps2::init() { - ps2_flush(); - ps2_writecmd(CMD_READ_CONFIG); - std::uint8_t ctrl = (std::uint8_t)ps2_read_data(); - if(ps2_is_timeout) { - Log::Display(LEVEL_MESSAGE_FAIL,"ps2: there's no ps2 controller !\n"); - return; - } - - ps2_writecmd(0xAD); - ps2_writecmd(0xA7); - - ps2_writecmd(0x20); - uint8_t config = ps2_read_data(); - config |= (1 << 0) | (1 << 1) | (1 << 6); - ps2_writecmd(0x60); - ps2_writedata(config); - - ps2_enableport(1); - ps2_enableport(2); - - ps2_writecmd(0xAE); - ps2_writecmd(0xA8); - - ps2_flush(); - - mouse_evdev = vfs::evdev::create("Generic PS/2 Mouse",EVDEV_TYPE_MOUSE); - kbd_evdev = vfs::evdev::create("Generic PS/2 Keyboard",EVDEV_TYPE_KEYBOARD); - - arch::x86_64::scheduling::create_kernel_thread(ps2_process,0); - Log::Display(LEVEL_MESSAGE_INFO,"PS/2 Initializied\n"); -}
\ No newline at end of file diff --git a/kernel/src/drivers/serial.cpp b/kernel/src/drivers/serial.cpp deleted file mode 100644 index 626aa0d..0000000 --- a/kernel/src/drivers/serial.cpp +++ /dev/null @@ -1,46 +0,0 @@ - -#include <cstdint> -#include <cstddef> - -#include <drivers/serial.hpp> -#include <drivers/io.hpp> - -#include <etc/libc.hpp> - -serial_mapping_t __serial_map[32]; -int __serial_map_ptr = 0; - -void drivers::serial::init(uint16_t port) { - - if(__serial_map_ptr == 0) - memset(__serial_map,0,sizeof(serial_mapping_t)); - - drivers::io io; - io.outb(DEFAULT_SERIAL_PORT + 1, 0x00); - io.outb(DEFAULT_SERIAL_PORT + 3, 0x80); - io.outb(DEFAULT_SERIAL_PORT + 0, 0x03); - io.outb(DEFAULT_SERIAL_PORT + 1, 0x00); - io.outb(DEFAULT_SERIAL_PORT + 3, 0x03); - io.outb(DEFAULT_SERIAL_PORT + 2, 0xC7); - io.outb(DEFAULT_SERIAL_PORT + 4, 0x0B); - io.outb(DEFAULT_SERIAL_PORT + 4, 0x1E); - io.outb(DEFAULT_SERIAL_PORT + 0, 0xAE); - - if(io.inb(DEFAULT_SERIAL_PORT + 0) != 0xAE) { - __serial_map[__serial_map_ptr].port = port; - __serial_map[__serial_map_ptr++].is_init = 0; - } - - io.outb(DEFAULT_SERIAL_PORT + 4, 0x0F); - __serial_map[__serial_map_ptr].port = port; - __serial_map[__serial_map_ptr++].is_init = 1; -} - -std::uint8_t drivers::serial::is_init(uint16_t port) { - - for(int i = 0;i < __serial_map_ptr;i++) { - if(__serial_map[i].port == port && __serial_map[i].is_init == 1) - return 1; - } - return 0; -}
\ No newline at end of file diff --git a/kernel/src/drivers/tsc.cpp b/kernel/src/drivers/tsc.cpp deleted file mode 100644 index 0490ccd..0000000 --- a/kernel/src/drivers/tsc.cpp +++ /dev/null @@ -1,46 +0,0 @@ - -#include <drivers/tsc.hpp> -#include <drivers/hpet.hpp> -#include <cstdint> - -#include <generic/time.hpp> - -#include <arch/x86_64/cpu/data.hpp> - -#include <etc/logging.hpp> - -#include <etc/assembly.hpp> - -using namespace drivers; - -std::uint64_t freq; - -void tsc::init() { - std::uint64_t start = __rdtsc(); - time::sleep(100); - std::uint64_t end = __rdtsc(); - std::uint64_t d = end - start; - arch::x86_64::cpu::data()->tsc.freq = (d * 1000000ULL) / (100 * 1000ULL); -} - - -void tsc::sleep(std::uint64_t us) { - - if(arch::x86_64::cpu::data()->tsc.freq == 0) { - drivers::hpet::sleep(us); - return; - } - - std::uint64_t current = currentnano(); - std::uint64_t end = us * 1000; - while((currentnano() - current) < end); - __nop(); -} - -std::uint64_t tsc::currentnano() { - return (__rdtsc() * 1000000ULL) / arch::x86_64::cpu::data()->tsc.freq; -} - -std::uint64_t tsc::currentus() { - return currentnano() / 1000; -}
\ No newline at end of file diff --git a/kernel/src/drivers/uacpi_kernel_api.cpp b/kernel/src/drivers/uacpi_kernel_api.cpp new file mode 100644 index 0000000..532fe63 --- /dev/null +++ b/kernel/src/drivers/uacpi_kernel_api.cpp @@ -0,0 +1,397 @@ + +#include <uacpi/types.h> +#include <uacpi/kernel_api.h> +#include <uacpi/platform/arch_helpers.h> +#if defined(__x86_64__) +#include <arch/x86_64/drivers/io.hpp> +#include <arch/x86_64/drivers/pci.hpp> +#endif +#include <generic/bootloader/bootloader.hpp> +#include <generic/hhdm.hpp> +#include <generic/paging.hpp> +#include <utils/gobject.hpp> +#include <klibc/stdio.hpp> +#include <generic/heap.hpp> +#include <generic/lock/spinlock.hpp> +#include <generic/time.hpp> + +uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *out_rsdp_address) { + + if(bootloader::bootloader->get_rsdp() == nullptr) + return UACPI_STATUS_NOT_FOUND; + + *out_rsdp_address = ((std::uint64_t)bootloader::bootloader->get_rsdp() - etc::hhdm()); + return UACPI_STATUS_OK; +} + +void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len) { + paging::map_range(gobject::kernel_root,addr,addr + etc::hhdm(),ALIGNUP(len, PAGE_SIZE),PAGING_PRESENT | PAGING_RW); + return (void*)(addr + etc::hhdm()); +} + +void uacpi_kernel_unmap(void *addr, uacpi_size len) { + (void)addr; + (void)len; +} + +void uacpi_kernel_log(uacpi_log_level, const uacpi_char* msg) { + klibc::printf("uACPI: %s\r", msg); +} + +uacpi_status uacpi_kernel_pci_device_open( + uacpi_pci_address address, uacpi_handle *out_handle +) { + uacpi_pci_address* pci = (uacpi_pci_address*)kheap::opt_malloc(sizeof(uacpi_pci_address)); + *pci = address; + *out_handle = (uacpi_handle)pci; + return UACPI_STATUS_OK; +} + +void uacpi_kernel_pci_device_close(uacpi_handle hnd) { + kheap::opt_free((void*)hnd); +} + +typedef struct { + uint64_t base; + uint64_t len; +} __attribute__((packed)) uacpi_io_struct_t; + +uacpi_status uacpi_kernel_io_map( + uacpi_io_addr base, uacpi_size len, uacpi_handle *out_handle +) { + uacpi_io_struct_t* iomap = (uacpi_io_struct_t*)kheap::opt_malloc(sizeof(uacpi_io_struct_t)); + iomap->base = base; + iomap->len = len; + *out_handle = (uacpi_handle*)iomap; + return UACPI_STATUS_OK; +} + +void uacpi_kernel_io_unmap(uacpi_handle handle) { + kheap::opt_free((void*)handle); +} + +#if defined(__x86_64__) + +uacpi_status uacpi_kernel_pci_read8( + uacpi_handle device, uacpi_size offset, uacpi_u8 *value +) { + uacpi_pci_address* pci = (uacpi_pci_address*)device; + *value = x86_64::pci::pci_read_config8(pci->bus,pci->device,pci->function,offset); + return UACPI_STATUS_OK; +} +uacpi_status uacpi_kernel_pci_read16( + uacpi_handle device, uacpi_size offset, uacpi_u16 *value +) { + uacpi_pci_address* pci = (uacpi_pci_address*)device; + *value = x86_64::pci::pci_read_config16(pci->bus,pci->device,pci->function,offset); + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_pci_read32( + uacpi_handle device, uacpi_size offset, uacpi_u32 *value +) { + uacpi_pci_address* pci = (uacpi_pci_address*)device; + *value = x86_64::pci::pci_read_config32(pci->bus,pci->device,pci->function,offset); + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_pci_write8( + uacpi_handle device, uacpi_size offset, uacpi_u8 value +) { + uacpi_pci_address* pci = (uacpi_pci_address*)device; + x86_64::pci::pci_write_config8(pci->bus,pci->device,pci->function,offset,value); + return UACPI_STATUS_OK; +} +uacpi_status uacpi_kernel_pci_write16( + uacpi_handle device, uacpi_size offset, uacpi_u16 value +) { + uacpi_pci_address* pci = (uacpi_pci_address*)device; + x86_64::pci::pci_write_config16(pci->bus,pci->device,pci->function,offset,value); + return UACPI_STATUS_OK; +} +uacpi_status uacpi_kernel_pci_write32( + uacpi_handle device, uacpi_size offset, uacpi_u32 value +) { + uacpi_pci_address* pci = (uacpi_pci_address*)device; + x86_64::pci::pci_write_config32(pci->bus,pci->device,pci->function,offset,value); + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_io_read8( + uacpi_handle hnd, uacpi_size offset, uacpi_u8 *out_value +) { + *out_value = x86_64::io::inb(*(std::uint16_t*)hnd + offset); + return UACPI_STATUS_OK; +} +uacpi_status uacpi_kernel_io_read16( + uacpi_handle hnd, uacpi_size offset, uacpi_u16 *out_value +) { + *out_value = x86_64::io::inw(*(std::uint16_t*)hnd + offset); + return UACPI_STATUS_OK; +} +uacpi_status uacpi_kernel_io_read32( + uacpi_handle hnd, uacpi_size offset, uacpi_u32 *out_value +) { + *out_value = x86_64::io::ind(*(std::uint16_t*)hnd + offset); + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_io_write8( + uacpi_handle hnd, uacpi_size offset, uacpi_u8 in_value +) { + x86_64::io::outb(*(std::uint16_t*)hnd + offset,in_value); + return UACPI_STATUS_OK; +} +uacpi_status uacpi_kernel_io_write16( + uacpi_handle hnd, uacpi_size offset, uacpi_u16 in_value +) { + x86_64::io::outw(*(std::uint16_t*)hnd + offset,in_value); + return UACPI_STATUS_OK; +} +uacpi_status uacpi_kernel_io_write32( + uacpi_handle hnd, uacpi_size offset, uacpi_u32 in_value +) { + x86_64::io::outd(*(std::uint16_t*)hnd + offset,in_value); + return UACPI_STATUS_OK; +} + +#else + +uacpi_status uacpi_kernel_pci_read8( + uacpi_handle device, uacpi_size offset, uacpi_u8 *value +) { + (void)device; + (void)offset; + (void)value; + return UACPI_STATUS_UNIMPLEMENTED; +} +uacpi_status uacpi_kernel_pci_read16( + uacpi_handle device, uacpi_size offset, uacpi_u16 *value +) { + (void)device; + (void)offset; + (void)value; + return UACPI_STATUS_UNIMPLEMENTED; +} + +uacpi_status uacpi_kernel_pci_read32( + uacpi_handle device, uacpi_size offset, uacpi_u32 *value +) { + (void)device; + (void)offset; + (void)value; + return UACPI_STATUS_UNIMPLEMENTED; +} + +uacpi_status uacpi_kernel_pci_write8( + uacpi_handle device, uacpi_size offset, uacpi_u8 value +) { + (void)device; + (void)offset; + (void)value; + return UACPI_STATUS_UNIMPLEMENTED; +} +uacpi_status uacpi_kernel_pci_write16( + uacpi_handle device, uacpi_size offset, uacpi_u16 value +) { + (void)device; + (void)offset; + (void)value; + return UACPI_STATUS_UNIMPLEMENTED; +} +uacpi_status uacpi_kernel_pci_write32( + uacpi_handle device, uacpi_size offset, uacpi_u32 value +) { + (void)device; + (void)offset; + (void)value; + return UACPI_STATUS_UNIMPLEMENTED; +} + +uacpi_status uacpi_kernel_io_read8( + uacpi_handle hnd, uacpi_size offset, uacpi_u8 *out_value +) { + (void)hnd; + (void)offset; + (void)out_value; + return UACPI_STATUS_UNIMPLEMENTED; +} +uacpi_status uacpi_kernel_io_read16( + uacpi_handle hnd, uacpi_size offset, uacpi_u16 *out_value +) { + (void)hnd; + (void)offset; + (void)out_value; + return UACPI_STATUS_UNIMPLEMENTED; +} +uacpi_status uacpi_kernel_io_read32( + uacpi_handle hnd, uacpi_size offset, uacpi_u32 *out_value +) { + (void)hnd; + (void)offset; + (void)out_value; + return UACPI_STATUS_UNIMPLEMENTED; +} + +uacpi_status uacpi_kernel_io_write8( + uacpi_handle hnd, uacpi_size offset, uacpi_u8 in_value +) { + (void)hnd; + (void)offset; + (void)in_value; + return UACPI_STATUS_UNIMPLEMENTED; +} +uacpi_status uacpi_kernel_io_write16( + uacpi_handle hnd, uacpi_size offset, uacpi_u16 in_value +) { + (void)hnd; + (void)offset; + (void)in_value; + return UACPI_STATUS_UNIMPLEMENTED; +} +uacpi_status uacpi_kernel_io_write32( + uacpi_handle hnd, uacpi_size offset, uacpi_u32 in_value +) { + (void)hnd; + (void)offset; + (void)in_value; + return UACPI_STATUS_UNIMPLEMENTED; +} + + +#endif + +void *uacpi_kernel_alloc(uacpi_size size) { + return kheap::opt_malloc(size); +} + +void uacpi_kernel_free(void *mem) { + kheap::opt_free(mem); +} + +/* + * Returns the number of nanosecond ticks elapsed since boot, + * strictly monotonic. + */ +uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void) { + if(!time::timer) { + klibc::printf("uACPI: generic timer is missing !\r\n"); + return 0; + } + + return time::timer->current_nano(); +} + +/* + * Spin for N microseconds. + */ +void uacpi_kernel_stall(uacpi_u8 usec) { + if(!time::timer) { + klibc::printf("uACPI: generic timer is missing !\r\n"); + return; + } + + time::timer->sleep(usec); +} + +void uacpi_kernel_sleep(uacpi_u64 msec) { + if(!time::timer) { + klibc::printf("uACPI: generic timer is missing !\r\n"); + return; + } + + time::timer->sleep(msec * 1000); +} + +uacpi_handle uacpi_kernel_create_mutex(void) { + locks::spinlock* lock = (locks::spinlock*)kheap::opt_malloc(sizeof(locks::spinlock)); + return (uacpi_handle)lock; +} + +void uacpi_kernel_free_mutex(uacpi_handle hnd) { + kheap::opt_free((void*)hnd); +} + +uacpi_handle uacpi_kernel_create_event(void) { + return (uacpi_handle)1; +} + +void uacpi_kernel_free_event(uacpi_handle) { + asm volatile("nop"); +} + +uacpi_thread_id uacpi_kernel_get_thread_id(void) { + return 0; +} + +uacpi_status uacpi_kernel_acquire_mutex(uacpi_handle lock, uacpi_u16) { + (void)lock; + return UACPI_STATUS_OK; +} + +void uacpi_kernel_release_mutex(uacpi_handle lock) { + (void)lock; +} + +uacpi_bool uacpi_kernel_wait_for_event(uacpi_handle, uacpi_u16) { + return 1; +} + +void uacpi_kernel_signal_event(uacpi_handle) { + asm volatile("nop"); +} + +void uacpi_kernel_reset_event(uacpi_handle) { + asm volatile("nop"); +} + +uacpi_status uacpi_kernel_handle_firmware_request(uacpi_firmware_request*) { + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_install_interrupt_handler( + uacpi_u32 irq, uacpi_interrupt_handler base, uacpi_handle ctx, + uacpi_handle *out_irq_handle +) { + (void)irq; + (void)base; + (void)ctx; + (void)out_irq_handle; + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_uninstall_interrupt_handler( + uacpi_interrupt_handler, uacpi_handle irq_handle +) { + (void)irq_handle; + return UACPI_STATUS_OK; +} + +uacpi_handle uacpi_kernel_create_spinlock(void) { + locks::spinlock* lock = (locks::spinlock*)kheap::opt_malloc(sizeof(locks::spinlock)); + return (uacpi_handle)lock; +} + +void uacpi_kernel_free_spinlock(uacpi_handle hnd) { + kheap::opt_free((void*)hnd); +} + +uacpi_cpu_flags uacpi_kernel_lock_spinlock(uacpi_handle hnd) { + (void)hnd; + return UACPI_STATUS_OK; +} + +void uacpi_kernel_unlock_spinlock(uacpi_handle hnd, uacpi_cpu_flags) { + (void)hnd; +} + +uacpi_status uacpi_kernel_schedule_work( + uacpi_work_type, uacpi_work_handler, uacpi_handle ctx +) { + (void)ctx; + return UACPI_STATUS_UNIMPLEMENTED; +} + +uacpi_status uacpi_kernel_wait_for_work_completion(void) { + return UACPI_STATUS_OK; +} diff --git a/kernel/src/drivers/xhci.cpp b/kernel/src/drivers/xhci.cpp deleted file mode 100644 index 816a049..0000000 --- a/kernel/src/drivers/xhci.cpp +++ /dev/null @@ -1,1602 +0,0 @@ - -#include <drivers/xhci.hpp> -#include <etc/libc.hpp> -#include <drivers/tsc.hpp> -#include <generic/mm/paging.hpp> -#include <generic/mm/pmm.hpp> -#include <generic/mm/heap.hpp> -#include <generic/vfs/vfs.hpp> -#include <etc/etc.hpp> -#include <etc/logging.hpp> - -#include <drivers/pci.hpp> -#include <generic/vfs/evdev.hpp> - -#include <arch/x86_64/scheduling.hpp> - -xhci_device_t* xhci_list; - -void __xhci_put_new_device(xhci_device_t* dev) { - if(!dev) { - return; - } - - if(!xhci_list) { - xhci_list = dev; - } else { - dev->next = xhci_list; - xhci_list = dev; - } - -} - -void __xhci_doorbell(xhci_device_t* dev,uint32_t value) { - *dev->doorbell = value; -} - -void __xhci_doorbell_id(xhci_device_t* dev,uint32_t idx,uint32_t val) { - dev->doorbell[idx] = val; -} - -void __xhci_reset(xhci_device_t* dev) { - - drivers::tsc::sleep(50*1000); // wait some time - - dev->op->usbcmd |= (1 << 1); - uint16_t timeout = XHCI_RESET_TIMEOUT; - while(dev->op->usbsts & (1 << 11)) { - if(!timeout) { - Log::Display(LEVEL_MESSAGE_FAIL,"Can't reset XHCI Controller, ignoring\n"); - break; - } - drivers::tsc::sleep(5 * 1000); - timeout = timeout - 1; - } - - drivers::tsc::sleep(5000); - -} - -void __xhci_enable(xhci_device_t* dev) { - drivers::tsc::sleep(50*1000); - dev->op->usbcmd |= (1 << 0) | (1 << 2); - uint16_t timeout = XHCI_RESET_TIMEOUT; - while(dev->op->usbsts & (1 << 0)) { - if(!timeout) { - Log::Display(LEVEL_MESSAGE_FAIL,"Can't start XHCI Controller, crying\n"); - break; - } - drivers::tsc::sleep(5 * 1000); - timeout = timeout - 1; - } - - drivers::tsc::sleep(5000); - -} - -void __xhci_reset_intr(xhci_device_t* dev, uint16_t intr) { - - if(intr > dev->cap->hcsparams1.maxintrs) { - Log::Display(LEVEL_MESSAGE_FAIL,"Intr is higher than maxintrs! Skipping"); - return; - } - - dev->op->usbsts = (1 << 3); - dev->runtime->int_regs[intr].iman |= (1 << 0); -} - -void __xhci_punch_intr(xhci_device_t* dev,uint16_t intr) { - dev->runtime->int_regs[intr].erdp.event_busy = 1; -} - -void __xhci_update_stepfather(xhci_device_t* dev,xhci_event_ring_ctx_t* grandpa) { - grandpa->father->erdp_val = grandpa->table[0].base + (grandpa->queue * sizeof(xhci_trb_t)); -} - -xhci_trb_t* __xhci_move_father(xhci_device_t* dev,xhci_event_ring_ctx_t* ctx) { - xhci_trb_t* trb = &ctx->trb[ctx->queue++]; - if(ctx->queue == ctx->trb_limit) { - ctx->cycle = !ctx->cycle; - ctx->queue = 0; - } - return trb; -} - -xhci_event_ring_ctx_t* __xhci_create_event_ring(xhci_device_t* dev,uint16_t trb_size,volatile IR_t* stepfather,uint16_t sons) { - xhci_event_ring_ctx_t* ring_info = new xhci_event_ring_ctx_t; - ring_info->cycle = 1; - ring_info->queue = 0; - ring_info->father = stepfather; // :pensive: - ring_info->trb_limit = trb_size; - ring_info->trb = 0; - - uint64_t new_table = memory::pmm::_physical::alloc(ALIGNPAGEUP(sons * sizeof(xhci_erst_t))); - void* virt_table = Other::toVirt(new_table); - - ring_info->table = (xhci_erst_t*)virt_table; - - uint64_t phys_trb = memory::pmm::_physical::alloc(16 * PAGE_SIZE); - ring_info->table[0].base = phys_trb; - ring_info->table[0].size = trb_size; - - ring_info->trb = (xhci_trb_t*)Other::toVirt(phys_trb); - - stepfather->erstsz = sons; - __xhci_update_stepfather(dev,ring_info); - stepfather->erstba = new_table; - - return ring_info; - -} - -xhci_trb_t get_trb(xhci_event_ring_ctx_t* father,uint16_t idx) { - return father->trb[idx]; -} - -int __xhci_event_receive(xhci_device_t* dev,xhci_event_ring_ctx_t* father,xhci_trb_t** out) { // it will return trb virtual addresses - int len = 0; - while(get_trb(father,father->queue).info_s.cycle == father->cycle) - out[len++] = __xhci_move_father(dev,father); - __xhci_punch_intr(dev,0); - __xhci_update_stepfather(dev,father); - return len; -} - -xhci_command_ring_ctx_t* __xhci_create_command_ring(xhci_device_t* dev,uint16_t trb_size) { - xhci_command_ring_ctx_t* ring_info = new xhci_command_ring_ctx_t; - ring_info->cycle = 1; - ring_info->queue = 0; - ring_info->trb_limit = trb_size; - - uint64_t phys_trb = memory::pmm::_physical::alloc(ALIGNPAGEUP(trb_size * sizeof(xhci_trb_t))); - - ring_info->phys = phys_trb; - - ring_info->trb = (xhci_trb_t*)Other::toVirt(phys_trb); - ring_info->trb[trb_size - 1].base = phys_trb; - ring_info->trb[trb_size - 1].info = (6 << 10) | (1 << 1) | (1 << 0); - return ring_info; -} - - -void __xhci_command_ring_queue(xhci_device_t* dev,xhci_command_ring_ctx_t* ctx,xhci_trb_t* trb) { - trb->info |= ctx->cycle; - memcpy(&ctx->trb[ctx->queue],trb,sizeof(xhci_trb_t)); - if(++ctx->queue == ctx->trb_limit - 1) { - ctx->queue = 0; - ctx->trb[ctx->trb_limit - 1].info = (6 << 10) | (1 << 1) | (ctx->cycle << 0); - ctx->cycle = !ctx->cycle; - } -} - -void __xhci_setup_run(xhci_device_t* dev) { - volatile IR_t* head = (volatile IR_t*)&dev->runtime->int_regs[0]; - head->iman |= (1 << 1); - - dev->event_ring = __xhci_create_event_ring(dev,256,head,1); - - __xhci_reset_intr(dev,0); -} - -void __xhci_fill_dcbaa(xhci_device_t* dev) { - - uint64_t phys_dcbaa = memory::pmm::_physical::alloc(ALIGNPAGEUP(8*dev->cap->hcsparams1.maxslots)); - - uint64_t* dcbaa = (uint64_t*)Other::toVirt(phys_dcbaa); - - if(dev->calculated_scratchpad_count) { - - uint64_t phys_list = memory::pmm::_physical::alloc(ALIGNPAGEUP(8*dev->calculated_scratchpad_count)); - - uint64_t* list = (uint64_t*)Other::toVirt(phys_list); - for(uint16_t i = 0;i < dev->calculated_scratchpad_count;i++) { - uint64_t hi = memory::pmm::_physical::alloc(4096); - list[i] = hi; - } - dcbaa[0] = phys_list; - } - - dev->dcbaa = (uint64_t*)dcbaa; - dev->op->dcbaap = phys_dcbaa; - drivers::tsc::sleep(5000); -} - -void __xhci_setup_op(xhci_device_t* dev) { - __xhci_fill_dcbaa(dev); - dev->com_ring = __xhci_create_command_ring(dev,128); // i dont think what command ring will be fat - dev->op->crcr = dev->com_ring->phys | dev->com_ring->cycle; - dev->op->config = dev->cap->hcsparams1.maxslots; - dev->op->dnctrl = 0xFFFF; -} - -volatile uint32_t* __xhci_portsc(xhci_device_t* dev,uint32_t portnum) { - return ((volatile uint32_t*)(dev->xhci_virt_base + 0x400 + dev->cap->caplength + (0x10 * portnum))); -} - -void* __xhci_helper_map(uint64_t start,uint64_t pagelen) { - return memory::paging::maprangeret(start,pagelen,PTE_MMIO); -} - -const char* trb_type_to_str(int type) { - switch(type) { - case TRB_COMMANDCOMPLETIONEVENT_TYPE: - return "TRB_COMMAND_COMPLETION_EVENT"; - case TRB_TRANSFEREVENT_TYPE: - return "TRB_TRANSFER_EVENT"; - default: - return "Unknown"; - } -} - -xhci_trb_t __xhci_event_wait(xhci_device_t* dev,int type) { - xhci_event_ring_ctx_t* father = dev->event_ring; - xhci_trb_t* buffer[1024]; - int timeout = 100; - while(1) { - int count = 0; - memset(buffer,0,sizeof(xhci_trb_t*) * 1024); - if(get_trb(father,father->queue).info_s.cycle == father->cycle) - count = __xhci_event_receive(dev,father,buffer); - - if(count) { - xhci_trb_t* current = 0; - for(int i = 0;i < count;i++) { - current = buffer[i]; - if(current->info_s.type == type) { - return *current; - } else { - Log::Display(LEVEL_MESSAGE_WARN,"Wait for wrong type %d\n",current->info_s.type); - } - } - } - - if(--timeout == 0) { - xhci_trb_t t; - t.base = 0xDEAD; - t.ret_code = 0; - return t; - } - - drivers::tsc::sleep(5000); - - } -} - -void __xhci_clear_event(xhci_device_t* dev) { - int count = 0; - xhci_trb_t* buffer[1024]; - if(get_trb(dev->event_ring,dev->event_ring->queue).info_s.cycle == dev->event_ring->cycle) - count = __xhci_event_receive(dev,dev->event_ring,buffer); -} - -xhci_port_ring_ctx_t* __xhci_setup_port_ring(uint16_t trb_count,uint16_t slot) { - xhci_port_ring_ctx_t* ring_info = new xhci_port_ring_ctx_t; - ring_info->cycle = 1; - ring_info->queue = 0; - ring_info->slot = slot; - ring_info->trb_limit = trb_count; - - uint64_t phys_trb = memory::pmm::_physical::alloc(16 * 4096); - ring_info->trb = (xhci_trb_t*)Other::toVirt(phys_trb); - - ring_info->phys = phys_trb; - ring_info->trb[trb_count - 1].base = phys_trb; - ring_info->trb[trb_count - 1].info = (6 << 10) | (1 << 1) | (1 << 0); - return ring_info; -} - -// its same as command ring -void __xhci_port_ring_queue(xhci_port_ring_ctx_t* ctx,xhci_trb_t* trb) { - trb->info |= ctx->cycle; - memcpy(&ctx->trb[ctx->queue],trb,sizeof(xhci_trb_t)); - if(++ctx->queue == ctx->trb_limit - 1) { - ctx->queue = 0; - ctx->trb[ctx->trb_limit - 1].info = (6 << 10) | (1 << 1) | (ctx->cycle << 0); - ctx->cycle = !ctx->cycle; - } -} - -void __xhci_create_dcbaa(xhci_device_t* dev,uint32_t slotid,uint64_t addr) { - dev->dcbaa[slotid] = addr; -} - -xhci_usb_device_t* usbdevs = 0; - -xhci_usb_device_t* __xhci_alloc_dev(uint32_t portnum,uint32_t slotid) { - xhci_usb_device_t* dev = new xhci_usb_device_t; - dev->next = 0; - dev->portnum = portnum; - dev->slotid = slotid; - dev->transfer_ring = __xhci_setup_port_ring(256,slotid); - dev->phys_input_ctx = memory::pmm::_physical::alloc(4096); - if(!usbdevs) { - usbdevs = dev; - } else { - dev->next = usbdevs; - usbdevs = dev; - } - return dev; -} - -int __xhci_enable_slot(xhci_device_t* dev, int portnum) { - xhci_trb_t trb; - - memset(&trb,0,sizeof(xhci_trb_t)); - - trb.info_s.intoncompletion = 1; - trb.info_s.type = TRB_ENABLESLOTCOMMAND_TYPE; - - __xhci_clear_event(dev); - - __xhci_command_ring_queue(dev,dev->com_ring,&trb); - __xhci_doorbell(dev,0); - drivers::tsc::sleep(25000); - - xhci_trb_t ret = __xhci_event_wait(dev,TRB_COMMANDCOMPLETIONEVENT_TYPE); - - if(ret.base == 0xDEAD) { - Log::Display(LEVEL_MESSAGE_FAIL,"Timeout for port %d in slot enabling\n",portnum); - return 0; - } - - xhci_slot_trb_t* slot_ret = (xhci_slot_trb_t*)&ret; - - if(ret.ret_code != 1) - Log::Display(LEVEL_MESSAGE_FAIL,"Can't allocate slot for port %d (ret %d)\n",portnum,ret.ret_code); - - return slot_ret->info_s.slotid; - -} - -int __xhci_set_addr(xhci_device_t* dev,uint64_t addr,uint32_t id,char bsr) { - xhci_set_addr_trb_t trb; - memset(&trb,0,sizeof(trb)); - trb.base = addr; - trb.info_s.bsr = 0; - trb.info_s.type = TRB_ADDRESSDEVICECOMMAND_TYPE; - trb.info_s.slotid = id; - __xhci_clear_event(dev); - - drivers::tsc::sleep(5000); - - __xhci_clear_event(dev); - - __xhci_command_ring_queue(dev,dev->com_ring,(xhci_trb_t*)&trb); - __xhci_doorbell(dev,0); - drivers::tsc::sleep(5000); - - xhci_trb_t ret = __xhci_event_wait(dev,TRB_COMMANDCOMPLETIONEVENT_TYPE); - - if(ret.ret_code != 1 && ret.ret_code != 0) - Log::Display(LEVEL_MESSAGE_FAIL,"Can't set XHCI port address (ret %d)\n",ret.ret_code); - - return ret.ret_code; - -} - -xhci_trb_t __xhci_send_usb_request_packet(xhci_device_t* dev,xhci_usb_device_t* usbdev,xhci_usb_command_t usbcommand,void* out,uint64_t len) { - - uint64_t phys_status_buf = memory::pmm::_physical::alloc(4096); - uint64_t phys_desc_buf = memory::pmm::_physical::alloc(4096); - - void* status_buf = Other::toVirt(phys_status_buf); - void* desc_buf = Other::toVirt(phys_desc_buf); - - memset(out,0,len); - - xhci_setupstage_trb_t setup; - xhci_datastage_trb_t data; - xhci_eventdata_trb_t event0; - xhci_statusstage_trb_t status; - xhci_eventdata_trb_t event1; - - memset(&setup,0,sizeof(xhci_trb_t)); - memset(&data,0, sizeof(xhci_trb_t)); - memset(&event0,0,sizeof(xhci_trb_t)); - memset(&status,0,sizeof(xhci_trb_t)); - memset(&event1,0,sizeof(xhci_trb_t)); - - memcpy(&setup.command,&usbcommand,sizeof(xhci_usb_command_t)); - - setup.type = TRB_SETUPSTAGE_TYPE; - setup.trt = 3; - setup.imdata = 1; - setup.len = 8; - - data.type = TRB_DATASTAGE_TYPE; - data.data = phys_desc_buf; - data.len = len; - data.chain = 1; - data.direction = 1; - - event0.type = TRB_EVENTDATA_TYPE; - event0.base = phys_status_buf; - event0.intoncomp = 1; - - status.type = TRB_STATUSSTAGE_TYPE; - status.chain = 1; - - event1.type = TRB_EVENTDATA_TYPE; - event1.intoncomp = 1; - - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&setup); - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&data); - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&event0); - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&status); - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&event1); - - __xhci_clear_event(dev); - - __xhci_doorbell_id(dev,usbdev->slotid,1); - drivers::tsc::sleep(5000); - - xhci_trb_t ret = __xhci_event_wait(dev,TRB_TRANSFEREVENT_TYPE); - - if(ret.base == 0xDEAD) { - ret.ret_code = 0; - return ret; - } - - if(ret.ret_code != 1) { - Log::Display(LEVEL_MESSAGE_FAIL,"Failed to request xhci device, idx: %p, val: %p, type: %p, len: %p, request: %d ret_code %d\n",usbcommand.index,usbcommand.value,usbcommand.type,usbcommand.len,usbcommand.request,ret.ret_code); - ret.ret_code = 0; - return ret; - } - - drivers::tsc::sleep(5000); - - memcpy(out,desc_buf,len); - - memory::pmm::_physical::free(phys_desc_buf); - memory::pmm::_physical::free(phys_status_buf); - - return ret; - -} - -xhci_trb_t __xhci_send_usb_packet(xhci_device_t* dev,xhci_usb_device_t* usbdev,xhci_usb_command_t com) { - - xhci_setupstage_trb_t setup; - xhci_statusstage_trb_t status; - - memset(&setup,0,sizeof(xhci_setupstage_trb_t)); - memset(&status,0,sizeof(xhci_statusstage_trb_t)); - - memcpy(&setup.command,&com,sizeof(xhci_usb_command_t)); - - setup.imdata = 1; - setup.len = 8; - setup.type = TRB_SETUPSTAGE_TYPE; - - status.direction = 1; - status.intoncomp = 1; - status.type = TRB_STATUSSTAGE_TYPE; - - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&setup); - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&status); - - __xhci_clear_event(dev); - - __xhci_doorbell_id(dev,usbdev->slotid,1); - drivers::tsc::sleep(5000); - - xhci_trb_t ret = __xhci_event_wait(dev,TRB_TRANSFEREVENT_TYPE); - - return ret; - -} - -int __xhci_get_usb_descriptor(xhci_device_t* dev,xhci_usb_device_t* usbdev,void* out,uint64_t len) { - xhci_usb_command_t usbcommand; - usbcommand.type = 0x80; - usbcommand.request = 6; - usbcommand.value = 1 << 8; - usbcommand.index = 0; - usbcommand.len = len; - - xhci_trb_t ret = __xhci_send_usb_request_packet(dev,usbdev,usbcommand,out,len); - if(ret.ret_code != 1) - return 0; - - return 1; - -} - -uint16_t __xhci_get_speed(xhci_device_t* dev,uint32_t portsc) { - uint8_t extracted_speed = (portsc & 0x3C00) >> 10; - switch (extracted_speed) { - case XHCI_USB_SPEED_LOW_SPEED: - return 8; - - case XHCI_USB_SPEED_FULL_SPEED: - return 64; - - case XHCI_USB_SPEED_HIGH_SPEED: - return 64; - - case XHCI_USB_SPEED_SUPER_SPEED: - return 512; - - case XHCI_USB_SPEED_SUPER_SPEED_PLUS: - return 512; - - default: - return 0; - } -} - -int __xhci_reset_dev(xhci_device_t* dev,uint32_t portnum) { - volatile uint32_t* portsc = (volatile uint32_t*)__xhci_portsc(dev,portnum); - uint32_t load_portsc = *portsc; - - if(!(*portsc & (1 << 9))) { - load_portsc |= (1 << 9); - *portsc = load_portsc; - drivers::tsc::sleep(5000); - if(!(*portsc & (1 << 9))) { - return 0; - } - } - - uint8_t old_bit = load_portsc & (1 << 1); - - if(dev->usb3ports[portnum]) { - load_portsc |= (1 << 31); - *portsc = load_portsc; - } else { - load_portsc |= 0x10; - *portsc = load_portsc; - } - - uint16_t time = 50; - - if(dev->usb3ports[portnum]) { - while(*portsc & (1 << 19)) { - if(time-- == 0) { - Log::Display(LEVEL_MESSAGE_FAIL,"Can't reset USB 3.0 device with port %d, ignoring\n",portnum); - return 0; - } - drivers::tsc::sleep(5000); - } - } else { - while((*portsc & (1 << 1)) == old_bit) { - if(time-- == 0) { - Log::Display(LEVEL_MESSAGE_FAIL,"Can't reset USB 2.0 device with port %d, ignoring\n",portnum); - return 1; - } - drivers::tsc::sleep(5000); - } - } - - drivers::tsc::sleep(5000); - return 1; - -} - -void __xhci_unicode_to_ascii(uint16_t* src,char* dest) { - uint16_t src_ptr = 0; - uint16_t dest_ptr = 0; - - uint16_t* ptr = (uint16_t*)src; - while(ptr[src_ptr]) { - - if(ptr[src_ptr] < 128) - dest[dest_ptr++] = ptr[src_ptr++]; - else - dest[dest_ptr++] = '?'; - } - dest[dest_ptr] = '\0'; -} - -int __xhci_read_usb_string(xhci_device_t* dev,xhci_usb_device_t* usbdev,xhci_string_descriptor_t* out,uint8_t index,uint8_t lang) { - xhci_usb_command_t usbcommand; - usbcommand.type = 0x80; - usbcommand.request = 6; - usbcommand.value = (3 << 8) | index; - usbcommand.index = lang; - usbcommand.len = sizeof(xhci_usb_descriptor_header); - - xhci_trb_t ret = __xhci_send_usb_request_packet(dev,usbdev,usbcommand,out,usbcommand.len); - if(ret.ret_code != 1) - return 0; - - usbcommand.len = out->head.len; - - if(usbcommand.len < 8) { - return 1; - } - - ret = __xhci_send_usb_request_packet(dev,usbdev,usbcommand,out,usbcommand.len); - if(ret.ret_code != 1) - return 0; - - return 1; - -} - - - -int __xhci_read_usb_lang_string(xhci_device_t* dev,xhci_usb_device_t* usbdev,xhci_lang_descriptor_t* out) { - xhci_usb_command_t usbcommand; - usbcommand.type = 0x80; - usbcommand.request = 6; - usbcommand.value = (3 << 8); - usbcommand.index = 0; - usbcommand.len = sizeof(xhci_usb_descriptor_header); - - xhci_trb_t ret = __xhci_send_usb_request_packet(dev,usbdev,usbcommand,out,usbcommand.len); - if(ret.ret_code != 1) - return 0; - - usbcommand.len = out->head.len; - - ret = __xhci_send_usb_request_packet(dev,usbdev,usbcommand,out,usbcommand.len); - if(ret.ret_code != 1) - return 0; - - return 1; - -} - -int __xhci_print_device_info(xhci_device_t* dev,xhci_usb_device_t* usb_dev,char* product0,char* manufacter0) { - xhci_lang_descriptor_t lang; - - int status = __xhci_read_usb_lang_string(dev,usb_dev,&lang); - - if(!status) - return 0; - - uint16_t lang0 = lang.lang[0]; - - xhci_string_descriptor_t product; - xhci_string_descriptor_t manufacter; - - memset(&product,0,sizeof(product)); - memset(&manufacter,0,sizeof(manufacter)); - - status = __xhci_read_usb_string(dev,usb_dev,&product,usb_dev->desc->product1,lang0); - - if(!status) - return 0; - - status = __xhci_read_usb_string(dev,usb_dev,&manufacter,usb_dev->desc->manufacter,lang0); - - if(!status) - return 0; - - memset(product0,0,256); - memset(manufacter0,0,256); - - __xhci_unicode_to_ascii(product.str,product0); - __xhci_unicode_to_ascii(manufacter.str,manufacter0); - - return 1; - -} - -void __xhci_setup_config(xhci_device_t* dev,xhci_usb_device_t* usbdev,uint16_t value) { - xhci_usb_command_t command; - command.type = 0; - command.index = 0; - command.len = 0; - command.request = 9; - command.value = value; - - int ret = __xhci_send_usb_packet(dev,usbdev,command).ret_code; - - if(ret != 1) - Log::Display(LEVEL_MESSAGE_FAIL,"Can't set configuration on port %d with val %d (ret %d)\n",usbdev->portnum,value,ret); -} - -void __xhci_get_config_descriptor(xhci_device_t* dev,xhci_usb_device_t* usbdev, xhci_config_descriptor_t* out) { - xhci_usb_command_t com; - com.type = 0x80; - com.value = 2 << 8; - com.index = 0; - com.len = sizeof(xhci_usb_descriptor_header); - com.request = 6; - - __xhci_send_usb_request_packet(dev,usbdev,com,out,sizeof(xhci_usb_descriptor_header)); - com.len = out->head.len; - __xhci_send_usb_request_packet(dev,usbdev,com,out,out->head.len); - com.len = out->len; - __xhci_send_usb_request_packet(dev,usbdev,com,out,out->len); - -} - -void __xhci_get_hid_report(xhci_device_t* dev,xhci_usb_device_t* usbdev,uint8_t idx,uint8_t internum,void* data,uint32_t len) { - xhci_usb_command_t cmd; - cmd.index = internum; - cmd.request = 6; - cmd.type = 0x81; - cmd.len = len; - cmd.value = (0x22 << 8) | idx; - __xhci_send_usb_request_packet(dev,usbdev,cmd,data,len); -} - -void __xhci_set_boot_protocol(xhci_device_t* dev, xhci_usb_device_t* usbdev, int internum) { - xhci_usb_command_t cmd; - cmd.index = internum; - cmd.request = 0x0B; - cmd.type = 0x21; - cmd.len = 0; - cmd.value = 0; - - char data[4096]; - __xhci_send_usb_request_packet(dev,usbdev,cmd,data,0); -} - -int __xhci_ep_to_type(xhci_endpoint_descriptor_t* desc) { - uint8_t direction = (desc->endpointaddr & 0x80) ? 1 : 0; - uint8_t type = desc->attributes & 3; - - switch (type) { - case 1: - return direction == 1 ? XHCI_ENDPOINTTYPE_ISOCHRONOUS_IN : XHCI_ENDPOINTTYPE_ISOCHRONOUS_OUT; - - case 2: - return direction == 1 ? XHCI_ENDPOINTTYPE_BULK_IN : XHCI_ENDPOINTTYPE_BULK_OUT; - - case 3: - return direction == 1 ? XHCI_ENDPOINTTYPE_INTERRUPT_IN : XHCI_ENDPOINTTYPE_INTERRUPT_OUT; - } - - return 0; // without it i will got UB -} - -void __xhci_ask_for_help_hid(xhci_device_t* dev,xhci_usb_device_t* usbdev) { - - for(int i = 0;i < 30;i++) { - - if(!usbdev->doorbell_values[i]) - continue; - - xhci_port_ring_ctx_t* transfer_ring = usbdev->ep_ctx[i]; - xhci_normal_trb_t trb; - memset(&trb,0,sizeof(xhci_normal_trb_t)); - trb.info_s.type = 1; - trb.info_s.ioc = 1; - trb.base = (uint64_t)usbdev->phys_buffers[i]; - trb.trbtransferlen = usbdev->buffers_need_size[i]; - - __xhci_port_ring_queue(transfer_ring,(xhci_trb_t*)&trb); - __xhci_doorbell_id(dev,usbdev->slotid,usbdev->doorbell_values[i]); - } - -} - -const char* __xhci_usb_type_to_str(int type) { - switch(type) { - case USB_TYPE_KEYBOARD: - return "USB Keyboard"; - case USB_TYPE_MOUSE: - return "USB Mouse"; - default: - return "Unsupported"; - }; -} - -int log2(unsigned int x) { - int result = -1; - while (x) { - x >>= 1; - result++; - } - return result; -} - -void __xhci_init_dev(xhci_device_t* dev,int portnum) { - - volatile uint32_t* portsc = __xhci_portsc(dev,portnum); - uint32_t load_portsc = *portsc; - if(!(load_portsc & 1)) - return; - - int status = __xhci_reset_dev(dev,portnum); - if(!status) - return; - - int id = __xhci_enable_slot(dev,portnum); - - xhci_usb_device_t* usb_dev = __xhci_alloc_dev(portnum,id); - //String::memset(usb_dev,0,sizeof(xhci_usb_device_t)); - - memset(usb_dev->doorbell_values,0,30); - - usb_dev->interface = 0; - - uint64_t addr = memory::pmm::_physical::alloc(4096); - __xhci_create_dcbaa(dev,usb_dev->slotid,addr); - - uint32_t* hccparams = (uint32_t*)(&dev->cap->hccparams1); - char context_size = ((hccparams1_t*)hccparams)->contextsize; - - if(!context_size) - dev->dcbaa[id] += 64; - else - dev->dcbaa[id] += 128; - - if(!context_size) - usb_dev->_is64byte = 0; - else - usb_dev->_is64byte = 1; - - usb_dev->dev = dev; - - load_portsc = *portsc; // load it again - - uint16_t speed = __xhci_get_speed(dev,load_portsc); - - const char* speed_to_str[7] = { - "(0 MB/s - USB ?)", - "(12 MB/s - USB 2.0)", - "(1.5 Mb/s - USB 2.0)", - "(480 Mb/s - USB 2.0)", - "(5 Gb/s - USB3.0)", - "(10 Gb/s - USB 3.1)" - }; - - if(!context_size) { - xhci_input_ctx_t* input_ctx = (xhci_input_ctx_t*)Other::toVirt(addr); - - memset(input_ctx,0,4096); - input_ctx->input_ctx.A = (1 << 0) | (1 << 1); - input_ctx->slot.contextentries = 1; - input_ctx->slot.speed = (load_portsc & 0x3C00) >> 10; - input_ctx->slot.porthubnum = portnum + 1; - input_ctx->ep0.endpointtype = 4; - input_ctx->ep0.cerr = 3; - input_ctx->ep0.maxpacketsize = speed; - input_ctx->ep0.base = usb_dev->transfer_ring->phys | usb_dev->transfer_ring->cycle; - input_ctx->ep0.averagetrblen = 0x8; - usb_dev->input_ctx = (xhci_input_ctx_t*)input_ctx; - - } else { - xhci_input_ctx64_t* input_ctx = (xhci_input_ctx64_t*)Other::toVirt(addr); - - memset(input_ctx,0,4096); - input_ctx->input_ctx.A = (1 << 0) | (1 << 1); - input_ctx->slot.contextentries = 1; - input_ctx->slot.speed = (load_portsc & 0x3C00) >> 10; - input_ctx->slot.porthubnum = portnum + 1; - input_ctx->ep0.endpointtype = 4; - input_ctx->ep0.cerr = 3; - input_ctx->ep0.maxpacketsize = speed; - input_ctx->ep0.base = usb_dev->transfer_ring->phys | usb_dev->transfer_ring->cycle; - input_ctx->ep0.averagetrblen = 8; - - usb_dev->input_ctx = (xhci_input_ctx_t*)input_ctx; - - } - - int status_addr = __xhci_set_addr(dev,addr,id,0); - - if(status_addr == 0) { - Log::Display(LEVEL_MESSAGE_WARN,"zero ret from xhci_set_addr (broken xhci ?)\n"); - } else if(status_addr != 1) - return; - - xhci_usb_descriptor_t* descriptor = (xhci_usb_descriptor_t*)malloc(4096); - int status2 = __xhci_get_usb_descriptor(dev,usb_dev,(void*)descriptor,8); - - if(!status2) - return; - - ((xhci_input_ctx_t*)Other::toVirt(dev->dcbaa[id]))->ep0.maxpacketsize = descriptor->maxpacketsize; - - status2 = __xhci_get_usb_descriptor(dev,usb_dev,(void*)descriptor,descriptor->head.len); - if(!status2) - return; - usb_dev->desc = descriptor; - - usb_dev->type = 0; - - if(!speed) { - Log::Display(LEVEL_MESSAGE_FAIL,"Broken USB Device/Firmware, can't continue work. skipping\n"); - return; - } - - char product[1024]; - char manufacter[1024]; - - memset(product,0,1024); - memset(manufacter,0,1024); - - int status4 = __xhci_print_device_info(dev,usb_dev,product,manufacter); - if(!status4) - return; - - xhci_config_descriptor_t* cfg = (xhci_config_descriptor_t*)malloc(4096); - usb_dev->config = cfg; - - __xhci_get_config_descriptor(dev,usb_dev,cfg); - - __xhci_setup_config(dev,usb_dev,cfg->configval); - - if(!context_size) { - usb_dev->input_ctx->input_ctx.A = (1 << 0); - } else { - xhci_input_ctx64_t* input = (xhci_input_ctx64_t*)Other::toVirt(addr); - input->input_ctx.A = (1 << 0); - } - - uint16_t i = 0; - while(i < (cfg->len - cfg->head.len)) { - xhci_usb_descriptor_header* current = (xhci_usb_descriptor_header*)(&cfg->data[i]); - //INFO("Found descriptor with type %d (0x%p) and len %d (i %d)!\n",current->type,current->type,current->len,i); - - xhci_interface_t* inter = new xhci_interface_t; - inter->type = current->type; - inter->data = current; - memset(inter,0,sizeof(xhci_interface_t)); - if(!usb_dev->interface) - usb_dev->interface = inter; - else { - inter->next = usb_dev->interface; - usb_dev->interface = inter; - } - - switch(current->type) { - - case 0x04: { - xhci_interface_descriptor_t* interface = (xhci_interface_descriptor_t*)current; - //INFO("interface interclass %d, interface intersubclass %d, protocol %d\n",interface->interclass,interface->intersubclass,interface->protocol); - if(interface->interclass == 3 && interface->intersubclass == 1 && !usb_dev->type) { - switch(interface->protocol) { - case 2: { - usb_dev->type = USB_TYPE_MOUSE; - break; - } - - case 1: { - usb_dev->type = USB_TYPE_KEYBOARD; - break; - } - } - } - break; - } - - case 0x21: { - xhci_hid_descriptor_t* hid = (xhci_hid_descriptor_t*)current; - for(int i = 0; i < hid->numdesc;i++) { - xhci_hid_sub_desc* desc = &hid->desc[i]; - if(desc->desctype == 0x22) { - - xhci_interface_t* need_interface = usb_dev->interface; - while(need_interface) { - if(need_interface->type = 0x04) - break; - need_interface = need_interface->next; - } - - if(!need_interface) - continue; - - need_interface->buffer = malloc(desc->desclen + 1); - memset(need_interface->buffer,0,desc->desclen + 1); - need_interface->len = desc->desclen; - - xhci_interface_descriptor_t* interface = (xhci_interface_descriptor_t*)need_interface; - - __xhci_set_boot_protocol(dev,usb_dev,interface->num); - __xhci_get_hid_report(dev,usb_dev,0,interface->num,need_interface->buffer,need_interface->len); - - } - } - break; - } - // __xhci_setup_port_ring(256,slotid); - case 0x05: { - xhci_endpoint_descriptor_t* ep = (xhci_endpoint_descriptor_t*)current; - - int idx = ((ep->endpointaddr >> 7) & 1) + ((ep->endpointaddr & 0x0F) << 1); - usb_dev->main_ep = idx; - idx -= 2; - usb_dev->ep_ctx[idx] = __xhci_setup_port_ring(256,usb_dev->slotid); - - usb_dev->buffers_need_size[idx] = ep->maxpacketsize; - - usb_dev->phys_buffers[idx] = memory::pmm::_physical::alloc(4096); - usb_dev->buffers[idx] = (uint8_t*)Other::toVirt(usb_dev->phys_buffers[idx]); - usb_dev->doorbell_values[idx] = idx + 2; - - if(!context_size) { - xhci_input_ctx_t* input = (xhci_input_ctx_t*)Other::toVirt(addr); - xhci_endpoint_ctx_t* ep1 = &input->ep[idx]; - memset(ep1,0,sizeof(xhci_endpoint_ctx_t)); - usb_dev->input_ctx->input_ctx.A |= (1 << (idx + 2)); - - input->slot.contextentries += 2; - ep1->state = 0; - ep1->endpointtype = __xhci_ep_to_type(ep); - ep1->maxpacketsize = ep->maxpacketsize; - ep1->some_shit_with_long_name_lo = ep->maxpacketsize; - ep1->cerr = 3; - ep1->maxburstsize = 0; - ep1->averagetrblen = ep->maxpacketsize; - ep1->base = usb_dev->ep_ctx[idx]->phys | usb_dev->ep_ctx[idx]->cycle; - uint8_t port_speed = (load_portsc & 0x3C00) >> 10; - uint8_t interval = ep->interval; - uint8_t epty = ep1->endpointtype; - - /* thanks n00byedge for tips */ - - if(port_speed == XHCI_USB_SPEED_HIGH_SPEED || port_speed == XHCI_USB_SPEED_SUPER_SPEED || port_speed == XHCI_USB_SPEED_SUPER_SPEED_PLUS) - ep1->interval = interval - 1; - else if(port_speed == XHCI_USB_SPEED_FULL_SPEED && (epty == XHCI_ENDPOINTTYPE_ISOCHRONOUS_IN || epty == XHCI_ENDPOINTTYPE_ISOCHRONOUS_OUT)) - ep1->interval = interval + 2; - else if((port_speed == XHCI_USB_SPEED_FULL_SPEED || port_speed == XHCI_USB_SPEED_LOW_SPEED) && (epty == XHCI_ENDPOINTTYPE_INTERRUPT_IN || epty == XHCI_ENDPOINTTYPE_INTERRUPT_OUT)) { - ep1->interval = log2(interval) + 4; - } - - - } else { - xhci_input_ctx64_t* input = (xhci_input_ctx64_t*)Other::toVirt(addr); - xhci_endpoint_ctx_t* ep1 = (xhci_endpoint_ctx_t*)(&input->ep[idx]); - memset(ep1,0,sizeof(xhci_endpoint_ctx_t)); - - input->slot.contextentries += 2; - input->input_ctx.A |= (1 << (idx + 2)); - ep1->state = 0; - ep1->endpointtype = __xhci_ep_to_type(ep); - ep1->maxpacketsize = ep->maxpacketsize; - ep1->some_shit_with_long_name_lo = ep->maxpacketsize; - ep1->cerr = 3; - ep1->maxburstsize = 0; - ep1->averagetrblen = ep->maxpacketsize; - ep1->base = (uint64_t)usb_dev->ep_ctx[idx]->phys | usb_dev->ep_ctx[idx]->cycle; - uint8_t port_speed = (load_portsc & 0x3C00) >> 10; - uint8_t interval = ep->interval; - uint8_t epty = ep1->endpointtype; - - if(port_speed == XHCI_USB_SPEED_HIGH_SPEED || port_speed == XHCI_USB_SPEED_SUPER_SPEED || port_speed == XHCI_USB_SPEED_SUPER_SPEED_PLUS) - ep1->interval = interval - 1; - else if(port_speed == XHCI_USB_SPEED_FULL_SPEED && (epty == XHCI_ENDPOINTTYPE_ISOCHRONOUS_IN || epty == XHCI_ENDPOINTTYPE_ISOCHRONOUS_OUT)) - ep1->interval = interval + 2; - else if((port_speed == XHCI_USB_SPEED_FULL_SPEED || port_speed == XHCI_USB_SPEED_LOW_SPEED) && (epty == XHCI_ENDPOINTTYPE_INTERRUPT_IN || epty == XHCI_ENDPOINTTYPE_INTERRUPT_OUT)) { - ep1->interval = log2(interval) + 4; - } - } - - break; - } - } - - i += current->len; - } - - xhci_configure_endpoints_trb_t ep_trb; - memset(&ep_trb,0,sizeof(xhci_trb_t)); - - ep_trb.info_s.type = 12; - ep_trb.base = addr; - ep_trb.info_s.slot = usb_dev->slotid; - - __xhci_clear_event(dev); - - __xhci_command_ring_queue(dev,dev->com_ring,(xhci_trb_t*)&ep_trb); - __xhci_doorbell(dev,0); - drivers::tsc::sleep(5000); - - xhci_trb_t ret = __xhci_event_wait(dev,TRB_COMMANDCOMPLETIONEVENT_TYPE); - - if(ret.ret_code > 1) { - Log::Display(LEVEL_MESSAGE_FAIL,"Can't configure endpoints for port %d (ret %d base %p), context_size: %d, given addr %p\n",portnum,ret.ret_code,ret.base,usb_dev->_is64byte,ep_trb.base); - return; - } else if(ret.ret_code == 0) { - Log::Display(LEVEL_MESSAGE_WARN,"Endpoint configure TRB ret_code is 0 (it shouldn't)\n"); - } - - __xhci_ask_for_help_hid(dev,usb_dev); - - drivers::tsc::sleep(1000); - - Log::Display(LEVEL_MESSAGE_INFO,"Found USB%s Device %s (%d, %d, %d) %s %s on port %d and slot %d\n",dev->usb3ports[portnum] == 1 ? "3.0" : "2.0",((load_portsc & 0x3C00) >> 10) < 7 ? speed_to_str[(load_portsc & 0x3C00) >> 10] : "Broken (0 MB/S - USB ?)",(load_portsc & 0x3C00) >> 10,speed,descriptor->maxpacketsize,manufacter,product,portnum,usb_dev->slotid); - - char buffer[2048]; - memset(buffer,0,2048); - __printfbuf(buffer,2048,"%s %s",manufacter, product); - - usb_dev->evdev_num = vfs::evdev::create(buffer,usb_dev->type == USB_TYPE_KEYBOARD ? EVDEV_TYPE_KEYBOARD : EVDEV_TYPE_MOUSE); - -} - -void __xhci_init_ports(xhci_device_t* dev) { - for(int i = 0;i <= dev->max_ports;i++) { - __xhci_init_dev(dev,i); - } -} - -void __xhci_iterate_usb_ports(xhci_device_t* dev) { - - volatile uint32_t* cap = (volatile uint32_t*)(dev->xhci_virt_base + dev->cap->hccparams1.xECP * 4); - - xhci_ext_cap_t load_cap; - load_cap.full = *cap; - //INFO("0x%p\n",cap); - while(1) { - //INFO("Found cap with id %d\n",load_cap.id); - - if(load_cap.id == 2) { - - xhci_usb_cap_t usb_cap; - - usb_cap.firsthalf = cap[0]; - usb_cap.name = cap[1]; - usb_cap.thirdhalf = cap[2]; - usb_cap.fourhalf = cap[3]; - - if(usb_cap.major == 3) { - for(uint8_t i = usb_cap.portoffset - 1;i <= (usb_cap.portoffset - 1) + usb_cap.portcount - 1;i++) { - dev->usb3ports[i] = 1; - //Log::Display(LEVEL_MESSAGE_INFO,"Found USB 3.0 Port %d !\n",i); - } - } else { - for(uint8_t i = usb_cap.portoffset - 1;i <= (usb_cap.portoffset - 1) + usb_cap.portcount - 1;i++) { - dev->usb3ports[i] = 0; - //Log::Display(LEVEL_MESSAGE_INFO,"Found USB 2.0 Port %d !\n",i); - } - } - - } else if(load_cap.id == 1) { - *((uint32_t*)((uint64_t)cap + 4)) &= ~((1 << 0) | (1 << 13) | (1 << 4) | (1 << 14) | (1 << 15)); - *cap |= (1 << 24); - - drivers::tsc::sleep(500 * 1000); - - } - - - - if(!load_cap.nextcap) - break; - - - cap = (uint32_t*)((uint64_t)cap + (load_cap.nextcap * 4)); - load_cap.full = *cap; - - } -} - -xhci_hid_driver_t* hid_drv = 0; - -void xhci_hid_register(void (*func)(xhci_usb_device_t* usbdev,xhci_done_trb_t* trb),int type) { - xhci_hid_driver_t* drv = new xhci_hid_driver_t; - drv->func = func; - drv->type = type; - - if(!hid_drv) - hid_drv = drv; - else { - drv->next = hid_drv; - hid_drv = drv; - } -} - -void __xhci_process_fetch(xhci_device_t* dev) { - xhci_event_ring_ctx_t* father = dev->event_ring; - xhci_trb_t* buffer[1024]; - - xhci_usb_device_t* usbdev = usbdevs; - - while(1) { - //Paging::EnableKernel(); - int count = 0; - memset(buffer,0,sizeof(xhci_trb_t*) * 1024); - if(get_trb(father,father->queue).info_s.cycle == father->cycle) - count = __xhci_event_receive(dev,father,buffer); - - if(!count) { - asm volatile("cli"); - yield(); - asm volatile("sti"); - } - - if(count) { - xhci_trb_t* current = 0; - for(int i = 0;i < count;i++) { - current = buffer[i]; - switch(current->info_s.type) { - case TRB_TRANSFEREVENT_TYPE: { - xhci_usb_device_t* usbdev = usbdevs; - xhci_done_trb_t* trb = (xhci_done_trb_t*)current; - while(usbdev) { - if(usbdev->dev == dev) { - if(usbdev->slotid == trb->info_s.slot) { - xhci_hid_driver_t* drv = hid_drv; - while(drv) { - if(drv->type == usbdev->type) - drv->func(usbdev,trb); - drv = drv->next; - } - __xhci_ask_for_help_hid(dev,usbdev); - } - } - usbdev = usbdev->next; - } - break; - } - default: { - Log::Display(LEVEL_MESSAGE_WARN,"xhci unsupported trb: %d\n",current->info_s.type); - } - } - } - } - - } -} - -void __xhci_device(pci_t pci_dev,uint8_t a, uint8_t b,uint8_t c) { - if(pci_dev.progIF != 0x30) { - //INFO("Current USB device with progIF 0x%p is not XHCI !\n",pci_dev.progIF); - return; - } - - xhci_device_t* dev = (xhci_device_t*)malloc(4096); - memset(dev,0,4096); - - uint32_t usb3_ports = drivers::pci::in(a,b,c,0xDC,4); - drivers::pci::out(a,b,c,0xD8,usb3_ports,4); - - auto usb2_ports = drivers::pci::in(a,b,c,0xD4,4); - drivers::pci::out(a,b,c,0xD0,usb2_ports,4); - - uint64_t addr = pci_dev.bar0 & ~4; // clear upper 2 bits - addr |= ((uint64_t)pci_dev.bar1 << 32); - - dev->xhci_phys_base = addr; - dev->xhci_virt_base = (uint64_t)memory::paging::maprangeret(addr,8 * PAGE_SIZE,PTE_RW | PTE_PRESENT); // map everything - - dev->cap = (xhci_cap_regs_t*)dev->xhci_virt_base; - dev->op = (xhci_op_regs_t*)(dev->xhci_virt_base + dev->cap->caplength); - dev->runtime = (xhci_runtime_regs_t*)(dev->xhci_virt_base + dev->cap->rtsoff); - dev->doorbell = (uint32_t*)(dev->xhci_virt_base + dev->cap->dboff); - - __xhci_put_new_device(dev); - if(dev->op->usbcmd & XHCI_USBCMD_RS) { // wtf how does it running - uint16_t timeout = XHCI_RESET_TIMEOUT; - //INFO("XHCI is already running, stopping it.\n"); - dev->op->usbcmd &= ~(XHCI_USBCMD_RS); - drivers::tsc::sleep(20 * 1000); - while(!(dev->op->usbsts & (1 << 0))) { - if(!timeout) { - Log::Raw("Can't disable XHCI. Ignoring\n"); - return; - } - drivers::tsc::sleep(20 * 1000); - timeout = timeout - 1; - } - } - //DEBUG("Resetting XHCI device\n"); - __xhci_reset(dev); - - dev->calculated_scratchpad_count = (uint16_t)((dev->cap->hcsparams2.max_scratchpad_hi << 5) | dev->cap->hcsparams2.max_scratchpad_lo); - - uint32_t hcsparams1 = *(uint32_t*)(&dev->cap->hcsparams1); - - dev->max_ports = ((volatile hcsparams1_t*)&hcsparams1)->maxports; - - //INFO("Configuring XHCI OPER\n"); - __xhci_setup_op(dev); - //INFO("Configuring XHCI Runtime\n"); - __xhci_setup_run(dev); - //INFO("Starting XHCI Device\n"); - __xhci_enable(dev); - //INFO("Iterating USB Ports\n"); - __xhci_iterate_usb_ports(dev); - //INFO("Configuring XHCI Ports\n"); - __xhci_init_ports(dev); - - // int pid = fork(); - // if(pid == 0) - // __xhci_process_fetch(dev); - - arch::x86_64::scheduling::create_kernel_thread((void (*)(void*))__xhci_process_fetch,(void*)dev); - Log::Display(LEVEL_MESSAGE_OK,"XHCI initializied\n"); - - -} - -char hid_to_ps2_layout[0x48]; - -int input0_fd = 0; -int mouse_fd = 0; - -void hid_layout_init() { - hid_to_ps2_layout[0x04] = 0x1E; - hid_to_ps2_layout[0x05] = 0x30; - hid_to_ps2_layout[0x06] = 0x2E; - hid_to_ps2_layout[0x07] = 0x20; - hid_to_ps2_layout[0x08] = 0x12; - hid_to_ps2_layout[0x09] = 0x21; - hid_to_ps2_layout[0x0A] = 0x22; - hid_to_ps2_layout[0x0B] = 0x23; - hid_to_ps2_layout[0x0C] = 0x17; - hid_to_ps2_layout[0x0D] = 0x24; - hid_to_ps2_layout[0x0E] = 0x25; - hid_to_ps2_layout[0x0F] = 0x26; - hid_to_ps2_layout[0x10] = 0x32; - hid_to_ps2_layout[0x11] = 0x31; - hid_to_ps2_layout[0x12] = 0x18; - hid_to_ps2_layout[0x13] = 0x19; - hid_to_ps2_layout[0x14] = 0x10; - hid_to_ps2_layout[0x15] = 0x13; - hid_to_ps2_layout[0x16] = 0x1F; - hid_to_ps2_layout[0x17] = 0x14; - hid_to_ps2_layout[0x18] = 0x16; - hid_to_ps2_layout[0x19] = 0x2F; - hid_to_ps2_layout[0x1A] = 0x11; - hid_to_ps2_layout[0x1B] = 0x2D; - hid_to_ps2_layout[0x1C] = 0x15; - hid_to_ps2_layout[0x1D] = 0x2C; - hid_to_ps2_layout[0x1E] = 0x02; - hid_to_ps2_layout[0x1F] = 0x03; - hid_to_ps2_layout[0x20] = 0x04; - hid_to_ps2_layout[0x21] = 0x05; - hid_to_ps2_layout[0x22] = 0x06; - hid_to_ps2_layout[0x23] = 0x07; - hid_to_ps2_layout[0x24] = 0x08; - hid_to_ps2_layout[0x25] = 0x09; - hid_to_ps2_layout[0x26] = 0x0A; - hid_to_ps2_layout[0x27] = 0x0B; - hid_to_ps2_layout[0x28] = 0x1C; - hid_to_ps2_layout[0x29] = 0x01; - hid_to_ps2_layout[0x2A] = 0x0E; - hid_to_ps2_layout[0x2B] = 0x0F; - hid_to_ps2_layout[0x2C] = 0x39; - hid_to_ps2_layout[0x2D] = 0x0C; - hid_to_ps2_layout[0x2E] = 0x0D; - hid_to_ps2_layout[0x2F] = 0x1A; - hid_to_ps2_layout[0x30] = 0x1B; - hid_to_ps2_layout[0x31] = 0x2B; - hid_to_ps2_layout[0x32] = 0x2B; - hid_to_ps2_layout[0x33] = 0x27; - hid_to_ps2_layout[0x34] = 0x28; - hid_to_ps2_layout[0x35] = 0x29; - hid_to_ps2_layout[0x36] = 0x33; - hid_to_ps2_layout[0x37] = 0x34; - hid_to_ps2_layout[0x38] = 0x35; - hid_to_ps2_layout[0x39] = 0x3A; - hid_to_ps2_layout[0x3B] = 0x3C; - hid_to_ps2_layout[0x3C] = 0x3D; - hid_to_ps2_layout[0x3D] = 0x3E; - hid_to_ps2_layout[0x3E] = 0x3F; - hid_to_ps2_layout[0x3F] = 0x40; - hid_to_ps2_layout[0x40] = 0x41; - hid_to_ps2_layout[0x41] = 0x42; - hid_to_ps2_layout[0x42] = 0x43; - hid_to_ps2_layout[0x43] = 0x44; - hid_to_ps2_layout[0x44] = 0x57; - hid_to_ps2_layout[0x45] = 0x58; - hid_to_ps2_layout[0x46] = 0x00; - hid_to_ps2_layout[0x47] = 0x46; -} - -void input_send(int num, uint8_t key) { - userspace_fd_t fd; - memset(&fd,0,sizeof(userspace_fd_t)); - memcpy(fd.path,"/dev/masterps2keyboard",strlen("/dev/masterps2keyboard")); - fd.is_cached_path = 1; - - std::uint64_t current_nano = drivers::tsc::currentnano(); - - asm volatile("cli"); - input_event ev; - ev.time.tv_sec = current_nano / 1000000000; - ev.time.tv_usec = (current_nano & 1000000000) / 1000; - ev.type = 1; - ev.code = key & ~(1 << 7); - ev.value = (key & (1 << 7)) ? 0 : 1; - vfs::evdev::submit(num,ev); - vfs::vfs::write(&fd,&key,1); - asm volatile("sti"); -} - -uint8_t hid_mods_to_ps2[8] = { - 0x1D, - 0x2A, - 0x38, - 0x5B, - 0x1D, - 0x36, - 0x38, - 0x5C -}; - -void __usbkeyboard_handler(xhci_usb_device_t* usbdev, xhci_done_trb_t* trb) { - uint8_t* data = usbdev->buffers[trb->info_s.ep_id - 2]; - uint8_t mods = data[0]; - uint8_t prev_mods = usbdev->add_buffer[0]; - - for (int i = 0; i < 8; i++) { - uint8_t mask = 1 << i; - if ((mods & mask) && !(prev_mods & mask)) { - if (i >= 4) input_send(usbdev->evdev_num, 0xE0); - input_send(usbdev->evdev_num, hid_mods_to_ps2[i]); - } else if (!(mods & mask) && (prev_mods & mask)) { - if (i >= 4) input_send(usbdev->evdev_num, 0xE0); - input_send(usbdev->evdev_num, hid_mods_to_ps2[i] | 0x80); - } - } - - for (int i = 2; i < 8; i++) { - int isPressed = 0; - for (int j = 2; j < 8; j++) { - if (usbdev->add_buffer[j] == data[i]) { - isPressed = 1; - break; - } - } - if (!isPressed && data[i] != 0) { - if (data[i] < 0x47) { - input_send(usbdev->evdev_num, hid_to_ps2_layout[data[i]]); - } else if(data[i] == 0x4F) { - input_send(usbdev->evdev_num, 0xE0); - input_send(usbdev->evdev_num, 0x4D); - } else if(data[i] == 0x50) { - input_send(usbdev->evdev_num, 0xE0); - input_send(usbdev->evdev_num, 0x4B); - } else if(data[i] == 0x51) { - input_send(usbdev->evdev_num, 0xE0); - input_send(usbdev->evdev_num, 0x50); - } else if(data[i] == 0x52) { - input_send(usbdev->evdev_num, 0xE0); - input_send(usbdev->evdev_num, 0x48); - } - } - } - - for (int i = 2; i < 8; i++) { - int isStillPressed = 0; - for (int j = 2; j < 8; j++) { - if (usbdev->add_buffer[i] == data[j]) { - isStillPressed = 1; - break; - } - } - if (!isStillPressed && usbdev->add_buffer[i] != 0) { - input_send(usbdev->evdev_num, hid_to_ps2_layout[usbdev->add_buffer[i]] | 0x80); - } else if(usbdev->add_buffer[i] == 0x4F) { - input_send(usbdev->evdev_num, 0xE0 | 0x80); - input_send(usbdev->evdev_num, 0x4D | 0x80); - } else if(usbdev->add_buffer[i] == 0x50) { - input_send(usbdev->evdev_num, 0xE0 | 0x80); - input_send(usbdev->evdev_num, 0x4B | 0x80); - } else if(usbdev->add_buffer[i] == 0x51) { - input_send(usbdev->evdev_num, 0xE0 | 0x80); - input_send(usbdev->evdev_num, 0x50 | 0x80); - } else if(usbdev->add_buffer[i] == 0x52) { - input_send(usbdev->evdev_num, 0xE0 | 0x80); - input_send(usbdev->evdev_num, 0x48 | 0x80); - } - } - - memcpy(usbdev->add_buffer, data, 8); -} - - -#define MOUSE_LB (1 << 0) -#define MOUSE_RB (1 << 1) -#define MOUSE_MB (1 << 2) -#define MOUSE_B4 (1 << 3) -#define MOUSE_B5 (1 << 4) - -/* -input0_fd = open("/dev/masterps2keyboard",O_RDWR); - mouse_fd = open("/dev/mastermouse",O_RDWR); -*/ - -#define REL_X 0x00 -#define REL_Y 0x01 -#define REL_Z 0x02 -#define REL_RX 0x03 -#define REL_RY 0x04 -#define REL_RZ 0x05 -#define REL_HWHEEL 0x06 -#define REL_DIAL 0x07 -#define REL_WHEEL 0x08 -#define REL_MISC 0x09 - -void __usbmouse_handler(xhci_usb_device_t* usbdev, xhci_done_trb_t* trb) { - uint8_t* data = usbdev->buffers[trb->info_s.ep_id - 2]; - - mouse_packet_t packet; - - packet.buttons = 0; - - packet.buttons |= (data[0] & (1 << 0)) ? MOUSE_LB : 0; - packet.buttons |= (data[0] & (1 << 1)) ? MOUSE_RB : 0; - packet.buttons |= (data[0] & (1 << 2)) ? MOUSE_MB : 0; - - packet.x = data[1]; - packet.y = -data[2]; - packet.z = 0; // todo: figure out how to get mouse scroll wheel data - - userspace_fd_t fd; - memset(&fd,0,sizeof(userspace_fd_t)); - memcpy(fd.path,"/dev/mastermouse",strlen("/dev/mastermouse")); - fd.is_cached_path = 1; - - asm volatile("cli"); - std::uint64_t current_nano = drivers::tsc::currentnano(); - input_event ev; - ev.time.tv_sec = current_nano / 1000000000; - ev.time.tv_usec = (current_nano & 1000000000) / 1000; - if(packet.x) { - ev.code = REL_X; - ev.type = 2; - ev.value = (packet.x & 0x80) ? (packet.x | 0xFFFFFF00) : packet.x; - vfs::evdev::submit(usbdev->evdev_num,ev); - } - - if(packet.y) { - ev.code = REL_Y; - ev.type = 2; - ev.value = (packet.y & 0x80) ? (packet.y | 0xFFFFFF00) : packet.y; - vfs::evdev::submit(usbdev->evdev_num,ev); - } - - if(packet.z) { - ev.code = REL_Z; - ev.type = 2; - ev.value = (packet.z & 0x80) ? (packet.z | 0xFFFFFF00) : packet.z; - vfs::evdev::submit(usbdev->evdev_num,ev); - } - - if((packet.buttons & MOUSE_LB) && !(usbdev->last_pack.buttons & MOUSE_LB)) { - ev.code = 272; - ev.type = 1; - ev.value = 1; - vfs::evdev::submit(usbdev->evdev_num,ev); - } else if(!(packet.buttons & MOUSE_LB) && (usbdev->last_pack.buttons & MOUSE_LB)) { - ev.code = 272; - ev.type = 1; - ev.value = 0; - vfs::evdev::submit(usbdev->evdev_num,ev); - } - - if((packet.buttons & MOUSE_RB) && !(usbdev->last_pack.buttons & MOUSE_RB)) { - ev.code = 273; - ev.type = 1; - ev.value = 1; - vfs::evdev::submit(usbdev->evdev_num,ev); - } else if(!(packet.buttons & MOUSE_RB) && (usbdev->last_pack.buttons & MOUSE_RB)) { - ev.code = 273; - ev.type = 1; - ev.value = 0; - vfs::evdev::submit(usbdev->evdev_num,ev); - } - - if((packet.buttons & MOUSE_MB) && !(usbdev->last_pack.buttons & MOUSE_MB)) { - ev.code = 274; - ev.type = 1; - ev.value = 1; - vfs::evdev::submit(usbdev->evdev_num,ev); - } else if(!(packet.buttons & MOUSE_MB) && (usbdev->last_pack.buttons & MOUSE_MB)) { - ev.code = 274; - ev.type = 1; - ev.value = 0; - vfs::evdev::submit(usbdev->evdev_num,ev); - } - - asm volatile("sti"); - - usbdev->last_pack = packet; - - drivers::tsc::sleep(1000); // actually hid wants this only after 1 ms - -} - -#include <drivers/pci.hpp> - -int xhci_init() { - - xhci_hid_register(__usbkeyboard_handler,USB_TYPE_KEYBOARD); - xhci_hid_register(__usbmouse_handler,USB_TYPE_MOUSE); - - hid_layout_init(); - - drivers::pci::reg(__xhci_device,0x0C,0x03); - return 0; -}
\ No newline at end of file diff --git a/kernel/src/etc/bootloaderinfo.cpp b/kernel/src/etc/bootloaderinfo.cpp deleted file mode 100644 index 50fb856..0000000 --- a/kernel/src/etc/bootloaderinfo.cpp +++ /dev/null @@ -1,105 +0,0 @@ - -#include <etc/bootloaderinfo.hpp> - -#include <etc/logging.hpp> - -#include <limine.h> -#include <cstdint> - -namespace { - -__attribute__((used, section(".limine_requests"))) -volatile LIMINE_BASE_REVISION(3); - -} - -namespace { - -__attribute__((used, section(".limine_requests"))) -volatile limine_framebuffer_request framebuffer_request = { - .id = LIMINE_FRAMEBUFFER_REQUEST, - .revision = 0, - .response = nullptr -}; - -__attribute__((used, section(".limine_requests"))) -volatile limine_hhdm_request hhdm_request = { - .id = LIMINE_HHDM_REQUEST, - .revision = 0, - .response = nullptr -}; - -__attribute__((used, section(".limine_requests"))) -volatile limine_memmap_request memmap_request = { - .id = LIMINE_MEMMAP_REQUEST, - .revision = 0, - .response = nullptr -}; - -__attribute__((used, section(".limine_requests"))) -volatile limine_rsdp_request rsdp_request = { - .id = LIMINE_RSDP_REQUEST, - .revision = 0, - .response = nullptr -}; - -__attribute__((used, section(".limine_requests"))) -volatile limine_executable_address_request keraddr_request = { - .id = LIMINE_EXECUTABLE_ADDRESS_REQUEST, - .revision = 0, - .response = nullptr -}; - -__attribute__((used, section(".limine_requests"))) -volatile limine_module_request initrd_request = { - .id = LIMINE_MODULE_REQUEST, - .revision = 0, - .response = nullptr -}; - -__attribute__((used, section(".limine_requests"))) -volatile LIMINE_MP(request) smp_request = { - .id = LIMINE_MP_REQUEST, - .revision = 0, - .response = nullptr -}; - -} - -namespace { - -__attribute__((used, section(".limine_requests_start"))) -volatile LIMINE_REQUESTS_START_MARKER; - -__attribute__((used, section(".limine_requests_end"))) -volatile LIMINE_REQUESTS_END_MARKER; - -} - -std::uint64_t BootloaderInfo::AccessRSDP() { - return rsdp_request.response->address; -} - -struct limine_framebuffer* BootloaderInfo::AccessFramebuffer() { - return framebuffer_request.response->framebuffers[0]; -} - -std::uint64_t BootloaderInfo::AccessHHDM() { - return hhdm_request.response->offset; -} - -struct limine_memmap_response* BootloaderInfo::AccessMemoryMap() { - return memmap_request.response; -} - -struct limine_executable_address_response* BootloaderInfo::AccessKernel() { - return keraddr_request.response; -} - -struct LIMINE_MP(response)* BootloaderInfo::AccessMP() { - return smp_request.response; -} - -struct limine_module_response* BootloaderInfo::AccessInitrd() { - return initrd_request.response; -}
\ No newline at end of file diff --git a/kernel/src/etc/libc.cpp b/kernel/src/etc/libc.cpp deleted file mode 100644 index 60f87ca..0000000 --- a/kernel/src/etc/libc.cpp +++ /dev/null @@ -1,4 +0,0 @@ - -#include <cstdint> - -#include <etc/libc.hpp> diff --git a/kernel/src/etc/logging.cpp b/kernel/src/etc/logging.cpp deleted file mode 100644 index ee5e7cf..0000000 --- a/kernel/src/etc/logging.cpp +++ /dev/null @@ -1,221 +0,0 @@ - -#include <etc/bootloaderinfo.hpp> -#include <etc/logging.hpp> - -#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 0 -#define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 0 -#define NANOPRINTF_IMPLEMENTATION -#include <lib/nanoprintf.h> - -#include <etc/libc.hpp> - -#include <drivers/serial.hpp> - -#include <generic/locks/spinlock.hpp> - -#include <stddef.h> -#include <stdarg.h> - -int __snprintf(char *buffer, size_t bufsz, char const *fmt, va_list vlist) { - int const rv = npf_vsnprintf(buffer, bufsz, fmt, vlist); - return rv; -} - -Log LogObject; -uint32_t default_fg = 0xFFFFFFFF; -uint32_t default_fg_bright = 0xFFFFFFFF; - -locks::spinlock log_lock; -#include <etc/font.hpp> - -extern "C" void* __flanterm_malloc(size_t size) { - return malloc(size); -} - -extern "C" void __flanterm_free(void* ptr,size_t size) { - free(ptr); -} - - -void Log::Init() { - struct limine_framebuffer* fb0 = BootloaderInfo::AccessFramebuffer(); - struct flanterm_context *ft_ctx = flanterm_fb_init( - __flanterm_malloc, - __flanterm_free, - (uint32_t*)fb0->address, fb0->width, fb0->height, fb0->pitch, - fb0->red_mask_size, fb0->red_mask_shift, - fb0->green_mask_size, fb0->green_mask_shift, - fb0->blue_mask_size, fb0->blue_mask_shift, - NULL, - NULL, NULL, - NULL, &default_fg, - NULL, &default_fg_bright, - (void*)unifont_arr, FONT_WIDTH, FONT_HEIGHT, 0, - 1, 1, 0 - ); - LogObject.Setup(ft_ctx); - -} - -const char* level_messages[] = { - [LEVEL_MESSAGE_OK] = "[ \x1b[38;2;0;255;0mOK\033[0m ] ", - [LEVEL_MESSAGE_FAIL] = "[ \x1b[38;2;255;0;0mFAILED\033[0m ] ", - [LEVEL_MESSAGE_WARN] = "[ \x1b[38;2;255;165;0mWARN\033[0m ] ", - [LEVEL_MESSAGE_INFO] = "[ \x1b[38;2;0;191;255mINFO\033[0m ] " -}; - -int __printfbuf(char* buffer, size_t bufsf, char const* fmt, ...) { - va_list val; - va_start(val, fmt); - return __snprintf(buffer,bufsf,fmt,val); - va_end(val); -} - -void Log::RawDisp(char* buffer, int len) { - LogObject.Write(buffer,len); -} - -void Log::SerialDisplay(int level,char* msg,...) { - log_lock.lock(); - va_list val; - va_start(val, msg); - char buffer[512]; - memset(buffer,0,512); - - drivers::serial serial(DEFAULT_SERIAL_PORT); - - serial.write((uint8_t*)level_messages[level],strlen(level_messages[level])); - int len = __snprintf(buffer,512,msg,val); - serial.write((uint8_t*)buffer,len); - va_end(val); - log_lock.unlock(); -} - -void Log::Display(int level,char* msg,...) { - va_list val; - va_start(val, msg); - char buffer[4096]; - memset(buffer,0,4096); - log_lock.lock(); - LogObject.Write((char*)level_messages[level],strlen(level_messages[level])); - int len = __snprintf(buffer,4096,msg,val); - LogObject.Write(buffer,len); - - drivers::serial serial(DEFAULT_SERIAL_PORT); - - serial.write((uint8_t*)level_messages[level],strlen(level_messages[level])); - serial.write((uint8_t*)buffer,len); - - log_lock.unlock(); - va_end(val); -} - -winsizez Log::GetDimensions() { - struct winsizez buf; - - size_t cols = 0; - size_t rows = 0; - flanterm_get_dimensions(LogObject.ft_ctx0,&cols,&rows); - buf.ws_col = cols; - buf.ws_row = rows; - return buf; -} - -void Log::Raw(char* msg,...) { - va_list val; - va_start(val, msg); - char buffer[4096]; - memset(buffer,0,4096); - log_lock.lock(); - int len = __snprintf(buffer,4096,msg,val); - LogObject.Write(buffer,len); - - drivers::serial serial(DEFAULT_SERIAL_PORT); - - serial.write((uint8_t*)buffer,len); - - log_lock.unlock(); - va_end(val); -} - -#include <generic/mm/pmm.hpp> - -char* dmesg_buf = 0; -std::uint64_t dmesg_size = 0; -std::uint64_t dmesg_real_size = 0; - -std::uint64_t dmesg_bufsize() { - return dmesg_size; -} - -void dmesg_read(char* buffer,std::uint64_t count) { - memset(buffer,0,count); - memcpy(buffer,dmesg_buf,dmesg_size > count ? count : dmesg_size); -} - -void dmesg0(char* msg,...) { - - if(!dmesg_buf) { - dmesg_buf = (char*)memory::pmm::_virtual::alloc(4096); - dmesg_real_size = 4096; - } - - log_lock.lock(); - - va_list val; - va_start(val, msg); - char buffer[4096]; - memset(buffer,0,4096); - int len = __snprintf(buffer,4096,msg,val); - - drivers::serial serial(DEFAULT_SERIAL_PORT); - serial.write((uint8_t*)buffer,len); - - uint64_t size = len; - - std::uint64_t offset = dmesg_size; - std::uint64_t new_size = offset + size; - - if (new_size > dmesg_real_size) { - alloc_t new_content0 = memory::pmm::_physical::alloc_ext(new_size); - std::uint8_t* new_content = (std::uint8_t*)new_content0.virt; - memcpy(new_content, dmesg_buf, dmesg_size); - memory::pmm::_physical::free((std::uint64_t)dmesg_buf); - dmesg_buf = (char*)new_content; - dmesg_real_size = new_content0.real_size; - } - - dmesg_size = new_size; - - memcpy(dmesg_buf + offset, buffer, size); - - dmesg_size += size; - - log_lock.unlock(); - - va_end(val); -} - -#include <arch/x86_64/interrupts/idt.hpp> - -extern void panic(int_frame_t* ctx, const char* msg); - -void panic_wrap(const char* msg,...) { - - va_list val; - va_start(val, msg); - char buffer[4096]; - memset(buffer,0,4096); - log_lock.lock(); - int len = __snprintf(buffer,4096,msg,val); - - panic(0,buffer); - - log_lock.unlock(); - va_end(val); -}
\ No newline at end of file diff --git a/kernel/src/gaster.txt b/kernel/src/gaster.txt new file mode 100644 index 0000000..294ea7c --- /dev/null +++ b/kernel/src/gaster.txt @@ -0,0 +1,22 @@ + + ++++++++ ++ + +&&&&&&&&&&&&&&&&&+ + +&&&&&&&&&&&&&&&&&&&+ + +&x. .;&&&x++ + &&&&.&&&&&. &&&&+ + &::::&:::::&&&&+ + &&&&.&&&&& .& + ++ ... . :&X .&+&&+ + +++........ +&& .&&&&++ + + & +$ &&&+ + +&.&. Xx .&+ + +&&&... . .&&&+ + +$&&&&x;;;+x&&&&&+ + +&&&&&&&+.;X&&&+&&&+ + ++ +&+ +&&&&&&&&&&+ +&&+ + +++ +&&&&&&&&+ +& + + ;&&&&&&; + +&... .+ + +.&;:+ + +
\ No newline at end of file diff --git a/kernel/src/generic/arch.hpp b/kernel/src/generic/arch.hpp new file mode 100644 index 0000000..7649b5b --- /dev/null +++ b/kernel/src/generic/arch.hpp @@ -0,0 +1,35 @@ +#include <cstdint> + +#define PAGE_SIZE 4096 +#define PAGING_PRESENT (1 << 0) +#define PAGING_RW (1 << 1) +#define PAGING_USER (1 << 2) +#define PAGING_NC (1 << 3) +#define PAGING_WC (1 << 4) +#define PTE_INDEX(address, bit) ((address & (uint64_t) 0x1FF << bit) >> bit) + +#define ARCH_INIT_EARLY 0 +#define ARCH_INIT_COMMON 1 + +namespace arch { + + extern void init(int stage); + + extern void disable_interrupts(); + extern void enable_interrupts(); + extern void wait_for_interrupt(); + extern void hcf(); + extern void pause(); + extern void tlb_flush(std::uintptr_t hint, std::uintptr_t len); + extern const char* name(); + + extern void enable_paging(std::uintptr_t root); + extern void map_page(std::uintptr_t root, std::uint64_t phys, std::uintptr_t virt, int flags); + extern std::uint64_t get_phys_from_page(std::uintptr_t root, std::uintptr_t virt); + extern void destroy_root(std::uintptr_t root, int level); + extern void copy_higher_half(std::uintptr_t root, std::uintptr_t src_root); + extern int level_paging(); + + extern void panic(char* msg); + +};
\ No newline at end of file diff --git a/kernel/src/generic/bootloader/bootloader.cpp b/kernel/src/generic/bootloader/bootloader.cpp new file mode 100644 index 0000000..a51035d --- /dev/null +++ b/kernel/src/generic/bootloader/bootloader.cpp @@ -0,0 +1,10 @@ + +#include <cstdint> +#include <generic/bootloader/limine.hpp> +#include <generic/bootloader/bootloader.hpp> + +bootloader::limine limine_bootloader; + +void bootloader::init() { + bootloader::bootloader = &limine_bootloader; +}
\ No newline at end of file diff --git a/kernel/src/generic/bootloader/bootloader.hpp b/kernel/src/generic/bootloader/bootloader.hpp new file mode 100644 index 0000000..21aa650 --- /dev/null +++ b/kernel/src/generic/bootloader/bootloader.hpp @@ -0,0 +1,20 @@ +#pragma once +#include <cstdint> +#include <limine.h> + +namespace bootloader { + + class bootloader_generic { + public: + virtual limine_framebuffer* get_framebuffer() = 0; + virtual std::uintptr_t get_hhdm() = 0; + virtual void* get_rsdp() = 0; + virtual std::uint64_t get_kernel_phys() = 0; + virtual std::uintptr_t get_kernel_virt() = 0; + virtual limine_memmap_response* get_memory_map() = 0; + virtual bool is_5_level_paging() = 0; + }; + + void init(); + inline bootloader_generic* bootloader = nullptr; +}
\ No newline at end of file diff --git a/kernel/src/generic/bootloader/limine.cpp b/kernel/src/generic/bootloader/limine.cpp new file mode 100644 index 0000000..e7175a4 --- /dev/null +++ b/kernel/src/generic/bootloader/limine.cpp @@ -0,0 +1,87 @@ + +#include <generic/bootloader/bootloader.hpp> +#include <generic/bootloader/limine.hpp> +#include <limine.h> + +namespace { + +__attribute__((used, section(".limine_requests"))) +volatile std::uint64_t limine_base_revision[] = LIMINE_BASE_REVISION(5); + +} + +namespace { + +__attribute__((used, section(".limine_requests"))) +volatile limine_framebuffer_request framebuffer_request = { + .id = LIMINE_FRAMEBUFFER_REQUEST_ID, + .revision = 0, + .response = nullptr +}; + +__attribute__((used, section(".limine_requests"))) volatile limine_memmap_request memmap_request = { .id = LIMINE_MEMMAP_REQUEST_ID, .revision = 0, .response = nullptr }; + + +__attribute__((used, section(".limine_requests"))) volatile limine_hhdm_request hhdm_request = { .id = LIMINE_HHDM_REQUEST_ID, .revision = 0, .response = nullptr }; + + +__attribute__((used, section(".limine_requests"))) volatile limine_executable_address_request kaddr_request = { .id = LIMINE_EXECUTABLE_ADDRESS_REQUEST_ID, .revision = 0, .response = nullptr }; + + +__attribute__((used, section(".limine_requests"))) volatile limine_rsdp_request rsdp_request = { .id = LIMINE_RSDP_REQUEST_ID, .revision = 0, .response = nullptr }; + +#if defined(__x86_64__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" + [[gnu::used]] [[gnu::section(".limine_requests")]] volatile limine_paging_mode_request _5lvl_paging = { .id = LIMINE_PAGING_MODE_REQUEST_ID,.revision = 0,.response = nullptr,.mode = LIMINE_PAGING_MODE_X86_64_5LVL,.max_mode = LIMINE_PAGING_MODE_AARCH64_5LVL,.min_mode = LIMINE_PAGING_MODE_AARCH64_4LVL }; +#pragma GCC diagnostic pop +#endif +} + +namespace { + +__attribute__((used, section(".limine_requests_start"))) +volatile std::uint64_t limine_requests_start_marker[] = LIMINE_REQUESTS_START_MARKER; + +__attribute__((used, section(".limine_requests_end"))) +volatile std::uint64_t limine_requests_end_marker[] = LIMINE_REQUESTS_END_MARKER; + +} + +namespace bootloader { + + std::uintptr_t limine::get_hhdm() { + return hhdm_request.response->offset; + } + + limine_framebuffer* limine::get_framebuffer() { + return framebuffer_request.response->framebuffers[0]; + } + + void* limine::get_rsdp() { + return rsdp_request.response->address; + } + + std::uint64_t limine::get_kernel_phys() { + return kaddr_request.response->physical_base; + } + + std::uint64_t limine::get_kernel_virt() { + return kaddr_request.response->virtual_base; + } + + limine_memmap_response* limine::get_memory_map() { + return memmap_request.response; + } + +#if defined(__x86_64__) + bool limine::is_5_level_paging() { + return _5lvl_paging.response->mode == LIMINE_PAGING_MODE_X86_64_5LVL ? true : false; + } +#else + bool limine::is_5_level_paging() { + return false; + } +#endif + +};
\ No newline at end of file diff --git a/kernel/src/generic/bootloader/limine.hpp b/kernel/src/generic/bootloader/limine.hpp new file mode 100644 index 0000000..c0fd78b --- /dev/null +++ b/kernel/src/generic/bootloader/limine.hpp @@ -0,0 +1,15 @@ + +#include <generic/bootloader/bootloader.hpp> + +namespace bootloader { + class limine final : public bootloader_generic { +public: + limine_framebuffer* get_framebuffer() override; + std::uintptr_t get_hhdm() override; + void* get_rsdp() override; + std::uint64_t get_kernel_phys() override; + std::uint64_t get_kernel_virt() override; + limine_memmap_response* get_memory_map() override; + bool is_5_level_paging() override; + }; +};
\ No newline at end of file diff --git a/kernel/src/generic/heap.cpp b/kernel/src/generic/heap.cpp new file mode 100644 index 0000000..e096a68 --- /dev/null +++ b/kernel/src/generic/heap.cpp @@ -0,0 +1,124 @@ +#include <cstdint> +#include <generic/pmm.hpp> +#include <generic/heap.hpp> +#include <generic/lock/spinlock.hpp> +#include <generic/hhdm.hpp> +#include <klibc/stdio.hpp> + +std::uint8_t* heap_pool; +heap_block* heap_end; +heap_block* current; + +locks::spinlock heap_lock; + +void kheap::init() { + heap_pool = (std::uint8_t*)(pmm::buddy::alloc(KHEAP_SIZE).phys + etc::hhdm()); + heap_block* block = (heap_block*)heap_pool; + block->size = KHEAP_SIZE; + block->is_free = 1; + block->next = 0; + current = (heap_block*)heap_pool; + heap_end = block; + klibc::printf("KHeap: Available memory %lli bytes\r\n",KHEAP_SIZE); + +} + +int is_early = 1; + +void kheap::opt_free(void* ptr) { + if(!is_early) { + kheap::free(ptr); + return; + } + + if(!ptr) return; + heap_block* block = (heap_block*)((std::uint64_t)ptr - sizeof(heap_block)); + block->is_free = 1; + if (block->next && block->next->is_free) { + block->size += block->next->size; + block->next = block->next->next; + } +} + +void* kheap::opt_malloc(std::size_t size) { + + if(!is_early) { + return kheap::malloc(size); + } + + size = (size + sizeof(heap_block) + 7) & ~7; + + if (1) { + heap_block* block = heap_end; + block->size = size; + block->is_free = 0; + block->next = nullptr; + + heap_end = (heap_block*)((std::uint64_t)heap_end + size); + + return (void*)((std::uint64_t)block + sizeof(heap_block)); + } + return 0; +} + +void kheap::free(void* ptr) { + if(ptr == 0) + return; + + heap_lock.lock(); + + heap_block* block = (heap_block*)((std::uint64_t)ptr - sizeof(heap_block)); + block->is_free = 1; + if (block->next && block->next->is_free) { + block->size += block->next->size; + block->next = block->next->next; + } + + heap_lock.unlock(); + +} + +void* kheap::malloc(std::size_t size) { + + heap_lock.lock(); + + size = (size + sizeof(heap_block) + 7) & ~7; + + if ((std::uint64_t)heap_end + size <= (std::uint64_t)heap_pool + KHEAP_SIZE) { + heap_block* block = heap_end; + block->size = size; + block->is_free = 0; + block->next = nullptr; + + heap_end = (heap_block*)((std::uint64_t)heap_end + size); + + heap_lock.unlock(); + return (void*)((std::uint64_t)block + sizeof(heap_block)); + } + + heap_block* start = current; + do { + if (current->is_free && current->size >= size) { + if (current->size > size + sizeof(heap_block)) { + heap_block* new_block = (heap_block*)((char*)current + size); + new_block->size = current->size - size; + new_block->is_free = 1; + new_block->next = current->next; + + current->size = size; + current->next = new_block; + } + + current->is_free = 0; + void* allocated = (void*)((char*)current + sizeof(heap_block)); + current = current->next ? current->next : (heap_block*)heap_pool; + heap_lock.unlock(); + return allocated; + } + + current = current->next ? current->next : (heap_block*)heap_pool; + } while (current != start); + + heap_lock.unlock(); + return 0; +}
\ No newline at end of file diff --git a/kernel/src/generic/heap.hpp b/kernel/src/generic/heap.hpp new file mode 100644 index 0000000..960087b --- /dev/null +++ b/kernel/src/generic/heap.hpp @@ -0,0 +1,20 @@ +#pragma once +#include <cstdint> + +#define KHEAP_SIZE (16 * 1024 * 1024) +#define HEAP_SIZE KHEAP_SIZE +struct heap_block { + std::uint32_t size; + std::uint16_t is_free; + heap_block* next; +}; + +namespace kheap { + + void* opt_malloc(std::size_t size); + void opt_free(void* ptr); + + void init(); + void* malloc(std::size_t size); + void free(void* ptr); +}
\ No newline at end of file diff --git a/kernel/src/generic/hhdm.hpp b/kernel/src/generic/hhdm.hpp new file mode 100644 index 0000000..edfab3c --- /dev/null +++ b/kernel/src/generic/hhdm.hpp @@ -0,0 +1,8 @@ +#pragma once +#include <generic/bootloader/bootloader.hpp> + +namespace etc { + inline static std::uintptr_t hhdm() { + return bootloader::bootloader->get_hhdm(); + } +}
\ No newline at end of file diff --git a/kernel/src/generic/lock/spinlock.hpp b/kernel/src/generic/lock/spinlock.hpp new file mode 100644 index 0000000..12bbe16 --- /dev/null +++ b/kernel/src/generic/lock/spinlock.hpp @@ -0,0 +1,29 @@ +#include <atomic> +#include <cstdint> + +#include <generic/arch.hpp> + +namespace locks { + class spinlock { + private: + std::atomic_flag flag = ATOMIC_FLAG_INIT; + public: + void lock() { + while (flag.test_and_set(std::memory_order_acquire)) { + arch::pause(); + } + } + + void unlock() { + flag.clear(std::memory_order_release); + } + + bool test() { + return flag.test(); + } + + bool try_lock() { + return !flag.test_and_set(std::memory_order_acquire); + } + }; +};
\ No newline at end of file diff --git a/kernel/src/generic/mm/heap.cpp b/kernel/src/generic/mm/heap.cpp deleted file mode 100644 index e85bb54..0000000 --- a/kernel/src/generic/mm/heap.cpp +++ /dev/null @@ -1,103 +0,0 @@ - -#include <cstdint> -#include <cstddef> - -#include <generic/mm/heap.hpp> -#include <generic/mm/pmm.hpp> -#include <generic/mm/paging.hpp> - -#include <etc/logging.hpp> - -#include <config.hpp> - -#include <generic/locks/spinlock.hpp> - -#include <etc/etc.hpp> - -std::uint8_t* heap_pool; -heap_block_t* heap_end; -heap_block_t* current; - -locks::spinlock heap_lock; - -void memory::heap::init() { - heap_pool = (std::uint8_t*)memory::pmm::_virtual::alloc(KHEAP_SIZE); - heap_block_t* block = (heap_block_t*)heap_pool; - block->size = KHEAP_SIZE; - block->is_free = 1; - block->next = 0; - current = (heap_block_t*)heap_pool; - heap_end = block; - - memory::paging::alwaysmappedadd(Other::toPhys(heap_pool),KHEAP_SIZE); -} - -void memory::heap::lock() { - heap_lock.lock(); -} - -void memory::heap::unlock() { - heap_lock.unlock(); -} - -void memory::heap::free(void* ptr) { - if(ptr == 0) - return; - - heap_lock.lock(); - - heap_block_t* block = (heap_block_t*)((std::uint64_t)ptr - sizeof(heap_block_t)); - block->is_free = 1; - if (block->next && block->next->is_free) { - block->size += block->next->size; - block->next = block->next->next; - } - - heap_lock.unlock(); - -} - -void* memory::heap::malloc(std::uint32_t size) { - - heap_lock.lock(); - - size = (size + sizeof(heap_block_t) + 7) & ~7; - - if ((std::uint64_t)heap_end + size <= (std::uint64_t)heap_pool + KHEAP_SIZE) { - heap_block_t* block = heap_end; - block->size = size; - block->is_free = 0; - block->next = nullptr; - - heap_end = (heap_block_t*)((std::uint64_t)heap_end + size); - - heap_lock.unlock(); - return (void*)((std::uint64_t)block + sizeof(heap_block_t)); - } - - heap_block_t* start = current; - do { - if (current->is_free && current->size >= size) { - if (current->size > size + sizeof(heap_block_t)) { - heap_block_t* new_block = (heap_block_t*)((char*)current + size); - new_block->size = current->size - size; - new_block->is_free = 1; - new_block->next = current->next; - - current->size = size; - current->next = new_block; - } - - current->is_free = 0; - void* allocated = (void*)((char*)current + sizeof(heap_block_t)); - current = current->next ? current->next : (heap_block_t*)heap_pool; - heap_lock.unlock(); - return allocated; - } - - current = current->next ? current->next : (heap_block_t*)heap_pool; - } while (current != start); - - heap_lock.unlock(); - return 0; -} diff --git a/kernel/src/generic/mm/paging.cpp b/kernel/src/generic/mm/paging.cpp deleted file mode 100644 index 5f2f9fe..0000000 --- a/kernel/src/generic/mm/paging.cpp +++ /dev/null @@ -1,245 +0,0 @@ - -#include <cstdint> -#include <generic/mm/pmm.hpp> -#include <generic/mm/heap.hpp> -#include <generic/mm/paging.hpp> -#include <etc/bootloaderinfo.hpp> -#include <etc/logging.hpp> -#include <limine.h> -#include <etc/etc.hpp> - -#include <etc/libc.hpp> - -static void init(); -std::uint64_t kernel_cr3; -alwaysmapped_t* alwmap = 0; - -uint64_t* __paging_next_level(std::uint64_t* table,std::uint16_t idx,std::uint64_t flags,std::uint32_t id) { - if(!(table[idx] & PTE_PRESENT)) - table[idx] = memory::pmm::_physical::allocid(4096,id) | flags; - return (uint64_t*)Other::toVirt(table[idx] & PTE_MASK_VALUE); -} - -uint64_t* __paging_next_level_noalloc(std::uint64_t* table,std::uint16_t idx,std::uint64_t flags,std::uint32_t id) { - if(!(table[idx] & PTE_PRESENT)) - return 0; - return (uint64_t*)Other::toVirt(table[idx] & PTE_MASK_VALUE); -} - -void memory::paging::map(std::uint64_t cr3,std::uint64_t phys,std::uint64_t virt,std::uint64_t flags) { - std::uint64_t align_phys = ALIGNDOWN(phys,4096); - std::uint64_t align_virt = ALIGNDOWN(virt,4096); - std::uint64_t* cr30 = (std::uint64_t*)Other::toVirt(cr3); - std::uint64_t new_flags = PTE_PRESENT | PTE_RW; - if(PTE_INDEX(align_virt,39) < 256) - new_flags |= PTE_USER; - uint64_t* pml3 = __paging_next_level(cr30,PTE_INDEX(align_virt,39),new_flags,0); - uint64_t* pml2 = __paging_next_level(pml3,PTE_INDEX(align_virt,30),new_flags,0); - uint64_t* pml = __paging_next_level(pml2,PTE_INDEX(align_virt,21),new_flags,0); - pml[PTE_INDEX(align_virt,12)] = align_phys | flags; -} - -void memory::paging::mapid(std::uint64_t cr3,std::uint64_t phys,std::uint64_t virt,std::uint64_t flags,std::uint32_t id) { - std::uint64_t align_phys = ALIGNDOWN(phys,4096); - std::uint64_t align_virt = ALIGNDOWN(virt,4096); - std::uint64_t* cr30 = (std::uint64_t*)Other::toVirt(cr3); - std::uint64_t new_flags = PTE_PRESENT | PTE_RW; - if(PTE_INDEX(align_virt,39) < 256) - new_flags |= PTE_USER; - uint64_t* pml3 = __paging_next_level(cr30,PTE_INDEX(align_virt,39),new_flags,id); - uint64_t* pml2 = __paging_next_level(pml3,PTE_INDEX(align_virt,30),new_flags,id); - uint64_t* pml = __paging_next_level(pml2,PTE_INDEX(align_virt,21),new_flags,id); - pml[PTE_INDEX(align_virt,12)] = align_phys | flags; -} - -void memory::paging::change(std::uint64_t cr3, std::uint64_t virt, std::uint64_t flags) { - std::uint64_t align_virt = ALIGNDOWN(virt,4096); - std::uint64_t* cr30 = (std::uint64_t*)Other::toVirt(cr3); - std::uint64_t new_flags = PTE_PRESENT | PTE_RW; - if(PTE_INDEX(align_virt,39) < 256) - new_flags |= PTE_USER; - uint64_t* pml3 = __paging_next_level(cr30,PTE_INDEX(align_virt,39),new_flags,0);//1 - uint64_t* pml2 = __paging_next_level(pml3,PTE_INDEX(align_virt,30),new_flags,0); // 2 - uint64_t* pml = __paging_next_level(pml2,PTE_INDEX(align_virt,21),new_flags,0); // 3 - pml[PTE_INDEX(align_virt,12)] = (pml[PTE_INDEX(align_virt,12)] & PTE_MASK_VALUE) | flags; -} - -std::int64_t __memory_paging_getphys(std::uint64_t cr3, std::uint64_t virt) { - std::uint64_t align_virt = ALIGNDOWN(virt,4096); - std::uint64_t* cr30 = (std::uint64_t*)Other::toVirt(cr3); - if(cr30[PTE_INDEX(virt,39)] & PTE_PRESENT) { - std::uint64_t* pml3 = __paging_next_level_noalloc(cr30,PTE_INDEX(align_virt,39),0,0);//1 - if(pml3[PTE_INDEX(virt,30)] & PTE_PRESENT) { - std::uint64_t* pml2 = __paging_next_level_noalloc(pml3,PTE_INDEX(align_virt,30),0,0); // 2 - if(pml2[PTE_INDEX(virt,21)] & PTE_PRESENT) { - uint64_t* pml = __paging_next_level_noalloc(pml2,PTE_INDEX(align_virt,21),0,0); // 3 - if(pml[PTE_INDEX(align_virt,12)] & PTE_PRESENT) { - return pml[PTE_INDEX(virt,12)] & PTE_MASK_VALUE; - } else { - return -1; - } - } else { - return -1; - } - } else { - return -1; - } - } else { - return -1; - } -} - -void memory::paging::destroyrange(std::uint64_t cr3, std::uint64_t virt, std::uint64_t len) { - for(std::uint64_t i = 0;i < len; i += 4096) { - std::int64_t phys = __memory_paging_getphys(cr3,virt + i); - if(phys != -1 && phys != 0) { - memory::pmm::_physical::free((std::uint64_t)phys); - map(cr3,0,virt + i,0); - } - } -} - -void memory::paging::duplicaterangeifexists(std::uint64_t src_cr3, std::uint64_t dest_cr3, std::uint64_t virt, std::uint64_t len, std::uint64_t flags) { - zerorange(dest_cr3,virt,len); - for(std::uint64_t i = 0;i < len; i += 4096) { - std::int64_t phys = __memory_paging_getphys(src_cr3,virt + i); - if(phys != -1) { - std::uint64_t new_phys = memory::pmm::_physical::alloc(4096); - memcpy(Other::toVirt(new_phys),Other::toVirt(phys),4096); - map(dest_cr3,new_phys,virt + i,flags); - } - } -} - -void memory::paging::changerange(std::uint64_t cr3, std::uint64_t virt, std::uint64_t len , std::uint64_t flags) { - for(std::uint64_t i = 0;i < len; i += 4096) { - change(cr3,virt + i, flags); - } -} - -void memory::paging::maprange(std::uint64_t cr3,std::uint64_t phys,std::uint64_t virt,std::uint64_t len,std::uint64_t flags) { - for(std::uint64_t i = 0; i < len; i += 4096) { - map(cr3,phys + i,virt + i,flags); - } -} - -void* memory::paging::maprangeret(std::uint64_t phys,std::uint64_t len,std::uint64_t flags) { - std::uint64_t virt = (std::uint64_t)Other::toVirt(phys); - for(std::uint64_t i = 0; i < len; i += 4096) { - map(kernel_cr3,phys + i,virt + i,flags); - } - return (void*)Other::toVirt(phys); -} - -void memory::paging::zerorange(std::uint64_t cr3,std::uint64_t virt,std::uint64_t len) { - for(std::uint64_t i = 0; i < len; i += 4096) { - map(cr3,0,virt + i,0); - } -} - -void memory::paging::maprangeid(std::uint64_t cr3,std::uint64_t phys,std::uint64_t virt,std::uint64_t len,std::uint64_t flags, std::uint32_t id) { - for(std::uint64_t i = 0; i < len; i += 4096) { - mapid(cr3,phys + i,virt + i,flags,id); - } -} - -void memory::paging::mapentry(std::uint64_t cr3,std::uint8_t type,std::uint64_t add_flags) { - limine_memmap_response* mmap = BootloaderInfo::AccessMemoryMap(); - limine_memmap_entry* current = mmap->entries[0]; - for(int i = 0;i < mmap->entry_count;i++) { - current = mmap->entries[i]; - if(current->type == type) - maprange(cr3,current->base,(std::uint64_t)Other::toVirt(current->base),current->length,PTE_PRESENT | PTE_RW | add_flags); - } -} - -void* memory::paging::kernelmap(std::uint64_t cr3,std::uint64_t phys) { - map(kernel_cr3,phys,(std::uint64_t)Other::toVirt(phys),PTE_PRESENT | PTE_RW); - return Other::toVirt(phys); -} - -void __paging_map_kernel(std::uint64_t cr3,std::uint32_t id) { - extern std::uint64_t kernel_start; - extern std::uint64_t kernel_end; - limine_executable_address_response* ker = BootloaderInfo::AccessKernel(); - - for(std::uint64_t i = ALIGNDOWN((std::uint64_t)&kernel_start,4096);i < ALIGNUP((std::uint64_t)&kernel_end,4096);i += 4096) { - memory::paging::mapid(cr3,i - ker->virtual_base + ker->physical_base,i,PTE_PRESENT | PTE_RW,0); - } -} - -void memory::paging::mapkernel(std::uint64_t cr3,std::uint32_t id) { - __paging_map_kernel(cr3,id); -} - -void memory::paging::enablekernel() { - asm volatile("mov %0, %%cr3" : : "r"(kernel_cr3) : "memory"); -} - -void memory::paging::enablepaging(std::uint64_t cr3) { - asm volatile("mov %0, %%cr3" : : "r"(cr3) : "memory"); -} - -std::uint64_t memory::paging::kernelget() { - return kernel_cr3; -} - -void __map_range_id(std::uint64_t cr3,std::uint64_t phys,std::uint64_t virt,std::uint64_t len,std::uint64_t flags,std::uint32_t id) { - for(std::uint64_t i = 0; i < len; i += 4096) { - memory::paging::map(cr3,phys + i,virt + i,flags); - } -} - -void memory::paging::alwaysmappedadd(std::uint64_t phys, std::uint64_t len) { - alwaysmapped_t* alw = new alwaysmapped_t; - alw->next = alwmap; - alw->phys = phys; - alw->len = len; - alwmap = alw; -} - -void memory::paging::alwaysmappedmap(std::uint64_t cr3,std::uint32_t id) { - alwaysmapped_t* current = alwmap; - while(current) { - __map_range_id(cr3,current->phys,(std::uint64_t)Other::toVirt(current->phys),current->len,PTE_RW | PTE_PRESENT,id); - current = current->next; - } -} - -void __paging_destroy_table(std::uint64_t phys_table, int level) { - std::uint64_t* table = (std::uint64_t*)Other::toVirt(phys_table); - if(level != 3) { - if(level == 0) { - for(int i = 0; i < 256; i++) { - if(table[i] & PTE_PRESENT) { - __paging_destroy_table(table[i] & PTE_MASK_VALUE,level + 1); - } - } - } else { - for(int i = 0;i < 512; i++) { - if(table[i] & PTE_PRESENT) { - __paging_destroy_table(table[i] & PTE_MASK_VALUE,level + 1); - } - } - } - } - - if(level != 0) - memory::pmm::_physical::free(phys_table); -} - -void memory::paging::destroy(std::uint64_t cr3) { - if(cr3 == kernel_cr3) - return; - __paging_destroy_table(cr3,0); -} - -void memory::paging::init() { - kernel_cr3 = memory::pmm::_physical::alloc(4096); - mapentry(kernel_cr3,LIMINE_MEMMAP_USABLE,0); - mapentry(kernel_cr3,LIMINE_MEMMAP_FRAMEBUFFER,PTE_WC); - mapentry(kernel_cr3,LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE,0); - mapentry(kernel_cr3,LIMINE_MEMMAP_EXECUTABLE_AND_MODULES,0); - mapkernel(kernel_cr3,0); - enablekernel(); -}
\ No newline at end of file diff --git a/kernel/src/generic/mm/pmm.cpp b/kernel/src/generic/mm/pmm.cpp deleted file mode 100644 index 3225854..0000000 --- a/kernel/src/generic/mm/pmm.cpp +++ /dev/null @@ -1,452 +0,0 @@ - -#include <generic/locks/spinlock.hpp> -#include <etc/bootloaderinfo.hpp> -#include <generic/mm/pmm.hpp> -#include <etc/logging.hpp> -#include <etc/libc.hpp> -#include <etc/etc.hpp> -#include <limine.h> -#include <cstddef> -#include <cstdint> - -/* buddy allocator */ - -locks::spinlock pmm_lock; -buddy_t mem; - -buddy_info_t* buddy_find_by_parent(buddy_info_t* blud,char split_x) { - if(split_x) { - for(std::uint64_t i = 0;i < mem.buddy_queue;i++) { - if(mem.mem[i].parent == blud && mem.mem[i].split_x) - return &mem.mem[i]; - } - } else { - for(std::uint64_t i = 0;i < mem.buddy_queue;i++) { - if(mem.mem[i].parent == blud && !mem.mem[i].split_x) - return &mem.mem[i]; - } - } -} - -buddy_info_t* buddy_find_by_phys(std::uint64_t phys) { - for(std::uint64_t i = 0;i < mem.buddy_queue;i++) { - if(mem.mem[i].phys == phys) - return &mem.mem[i]; - } - return 0; -} - -buddy_info_t* buddy_find_by_phys_without_split(std::uint64_t phys) { - for(std::uint64_t i = 0;i < mem.buddy_queue;i++) { - if(mem.mem[i].phys == phys && !mem.mem[i].is_splitted) - return &mem.mem[i]; - } - return 0; -} - -buddy_info_t* memory::buddy::put(std::uint64_t phys, std::uint8_t level) { - buddy_info_t* blud = &mem.mem[mem.buddy_queue++]; - blud->level = level; - blud->phys = phys; - blud->is_free = 1; - blud->is_splitted = 0; - blud->is_was_splitted = 0; - blud->parent = 0; - blud->split_x = 0; - return blud; -} - -buddy_info_t* memory::buddy::split_maximum(buddy_info_t* blud, std::uint64_t size) { - if((size <= LEVEL_TO_SIZE(blud->level) && LEVEL_TO_SIZE(blud->level - 1) < size) || LEVEL_TO_SIZE(blud->level) == 4096) - return blud; - return split_maximum(split(blud).first,size); -} - -void memory::buddy::merge(buddy_info_t* budy) { - buddy_info_t* bl = budy; - buddy_info_t* ud = budy->twin; - if(!bl || !ud || !bl->is_free || !ud->is_free) - return; - - buddy_info_t* blud = budy->parent; - bl->is_free = 0; - ud->is_free = 0; - blud->is_splitted = 0; - blud->is_was_splitted = 1; - blud->is_free = 1; - blud->id = 0; - bl->id = 0; - ud->id = 0; - if(blud->parent) - merge(blud); - return; -} - -buddy_split_t memory::buddy::split(buddy_info_t* info) { - if(!info || LEVEL_TO_SIZE(info->level) == 4096 || !info->is_free) - return {info,info}; - buddy_info_t* bl = 0; - buddy_info_t* ud = 0; - if(!info->is_was_splitted) { - bl = put(info->phys,info->level - 1); - ud = put(info->phys + LEVEL_TO_SIZE(info->level - 1), info->level - 1); - bl->split_x = 0; - bl->is_free = 1; - ud->split_x = 1; - ud->is_free = 1; - bl->parent = info; - ud->parent = info; - bl->twin = ud; - ud->twin = bl; - } else { - bl = buddy_find_by_parent(info,0); - ud = bl->twin; - bl->is_free = 1; - ud->is_free = 1; - } - info->is_splitted = 1; - info->is_free = 0; - info->is_was_splitted = 1; - return {bl,ud}; -} - -int __buddy_align_power(uint64_t number) { - if (number == 0) return 0; - - uint64_t power = 12; - - while (LEVEL_TO_SIZE(power) <= number && power < MAX_LEVEL) { - power++; - } - - return power - 1; -} - -void memory::buddy::init() { - limine_memmap_response* mmap = BootloaderInfo::AccessMemoryMap(); - limine_memmap_entry* current = mmap->entries[0]; - std::uint64_t top,top_size,total_pages; - top = 0; - top_size = 0; - total_pages = 0; - total_pages = 0; - for(int i = 0;i < mmap->entry_count; i++) { - current = mmap->entries[i]; - if(current->type == LIMINE_MEMMAP_USABLE) { - total_pages += current->length / 4096; - if(current->length > top_size) { - top = current->base; - top_size = current->length; - } - } - } - - std::uint64_t buddy_size = (total_pages * sizeof(buddy_info_t)); - - memset(&mem,0,sizeof(buddy_t)); - mem.mem = (buddy_info_t*)Other::toVirt(top); - memset(mem.mem,0,buddy_size); - - mem.buddy_queue = 0; - - for(int i = 0;i < mmap->entry_count; i++) { - current = mmap->entries[i]; - if(current->type == LIMINE_MEMMAP_USABLE) { - std::int64_t new_len = 0; - std::uint64_t new_base = 0; - new_len = current->length; - new_base = current->base; - if(new_base == top) { - new_len = top_size - buddy_size; - new_base = ALIGNUP(top + buddy_size,4096); - } - while(new_len > 4096) { - auto blud = put(new_base,__buddy_align_power(new_len)); - new_base += LEVEL_TO_SIZE(__buddy_align_power(new_len)); - new_len -= LEVEL_TO_SIZE(__buddy_align_power(new_len)); - } - } - } - -} - -int memory::buddy::free(std::uint64_t phys) { - auto blud = buddy_find_by_phys_without_split(phys); - if(!blud || blud->is_splitted) - return -1; - blud->is_free = 1; - blud->id = 0; - if(blud->parent) - merge(blud); - return 0; -} - -int last_i = 0; - -std::int64_t memory::buddy::alloc(std::size_t size) { - std::uint64_t top_size = UINT64_MAX; - buddy_info_t* nearest_buddy = 0; - - if(size < 4096) - size = 4096; - - for(std::uint64_t i = 0;i < mem.buddy_queue; i++) { - if(LEVEL_TO_SIZE(mem.mem[i].level) >= size && LEVEL_TO_SIZE(mem.mem[i].level) < top_size && mem.mem[i].is_free) { - top_size = LEVEL_TO_SIZE(mem.mem[i].level); - nearest_buddy = &mem.mem[i]; - if(top_size == size) { - last_i = i; break; } - } - } - -found: - if(nearest_buddy) { - auto blud = split_maximum(nearest_buddy,size); - blud->is_free = 0; - memset(Other::toVirt(blud->phys),0,LEVEL_TO_SIZE(blud->level)); - return blud->phys; - } - - assert(0,"There's no memory !"); - return 0; - -} - -alloc_t memory::buddy::alloc_ext(std::size_t size) { - std::uint64_t top_size = UINT64_MAX; - buddy_info_t* nearest_buddy = 0; - - if(size < 4096) - size = 4096; - - for(std::uint64_t i = 0;i < mem.buddy_queue; i++) { - if(LEVEL_TO_SIZE(mem.mem[i].level) >= size && LEVEL_TO_SIZE(mem.mem[i].level) < top_size && mem.mem[i].is_free) { - top_size = LEVEL_TO_SIZE(mem.mem[i].level); - nearest_buddy = &mem.mem[i]; - if(top_size == size) - break; - } - } - - if(nearest_buddy) { - auto blud = split_maximum(nearest_buddy,size); - blud->is_free = 0; - memset(Other::toVirt(blud->phys),0,LEVEL_TO_SIZE(blud->level)); - - alloc_t result; - result.real_size = LEVEL_TO_SIZE(blud->level); - result.virt = blud->phys; - - return result; - } - - assert(0,"There's no memory !"); - return {0,0}; -} - -std::int64_t memory::buddy::allocid(std::size_t size,std::uint32_t id0) { - std::uint64_t top_size = UINT64_MAX; - buddy_info_t* nearest_buddy = 0; - - if(size < 4096) - size = 4096; - - for(std::uint64_t i = 0;i < mem.buddy_queue; i++) { - if(LEVEL_TO_SIZE(mem.mem[i].level) >= size && LEVEL_TO_SIZE(mem.mem[i].level) < top_size && mem.mem[i].is_free) { - top_size = LEVEL_TO_SIZE(mem.mem[i].level); - nearest_buddy = &mem.mem[i]; - if(top_size == size) - break; - } - } - - if(nearest_buddy) { - auto blud = split_maximum(nearest_buddy,size); - blud->is_free = 0; - blud->id = id0; - memset(Other::toVirt(blud->phys),0,LEVEL_TO_SIZE(blud->level)); - return blud->phys; - } - - assert(0,"There's no memory !"); - return 0; -} - -void memory::buddy::fullfree(std::uint32_t id) { - for(std::uint64_t i = 0;i < mem.buddy_queue; i++) { - if(mem.mem[i].id == id) { - //free(mem.mem[i].phys); - } - } -} - -/* freelist allocator */ - -template <int N> -struct freelist_allocated_memory { - std::uint64_t arr[131072]; -}; - -template <int N> -struct memory_id_block { - std::uint64_t phys_block[N]; - struct memory_id_block* next; -}; - -typedef struct memory_id_block<4> memory_id_t; - -typedef struct freelist_allocated_memory<1048576> freelist_allocated_memory_t; - -std::uint64_t freelist_page = 0; - -freelist_allocated_memory_t freelist_aloc_mem; -int freelist_aloc_mem_ptr = 0; - -int memory::freelist::free(std::uint64_t phys) { - if(phys == 0) - return -1; - // sorry but my freelist free is O(n) :( - - int success = 0; - - //Log::SerialDisplay(LEVEL_MESSAGE_INFO,"freelist: free 0x%p\n",phys); - - for(int i = 0; i < freelist_aloc_mem_ptr; i++) { - if(phys >= freelist_aloc_mem.arr[i] && phys < freelist_aloc_mem.arr[i] + (1024 * 1024)) { - success = 1; - break; - } - } - - if(!success) { - return -1; // not free list memory, ignore - } - - memset(Other::toVirt(phys),0,4096); - - *((std::uint64_t*)Other::toVirt(phys)) = freelist_page; - freelist_page = phys; - return 0; -} - -std::int64_t memory::freelist::alloc() { - if(!freelist_page) { // request memory from buddy, 1 mb will be enough - std::uint64_t phys = memory::buddy::alloc(1024 * 1024 * 4); - - freelist_aloc_mem.arr[freelist_aloc_mem_ptr++] = phys; - - std::uint64_t ptr = phys; - while(1) { - if(ptr >= phys + (1024 * 1024 * 4)) - break; - free(ptr); - ptr += 4096; - } - } - std::uint64_t freelist_mem = freelist_page; - - freelist_page = *((std::uint64_t*)Other::toVirt(freelist_mem)); - - memset(Other::toVirt(freelist_mem),0,4096); - return freelist_mem; -} - -/* pmm wrapper */ - -void memory::pmm::_physical::init() { - memset(&freelist_aloc_mem,0,sizeof(freelist_aloc_mem)); - memory::buddy::init(); -} - -int __is_in_freelist_array(std::uint64_t phys) { - for(int i = 0;i < freelist_aloc_mem_ptr; i++) { - if(phys >= freelist_aloc_mem.arr[i] && phys < freelist_aloc_mem.arr[i] + (1024 * 1024)) - return 1; - } - return 0; -} - -void memory::pmm::_physical::free(std::uint64_t phys) { - return; - asm volatile("cli"); - pmm_lock.lock(); - int status = -1; - if(!__is_in_freelist_array(phys)) // not used by freelist ? - status = memory::buddy::free(phys); - if(status != 0) - memory::freelist::free(phys); - pmm_lock.unlock(); -} - -void memory::pmm::_physical::fullfree(std::uint32_t id) { - pmm_lock.lock(); - memory::buddy::fullfree(id); - pmm_lock.unlock(); -} - -std::int64_t memory::pmm::_physical::alloc(std::size_t size) { - asm volatile("cli"); - pmm_lock.lock(); - std::int64_t p = 0; - if(size <= 4096) { // sure we can do freelist optimization - p = memory::freelist::alloc(); - } else { - p = memory::buddy::alloc(size); - } - pmm_lock.unlock(); - return p; -} - -std::int64_t memory::pmm::_physical::allocid(std::size_t size, std::uint32_t id) { - asm volatile("cli"); - pmm_lock.lock(); - std::int64_t p = 0; - if(size <= 4096) { // sure we can do freelist optimization - p = memory::freelist::alloc(); - } else { - p = memory::buddy::allocid(size,id); - } - pmm_lock.unlock(); - return p; -} - -void memory::pmm::_physical::lock() { - pmm_lock.lock(); -} - -void memory::pmm::_physical::unlock() { - pmm_lock.unlock(); -} - -void memory::pmm::_virtual::free(void* virt) { - memory::pmm::_physical::free(Other::toPhys(virt)); -} - -void* memory::pmm::_virtual::alloc(std::size_t size) { - asm volatile("cli"); - return Other::toVirt(memory::pmm::_physical::alloc(size)); -} - -alloc_t memory::pmm::_physical::alloc_ext(std::size_t size) { - asm volatile("cli"); - pmm_lock.lock(); - alloc_t result; - if(size <= 4096) { - result.real_size = 4096; - result.virt = memory::freelist::alloc(); - } else - result = memory::buddy::alloc_ext(size); - result.virt = (std::uint64_t)Other::toVirt(result.virt); - pmm_lock.unlock(); - return result; -} - -/* some helper functions */ - -#include <generic/mm/paging.hpp> - -std::uint64_t memory::pmm::helper::alloc_kernel_stack(std::size_t size) { - std::uint64_t stack = memory::pmm::_physical::alloc(size); /* extra page */ - memory::paging::alwaysmappedadd(stack,size); - return (std::uint64_t)Other::toVirt(stack) + size; -}
\ No newline at end of file diff --git a/kernel/src/generic/paging.cpp b/kernel/src/generic/paging.cpp new file mode 100644 index 0000000..5605e14 --- /dev/null +++ b/kernel/src/generic/paging.cpp @@ -0,0 +1,85 @@ +#include <cstdint> +#include <generic/arch.hpp> +#include <generic/pmm.hpp> +#include <generic/hhdm.hpp> +#include <klibc/string.hpp> +#include <generic/bootloader/bootloader.hpp> +#include <utils/align.hpp> +#include <utils/gobject.hpp> +#include <klibc/stdio.hpp> +#include <generic/paging.hpp> + +void __map_kernel(std::uintptr_t root) { + extern std::uint64_t kernel_start; + extern std::uint64_t kernel_end; + std::uint64_t virt_base = bootloader::bootloader->get_kernel_virt(); + std::uint64_t phys_base = bootloader::bootloader->get_kernel_phys(); + + for (std::uint64_t i = ALIGNDOWN((std::uint64_t) &kernel_start, 4096); i < ALIGNUP((std::uint64_t) &kernel_end, 4096); i += 4096) { + paging::map_range(root, i - virt_base + phys_base, i, PAGE_SIZE, PAGING_PRESENT | PAGING_RW); + } +} + +namespace paging { + + void map_kernel(std::uintptr_t root) { + return __map_kernel(root); + } + + void mapentry(std::uintptr_t root, std::uint8_t type, std::uint32_t flags) { + limine_memmap_response* mmap = bootloader::bootloader->get_memory_map(); + limine_memmap_entry* current = mmap->entries[0]; + for (uint64_t i = 0; i < mmap->entry_count; i++) { + current = mmap->entries[i]; + if (current->type == type) + paging::map_range(root, current->base, current->base + etc::hhdm(), current->length, PAGING_PRESENT | PAGING_RW | flags); + } + } + + + void map_range(std::uintptr_t root, std::uint64_t phys, std::uintptr_t virt, std::size_t size, int flags) { + for(std::size_t i = 0;i < size;i += PAGE_SIZE) { + arch::map_page(root,phys + i, virt + i, flags); + } + } + + void zero_range(std::uintptr_t root, std::uintptr_t virt, std::size_t size) { + for(std::size_t i = 0;i < size;i += PAGE_SIZE) { + arch::map_page(root,0, virt + i, 0); + } + } + + void free_range(std::uintptr_t root, std::uintptr_t virt, std::uintptr_t len) { + for (std::uint64_t i = 0; i < len; i += 4096) { + std::int64_t phys = arch::get_phys_from_page(root, virt + i); + if (phys != -1 && phys != 0) { + pmm::freelist::free((std::uint64_t) phys); + arch::map_page(root, 0, virt + i, 0); + } + } + } + + void duplicate_range(std::uintptr_t root, std::uintptr_t src_root, std::uintptr_t virt, std::uintptr_t len, std::uint32_t flags) { + zero_range(root, virt, len); + for (std::uint64_t i = 0; i < len; i += 4096) { + std::int64_t phys = arch::get_phys_from_page(src_root, virt + i); + if (phys != -1) { + std::uint64_t new_phys = pmm::freelist::alloc_4k(); + klibc::memcpy((void*)(new_phys + etc::hhdm()), (void*) (phys + etc::hhdm()), 4096); + arch::map_page(root, new_phys, virt + i, flags); + } + } + } + + void init() { + std::uintptr_t kernel_root = pmm::freelist::alloc_4k(); + gobject::kernel_root = kernel_root; + mapentry(kernel_root, LIMINE_MEMMAP_USABLE, 0); + mapentry(kernel_root, LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE, 0); + mapentry(kernel_root, LIMINE_MEMMAP_FRAMEBUFFER, PAGING_WC); + mapentry(kernel_root, LIMINE_MEMMAP_EXECUTABLE_AND_MODULES, 0); + map_kernel(kernel_root); + arch::enable_paging(kernel_root); + klibc::printf("Paging: Enabled kernel root with %d level paging\n\r", arch::level_paging()); + } +}; diff --git a/kernel/src/generic/paging.hpp b/kernel/src/generic/paging.hpp new file mode 100644 index 0000000..56e88cc --- /dev/null +++ b/kernel/src/generic/paging.hpp @@ -0,0 +1,20 @@ +#pragma once +#include <cstdint> +#include <generic/arch.hpp> +#include <generic/pmm.hpp> +#include <generic/hhdm.hpp> +#include <klibc/string.hpp> +#include <generic/bootloader/bootloader.hpp> +#include <utils/align.hpp> +#include <utils/gobject.hpp> +#include <klibc/stdio.hpp> + +namespace paging { + void map_kernel(std::uintptr_t root); + void mapentry(std::uintptr_t root, std::uint8_t type, std::uint32_t flags); + void map_range(std::uintptr_t root, std::uint64_t phys, std::uintptr_t virt, std::size_t size, int flags); + void zero_range(std::uintptr_t root, std::uintptr_t virt, std::size_t size); + void free_range(std::uintptr_t root, std::uintptr_t virt, std::uintptr_t len); + void duplicate_range(std::uintptr_t root, std::uintptr_t src_root, std::uintptr_t virt, std::uintptr_t len, std::uint32_t flags); + void init(); +}; diff --git a/kernel/src/generic/pmm.cpp b/kernel/src/generic/pmm.cpp new file mode 100644 index 0000000..01d38f0 --- /dev/null +++ b/kernel/src/generic/pmm.cpp @@ -0,0 +1,270 @@ +#include <cstdint> +#include <generic/pmm.hpp> +#include <generic/bootloader/bootloader.hpp> +#include <generic/lock/spinlock.hpp> +#include <generic/hhdm.hpp> +#include <klibc/string.hpp> +#include <klibc/stdio.hpp> +#include <utils/align.hpp> +#include <atomic> + +locks::spinlock pmm_lock; +std::uint64_t* freelist_hhdm = 0; +std::size_t memory_size = 0; + +buddy_t mem; + +buddy_info_t* buddy_find_by_parent(buddy_info_t* blud,char split_x) { + if(split_x) { + for(std::uint64_t i = 0;i < mem.buddy_queue;i++) { + if(mem.mem[i].parent == blud && mem.mem[i].split_x) + return &mem.mem[i]; + } + } else { + for(std::uint64_t i = 0;i < mem.buddy_queue;i++) { + if(mem.mem[i].parent == blud && !mem.mem[i].split_x) + return &mem.mem[i]; + } + } + return nullptr; +} + +buddy_info_t* buddy_find_by_phys(std::uint64_t phys) { + for(std::uint64_t i = 0;i < mem.buddy_queue;i++) { + if(mem.mem[i].phys == phys) + return &mem.mem[i]; + } + return 0; +} + +buddy_info_t* buddy_find_by_phys_without_split(std::uint64_t phys) { + for(std::uint64_t i = 0;i < mem.buddy_queue;i++) { + if(mem.mem[i].phys == phys && !mem.mem[i].is_splitted) + return &mem.mem[i]; + } + return 0; +} + +buddy_info_t* pmm::buddy::put(std::uint64_t phys, std::uint8_t level) { + buddy_info_t* blud = &mem.mem[mem.buddy_queue++]; + blud->level = level; + blud->phys = phys; + blud->is_free = 1; + blud->is_splitted = 0; + blud->is_was_splitted = 0; + blud->parent = 0; + blud->split_x = 0; + return blud; +} + +buddy_info_t* pmm::buddy::split_maximum(buddy_info_t* blud, std::uint64_t size) { + if((size <= LEVEL_TO_SIZE(blud->level) && LEVEL_TO_SIZE(blud->level - 1) < size) || LEVEL_TO_SIZE(blud->level) == 4096) + return blud; + return split_maximum(split(blud).first,size); +} + +void pmm::buddy::merge(buddy_info_t* budy) { + buddy_info_t* bl = budy; + buddy_info_t* ud = budy->twin; + if(!bl || !ud || !bl->is_free || !ud->is_free) + return; + + buddy_info_t* blud = budy->parent; + bl->is_free = 0; + ud->is_free = 0; + blud->is_splitted = 0; + blud->is_was_splitted = 1; + blud->is_free = 1; + blud->id = 0; + bl->id = 0; + ud->id = 0; + if(blud->parent) + merge(blud); + return; +} + +buddy_split_t pmm::buddy::split(buddy_info_t* info) { + if(!info || LEVEL_TO_SIZE(info->level) == 4096 || !info->is_free) + return {info,info}; + buddy_info_t* bl = 0; + buddy_info_t* ud = 0; + if(!info->is_was_splitted) { + bl = put(info->phys,info->level - 1); + ud = put(info->phys + LEVEL_TO_SIZE(info->level - 1), info->level - 1); + bl->split_x = 0; + bl->is_free = 1; + ud->split_x = 1; + ud->is_free = 1; + bl->parent = info; + ud->parent = info; + bl->twin = ud; + ud->twin = bl; + } else { + bl = buddy_find_by_parent(info,0); + ud = bl->twin; + bl->is_free = 1; + ud->is_free = 1; + } + info->is_splitted = 1; + info->is_free = 0; + info->is_was_splitted = 1; + return {bl,ud}; +} + +int __buddy_align_power(uint64_t number) { + if (number == 0) return 0; + + uint64_t power = 12; + + while (LEVEL_TO_SIZE(power) <= number && power < MAX_LEVEL) { + power++; + } + + return power - 1; +} + +void pmm::buddy::init() { + limine_memmap_response* mmap = bootloader::bootloader->get_memory_map(); + limine_memmap_entry* current = mmap->entries[0]; + std::uint64_t top,top_size,total_pages; + top = 0; + top_size = 0; + total_pages = 0; + total_pages = 0; + for(std::size_t i = 0;i < mmap->entry_count; i++) { + current = mmap->entries[i]; + if(current->type == LIMINE_MEMMAP_USABLE) { + total_pages += current->length / 4096; + memory_size += current->length; + if(current->length > top_size) { + top = current->base; + top_size = current->length; + } + } + } + + std::uint64_t buddy_size = (total_pages * sizeof(buddy_info_t)); + + klibc::memset(&mem,0,sizeof(buddy_t)); + mem.mem = (buddy_info_t*)(top + etc::hhdm()); + klibc::memset(mem.mem,0,buddy_size); + + mem.buddy_queue = 0; + + for(std::size_t i = 0;i < mmap->entry_count; i++) { + current = mmap->entries[i]; + if(current->type == LIMINE_MEMMAP_USABLE) { + std::int64_t new_len = 0; + std::uint64_t new_base = 0; + new_len = current->length; + new_base = current->base; + if(new_base == top) { + new_len = top_size - buddy_size; + new_base = ALIGNUP(top + buddy_size,4096); + } + while(new_len > 4096) { + put(new_base,__buddy_align_power(new_len)); + new_base += LEVEL_TO_SIZE(__buddy_align_power(new_len)); + new_len -= LEVEL_TO_SIZE(__buddy_align_power(new_len)); + } + } + } + +} + +int pmm::buddy::nlfree(std::uint64_t phys) { + auto blud = buddy_find_by_phys_without_split(phys); + if(!blud || blud->is_splitted) + return -1; + blud->is_free = 1; + blud->id = 0; + if(blud->parent) + merge(blud); + return 0; +} + +alloc_t pmm::buddy::nlalloc_ext(std::size_t size) { + std::uint64_t top_size = UINT64_MAX; + buddy_info_t* nearest_buddy = 0; + + if(size < 4096) + size = 4096; + + for(std::uint64_t i = 0;i < mem.buddy_queue; i++) { + if(LEVEL_TO_SIZE(mem.mem[i].level) >= size && LEVEL_TO_SIZE(mem.mem[i].level) < top_size && mem.mem[i].is_free) { + top_size = LEVEL_TO_SIZE(mem.mem[i].level); + nearest_buddy = &mem.mem[i]; + if(top_size == size) + break; + } + } + + if(nearest_buddy) { + auto blud = split_maximum(nearest_buddy,size); + blud->is_free = 0; + klibc::memset((void*)(blud->phys + etc::hhdm()),0,LEVEL_TO_SIZE(blud->level)); + + alloc_t result; + result.real_size = LEVEL_TO_SIZE(blud->level); + result.phys = blud->phys; + + return result; + } + + klibc::printf("There's no memory !\n\r"); + return {0,0}; +} + +alloc_t pmm::buddy::alloc(std::size_t size) { + pmm_lock.lock(); + alloc_t res = pmm::buddy::nlalloc_ext(size); + pmm_lock.unlock(); + return res; +} + +int pmm::buddy::free(std::uint64_t phys) { + pmm_lock.lock(); + int res = pmm::buddy::nlfree(phys); + pmm_lock.unlock(); + return res; +} + +void pmm::init() { + buddy::init(); + klibc::printf("PMM: Total usable memory: %lli bytes\r\n",memory_size); +} + +std::uint64_t pmm::freelist::alloc_4k() { + pmm_lock.lock(); + + if(!freelist_hhdm) { // request memory from buddy, 4 mb will be enough + alloc_t res = buddy::nlalloc_ext(1024 * 1024 * 4); + std::uint64_t phys = res.phys; + + std::uint64_t ptr = phys; + while(1) { + if(ptr >= phys + (1024 * 1024 * 4)) + break; + freelist::nlfree(ptr); + ptr += PAGE_SIZE; + } + } + + std::uint64_t mem = (std::uint64_t)freelist_hhdm - etc::hhdm(); + freelist_hhdm = (std::uint64_t*)(*freelist_hhdm); + klibc::memset((void*)(mem + etc::hhdm()),0,PAGE_SIZE); + pmm_lock.unlock(); + return mem; +} + +void pmm::freelist::nlfree(std::uint64_t phys) { + std::uint64_t virt = phys + etc::hhdm(); + *(std::uint64_t**)virt = freelist_hhdm; + freelist_hhdm = (std::uint64_t*)virt; +} + +void pmm::freelist::free(std::uint64_t phys) { + pmm_lock.lock(); + freelist::nlfree(phys); + pmm_lock.unlock(); +}
\ No newline at end of file diff --git a/kernel/src/generic/pmm.hpp b/kernel/src/generic/pmm.hpp new file mode 100644 index 0000000..d3279a9 --- /dev/null +++ b/kernel/src/generic/pmm.hpp @@ -0,0 +1,66 @@ +#pragma once + +#include <cstdint> + +#define LEVEL_TO_SIZE(level) (1U << (level)) +#define MAX_LEVEL 32 + +typedef struct buddy_info { + union { + struct { + std::uint16_t level : 8; + std::uint16_t is_was_splitted : 1; + std::uint16_t is_splitted : 1; + std::uint16_t is_free : 1; + std::uint16_t split_x : 1; + }; + std::uint16_t buddy_info_raw; + }; + struct buddy_info* parent; + struct buddy_info* twin; + std::uint32_t id; + std::uint64_t phys; +} __attribute__((packed)) buddy_info_t; + +typedef struct { + buddy_info_t* first; + buddy_info_t* second; +} buddy_split_t; + +typedef struct { + uint64_t buddy_queue; + uint64_t total_size; + buddy_info_t* mem; +} __attribute__((packed)) buddy_t; + +typedef struct { + std::uint64_t phys; + std::uint64_t real_size; //optimization for tmpfs +} alloc_t; + + +namespace pmm { + void init(); + + class buddy { + private: + static buddy_info_t* split_maximum(buddy_info_t* blud, std::uint64_t size); + static buddy_info_t* put(std::uint64_t phys, std::uint8_t level); + static buddy_split_t split(buddy_info_t* info); + static void merge(buddy_info_t* budy); + public: + static void init(); + static int nlfree(std::uint64_t phys); + static alloc_t nlalloc_ext(std::size_t size); + + static alloc_t alloc(std::size_t size); + static int free(std::uint64_t phys); + + }; + + namespace freelist { + std::uint64_t alloc_4k(); + void free(std::uint64_t phys); + void nlfree(std::uint64_t phys); + }; +};
\ No newline at end of file diff --git a/kernel/src/generic/time.cpp b/kernel/src/generic/time.cpp deleted file mode 100644 index 58cfa1d..0000000 --- a/kernel/src/generic/time.cpp +++ /dev/null @@ -1,36 +0,0 @@ - -#include <generic/time.hpp> -#include <cstdint> - -#include <drivers/tsc.hpp> -#include <drivers/kvmtimer.hpp> -#include <drivers/hpet.hpp> - -std::uint64_t time::counter() { - extern std::uint16_t KERNEL_GOOD_TIMER; - switch(KERNEL_GOOD_TIMER) { - case TSC_TIMER: - return drivers::tsc::currentnano(); - case KVM_TIMER: - return drivers::kvmclock::currentnano(); - case HPET_TIMER: - return drivers::hpet::nanocurrent(); - - } -} - -void time::sleep(std::uint64_t us) { - extern std::uint16_t KERNEL_GOOD_TIMER; - switch(KERNEL_GOOD_TIMER) { - case TSC_TIMER: - drivers::tsc::sleep(us); - break; - case KVM_TIMER: - drivers::kvmclock::sleep(us); - break; - case HPET_TIMER: - drivers::hpet::sleep(us); - break; - } - return; -}
\ No newline at end of file diff --git a/kernel/src/generic/time.hpp b/kernel/src/generic/time.hpp new file mode 100644 index 0000000..a3653cc --- /dev/null +++ b/kernel/src/generic/time.hpp @@ -0,0 +1,27 @@ +#pragma once +#include <cstdint> +#include <klibc/stdio.hpp> + +namespace time { + class generic_timer { + public: + virtual int get_priority() = 0; + + virtual std::uint64_t current_nano() = 0; + virtual void sleep(std::uint64_t us) = 0; + }; + + inline generic_timer* timer = nullptr; + inline generic_timer* previous_timer = nullptr; + + inline void setup_timer(generic_timer* ztimer) { + if(!time::timer) { + time::timer = ztimer; + } else { + if(time::timer->get_priority() < ztimer->get_priority()) { + time::previous_timer = time::timer; + time::timer = ztimer; + } + } + } +}
\ No newline at end of file diff --git a/kernel/src/generic/vfs/devfs.cpp b/kernel/src/generic/vfs/devfs.cpp deleted file mode 100644 index ffe503e..0000000 --- a/kernel/src/generic/vfs/devfs.cpp +++ /dev/null @@ -1,1019 +0,0 @@ - -#include <generic/vfs/vfs.hpp> -#include <cstdint> - -#include <generic/vfs/devfs.hpp> - -#include <generic/mm/pmm.hpp> - -#include <etc/libc.hpp> -#include <etc/logging.hpp> - -#include <generic/mm/paging.hpp> - -#include <drivers/ioapic.hpp> -#include <arch/x86_64/interrupts/irq.hpp> - -#include <etc/assembly.hpp> - -#include <etc/errno.hpp> - -vfs::devfs_node_t* __devfs_head; - -int dev_num = 0; -int is_slave = 0; - -bool isdigit(char ch) { - return ch >= '0' && ch <= '9'; -} - -long reverse_number(long num) { - long reversed_num = 0; - - while(num > 0) { - int digit = num % 10; - reversed_num = reversed_num * 10 + digit; - num /= 10; - } - - return reversed_num; -} - - -vfs::devfs_node_t* devfs_find_dev(char* loc) { - - vfs::devfs_node_t* dev = __devfs_head; - char temp[256]; - int len = strlen((char*)loc); - int i = len - 1; - - dev_num = 0; - - while (i >= 0 && isdigit(loc[i])) { - dev_num = dev_num * 10 + (loc[i] - '0'); - i--; - } - - dev_num = reverse_number(dev_num); - - memcpy(temp, loc, i + 1); - temp[i + 1] = '\0'; - - while (dev) { - if (!strcmp(temp, dev->slavepath) && dev_num == dev->dev_num) { - is_slave = 1; - return dev; - } else if(!strcmp(temp,dev->masterpath) && dev_num == dev->dev_num) { - is_slave = 0; - return dev; - } - dev = dev->next; - } - - return 0; -} - -std::int32_t __devfs__open(userspace_fd_t* fd, char* path) { - vfs::devfs_node_t* node = devfs_find_dev(path); - - if(!node) - return ENOENT; - - if(node->open) - return node->open(fd,path); - - if(!node->open_flags.is_pipe && !node->readring) - return 0; - - if(node->open_flags.is_pipe) { - fd->pipe = (vfs::pipe*)(node->pipe0 | (((uint64_t)node->pipe0 & (1 << 62)) << 63)); - fd->state = USERSPACE_FD_STATE_PIPE; - fd->pipe_side = (node->pipe0 & (1 << 63)) ? PIPE_SIDE_WRITE : PIPE_SIDE_READ; - } else { - fd->queue = is_slave == 1 ? node->readring->ring.tail : node->writering->ring.tail; - fd->cycle = is_slave == 1 ? node->readring->ring.cycle : node->writering->ring.cycle; - } - - fd->is_a_tty = node->is_tty; - fd->other_state = is_slave == 1 ? USERSPACE_FD_OTHERSTATE_SLAVE : USERSPACE_FD_OTHERSTATE_MASTER; - return 0; -} - -int is_printable(char c) { - return (c >= 32 && c <= 126) || c == 10; -} - -std::int64_t __devfs__write(userspace_fd_t* fd, char* path, void* buffer, std::uint64_t size) { - - vfs::devfs_node_t* node = devfs_find_dev(path); - - if(!node) { vfs::vfs::unlock(); - return -ENOENT; } - - if(node->write) - return node->write(fd,buffer,size); - - if(is_slave == 1 && node->slave_write) - return node->slave_write(fd,buffer,size); - - if(node->is_tty && !is_slave) { // handle stdio logic from /dev/pty writing - vfs::vfs::unlock(); - for(int i = 0;i < size;i++) { - - - - char c = ((char*)buffer)[i]; - - if(!(node->term_flags->c_lflag & ICANON)) { - if(c == '\n') c = 13; - } - - if((node->term_flags->c_lflag & ECHO) && (is_printable(c) || c == 13)) { - if(c == 13) { - node->writepipe->write("\n",1,0); - } else if(c == '\n') - node->writepipe->write("\r",1,0); - asm volatile("cli"); - node->writepipe->write(&((char*)buffer)[i],1,0); - asm volatile("cli"); - } - - if(c == '\b' || c == '\x7f' || c == '\x08') { - if(node->readpipe->size > 0) { - if(node->term_flags->c_lflag & ECHO) { - const char* back = "\b \b"; - node->writepipe->write(back,strlen(back),0); - asm volatile("cli"); - } - node->readpipe->lock.lock(); - node->readpipe->read_counter--; - node->readpipe->buffer[node->readpipe->size--] = '\0'; - node->readpipe->lock.unlock(); - } - } - - if(is_printable(c) || !(node->term_flags->c_lflag & ICANON)) { - node->readpipe->write(&c,1,0); - asm volatile("cli"); - } else if(c == 13) { - node->readpipe->write("\n",1,0); - asm volatile("cli"); - } - - if((c == '\n' || c == 13) && (node->term_flags->c_lflag & ICANON)) { - node->readpipe->set_tty_ret(); - } - - if(!(node->term_flags->c_lflag & ICANON) && node->readpipe->size >= node->term_flags->c_cc[VMIN]) { - node->readpipe->set_tty_ret(); - } - - asm volatile("cli"); - } - return size; - } else if(node->is_tty && is_slave) { - vfs::vfs::unlock(); - for(int i = 0;i < size;i++) { - char c = ((char*)buffer)[i]; - if(c == '\n') { - node->writepipe->write("\r\n",2,0); - } else - node->writepipe->write(&c,1,0); - asm volatile("cli"); - } - return size; - } - - std::uint64_t status; - int is_master = !is_slave; - if(node->open_flags.is_pipe_rw) { - vfs::vfs::unlock(); - status = is_master ? node->readpipe->write((char*)buffer,size,0) : node->writepipe->write((char*)buffer,size,0); - } else { - if(!is_master) { - if(node->writering->ring.bytelen == 1) { - node->writering->send(*(char*)buffer); - } else if(node->writering->ring.bytelen == 2) { - node->writering->send(*(short*)buffer); - } else if(node->writering->ring.bytelen == 4) { - node->writering->send(*(int*)buffer); - } else if(node->writering->ring.bytelen == 8) { - node->writering->send(*(long long*)buffer); - } - } else { - if(node->readring->ring.bytelen == 1) { - node->readring->send(*(char*)buffer); - } else if(node->readring->ring.bytelen == 2) { - node->readring->send(*(short*)buffer); - } else if(node->readring->ring.bytelen == 4) { - node->readring->send(*(int*)buffer); - } else if(node->readring->ring.bytelen == 8) { - node->readring->send(*(long long*)buffer); - } - } - vfs::vfs::unlock(); - return node->writering->ring.bytelen; - } - - return status; -} - -std::int64_t __devfs__read(userspace_fd_t* fd, char* path, void* buffer, std::uint64_t count) { - - vfs::devfs_node_t* node = devfs_find_dev(path); - - if(!node) { vfs::vfs::unlock(); - return -ENOENT; } - - if(node->read) - return node->read(fd,buffer,count); - - std::uint64_t status; - int is_master = !is_slave; - - if(node->open_flags.is_pipe_rw) { - vfs::vfs::unlock(); - if(!node->is_tty) - status = is_master ? node->writepipe->read(&fd->read_counter,(char*)buffer,count,(fd->flags & O_NONBLOCK) ? 1 : 0) : node->readpipe->read(&fd->read_counter,(char*)buffer,count,(fd->flags & O_NONBLOCK) ? 1 : 0); - else - status = is_master ? node->writepipe->read(&fd->read_counter,(char*)buffer,count,(fd->flags & O_NONBLOCK) ? 1 : 0) : node->readpipe->ttyread(&fd->read_counter,(char*)buffer,count,(fd->flags & O_NONBLOCK) ? 1 : 0); - } else { - //DEBUG(1,"read %s ring count %d",path,count); - status = is_master ? node->writering->receivevals(buffer,dev_num,count,&fd->cycle,&fd->queue) : node->readring->receivevals(buffer,dev_num,count,&fd->cycle,&fd->queue); - vfs::vfs::unlock(); - } - - return status; -} - -#define TIOCGPGRP 0x540F -#define TIOCSPGRP 0x5410 - - -std::int32_t __devfs__ioctl(userspace_fd_t* fd, char* path, unsigned long req, void *arg, int *res) { - - vfs::devfs_node_t* node = devfs_find_dev(path); - if(!node) - return ENOENT; - - if(node->ioctl) - return node->ioctl(fd,req,arg,res); - - if(!arg) - return 0; - - if(req == 0x80045430 && node->is_tty) { - // get pty num - vfs::devfs_packet_t packet; - packet.request = devfs_packet_get_num; - packet.value = 0; - std::int64_t status = vfs::devfs::send_packet(path,&packet); - *res = status; - *((int*)arg) = packet.value; - return status; - } else if(req == TIOCGPGRP && node->is_tty) { - *(int*)arg = node->pgrp; - *res = 0; - return 0; - } else if(req == TIOCSPGRP && node->is_tty) { - node->pgrp = *(int*)arg; - *res = 0; - return 0; - } - - vfs::devfs_packet_t packet; - packet.request = DEVFS_PACKET_IOCTL; - packet.ioctl.arg = (std::uint64_t)arg; - packet.ioctl.ioctlreq = req; - std::int64_t status = vfs::devfs::send_packet(path,&packet); - *res = status; - return status; -} - -std::int32_t __devfs__mmap(userspace_fd_t* fd, char* path, std::uint64_t* outp, std::uint64_t* outsz, std::uint64_t* outflags) { - vfs::devfs_node_t* node = devfs_find_dev(path); - if(!node) - return ENOENT; - - *outp = node->mmap_base; - *outsz = node->mmap_size; - *outflags = node->mmap_flags; - - return 0; -} - -std::int32_t __devfs__var(userspace_fd_t* fd, char* path, std::uint64_t value, std::uint8_t request) { - - vfs::devfs_node_t* node = devfs_find_dev(path); - if(!node) - return ENOENT; - - int status = 0; - if(request == DEVFS_VAR_ISATTY) - status = node->is_tty ? 0 : ENOTTY; - - if((request & ~(1 << 7)) == TMPFS_VAR_CHMOD) { - if(request & (1 << 7)) - node->mode = value & 0xFFFFFFFF; - else - *(std::uint64_t*)value = (std::uint64_t)node->mode; - } - - return status; -} - -std::int32_t __devfs__stat(userspace_fd_t* fd, char* path, vfs::stat_t* out) { - if(!path) - return EFAULT; - - DEBUG(1,"stat %s:%s",path,fd->path); - - if(path[0] == '\0') { - path[0] = '/'; - path[1] = '\0'; - out->st_size = 0; - out->st_mode = S_IFDIR; - out->st_ino = 0; - return 0; - } - - vfs::devfs_node_t* node = devfs_find_dev(path); - - if(!node) - return ENOENT; - - if(!out) - return EINVAL; - - if(node->slavepath[0] == '/' && node->slavepath[1] == '\0') { - out->st_size = 0; - out->st_mode = S_IFDIR; - out->st_ino = node->ino; - out->st_mode |= 020666; - } else { - out->st_size = 0; - out->st_mode = node->is_dir ? S_IFDIR : S_IFCHR; - out->st_ino = node->ino; - out->st_mode |= 0666; - } - return 0; -} - -std::int32_t __devfs__ls(userspace_fd_t* fd, char* path, vfs::dirent_t* out) { - - if(!path) - return EFAULT; - -againdev: - - vfs::devfs_node_t* nod = 0; - - if(fd->rv0 == 0 & fd->rv1 == 0) { - fd->rv0 = (std::uint64_t)__devfs_head->next; - nod = __devfs_head; - } else if(fd->rv0 != 0) { - nod = (vfs::devfs_node_t*)fd->rv0; - fd->rv0 = (std::uint64_t)nod->next; - } - - if(!nod) { - out->d_reclen = 0; - memset(out->d_name,0,sizeof(out->d_name)); - return 0; - } - - if(nod->slavepath[0] == '/' && nod->slavepath[1] == '\0') { - if(nod->slavepath[0] == '/' && nod->slavepath[1] == '\0') - goto againdev; - } - - memset(out->d_name,0,sizeof(out->d_name)); - __printfbuf(out->d_name,1024,nod->show_num == 1 ? "%s" : "%s%d",nod->slavepath + 1,nod->dev_num); - - out->d_reclen = sizeof(vfs::dirent_t); - out->d_ino = fd->rv1++; - out->d_off = 0; - out->d_type = nod->is_dir ? S_IFDIR : S_IFCHR; - fd->offset++; - - return 0; -} - -std::int64_t __devfs__poll(userspace_fd_t* fd, char* path, int operation_type) { - - vfs::devfs_node_t* node = devfs_find_dev(path); - - std::int64_t ret = 0; - if(node->open_flags.is_pipe_rw) { - node->writepipe->lock.lock(); - node->readpipe->lock.lock(); - if(operation_type == POLLIN) { - if(!is_slave) { - ret = node->writepipe->size != 0 ? 1 : 0; - } else { - if(!node->is_tty) - ret = node->readpipe->size != 0 ? 1 : 0; - else { - ret = (node->readpipe->tty_ret && node->readpipe->size != 0) != 0 ? 1 : 0; - } - } - } else if(operation_type == POLLOUT) { - if(!is_slave) { - ret = node->writepipe->size != node->writepipe->total_size ? 1 : 0; - } else { - ret = node->readpipe->size != node->readpipe->total_size ? 1 : 0; - } - } - node->writepipe->lock.unlock(); - node->readpipe->lock.unlock(); - } else { - if(operation_type == POLLIN) { - ret = 0; - if(!is_slave) { - if(node->writering->isnotempty((int*)&fd->queue,(char*)&fd->cycle)) { - ret = 1; - } - } else if(is_slave) { - if(node->readring->isnotempty((int*)&fd->queue,(char*)&fd->cycle)) { - ret = 1; - - } - } - - } else if(operation_type == POLLOUT) { - ret = 1; - } - } - - return ret; -} - -extern locks::spinlock* vfs_lock; - -std::uint64_t devfs_ino_ptr = 1; - -std::int64_t vfs::devfs::send_packet(char* path,devfs_packet_t* packet) { - devfs_node_t* node = devfs_find_dev(path); - - switch(packet->request) { - case DEVFS_PACKET_CREATE_DEV: { - devfs_node_t* new_node = (devfs_node_t*)memory::pmm::_virtual::alloc(4096); - memcpy(new_node->slavepath,path,strlen(path)); - memcpy(new_node->masterpath,(char*)packet->value,strlen((const char*)packet->value)); /* Actually path is slavepath and pcket.value is masterpath when driver creates new device */ - new_node->readring = new Lists::Ring(128); - new_node->writering = new Lists::Ring(128); - new_node->dev_num = packet->size; - new_node->next = __devfs_head; - new_node->ino = devfs_ino_ptr++; - __devfs_head = new_node; - return 0; - } - - case DEVFS_PACKET_CREATE_PIPE_DEV: { - devfs_node_t* new_node = (devfs_node_t*)memory::pmm::_virtual::alloc(4096); - memcpy(new_node->slavepath,path,strlen(path)); - memcpy(new_node->masterpath,(char*)packet->value,strlen((const char*)packet->value)); - new_node->readpipe = new pipe(0); - new_node->writepipe = new pipe(0); - //DEBUG(1,"%d %d\n",new_node->readpipe->size.load(),new_node->writepipe->size.load()); - new_node->readpipe->create(PIPE_SIDE_READ); - new_node->readpipe->create(PIPE_SIDE_WRITE); - new_node->writepipe->create(PIPE_SIDE_READ); - new_node->writepipe->create(PIPE_SIDE_WRITE); - new_node->dev_num = packet->size; - new_node->open_flags.is_pipe_rw = 1; - new_node->next = __devfs_head; - new_node->ino = devfs_ino_ptr++; - __devfs_head = new_node; - return 0; - } - - case DEVFS_PACKET_IOCTL: { - - if(!node) - return ENOENT; - - if(!packet->ioctl.arg) - return 0; - - std::uint64_t originalreq = packet->ioctl.ioctlreq; - - if(packet->ioctl.ioctlreq == TCGETS2) - packet->ioctl.ioctlreq = TCGETS; - - if(packet->ioctl.ioctlreq == TCSETS2 || packet->ioctl.ioctlreq == TCSETSW2 || packet->ioctl.ioctlreq == TCSETSF2) - packet->ioctl.ioctlreq = TCSETS; - - for(int i = 0;i < 32;i++) { - if(node->ioctls[i].read_req == packet->ioctl.ioctlreq) { /* Read */ - if(node->is_tty) { - if(originalreq == TCGETS2) - memcpy((void*)packet->ioctl.arg,node->ioctls[i].pointer_to_struct,sizeof(termios_t)); - else if(originalreq == TCGETS) - memcpy((void*)packet->ioctl.arg,node->ioctls[i].pointer_to_struct,sizeof(termiosold_t)); - else - memcpy((void*)packet->ioctl.arg,node->ioctls[i].pointer_to_struct,node->ioctls[i].size); - } else - memcpy((void*)packet->ioctl.arg,node->ioctls[i].pointer_to_struct,node->ioctls[i].size); - return 0; - } else if(node->ioctls[i].write_req == packet->ioctl.ioctlreq) { /* Write */ - if(node->is_tty) { - if(originalreq == TCSETS) { - memcpy(node->ioctls[i].pointer_to_struct,(void*)packet->ioctl.arg,sizeof(termiosold_t)); - } else - memcpy(node->ioctls[i].pointer_to_struct,(void*)packet->ioctl.arg,node->ioctls[i].size); - - } else - memcpy(node->ioctls[i].pointer_to_struct,(void*)packet->ioctl.arg,node->ioctls[i].size); - return 0; - } - } - return 0; - } - case DEVFS_PACKET_SIZE_IOCTL: { - - if(!node) - return -ENOENT; - - for(int i = 0;i < 32;i++) { - if(node->ioctls[i].read_req == packet->ioctl.ioctlreq) { /* Read */ - return node->ioctls[i].size; - } else if(node->ioctls[i].write_req == packet->ioctl.ioctlreq) { /* Write */ - return node->ioctls[i].size; - } - } - return -EINVAL; - } - case DEVFS_PACKET_CREATE_IOCTL: { - - if(!node) - return ENOENT; - - for(int i = 0;i < 32;i++) { - if(node->ioctls[i].pointer_to_struct == 0) { - devfs_ioctl_packet_t* current = &node->ioctls[i]; - current->read_req = packet->create_ioctl.readreg; - current->write_req = packet->create_ioctl.writereg; - current->pointer_to_struct = (void*)packet->create_ioctl.pointer; - current->size = packet->create_ioctl.size; - - if(current->write_req == TCSETS) { - node->writepipe->ttyflags = 0; - node->readpipe->ttyflags = (termios_t*)packet->create_ioctl.pointer; - node->term_flags = (termios_t*)packet->create_ioctl.pointer; - } - - return 0; - } - } - } - case DEVFS_ENABLE_PIPE: { - - if(!node) - return ENOENT; - - node->pipe0 = packet->enable_pipe.pipe_pointer; - node->open_flags.is_pipe = 1; - return 0; - } - - case DEVFS_SETUP_MMAP: { - - if(!node) - return ENOENT; - - node->mmap_base = packet->setup_mmap.dma_addr; - node->mmap_size = packet->setup_mmap.size; - node->mmap_flags = packet->setup_mmap.flags; - return 0; - } - - case DEVFS_PACKET_ISATTY: - - if(!node) - return ENOENT; - - if(node->is_tty) - return 0; - else - return ENOTTY; - - case DEVFS_PACKET_SETUPTTY: - - if(!node) - return ENOENT; - - node->is_tty = 1; - return 0; - - case devfs_packet_get_num: - - if(!node) - return ENOENT; - - packet->value = node->dev_num; - return 0; - - case DEVFS_GETSLAVE_BY_MASTER: - - if(!node) - return ENOENT; - - __printfbuf((char*)packet->value,256,"%s%d",node->slavepath,node->dev_num); - - return 0; - - case DEVFS_PACKET_SETUP_RING_SIZE: - - if(!node) - return ENOENT; - - if(!node->open_flags.is_pipe) { - node->readring->setup_bytelen(packet->size); - node->writering->setup_bytelen(packet->size); - } - - return 0; - - } - - vfs::vfs::unlock(); - return 0; -} - -# define NLDLY 0000400 /* Select newline delays: */ -# define NL0 0000000 /* Newline type 0. */ -# define NL1 0000400 /* Newline type 1. */ -# define CRDLY 0003000 /* Select carriage-return delays: */ -# define CR0 0000000 /* Carriage-return delay type 0. */ -# define CR1 0001000 /* Carriage-return delay type 1. */ -# define CR2 0002000 /* Carriage-return delay type 2. */ -# define CR3 0003000 /* Carriage-return delay type 3. */ -# define TABDLY 0014000 /* Select horizontal-tab delays: */ -# define TAB0 0000000 /* Horizontal-tab delay type 0. */ -# define TAB1 0004000 /* Horizontal-tab delay type 1. */ -# define TAB2 0010000 /* Horizontal-tab delay type 2. */ -# define TAB3 0014000 /* Expand tabs to spaces. */ -# define BSDLY 0020000 /* Select backspace delays: */ -# define BS0 0000000 /* Backspace-delay type 0. */ -# define BS1 0020000 /* Backspace-delay type 1. */ -# define FFDLY 0100000 /* Select form-feed delays: */ -# define FF0 0000000 /* Form-feed delay type 0. */ -# define FF1 0100000 /* Form-feed delay type 1. */ - -#define OPOST 0000001 /* Post-process output. */ -#define OLCUC 0000002 -#define ONLCR 0000004 /* Map NL to CR-NL on output. */ -#define OCRNL 0000010 /* Map CR to NL on output. */ -#define ONOCR 0000020 /* No CR output at column 0. */ -#define ONLRET 0000040 /* NL performs CR function. */ -#define OFILL 0000100 /* Use fill characters for delay. */ - -#define IUCLC 0x0200 -#define IXON 0x0400 -#define IXOFF 0x1000 -#define IMAXBEL 0x2000 -#define IUTF8 0x4000 -#define CREAD 0x00000080 -#define PARENB 0x00000100 -#define PARODD 0x00000200 -#define HUPCL 0x00000400 -#define CLOCAL 0x00000800 -#define CBAUDEX 0x00001000 -#define BOTHER 0x00001000 -#define B57600 0x00001001 -#define B115200 0x00001002 -#define B230400 0x00001003 -#define B460800 0x00001004 -#define B500000 0x00001005 -#define B576000 0x00001006 -#define B921600 0x00001007 -#define B1000000 0x00001008 -#define B1152000 0x00001009 -#define B1500000 0x0000100a -#define B2000000 0x0000100b -#define B2500000 0x0000100c -#define B3000000 0x0000100d - -#define ISIG 0x00001 -#define XCASE 0x00004 -#define ECHOE 0x00010 -#define ECHOK 0x00020 -#define ECHONL 0x00040 -#define NOFLSH 0x00080 -#define TOSTOP 0x00100 -#define ECHOCTL 0x00200 -#define ECHOPRT 0x00400 -#define ECHOKE 0x00800 -#define FLUSHO 0x01000 -#define PENDIN 0x04000 -#define IEXTEN 0x08000 -#define EXTPROC 0x10000 - -int is_early = 1; - -int tty_ptr = 0; -std::int32_t __ptmx_open(userspace_fd_t* fd, char* path) { - - memset(fd->path,0,2048); - __printfbuf(fd->path,2048,"/dev/tty"); - char ttyname[2048]; - memset(ttyname,0,2048); - __printfbuf(ttyname,2048,"/dev/pts/"); - - vfs::devfs_packet_t packet; - packet.size = tty_ptr; - packet.request = DEVFS_PACKET_CREATE_PIPE_DEV; - packet.value = (std::uint64_t)fd->path + 4; - - vfs::devfs::send_packet(ttyname + 4,&packet); - - memset(fd->path,0,2048); - __printfbuf(fd->path,2048,"/dev/tty%d",tty_ptr); - memset(ttyname,0,2048); - __printfbuf(ttyname,2048,"/dev/pts/%d",tty_ptr); - - packet.request = DEVFS_PACKET_SETUPTTY; - packet.value = (std::uint64_t)fd->path + 4; - - vfs::devfs::send_packet(ttyname + 4,&packet); - - termios_t* t = (termios_t*)memory::pmm::_virtual::alloc(4096); - - t->c_lflag |= (ICANON | ECHO); - - t->c_iflag = IGNPAR | ICRNL; - t->c_oflag = OPOST; - t->c_cflag |= (CS8); - - packet.request = DEVFS_PACKET_CREATE_IOCTL; - packet.create_ioctl.pointer = (std::uint64_t)t; - packet.create_ioctl.size = sizeof(termios_t); - packet.create_ioctl.readreg = TCGETS; - packet.create_ioctl.writereg = TCSETS; - - vfs::devfs::send_packet(ttyname + 4,&packet); - - std::uint64_t wins = (uint64_t)memory::pmm::_virtual::alloc(4096); - - packet.request = DEVFS_PACKET_CREATE_IOCTL; - packet.create_ioctl.pointer = (uint64_t)wins; - packet.create_ioctl.size = sizeof(struct winsize); - packet.create_ioctl.readreg = TIOCGWINSZ; - packet.create_ioctl.writereg = TIOCSWINSZ; - - if(is_early) { - winsizez ws = Log::GetDimensions(); - memcpy((void*)wins,&ws,sizeof(winsize)); - is_early = 0; - } - - vfs::devfs::send_packet(ttyname + 4,&packet); - - fd->other_state = USERSPACE_FD_OTHERSTATE_MASTER; - __printfbuf(fd->path,2048,"/dev/tty%d",tty_ptr); - - tty_ptr++; - - return 0; -} - -std::int64_t __irq_write(userspace_fd_t* fd, void* buffer, std::uint64_t size) { - drivers::ioapic::unmask(dev_num); - vfs::vfs::unlock(); - return size; -} - -std::int64_t __pic_write(userspace_fd_t* fd, void* buffer, std::uint64_t size) { - if(size != 10) {vfs::vfs::unlock(); - return -EINVAL; } - - std::uint16_t irq_num = *(std::uint16_t*)((std::uint64_t)buffer); - std::uint64_t ioapic_flags = *(std::uint64_t*)((std::uint64_t)buffer + 2); - - const char* path0 = "/masterirq"; - const char* path1 = "/irq"; - - vfs::devfs_node_t* new_node = (vfs::devfs_node_t*)memory::pmm::_virtual::alloc(4096); - memcpy(new_node->slavepath,path1,strlen(path1)); - memcpy(new_node->masterpath,(char*)path0,strlen((const char*)path0)); - new_node->readring = new Lists::Ring(128); - new_node->writering = new Lists::Ring(128); - new_node->dev_num = irq_num; - new_node->next = __devfs_head; - new_node->slave_write = __irq_write; - __devfs_head = new_node; - - new_node->writering->setup_bytelen(1); - new_node->readring->setup_bytelen(1); - - arch::x86_64::interrupts::irq::create(irq_num,IRQ_TYPE_LEGACY_USERSPACE,0,0,ioapic_flags); - drivers::ioapic::unmask(irq_num); - - vfs::vfs::unlock(); - return 10; - -} - -std::int64_t __zero_write(userspace_fd_t* fd, void* buffer, std::uint64_t size) { - vfs::vfs::unlock(); - return size; -} - -std::int64_t __zero_read(userspace_fd_t* fd, void* buffer, std::uint64_t count) { - vfs::vfs::unlock(); // dont waste time on this - memset(buffer,0,count); - return 0; -} - -std::int64_t __random_write(userspace_fd_t* fd, void* buffer, std::uint64_t size) { - vfs::vfs::unlock(); - return size; -} - -std::uint64_t next = 2; - -std::uint64_t __rand() { - uint64_t t = __rdtsc(); - return t * (++next); -} - -std::int64_t __random_read(userspace_fd_t* fd, void* buffer, std::uint64_t count) { - vfs::vfs::unlock(); // dont waste time on this - memset(buffer,0,count); - for(std::uint64_t i = 0; i < count; i++) { - ((char*)buffer)[i] = __rand() & 0xFF; - } - return count; -} - -#include <etc/bootloaderinfo.hpp> - -#define FBIOGET_VSCREENINFO 0x4600 -#define FBIOPUT_VSCREENINFO 0x4601 -#define FBIOGET_FSCREENINFO 0x4602 -#define FB_VISUAL_TRUECOLOR 2 /* True color */ -#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ - -vfs::devfs_node_t* ktty_node = 0; - -void vfs::devfs::mount(vfs_node_t* node) { - __devfs_head = (devfs_node_t*)memory::pmm::_virtual::alloc(4096); - memcpy(__devfs_head->slavepath,"/\0",2); - - __devfs_head->show_num = 1; - node->open = __devfs__open; - node->read = __devfs__read; - node->write = __devfs__write; - node->ioctl = __devfs__ioctl; - node->mmap = __devfs__mmap; - node->var = __devfs__var; - node->stat = __devfs__stat; - node->poll = __devfs__poll; - node->ls = __devfs__ls; - - const char* name = "/ptmx"; - - devfs_packet_t packet; - packet.size = tty_ptr; - packet.request = DEVFS_PACKET_CREATE_PIPE_DEV; - packet.value = (std::uint64_t)name; - - send_packet((char*)name,&packet); - - __devfs_head->show_num = 1; - __devfs_head->open = __ptmx_open; - - packet.size = tty_ptr; - packet.request = DEVFS_PACKET_CREATE_PIPE_DEV; - packet.value = (std::uint64_t)"/input"; - - send_packet((char*)"/input",&packet); - - __devfs_head->is_dir = 1; - __devfs_head->show_num = 1; - - const char* name0 = "/pic"; - - packet.size = tty_ptr; - packet.request = DEVFS_PACKET_CREATE_DEV; - packet.value = (std::uint64_t)name0; - - send_packet((char*)name0,&packet); - - /* The head should be this dev so all ok */ - - __devfs_head->show_num = 1; - __devfs_head->write = __pic_write; - - - const char* name00 = "/null"; - - packet.size = 0; - packet.request = DEVFS_PACKET_CREATE_DEV; - packet.value = (std::uint64_t)name00; - - send_packet((char*)name00,&packet); - - __devfs_head->show_num = 1; - __devfs_head->write = __zero_write; - __devfs_head->read = __zero_read; - - const char* name001 = "/urandom"; - - packet.size = 0; - packet.request = DEVFS_PACKET_CREATE_DEV; - packet.value = (std::uint64_t)name001; - - send_packet((char*)name001,&packet); - - __devfs_head->show_num = 1; - __devfs_head->write = __random_write; - __devfs_head->read = __random_read; - - // liborange_create_dev(((uint64_t)DEVFS_PACKET_CREATE_DEV << 32) | 0, "/ps2keyboard", "/masterps2keyboard"); - // liborange_setup_ring_bytelen("/ps2keyboard0",1); - - // liborange_create_dev(((uint64_t)DEVFS_PACKET_CREATE_DEV << 32) | 0, "/mouse", "/mastermouse"); - // liborange_setup_ring_bytelen("/mouse0",4); - - packet.size = 0; - __devfs_head->show_num = 1; - packet.request = DEVFS_PACKET_CREATE_DEV; - packet.value = (std::uint64_t)"/masterps2keyboard"; - - send_packet((char*)"/ps2keyboard",&packet); - - __devfs_head->readring->setup_bytelen(1); - __devfs_head->writering->setup_bytelen(1); - - packet.size = 0; - __devfs_head->show_num = 1; - packet.request = DEVFS_PACKET_CREATE_DEV; - packet.value = (std::uint64_t)"/mastermouse"; - - send_packet("/mouse",&packet); - - __devfs_head->readring->setup_bytelen(4); - __devfs_head->writering->setup_bytelen(4); - - struct limine_framebuffer fb = *BootloaderInfo::AccessFramebuffer(); - - packet.size = 0; - packet.request = DEVFS_PACKET_CREATE_DEV; - packet.value = (std::uint64_t)"/zfb"; - - send_packet("/fb",&packet); - - __devfs_head->mmap_base = (std::uint64_t)((std::uint64_t)fb.address - BootloaderInfo::AccessHHDM()); - __devfs_head->mmap_size = fb.pitch * fb.height; - __devfs_head->mmap_flags = PTE_WC; - - struct fb_var_screeninfo* vinfo = (struct fb_var_screeninfo*)memory::pmm::_virtual::alloc(sizeof(struct fb_var_screeninfo));; - struct fb_fix_screeninfo* finfo = (struct fb_fix_screeninfo*)memory::pmm::_virtual::alloc(sizeof(struct fb_fix_screeninfo)); - - devfs_packet_t packeta; - packeta.create_ioctl.readreg = FBIOGET_VSCREENINFO; - packeta.create_ioctl.writereg = 0; - packeta.create_ioctl.request = DEVFS_PACKET_CREATE_IOCTL; - packeta.create_ioctl.size = sizeof(struct fb_var_screeninfo); - packeta.create_ioctl.pointer = (std::uint64_t)vinfo; - send_packet("/fb0",&packeta); - - packeta.create_ioctl.readreg = FBIOGET_FSCREENINFO; - packeta.create_ioctl.writereg = 0; - packeta.create_ioctl.request = DEVFS_PACKET_CREATE_IOCTL; - packeta.create_ioctl.size = sizeof(struct fb_fix_screeninfo); - packeta.create_ioctl.pointer = (std::uint64_t)finfo; - send_packet("/fb0",&packeta); - - vinfo->red.length = fb.red_mask_size; - vinfo->red.offset = fb.red_mask_shift; - vinfo->blue.offset = fb.blue_mask_shift; - vinfo->blue.length = fb.blue_mask_size; - vinfo->green.length = fb.green_mask_size; - vinfo->green.offset = fb.green_mask_shift; - vinfo->xres = fb.width; - vinfo->yres = fb.height; - vinfo->bits_per_pixel = fb.bpp < 5 ? (fb.bpp * 8) : fb.bpp; - vinfo->xres_virtual = fb.width; - vinfo->yres_virtual = fb.height; - vinfo->red.msb_right = 1; - vinfo->green.msb_right = 1; - vinfo->blue.msb_right = 1; - vinfo->transp.msb_right = 1; - vinfo->height = -1; - vinfo->width = -1; - finfo->line_length = fb.pitch; - finfo->smem_len = fb.pitch * fb.height; - finfo->visual = FB_VISUAL_TRUECOLOR; - finfo->type = FB_TYPE_PACKED_PIXELS; - finfo->mmio_len = fb.pitch * fb.height; - - // now init kernel tty - userspace_fd_t hi; - memset(&hi,0,sizeof(userspace_fd_t)); - memcpy(hi.path,"/dev/ptmx",sizeof("/dev/ptmx")); - __ptmx_open(&hi,"/ptmx"); - -}
\ No newline at end of file diff --git a/kernel/src/generic/vfs/evdev.cpp b/kernel/src/generic/vfs/evdev.cpp deleted file mode 100644 index 4868473..0000000 --- a/kernel/src/generic/vfs/evdev.cpp +++ /dev/null @@ -1,304 +0,0 @@ - -#include <generic/vfs/vfs.hpp> -#include <generic/vfs/devfs.hpp> -#include <generic/vfs/evdev.hpp> -#include <etc/logging.hpp> - -#include <cstdint> - -vfs::evdev_node* evdev_head_node = 0; - -int evdev_num = 0; - -inline bool isdigit(char ch) { - return ch >= '0' && ch <= '9'; -} - -inline long reverse_number(long num) { - long reversed_num = 0; - - while(num > 0) { - int digit = num % 10; - reversed_num = reversed_num * 10 + digit; - num /= 10; - } - - return reversed_num; -} - -vfs::evdev_node* evdev_find_by_num(int num) { - vfs::evdev_node* dev = evdev_head_node; - while (dev) { - if (num == dev->num) { - return dev; - } - dev = dev->next; - } - - return 0; -} - -vfs::evdev_node* evdev_find_dev(const char* loc) { - vfs::evdev_node* dev = evdev_head_node; - char temp[256]; - int len = strlen((char*)loc); - int i = len - 1; - - evdev_num = 0; - - while (i >= 0 && isdigit(loc[i])) { - evdev_num = evdev_num * 10 + (loc[i] - '0'); - i--; - } - - evdev_num = reverse_number(evdev_num); - - memcpy(temp, loc, i + 1); - temp[i + 1] = '\0'; - - while (dev) { - if (!strcmp(temp,"/event") && evdev_num == dev->num) { - return dev; - } - dev = dev->next; - } - - return 0; -} - -std::int32_t __evdev__open(userspace_fd_t* fd, char* path) { - - if(path[0] == '\0' || (path[0] == '/' && path[1] == '\0')) - return 0; - - vfs::evdev_node* node = evdev_find_dev(path); - if(!node) - return ENOENT; - - if(node->main_ring) { - fd->queue = node->main_ring->ring.tail; - fd->cycle = node->main_ring->ring.cycle; - } - - return 0; -} - -std::int32_t __evdev__stat(userspace_fd_t* fd, char* path, vfs::stat_t* out) { - memset(out,0,sizeof(vfs::stat_t)); - if(path[0] == '\0' || (path[0] == '/' && path[1] == '\0')) { - out->st_ino = 0; - out->st_mode |= S_IFDIR; - return 0; - } - - vfs::evdev_node* node = evdev_find_dev(path); - if(!node) - return -EINVAL; - - out->st_ino = node->num + 1; - out->st_mode = S_IFCHR; - return 0; -} - -std::int32_t __evdev__statx(userspace_fd_t* fd, char* path, int flags, int mask, statx_t* out) { - memset(out,0,sizeof(statx_t)); - - if(path[0] == '\0' || (path[0] == '/' && path[1] == '\0')) { - out->stx_mask = STATX_BASIC_STATS; - out->stx_blksize = 4096; - out->stx_nlink = 0; - out->stx_uid = 0; - out->stx_gid = 0; - out->stx_mode = S_IFDIR; - out->stx_ino = 0; - out->stx_size = 0; - out->stx_blocks = 0; - out->stx_atime.tv_sec = 0; - out->stx_atime.tv_nsec = 0; - out->stx_btime.tv_sec = 0; - out->stx_btime.tv_nsec = 0; - out->stx_ctime.tv_sec = 0; - out->stx_ctime.tv_nsec = 0; - out->stx_mtime.tv_sec = 0; - out->stx_mtime.tv_nsec = 0; - out->stx_rdev_major = 0; - out->stx_rdev_minor = 0; - out->stx_dev_major = 0; - out->stx_dev_minor = 0; - return 0; - } - - vfs::evdev_node* node = evdev_find_dev(path); - if(!node) - return -EINVAL; - - out->stx_mask = STATX_BASIC_STATS; - out->stx_blksize = 4096; - out->stx_nlink = 0; - out->stx_uid = 0; - out->stx_gid = 0; - out->stx_mode = S_IFCHR; - out->stx_ino = node->num + 1; - out->stx_size = 0; - out->stx_blocks = 0; - out->stx_atime.tv_sec = 0; - out->stx_atime.tv_nsec = 0; - out->stx_btime.tv_sec = 0; - out->stx_btime.tv_nsec = 0; - out->stx_ctime.tv_sec = 0; - out->stx_ctime.tv_nsec = 0; - out->stx_mtime.tv_sec = 0; - out->stx_mtime.tv_nsec = 0; - out->stx_rdev_major = 0; - out->stx_rdev_minor = 0; - out->stx_dev_major = 0; - out->stx_dev_minor = 0; - return 0; -} - -std::int32_t __evdev__ls(userspace_fd_t* fd, char* path, vfs::dirent_t* out) { -againdev: - vfs::evdev_node* nod = 0; - - if(fd->rv0 == 0 & fd->rv1 == 0) { - fd->rv0 = (std::uint64_t)evdev_head_node->next; - nod = evdev_head_node; - } else if(fd->rv0 != 0) { - nod = (vfs::evdev_node*)fd->rv0; - fd->rv0 = (std::uint64_t)nod->next; - } - - if(!nod) { - out->d_reclen = 0; - memset(out->d_name,0,sizeof(out->d_name)); - return 0; - } - - memset(out->d_name,0,sizeof(out->d_name)); - __printfbuf(out->d_name,1024,"event%d",nod->num); - - out->d_reclen = sizeof(vfs::dirent_t); - out->d_ino = fd->rv1++; - out->d_off = 0; - out->d_type = S_IFCHR; - fd->offset++; - return 0; -} - -std::int64_t __evdev__read(userspace_fd_t* fd, char* path, void* buffer, std::uint64_t count) { - vfs::evdev_node* node = evdev_find_dev(path); - if(!node) { - vfs::vfs::unlock(); - return -ENOENT; - } - - if(node->main_ring) { - std::uint64_t c = node->main_ring->receivevals(buffer, count, &fd->cycle, &fd->queue); - vfs::vfs::unlock(); - return c; - } - assert(0,"BROOOOOO"); - return -EFAULT; -} - -std::int64_t __evdev__write(userspace_fd_t* fd, char* path, void* buffer, std::uint64_t size) { - vfs::vfs::unlock(); - return -ENOTSUP; -} - -int __bitmap_size(int c) { - return ALIGNUP(c,8) / 8; -} - -std::int32_t __evdev__ioctl(userspace_fd_t* fd, char* path, unsigned long req, void *arg, int *res) { - - vfs::evdev_node* node = evdev_find_dev(path); - if(!node) - return -EINVAL; - - std::uint64_t size = _IOC_SIZE(req); - - if (_IOC_DIR(req) == _IOC_READ && (_IOC_NR(req) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) { - switch(_IOC_NR(req) & EV_MAX) { - case 0: - memcpy(arg,node->ev_bitmap->pool,__bitmap_size(EV_MAX)); - return 0; - } - assert(0,"doing req %d",_IOC_NR(req) & EV_MAX); - } else { - switch(EVIOC_MASK_SIZE(req)) { - case EVIOCGNAME(0): - memcpy(arg, node->name, size > strlen(node->name) ? size : strlen(node->name)); - return 0; - }; - } - - assert(0, "ioctl req 0x%p arg 0x%p path %s rev 0x%p",EVIOC_MASK_SIZE(req),arg,path,_IOC_NR(req) & EV_MAX); -} - -std::int64_t __evdev__poll(userspace_fd_t* fd, char* path, int operation_type) { - - vfs::evdev_node* node = evdev_find_dev(path); - if(!node) - return -EINVAL; - - if(!node->main_ring) - return 0; // always return will block - - int ret; - if(operation_type == POLLIN) { - ret = 0; - if(node->main_ring->isnotempty((int*)&fd->queue,(char*)&fd->cycle)) { - ret = 1; - } - - } else if(operation_type == POLLOUT) { - ret = 1; - } - return ret; -} - -#define BITS_PER_LONG (8 * sizeof(long)) -#define IS_SET(bit, array) ((array[(bit) / BITS_PER_LONG] >> ((bit) % BITS_PER_LONG)) & 1) - -int vfs::evdev::create(char* name, int type) { - evdev_node* new_node = (evdev_node*)memory::pmm::_virtual::alloc(4096); - new_node->num = evdev_num++; - memcpy(new_node->path,"/event\0",7); - new_node->main_ring = new evdev_modif_ring(256); - memcpy(new_node->name,name,strlen(name) + 1); - - if(type == EVDEV_TYPE_KEYBOARD) { - new_node->ev_bitmap = new Lists::Bitmap(EV_MAX + 1); - new_node->ev_bitmap->set(EV_KEY); - new_node->ev_bitmap->set(EV_REP); - } else if(type == EVDEV_TYPE_MOUSE) { - new_node->ev_bitmap = new Lists::Bitmap(EV_MAX + 1); - new_node->ev_bitmap->set(EV_REL); - new_node->ev_bitmap->set(EV_SYN); - } - - new_node->next = evdev_head_node; - new_node->type = type; - evdev_head_node = new_node; - Log::Display(LEVEL_MESSAGE_INFO,"evdev: new device /dev/input/event%d with name \"%s\" and type %d\n",new_node->num,name,type); - return new_node->num; -} - -void vfs::evdev::submit(int num, input_event event) { - evdev_node* node = evdev_find_by_num(num); - assert(node, "evdev node with num %d not found",num); - assert(node->main_ring, "wtf !7&77177171???!?!!?771711771 %d %s 0x%p",num,node->name,node->main_ring); - node->main_ring->send(event); -} - -void vfs::evdev::mount(vfs_node_t* node) { - node->open = __evdev__open; - node->stat = __evdev__stat; - node->statx = __evdev__statx; - node->ls = __evdev__ls; - node->read = __evdev__read; - node->write = __evdev__write; - node->poll = __evdev__poll; - node->ioctl = __evdev__ioctl; -}
\ No newline at end of file diff --git a/kernel/src/generic/vfs/tmpfs.cpp b/kernel/src/generic/vfs/tmpfs.cpp deleted file mode 100644 index b3ad3c1..0000000 --- a/kernel/src/generic/vfs/tmpfs.cpp +++ /dev/null @@ -1,1065 +0,0 @@ - -#include <cstdint> -#include <generic/vfs/tmpfs.hpp> -#include <generic/vfs/vfs.hpp> - -#include <generic/mm/pmm.hpp> -#include <generic/mm/heap.hpp> - -#include <etc/etc.hpp> - -#include <etc/hash.hpp> - -#include <etc/libc.hpp> -#include <etc/errno.hpp> - -#include <drivers/cmos.hpp> -#include <drivers/tsc.hpp> - -#include <etc/logging.hpp> - -std::uint64_t __tmpfs_ptr_id = 0; - -vfs::tmpfs_node_t* head_node = 0; -vfs::tmpfs_node_t* root_node = 0; - -vfs::tmpfs_node_t* __tmpfs__find(const char* path) { - - extern locks::spinlock* vfs_lock; - - if(path[0] == '/' && path[1] == '\0') - return root_node; - - if(path[0] == '\0') - return root_node; - - char built_path[2048]; - char copied_path[2048]; - memcpy(copied_path,path,strlen(path) + 1); - memset(built_path,0,2048); - char* next = 0; - char* token = __vfs__strtok(&next, copied_path, "/"); - - std::uint64_t need_hash = hash_fnv1(path); - std::uint64_t ptr = 0; - - vfs::tmpfs_node_t* current = root_node; - while(token) { - - built_path[ptr] = '/'; - ptr++; - - memcpy((char*)((uint64_t)built_path + ptr),token,strlen(token)); - ptr += strlen(token); - built_path[ptr] = '\0'; - - std::uint64_t rehashed = hash_fnv1(built_path); - if(current->type != VFS_TYPE_DIRECTORY) { - return 0; - } else if(current->path_hash == need_hash) - return current; - - int is_cont = 1; - - std::uint64_t* cont = (std::uint64_t*)current->content; - if(current->content) { - for(std::uint64_t i = 0; (i < (current->size / 8)) && is_cont; i++) { - vfs::tmpfs_node_t* chld = (vfs::tmpfs_node_t*)cont[i]; - if(chld) { - if(chld->path_hash == rehashed) { - current = chld; - is_cont = 0; - goto end; - } - } - } - } -end: - if(is_cont) - return 0; - - if(current->path_hash == need_hash) - return current; - - token = __vfs__strtok(&next,0,"/"); - } - - if(current->path_hash == need_hash) - return current; - - return 0; -} - -void __tmpfs__find_dir(char *path) { - char *last_slash = strrchr(path, '/'); - if (last_slash!= NULL && last_slash!= path) { - *last_slash = '\0'; - } else { - path[1] = '\0'; - } -} - -char* __tmpfs__find_name(char* path) { - char* last_slash = 0; - while (*path) { - if (*path == '/') { - last_slash = path; - } - path++; - } - if (last_slash) { - return last_slash + 1; - } - return path; -} - -vfs::tmpfs_node_t* __tmpfs__symfind(char* path) { - return __tmpfs__find(path); // symlinks will be handled by vfs -} - -std::uint8_t __tmpfs__exists(char* path) { - vfs::tmpfs_node_t* node = __tmpfs__find(path); - if(node) { - return 1; - } - - return 0; -} - -std::uint8_t __tmpfs__create_parent_dirs_by_default = 1; /* Used for ustar */ - -NodePoolBlock* node_pool_blocks_head = 0; - -vfs::tmpfs_node_t* node_pool_current = 0; -size_t node_pool_offset = 0; -size_t node_pool_capacity = 0; - -static void allocate_node_pool_block() { - void* block = memory::pmm::_virtual::alloc(NODE_POOL_BLOCK_SIZE); - if (!block) { - return; - } - - NodePoolBlock* new_block = (NodePoolBlock*)memory::pmm::_virtual::alloc(sizeof(NodePoolBlock)); - if (!new_block) { - return; - } - new_block->block = reinterpret_cast<vfs::tmpfs_node_t*>(block); - new_block->next = node_pool_blocks_head; - node_pool_blocks_head = new_block; - - node_pool_current = new_block->block; - node_pool_offset = 0; - node_pool_capacity = NODE_POOL_BLOCK_SIZE / sizeof(vfs::tmpfs_node_t);; -} - -static vfs::tmpfs_node_t* allocate_node_from_pool() { - if (!node_pool_current || node_pool_offset >= node_pool_capacity) { - allocate_node_pool_block(); - if (!node_pool_current) { - return 0; - } - } - vfs::tmpfs_node_t* node = node_pool_current + node_pool_offset; - node_pool_offset++; - memset(node, 0, sizeof(vfs::tmpfs_node_t)); - return node; -} - - -int __tmpfs__is_busy(vfs::tmpfs_node_t* node) { - - if(!node) - return 0; - - if(node->busy != 0) - return 1; - - if(node->type != TMPFS_TYPE_DIRECTORY) - return 0; // node->busy is ok so return 0 - - if(node->type == TMPFS_TYPE_DIRECTORY) { - - std::uint64_t* cont = (std::uint64_t*)node->content; - for(std::uint64_t i = 0; i < (node->size / 8); i++) { - if(cont[i] != 0) { - vfs::tmpfs_node_t* chld_node = (vfs::tmpfs_node_t*)(((std::uint64_t*)node->content)[i]); - if(chld_node->busy != 0) - return 1; - - if(chld_node->type == TMPFS_TYPE_DIRECTORY) { - int c = __tmpfs__is_busy(chld_node); - if(c == 1) - return c; - } - } - - } - } - - return 0; -} - -vfs::tmpfs_node_t* last = 0; - -std::int32_t __tmpfs__create(char* path,std::uint8_t type, vfs::tmpfs_node_t** out) { - - if(out) { - if(__tmpfs__exists(path)) - return -EEXIST; - } - - char copy[2048]; - memset(copy,0,2048); - memcpy(copy,path,strlen(path)); - - if(path[0] == '\0') - return -EINVAL; - - __tmpfs__find_dir(copy); - - if(copy[0] == '\0') { - copy[0] = '/'; - copy[1] = '\0'; - } - - vfs::tmpfs_node_t* parent = __tmpfs__find(copy); - - if(!parent) { - if(!__tmpfs__create_parent_dirs_by_default) - return -ENOENT; - else { - __tmpfs__create(copy,TMPFS_TYPE_DIRECTORY,&parent); - } - } - - vfs::tmpfs_node_t* node = head_node; - - int is_success_find = 0; - - while(node) { - if(node->name[0] == '\0') { - vfs::tmpfs_node_t* nex = node->next; - memset(node,0,sizeof(vfs::tmpfs_node_t)); - node->next = nex; - is_success_find = 1; - break; - } - - node = node->next; - } - - if(!node) - node = (vfs::tmpfs_node_t*)memory::pmm::_virtual::alloc(4096); - - node->type = type; - node->content = 0; - node->size = 0; - node->busy = 0; - node->id = ++__tmpfs_ptr_id; - - - - node->create_time = getUnixTime(); - node->access_time = getUnixTime(); - - memcpy(node->name,path,strlen(path)); - - node->path_hash = hash_fnv1(node->name); - - if(!is_success_find) { - node->next = head_node; - head_node = node; - } - - if(!(parent->size <= parent->real_size)) { - // overflow ! increase size - parent->content = (std::uint8_t*)memory::pmm::_virtual::realloc(parent->content,parent->real_size,parent->real_size + PAGE_SIZE); - parent->real_size += PAGE_SIZE; - } - - if(parent->size <= parent->real_size) { - // first: find free entry - - std::uint64_t* free_entry = 0; - for(std::uint64_t i = 0; i < (parent->size / 8); i++) { - if(((std::uint64_t*)parent->content)[i] == 0) { - free_entry = &(((std::uint64_t*)parent->content)[i]); - break; - } - } - - if(!free_entry) { - free_entry = &((std::uint64_t*)parent->content)[parent->size / 8]; - parent->size += 8; - } - - *free_entry = (std::uint64_t)node; - - } - - if(node->type == VFS_TYPE_DIRECTORY) { - node->content = (std::uint8_t*)memory::pmm::_virtual::alloc(DIRECTORY_LIST_SIZE); - node->real_size = DIRECTORY_LIST_SIZE; - node->size = 0; - } - - last = node; - - if(out) { - *out = node; - } - - return 0; -} - -void __tmpfs__dealloc(vfs::tmpfs_node_t* node){ - if(!node->content) - return; - memory::pmm::_virtual::free(node->content); -} - -std::uint8_t __tmpfs__dont_alloc_memory = 0; - -std::int64_t __tmpfs__write(userspace_fd_t* fd, char* path, void* buffer, std::uint64_t size) { - if (!path || !buffer || !size) { vfs::vfs::unlock(); - return -EBADF; } - - vfs::tmpfs_node_t* node = __tmpfs__symfind(path); - - if (!node) { vfs::vfs::unlock(); - return -ENOENT; } - - if (!node) { vfs::vfs::unlock(); - return -ENOENT; } - - if (node->type == TMPFS_TYPE_DIRECTORY) { vfs::vfs::unlock(); - return -EISDIR; } - - if (!fd) { - __tmpfs__dealloc(node); - node->content = (std::uint8_t*)memory::pmm::_virtual::alloc(size); - memcpy(node->content, buffer, size); - node->size = size; - } else { - std::uint64_t offset = fd->offset; - std::uint64_t new_size = offset + size; - - if (new_size > node->real_size || node->is_non_allocated) { - alloc_t new_content0 = memory::pmm::_physical::alloc_ext(new_size); - std::uint8_t* new_content = (std::uint8_t*)new_content0.virt; - if (node->content) { - memcpy(new_content, node->content, node->size); - if(!node->is_non_allocated) - __tmpfs__dealloc(node); - } - node->is_non_allocated = 0; - node->content = new_content; - node->real_size = new_content0.real_size; - } - - if(new_size > node->size) - node->size = new_size; - - node->access_time = getUnixTime(); - memcpy(node->content + offset, buffer, size); - - fd->offset += size; - } - - vfs::vfs::unlock(); - return size; -} - -std::int64_t __tmpfs__read(userspace_fd_t* fd, char* path, void* buffer, std::uint64_t count) { - if (!path || !buffer) { vfs::vfs::unlock(); - return -EBADF; } - - if(!count) { vfs::vfs::unlock(); - return 0; } - - vfs::tmpfs_node_t* node = __tmpfs__symfind(path); - - if (!node) { vfs::vfs::unlock(); - return -ENOENT; } - - if (!node) { vfs::vfs::unlock(); - return -ENOENT; } - - if (node->type == TMPFS_TYPE_DIRECTORY) { vfs::vfs::unlock(); - return -EISDIR; } - - if (!fd) { - std::uint64_t to_read = (count >= node->size) ? node->size : count; - memcpy(buffer, node->content, to_read); - vfs::vfs::unlock(); - return to_read; - } else { - std::uint64_t offset = fd->offset; - if (offset >= node->size) { - vfs::vfs::unlock(); - return 0; - } - std::uint64_t available = node->size - offset; - std::uint64_t to_read = (count > available) ? available : count; - - memcpy(buffer, node->content + offset, to_read); - fd->offset += to_read; - - vfs::vfs::unlock(); - return to_read; - } -} - -void __tmpfs__opt_create_and_write(char* path, int type, char* content, std::uint64_t content_len, int chmod) { - - char copy[2048]; - memcpy(copy,path,strlen(path) + 1); - - if(path[0] == '\0') - return; - - __tmpfs__find_dir(copy); - - if(copy[0] == '\0') { - copy[0] = '/'; - copy[1] = '\0'; - } - - vfs::tmpfs_node_t* parent = __tmpfs__find(copy); - - if(!parent) { - if(!__tmpfs__create_parent_dirs_by_default) - return; - else { - __tmpfs__create(copy,TMPFS_TYPE_DIRECTORY,&parent); - } - } - - vfs::tmpfs_node_t* node = 0; - - if(!node) - node = (vfs::tmpfs_node_t*)allocate_node_from_pool(); - - node->type = type; - node->content = 0; - node->size = 0; - node->busy = 0; - node->id = ++__tmpfs_ptr_id; - - node->create_time = getUnixTime(); - node->access_time = getUnixTime(); - - memcpy(node->name,path,strlen(path) + 1); - - node->path_hash = hash_fnv1(node->name); - - node->next = head_node; - head_node = node; - - assert(parent,"parent is null %s (%d)",copy,__tmpfs__create_parent_dirs_by_default); - - if(!parent->content) { - node->content = (std::uint8_t*)memory::pmm::_virtual::alloc(DIRECTORY_LIST_SIZE); - node->real_size = DIRECTORY_LIST_SIZE; - node->size = 0; - } - - if(!(parent->size <= parent->real_size)) { - // overflow ! increase size - parent->content = (std::uint8_t*)memory::pmm::_virtual::realloc(parent->content,parent->real_size,parent->real_size + PAGE_SIZE); - parent->real_size += PAGE_SIZE; - } - - if(parent->size <= parent->real_size) { - std::uint64_t* free_entry = &((std::uint64_t*)parent->content)[parent->size / 8]; - parent->size += 8; - - *free_entry = (std::uint64_t)node; - } - - if(node->type == VFS_TYPE_DIRECTORY) { - node->content = (std::uint8_t*)memory::pmm::_virtual::alloc(DIRECTORY_LIST_SIZE); - node->real_size = DIRECTORY_LIST_SIZE; - node->size = 0; - } else { - alloc_t new_content0 = memory::pmm::_physical::alloc_ext(content_len); - std::uint8_t* new_content = (std::uint8_t*)new_content0.virt; - if (node->content) { - memcpy(new_content, node->content, node->size); - if(!node->is_non_allocated) - __tmpfs__dealloc(node); - } - node->is_non_allocated = 0; - node->content = new_content; - node->real_size = new_content0.real_size; - node->size = content_len; - memcpy(node->content,content,content_len); - } - - node->vars[TMPFS_VAR_CHMOD] = chmod; - - return; - -} - -std::int32_t __tmpfs__open(userspace_fd_t* fd, char* path) { - if(!path) - return EFAULT; - - vfs::tmpfs_node_t* node = __tmpfs__symfind(path); - - if(!node) - return ENOENT; - - node->busy++; - - /* TmpFS doesnt need to change something in fd */ - - return 0; -} - -std::int32_t __tmpfs__var(userspace_fd_t* fd, char* path, std::uint64_t value, std::uint8_t request) { - if(!path) - return EFAULT; - - vfs::tmpfs_node_t* node = __tmpfs__symfind(path); - - if(!node) - return ENOENT; - - if(request == DEVFS_VAR_ISATTY) - return ENOTTY; - - if(request & (1 << 7)) - node->vars[request & ~(1 << 7)] = value; - else - *(std::uint64_t*)value = node->vars[request & ~(1 << 7)]; - - return 0; - -} - -std::int32_t __tmpfs__ls(userspace_fd_t* fd, char* path, vfs::dirent_t* out) { - -again: - - if(!path) - return EFAULT; - - vfs::tmpfs_node_t* node = __tmpfs__symfind(path); - - if(!node) - return ENOENT; - - if(node->type != VFS_TYPE_DIRECTORY) - return ENOTDIR; - - if(fd->offset == node->size / 8) { - out->d_reclen = 0; - memset(out->d_name,0,sizeof(out->d_name)); - return 0; - } - - vfs::tmpfs_node_t* next = (vfs::tmpfs_node_t*)(((std::uint64_t*)node->content)[fd->offset]); - - if(next == 0) { // null pointer fix - fd->offset++; - goto again; - } - - memset(out->d_name,0,sizeof(out->d_name)); - memcpy(out->d_name,__tmpfs__find_name(next->name),strlen(__tmpfs__find_name(next->name))); - - std::uint64_t mod = next->type == TMPFS_TYPE_DIRECTORY ? DT_DIR : DT_REG; - if(next->type == TMPFS_TYPE_SYMLINK) - mod = DT_LNK; - - out->d_reclen = sizeof(vfs::dirent_t); - out->d_ino = next->id; - out->d_off = 0; - out->d_type = mod; - fd->offset++; - - if(out->d_name[0] == 0) - goto again; - - return 0; -} - -std::int32_t __tmpfs__remove(userspace_fd_t* fd, char* path) { - if(!path) - return -EFAULT; - - vfs::tmpfs_node_t* node = __tmpfs__find(path); - - if(!node) - return -ENOENT; - - char copy[2048]; - memset(copy,0,2048); - memcpy(copy,path,strlen(path)); - - if(path[0] == '\0') - return -EINVAL; - - __tmpfs__find_dir(copy); - - if(copy[0] == '\0') { - copy[0] = '/'; - copy[1] = '\0'; - } - - vfs::tmpfs_node_t* parent = __tmpfs__find(copy); - - if(__tmpfs__is_busy(node)) - return -EBUSY; - - if(node->type != TMPFS_TYPE_DIRECTORY) { - - } else { - for(std::uint64_t i = 0;i < node->size / 8;i++) { - __tmpfs__remove(fd,((vfs::tmpfs_node_t*)(((std::uint64_t*)node->content)[fd->offset / 8]))->name); - } - } - - if(parent) { - if(parent->type == TMPFS_TYPE_DIRECTORY) { - std::uint64_t* cont = (std::uint64_t*)parent->content; - - for(std::uint64_t i = 0; i < (parent->size / 8); i++) { - if(cont[i] != 0) { - vfs::tmpfs_node_t* chld_node = (vfs::tmpfs_node_t*)cont[i]; - if((std::uint64_t)chld_node == (std::uint64_t)node) { - cont[i] = 0; - } - } - } - } - } - - memset(node->name,0,2048); - __tmpfs__dealloc(node); - - return 0; -} - -std::int32_t __tmpfs__touch(char* path, int mode) { - if(!path) - return EFAULT; - - vfs::tmpfs_node_t* node = __tmpfs__symfind(path); - - if(!node) { - int status = __tmpfs__create(path,VFS_TYPE_FILE,0); - node = __tmpfs__symfind(path); - if(node) - node->vars[TMPFS_VAR_CHMOD] |= (mode & ~(S_IFDIR | S_IFREG | S_IFCHR | S_IFBLK | S_IFIFO | S_IFDIR | S_IFIFO | S_IFMT | S_IFLNK)); - } - - return 0; - -} - -#define STATX_BASIC_STATS 0x7ff -#define STATX_BTIME 0x800 - - - -std::int32_t __tmpfs__statx(userspace_fd_t* fd, char* path, int flags, int mask, statx_t* out) { - if(!path) - return -EFAULT; - - if(!__tmpfs__exists(path)) - return -ENOENT; - - if(!out) - return -EINVAL; - - vfs::tmpfs_node_t* node = __tmpfs__symfind(path); - - memset(out,0,sizeof(statx_t)); - - out->stx_mask = STATX_BASIC_STATS | STATX_BTIME; - out->stx_blksize = 4096; - out->stx_nlink = 0; - out->stx_uid = 0; - out->stx_gid = 0; - out->stx_mode = 0; - switch(node->type) { - case TMPFS_TYPE_DIRECTORY: - out->stx_mode |= S_IFDIR; - break; - case TMPFS_TYPE_FILE: - out->stx_mode |= S_IFREG; - break; - case TMPFS_TYPE_SYMLINK: - out->stx_mode |= S_IFLNK; - break; - default: - out->stx_mode |= S_IFREG; - break; - } - out->stx_ino = node->id; - out->stx_size = node->size; - out->stx_blocks = node->real_size / 512; - out->stx_atime.tv_sec = node->access_time; - out->stx_atime.tv_nsec = 0; - out->stx_btime.tv_sec = node->create_time; - out->stx_btime.tv_nsec = 0; - out->stx_ctime.tv_sec = node->access_time; - out->stx_ctime.tv_nsec = 0; - out->stx_mtime.tv_sec = node->access_time; - out->stx_mtime.tv_nsec = 0; - out->stx_rdev_major = 0; - out->stx_rdev_minor = 0; - out->stx_dev_major = 0; - out->stx_dev_minor = 0; - return 0; -} - -std::int32_t __tmpfs__stat(userspace_fd_t* fd, char* path, vfs::stat_t* out) { - if(!path) - return EFAULT; - -vfs::tmpfs_node_t* node = __tmpfs__symfind(path); - - if(!node) - return ENOENT; - - if(!out) - return EINVAL; - - - if(!node) - return ENOENT; - - out->st_size = node->type == TMPFS_TYPE_DIRECTORY ? 0 : node->size; - out->st_mode = node->type == TMPFS_TYPE_DIRECTORY ? S_IFDIR : S_IFREG; - if(node->type == TMPFS_TYPE_SYMLINK) - out->st_mode = S_IFLNK; - out->st_mode |= ((node->vars[0] & ~(S_IFDIR | S_IFREG | S_IFCHR | S_IFBLK | S_IFIFO | S_IFDIR | S_IFIFO | S_IFMT | S_IFLNK)) & 0xFFFFFFFF); - out->st_uid = 0; - out->st_gid = 0; - out->st_blksize = 4096; - out->st_ino = node->id; - out->st_nlink = 0; // unimplemented - out->st_dev = 0; - out->st_rdev = 0; - out->st_blocks = node->real_size / 4096; - out->st_atim.tv_sec = node->access_time; - out->st_mtim.tv_sec = node->access_time; - out->st_ctim.tv_sec = node->create_time; - out->st_atim.tv_nsec = 0; - out->st_mtim.tv_nsec = 0; - out->st_ctim.tv_nsec = 0; - - return 0; -} - -// note for me never touch this in future -std::int32_t __tmpfs__readlink(char* path, char* out, std::uint32_t out_len) { - if(!path) - return EFAULT; - - vfs::tmpfs_node_t* node = __tmpfs__symfind(path); - - if(!node) - return ENOENT; - - if(!out) - return EINVAL; - - if(!node) - return ENOENT; - - if(node->type != TMPFS_TYPE_SYMLINK) - return EINVAL; - - if(node->size >= out_len) { - Log::SerialDisplay(LEVEL_MESSAGE_INFO,"ur taking too long nodesize %d outlen %d",node->size,out_len); - return EINVAL; - } - - if(!node->content) - return EINVAL; // symlink is not initializied now :( - - memcpy(out,node->content,node->size + 1); - - return 0; -} - -void __tmpfs_build_newfile(char* path, char* new_path, int path_start_len, char* result) { - char temp_path[2048]; // /usr/bin -> /bin - memset(temp_path,0,2048); - memcpy(temp_path,path + path_start_len,strlen(path + path_start_len)); - memcpy(result,new_path,strlen(new_path)); - memcpy(result + strlen(new_path),temp_path,strlen(temp_path) + 1); - if(result[0] == '/' && result[1] == '/') { - // fix - memset(temp_path,0,2048); - memcpy(temp_path,result + 1, strlen(result + 1)); - memcpy(result,temp_path,strlen(temp_path) + 1); - } -} - -void __tmpfs__rename_dirents(char* path, char* new_path, int path_start_len) { - if(!__tmpfs__exists(path)) - return; - - vfs::tmpfs_node_t* node = __tmpfs__symfind(path); - - if(!node) - return; - - if(node->busy != 0) - return; - - char old_node_path[2048]; - memcpy(old_node_path,node->name,strlen(node->name) + 1); - - if(node->type == TMPFS_TYPE_DIRECTORY) { - - std::uint64_t* cont = (std::uint64_t*)node->content; - for(std::uint64_t i = 0; i < (node->size / 8); i++) { - if(cont[i] != 0) { - vfs::tmpfs_node_t* chld_node = (vfs::tmpfs_node_t*)cont[i]; - char old_name[2048]; - memset(old_name,0,2048); - memcpy(old_name,chld_node->name,strlen(chld_node->name) + 1); - memset(chld_node->name,0,sizeof(chld_node->name)); - __tmpfs_build_newfile(old_name,node->name,path_start_len,chld_node->name); - chld_node->path_hash = hash_fnv1(chld_node->name); - DEBUG(1,"new_path %s\n",chld_node->name); - if(chld_node->type == TMPFS_TYPE_DIRECTORY) { - __tmpfs__rename_dirents(chld_node->name,new_path,path_start_len); - } - } - } - } - return; -} - -std::int32_t __tmpfs__rename(char* path, char* new_path) { - if(!__tmpfs__exists(path)) - return -ENOENT; - - vfs::tmpfs_node_t* node = __tmpfs__symfind(path); - - if(!node) - return -ENOENT; - - if(node->busy != 0) - return -EBUSY; - - if(__tmpfs__is_busy(node)) - return -EBUSY; - - char old_node_path[2048]; - memcpy(old_node_path,node->name,strlen(node->name) + 1); - - vfs::tmpfs_node_t* node2 = __tmpfs__symfind(new_path); - - if(node2) { - - if(node2->busy != 0) - return -EBUSY; - - if(node2->type == TMPFS_TYPE_DIRECTORY) { - // man says it shoudl return error only if its non empty - int is_non_empty = 1; - for(std::uint64_t i = 0;i < node2->size / 8; i++) { - if((node2->content[i])) - return ENOTEMPTY; - } - } - - userspace_fd_t fd; - memset(&fd,0,sizeof(fd)); - __tmpfs__remove(&fd,new_path); - } - - char copy[2048]; - memset(copy,0,2048); - memcpy(copy,path,strlen(path)); - - __tmpfs__find_dir(copy); - - if(copy[0] == '\0') { - copy[0] = '/'; - copy[1] = '\0'; - } - - if(!__tmpfs__exists(copy)) { - if(!__tmpfs__create_parent_dirs_by_default) - return ENOENT; - else { - __tmpfs__create(copy,TMPFS_TYPE_DIRECTORY,0); - } - } - - if(__tmpfs__find(copy)->type != VFS_TYPE_DIRECTORY) - return -ENOTDIR; - - vfs::tmpfs_node_t* parent = __tmpfs__find(copy); - if(parent->size <= DIRECTORY_LIST_SIZE) { - // first: find free entry - - std::uint64_t* free_entry = 0; - for(std::uint64_t i = 0; i < (parent->size / 8); i++) { - if(((std::uint64_t*)parent->content)[i] == (std::uint64_t)node) { - free_entry = &(((std::uint64_t*)parent->content)[i]); - *free_entry = 0; - } - } - - } - - int path_start_len = strlen(node->name); - if(node->name[0] == '/' && node->name[1] == '\0') - path_start_len = 0; - - memset(node->name,0,2048); - memcpy(node->name,new_path,strlen(new_path)); - - node->path_hash = hash_fnv1(node->name); - - if(node->type == TMPFS_TYPE_DIRECTORY) { - - std::uint64_t* cont = (std::uint64_t*)node->content; - for(std::uint64_t i = 0; i < (node->size / 8); i++) { - if(cont[i] != 0) { - vfs::tmpfs_node_t* chld_node = (vfs::tmpfs_node_t*)cont[i]; - char old_name[2048]; - memset(old_name,0,2048); - memcpy(old_name,chld_node->name,strlen(chld_node->name) + 1); - memset(chld_node->name,0,sizeof(chld_node->name)); - __tmpfs_build_newfile(old_name,node->name,path_start_len,chld_node->name); - chld_node->path_hash = hash_fnv1(chld_node->name); - DEBUG(1,"new_path %s\n",chld_node->name); - if(chld_node->type == TMPFS_TYPE_DIRECTORY) { - __tmpfs__rename_dirents(chld_node->name,new_path,path_start_len); - } - } - } - } - - memset(copy,0,2048); - memcpy(copy,path,strlen(path)); - - __tmpfs__find_dir(copy); - - if(copy[0] == '\0') { - copy[0] = '/'; - copy[1] = '\0'; - } - - if(!__tmpfs__exists(copy)) { - if(!__tmpfs__create_parent_dirs_by_default) - return ENOENT; - else { - __tmpfs__create(copy,TMPFS_TYPE_DIRECTORY,0); - } - } - - if(__tmpfs__find(copy)->type != VFS_TYPE_DIRECTORY) - return ENOTDIR; - - parent = __tmpfs__find(copy); - if(parent->size <= DIRECTORY_LIST_SIZE) { - // first: find free entry - - std::uint64_t* free_entry = 0; - for(std::uint64_t i = 0; i < (parent->size / 8); i++) { - if(((std::uint64_t*)parent->content)[i] == 0) { - free_entry = &(((std::uint64_t*)parent->content)[i]); - break; - } - } - - if(!free_entry) { - free_entry = &((std::uint64_t*)parent->content)[parent->size / 8]; - parent->size += 8; - } - - *free_entry = (std::uint64_t)node; - - } - - return 0; - -} - -void __tmpfs__close(userspace_fd_t* fd, char* path) { - - vfs::tmpfs_node_t* node = __tmpfs__symfind(path); - - if(!node) - return; - - if(!node) - return; - - if(node->busy > 0) - node->busy--; - - if(node->is_request_unlink) { - if(node->busy == 0) { - __tmpfs__remove(fd,path); - } - } - - return; -} - -std::int32_t __tmpfs__unlink(userspace_fd_t* fd, char* path) { - - if(!path) - return -EINVAL; - - vfs::tmpfs_node_t* node = __tmpfs__symfind(path); - if(!node) - return -ENOENT; - - node->is_request_unlink = 1; - if(node->busy == 0) { - __tmpfs__remove(fd,path); - } - - return 0; -} - -void vfs::tmpfs::mount(vfs_node_t* node) { - - head_node = (tmpfs_node_t*)memory::pmm::_virtual::alloc(4096); - - head_node->type = TMPFS_TYPE_DIRECTORY; - head_node->id = 0; - - root_node = head_node; - - memcpy(head_node->name,"/",1); - - head_node->path_hash = hash_fnv1(head_node->name); - - head_node->content = (std::uint8_t*)memory::pmm::_virtual::alloc(DIRECTORY_LIST_SIZE); - - node->readlink = __tmpfs__readlink; - node->create = (int (*)(char*,uint8_t))__tmpfs__create; - node->remove = __tmpfs__remove; - node->rename = __tmpfs__rename; - node->write = __tmpfs__write; - node->touch = __tmpfs__touch; - node->close = __tmpfs__close; - node->read = __tmpfs__read; - node->open = __tmpfs__open; - node->stat = __tmpfs__stat; - node->var = __tmpfs__var; - node->ls = __tmpfs__ls; - - node->statx = __tmpfs__statx; - node->unlink = __tmpfs__unlink; - - node->opt_create_and_write = __tmpfs__opt_create_and_write; - -}
\ No newline at end of file diff --git a/kernel/src/generic/vfs/ustar.cpp b/kernel/src/generic/vfs/ustar.cpp deleted file mode 100644 index 7aa2c6d..0000000 --- a/kernel/src/generic/vfs/ustar.cpp +++ /dev/null @@ -1,177 +0,0 @@ - -#include <cstdint> - -#include <generic/vfs/ustar.hpp> -#include <generic/vfs/vfs.hpp> - -#include <etc/bootloaderinfo.hpp> -#include <etc/logging.hpp> -#include <limine.h> - -#include <etc/etc.hpp> - -inline int oct2bin(unsigned char *str, int size) { - - if(!str) - return 0; - - std::uint64_t n = 0; - volatile unsigned char *c = str; - for(int i = 0;i < size;i++) { - n *= 8; - n += *c - '0'; - c++; - - } - return n; -} - - -void __ustar_fault(const char* msg) { - - Log::Display(LEVEL_MESSAGE_FAIL,"Can't continue kernel work ! initrd error, msg \"%s\"\n",msg); - - while(1) { - asm volatile("hlt"); - } -} - -#define TAR_BLOCK_SIZE 512 - -std::uint64_t count_tar_files_simple(const unsigned char *data, size_t size) { - int count = 0; - size_t pos = 0; - - while (pos + TAR_BLOCK_SIZE <= size) { - int all_zero = 1; - for (int i = 0; i < TAR_BLOCK_SIZE; i++) { - if (data[pos + i] != 0) { - all_zero = 0; - break; - } - } - - if (all_zero) { - if (pos + 2 * TAR_BLOCK_SIZE <= size) { - all_zero = 1; - for (int i = 0; i < TAR_BLOCK_SIZE; i++) { - if (data[pos + TAR_BLOCK_SIZE + i] != 0) { - all_zero = 0; - break; - } - } - if (all_zero) break; - } - } - - count++; - - unsigned long file_size = 0; - for (int i = 0; i < 11; i++) { - unsigned char c = data[pos + 124 + i]; - if (c < '0' || c > '7') break; - file_size = file_size * 8 + (c - '0'); - } - - unsigned long blocks = (file_size + TAR_BLOCK_SIZE - 1) / TAR_BLOCK_SIZE; - pos += (1 + blocks) * TAR_BLOCK_SIZE; - - if (pos > size) break; - } - - return count; -} - - -extern const char* level_messages[]; -void update_progress_bar(int current, int total, int bar_width) { - static int last_percent = -1; - - int percent = 0; - if (total > 0) { - percent = (current * 100) / total; - } - - if (percent == last_percent && current != total) { - return; - } - last_percent = percent; - - int filled_width = 0; - if (percent > 0) { - filled_width = (percent * bar_width) / 100; - if (filled_width > bar_width) { - filled_width = bar_width; - } - } - - printf("\r%sLoading initrd ",level_messages[LEVEL_MESSAGE_INFO]); - - printf("["); - for (int i = 0; i < bar_width; i++) { - if (i < filled_width) { - printf("="); - } else if (i == filled_width && percent < 100) { - printf(">"); - } else { - printf(" "); - } - } - printf("] %3d%% (%d/%d)", percent, current, total); - - if (current >= total) { - printf("\n"); - } - -} - -extern std::uint8_t __tmpfs__create_parent_dirs_by_default; -extern std::uint8_t __tmpfs__dont_alloc_memory; - - -void vfs::ustar::copy() { - struct limine_module_response* initrd = BootloaderInfo::AccessInitrd(); - if(!initrd || initrd->module_count < 1) - __ustar_fault("there's no initrd"); - - ustar_header_t* current = (ustar_header_t*)initrd->modules[0]->address; - - std::uint64_t total = count_tar_files_simple((std::uint8_t*)current,initrd->modules[0]->size); - std::uint64_t currentp = 0; - - Log::Raw("%sLoading initrd ",level_messages[LEVEL_MESSAGE_INFO]); - - std::uint64_t actual_tar_ptr_end = ((uint64_t)initrd->modules[0]->address + initrd->modules[0]->size) - 1024; - while((std::uint64_t)current < actual_tar_ptr_end) { - std::uint8_t type = oct2bin((uint8_t*)¤t->type,1); - switch(type) { - case 0: { - char* file = (char*)((uint64_t)current->file_name + 1); - int size = oct2bin((uint8_t*)current->file_size,strlen(current->file_size)); - std::uint64_t actual_mode = oct2bin((uint8_t*)current->file_mode,7); - vfs::vfs::opt_create_and_write(file,VFS_TYPE_FILE,(char*)((std::uint64_t)current + 512),size,actual_mode); - break; - } - - case 5: { - char* file = (char*)((uint64_t)current->file_name + 1); - std::uint64_t actual_mode = oct2bin((uint8_t*)current->file_mode,7); - vfs::vfs::opt_create_and_write(file,VFS_TYPE_DIRECTORY,0,0,actual_mode); - break; - } - - case 2: { - char* file = (char*)((uint64_t)current->file_name + 1); - std::uint64_t actual_mode = oct2bin((uint8_t*)current->file_mode,7); - vfs::vfs::opt_create_and_write(file,VFS_TYPE_SYMLINK,current->name_linked,strlen(current->name_linked),actual_mode); - break; - } - } - currentp++; - update_progress_bar(currentp,total,25); - current = (ustar_header_t*)((uint64_t)current + ALIGNUP(oct2bin((uint8_t*)¤t->file_size,strlen(current->file_size)),512) + 512); - } - - __tmpfs__create_parent_dirs_by_default = 0; - -}
\ No newline at end of file diff --git a/kernel/src/generic/vfs/vfs.cpp b/kernel/src/generic/vfs/vfs.cpp deleted file mode 100644 index e7f2fd2..0000000 --- a/kernel/src/generic/vfs/vfs.cpp +++ /dev/null @@ -1,922 +0,0 @@ - -#include <generic/mm/pmm.hpp> -#include <generic/vfs/vfs.hpp> -#include <generic/vfs/tmpfs.hpp> -#include <generic/locks/spinlock.hpp> -#include <generic/vfs/devfs.hpp> - -#include <generic/vfs/evdev.hpp> - -#include <arch/x86_64/syscalls/sockets.hpp> - -#include <cstdint> -#include <etc/errno.hpp> - -#include <etc/logging.hpp> - -vfs::vfs_node_t vfs_nodes[512]; -locks::spinlock* vfs_lock; - -vfs::vfs_node_t* find_node(char* path) { - std::uint64_t r = 0; - vfs::vfs_node_t* match; - for(int i = 0;i < 512;i++) { - if(!strncmp(path,vfs_nodes[i].path,strlen(vfs_nodes[i].path))) { - if(strlen(vfs_nodes[i].path) > r) { - match = &vfs_nodes[i]; - } - } - - if(!strncmp(path, vfs_nodes[i].path,strlen(vfs_nodes[i].path) - 1) && path[strlen(vfs_nodes[i].path) + 1] == '\0') { - return &vfs_nodes[i]; - } - - } - return match; -} - -vfs::fifo_node_t* fifo_head = 0; - -int is_fifo_exists(char* path) { - vfs::fifo_node_t* current = fifo_head; - while(current) { - if(!strcmp(current->path,path)) - return 1; - current = current->next; - } - return 0; -} - -vfs::fifo_node_t* fifo_get(char* path) { - - vfs::fifo_node_t* current = fifo_head; - while(current) { - if(!strcmp(current->path,path)) - return current; - current = current->next; - } - return 0; - -} - -char * __vfs__strtok(char **next,char *str, const char *delim) { - if (str) *next = str; - if (!*next) return NULL; - - char *start = *next; - while (*start && strchr(delim, *start)) { - start++; - } - if (!*start) { - *next = NULL; - return NULL; - } - - char *end = start; - while (*end && !strchr(delim, *end)) { - end++; - } - - if (*end) { - *end = '\0'; - *next = end + 1; - } else { - *next = NULL; - } - - return start; -} - -int cc = 0; // symlink resolve only used from lock - -// /bin/path -> /usr/bin/path -void __vfs_symlink_resolve_no_at_symlink_follow(char* path, char* out) { - char *next = NULL; - char buffer[2048]; - - int e = vfs::vfs::readlink(path,buffer,2048); - - if(!vfs_lock->test()) - Log::Display(LEVEL_MESSAGE_WARN,"vfs_lock didnt set lock in symlink resolve"); - - if(e == ENOSYS) - memcpy(out,path,strlen(path) + 1); - - if(e == EINVAL) - memcpy(out,path,strlen(path) + 1); - else if(e == 0) { - - memcpy(out,path,strlen(path) + 1); - } else if(e == ENOENT) { - memcpy(out,path,strlen(path) + 1); - // maybe it wants directory symlink ? - char path0[2048]; - memcpy(path0,path,strlen(path) + 1); - - char result[2048]; - - int c = 0; - - char* token = __vfs__strtok(&next, path0, "/"); - - /* Start building path from null and trying to find symlink */ - while(token) { - - result[c] = '/'; - c++; - - std::uint64_t mm = 0; - mm = strlen(token); - memcpy((char*)((std::uint64_t)result + c),token,mm); - c += mm; - result[c] = '\0'; - - e = vfs::vfs::readlink(result,buffer,2048); - if(e == 0) { - char buffer2[2048]; - vfs::resolve_path(buffer,result,buffer2,0,1); - c = strlen(buffer2); - buffer2[c++] = '/'; - memcpy(buffer2 + c, path + strlen(result) + 1, strlen(path) - strlen(result)); - __vfs_symlink_resolve_no_at_symlink_follow(buffer2,out); - return; - } else if(e == ENOENT) { - memcpy(out,path,strlen(path) + 1); - } - - token = __vfs__strtok(&next,0,"/"); - } - memcpy(out,path,strlen(path) + 1); - } -} - -void __vfs_symlink_resolve(char* path, char* out, int level) { - - char *next = NULL; - - char buffer[2048]; - - if(level == 25) { - // hell no :skull: - memcpy(out,path,strlen(path) + 1); - return; - } - - int e = vfs::vfs::readlink(path,buffer,2048); - - if(e == ENOSYS) - memcpy(out,path,strlen(path) + 1); - - if(e == EINVAL) - memcpy(out,path,strlen(path) + 1); - else if(e == 0) { - - char result[2048]; - vfs::resolve_path(buffer,path,result,0,1); - __vfs_symlink_resolve(result,out, level + 1); - } else if(e == ENOENT) { - memcpy(out,path,strlen(path) + 1); - // maybe it wants directory symlink ? - char path0[2048]; - memcpy(path0,path,strlen(path) + 1); - - char result[2048]; - - int c = 0; - - char* token = __vfs__strtok(&next, path0, "/"); - - /* Start building path from null and trying to find symlink */ - while(token) { - - result[c] = '/'; - c++; - - std::uint64_t mm = 0; - mm = strlen(token); - memcpy((char*)((std::uint64_t)result + c),token,mm); - c += mm; - result[c] = '\0'; - - e = vfs::vfs::readlink(result,buffer,2048); - if(e == 0) { - char buffer2[2048]; - vfs::resolve_path(buffer,result,buffer2,0,1); - c = strlen(buffer2); - buffer2[c++] = '/'; - memcpy(buffer2 + c, path + strlen(result) + 1, strlen(path) - strlen(result)); - __vfs_symlink_resolve(buffer2,out, level + 1); - return; - } else if(e == ENOENT) { - memcpy(out,path,strlen(path) + 1); - return; - } else { - memcpy(out,path,strlen(path) + 1); - return; - } - - token = __vfs__strtok(&next,0,"/"); - } - memcpy(out,path,strlen(path) + 1); - } -} - -std::uint32_t vfs::vfs::create_fifo(char* path) { - - vfs_lock->lock(); - - if(!path) { - vfs_lock->unlock(); - return EINVAL; - } - - if(is_fifo_exists(path)) { - vfs_lock->unlock(); - return EEXIST; - } - - fifo_node_t* current = fifo_head; - while(current) { - if(!current->is_used) - break; - current = current->next; - } - - if(!current) { - current = new fifo_node_t; - current->next = fifo_head; - fifo_head = current; - } - - current->main_pipe = new pipe(0); - current->main_pipe->connected_to_pipe_write = 2; - - memset(current->path,0,2048); - memcpy(current->path,path,strlen(path)); - - current->is_used = 1; - - vfs_lock->unlock(); - return 0; -} - -std::int64_t vfs::vfs::write(userspace_fd_t* fd, void* buffer, std::uint64_t size) { - vfs_lock->lock(); - - char out[2048]; - - if(!fd->is_cached_path) { - __vfs_symlink_resolve(fd->path,out,0); - memcpy(fd->path,out,strlen(out) + 1); - fd->is_cached_path = 1; - } else - memcpy(out,fd->path,strlen(fd->path) + 1); - - - if(is_fifo_exists(out)) { - fifo_node_t* fifo = fifo_get(out); - vfs_lock->unlock(); - return fifo->main_pipe->write((const char*)buffer,size,0); - } - - vfs_node_t* node = find_node(out); - if(!node) { vfs::vfs::unlock(); - return -ENOENT; } - - char* fs_love_name = &out[0] + strlen(node->path) - 1; - if(!node->write) { vfs::vfs::unlock(); - return -ENOSYS; } - - std::int64_t status = node->write(fd,fs_love_name,buffer,size); - return status; -} - -std::int64_t vfs::vfs::read(userspace_fd_t* fd, void* buffer, std::uint64_t count) { - vfs_lock->lock(); - - char out[2048]; - - if(!fd->is_cached_path) { - __vfs_symlink_resolve(fd->path,out,0); - memcpy(fd->path,out,strlen(out) + 1); - fd->is_cached_path = 1; - } else - memcpy(out,fd->path,strlen(fd->path) + 1); - - if(is_fifo_exists(out)) { - fifo_node_t* fifo = fifo_get(out); - vfs_lock->unlock(); - return fifo->main_pipe->read(&fd->read_counter,(char*)buffer,count,(fd->flags & O_NONBLOCK) ? 1 : 0); - } - - vfs_node_t* node = find_node(out); - if(!node) { vfs::vfs::unlock(); - return -ENOENT; } - - char* fs_love_name = out + strlen(node->path) - 1; - if(!node->read) { vfs::vfs::unlock(); - return -ENOSYS; } - - std::int64_t status = node->read(fd,fs_love_name,buffer,count); - assert(status != -9,"omg"); - return status; -} - -std::int32_t vfs::vfs::create(char* path, std::uint8_t type) { - vfs_lock->lock(); - - char out[2048]; - memset(out,0,2048); - - __vfs_symlink_resolve(path,out,0); - - if(sockets::is_exists(out) || is_fifo_exists(out)) { - vfs_lock->unlock(); - return -EEXIST; - } - - vfs_node_t* node = find_node(out); - if(!node) { vfs::vfs::unlock(); - return -ENOENT; } - - char* fs_love_name = out + strlen(node->path) - 1; - if(!node->create) { vfs::vfs::unlock(); - return -ENOSYS; } - - - std::int32_t status = ((std::int32_t (*)(char*,int,long long))node->create)(out,type,0); - vfs_lock->unlock(); - return status; -} - -std::int32_t vfs::vfs::mmap(userspace_fd_t* fd, std::uint64_t* outp, std::uint64_t* outsz, std::uint64_t* outflags) { - vfs_lock->lock(); - - char out[2048]; - memset(out,0,2048); - - if(!fd->is_cached_path) { - __vfs_symlink_resolve(fd->path,out,0); - memcpy(fd->path,out,strlen(out)); - fd->is_cached_path = 1; - } else - memcpy(out,fd->path,strlen(fd->path)); - - vfs_node_t* node = find_node(out); - if(!node) { vfs::vfs::unlock(); - return ENOENT; } - - char* fs_love_name = out + strlen(node->path) - 1; - if(!node->mmap) { vfs::vfs::unlock(); - return ENOSYS; } - - std::int32_t status = node->mmap(fd,fs_love_name,outp,outsz,outflags); - vfs_lock->unlock(); - return status; -} - -std::int32_t vfs::vfs::open(userspace_fd_t* fd) { - vfs_lock->lock(); - - char out[2048]; - memset(out,0,2048); - - if(!fd->is_cached_path) { - __vfs_symlink_resolve(fd->path,out,0); - memcpy(fd->path,out,strlen(out) + 1); - fd->is_cached_path = 1; - } else - memcpy(out,fd->path,strlen(fd->path)); - - if(is_fifo_exists(out)) { - fifo_node_t* fifo = fifo_get(out); - vfs_lock->unlock(); - return 0; - } - - vfs_node_t* node = find_node(out); - - if(!node) { vfs::vfs::unlock(); - return ENOENT; } - - char* fs_love_name = out + strlen(node->path) - 1; - if(!node->open) { vfs::vfs::unlock(); - return ENOSYS; } - - std::int32_t status = node->open(fd,fs_love_name); - vfs_lock->unlock(); - return status; -} - -std::int32_t vfs::vfs::remove(userspace_fd_t* fd) { - vfs_lock->lock(); - - char out[2048]; - memset(out,0,2048); - - __vfs_symlink_resolve(fd->path,out,0); - - if(is_fifo_exists(out)) { - fifo_node_t* fifo = fifo_get(out); - memset(fifo->path,0,2048); - fifo->is_used = 0; - delete fifo->main_pipe; - vfs_lock->unlock(); - return 0; - } - - vfs_node_t* node = find_node(out); - if(!node) { vfs::vfs::unlock(); - return ENOENT; } - - char* fs_love_name = out + strlen(node->path) - 1; - if(!node->remove) {vfs::vfs::unlock(); - return ENOSYS; } - - std::int32_t status = node->remove(fd,fs_love_name); - vfs_lock->unlock(); - return status; -} - -std::int32_t vfs::vfs::ls(userspace_fd_t* fd, dirent_t* out) { - vfs_lock->lock(); - - char out0[2048]; - memset(out0,0,2048); - - if(!fd->is_cached_path) { - __vfs_symlink_resolve(fd->path,out0,0); - memcpy(fd->path,out0,strlen(out0)); - fd->is_cached_path = 1; - } else - memcpy(out0,fd->path,strlen(fd->path)); - - vfs_node_t* node = find_node(out0); - if(!node) { vfs::vfs::unlock(); - return ENOENT; } - - char* fs_love_name = out0 + strlen(node->path) - 1; - if(!node->ls) { vfs::vfs::unlock(); - return ENOSYS; } - - std::int32_t status = node->ls(fd,fs_love_name,out); - vfs_lock->unlock(); - return status; -} - -std::int32_t vfs::vfs::var(userspace_fd_t* fd, std::uint64_t value, std::uint8_t request) { - vfs_lock->lock(); - - char out[2048]; - memset(out,0,2048); - - if(!fd->is_cached_path) { - __vfs_symlink_resolve(fd->path,out,0); - memcpy(fd->path,out,strlen(out)); - fd->is_cached_path = 1; - } else - memcpy(out,fd->path,strlen(fd->path)); - - if((sockets::is_exists(out))) { - socket_node_t* node = sockets::find(out); - if(request & (1 << 7)) - node->vars[request & ~(1 << 7)] = value; - else - *(std::uint64_t*)value = node->vars[request & ~(1 << 7)]; - vfs_lock->unlock(); - return 0; - } - - vfs_node_t* node = find_node(out); - if(!node) { vfs::vfs::unlock(); - return ENOENT; } - - char* fs_love_name = out + strlen(node->path) - 1; - if(!node->var) { vfs::vfs::unlock(); - return ENOSYS; } - - std::int32_t status = node->var(fd,fs_love_name,value,request); - vfs_lock->unlock(); - return status; -} - -std::int32_t vfs::vfs::touch(char* path, int mode) { - vfs_lock->lock(); - - char out[2048]; - memset(out,0,2048); - - __vfs_symlink_resolve(path,out,0); - - if(sockets::is_exists(out) || is_fifo_exists(out)) { - vfs_lock->unlock(); - return EEXIST; - } - - vfs_node_t* node = find_node(out); - if(!node) { vfs::vfs::unlock(); - return ENOENT; } - - char* fs_love_name = out + strlen(node->path) - 1; - if(!node->touch) { vfs::vfs::unlock(); - return ENOSYS; } - - std::int32_t status = node->touch(fs_love_name, mode); - vfs_lock->unlock(); - return status; -} - -std::int32_t vfs::vfs::nosym_stat(userspace_fd_t* fd, stat_t* out) { - vfs_lock->lock(); - - char out0[2048]; - memset(out0,0,2048); - - __vfs_symlink_resolve_no_at_symlink_follow(fd->path,out0); - - if(is_fifo_exists(out0)) { - memset(out,0,sizeof(stat_t)); - out->st_mode |= S_IFIFO; - vfs_lock->unlock(); - return 0; - } - - if(sockets::is_exists(out0)) { - memset(out,0,sizeof(stat_t)); - out->st_mode |= S_IFSOCK; - vfs_lock->unlock(); - return 0; - } - - vfs_node_t* node = find_node(out0); - if(!node) { vfs::vfs::unlock(); - return ENOENT; } - - char* fs_love_name = out0 + strlen(node->path) - 1; - if(!node->stat) { vfs::vfs::unlock(); - return ENOSYS; } - - std::int32_t status = node->stat(fd,fs_love_name,out); - vfs_lock->unlock(); - return status; -} - -std::int32_t vfs::vfs::statx(userspace_fd_t* fd, int flags, int mask, statx_t* out) { - vfs_lock->lock(); - - char out0[2048]; - memset(out0,0,2048); - - if(!fd->is_cached_path) { - if(flags & AT_SYMLINK_NOFOLLOW) { - __vfs_symlink_resolve_no_at_symlink_follow(fd->path,out0); - } else - __vfs_symlink_resolve(fd->path,out0,0); - memcpy(fd->path,out0,strlen(out0)); - fd->is_cached_path = 1; - } else - memcpy(out0,fd->path,strlen(fd->path)); - - vfs_node_t* node = find_node(out0); - if(!node) { vfs::vfs::unlock(); - return -ENOENT; } - - char* fs_love_name = out0 + strlen(node->path) - 1; - if(!node->statx) { vfs::vfs::unlock(); - return -ENOSYS; } - - std::int32_t status = node->statx(fd,fs_love_name,flags,mask,out); - vfs_lock->unlock(); - return status; -} - -std::int32_t vfs::vfs::stat(userspace_fd_t* fd, stat_t* out) { - vfs_lock->lock(); - - char out0[2048]; - memset(out0,0,2048); - - if(!fd->is_cached_path) { - __vfs_symlink_resolve(fd->path,out0,0); - memcpy(fd->path,out0,strlen(out0)); - fd->is_cached_path = 1; - } else - memcpy(out0,fd->path,strlen(fd->path)); - - if(is_fifo_exists(out0)) { - memset(out,0,sizeof(stat_t)); - out->st_mode |= S_IFIFO; - vfs_lock->unlock(); - return 0; - } - - if(sockets::is_exists(out0)) { - memset(out,0,sizeof(stat_t)); - out->st_mode |= S_IFSOCK; - vfs_lock->unlock(); - return 0; - } - - vfs_node_t* node = find_node(out0); - if(!node) { vfs::vfs::unlock(); - return ENOENT; } - - char* fs_love_name = out0 + strlen(node->path) - 1; - if(!node->stat) { vfs::vfs::unlock(); - return ENOSYS; } - - std::int32_t status = node->stat(fd,fs_love_name,out); - vfs_lock->unlock(); - return status; -} - -std::int64_t vfs::vfs::ioctl(userspace_fd_t* fd, unsigned long req, void *arg, int *res) { - vfs_lock->lock(); - - char out0[2048]; - memset(out0,0,2048); - - if(!fd->is_cached_path) { - __vfs_symlink_resolve(fd->path,out0,0); - memcpy(fd->path,out0,strlen(out0)); - fd->is_cached_path = 1; - } else - memcpy(out0,fd->path,strlen(fd->path)); - - vfs_node_t* node = find_node(out0); - if(!node) { vfs::vfs::unlock(); - return ENOENT; } - - char* fs_love_name = out0 + strlen(node->path) - 1; - if(!node->ioctl) { vfs::vfs::unlock(); - return ENOTTY; } - - std::int64_t status = node->ioctl(fd,fs_love_name,req,arg,res); - vfs_lock->unlock(); - return status; -} - -std::int32_t vfs::vfs::unlink(userspace_fd_t* fd) { - vfs_lock->lock(); - - char out0[2048]; - memset(out0,0,2048); - - if(!fd->is_cached_path) { - __vfs_symlink_resolve(fd->path,out0,0); - memcpy(fd->path,out0,strlen(out0)); - fd->is_cached_path = 1; - } else - memcpy(out0,fd->path,strlen(fd->path)); - - vfs_node_t* node = find_node(out0); - if(!node) { vfs::vfs::unlock(); - return -ENOENT; } - - char* fs_love_name = out0 + strlen(node->path) - 1; - if(!node->unlink) { vfs::vfs::unlock(); - return -ENOTSUP; } - - std::int32_t ret = node->unlink(fd,fs_love_name); - vfs_lock->unlock(); - return ret; -} - - -void vfs::vfs::close(userspace_fd_t* fd) { - vfs_lock->lock(); - - char out0[2048]; - memset(out0,0,2048); - - if(fd->state == USERSPACE_FD_STATE_SOCKET) { - // fd->read_socket_pipe->lock.lock(); - // fd->write_socket_pipe->lock.lock(); - // fd->read_socket_pipe->is_closed.test_and_set(); - // fd->write_socket_pipe->is_closed.test_and_set(); - // fd->read_socket_pipe->lock.unlock(); - // fd->write_socket_pipe->lock.unlock(); - vfs_lock->unlock(); - return; - } - - if(!fd->is_cached_path) { - __vfs_symlink_resolve(fd->path,out0,0); - memcpy(fd->path,out0,strlen(out0)); - fd->is_cached_path = 1; - } else - memcpy(out0,fd->path,strlen(fd->path)); - - if(is_fifo_exists(out0)) { - fifo_node_t* fifo = fifo_get(out0); - fifo->main_pipe->fifoclose(); - vfs_lock->unlock(); - return; - } - - vfs_node_t* node = find_node(out0); - if(!node) { vfs::vfs::unlock(); - return; } - - char* fs_love_name = out0 + strlen(node->path) - 1; - if(!node->close) { vfs::vfs::unlock(); - return; } - - node->close(fd,fs_love_name); - vfs_lock->unlock(); - return; -} - -std::int32_t vfs::vfs::rename(char* path, char* new_path) { - vfs_lock->lock(); - - char out0[2048]; - char new_path0[2048]; - - __vfs_symlink_resolve(path,out0,0); - __vfs_symlink_resolve(new_path,new_path0,0); - - if(is_fifo_exists(out0)) { - return -ENOSYS; - } - - vfs_node_t* node = find_node(out0); - if(!node) { vfs::vfs::unlock(); - return -ENOENT; } - - vfs_node_t* new_node = find_node(new_path0); - if(new_node != node) { - vfs::vfs::unlock(); - return -EXDEV; - } - - char* fs_love_name = out0 + strlen(node->path) - 1; - char* fs_love_name0 = new_path0 + strlen(node->path) - 1; - if(!node->rename) { vfs::vfs::unlock(); - return -ENOSYS; } - - int status = node->rename(fs_love_name,fs_love_name0); - - if(status != 0) - Log::SerialDisplay(LEVEL_MESSAGE_WARN,"non zero ret %d from rename %s to %s\n",status,path,new_path); - - vfs_lock->unlock(); - return 0; -} - -// internal readlink -std::int32_t vfs::vfs::readlink(char* path, char* out, std::uint32_t out_len) { - if(is_fifo_exists(path)) { - return EINVAL; - } else if(sockets::is_exists(path)) { - return EINVAL; - } - - if(path[0] == '\0') { - path[0] = '/'; - path[1] = '\n'; - } - - vfs_node_t* node = find_node(path); - if(!node) { - return ENOENT; } - - char* fs_love_name = path + strlen(node->path) - 1; - if(!node->readlink) { - return EINVAL; } - - return node->readlink(fs_love_name,out,out_len); -} - -void vfs::vfs::opt_create_and_write(char* path, int type, char* content, std::uint64_t content_len, int chmod) { - vfs_lock->lock(); - vfs_node_t* node = find_node(path); - if(!node) { vfs_lock->unlock(); - return; } - - char* fs_love_name = path + strlen(node->path) - 1; - if(!node->opt_create_and_write) { vfs_lock->unlock(); - return; } - - node->opt_create_and_write(fs_love_name,type,content,content_len,chmod); - vfs_lock->unlock(); - return; -} - -// readlink syscall -std::int32_t vfs::vfs::extern_readlink(char* path, char* out, std::uint32_t out_len) { - - char out0[2048]; - memset(out0,0,2048); - - if(path[0] == '\0') { - path[0] = '/'; - path[1] = '\n'; - } - - __vfs_symlink_resolve_no_at_symlink_follow(path,out0); - - if(is_fifo_exists(out0)) { - return EINVAL; - } else if(sockets::is_exists(out0)) { - return EINVAL; - } - - vfs_node_t* node = find_node(out0); - if(!node) { - return ENOENT; } - - char* fs_love_name = out0 + strlen(node->path) - 1; - if(!node->readlink) { - return EINVAL; } - - return node->readlink(fs_love_name,out,out_len); -} - - -std::int64_t vfs::vfs::poll(userspace_fd_t* fd, int operation_type) { - - vfs::vfs::lock(); - - char out0[2048]; - memset(out0,0,2048); - - if(!fd) { - vfs::vfs::unlock(); - return 0; - } - - if(!fd->is_cached_path) { - __vfs_symlink_resolve(fd->path,out0,0); - memcpy(fd->path,out0,strlen(out0)); - fd->is_cached_path = 1; - } else - memcpy(out0,fd->path,strlen(fd->path)); - - if(is_fifo_exists(out0)) { - fifo_node_t* fifo = fifo_get(out0); - std::int64_t ret = 0; - switch (operation_type) - { - - case POLLIN: - fifo->main_pipe->lock.lock(); - ret = fifo->main_pipe->size != 0 ? 1 : 0; - fifo->main_pipe->lock.lock(); - break; - - case POLLOUT: - fifo->main_pipe->lock.lock(); - ret = fifo->main_pipe->size < fifo->main_pipe->total_size ? 1 : 0; - fifo->main_pipe->lock.lock(); - break; - - default: - break; - } - vfs::vfs::unlock(); - return ret; - } - - vfs_node_t* node = find_node(out0); - if(!node) { vfs::vfs::unlock(); - return -ENOENT; } - - char* fs_love_name = out0 + strlen(node->path) - 1; - if(!node->poll) { vfs::vfs::unlock(); - return -ENOSYS ; } - - std::int64_t ret = node->poll(fd,fs_love_name,operation_type); - vfs::vfs::unlock(); - return ret; -} - - -void vfs::vfs::unlock() { - vfs_lock->unlock(); -} - -void vfs::vfs::lock() { - vfs_lock->lock(); -} - -void vfs::vfs::init() { - - memset(vfs_nodes,0,sizeof(vfs_nodes)); - - vfs_lock = new locks::spinlock; - vfs_lock->unlock(); - - tmpfs::mount(&vfs_nodes[0]); - memcpy(vfs_nodes[0].path,"/",1); - Log::Display(LEVEL_MESSAGE_OK,"TmpFS initializied\n"); - - devfs::mount(&vfs_nodes[1]); - memcpy(vfs_nodes[1].path,"/dev/",5); - Log::Display(LEVEL_MESSAGE_OK,"DevFS initializied\n"); - - evdev::mount(&vfs_nodes[2]); - memcpy(vfs_nodes[2].path,"/dev/input/",sizeof("/dev/input/")); - Log::Display(LEVEL_MESSAGE_OK,"EvDev initializied\n"); - -} diff --git a/kernel/src/klibc/c/assert.h b/kernel/src/klibc/c/assert.h new file mode 100644 index 0000000..0798878 --- /dev/null +++ b/kernel/src/klibc/c/assert.h @@ -0,0 +1,2 @@ + +#define assert(x) 100
\ No newline at end of file diff --git a/kernel/src/klibc/c/stdlib.h b/kernel/src/klibc/c/stdlib.h new file mode 100644 index 0000000..d97c7f4 --- /dev/null +++ b/kernel/src/klibc/c/stdlib.h @@ -0,0 +1,32 @@ +#pragma once + +#include <klibc/string.hpp> +#include <klibc/stdlib.hpp> + +using namespace klibc; + +#define realloc(ptr, new_size) \ + ({ \ + void *__new_ptr = NULL; \ + size_t __new_size = (new_size); \ + \ + if (__new_size == 0) { \ + /* Если размер 0 - free и возвращаем NULL */ \ + if (ptr) free(ptr); \ + __new_ptr = NULL; \ + } else { \ + /* Выделяем новую память */ \ + __new_ptr = malloc(__new_size); \ + if (__new_ptr && ptr) { \ + /* Копируем старые данные (размер неизвестен, копируем сколько влезет) */ \ + /* Примечание: old_size неизвестен, поэтому копируем весь новый размер */ \ + /* Это безопасно только если старый размер >= нового */ \ + memcpy(__new_ptr, ptr, __new_size); \ + } \ + /* Освобождаем старый указатель */ \ + if (ptr) { \ + free(ptr); \ + } \ + } \ + __new_ptr; \ + })
\ No newline at end of file diff --git a/kernel/src/klibc/c/string.h b/kernel/src/klibc/c/string.h new file mode 100644 index 0000000..200c7e4 --- /dev/null +++ b/kernel/src/klibc/c/string.h @@ -0,0 +1,3 @@ +#pragma once +#define memset(a,b,c) klibc::memset(a,b,c) +#define memcpy(a,b,c) klibc::memcpy(a,b,c)
\ No newline at end of file diff --git a/kernel/src/klibc/stdio.cpp b/kernel/src/klibc/stdio.cpp new file mode 100644 index 0000000..7e8e283 --- /dev/null +++ b/kernel/src/klibc/stdio.cpp @@ -0,0 +1,34 @@ +#include <klibc/stdio.hpp> +#include <klibc/string.hpp> +#include <utils/flanterm.hpp> +#include <cstdint> +#include <cstddef> +#include <cstdarg> + +#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 0 +#define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 0 +#define NANOPRINTF_IMPLEMENTATION +#include <nanoprintf.h> + +#include <cstdint> +#include <cstddef> + +int klibc::_snprintf(char *buffer, std::size_t bufsz, char const *fmt, va_list vlist) { + int const rv = npf_vsnprintf(buffer, bufsz, fmt, vlist); + return rv; +} + +void klibc::printf(const char* fmt, ...) { + va_list val; + va_start(val, fmt); + char buffer[4096]; + memset(buffer,0,4096); + int len = _snprintf(buffer,4096,fmt,val); + utils::flanterm::write(buffer,len); + va_end(val); +}
\ No newline at end of file diff --git a/kernel/src/klibc/stdio.hpp b/kernel/src/klibc/stdio.hpp new file mode 100644 index 0000000..cce2bcf --- /dev/null +++ b/kernel/src/klibc/stdio.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include <cstdint> +#include <cstdarg> + +namespace klibc { + + int _snprintf(char *buffer, std::size_t bufsz, char const *fmt, va_list vlist); + + inline static int __printfbuf(char* buffer, std::size_t bufsf, char const* fmt, ...) { + va_list val; + va_start(val, fmt); + return _snprintf(buffer,bufsf,fmt,val); + va_end(val); + } + + void printf(const char* fmt, ...); +};
\ No newline at end of file diff --git a/kernel/src/klibc/stdlib.cpp b/kernel/src/klibc/stdlib.cpp new file mode 100644 index 0000000..ab6e06e --- /dev/null +++ b/kernel/src/klibc/stdlib.cpp @@ -0,0 +1,14 @@ +#include <generic/heap.hpp> +#include <cstdint> + +namespace klibc { + + void* malloc(std::size_t size) { + return kheap::malloc(size); + } + + void free(void* ptr) { + kheap::free(ptr); + } + +};
\ No newline at end of file diff --git a/kernel/src/klibc/stdlib.hpp b/kernel/src/klibc/stdlib.hpp new file mode 100644 index 0000000..582a2a8 --- /dev/null +++ b/kernel/src/klibc/stdlib.hpp @@ -0,0 +1,7 @@ +#pragma once +#include <cstdint> + +namespace klibc { + void* malloc(std::size_t size); + void free(void* ptr); +};
\ No newline at end of file diff --git a/kernel/src/klibc/string.cpp b/kernel/src/klibc/string.cpp new file mode 100644 index 0000000..27884ad --- /dev/null +++ b/kernel/src/klibc/string.cpp @@ -0,0 +1,62 @@ + +#include <cstdint> +#include <klibc/string.hpp> + +void* klibc::memcpy(void *__restrict dest, const void *__restrict src, std::size_t n) { + std::uint8_t *__restrict pdest = static_cast<std::uint8_t *__restrict>(dest); + const std::uint8_t *__restrict psrc = static_cast<const std::uint8_t *__restrict>(src); + + for (std::size_t i = 0; i < n; i++) { + pdest[i] = psrc[i]; + } + + return dest; +} + +void* klibc::memset(void *s, int c, std::size_t n) { + std::uint8_t *p = static_cast<std::uint8_t *>(s); + + for (std::size_t i = 0; i < n; i++) { + p[i] = static_cast<uint8_t>(c); + } + + return s; +} + +void* klibc::memmove(void *dest, const void *src, std::size_t n) { + std::uint8_t *pdest = static_cast<std::uint8_t *>(dest); + const std::uint8_t *psrc = static_cast<const std::uint8_t *>(src); + + if (reinterpret_cast<std::uintptr_t>(src) > reinterpret_cast<std::uintptr_t>(dest)) { + for (std::size_t i = 0; i < n; i++) { + pdest[i] = psrc[i]; + } + } else if (reinterpret_cast<std::uintptr_t>(src) < reinterpret_cast<std::uintptr_t>(dest)) { + for (std::size_t i = n; i > 0; i--) { + pdest[i-1] = psrc[i-1]; + } + } + + return dest; +} + +int klibc::memcmp(const void *s1, const void *s2, std::size_t n) { + const std::uint8_t *p1 = static_cast<const std::uint8_t *>(s1); + const std::uint8_t *p2 = static_cast<const std::uint8_t *>(s2); + + for (std::size_t i = 0; i < n; i++) { + if (p1[i] != p2[i]) { + return p1[i] < p2[i] ? -1 : 1; + } + } + + return 0; +} + +int klibc::strlen(const char *str) { + int len = 0; + while (str[len] != '\0') { + len++; + } + return len; +}
\ No newline at end of file diff --git a/kernel/src/klibc/string.hpp b/kernel/src/klibc/string.hpp new file mode 100644 index 0000000..c900862 --- /dev/null +++ b/kernel/src/klibc/string.hpp @@ -0,0 +1,10 @@ +#pragma once +#include <cstdint> + +namespace klibc { + int strlen(const char* str); + void* memcpy(void *__restrict dest, const void *__restrict src, std::size_t n); + void* memset(void *s, int c, std::size_t n); + void* memmove(void *dest, const void *src, std::size_t n); + int memcmp(const void *s1, const void *s2, std::size_t n); +};
\ No newline at end of file diff --git a/kernel/src/lib/Flanterm/.gitignore b/kernel/src/lib/Flanterm/.gitignore deleted file mode 100644 index cc62e43..0000000 --- a/kernel/src/lib/Flanterm/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.d -*.o
\ No newline at end of file diff --git a/kernel/src/lib/Flanterm/LICENSE b/kernel/src/lib/Flanterm/LICENSE deleted file mode 100644 index b3f6075..0000000 --- a/kernel/src/lib/Flanterm/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (C) 2022-2025 mintsuki and contributors. - -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. - -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 HOLDER 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. diff --git a/kernel/src/lib/Flanterm/README.md b/kernel/src/lib/Flanterm/README.md deleted file mode 100644 index f392efc..0000000 --- a/kernel/src/lib/Flanterm/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Flanterm - -Flanterm is a fast and reasonably complete terminal emulator with support for -multiple output backends. Included is a fast framebuffer backend. - -### Quick usage - -To quickly set up and use a framebuffer Flanterm instance, it is possible to -use the `flanterm_fb_init()` function as such: -```c -#include <flanterm.h> -#include <flanterm_backends/fb.h> - -struct flanterm_context *ft_ctx = flanterm_fb_init( - NULL, - NULL, - framebuffer_ptr, width, height, pitch, - red_mask_size, red_mask_shift, - green_mask_size, green_mask_shift, - blue_mask_size, blue_mask_shift, - NULL, - NULL, NULL, - NULL, NULL, - NULL, NULL, - NULL, 0, 0, 1, - 0, 0, - 0 - ); -``` -Where `framebuffer_ptr, width, height, pitch` and `{red,green,blue}_mask_{size,shift}` -represent the corresponding info about the framebuffer to use for this given instance. - -The meaning of the other arguments can be found in `flanterm_backends/fb.h`. - -To then print to the terminal instance, simply use the `flanterm_write()` -function on the given instance. For example: -```c -#include <flanterm.h> - -const char msg[] = "Hello world\n"; - -flanterm_write(ft_ctx, msg, sizeof(msg)); -``` diff --git a/kernel/src/lib/Flanterm/src/flanterm.c b/kernel/src/lib/Flanterm/src/flanterm.c deleted file mode 100644 index 822db63..0000000 --- a/kernel/src/lib/Flanterm/src/flanterm.c +++ /dev/null @@ -1,1424 +0,0 @@ -/* Copyright (C) 2022-2025 mintsuki and contributors. - * - * 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. - * - * 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 HOLDER 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. - */ - -#ifdef __cplusplus -#error "Please do not compile Flanterm as C++ code! Flanterm should be compiled as C99 or newer." -#endif - -#ifndef __STDC_VERSION__ -#error "Flanterm must be compiled as C99 or newer." -#endif - -#include <stdint.h> -#include <stddef.h> -#include <stdbool.h> - -#ifndef FLANTERM_IN_FLANTERM -#define FLANTERM_IN_FLANTERM -#endif - -#include "flanterm.h" - -// Tries to implement this standard for terminfo -// https://man7.org/linux/man-pages/man4/console_codes.4.html - -static const uint32_t col256[] = { - 0x000000, 0x00005f, 0x000087, 0x0000af, 0x0000d7, 0x0000ff, 0x005f00, 0x005f5f, - 0x005f87, 0x005faf, 0x005fd7, 0x005fff, 0x008700, 0x00875f, 0x008787, 0x0087af, - 0x0087d7, 0x0087ff, 0x00af00, 0x00af5f, 0x00af87, 0x00afaf, 0x00afd7, 0x00afff, - 0x00d700, 0x00d75f, 0x00d787, 0x00d7af, 0x00d7d7, 0x00d7ff, 0x00ff00, 0x00ff5f, - 0x00ff87, 0x00ffaf, 0x00ffd7, 0x00ffff, 0x5f0000, 0x5f005f, 0x5f0087, 0x5f00af, - 0x5f00d7, 0x5f00ff, 0x5f5f00, 0x5f5f5f, 0x5f5f87, 0x5f5faf, 0x5f5fd7, 0x5f5fff, - 0x5f8700, 0x5f875f, 0x5f8787, 0x5f87af, 0x5f87d7, 0x5f87ff, 0x5faf00, 0x5faf5f, - 0x5faf87, 0x5fafaf, 0x5fafd7, 0x5fafff, 0x5fd700, 0x5fd75f, 0x5fd787, 0x5fd7af, - 0x5fd7d7, 0x5fd7ff, 0x5fff00, 0x5fff5f, 0x5fff87, 0x5fffaf, 0x5fffd7, 0x5fffff, - 0x870000, 0x87005f, 0x870087, 0x8700af, 0x8700d7, 0x8700ff, 0x875f00, 0x875f5f, - 0x875f87, 0x875faf, 0x875fd7, 0x875fff, 0x878700, 0x87875f, 0x878787, 0x8787af, - 0x8787d7, 0x8787ff, 0x87af00, 0x87af5f, 0x87af87, 0x87afaf, 0x87afd7, 0x87afff, - 0x87d700, 0x87d75f, 0x87d787, 0x87d7af, 0x87d7d7, 0x87d7ff, 0x87ff00, 0x87ff5f, - 0x87ff87, 0x87ffaf, 0x87ffd7, 0x87ffff, 0xaf0000, 0xaf005f, 0xaf0087, 0xaf00af, - 0xaf00d7, 0xaf00ff, 0xaf5f00, 0xaf5f5f, 0xaf5f87, 0xaf5faf, 0xaf5fd7, 0xaf5fff, - 0xaf8700, 0xaf875f, 0xaf8787, 0xaf87af, 0xaf87d7, 0xaf87ff, 0xafaf00, 0xafaf5f, - 0xafaf87, 0xafafaf, 0xafafd7, 0xafafff, 0xafd700, 0xafd75f, 0xafd787, 0xafd7af, - 0xafd7d7, 0xafd7ff, 0xafff00, 0xafff5f, 0xafff87, 0xafffaf, 0xafffd7, 0xafffff, - 0xd70000, 0xd7005f, 0xd70087, 0xd700af, 0xd700d7, 0xd700ff, 0xd75f00, 0xd75f5f, - 0xd75f87, 0xd75faf, 0xd75fd7, 0xd75fff, 0xd78700, 0xd7875f, 0xd78787, 0xd787af, - 0xd787d7, 0xd787ff, 0xd7af00, 0xd7af5f, 0xd7af87, 0xd7afaf, 0xd7afd7, 0xd7afff, - 0xd7d700, 0xd7d75f, 0xd7d787, 0xd7d7af, 0xd7d7d7, 0xd7d7ff, 0xd7ff00, 0xd7ff5f, - 0xd7ff87, 0xd7ffaf, 0xd7ffd7, 0xd7ffff, 0xff0000, 0xff005f, 0xff0087, 0xff00af, - 0xff00d7, 0xff00ff, 0xff5f00, 0xff5f5f, 0xff5f87, 0xff5faf, 0xff5fd7, 0xff5fff, - 0xff8700, 0xff875f, 0xff8787, 0xff87af, 0xff87d7, 0xff87ff, 0xffaf00, 0xffaf5f, - 0xffaf87, 0xffafaf, 0xffafd7, 0xffafff, 0xffd700, 0xffd75f, 0xffd787, 0xffd7af, - 0xffd7d7, 0xffd7ff, 0xffff00, 0xffff5f, 0xffff87, 0xffffaf, 0xffffd7, 0xffffff, - 0x080808, 0x121212, 0x1c1c1c, 0x262626, 0x303030, 0x3a3a3a, 0x444444, 0x4e4e4e, - 0x585858, 0x626262, 0x6c6c6c, 0x767676, 0x808080, 0x8a8a8a, 0x949494, 0x9e9e9e, - 0xa8a8a8, 0xb2b2b2, 0xbcbcbc, 0xc6c6c6, 0xd0d0d0, 0xdadada, 0xe4e4e4, 0xeeeeee -}; - -#define CHARSET_DEFAULT 0 -#define CHARSET_DEC_SPECIAL 1 - -void flanterm_context_reinit(struct flanterm_context *ctx) { - ctx->tab_size = 8; - ctx->autoflush = true; - ctx->cursor_enabled = true; - ctx->scroll_enabled = true; - ctx->control_sequence = false; - ctx->escape = false; - ctx->osc = false; - ctx->osc_escape = false; - ctx->rrr = false; - ctx->discard_next = false; - ctx->bold = false; - ctx->bg_bold = false; - ctx->reverse_video = false; - ctx->dec_private = false; - ctx->insert_mode = false; - ctx->csi_unhandled = false; - ctx->unicode_remaining = 0; - ctx->g_select = 0; - ctx->charsets[0] = CHARSET_DEFAULT; - ctx->charsets[1] = CHARSET_DEC_SPECIAL; - ctx->current_charset = 0; - ctx->escape_offset = 0; - ctx->esc_values_i = 0; - ctx->saved_cursor_x = 0; - ctx->saved_cursor_y = 0; - ctx->current_primary = (size_t)-1; - ctx->current_bg = (size_t)-1; - ctx->scroll_top_margin = 0; - ctx->scroll_bottom_margin = ctx->rows; - ctx->oob_output = FLANTERM_OOB_OUTPUT_ONLCR; -} - -static void flanterm_putchar(struct flanterm_context *ctx, uint8_t c); - -void flanterm_write(struct flanterm_context *ctx, const char *buf, size_t count) { - for (size_t i = 0; i < count; i++) { - flanterm_putchar(ctx, buf[i]); - } - - if (ctx->autoflush) { - ctx->double_buffer_flush(ctx); - } -} - -static void sgr(struct flanterm_context *ctx) { - size_t i = 0; - - if (!ctx->esc_values_i) - goto def; - - for (; i < ctx->esc_values_i; i++) { - size_t offset; - - if (ctx->esc_values[i] == 0) { -def: - if (ctx->reverse_video) { - ctx->reverse_video = false; - ctx->swap_palette(ctx); - } - ctx->bold = false; - ctx->bg_bold = false; - ctx->current_primary = (size_t)-1; - ctx->current_bg = (size_t)-1; - ctx->set_text_bg_default(ctx); - ctx->set_text_fg_default(ctx); - continue; - } - - else if (ctx->esc_values[i] == 1) { - ctx->bold = true; - if (ctx->current_primary != (size_t)-1) { - if (!ctx->reverse_video) { - ctx->set_text_fg_bright(ctx, ctx->current_primary); - } else { - ctx->set_text_bg_bright(ctx, ctx->current_primary); - } - } else { - if (!ctx->reverse_video) { - ctx->set_text_fg_default_bright(ctx); - } else { - ctx->set_text_bg_default_bright(ctx); - } - } - continue; - } - - else if (ctx->esc_values[i] == 5) { - ctx->bg_bold = true; - if (ctx->current_bg != (size_t)-1) { - if (!ctx->reverse_video) { - ctx->set_text_bg_bright(ctx, ctx->current_bg); - } else { - ctx->set_text_fg_bright(ctx, ctx->current_bg); - } - } else { - if (!ctx->reverse_video) { - ctx->set_text_bg_default_bright(ctx); - } else { - ctx->set_text_fg_default_bright(ctx); - } - } - continue; - } - - else if (ctx->esc_values[i] == 22) { - ctx->bold = false; - if (ctx->current_primary != (size_t)-1) { - if (!ctx->reverse_video) { - ctx->set_text_fg(ctx, ctx->current_primary); - } else { - ctx->set_text_bg(ctx, ctx->current_primary); - } - } else { - if (!ctx->reverse_video) { - ctx->set_text_fg_default(ctx); - } else { - ctx->set_text_bg_default(ctx); - } - } - continue; - } - - else if (ctx->esc_values[i] == 25) { - ctx->bg_bold = false; - if (ctx->current_bg != (size_t)-1) { - if (!ctx->reverse_video) { - ctx->set_text_bg(ctx, ctx->current_bg); - } else { - ctx->set_text_fg(ctx, ctx->current_bg); - } - } else { - if (!ctx->reverse_video) { - ctx->set_text_bg_default(ctx); - } else { - ctx->set_text_fg_default(ctx); - } - } - continue; - } - - else if (ctx->esc_values[i] >= 30 && ctx->esc_values[i] <= 37) { - offset = 30; - ctx->current_primary = ctx->esc_values[i] - offset; - - if (ctx->reverse_video) { - goto set_bg; - } - -set_fg: - if ((ctx->bold && !ctx->reverse_video) - || (ctx->bg_bold && ctx->reverse_video)) { - ctx->set_text_fg_bright(ctx, ctx->esc_values[i] - offset); - } else { - ctx->set_text_fg(ctx, ctx->esc_values[i] - offset); - } - continue; - } - - else if (ctx->esc_values[i] >= 40 && ctx->esc_values[i] <= 47) { - offset = 40; - ctx->current_bg = ctx->esc_values[i] - offset; - - if (ctx->reverse_video) { - goto set_fg; - } - -set_bg: - if ((ctx->bold && ctx->reverse_video) - || (ctx->bg_bold && !ctx->reverse_video)) { - ctx->set_text_bg_bright(ctx, ctx->esc_values[i] - offset); - } else { - ctx->set_text_bg(ctx, ctx->esc_values[i] - offset); - } - continue; - } - - else if (ctx->esc_values[i] >= 90 && ctx->esc_values[i] <= 97) { - offset = 90; - ctx->current_primary = ctx->esc_values[i] - offset; - - if (ctx->reverse_video) { - goto set_bg_bright; - } - -set_fg_bright: - ctx->set_text_fg_bright(ctx, ctx->esc_values[i] - offset); - continue; - } - - else if (ctx->esc_values[i] >= 100 && ctx->esc_values[i] <= 107) { - offset = 100; - ctx->current_bg = ctx->esc_values[i] - offset; - - if (ctx->reverse_video) { - goto set_fg_bright; - } - -set_bg_bright: - ctx->set_text_bg_bright(ctx, ctx->esc_values[i] - offset); - continue; - } - - else if (ctx->esc_values[i] == 39) { - ctx->current_primary = (size_t)-1; - - if (ctx->reverse_video) { - ctx->swap_palette(ctx); - } - - if (!ctx->bold) { - ctx->set_text_fg_default(ctx); - } else { - ctx->set_text_fg_default_bright(ctx); - } - - if (ctx->reverse_video) { - ctx->swap_palette(ctx); - } - - continue; - } - - else if (ctx->esc_values[i] == 49) { - ctx->current_bg = (size_t)-1; - - if (ctx->reverse_video) { - ctx->swap_palette(ctx); - } - - if (!ctx->bg_bold) { - ctx->set_text_bg_default(ctx); - } else { - ctx->set_text_bg_default_bright(ctx); - } - - if (ctx->reverse_video) { - ctx->swap_palette(ctx); - } - - continue; - } - - else if (ctx->esc_values[i] == 7) { - if (!ctx->reverse_video) { - ctx->reverse_video = true; - ctx->swap_palette(ctx); - } - continue; - } - - else if (ctx->esc_values[i] == 27) { - if (ctx->reverse_video) { - ctx->reverse_video = false; - ctx->swap_palette(ctx); - } - continue; - } - - // 256/RGB - else if (ctx->esc_values[i] == 38 || ctx->esc_values[i] == 48) { - bool fg = ctx->esc_values[i] == 38; - - i++; - if (i >= ctx->esc_values_i) { - break; - } - - switch (ctx->esc_values[i]) { - case 2: { // RGB - if (i + 3 >= ctx->esc_values_i) { - goto out; - } - - uint32_t rgb_value = 0; - - rgb_value |= ctx->esc_values[i + 1] << 16; - rgb_value |= ctx->esc_values[i + 2] << 8; - rgb_value |= ctx->esc_values[i + 3]; - - i += 3; - - (fg ? ctx->set_text_fg_rgb : ctx->set_text_bg_rgb)(ctx, rgb_value); - - break; - } - case 5: { // 256 colors - if (i + 1 >= ctx->esc_values_i) { - goto out; - } - - uint32_t col = ctx->esc_values[i + 1]; - - i++; - - if (col < 8) { - (fg ? ctx->set_text_fg : ctx->set_text_bg)(ctx, col); - } else if (col < 16) { - (fg ? ctx->set_text_fg_bright : ctx->set_text_bg_bright)(ctx, col - 8); - } else if (col < 256) { - uint32_t rgb_value = col256[col - 16]; - (fg ? ctx->set_text_fg_rgb : ctx->set_text_bg_rgb)(ctx, rgb_value); - } - - break; - } - default: continue; - } - } - } - -out:; -} - -static void dec_private_parse(struct flanterm_context *ctx, uint8_t c) { - ctx->dec_private = false; - - if (ctx->esc_values_i == 0) { - return; - } - - bool set; - - switch (c) { - case 'h': - set = true; break; - case 'l': - set = false; break; - default: - return; - } - - switch (ctx->esc_values[0]) { - case 25: { - if (set) { - ctx->cursor_enabled = true; - } else { - ctx->cursor_enabled = false; - } - return; - } - } - - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_DEC, ctx->esc_values_i, (uintptr_t)ctx->esc_values, c); - } -} - -static void linux_private_parse(struct flanterm_context *ctx) { - if (ctx->esc_values_i == 0) { - return; - } - - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_LINUX, ctx->esc_values_i, (uintptr_t)ctx->esc_values, 0); - } -} - -static void mode_toggle(struct flanterm_context *ctx, uint8_t c) { - if (ctx->esc_values_i == 0) { - return; - } - - bool set; - - switch (c) { - case 'h': - set = true; break; - case 'l': - set = false; break; - default: - return; - } - - switch (ctx->esc_values[0]) { - case 4: - ctx->insert_mode = set; return; - } - - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_MODE, ctx->esc_values_i, (uintptr_t)ctx->esc_values, c); - } -} - -static bool osc_parse(struct flanterm_context *ctx, uint8_t c) { - // ESC \ terminates an OSC sequence cleanly - // but if ESC is followed by non-\, report failure from osc_parse and - // try parsing the character as another escape code - if (ctx->osc_escape) { - if (c == '\\') { - ctx->osc = false; - ctx->osc_escape = false; - ctx->escape = false; - return true; - } else { - ctx->osc_escape = false; - ctx->osc = false; - // escape stays true here - return false; - } - } - switch (c) { - case 0x1b: - ctx->osc_escape = true; - break; - // BEL is the other terminator - case '\a': - ctx->osc_escape = false; - ctx->osc = false; - ctx->escape = false; - break; - default: - break; - } - return true; -} - -static void control_sequence_parse(struct flanterm_context *ctx, uint8_t c) { - if (ctx->escape_offset == 2) { - switch (c) { - case '[': - ctx->discard_next = true; - goto cleanup; - case '?': - ctx->dec_private = true; - return; - } - } - - if (c >= '0' && c <= '9') { - if (ctx->esc_values_i == FLANTERM_MAX_ESC_VALUES) { - return; - } - ctx->rrr = true; - ctx->esc_values[ctx->esc_values_i] *= 10; - ctx->esc_values[ctx->esc_values_i] += c - '0'; - return; - } - - if (ctx->rrr == true) { - ctx->esc_values_i++; - ctx->rrr = false; - if (c == ';') - return; - } else if (c == ';') { - if (ctx->esc_values_i == FLANTERM_MAX_ESC_VALUES) { - return; - } - ctx->esc_values[ctx->esc_values_i] = 0; - ctx->esc_values_i++; - return; - } - - size_t esc_default; - switch (c) { - case 'J': case 'K': case 'q': - esc_default = 0; break; - default: - esc_default = 1; break; - } - - for (size_t i = ctx->esc_values_i; i < FLANTERM_MAX_ESC_VALUES; i++) { - ctx->esc_values[i] = esc_default; - } - - if (ctx->dec_private == true) { - dec_private_parse(ctx, c); - goto cleanup; - } - - bool r = ctx->scroll_enabled; - ctx->scroll_enabled = false; - size_t x, y; - ctx->get_cursor_pos(ctx, &x, &y); - - // CSI sequences are terminated by a byte in [0x40,0x7E] - // so skip all bytes until the terminator byte - if (ctx->csi_unhandled) { - if (c >= 0x40 && c <= 0x7E) { - ctx->csi_unhandled = false; - goto cleanup; - } - return; - } - - switch (c) { - // Got ESC in the middle of an escape sequence, start a new one - case 0x1B: - return; - case 'F': - x = 0; - // FALLTHRU - case 'A': { - if (ctx->esc_values[0] > y) - ctx->esc_values[0] = y; - size_t orig_y = y; - size_t dest_y = y - ctx->esc_values[0]; - bool will_be_in_scroll_region = false; - if ((ctx->scroll_top_margin >= dest_y && ctx->scroll_top_margin <= orig_y) - || (ctx->scroll_bottom_margin >= dest_y && ctx->scroll_bottom_margin <= orig_y)) { - will_be_in_scroll_region = true; - } - if (will_be_in_scroll_region && dest_y < ctx->scroll_top_margin) { - dest_y = ctx->scroll_top_margin; - } - ctx->set_cursor_pos(ctx, x, dest_y); - break; - } - case 'E': - x = 0; - // FALLTHRU - case 'e': - case 'B': { - if (y + ctx->esc_values[0] > ctx->rows - 1) - ctx->esc_values[0] = (ctx->rows - 1) - y; - size_t orig_y = y; - size_t dest_y = y + ctx->esc_values[0]; - bool will_be_in_scroll_region = false; - if ((ctx->scroll_top_margin >= orig_y && ctx->scroll_top_margin <= dest_y) - || (ctx->scroll_bottom_margin >= orig_y && ctx->scroll_bottom_margin <= dest_y)) { - will_be_in_scroll_region = true; - } - if (will_be_in_scroll_region && dest_y >= ctx->scroll_bottom_margin) { - dest_y = ctx->scroll_bottom_margin - 1; - } - ctx->set_cursor_pos(ctx, x, dest_y); - break; - } - case 'a': - case 'C': - if (x + ctx->esc_values[0] > ctx->cols - 1) - ctx->esc_values[0] = (ctx->cols - 1) - x; - ctx->set_cursor_pos(ctx, x + ctx->esc_values[0], y); - break; - case 'D': - if (ctx->esc_values[0] > x) - ctx->esc_values[0] = x; - ctx->set_cursor_pos(ctx, x - ctx->esc_values[0], y); - break; - case 'c': - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_PRIVATE_ID, 0, 0, 0); - } - break; - case 'd': - ctx->esc_values[0] -= 1; - if (ctx->esc_values[0] >= ctx->rows) - ctx->esc_values[0] = ctx->rows - 1; - ctx->set_cursor_pos(ctx, x, ctx->esc_values[0]); - break; - case 'G': - case '`': - ctx->esc_values[0] -= 1; - if (ctx->esc_values[0] >= ctx->cols) - ctx->esc_values[0] = ctx->cols - 1; - ctx->set_cursor_pos(ctx, ctx->esc_values[0], y); - break; - case 'H': - case 'f': - if (ctx->esc_values[0] != 0) { - ctx->esc_values[0]--; - } - if (ctx->esc_values[1] != 0) { - ctx->esc_values[1]--; - } - if (ctx->esc_values[1] >= ctx->cols) - ctx->esc_values[1] = ctx->cols - 1; - if (ctx->esc_values[0] >= ctx->rows) - ctx->esc_values[0] = ctx->rows - 1; - ctx->set_cursor_pos(ctx, ctx->esc_values[1], ctx->esc_values[0]); - break; - case 'M': { - size_t count = ctx->esc_values[0] > ctx->rows ? ctx->rows : ctx->esc_values[0]; - for (size_t i = 0; i < count; i++) { - ctx->scroll(ctx); - } - break; - } - case 'L': { - size_t old_scroll_top_margin = ctx->scroll_top_margin; - ctx->scroll_top_margin = y; - size_t count = ctx->esc_values[0] > ctx->rows ? ctx->rows : ctx->esc_values[0]; - for (size_t i = 0; i < count; i++) { - ctx->revscroll(ctx); - } - ctx->scroll_top_margin = old_scroll_top_margin; - break; - } - case 'n': - switch (ctx->esc_values[0]) { - case 5: - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_STATUS_REPORT, 0, 0, 0); - } - break; - case 6: - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_POS_REPORT, x + 1, y + 1, 0); - } - break; - } - break; - case 'q': - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_KBD_LEDS, ctx->esc_values[0], 0, 0); - } - break; - case 'J': - switch (ctx->esc_values[0]) { - case 0: { - size_t rows_remaining = ctx->rows - (y + 1); - size_t cols_diff = ctx->cols - (x + 1); - size_t to_clear = rows_remaining * ctx->cols + cols_diff + 1; - for (size_t i = 0; i < to_clear; i++) { - ctx->raw_putchar(ctx, ' '); - } - ctx->set_cursor_pos(ctx, x, y); - break; - } - case 1: { - ctx->set_cursor_pos(ctx, 0, 0); - bool b = false; - for (size_t yc = 0; yc < ctx->rows; yc++) { - for (size_t xc = 0; xc < ctx->cols; xc++) { - ctx->raw_putchar(ctx, ' '); - if (xc == x && yc == y) { - ctx->set_cursor_pos(ctx, x, y); - b = true; - break; - } - } - if (b == true) - break; - } - break; - } - case 2: - case 3: - ctx->clear(ctx, false); - break; - } - break; - case '@': - for (size_t i = ctx->cols - 1; ; i--) { - ctx->move_character(ctx, i + ctx->esc_values[0], y, i, y); - ctx->set_cursor_pos(ctx, i, y); - ctx->raw_putchar(ctx, ' '); - if (i == x) { - break; - } - } - ctx->set_cursor_pos(ctx, x, y); - break; - case 'P': - for (size_t i = x + ctx->esc_values[0]; i < ctx->cols; i++) - ctx->move_character(ctx, i - ctx->esc_values[0], y, i, y); - ctx->set_cursor_pos(ctx, ctx->cols - ctx->esc_values[0], y); - // FALLTHRU - case 'X': { - size_t count = ctx->esc_values[0] > ctx->cols ? ctx->cols : ctx->esc_values[0]; - for (size_t i = 0; i < count; i++) - ctx->raw_putchar(ctx, ' '); - ctx->set_cursor_pos(ctx, x, y); - break; - } - case 'm': - sgr(ctx); - break; - case 's': - ctx->get_cursor_pos(ctx, &ctx->saved_cursor_x, &ctx->saved_cursor_y); - break; - case 'u': - ctx->set_cursor_pos(ctx, ctx->saved_cursor_x, ctx->saved_cursor_y); - break; - case 'K': - switch (ctx->esc_values[0]) { - case 0: { - for (size_t i = x; i < ctx->cols; i++) - ctx->raw_putchar(ctx, ' '); - ctx->set_cursor_pos(ctx, x, y); - break; - } - case 1: { - ctx->set_cursor_pos(ctx, 0, y); - for (size_t i = 0; i < x; i++) - ctx->raw_putchar(ctx, ' '); - break; - } - case 2: { - ctx->set_cursor_pos(ctx, 0, y); - for (size_t i = 0; i < ctx->cols; i++) - ctx->raw_putchar(ctx, ' '); - ctx->set_cursor_pos(ctx, x, y); - break; - } - } - break; - case 'r': - if (ctx->esc_values[0] == 0) { - ctx->esc_values[0] = 1; - } - if (ctx->esc_values[1] == 0) { - ctx->esc_values[1] = 1; - } - ctx->scroll_top_margin = 0; - ctx->scroll_bottom_margin = ctx->rows; - if (ctx->esc_values_i > 0) { - ctx->scroll_top_margin = ctx->esc_values[0] - 1; - } - if (ctx->esc_values_i > 1) { - ctx->scroll_bottom_margin = ctx->esc_values[1]; - } - if (ctx->scroll_top_margin >= ctx->rows - || ctx->scroll_bottom_margin > ctx->rows - || ctx->scroll_top_margin >= (ctx->scroll_bottom_margin - 1)) { - ctx->scroll_top_margin = 0; - ctx->scroll_bottom_margin = ctx->rows; - } - ctx->set_cursor_pos(ctx, 0, 0); - break; - case 'l': - case 'h': - mode_toggle(ctx, c); - break; - case ']': - linux_private_parse(ctx); - break; - default: - ctx->csi_unhandled = true; - return; - } - - ctx->scroll_enabled = r; - -cleanup: - ctx->control_sequence = false; - ctx->escape = false; -} - -static void restore_state(struct flanterm_context *ctx) { - ctx->bold = ctx->saved_state_bold; - ctx->bg_bold = ctx->saved_state_bg_bold; - ctx->reverse_video = ctx->saved_state_reverse_video; - ctx->current_charset = ctx->saved_state_current_charset; - ctx->current_primary = ctx->saved_state_current_primary; - ctx->current_bg = ctx->saved_state_current_bg; - - ctx->restore_state(ctx); -} - -static void save_state(struct flanterm_context *ctx) { - ctx->save_state(ctx); - - ctx->saved_state_bold = ctx->bold; - ctx->saved_state_bg_bold = ctx->bg_bold; - ctx->saved_state_reverse_video = ctx->reverse_video; - ctx->saved_state_current_charset = ctx->current_charset; - ctx->saved_state_current_primary = ctx->current_primary; - ctx->saved_state_current_bg = ctx->current_bg; -} - -static void escape_parse(struct flanterm_context *ctx, uint8_t c) { - ctx->escape_offset++; - - if (ctx->osc == true) { - // ESC \ is one of the two possible terminators of OSC sequences, - // so osc_parse consumes ESC. - // If it is then followed by \ it cleans correctly, - // otherwise it returns false, and it tries parsing it as another escape sequence - if (osc_parse(ctx, c)) { - return; - } - } - - if (ctx->control_sequence == true) { - control_sequence_parse(ctx, c); - return; - } - - size_t x, y; - ctx->get_cursor_pos(ctx, &x, &y); - - switch (c) { - case ']': - ctx->osc_escape = false; - ctx->osc = true; - return; - case '[': - for (size_t i = 0; i < FLANTERM_MAX_ESC_VALUES; i++) - ctx->esc_values[i] = 0; - ctx->esc_values_i = 0; - ctx->rrr = false; - ctx->csi_unhandled = false; - ctx->control_sequence = true; - return; - case '7': - save_state(ctx); - break; - case '8': - restore_state(ctx); - break; - case 'c': - flanterm_context_reinit(ctx); - ctx->clear(ctx, true); - break; - case 'D': - if (y == ctx->scroll_bottom_margin - 1) { - ctx->scroll(ctx); - ctx->set_cursor_pos(ctx, x, y); - } else { - ctx->set_cursor_pos(ctx, x, y + 1); - } - break; - case 'E': - if (y == ctx->scroll_bottom_margin - 1) { - ctx->scroll(ctx); - ctx->set_cursor_pos(ctx, 0, y); - } else { - ctx->set_cursor_pos(ctx, 0, y + 1); - } - break; - case 'M': - // "Reverse linefeed" - if (y == ctx->scroll_top_margin) { - ctx->revscroll(ctx); - ctx->set_cursor_pos(ctx, 0, y); - } else { - ctx->set_cursor_pos(ctx, 0, y - 1); - } - break; - case 'Z': - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_PRIVATE_ID, 0, 0, 0); - } - break; - case '(': - case ')': - ctx->g_select = c - '\''; - break; - } - - ctx->escape = false; -} - -static bool dec_special_print(struct flanterm_context *ctx, uint8_t c) { -#define FLANTERM_DEC_SPCL_PRN(C) ctx->raw_putchar(ctx, (C)); return true; - switch (c) { - case '`': FLANTERM_DEC_SPCL_PRN(0x04) - case '0': FLANTERM_DEC_SPCL_PRN(0xdb) - case '-': FLANTERM_DEC_SPCL_PRN(0x18) - case ',': FLANTERM_DEC_SPCL_PRN(0x1b) - case '.': FLANTERM_DEC_SPCL_PRN(0x19) - case 'a': FLANTERM_DEC_SPCL_PRN(0xb1) - case 'f': FLANTERM_DEC_SPCL_PRN(0xf8) - case 'g': FLANTERM_DEC_SPCL_PRN(0xf1) - case 'h': FLANTERM_DEC_SPCL_PRN(0xb0) - case 'j': FLANTERM_DEC_SPCL_PRN(0xd9) - case 'k': FLANTERM_DEC_SPCL_PRN(0xbf) - case 'l': FLANTERM_DEC_SPCL_PRN(0xda) - case 'm': FLANTERM_DEC_SPCL_PRN(0xc0) - case 'n': FLANTERM_DEC_SPCL_PRN(0xc5) - case 'q': FLANTERM_DEC_SPCL_PRN(0xc4) - case 's': FLANTERM_DEC_SPCL_PRN(0x5f) - case 't': FLANTERM_DEC_SPCL_PRN(0xc3) - case 'u': FLANTERM_DEC_SPCL_PRN(0xb4) - case 'v': FLANTERM_DEC_SPCL_PRN(0xc1) - case 'w': FLANTERM_DEC_SPCL_PRN(0xc2) - case 'x': FLANTERM_DEC_SPCL_PRN(0xb3) - case 'y': FLANTERM_DEC_SPCL_PRN(0xf3) - case 'z': FLANTERM_DEC_SPCL_PRN(0xf2) - case '~': FLANTERM_DEC_SPCL_PRN(0xfa) - case '_': FLANTERM_DEC_SPCL_PRN(0xff) - case '+': FLANTERM_DEC_SPCL_PRN(0x1a) - case '{': FLANTERM_DEC_SPCL_PRN(0xe3) - case '}': FLANTERM_DEC_SPCL_PRN(0x9c) - } -#undef FLANTERM_DEC_SPCL_PRN - - return false; -} - -// Following wcwidth related code inherited from: -// https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c - -struct interval { - uint32_t first; - uint32_t last; -}; - -/* auxiliary function for binary search in interval table */ -static int bisearch(uint32_t ucs, const struct interval *table, int max) { - int min = 0; - int mid; - - if (ucs < table[0].first || ucs > table[max].last) - return 0; - while (max >= min) { - mid = (min + max) / 2; - if (ucs > table[mid].last) - min = mid + 1; - else if (ucs < table[mid].first) - max = mid - 1; - else - return 1; - } - - return 0; -} - -int mk_wcwidth(uint32_t ucs) { - /* sorted list of non-overlapping intervals of non-spacing characters */ - /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ - static const struct interval combining[] = { - { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 }, - { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, - { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 }, - { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 }, - { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, - { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, - { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 }, - { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, - { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, - { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, - { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, - { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, - { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, - { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, - { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C }, - { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D }, - { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, - { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, - { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC }, - { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, - { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, - { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, - { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, - { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, - { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, - { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, - { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, - { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, - { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, - { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F }, - { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 }, - { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, - { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, - { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, - { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, - { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 }, - { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, - { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF }, - { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 }, - { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F }, - { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, - { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, - { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, - { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, - { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 }, - { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, - { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F }, - { 0xE0100, 0xE01EF } - }; - - /* test for 8-bit control characters */ - if (ucs == 0) - return 0; - if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) - return 1; - - /* binary search in table of non-spacing characters */ - if (bisearch(ucs, combining, - sizeof(combining) / sizeof(struct interval) - 1)) - return 0; - - /* if we arrive here, ucs is not a combining or C0/C1 control character */ - - return 1 + - (ucs >= 0x1100 && - (ucs <= 0x115f || /* Hangul Jamo init. consonants */ - ucs == 0x2329 || ucs == 0x232a || - (ucs >= 0x2e80 && ucs <= 0xa4cf && - ucs != 0x303f) || /* CJK ... Yi */ - (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ - (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ - (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ - (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ - (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ - (ucs >= 0xffe0 && ucs <= 0xffe6) || - (ucs >= 0x20000 && ucs <= 0x2fffd) || - (ucs >= 0x30000 && ucs <= 0x3fffd))); -} - -// End of https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c inherited code - -static int unicode_to_cp437(uint64_t code_point) { - switch (code_point) { - case 0x263a: return 1; - case 0x263b: return 2; - case 0x2665: return 3; - case 0x2666: return 4; - case 0x2663: return 5; - case 0x2660: return 6; - case 0x2022: return 7; - case 0x25d8: return 8; - case 0x25cb: return 9; - case 0x25d9: return 10; - case 0x2642: return 11; - case 0x2640: return 12; - case 0x266a: return 13; - case 0x266b: return 14; - case 0x263c: return 15; - case 0x25ba: return 16; - case 0x25c4: return 17; - case 0x2195: return 18; - case 0x203c: return 19; - case 0x00b6: return 20; - case 0x00a7: return 21; - case 0x25ac: return 22; - case 0x21a8: return 23; - case 0x2191: return 24; - case 0x2193: return 25; - case 0x2192: return 26; - case 0x2190: return 27; - case 0x221f: return 28; - case 0x2194: return 29; - case 0x25b2: return 30; - case 0x25bc: return 31; - - case 0x2302: return 127; - case 0x00c7: return 128; - case 0x00fc: return 129; - case 0x00e9: return 130; - case 0x00e2: return 131; - case 0x00e4: return 132; - case 0x00e0: return 133; - case 0x00e5: return 134; - case 0x00e7: return 135; - case 0x00ea: return 136; - case 0x00eb: return 137; - case 0x00e8: return 138; - case 0x00ef: return 139; - case 0x00ee: return 140; - case 0x00ec: return 141; - case 0x00c4: return 142; - case 0x00c5: return 143; - case 0x00c9: return 144; - case 0x00e6: return 145; - case 0x00c6: return 146; - case 0x00f4: return 147; - case 0x00f6: return 148; - case 0x00f2: return 149; - case 0x00fb: return 150; - case 0x00f9: return 151; - case 0x00ff: return 152; - case 0x00d6: return 153; - case 0x00dc: return 154; - case 0x00a2: return 155; - case 0x00a3: return 156; - case 0x00a5: return 157; - case 0x20a7: return 158; - case 0x0192: return 159; - case 0x00e1: return 160; - case 0x00ed: return 161; - case 0x00f3: return 162; - case 0x00fa: return 163; - case 0x00f1: return 164; - case 0x00d1: return 165; - case 0x00aa: return 166; - case 0x00ba: return 167; - case 0x00bf: return 168; - case 0x2310: return 169; - case 0x00ac: return 170; - case 0x00bd: return 171; - case 0x00bc: return 172; - case 0x00a1: return 173; - case 0x00ab: return 174; - case 0x00bb: return 175; - case 0x2591: return 176; - case 0x2592: return 177; - case 0x2593: return 178; - case 0x2502: return 179; - case 0x2524: return 180; - case 0x2561: return 181; - case 0x2562: return 182; - case 0x2556: return 183; - case 0x2555: return 184; - case 0x2563: return 185; - case 0x2551: return 186; - case 0x2557: return 187; - case 0x255d: return 188; - case 0x255c: return 189; - case 0x255b: return 190; - case 0x2510: return 191; - case 0x2514: return 192; - case 0x2534: return 193; - case 0x252c: return 194; - case 0x251c: return 195; - case 0x2500: return 196; - case 0x253c: return 197; - case 0x255e: return 198; - case 0x255f: return 199; - case 0x255a: return 200; - case 0x2554: return 201; - case 0x2569: return 202; - case 0x2566: return 203; - case 0x2560: return 204; - case 0x2550: return 205; - case 0x256c: return 206; - case 0x2567: return 207; - case 0x2568: return 208; - case 0x2564: return 209; - case 0x2565: return 210; - case 0x2559: return 211; - case 0x2558: return 212; - case 0x2552: return 213; - case 0x2553: return 214; - case 0x256b: return 215; - case 0x256a: return 216; - case 0x2518: return 217; - case 0x250c: return 218; - case 0x2588: return 219; - case 0x2584: return 220; - case 0x258c: return 221; - case 0x2590: return 222; - case 0x2580: return 223; - case 0x03b1: return 224; - case 0x00df: return 225; - case 0x0393: return 226; - case 0x03c0: return 227; - case 0x03a3: return 228; - case 0x03c3: return 229; - case 0x00b5: return 230; - case 0x03c4: return 231; - case 0x03a6: return 232; - case 0x0398: return 233; - case 0x03a9: return 234; - case 0x03b4: return 235; - case 0x221e: return 236; - case 0x03c6: return 237; - case 0x03b5: return 238; - case 0x2229: return 239; - case 0x2261: return 240; - case 0x00b1: return 241; - case 0x2265: return 242; - case 0x2264: return 243; - case 0x2320: return 244; - case 0x2321: return 245; - case 0x00f7: return 246; - case 0x2248: return 247; - case 0x00b0: return 248; - case 0x2219: return 249; - case 0x00b7: return 250; - case 0x221a: return 251; - case 0x207f: return 252; - case 0x00b2: return 253; - case 0x25a0: return 254; - } - - return -1; -} - -static void flanterm_putchar(struct flanterm_context *ctx, uint8_t c) { - if (ctx->discard_next || (c == 0x18 || c == 0x1a)) { - ctx->discard_next = false; - ctx->escape = false; - ctx->control_sequence = false; - ctx->unicode_remaining = 0; - ctx->osc = false; - ctx->osc_escape = false; - ctx->g_select = 0; - return; - } - - if (ctx->unicode_remaining != 0) { - if ((c & 0xc0) != 0x80) { - ctx->unicode_remaining = 0; - goto unicode_error; - } - - ctx->unicode_remaining--; - ctx->code_point |= (uint64_t)(c & 0x3f) << (6 * ctx->unicode_remaining); - if (ctx->unicode_remaining != 0) { - return; - } - - int cc = unicode_to_cp437(ctx->code_point); - - if (cc == -1) { - size_t replacement_width = (size_t)mk_wcwidth(ctx->code_point); - if (replacement_width > 0) { - ctx->raw_putchar(ctx, 0xfe); - } - for (size_t i = 1; i < replacement_width; i++) { - ctx->raw_putchar(ctx, ' '); - } - } else { - ctx->raw_putchar(ctx, cc); - } - return; - } - -unicode_error: - if (c >= 0xc0 && c <= 0xf7) { - if (c >= 0xc0 && c <= 0xdf) { - ctx->unicode_remaining = 1; - ctx->code_point = (uint64_t)(c & 0x1f) << 6; - } else if (c >= 0xe0 && c <= 0xef) { - ctx->unicode_remaining = 2; - ctx->code_point = (uint64_t)(c & 0x0f) << (6 * 2); - } else if (c >= 0xf0 && c <= 0xf7) { - ctx->unicode_remaining = 3; - ctx->code_point = (uint64_t)(c & 0x07) << (6 * 3); - } - return; - } - - if (ctx->escape == true) { - escape_parse(ctx, c); - return; - } - - if (ctx->g_select) { - ctx->g_select--; - switch (c) { - case 'B': - ctx->charsets[ctx->g_select] = CHARSET_DEFAULT; break; - case '0': - ctx->charsets[ctx->g_select] = CHARSET_DEC_SPECIAL; break; - } - ctx->g_select = 0; - return; - } - - size_t x, y; - ctx->get_cursor_pos(ctx, &x, &y); - - switch (c) { - case 0x00: - case 0x7f: - return; - case 0x1b: - ctx->escape_offset = 0; - ctx->escape = true; - return; - case '\t': - if ((x / ctx->tab_size + 1) >= ctx->cols) { - ctx->set_cursor_pos(ctx, ctx->cols - 1, y); - return; - } - ctx->set_cursor_pos(ctx, (x / ctx->tab_size + 1) * ctx->tab_size, y); - return; - case 0x0b: - case 0x0c: - case '\n': - if (y == ctx->scroll_bottom_margin - 1) { - ctx->scroll(ctx); - ctx->set_cursor_pos(ctx, (ctx->oob_output & FLANTERM_OOB_OUTPUT_ONLCR) ? 0 : x, y); - } else { - ctx->set_cursor_pos(ctx, (ctx->oob_output & FLANTERM_OOB_OUTPUT_ONLCR) ? 0 : x, y + 1); - } - return; - case '\b': - ctx->set_cursor_pos(ctx, x - 1, y); - return; - case '\r': - ctx->set_cursor_pos(ctx, 0, y); - return; - case '\a': - // The bell is handled by the kernel - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_BELL, 0, 0, 0); - } - return; - case 14: - // Move to G1 set - ctx->current_charset = 1; - return; - case 15: - // Move to G0 set - ctx->current_charset = 0; - return; - } - - if (ctx->insert_mode == true) { - for (size_t i = ctx->cols - 1; ; i--) { - ctx->move_character(ctx, i + 1, y, i, y); - if (i == x) { - break; - } - } - } - - // Translate character set - switch (ctx->charsets[ctx->current_charset]) { - case CHARSET_DEFAULT: - break; - case CHARSET_DEC_SPECIAL: - if (dec_special_print(ctx, c)) { - return; - } - break; - } - - if (c >= 0x20 && c <= 0x7e) { - ctx->raw_putchar(ctx, c); - } else { - ctx->raw_putchar(ctx, 0xfe); - } -} - -void flanterm_flush(struct flanterm_context *ctx) { - ctx->double_buffer_flush(ctx); -} - -void flanterm_full_refresh(struct flanterm_context *ctx) { - ctx->full_refresh(ctx); -} - -void flanterm_deinit(struct flanterm_context *ctx, void (*_free)(void *, size_t)) { - ctx->deinit(ctx, _free); -} - -void flanterm_get_dimensions(struct flanterm_context *ctx, size_t *cols, size_t *rows) { - *cols = ctx->cols; - *rows = ctx->rows; -} - -void flanterm_set_autoflush(struct flanterm_context *ctx, bool state) { - ctx->autoflush = state; -} - -void flanterm_set_callback(struct flanterm_context *ctx, void (*callback)(struct flanterm_context *, uint64_t, uint64_t, uint64_t, uint64_t)) { - ctx->callback = callback; -} - -uint64_t flanterm_get_oob_output(struct flanterm_context *ctx) { - return ctx->oob_output; -} - -void flanterm_set_oob_output(struct flanterm_context *ctx, uint64_t oob_output) { - ctx->oob_output = oob_output; -} diff --git a/kernel/src/lib/Flanterm/src/flanterm.h b/kernel/src/lib/Flanterm/src/flanterm.h deleted file mode 100644 index 9e23cb5..0000000 --- a/kernel/src/lib/Flanterm/src/flanterm.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (C) 2022-2025 mintsuki and contributors. - * - * 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. - * - * 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 HOLDER 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 FLANTERM_H -#define FLANTERM_H 1 - -#include <stddef.h> -#include <stdint.h> -#include <stdbool.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define FLANTERM_CB_DEC 10 -#define FLANTERM_CB_BELL 20 -#define FLANTERM_CB_PRIVATE_ID 30 -#define FLANTERM_CB_STATUS_REPORT 40 -#define FLANTERM_CB_POS_REPORT 50 -#define FLANTERM_CB_KBD_LEDS 60 -#define FLANTERM_CB_MODE 70 -#define FLANTERM_CB_LINUX 80 - -#define FLANTERM_OOB_OUTPUT_OCRNL (1 << 0) -#define FLANTERM_OOB_OUTPUT_OFDEL (1 << 1) -#define FLANTERM_OOB_OUTPUT_OFILL (1 << 2) -#define FLANTERM_OOB_OUTPUT_OLCUC (1 << 3) -#define FLANTERM_OOB_OUTPUT_ONLCR (1 << 4) -#define FLANTERM_OOB_OUTPUT_ONLRET (1 << 5) -#define FLANTERM_OOB_OUTPUT_ONOCR (1 << 6) -#define FLANTERM_OOB_OUTPUT_OPOST (1 << 7) - -#ifdef FLANTERM_IN_FLANTERM - -#include "flanterm_private.h" - -#else - -struct flanterm_context; - -#endif - -void flanterm_write(struct flanterm_context *ctx, const char *buf, size_t count); -void flanterm_flush(struct flanterm_context *ctx); -void flanterm_full_refresh(struct flanterm_context *ctx); -void flanterm_deinit(struct flanterm_context *ctx, void (*_free)(void *ptr, size_t size)); - -void flanterm_get_dimensions(struct flanterm_context *ctx, size_t *cols, size_t *rows); -void flanterm_set_autoflush(struct flanterm_context *ctx, bool state); -void flanterm_set_callback(struct flanterm_context *ctx, void (*callback)(struct flanterm_context *, uint64_t, uint64_t, uint64_t, uint64_t)); -uint64_t flanterm_get_oob_output(struct flanterm_context *ctx); -void flanterm_set_oob_output(struct flanterm_context *ctx, uint64_t oob_output); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/src/lib/Flanterm/src/flanterm_backends/fb.c b/kernel/src/lib/Flanterm/src/flanterm_backends/fb.c deleted file mode 100644 index da00f9a..0000000 --- a/kernel/src/lib/Flanterm/src/flanterm_backends/fb.c +++ /dev/null @@ -1,1254 +0,0 @@ -/* Copyright (C) 2022-2025 mintsuki and contributors. - * - * 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. - * - * 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 HOLDER 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. - */ - -#ifdef __cplusplus -#error "Please do not compile Flanterm as C++ code! Flanterm should be compiled as C99 or newer." -#endif - -#ifndef __STDC_VERSION__ -#error "Flanterm must be compiled as C99 or newer." -#endif - -#if defined(_MSC_VER) -#define ALWAYS_INLINE __forceinline -#elif defined(__GNUC__) || defined(__clang__) -#define ALWAYS_INLINE __attribute__((always_inline)) inline -#else -#define ALWAYS_INLINE inline -#endif - -#include <stdint.h> -#include <stddef.h> -#include <stdbool.h> - -#ifndef FLANTERM_IN_FLANTERM -#define FLANTERM_IN_FLANTERM -#endif - -#include "../flanterm.h" -#include "fb.h" - -void *memset(void *, int, size_t); -void *memcpy(void *, const void *, size_t); - -#ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - -#ifndef FLANTERM_FB_BUMP_ALLOC_POOL_SIZE -#define FLANTERM_FB_BUMP_ALLOC_POOL_SIZE 873000 - -#define FLANTERM_FB_WIDTH_LIMIT 1920 -#define FLANTERM_FB_HEIGHT_LIMIT 1200 -#endif - -static uint8_t bump_alloc_pool[FLANTERM_FB_BUMP_ALLOC_POOL_SIZE]; -static size_t bump_alloc_ptr = 0; - -static void *bump_alloc(size_t s) { - static bool base_offset_added = false; - if (!base_offset_added) { - if ((uintptr_t)bump_alloc_pool & 0xf) { - bump_alloc_ptr += 0x10 - ((uintptr_t)bump_alloc_pool & 0xf); - } - base_offset_added = true; - } - - if ((s & 0xf) != 0) { - s += 0x10; - s &= ~(size_t)0xf; - } - - size_t next_ptr = bump_alloc_ptr + s; - if (next_ptr > FLANTERM_FB_BUMP_ALLOC_POOL_SIZE) { - return NULL; - } - void *ret = &bump_alloc_pool[bump_alloc_ptr]; - bump_alloc_ptr = next_ptr; - return ret; -} - -static bool bump_allocated_instance = false; - -#endif - -// Builtin font originally taken from: -// https://github.com/viler-int10h/vga-text-mode-fonts/raw/master/FONTS/PC-OTHER/TOSH-SAT.F16 -static const uint8_t builtin_font[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0xa5, 0xa5, 0x81, - 0x81, 0xa5, 0x99, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x7e, 0xff, - 0xff, 0xdb, 0xdb, 0xff, 0xff, 0xdb, 0xe7, 0xff, 0x7e, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, - 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x3c, 0x3c, 0xdb, 0xff, 0xff, 0xdb, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0xff, 0x66, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, - 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0x84, 0x84, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, - 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1e, - 0x0e, 0x1e, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x30, 0x30, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x1c, 0x1e, 0x16, 0x12, - 0x10, 0x10, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x38, 0x2c, - 0x26, 0x32, 0x3a, 0x2e, 0x26, 0x22, 0x62, 0xe2, 0xc6, 0x0e, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, - 0xf8, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, - 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, - 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, - 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, - 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, 0x30, 0xfc, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0xfc, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x0c, 0xfe, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0xfe, 0x60, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, - 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x24, 0x66, 0xff, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, - 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0x78, 0x78, 0x78, 0x30, 0x30, 0x30, 0x00, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, - 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0xc6, 0x7c, - 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x0c, 0x0c, 0x18, 0x38, - 0x30, 0x60, 0x60, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0x6c, 0x38, 0x30, 0x76, 0xde, 0xcc, 0xcc, 0xde, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x60, 0x60, 0x60, - 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0xfe, 0x38, 0x6c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, - 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, - 0x0c, 0x0c, 0x18, 0x38, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0x06, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, - 0xfe, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, - 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, - 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, - 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x00, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, - 0xde, 0xde, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0xc0, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, - 0xee, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xe6, 0xe6, 0xf6, 0xde, 0xce, 0xce, 0xc6, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, - 0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xf6, 0xda, - 0x6c, 0x06, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, - 0xd8, 0xcc, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, - 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x38, - 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xc0, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, - 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0x60, 0x60, 0x30, 0x38, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x06, 0x06, - 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0xc0, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xe6, 0xdc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x76, 0xce, 0xc6, - 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xce, 0xc6, - 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0xc0, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x1e, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0xc0, 0xc6, 0xcc, 0xd8, 0xf0, 0xf0, 0xd8, 0xcc, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, - 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc6, - 0xc6, 0xc6, 0xe6, 0xdc, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x76, 0xce, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0x06, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, - 0x70, 0x1c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, - 0x30, 0xfe, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x30, 0x30, - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x30, - 0x30, 0x30, 0x30, 0x1c, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, - 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x18, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, - 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, - 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0x06, 0x06, - 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, - 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, - 0x7c, 0x18, 0x0c, 0x38, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, - 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, - 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, - 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, - 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, - 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x00, 0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x36, 0x36, - 0x76, 0xde, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3c, - 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, - 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, - 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, - 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, - 0x30, 0x78, 0xcc, 0xc0, 0xc0, 0xcc, 0x78, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x60, 0x60, 0x60, 0xf8, 0x60, 0x60, 0x60, 0xe6, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0xfc, - 0x30, 0xfc, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, - 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, - 0x18, 0xd8, 0x70, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0x06, 0x06, - 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, - 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, - 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x78, 0xd8, 0xd8, 0x6c, 0x00, 0xfc, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, - 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc2, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, - 0x18, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc2, 0xc6, 0xcc, 0xd8, 0x30, - 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, - 0x00, 0x30, 0x30, 0x30, 0x78, 0x78, 0x78, 0x78, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, - 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x88, 0x22, 0x88, - 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, - 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, - 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, - 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf6, 0xf6, 0x06, 0x06, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x06, - 0x06, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf6, 0xf6, 0x06, 0x06, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, - 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, - 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x37, 0x37, 0x30, 0x30, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x30, 0x30, 0x37, 0x37, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0xf7, 0x00, - 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x30, 0x30, 0x37, 0x37, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, - 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf7, 0xf7, 0x00, 0x00, 0xf7, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, - 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0xff, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0xff, 0xff, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, - 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x76, 0xd6, 0xdc, 0xc8, 0xc8, 0xdc, 0xd6, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, - 0xd8, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7e, 0xfe, 0x24, 0x24, 0x24, 0x24, 0x66, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xfe, 0xc2, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc2, 0xfe, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc8, 0xcc, - 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x76, 0x6c, 0x60, 0xc0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xfc, 0x98, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x30, 0x30, 0x78, 0xcc, 0xcc, - 0xcc, 0x78, 0x30, 0x30, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, - 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0x60, 0x30, 0x78, 0xcc, - 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x76, 0xbb, 0x99, 0x99, 0xdd, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x06, 0x3c, 0x6c, 0xce, 0xd6, 0xd6, 0xe6, 0x6c, 0x78, - 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x60, 0xc0, 0xc0, 0xfe, - 0xc0, 0xc0, 0x60, 0x30, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, - 0x30, 0x30, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x36, 0x36, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, - 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, - 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c, 0x00, 0x00, - 0x00, 0xd8, 0xec, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x0c, 0x18, 0x30, 0x60, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -static ALWAYS_INLINE uint32_t convert_colour(struct flanterm_context *_ctx, uint32_t colour) { - struct flanterm_fb_context *ctx = (void *)_ctx; - uint32_t r = (colour >> 16) & 0xff; - uint32_t g = (colour >> 8) & 0xff; - uint32_t b = colour & 0xff; - return (r << ctx->red_mask_shift) | (g << ctx->green_mask_shift) | (b << ctx->blue_mask_shift); -} - -static void flanterm_fb_save_state(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->saved_state_text_fg = ctx->text_fg; - ctx->saved_state_text_bg = ctx->text_bg; - ctx->saved_state_cursor_x = ctx->cursor_x; - ctx->saved_state_cursor_y = ctx->cursor_y; -} - -static void flanterm_fb_restore_state(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->text_fg = ctx->saved_state_text_fg; - ctx->text_bg = ctx->saved_state_text_bg; - ctx->cursor_x = ctx->saved_state_cursor_x; - ctx->cursor_y = ctx->saved_state_cursor_y; -} - -static void flanterm_fb_swap_palette(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - uint32_t tmp = ctx->text_bg; - ctx->text_bg = ctx->text_fg; - ctx->text_fg = tmp; -} - -static void plot_char_scaled_canvas(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - x = ctx->offset_x + x * ctx->glyph_width; - y = ctx->offset_y + y * ctx->glyph_height; - - bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; - // naming: fx,fy for font coordinates, gx,gy for glyph coordinates - for (size_t gy = 0; gy < ctx->glyph_height; gy++) { - uint8_t fy = gy / ctx->font_scale_y; - volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); - uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width; - bool *glyph_pointer = glyph + (fy * ctx->font_width); - for (size_t fx = 0; fx < ctx->font_width; fx++) { - for (size_t i = 0; i < ctx->font_scale_x; i++) { - size_t gx = ctx->font_scale_x * fx + i; - uint32_t bg = c->bg == 0xffffffff ? canvas_line[gx] : c->bg; - uint32_t fg = c->fg == 0xffffffff ? canvas_line[gx] : c->fg; - fb_line[gx] = *glyph_pointer ? fg : bg; - } - glyph_pointer++; - } - } -} - -static void plot_char_scaled_uncanvas(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - uint32_t default_bg = ctx->default_bg; - - uint32_t bg = c->bg == 0xffffffff ? default_bg : c->bg; - uint32_t fg = c->fg == 0xffffffff ? default_bg : c->fg; - - x = ctx->offset_x + x * ctx->glyph_width; - y = ctx->offset_y + y * ctx->glyph_height; - - bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; - // naming: fx,fy for font coordinates, gx,gy for glyph coordinates - for (size_t gy = 0; gy < ctx->glyph_height; gy++) { - uint8_t fy = gy / ctx->font_scale_y; - volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); - bool *glyph_pointer = glyph + (fy * ctx->font_width); - for (size_t fx = 0; fx < ctx->font_width; fx++) { - for (size_t i = 0; i < ctx->font_scale_x; i++) { - size_t gx = ctx->font_scale_x * fx + i; - fb_line[gx] = *glyph_pointer ? fg : bg; - } - glyph_pointer++; - } - } -} - -static void plot_char_unscaled_canvas(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - x = ctx->offset_x + x * ctx->glyph_width; - y = ctx->offset_y + y * ctx->glyph_height; - - bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; - // naming: fx,fy for font coordinates, gx,gy for glyph coordinates - for (size_t gy = 0; gy < ctx->glyph_height; gy++) { - volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); - uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width; - bool *glyph_pointer = glyph + (gy * ctx->font_width); - for (size_t fx = 0; fx < ctx->font_width; fx++) { - uint32_t bg = c->bg == 0xffffffff ? canvas_line[fx] : c->bg; - uint32_t fg = c->fg == 0xffffffff ? canvas_line[fx] : c->fg; - fb_line[fx] = *(glyph_pointer++) ? fg : bg; - } - } -} - -static void plot_char_unscaled_uncanvas(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - uint32_t default_bg = ctx->default_bg; - - uint32_t bg = c->bg == 0xffffffff ? default_bg : c->bg; - uint32_t fg = c->fg == 0xffffffff ? default_bg : c->fg; - - x = ctx->offset_x + x * ctx->glyph_width; - y = ctx->offset_y + y * ctx->glyph_height; - - bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; - // naming: fx,fy for font coordinates, gx,gy for glyph coordinates - for (size_t gy = 0; gy < ctx->glyph_height; gy++) { - volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); - bool *glyph_pointer = glyph + (gy * ctx->font_width); - for (size_t fx = 0; fx < ctx->font_width; fx++) { - fb_line[fx] = *(glyph_pointer++) ? fg : bg; - } - } -} - -static inline bool compare_char(struct flanterm_fb_char *a, struct flanterm_fb_char *b) { - return !(a->c != b->c || a->bg != b->bg || a->fg != b->fg); -} - -static void push_to_queue(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - size_t i = y * _ctx->cols + x; - - struct flanterm_fb_queue_item *q = ctx->map[i]; - - if (q == NULL) { - if (compare_char(&ctx->grid[i], c)) { - return; - } - q = &ctx->queue[ctx->queue_i++]; - q->x = x; - q->y = y; - ctx->map[i] = q; - } - - q->c = *c; -} - -static void flanterm_fb_revscroll(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - for (size_t i = (_ctx->scroll_bottom_margin - 1) * _ctx->cols - 1; - i >= _ctx->scroll_top_margin * _ctx->cols; i--) { - if (i == (size_t)-1) { - break; - } - struct flanterm_fb_char *c; - struct flanterm_fb_queue_item *q = ctx->map[i]; - if (q != NULL) { - c = &q->c; - } else { - c = &ctx->grid[i]; - } - push_to_queue(_ctx, c, (i + _ctx->cols) % _ctx->cols, (i + _ctx->cols) / _ctx->cols); - } - - // Clear the first line of the screen. - struct flanterm_fb_char empty; - empty.c = ' '; - empty.fg = ctx->text_fg; - empty.bg = ctx->text_bg; - for (size_t i = 0; i < _ctx->cols; i++) { - push_to_queue(_ctx, &empty, i, _ctx->scroll_top_margin); - } -} - -static void flanterm_fb_scroll(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - for (size_t i = (_ctx->scroll_top_margin + 1) * _ctx->cols; - i < _ctx->scroll_bottom_margin * _ctx->cols; i++) { - struct flanterm_fb_char *c; - struct flanterm_fb_queue_item *q = ctx->map[i]; - if (q != NULL) { - c = &q->c; - } else { - c = &ctx->grid[i]; - } - push_to_queue(_ctx, c, (i - _ctx->cols) % _ctx->cols, (i - _ctx->cols) / _ctx->cols); - } - - // Clear the last line of the screen. - struct flanterm_fb_char empty; - empty.c = ' '; - empty.fg = ctx->text_fg; - empty.bg = ctx->text_bg; - for (size_t i = 0; i < _ctx->cols; i++) { - push_to_queue(_ctx, &empty, i, _ctx->scroll_bottom_margin - 1); - } -} - -static void flanterm_fb_clear(struct flanterm_context *_ctx, bool move) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - struct flanterm_fb_char empty; - empty.c = ' '; - empty.fg = ctx->text_fg; - empty.bg = ctx->text_bg; - for (size_t i = 0; i < _ctx->rows * _ctx->cols; i++) { - push_to_queue(_ctx, &empty, i % _ctx->cols, i / _ctx->cols); - } - - if (move) { - ctx->cursor_x = 0; - ctx->cursor_y = 0; - } -} - -static void flanterm_fb_set_cursor_pos(struct flanterm_context *_ctx, size_t x, size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (x >= _ctx->cols) { - if ((int)x < 0) { - x = 0; - } else { - x = _ctx->cols - 1; - } - } - if (y >= _ctx->rows) { - if ((int)y < 0) { - y = 0; - } else { - y = _ctx->rows - 1; - } - } - ctx->cursor_x = x; - ctx->cursor_y = y; -} - -static void flanterm_fb_get_cursor_pos(struct flanterm_context *_ctx, size_t *x, size_t *y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - *x = ctx->cursor_x >= _ctx->cols ? _ctx->cols - 1 : ctx->cursor_x; - *y = ctx->cursor_y >= _ctx->rows ? _ctx->rows - 1 : ctx->cursor_y; -} - -static void flanterm_fb_move_character(struct flanterm_context *_ctx, size_t new_x, size_t new_y, size_t old_x, size_t old_y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (old_x >= _ctx->cols || old_y >= _ctx->rows - || new_x >= _ctx->cols || new_y >= _ctx->rows) { - return; - } - - size_t i = old_x + old_y * _ctx->cols; - - struct flanterm_fb_char *c; - struct flanterm_fb_queue_item *q = ctx->map[i]; - if (q != NULL) { - c = &q->c; - } else { - c = &ctx->grid[i]; - } - - push_to_queue(_ctx, c, new_x, new_y); -} - -static void flanterm_fb_set_text_fg(struct flanterm_context *_ctx, size_t fg) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_fg = ctx->ansi_colours[fg]; -} - -static void flanterm_fb_set_text_bg(struct flanterm_context *_ctx, size_t bg) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_bg = ctx->ansi_colours[bg]; -} - -static void flanterm_fb_set_text_fg_bright(struct flanterm_context *_ctx, size_t fg) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_fg = ctx->ansi_bright_colours[fg]; -} - -static void flanterm_fb_set_text_bg_bright(struct flanterm_context *_ctx, size_t bg) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_bg = ctx->ansi_bright_colours[bg]; -} - -static void flanterm_fb_set_text_fg_rgb(struct flanterm_context *_ctx, uint32_t fg) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_fg = convert_colour(_ctx, fg); -} - -static void flanterm_fb_set_text_bg_rgb(struct flanterm_context *_ctx, uint32_t bg) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_bg = convert_colour(_ctx, bg); -} - -static void flanterm_fb_set_text_fg_default(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_fg = ctx->default_fg; -} - -static void flanterm_fb_set_text_bg_default(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_bg = 0xffffffff; -} - -static void flanterm_fb_set_text_fg_default_bright(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_fg = ctx->default_fg_bright; -} - -static void flanterm_fb_set_text_bg_default_bright(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_bg = ctx->default_bg_bright; -} - -static void draw_cursor(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (ctx->cursor_x >= _ctx->cols || ctx->cursor_y >= _ctx->rows) { - return; - } - - size_t i = ctx->cursor_x + ctx->cursor_y * _ctx->cols; - - struct flanterm_fb_char c; - struct flanterm_fb_queue_item *q = ctx->map[i]; - if (q != NULL) { - c = q->c; - } else { - c = ctx->grid[i]; - } - uint32_t tmp = c.fg; - c.fg = c.bg; - c.bg = tmp; - ctx->plot_char(_ctx, &c, ctx->cursor_x, ctx->cursor_y); - if (q != NULL) { - ctx->grid[i] = q->c; - ctx->map[i] = NULL; - } -} - -static void flanterm_fb_double_buffer_flush(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (_ctx->cursor_enabled) { - draw_cursor(_ctx); - } - - for (size_t i = 0; i < ctx->queue_i; i++) { - struct flanterm_fb_queue_item *q = &ctx->queue[i]; - size_t offset = q->y * _ctx->cols + q->x; - if (ctx->map[offset] == NULL) { - continue; - } - ctx->plot_char(_ctx, &q->c, q->x, q->y); - ctx->grid[offset] = q->c; - ctx->map[offset] = NULL; - } - - if ((ctx->old_cursor_x != ctx->cursor_x || ctx->old_cursor_y != ctx->cursor_y) || _ctx->cursor_enabled == false) { - if (ctx->old_cursor_x < _ctx->cols && ctx->old_cursor_y < _ctx->rows) { - ctx->plot_char(_ctx, &ctx->grid[ctx->old_cursor_x + ctx->old_cursor_y * _ctx->cols], ctx->old_cursor_x, ctx->old_cursor_y); - } - } - - ctx->old_cursor_x = ctx->cursor_x; - ctx->old_cursor_y = ctx->cursor_y; - - ctx->queue_i = 0; -} - -static void flanterm_fb_raw_putchar(struct flanterm_context *_ctx, uint8_t c) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (ctx->cursor_x >= _ctx->cols && (ctx->cursor_y < _ctx->scroll_bottom_margin - 1 || _ctx->scroll_enabled)) { - ctx->cursor_x = 0; - ctx->cursor_y++; - if (ctx->cursor_y == _ctx->scroll_bottom_margin) { - ctx->cursor_y--; - flanterm_fb_scroll(_ctx); - } - if (ctx->cursor_y >= _ctx->cols) { - ctx->cursor_y = _ctx->cols - 1; - } - } - - struct flanterm_fb_char ch; - ch.c = c; - ch.fg = ctx->text_fg; - ch.bg = ctx->text_bg; - push_to_queue(_ctx, &ch, ctx->cursor_x++, ctx->cursor_y); -} - -static void flanterm_fb_full_refresh(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - uint32_t default_bg = ctx->default_bg; - - for (size_t y = 0; y < ctx->height; y++) { - for (size_t x = 0; x < ctx->width; x++) { - if (ctx->canvas != NULL) { - ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = ctx->canvas[y * ctx->width + x]; - } else { - ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = default_bg; - } - } - } - - for (size_t i = 0; i < (size_t)_ctx->rows * _ctx->cols; i++) { - size_t x = i % _ctx->cols; - size_t y = i / _ctx->cols; - - ctx->plot_char(_ctx, &ctx->grid[i], x, y); - } - - if (_ctx->cursor_enabled) { - draw_cursor(_ctx); - } -} - -static void flanterm_fb_deinit(struct flanterm_context *_ctx, void (*_free)(void *, size_t)) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (_free == NULL) { -#ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - if (bump_allocated_instance == true) { - bump_alloc_ptr = 0; - bump_allocated_instance = false; - } -#endif - return; - } - - _free(ctx->font_bits, ctx->font_bits_size); - _free(ctx->font_bool, ctx->font_bool_size); - _free(ctx->grid, ctx->grid_size); - _free(ctx->queue, ctx->queue_size); - _free(ctx->map, ctx->map_size); - - if (ctx->canvas != NULL) { - _free(ctx->canvas, ctx->canvas_size); - } - - _free(ctx, sizeof(struct flanterm_fb_context)); -} - -struct flanterm_context *flanterm_fb_init( - void *(*_malloc)(size_t), - void (*_free)(void *, size_t), - uint32_t *framebuffer, size_t width, size_t height, size_t pitch, - uint8_t red_mask_size, uint8_t red_mask_shift, - uint8_t green_mask_size, uint8_t green_mask_shift, - uint8_t blue_mask_size, uint8_t blue_mask_shift, - uint32_t *canvas, - uint32_t *ansi_colours, uint32_t *ansi_bright_colours, - uint32_t *default_bg, uint32_t *default_fg, - uint32_t *default_bg_bright, uint32_t *default_fg_bright, - void *font, size_t font_width, size_t font_height, size_t font_spacing, - size_t font_scale_x, size_t font_scale_y, - size_t margin -) { - if (font_scale_x == 0 || font_scale_y == 0) { - font_scale_x = 1; - font_scale_y = 1; - if (width >= (1920 + 1920 / 3) && height >= (1080 + 1080 / 3)) { - font_scale_x = 2; - font_scale_y = 2; - } - if (width >= (3840 + 3840 / 3) && height >= (2160 + 2160 / 3)) { - font_scale_x = 4; - font_scale_y = 4; - } - } - - if (red_mask_size < 8 || red_mask_size != green_mask_size || red_mask_size != blue_mask_size) { - return NULL; - } - - if (_malloc == NULL) { -#ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - if (bump_allocated_instance == true) { - return NULL; - } - _malloc = bump_alloc; - // Limit terminal size if needed - if (width > FLANTERM_FB_WIDTH_LIMIT || height > FLANTERM_FB_HEIGHT_LIMIT) { - size_t width_limit = width > FLANTERM_FB_WIDTH_LIMIT ? FLANTERM_FB_WIDTH_LIMIT : width; - size_t height_limit = height > FLANTERM_FB_HEIGHT_LIMIT ? FLANTERM_FB_HEIGHT_LIMIT : height; - - framebuffer = (uint32_t *)((uintptr_t)framebuffer + ((((height / 2) - (height_limit / 2)) * pitch) + (((width / 2) - (width_limit / 2)) * 4))); - - width = width_limit; - height = height_limit; - } - - // Force disable canvas - canvas = NULL; -#else - return NULL; -#endif - } - - struct flanterm_fb_context *ctx = NULL; - ctx = _malloc(sizeof(struct flanterm_fb_context)); - if (ctx == NULL) { - goto fail; - } - - struct flanterm_context *_ctx = (void *)ctx; - memset(ctx, 0, sizeof(struct flanterm_fb_context)); - - ctx->red_mask_size = red_mask_size; - ctx->red_mask_shift = red_mask_shift + (red_mask_size - 8); - ctx->green_mask_size = green_mask_size; - ctx->green_mask_shift = green_mask_shift + (green_mask_size - 8); - ctx->blue_mask_size = blue_mask_size; - ctx->blue_mask_shift = blue_mask_shift + (blue_mask_size - 8); - - if (ansi_colours != NULL) { - for (size_t i = 0; i < 8; i++) { - ctx->ansi_colours[i] = convert_colour(_ctx, ansi_colours[i]); - } - } else { - ctx->ansi_colours[0] = convert_colour(_ctx, 0x00000000); // black - ctx->ansi_colours[1] = convert_colour(_ctx, 0x00aa0000); // red - ctx->ansi_colours[2] = convert_colour(_ctx, 0x0000aa00); // green - ctx->ansi_colours[3] = convert_colour(_ctx, 0x00aa5500); // brown - ctx->ansi_colours[4] = convert_colour(_ctx, 0x000000aa); // blue - ctx->ansi_colours[5] = convert_colour(_ctx, 0x00aa00aa); // magenta - ctx->ansi_colours[6] = convert_colour(_ctx, 0x0000aaaa); // cyan - ctx->ansi_colours[7] = convert_colour(_ctx, 0x00aaaaaa); // grey - } - - if (ansi_bright_colours != NULL) { - for (size_t i = 0; i < 8; i++) { - ctx->ansi_bright_colours[i] = convert_colour(_ctx, ansi_bright_colours[i]); - } - } else { - ctx->ansi_bright_colours[0] = convert_colour(_ctx, 0x00555555); // black - ctx->ansi_bright_colours[1] = convert_colour(_ctx, 0x00ff5555); // red - ctx->ansi_bright_colours[2] = convert_colour(_ctx, 0x0055ff55); // green - ctx->ansi_bright_colours[3] = convert_colour(_ctx, 0x00ffff55); // brown - ctx->ansi_bright_colours[4] = convert_colour(_ctx, 0x005555ff); // blue - ctx->ansi_bright_colours[5] = convert_colour(_ctx, 0x00ff55ff); // magenta - ctx->ansi_bright_colours[6] = convert_colour(_ctx, 0x0055ffff); // cyan - ctx->ansi_bright_colours[7] = convert_colour(_ctx, 0x00ffffff); // grey - } - - if (default_bg != NULL) { - ctx->default_bg = convert_colour(_ctx, *default_bg); - } else { - ctx->default_bg = 0x00000000; // background (black) - } - - if (default_fg != NULL) { - ctx->default_fg = convert_colour(_ctx, *default_fg); - } else { - ctx->default_fg = convert_colour(_ctx, 0x00aaaaaa); // foreground (grey) - } - - if (default_bg_bright != NULL) { - ctx->default_bg_bright = convert_colour(_ctx, *default_bg_bright); - } else { - ctx->default_bg_bright = convert_colour(_ctx, 0x00555555); // background (black) - } - - if (default_fg_bright != NULL) { - ctx->default_fg_bright = convert_colour(_ctx, *default_fg_bright); - } else { - ctx->default_fg_bright = convert_colour(_ctx, 0x00ffffff); // foreground (grey) - } - - ctx->text_fg = ctx->default_fg; - ctx->text_bg = 0xffffffff; - - ctx->framebuffer = (void *)framebuffer; - ctx->width = width; - ctx->height = height; - ctx->pitch = pitch; - -#define FONT_BYTES ((font_width * font_height * FLANTERM_FB_FONT_GLYPHS) / 8) - - if (font != NULL) { - ctx->font_width = font_width; - ctx->font_height = font_height; - ctx->font_bits_size = FONT_BYTES; - ctx->font_bits = _malloc(ctx->font_bits_size); - if (ctx->font_bits == NULL) { - goto fail; - } - memcpy(ctx->font_bits, font, ctx->font_bits_size); - } else { - ctx->font_width = font_width = 8; - ctx->font_height = font_height = 16; - ctx->font_bits_size = FONT_BYTES; - font_spacing = 1; - ctx->font_bits = _malloc(ctx->font_bits_size); - if (ctx->font_bits == NULL) { - goto fail; - } - memcpy(ctx->font_bits, builtin_font, ctx->font_bits_size); - } - -#undef FONT_BYTES - - ctx->font_width += font_spacing; - - ctx->font_bool_size = FLANTERM_FB_FONT_GLYPHS * font_height * ctx->font_width * sizeof(bool); - ctx->font_bool = _malloc(ctx->font_bool_size); - if (ctx->font_bool == NULL) { - goto fail; - } - - for (size_t i = 0; i < FLANTERM_FB_FONT_GLYPHS; i++) { - uint8_t *glyph = &ctx->font_bits[i * font_height]; - - for (size_t y = 0; y < font_height; y++) { - // NOTE: the characters in VGA fonts are always one byte wide. - // 9 dot wide fonts have 8 dots and one empty column, except - // characters 0xC0-0xDF replicate column 9. - for (size_t x = 0; x < 8; x++) { - size_t offset = i * font_height * ctx->font_width + y * ctx->font_width + x; - - if ((glyph[y] & (0x80 >> x))) { - ctx->font_bool[offset] = true; - } else { - ctx->font_bool[offset] = false; - } - } - // fill columns above 8 like VGA Line Graphics Mode does - for (size_t x = 8; x < ctx->font_width; x++) { - size_t offset = i * font_height * ctx->font_width + y * ctx->font_width + x; - - if (i >= 0xc0 && i <= 0xdf) { - ctx->font_bool[offset] = (glyph[y] & 1); - } else { - ctx->font_bool[offset] = false; - } - } - } - } - - ctx->font_scale_x = font_scale_x; - ctx->font_scale_y = font_scale_y; - - ctx->glyph_width = ctx->font_width * font_scale_x; - ctx->glyph_height = font_height * font_scale_y; - - _ctx->cols = (ctx->width - margin * 2) / ctx->glyph_width; - _ctx->rows = (ctx->height - margin * 2) / ctx->glyph_height; - - ctx->offset_x = margin + ((ctx->width - margin * 2) % ctx->glyph_width) / 2; - ctx->offset_y = margin + ((ctx->height - margin * 2) % ctx->glyph_height) / 2; - - ctx->grid_size = _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_char); - ctx->grid = _malloc(ctx->grid_size); - if (ctx->grid == NULL) { - goto fail; - } - for (size_t i = 0; i < _ctx->rows * _ctx->cols; i++) { - ctx->grid[i].c = ' '; - ctx->grid[i].fg = ctx->text_fg; - ctx->grid[i].bg = ctx->text_bg; - } - - ctx->queue_size = _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item); - ctx->queue = _malloc(ctx->queue_size); - if (ctx->queue == NULL) { - goto fail; - } - ctx->queue_i = 0; - memset(ctx->queue, 0, ctx->queue_size); - - ctx->map_size = _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item *); - ctx->map = _malloc(ctx->map_size); - if (ctx->map == NULL) { - goto fail; - } - memset(ctx->map, 0, ctx->map_size); - - if (canvas != NULL) { - ctx->canvas_size = ctx->width * ctx->height * sizeof(uint32_t); - ctx->canvas = _malloc(ctx->canvas_size); - if (ctx->canvas == NULL) { - goto fail; - } - for (size_t i = 0; i < ctx->width * ctx->height; i++) { - ctx->canvas[i] = convert_colour(_ctx, canvas[i]); - } - } - - if (font_scale_x == 1 && font_scale_y == 1) { - if (canvas == NULL) { - ctx->plot_char = plot_char_unscaled_uncanvas; - } else { - ctx->plot_char = plot_char_unscaled_canvas; - } - } else { - if (canvas == NULL) { - ctx->plot_char = plot_char_scaled_uncanvas; - } else { - ctx->plot_char = plot_char_scaled_canvas; - } - } - - _ctx->raw_putchar = flanterm_fb_raw_putchar; - _ctx->clear = flanterm_fb_clear; - _ctx->set_cursor_pos = flanterm_fb_set_cursor_pos; - _ctx->get_cursor_pos = flanterm_fb_get_cursor_pos; - _ctx->set_text_fg = flanterm_fb_set_text_fg; - _ctx->set_text_bg = flanterm_fb_set_text_bg; - _ctx->set_text_fg_bright = flanterm_fb_set_text_fg_bright; - _ctx->set_text_bg_bright = flanterm_fb_set_text_bg_bright; - _ctx->set_text_fg_rgb = flanterm_fb_set_text_fg_rgb; - _ctx->set_text_bg_rgb = flanterm_fb_set_text_bg_rgb; - _ctx->set_text_fg_default = flanterm_fb_set_text_fg_default; - _ctx->set_text_bg_default = flanterm_fb_set_text_bg_default; - _ctx->set_text_fg_default_bright = flanterm_fb_set_text_fg_default_bright; - _ctx->set_text_bg_default_bright = flanterm_fb_set_text_bg_default_bright; - _ctx->move_character = flanterm_fb_move_character; - _ctx->scroll = flanterm_fb_scroll; - _ctx->revscroll = flanterm_fb_revscroll; - _ctx->swap_palette = flanterm_fb_swap_palette; - _ctx->save_state = flanterm_fb_save_state; - _ctx->restore_state = flanterm_fb_restore_state; - _ctx->double_buffer_flush = flanterm_fb_double_buffer_flush; - _ctx->full_refresh = flanterm_fb_full_refresh; - _ctx->deinit = flanterm_fb_deinit; - - flanterm_context_reinit(_ctx); - flanterm_fb_full_refresh(_ctx); - -#ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - if (_malloc == bump_alloc) { - bump_allocated_instance = true; - } -#endif - - return _ctx; - -fail: - if (ctx == NULL) { - return NULL; - } - -#ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - if (_malloc == bump_alloc) { - bump_alloc_ptr = 0; - return NULL; - } -#endif - - if (_free == NULL) { - return NULL; - } - - if (ctx->canvas != NULL) { - _free(ctx->canvas, ctx->canvas_size); - } - if (ctx->map != NULL) { - _free(ctx->map, ctx->map_size); - } - if (ctx->queue != NULL) { - _free(ctx->queue, ctx->queue_size); - } - if (ctx->grid != NULL) { - _free(ctx->grid, ctx->grid_size); - } - if (ctx->font_bool != NULL) { - _free(ctx->font_bool, ctx->font_bool_size); - } - if (ctx->font_bits != NULL) { - _free(ctx->font_bits, ctx->font_bits_size); - } - if (ctx != NULL) { - _free(ctx, sizeof(struct flanterm_fb_context)); - } - - return NULL; -} diff --git a/kernel/src/lib/Flanterm/src/flanterm_backends/fb.h b/kernel/src/lib/Flanterm/src/flanterm_backends/fb.h deleted file mode 100644 index f4e5e4a..0000000 --- a/kernel/src/lib/Flanterm/src/flanterm_backends/fb.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (C) 2022-2025 mintsuki and contributors. - * - * 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. - * - * 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 HOLDER 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 FLANTERM_FB_H -#define FLANTERM_FB_H 1 - -#include <stdint.h> -#include <stddef.h> -#include <stdbool.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#include "../flanterm.h" - -#ifdef FLANTERM_IN_FLANTERM - -#include "fb_private.h" - -#endif - -struct flanterm_context *flanterm_fb_init( - /* If _malloc and _free are nulled, use the bump allocated instance (1 use only). */ - void *(*_malloc)(size_t size), - void (*_free)(void *ptr, size_t size), - uint32_t *framebuffer, size_t width, size_t height, size_t pitch, - uint8_t red_mask_size, uint8_t red_mask_shift, - uint8_t green_mask_size, uint8_t green_mask_shift, - uint8_t blue_mask_size, uint8_t blue_mask_shift, - uint32_t *canvas, /* If nulled, no canvas. */ - uint32_t *ansi_colours, uint32_t *ansi_bright_colours, /* If nulled, default. */ - uint32_t *default_bg, uint32_t *default_fg, /* If nulled, default. */ - uint32_t *default_bg_bright, uint32_t *default_fg_bright, /* If nulled, default. */ - /* If font is null, use default font and font_width and font_height ignored. */ - void *font, size_t font_width, size_t font_height, size_t font_spacing, - /* If scale_x and scale_y are 0, automatically scale font based on resolution. */ - size_t font_scale_x, size_t font_scale_y, - size_t margin -); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/src/lib/Flanterm/src/flanterm_backends/fb_private.h b/kernel/src/lib/Flanterm/src/flanterm_backends/fb_private.h deleted file mode 100644 index 532e1ab..0000000 --- a/kernel/src/lib/Flanterm/src/flanterm_backends/fb_private.h +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright (C) 2022-2025 mintsuki and contributors. - * - * 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. - * - * 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 HOLDER 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 FLANTERM_FB_PRIVATE_H -#define FLANTERM_FB_PRIVATE_H 1 - -#ifndef FLANTERM_IN_FLANTERM -#error "Do not use fb_private.h. Use interfaces defined in fb.h only." -#endif - -#include <stdint.h> -#include <stddef.h> -#include <stdbool.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define FLANTERM_FB_FONT_GLYPHS 256 - -struct flanterm_fb_char { - uint32_t c; - uint32_t fg; - uint32_t bg; -}; - -struct flanterm_fb_queue_item { - size_t x, y; - struct flanterm_fb_char c; -}; - -struct flanterm_fb_context { - struct flanterm_context term; - - void (*plot_char)(struct flanterm_context *ctx, struct flanterm_fb_char *c, size_t x, size_t y); - - size_t font_width; - size_t font_height; - size_t glyph_width; - size_t glyph_height; - - size_t font_scale_x; - size_t font_scale_y; - - size_t offset_x, offset_y; - - volatile uint32_t *framebuffer; - size_t pitch; - size_t width; - size_t height; - size_t bpp; - - uint8_t red_mask_size, red_mask_shift; - uint8_t green_mask_size, green_mask_shift; - uint8_t blue_mask_size, blue_mask_shift; - - size_t font_bits_size; - uint8_t *font_bits; - size_t font_bool_size; - bool *font_bool; - - uint32_t ansi_colours[8]; - uint32_t ansi_bright_colours[8]; - uint32_t default_fg, default_bg; - uint32_t default_fg_bright, default_bg_bright; - - size_t canvas_size; - uint32_t *canvas; - - size_t grid_size; - size_t queue_size; - size_t map_size; - - struct flanterm_fb_char *grid; - - struct flanterm_fb_queue_item *queue; - size_t queue_i; - - struct flanterm_fb_queue_item **map; - - uint32_t text_fg; - uint32_t text_bg; - size_t cursor_x; - size_t cursor_y; - - uint32_t saved_state_text_fg; - uint32_t saved_state_text_bg; - size_t saved_state_cursor_x; - size_t saved_state_cursor_y; - - size_t old_cursor_x; - size_t old_cursor_y; -}; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/src/lib/Flanterm/src/flanterm_private.h b/kernel/src/lib/Flanterm/src/flanterm_private.h deleted file mode 100644 index 8a2d5fa..0000000 --- a/kernel/src/lib/Flanterm/src/flanterm_private.h +++ /dev/null @@ -1,123 +0,0 @@ -/* Copyright (C) 2022-2025 mintsuki and contributors. - * - * 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. - * - * 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 HOLDER 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 FLANTERM_PRIVATE_H -#define FLANTERM_PRIVATE_H 1 - -#ifndef FLANTERM_IN_FLANTERM -#error "Do not use flanterm_private.h. Use interfaces defined in flanterm.h only." -#endif - -#include <stddef.h> -#include <stdint.h> -#include <stdbool.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define FLANTERM_MAX_ESC_VALUES 16 - -struct flanterm_context { - /* internal use */ - - size_t tab_size; - bool autoflush; - bool cursor_enabled; - bool scroll_enabled; - bool control_sequence; - bool escape; - bool osc; - bool osc_escape; - bool rrr; - bool discard_next; - bool bold; - bool bg_bold; - bool reverse_video; - bool dec_private; - bool insert_mode; - bool csi_unhandled; - uint64_t code_point; - size_t unicode_remaining; - uint8_t g_select; - uint8_t charsets[2]; - size_t current_charset; - size_t escape_offset; - size_t esc_values_i; - size_t saved_cursor_x; - size_t saved_cursor_y; - size_t current_primary; - size_t current_bg; - size_t scroll_top_margin; - size_t scroll_bottom_margin; - uint32_t esc_values[FLANTERM_MAX_ESC_VALUES]; - uint64_t oob_output; - bool saved_state_bold; - bool saved_state_bg_bold; - bool saved_state_reverse_video; - size_t saved_state_current_charset; - size_t saved_state_current_primary; - size_t saved_state_current_bg; - - /* to be set by backend */ - - size_t rows, cols; - - void (*raw_putchar)(struct flanterm_context *, uint8_t c); - void (*clear)(struct flanterm_context *, bool move); - void (*set_cursor_pos)(struct flanterm_context *, size_t x, size_t y); - void (*get_cursor_pos)(struct flanterm_context *, size_t *x, size_t *y); - void (*set_text_fg)(struct flanterm_context *, size_t fg); - void (*set_text_bg)(struct flanterm_context *, size_t bg); - void (*set_text_fg_bright)(struct flanterm_context *, size_t fg); - void (*set_text_bg_bright)(struct flanterm_context *, size_t bg); - void (*set_text_fg_rgb)(struct flanterm_context *, uint32_t fg); - void (*set_text_bg_rgb)(struct flanterm_context *, uint32_t bg); - void (*set_text_fg_default)(struct flanterm_context *); - void (*set_text_bg_default)(struct flanterm_context *); - void (*set_text_fg_default_bright)(struct flanterm_context *); - void (*set_text_bg_default_bright)(struct flanterm_context *); - void (*move_character)(struct flanterm_context *, size_t new_x, size_t new_y, size_t old_x, size_t old_y); - void (*scroll)(struct flanterm_context *); - void (*revscroll)(struct flanterm_context *); - void (*swap_palette)(struct flanterm_context *); - void (*save_state)(struct flanterm_context *); - void (*restore_state)(struct flanterm_context *); - void (*double_buffer_flush)(struct flanterm_context *); - void (*full_refresh)(struct flanterm_context *); - void (*deinit)(struct flanterm_context *, void (*)(void *, size_t)); - - /* to be set by client */ - - void (*callback)(struct flanterm_context *, uint64_t, uint64_t, uint64_t, uint64_t); -}; - -void flanterm_context_reinit(struct flanterm_context *ctx); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/src/lib/uACPI b/kernel/src/lib/uACPI deleted file mode 160000 -Subproject e5e5deea6f4dea0ea81237db39ca061ead048e6 diff --git a/kernel/src/main.asm b/kernel/src/main.asm deleted file mode 100644 index 88b0d53..0000000 --- a/kernel/src/main.asm +++ /dev/null @@ -1,22 +0,0 @@ - -section .text - -extern main -global kmain -kmain: - mov rsp,stack_top - call main - hlt - -global setwp -setwp: - mov rax,cr0 - or rax, 0x10000 - mov cr0,rax - ret - - -section .data -stack_bottom: -resb 1024*128 -stack_top:
\ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 292386e..e90731a 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,275 +1,33 @@ - -#include <drivers/xhci.hpp> -#include <drivers/pci.hpp> - -#include <arch/x86_64/syscalls/syscalls.hpp> -#include <arch/x86_64/syscalls/sockets.hpp> -#include <arch/x86_64/interrupts/idt.hpp> -#include <arch/x86_64/interrupts/irq.hpp> -#include <arch/x86_64/interrupts/pic.hpp> -#include <arch/x86_64/interrupts/pit.hpp> -#include <arch/x86_64/scheduling.hpp> -#include <arch/x86_64/cpu/lapic.hpp> -#include <arch/x86_64/cpu/gdt.hpp> -#include <arch/x86_64/cpu/smp.hpp> -#include <arch/x86_64/cpu/sse.hpp> -#include <generic/mm/paging.hpp> -#include <generic/vfs/ustar.hpp> -#include <drivers/kvmtimer.hpp> -#include <generic/vfs/vfs.hpp> -#include <generic/mm/heap.hpp> -#include <generic/mm/pmm.hpp> -#include <drivers/serial.hpp> -#include <drivers/cmos.hpp> +#include <cstdint> +#include <generic/bootloader/bootloader.hpp> +#include <utils/cxx/cxx_constructors.hpp> +#include <generic/arch.hpp> +#include <utils/flanterm.hpp> +#include <generic/pmm.hpp> +#include <generic/paging.hpp> +#include <generic/heap.hpp> #include <drivers/acpi.hpp> -#include <etc/assembly.hpp> -#include <drivers/tsc.hpp> -#include <etc/logging.hpp> -#include <uacpi/event.h> -#include <etc/etc.hpp> -#include <limine.h> - -#include <drivers/ps2.hpp> - -#include <generic/vfs/fd.hpp> - -char is_shift_pressed = 0; -char is_ctrl_pressed = 0; - -const char en_layout_translation[] = { - '\0', '\e', '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', ' ' -}; - -const char en_layout_translation_shift[] = { - '\0', '\e', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\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', ' ' -}; -\ -#define ASCII_CTRL_OFFSET 96 - -#define SHIFT_PRESSED 0x2A -#define SHIFT_RELEASED 0xAA -#define CTRL_PRESSED 29 -#define CTRL_RELEASED 157 - -#include <generic/locks/spinlock.hpp> - -std::uint16_t KERNEL_GOOD_TIMER = HPET_TIMER; - -static uacpi_interrupt_ret handle_power_button(uacpi_handle ctx) { - Log::Display(LEVEL_MESSAGE_OK,"Got uacpi power_button !\n"); - return UACPI_INTERRUPT_HANDLED; -} - -void interrupt_process_handle(void* arg) { - while(1) { - asm volatile("sti"); - asm volatile("pause"); - asm volatile("cli"); - yield(); - } -} - -arch::x86_64::process_t* init = 0; - -static void doKeyWork(uint8_t key,userspace_fd_t* fd_to_write) { - - if(key == SHIFT_PRESSED) { - is_shift_pressed = 1; - return; - } else if(key == SHIFT_RELEASED) { - is_shift_pressed = 0; - return; - } - - if(key == CTRL_PRESSED) { - is_ctrl_pressed = 1; - return; - } else if(key == CTRL_RELEASED) { - is_ctrl_pressed = 0; - return; - } - - if(!(key & (1 << 7))) { - char layout_key; - - if(!is_shift_pressed) - layout_key = en_layout_translation[key]; - else - layout_key = en_layout_translation_shift[key]; - - if(is_ctrl_pressed) - layout_key = en_layout_translation[key] - ASCII_CTRL_OFFSET; - - vfs::vfs::write(fd_to_write,&layout_key,1); - } -} - -void ktty(void* arg) { - userspace_fd_t kbd; - userspace_fd_t tty; - memset(&kbd,0,sizeof(userspace_fd_t)); - memset(&tty,0,sizeof(userspace_fd_t)); - memcpy(kbd.path,"/dev/ps2keyboard0",sizeof("/dev/ps2keyboard0")); - memcpy(tty.path,"/dev/tty0",sizeof("/dev/tty0")); // tty0 is reserved for kernel tty - - while(1) { - asm volatile("cli"); - std::int32_t kbd_poll = vfs::vfs::poll(&kbd,POLLIN); - std::int32_t tty_poll = vfs::vfs::poll(&tty,POLLIN); - asm volatile("sti"); - - if(kbd_poll > 0) { - char buffer[32]; - memset(buffer,0,32); - asm volatile("cli"); - std::int64_t bytes_read = vfs::vfs::read(&kbd,buffer,32); - for(int i = 0;i < bytes_read;i++) { - doKeyWork(buffer[i], &tty); - } - asm volatile("sti"); - } - - if(tty_poll > 0) { - char buffer[128]; - memset(buffer,0,128); - asm volatile("cli"); - std::int64_t bytes_read = vfs::vfs::read(&tty,buffer,32); - asm volatile("sti"); - if(bytes_read > 0) { - Log::RawDisp(buffer,bytes_read); - } - } - asm volatile("cli"); - yield(); - asm volatile("sti"); - } - -} - -extern "C" void main() { - - Other::ConstructorsInit(); - asm volatile("cli"); - - drivers::serial serial(DEFAULT_SERIAL_PORT); - - __wrmsr(0xC0000101,0); - - memory::pmm::_physical::init(); - memory::heap::init(); - - Log::Init(); - - memory::paging::init(); - //Log::Display(LEVEL_MESSAGE_OK,"Paging initializied\n"); - - arch::x86_64::cpu::gdt::init(); - //Log::Display(LEVEL_MESSAGE_OK,"GDT initializied\n"); - - arch::x86_64::interrupts::idt::init(); - //Log::Display(LEVEL_MESSAGE_OK,"IDT initializied\n"); - - arch::x86_64::interrupts::pic::init(); - Log::Display(LEVEL_MESSAGE_OK,"PIC initializied\n"); - - drivers::kvmclock::init(); - drivers::acpi::init(); - Log::Display(LEVEL_MESSAGE_OK,"ACPI initializied\n"); - - vfs::vfs::init(); - Log::Display(LEVEL_MESSAGE_OK,"VFS initializied\n"); - - arch::x86_64::cpu::sse::init(); - //Log::Display(LEVEL_MESSAGE_OK,"SSE initializied\n"); - - arch::x86_64::cpu::mp::init(); - arch::x86_64::cpu::mp::sync(0); - Log::Display(LEVEL_MESSAGE_OK,"SMP initializied\n"); - - arch::x86_64::scheduling::init(); - Log::Display(LEVEL_MESSAGE_OK,"Scheduling initializied\n"); - - init = arch::x86_64::scheduling::create(); - extern int how_much_cpus; - - for(int i = 0;i < how_much_cpus; i++) { - arch::x86_64::scheduling::create_kernel_thread(interrupt_process_handle,0); // we need to have processes which will do sti for interrupt waiting - } - - xhci_init(); - - arch::x86_64::scheduling::create_kernel_thread(ktty,0); - - drivers::pci::initworkspace(); - Log::Display(LEVEL_MESSAGE_OK,"PCI initializied\n"); - - drivers::ps2::init(); - - vfs::ustar::copy(); - Log::Display(LEVEL_MESSAGE_OK,"USTAR parsed\n"); - - arch::x86_64::syscall::init(); - Log::Display(LEVEL_MESSAGE_OK,"Syscalls initializied\n"); - - sockets::init(); - Log::Display(LEVEL_MESSAGE_OK,"Sockets initializied\n"); - - uacpi_status ret = uacpi_install_fixed_event_handler( - UACPI_FIXED_EVENT_POWER_BUTTON, - handle_power_button, UACPI_NULL - ); - - char* argv[] = {0}; - char* envp[] = {"TERM=linux","SHELL=/bin/bash","PATH=/usr/bin:/bin",0}; - - Log::Display(LEVEL_MESSAGE_INFO,"Trying to sync cpus...\n"); - arch::x86_64::cpu::mp::sync(1); - - arch::x86_64::scheduling::loadelf(init,"/bin/bash",argv,envp,0); - arch::x86_64::scheduling::wakeup(init); - - vfs::fdmanager* fd = (vfs::fdmanager*)init->fd; - - int stdin = fd->create(init); - int stdout = fd->create(init); - int stderr = fd->create(init); - - userspace_fd_t *stdins = fd->search(init,stdin); - userspace_fd_t *stdouts = fd->search(init,stdout); - userspace_fd_t* stderrs = fd->search(init,stderr); - - memcpy(stdins->path,"/dev/pts/0",sizeof("/dev/pts/0")); - memcpy(stdouts->path,"/dev/pts/0",sizeof("/dev/pts/0")); - memcpy(stderrs->path,"/dev/pts/0",sizeof("/dev/pts/0")); - - stdins->index = 0; - stdouts->index = 1; - stderrs->index = 2; - - stdins->is_cached_path = 0; - stdouts->is_cached_path = 0; - stderrs->is_cached_path = 0; - - extern locks::spinlock* vfs_lock; - extern locks::spinlock pmm_lock; - - Log::Display(LEVEL_MESSAGE_FAIL,"\e[1;1H\e[2J"); - arch::x86_64::cpu::lapic::tick(arch::x86_64::cpu::data()->lapic_block); - - dmesg("Now we are in userspace..."); - - setwp(); - - asm volatile("sti"); - while(1) { - - asm volatile("hlt"); - } +extern std::size_t memory_size; + +extern "C" void kmain() { + utils::cxx::init_constructors(); + bootloader::init(); + utils::flanterm::init(); + pmm::init(); + paging::init(); + kheap::init(); + utils::flanterm::fullinit(); + klibc::printf("PMM: Total usable memory: %lli bytes\r\n",memory_size); // i dont want to forgot these messages + klibc::printf("Paging: Enabled kernel root with %d level paging\n\r", arch::level_paging()); + klibc::printf("KHeap: Available memory %lli bytes\r\n",KHEAP_SIZE); + acpi::init_tables(); + arch::init(ARCH_INIT_EARLY); + acpi::full_init(); + arch::init(ARCH_INIT_COMMON); + extern int is_early; + is_early = 0; + klibc::printf("Boot is done\r\n"); + //*(int*)0x100 = 0; + arch::hcf(); } diff --git a/kernel/src/utils/align.hpp b/kernel/src/utils/align.hpp new file mode 100644 index 0000000..2f2c665 --- /dev/null +++ b/kernel/src/utils/align.hpp @@ -0,0 +1,2 @@ +#define ALIGNUP(VALUE, c) ((VALUE + c - 1) & ~(c - 1)) +#define ALIGNDOWN(VALUE, c) ((VALUE / c) * c)
\ No newline at end of file diff --git a/tools/pkg/14/mate/diff/dconf.diff b/kernel/src/utils/assembly.hpp index e69de29..e69de29 100644 --- a/tools/pkg/14/mate/diff/dconf.diff +++ b/kernel/src/utils/assembly.hpp diff --git a/kernel/src/utils/bitmap.hpp b/kernel/src/utils/bitmap.hpp new file mode 100644 index 0000000..0ebbb15 --- /dev/null +++ b/kernel/src/utils/bitmap.hpp @@ -0,0 +1,37 @@ +#pragma once +#include <klibc/stdio.hpp> +#include <klibc/stdlib.hpp> +#include <klibc/string.hpp> +#include <utils/align.hpp> + +namespace utils { + class bitmap { + private: + std::uint8_t* pool; + std::uint32_t pool_size; + + public: + bitmap(std::uint32_t size, std::uint8_t* custom_pool = 0) { + if (custom_pool) { + this->pool = custom_pool; + this->pool_size = (ALIGNUP(size, 8) / 8); + } else { + this->pool_size = (ALIGNUP(size, 8) / 8) + 1; + this->pool = (std::uint8_t*) klibc::malloc(pool_size); + } + klibc::memset(pool, 0, pool_size); + } + + std::uint8_t test(std::uint32_t idx) { + return pool[ALIGNDOWN(idx, 8) / 8] & (1 << (idx - ALIGNDOWN(idx, 8))); + } + + void clear(std::uint32_t idx) { + pool[ALIGNDOWN(idx, 8) / 8] &= ~(1 << (idx - ALIGNDOWN(idx, 8))); + } + + void set(std::uint32_t idx) { + pool[ALIGNDOWN(idx, 8) / 8] |= (1 << (idx - ALIGNDOWN(idx, 8))); + } + }; +};
\ No newline at end of file diff --git a/kernel/src/utils/cxx/cxx_constructors.cpp b/kernel/src/utils/cxx/cxx_constructors.cpp new file mode 100644 index 0000000..b1ee037 --- /dev/null +++ b/kernel/src/utils/cxx/cxx_constructors.cpp @@ -0,0 +1,12 @@ + +extern void (*__init_array[])(); +extern void (*__init_array_end[])(); + +#include <utils/cxx/cxx_constructors.hpp> +#include <cstdint> + +void utils::cxx::init_constructors() { + for (std::size_t i = 0; &__init_array[i] != __init_array_end; i++) { + __init_array[i](); + } +}
\ No newline at end of file diff --git a/kernel/src/utils/cxx/cxx_constructors.hpp b/kernel/src/utils/cxx/cxx_constructors.hpp new file mode 100644 index 0000000..f269745 --- /dev/null +++ b/kernel/src/utils/cxx/cxx_constructors.hpp @@ -0,0 +1,6 @@ + +namespace utils { + namespace cxx { + void init_constructors(); + } +}
\ No newline at end of file diff --git a/kernel/src/etc/etc.cpp b/kernel/src/utils/cxx/cxx_stuff.cpp index 2cf3d8c..c12546a 100644 --- a/kernel/src/etc/etc.cpp +++ b/kernel/src/utils/cxx/cxx_stuff.cpp @@ -1,7 +1,4 @@ - -#include <etc/etc.hpp> #include <cstdint> -#include <cstddef> extern "C" { @@ -30,11 +27,11 @@ void *memmove(void *dest, const void *src, std::size_t n) { std::uint8_t *pdest = static_cast<std::uint8_t *>(dest); const std::uint8_t *psrc = static_cast<const std::uint8_t *>(src); - if (src > dest) { + if (reinterpret_cast<std::uintptr_t>(src) > reinterpret_cast<std::uintptr_t>(dest)) { for (std::size_t i = 0; i < n; i++) { pdest[i] = psrc[i]; } - } else if (src < dest) { + } else if (reinterpret_cast<std::uintptr_t>(src) < reinterpret_cast<std::uintptr_t>(dest)) { for (std::size_t i = n; i > 0; i--) { pdest[i-1] = psrc[i-1]; } @@ -58,48 +55,50 @@ int memcmp(const void *s1, const void *s2, std::size_t n) { } -extern void (*__init_array[])(); -extern void (*__init_array_end[])(); - -void Other::ConstructorsInit() { - for (std::size_t i = 0; &__init_array[i] != __init_array_end; i++) { - __init_array[i](); - } -} +#include <generic/arch.hpp> extern "C" { int __cxa_atexit(void (*)(void *), void *, void *) { return 0; } - void __cxa_pure_virtual() { asm volatile("hlt"); } + void __cxa_pure_virtual() { arch::hcf(); } void *__dso_handle; } -#include <generic/mm/heap.hpp> +#include <generic/heap.hpp> + +typedef unsigned long size_t; void *operator new(size_t size) { - void* ptr = memory::heap::malloc(size); - memset(ptr,0,size); - return ptr; + void* p = kheap::malloc(size); + memset(p,0,size); + return p; } void *operator new[](size_t size) { - void* ptr = memory::heap::malloc(size); - memset(ptr,0,size); - return ptr; + void* p = kheap::malloc(size); + memset(p,0,size); + return p; } void operator delete(void *p) { - memory::heap::free(p); + kheap::free(p); } -void operator delete(void *p,unsigned long sz) +void operator delete[](void *p) { - memory::heap::free(p); + kheap::free(p); } -void operator delete[](void *p) +void operator delete(void *p, size_t size) { - memory::heap::free(p); + (void)size; + kheap::free(p); } + +void operator delete[](void *p, size_t size) +{ + (void)size; + kheap::free(p); +}
\ No newline at end of file diff --git a/kernel/include/etc/font.hpp b/kernel/src/utils/flanterm.cpp index 96d25a8..1c46922 100644 --- a/kernel/include/etc/font.hpp +++ b/kernel/src/utils/flanterm.cpp @@ -1,268 +1,184 @@ +#include <cstdint> +#include <generic/bootloader/bootloader.hpp> +#include <utils/flanterm.hpp> +#include <flanterm_backends/fb.h> +#include <generic/lock/spinlock.hpp> +#include <flanterm.h> -#pragma once +#include <generic/pmm.hpp> +#include <generic/hhdm.hpp> +#include <generic/heap.hpp> +#include <klibc/stdlib.hpp> +#include <klibc/stdio.hpp> +#include <klibc/string.hpp> -#define FONT_WIDTH 8 -#define FONT_HEIGHT 16 +locks::spinlock flanterm_lock; +flanterm_context* ft_ctx0 = 0; +int is_disabled_flanterm = 0; + +std::uint32_t default_fg = 0xEEEEEEEE; +std::uint32_t default_bright_fg = 0xFFFFFFFF; +std::uint32_t default_bg = 0; + +static inline int abs(int x) { + return x < 0 ? -x : x; +} + +extern "C" void* __flanterm_malloc(size_t size) { + return klibc::malloc(size); +} + +extern "C" void __flanterm_free(void* ptr,size_t size) { + (void)size; + klibc::free(ptr); +} + +void scale_image_nn(unsigned char* src, int src_w, int src_h, + unsigned char* dst, int dst_w, int dst_h, int channels) { + for (int y = 0; y < dst_h; y++) { + int src_y = y * src_h / dst_h; + for (int x = 0; x < dst_w; x++) { + int src_x = x * src_w / dst_w; + for (int c = 0; c < channels; c++) { + dst[(y*dst_w + x)*channels + c] = src[(src_y*src_w + src_x)*channels + c]; + } + } + } +} + +uint32_t rgb_to_pixel(uint8_t r, uint8_t g, uint8_t b, + int r_len, int r_off, + int g_len, int g_off, + int b_len, int b_off) { + uint32_t pixel = 0; + uint32_t R = (r >> (8 - r_len)) << r_off; + uint32_t G = (g >> (8 - g_len)) << g_off; + uint32_t B = (b >> (8 - b_len)) << b_off; + pixel = R | G | B; + return pixel; +} + +static uint32_t blend_pixel(uint32_t dst, uint8_t r_src, uint8_t g_src, uint8_t b_src, int alpha_fixed, + int r_len, int r_off, int g_len, int g_off, int b_len, int b_off) { + // alpha_fixed в диапазоне 0-256 (где 256 = 1.0) + + uint8_t r_dst = (dst >> r_off) & ((1 << r_len) - 1); + uint8_t g_dst = (dst >> g_off) & ((1 << g_len) - 1); + uint8_t b_dst = (dst >> b_off) & ((1 << b_len) - 1); -static const uint8_t builtin_font[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x42, 0x81, 0x81, 0xa5, 0xa5, 0x81, 0x81, 0xa5, 0x99, 0x81, 0x42, 0x3c, 0x00, 0x00, - 0x00, 0x3c, 0x7e, 0xff, 0xff, 0xdb, 0xdb, 0xff, 0xff, 0xdb, 0xe7, 0xff, 0x7e, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xdb, 0xff, 0xff, 0xdb, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0xff, 0x66, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0x84, 0x84, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x1e, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x18, 0x1c, 0x1e, 0x16, 0x12, 0x10, 0x10, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x38, 0x2c, 0x26, 0x32, 0x3a, 0x2e, 0x26, 0x22, 0x62, 0xe2, 0xc6, 0x0e, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, - 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e, 0xfe, 0x7e, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, 0x30, 0xfc, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0x78, 0x78, 0x78, 0x30, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x0c, 0x0c, 0x18, 0x38, 0x30, 0x60, 0x60, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x30, 0x76, 0xde, 0xcc, 0xcc, 0xde, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x30, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0xfe, 0x38, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x38, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x04, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xde, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xee, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xe6, 0xe6, 0xf6, 0xde, 0xce, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xf6, 0xda, 0x6c, 0x06, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0xd8, 0xcc, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0x60, 0x60, 0x30, 0x38, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xe6, 0xdc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x06, 0x06, 0x76, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xce, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0xf0, 0xf0, 0xd8, 0xcc, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xe6, 0xdc, 0xc0, 0xc0, 0xc0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xce, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0x06, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0x70, 0x1c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x30, 0xfe, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x30, 0x30, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0x30, 0x30, 0x30, 0x30, 0x1c, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x18, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x38, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x00, 0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x36, 0x36, 0x76, 0xde, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x3c, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, - 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x30, 0x30, 0x78, 0xcc, 0xc0, 0xc0, 0xcc, 0x78, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x60, 0x60, 0x60, 0xf8, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x76, 0xdc, 0x00, 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x78, 0xd8, 0xd8, 0x6c, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc2, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc2, 0xc6, 0xcc, 0xd8, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x30, 0x78, 0x78, 0x78, 0x78, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0xf6, 0x06, 0x06, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x06, 0x06, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0xf6, 0x06, 0x06, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x30, 0x30, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x30, 0x30, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0xf7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x30, 0x30, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0xf7, 0x00, 0x00, 0xf7, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xd6, 0xdc, 0xc8, 0xc8, 0xdc, 0xd6, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xd8, 0xc0, 0xc0, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xfe, 0x24, 0x24, 0x24, 0x24, 0x66, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xfe, 0xc2, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc2, 0xfe, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x76, 0x6c, 0x60, 0xc0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xfc, 0x98, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x30, 0x30, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0x60, 0x30, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xbb, 0x99, 0x99, 0xdd, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x06, 0x3c, 0x6c, 0xce, 0xd6, 0xd6, 0xe6, 0x6c, 0x78, 0xc0, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x30, 0x60, 0xc0, 0xc0, 0xfe, 0xc0, 0xc0, 0x60, 0x30, 0x1e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x36, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c, 0x00, 0x00, - 0x00, 0xd8, 0xec, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x0c, 0x18, 0x30, 0x60, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + // Расширяем до 8 бит + r_dst = (r_dst << (8 - r_len)) | (r_dst >> (2 * r_len - 8)); + g_dst = (g_dst << (8 - g_len)) | (g_dst >> (2 * g_len - 8)); + b_dst = (b_dst << (8 - b_len)) | (b_dst >> (2 * b_len - 8)); + + // Блендинг с фиксированной точкой + uint8_t r = (uint8_t)((r_src * alpha_fixed + r_dst * (256 - alpha_fixed)) >> 8); + uint8_t g = (uint8_t)((g_src * alpha_fixed + g_dst * (256 - alpha_fixed)) >> 8); + uint8_t b = (uint8_t)((b_src * alpha_fixed + b_dst * (256 - alpha_fixed)) >> 8); + + uint32_t pixel = 0; + pixel |= ((r >> (8 - r_len)) << r_off); + pixel |= ((g >> (8 - g_len)) << g_off); + pixel |= ((b >> (8 - b_len)) << b_off); + + return pixel; +} + +static void draw_transparent_black_square(uint32_t* canvas, int width, int height, + int r_len, int r_off, + int g_len, int g_off, + int b_len, int b_off, + int margin) { + int square_w = width - 2 * margin; + int square_h = height - 2 * margin; + int start_x = margin; + int start_y = margin; + + int alpha_fixed = 128; + + for (int y = start_y; y < start_y + square_h; y++) { + for (int x = start_x; x < start_x + square_w; x++) { + int idx = y * width + x; + canvas[idx] = blend_pixel(canvas[idx], 0, 0, 0, alpha_fixed, + r_len, r_off, g_len, g_off, b_len, b_off); + } + } +} + +#pragma pack(push, 1) +struct BMPHeader { + uint16_t signature; + uint32_t file_size; + uint32_t reserved; + uint32_t data_offset; + uint32_t header_size; + int32_t width; + int32_t height; + uint16_t planes; + uint16_t bpp; + uint32_t compression; + uint32_t image_size; + int32_t x_pixels_per_meter; + int32_t y_pixels_per_meter; + uint32_t colors_used; + uint32_t important_colors; +}; +#pragma pack(pop) + +static const unsigned char bg_bmp[] = { + #embed "src/bg.bmp" }; +static unsigned char* load_bmp_from_memory(const unsigned char* bmp_data, size_t bmp_size, + int* width, int* height, int* channels) { + if (bmp_size < sizeof(BMPHeader)) { + return nullptr; + } + + BMPHeader* header = (BMPHeader*)bmp_data; + + if (header->signature != 0x4D42) { // 'BM' + return nullptr; + } + + if (header->bpp != 24 || header->compression != 0) { + return nullptr; + } + + *width = abs(header->width); + *height = abs(header->height); + *channels = 3; + + unsigned char* rgb_data = (unsigned char*)(pmm::buddy::alloc((*width) * (*height) * 3).phys + etc::hhdm()); + if (!rgb_data) { + return nullptr; + } + + int row_size = ((*width) * 3 + 3) & ~3; + unsigned char* bmp_pixels = (unsigned char*)(bmp_data + header->data_offset); + + for (int y = 0; y < *height; y++) { + int src_y; + if (header->height > 0) { + + src_y = (*height - 1 - y); + } else { + + src_y = y; + } + + unsigned char* src_row = bmp_pixels + src_y * row_size; + unsigned char* dst_row = rgb_data + y * (*width) * 3; + + for (int x = 0; x < *width; x++) { + dst_row[x*3 + 0] = src_row[x*3 + 2]; // R + dst_row[x*3 + 1] = src_row[x*3 + 1]; // G + dst_row[x*3 + 2] = src_row[x*3 + 0]; // B + } + } + + return rgb_data; +} unsigned char unifont_arr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x81, 0xa5, @@ -607,3 +523,116 @@ unsigned char unifont_arr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +#define FONT_WIDTH 8 +#define FONT_HEIGHT 16 + +namespace utils { + + void flanterm::init() { + limine_framebuffer* fb0 = bootloader::bootloader->get_framebuffer(); + + if(fb0 == nullptr) { + is_disabled_flanterm = 1; + return; + } + + struct flanterm_context *ft_ctx = flanterm_fb_init( + NULL, + NULL, + (uint32_t*)fb0->address, fb0->width, fb0->height, fb0->pitch, + fb0->red_mask_size, fb0->red_mask_shift, + fb0->green_mask_size, fb0->green_mask_shift, + fb0->blue_mask_size, fb0->blue_mask_shift, + NULL, + NULL, NULL, + &default_bg, &default_fg, + NULL, &default_bright_fg, + (void*)NULL, 0, 0, 0, + 1, 1, 0, 0 + ); + ft_ctx0 = ft_ctx; + const char* msg = "flanterm: Found usable framebuffer\r\n"; + flanterm::write(msg,klibc::strlen(msg)); + } + + void flanterm::fullinit() { + + limine_framebuffer* fb0 = bootloader::bootloader->get_framebuffer(); + + if(fb0 == nullptr) { + is_disabled_flanterm = 1; + return; + } + + + uint32_t* test_canvas = (uint32_t*)(pmm::buddy::alloc(fb0->pitch * fb0->height).phys + etc::hhdm()); + if (!test_canvas) { + return; + } + + int img_w, img_h, img_channels; + unsigned char* img_data = load_bmp_from_memory(bg_bmp, sizeof(bg_bmp), &img_w, &img_h, &img_channels); + if (!img_data) { + klibc::printf("error in stbi\n\r"); + return; + } + + unsigned char* scaled_rgb = (unsigned char*)(pmm::buddy::alloc(fb0->pitch * fb0->height * 3).phys + etc::hhdm()); + if (!scaled_rgb) { + return; + } + + scale_image_nn(img_data, img_w, img_h, scaled_rgb, fb0->width, fb0->height, 3); + + for (std::size_t y = 0; y < fb0->height; y++) { + for (std::size_t x = 0; x < fb0->width; x++) { + int idx = (y * fb0->width + x) * 3; + uint8_t r = scaled_rgb[idx]; + uint8_t g = scaled_rgb[idx + 1]; + uint8_t b = scaled_rgb[idx + 2]; + test_canvas[y * fb0->width + x] = rgb_to_pixel(r, g, b, + fb0->red_mask_size, fb0->red_mask_shift, + fb0->green_mask_size, fb0->green_mask_shift, + fb0->blue_mask_size, fb0->blue_mask_shift); + } + } + + int margin = 64; + + draw_transparent_black_square(test_canvas, fb0->width, fb0->height, + fb0->red_mask_size, fb0->red_mask_shift, + fb0->green_mask_size, fb0->green_mask_shift, + fb0->blue_mask_size, fb0->blue_mask_shift, + margin - 1); + + flanterm_deinit(ft_ctx0, nullptr); + + ft_ctx0 = flanterm_fb_init( + __flanterm_malloc, __flanterm_free, + (uint32_t*)fb0->address, fb0->width, fb0->height, fb0->pitch, + fb0->red_mask_size, fb0->red_mask_shift, + fb0->green_mask_size, fb0->green_mask_shift, + fb0->blue_mask_size, fb0->blue_mask_shift, + test_canvas, + NULL, NULL, + NULL, &default_fg, + NULL, &default_bright_fg, + (void*)unifont_arr, FONT_WIDTH, FONT_HEIGHT, 0, + 1, 1, margin,0 + ); + + } + + void flanterm::write(const char* buffer, std::size_t size) { + if(is_disabled_flanterm) + return; + for(std::size_t i = 0; i < size; i++) { + if(buffer[i] == '\n') { + flanterm_write(ft_ctx0,"\r",1); + } + flanterm_write(ft_ctx0,&buffer[i],1); + } + } + +};
\ No newline at end of file diff --git a/kernel/src/utils/flanterm.hpp b/kernel/src/utils/flanterm.hpp new file mode 100644 index 0000000..9f30b9d --- /dev/null +++ b/kernel/src/utils/flanterm.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include <cstdint> + +namespace utils { + namespace flanterm { + void init(); + void fullinit(); + void write(const char* buffer, std::size_t size); + }; +};
\ No newline at end of file diff --git a/kernel/src/utils/gobject.hpp b/kernel/src/utils/gobject.hpp new file mode 100644 index 0000000..18bbc57 --- /dev/null +++ b/kernel/src/utils/gobject.hpp @@ -0,0 +1,6 @@ +#pragma once +#include <cstdint> + +namespace gobject { + inline std::uintptr_t kernel_root = 0; +};
\ No newline at end of file diff --git a/kernel/src/utils/hash/hash.hpp b/kernel/src/utils/hash/hash.hpp new file mode 100644 index 0000000..340e3f0 --- /dev/null +++ b/kernel/src/utils/hash/hash.hpp @@ -0,0 +1,8 @@ + +#include <cstdint> + +namespace utils { + namespace hash { + + }; +};
\ No newline at end of file diff --git a/limine.conf b/limine.conf new file mode 100644 index 0000000..0093fad --- /dev/null +++ b/limine.conf @@ -0,0 +1,10 @@ +# Timeout in seconds that Limine will use before automatically booting. +timeout: 3 + +# The entry name that will be displayed in the boot menu. +/Limine Template + # We use the Limine boot protocol. + protocol: limine + + # Path to the kernel to boot. boot():/ represents the partition on which limine.conf is located. + path: boot():/boot/kernel @@ -1,6 +1,6 @@ # Orange -Orange is my x86_64 os with linux binary compat +Orange is my posix x86_64 os with microkernel features [](https://github.com/cpplover0/orange/blob/main/kernel/GNUmakefile) [](https://github.com/cpplover0/orange/blob/master/LICENSE) @@ -8,61 +8,7 @@ Orange is my x86_64 os with linux binary compat [](https://github.com/cpplover0/orange/graphs/contributors) [](https://github.com/cpplover0/orange/commits) -## Preview - - -## Devices which supported by orange - -- [x] hpet -- [x] pvclock -- [x] ioapic -- [x] ps/2 -- [x] ps/2 keyboard -- [x] ps/2 mouse -- [x] xhci -- [x] usb keyboard -- [x] usb mouse - -# Build - -Build kernel +for build do ```sh -make all -``` - -To build initrd create folder initrd, debootstrap to it, install packages which you want and do -```sh -sudo sh refresh-initrd.sh -``` - -Build kernel and run iso -```sh -make run -``` - -Dependencies -``` -cmake meson (1.4.2) ninja gcc (13.3.0) libgmp3-dev libmpfr-dev libmpc-dev libglib2.0-dev-bin python3.13 python3.13-dev python3.13-venv python3.13-distutils gettext gperf rsync flex bison make nasm bash xsltproc docbook-xsl itstool zenity intltool -``` - -Host python dependencies -``` -mako pyyaml -``` - -Also if you have custom python version you need to pass environment variable because python requires newest version -``` -BUILDPYTHON=--with-build-python=python3.13 sh tar-initrd.sh -``` - -## TODO - -- [x] Move XHCI driver from old kernel to userspace -- [x] Implement IRQ userspace handling -- [x] Port lua, fastfetch, doomgeneric, nano and etc. -- [x] Improve XHCI driver -- [x] Port Xorg -- [ ] Port twm -- [ ] Port wine -- [ ] Implement userspace disk drivers -- [x] Improve kernel path resolver (add symlink support when trying to access another filesystem)
\ No newline at end of file +make run -j$(nproc) ARCH=$ARCH TOOLCHAIN=llvm +```
\ No newline at end of file diff --git a/refresh-initrd.sh b/refresh-initrd.sh deleted file mode 100644 index 6023736..0000000 --- a/refresh-initrd.sh +++ /dev/null @@ -1,9 +0,0 @@ - -echo '' - -chmod +x initrd/etc/ - -mkdir -p tools/base/boot - -cp -rf tools/fastfetch initrd/root -tar -cf tools/base/boot/initrd.tar -C initrd . diff --git a/strip-all.sh b/strip-all.sh deleted file mode 100644 index f346827..0000000 --- a/strip-all.sh +++ /dev/null @@ -1,15 +0,0 @@ - -export LIBTOOL="$HOME/opt/cross/orange/bin/libtool" -export LIBTOOLIZE="$HOME/opt/cross/orange/bin/libtoolize" -export PATH="$HOME/opt/cross/orange/bin:$PATH" - -sysroot_path="$(realpath initrd)" - -export CFLAGS="-fPIC -Wno-error -O2 -Wno-incompatible-pointer-types" -export PKG_CONFIG_SYSROOT_DIR="$sysroot_path" -export PKG_CONFIG_PATH="$sysroot_path/usr/lib/pkgconfig:$sysroot_path/usr/share/pkgconfig:$sysroot_path/usr/local/lib/pkgconfig:$sysroot_path/usr/local/share/pkgconfig:$HOME/opt/cross/orange/lib/pkgconfig:$HOME/opt/cross/orange/share/pkgconfig" - -strip --strip-debug initrd/usr/lib/* -strip --strip-unneeded initrd/usr/bin/* -rm -rf initrd/usr/{,share}/{info,man,doc} -find initrd/usr/{lib,libexec} -name \*.la -delete diff --git a/tar-initrd.sh b/tar-initrd.sh deleted file mode 100755 index 3d4006b..0000000 --- a/tar-initrd.sh +++ /dev/null @@ -1,31 +0,0 @@ - -sudo rm -rf initrd - -export LIBTOOL="$HOME/opt/cross/orange/bin/libtool" -export LIBTOOLIZE="$HOME/opt/cross/orange/bin/libtoolize" -export PATH="$HOME/opt/cross/orange/bin:$PATH" - -sysroot_path="$(realpath initrd)" - -export CFLAGS="-fPIC -Wno-error -O2 -Wno-incompatible-pointer-types -Wno-implicit-function-declaration" -export PKG_CONFIG_SYSROOT_DIR="$sysroot_path" -export PKG_CONFIG_PATH="$sysroot_path/usr/lib/pkgconfig:$sysroot_path/usr/share/pkgconfig:$sysroot_path/usr/local/lib/pkgconfig:$sysroot_path/usr/local/share/pkgconfig:$HOME/opt/cross/orange/lib/pkgconfig:$HOME/opt/cross/orange/share/pkgconfig" - -cd tools/pkg -bash build-pkg.sh "$(realpath ../../initrd)" -cd ../.. - -cd initrd - -rm -rf lib lib64 bin - -ln -sf usr/lib lib -ln -sf usr/lib lib64 -ln -sf usr/bin bin - -cd ../ - -cp -rf tools/initbase/* initrd - -mkdir -p tools/base/boot -tar -cf tools/base/boot/initrd.tar -C initrd . diff --git a/tools/base/boot/bg.jpg b/tools/base/boot/bg.jpg Binary files differdeleted file mode 100644 index 6080197..0000000 --- a/tools/base/boot/bg.jpg +++ /dev/null diff --git a/tools/base/etc/passwd b/tools/base/etc/passwd deleted file mode 100644 index 0cabc85..0000000 --- a/tools/base/etc/passwd +++ /dev/null @@ -1 +0,0 @@ -root:x:0:0::/root:/bin/bash
\ No newline at end of file diff --git a/tools/base/etc/shells b/tools/base/etc/shells deleted file mode 100644 index 5d4150d..0000000 --- a/tools/base/etc/shells +++ /dev/null @@ -1 +0,0 @@ -/bin/bash
\ No newline at end of file diff --git a/tools/base/readme b/tools/base/readme deleted file mode 100644 index 32f95c0..0000000 --- a/tools/base/readme +++ /dev/null @@ -1 +0,0 @@ -hi
\ No newline at end of file diff --git a/tools/base/root/.bash_history b/tools/base/root/.bash_history deleted file mode 100644 index ae3bc0a..0000000 --- a/tools/base/root/.bash_history +++ /dev/null @@ -1 +0,0 @@ -exit
\ No newline at end of file diff --git a/tools/base/root/.bashrc b/tools/base/root/.bashrc deleted file mode 100644 index b221318..0000000 --- a/tools/base/root/.bashrc +++ /dev/null @@ -1,7 +0,0 @@ -PS1='\e[92m\u\e[0m@\e[38;5;214morange\e[0m-# ' -export TERM="linux" -export SHELL="/bin/bash" -export PATH="/usr/bin" - -# gcc defaults to /usr/local/include so i'll set include to /usr -export C_INCLUDE_PATH="/usr/include" diff --git a/tools/diffs/binutils.diff b/tools/diffs/binutils.diff deleted file mode 100644 index 0150e35..0000000 --- a/tools/diffs/binutils.diff +++ /dev/null @@ -1,97 +0,0 @@ -diff -Naur binutils-2.38/bfd/config.bfd binutils-patched/bfd/config.bfd ---- binutils-2.38/bfd/config.bfd 2022-01-22 15:14:07.000000000 +0300 -+++ binutils-patched/bfd/config.bfd 2025-05-20 13:53:59.007878617 +0300 -@@ -656,11 +656,21 @@ - targ_selvecs= - targ64_selvecs=x86_64_elf64_vec - ;; -+ i[3-7]86-*-orange*) -+ targ_defvec=i386_elf32_vec -+ targ_selvecs= -+ targ64_selvecs=x86_64_elf64_vec -+ ;; - #ifdef BFD64 - x86_64-*-cloudabi*) - targ_defvec=x86_64_elf64_cloudabi_vec - want64=true - ;; -+ x86_64-*-orange*) -+ targ_defvec=x86_64_elf64_vec -+ targ_selvecs=i386_elf32_vec -+ want64=true -+ ;; - x86_64-*-darwin*) - targ_defvec=x86_64_mach_o_vec - targ_selvecs="i386_mach_o_vec mach_o_le_vec mach_o_be_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec" -diff -Naur binutils-2.38/config.sub binutils-patched/config.sub ---- binutils-2.38/config.sub 2022-01-22 15:14:07.000000000 +0300 -+++ binutils-patched/config.sub 2025-05-20 13:51:16.721951465 +0300 -@@ -1750,7 +1750,7 @@ - | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ - | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ - | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ -- | skyos* | haiku* | rdos* | toppers* | drops* | es* \ -+ | skyos* | orange* | haiku* | rdos* | toppers* | drops* | es* \ - | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ - | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ - | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ -diff -Naur binutils-2.38/gas/configure.tgt binutils-patched/gas/configure.tgt ---- binutils-2.38/gas/configure.tgt 2022-01-22 15:14:08.000000000 +0300 -+++ binutils-patched/gas/configure.tgt 2025-05-20 13:55:11.117623594 +0300 -@@ -233,6 +233,7 @@ - i386-*-knetbsd*-gnu | \ - i386-*-netbsd* | \ - i386-*-openbsd*) fmt=elf em=nbsd ;; -+ i386-*-orange*) fmt=elf em=gnu ;; - i386-*-linux-*) fmt=elf em=linux - case ${cpu}-${os} in - x86_64*-linux-gnux32) arch=x86_64:32 ;; -diff -Naur binutils-2.38/ld/configure.tgt binutils-patched/ld/configure.tgt ---- binutils-2.38/ld/configure.tgt 2022-01-22 17:19:36.000000000 +0300 -+++ binutils-patched/ld/configure.tgt 2025-05-20 13:58:35.200562165 +0300 -@@ -403,6 +403,15 @@ - ;; - i[3-7]86-*-haiku*) targ_emul=elf_i386_haiku - ;; -+i[3-7]86-*-orange*) -+ targ_emul=elf_i386_orange -+ targ_extra_emuls=elf_i386 -+ targ64_extra_emuls="elf_x86_64_orange elf_x86_64" -+ ;; -+x86_64-*-orange*) -+ targ_emul=elf_x86_64_orange -+ targ_extra_emuls="elf_i386_orange elf_x86_64 elf_i386" -+ ;; - i[3-7]86-*-vxworks*) targ_emul=elf_i386_vxworks - ;; - i[3-7]86-*-chaos) targ_emul=elf_i386_chaos -diff -Naur binutils-2.38/ld/emulparams/elf_i386_orange.sh binutils-patched/ld/emulparams/elf_i386_orange.sh ---- binutils-2.38/ld/emulparams/elf_i386_orange.sh 1970-01-01 03:00:00.000000000 +0300 -+++ binutils-patched/ld/emulparams/elf_i386_orange.sh 2025-05-20 13:58:57.848110210 +0300 -@@ -0,0 +1,2 @@ -+source_sh ${srcdir}/emulparams/elf_i386.sh -+TEXT_START_ADDR=0x08000000 -diff -Naur binutils-2.38/ld/emulparams/elf_x86_64_orange.sh binutils-patched/ld/emulparams/elf_x86_64_orange.sh ---- binutils-2.38/ld/emulparams/elf_x86_64_orange.sh 1970-01-01 03:00:00.000000000 +0300 -+++ binutils-patched/ld/emulparams/elf_x86_64_orange.sh 2025-05-20 13:59:14.619516061 +0300 -@@ -0,0 +1 @@ -+source_sh ${srcdir}/emulparams/elf_x86_64.sh -diff -Naur binutils-2.38/ld/Makefile.am binutils-patched/ld/Makefile.am ---- binutils-2.38/ld/Makefile.am 2022-01-22 15:14:09.000000000 +0300 -+++ binutils-patched/ld/Makefile.am 2025-05-20 14:00:18.033050595 +0300 -@@ -281,6 +281,7 @@ - eelf_i386_be.c \ - eelf_i386_fbsd.c \ - eelf_i386_haiku.c \ -+ eelf_i386_orange.c \ - eelf_i386_ldso.c \ - eelf_i386_sol2.c \ - eelf_i386_vxworks.c \ -@@ -463,6 +464,7 @@ - eelf_x86_64_cloudabi.c \ - eelf_x86_64_fbsd.c \ - eelf_x86_64_haiku.c \ -+ eelf_x86_64_orange.c \ - eelf_x86_64_sol2.c \ - ehppa64linux.c \ - ei386pep.c \ diff --git a/tools/diffs/gcc.diff b/tools/diffs/gcc.diff deleted file mode 100644 index df4c770..0000000 --- a/tools/diffs/gcc.diff +++ /dev/null @@ -1,201 +0,0 @@ -diff -Naur gcc-15.1.0/fixincludes/mkfixinc.sh gcc-patched/fixincludes/mkfixinc.sh ---- gcc-15.1.0/fixincludes/mkfixinc.sh 2025-04-25 11:17:59.000000000 +0300 -+++ gcc-patched/fixincludes/mkfixinc.sh 2025-07-26 08:31:28.520072553 +0300 -@@ -13,6 +13,8 @@ - case $machine in - i?86-*-cygwin* | \ - *-mingw32* | \ -+ *-*-mlibc* | \ -+ *-mlibc* | \ - powerpc-*-eabisim* | \ - powerpc-*-eabi* | \ - powerpc-*-rtems* | \ -diff -Naur gcc-15.1.0/gcc/config/gnu-user.h gcc-patched/gcc/config/gnu-user.h ---- gcc-15.1.0/gcc/config/gnu-user.h 2025-04-25 11:18:00.000000000 +0300 -+++ gcc-patched/gcc/config/gnu-user.h 2025-07-26 09:09:48.204916096 +0300 -@@ -51,13 +51,12 @@ - #define GNU_USER_TARGET_STARTFILE_SPEC \ - "%{shared:; \ - pg|p|profile:%{static-pie:grcrt1.o%s;:gcrt1.o%s}; \ -- static:crt1.o%s; \ -- static-pie:rcrt1.o%s; \ -+ static|static-pie:%{" PIE_SPEC ":rcrt1.o%s;:crt1.o%s}; \ - " PIE_SPEC ":Scrt1.o%s; \ - :crt1.o%s} " \ - GNU_USER_TARGET_CRTI " \ -- %{static:crtbeginT.o%s; \ -- shared|static-pie|" PIE_SPEC ":crtbeginS.o%s; \ -+ %{shared|" PIE_SPEC ":crtbeginS.o%s; \ -+ static:crtbeginT.o%s; \ - :crtbegin.o%s} \ - %{fvtable-verify=none:%s; \ - fvtable-verify=preinit:vtv_start_preinit.o%s; \ -@@ -73,11 +72,11 @@ - GNU userspace "finalizer" file, `crtn.o'. */ - - #define GNU_USER_TARGET_ENDFILE_SPEC \ -- "%{!static:%{fvtable-verify=none:%s; \ -+ "%{static|static-pie:; \ -+ fvtable-verify=none:%s; \ - fvtable-verify=preinit:vtv_end_preinit.o%s; \ - fvtable-verify=std:vtv_end.o%s}} \ -- %{static:crtend.o%s; \ -- shared|static-pie|" PIE_SPEC ":crtendS.o%s; \ -+ %{shared|" PIE_SPEC ":crtendS.o%s; \ - :crtend.o%s} " \ - GNU_USER_TARGET_CRTN " " \ - CRTOFFLOADEND -@@ -106,7 +105,7 @@ - #define LIB_SPEC GNU_USER_TARGET_LIB_SPEC - - #if defined(HAVE_LD_EH_FRAME_HDR) --#define LINK_EH_SPEC "%{!static|static-pie:--eh-frame-hdr} " -+#define LINK_EH_SPEC "%{!static|" PIE_SPEC ":--eh-frame-hdr} " - #endif - - #define GNU_USER_TARGET_LINK_GCC_C_SEQUENCE_SPEC \ -diff -Naur gcc-15.1.0/gcc/config/orange.h gcc-patched/gcc/config/orange.h ---- gcc-15.1.0/gcc/config/orange.h 1970-01-01 03:00:00.000000000 +0300 -+++ gcc-patched/gcc/config/orange.h 2025-07-26 08:30:27.666446812 +0300 -@@ -0,0 +1,31 @@ -+/* Useful if you wish to make target-specific GCC changes. */ -+#undef TARGET_ORANGE -+#define TARGET_ORANGE 1 -+ -+#undef LINK_SPEC -+#define LINK_SPEC "%{shared:-shared} %{static:-static} %{!shared: %{!static: %{rdynamic:-export-dynamic}}}" -+ -+/* Default arguments you want when running your -+ i686-myos-gcc/x86_64-myos-gcc toolchain */ -+#undef LIB_SPEC -+#define LIB_SPEC "-lc" /* link against C standard library */ -+ -+/* Files that are linked before user code. -+ The %s tells GCC to look for these files in the library directory. */ -+#undef STARTFILE_SPEC -+#define STARTFILE_SPEC "%{!shared:crt0.o%s} crti.o%s %{shared|static-pie|pie|!no-pie:crtbeginS.o%s;:crtbegin.o%s}" -+ -+/* Files that are linked after user code. */ -+#undef ENDFILE_SPEC -+#define ENDFILE_SPEC "%{shared|static-pie|pie|!no-pie:crtendS.o%s;:crtend.o%s} crtn.o%s" -+ -+/* Additional predefined macros. */ -+#undef TARGET_OS_CPP_BUILTINS -+#define TARGET_OS_CPP_BUILTINS() \ -+ do { \ -+ builtin_define ("__orange__"); builtin_define ("__mlibc__"); \ -+ builtin_define ("__unix__"); \ -+ builtin_assert ("system=orange"); \ -+ builtin_assert ("system=unix"); \ -+ builtin_assert ("system=posix"); \ -+ } while(0); -diff -Naur gcc-15.1.0/gcc/config/sh/sh.cc gcc-patched/gcc/config/sh/sh.cc ---- gcc-15.1.0/gcc/config/sh/sh.cc 2025-04-25 11:18:00.000000000 +0300 -+++ gcc-patched/gcc/config/sh/sh.cc 2025-07-26 09:12:46.043423847 +0300 -@@ -9154,7 +9154,7 @@ - { - /* Weak functions may be NULL which doesn't work with - GOTOFFFUNCDESC because the runtime offset is not known. */ -- if (SYMBOL_REF_WEAK (orig)) -+ if (SYMBOL_REF_WEAK (orig) || (TREE_PUBLIC(SYMBOL_REF_DECL(orig)) && DECL_VISIBILITY (SYMBOL_REF_DECL(orig)) != VISIBILITY_HIDDEN)) - emit_insn (gen_symGOTFUNCDESC2reg (reg, orig)); - else - emit_insn (gen_symGOTOFFFUNCDESC2reg (reg, orig)); -diff -Naur gcc-15.1.0/gcc/config.gcc gcc-patched/gcc/config.gcc ---- gcc-15.1.0/gcc/config.gcc 2025-04-25 11:18:00.000000000 +0300 -+++ gcc-patched/gcc/config.gcc 2025-07-26 08:28:59.040282804 +0300 -@@ -993,6 +993,13 @@ - rust_target_objs="${rust_target_objs} netbsd-rust.o" - target_has_targetrustm=yes - ;; -+*-*-*-mlibc) -+ extra_options="$extra_options gnu-user.opt" -+ gas=yes -+ gnu_ld=yes -+ default_use_cxa_atexit=yes -+ use_gcc_stdint=provide -+ ;; - *-*-openbsd*) - tmake_file="t-openbsd" - case ${enable_threads} in -@@ -1700,6 +1707,12 @@ - extra_options="${extra_options} cris/elf.opt" - use_gcc_stdint=wrap - ;; -+i[34567]86-*-orange*) -+ tm_file="${tm_file} i386/unix.h i386/att.h elfos.h glibc-stdint.h i386/i386elf.h orange.h" -+ ;; -+x86_64-*-orange*) -+ tm_file="${tm_file} i386/unix.h i386/att.h elfos.h glibc-stdint.h i386/i386elf.h i386/x86-64.h orange.h" -+ ;; - csky-*-*) - if test x${with_endian} != x; then - case ${with_endian} in -diff -Naur gcc-15.1.0/gcc/gcc.cc gcc-patched/gcc/gcc.cc ---- gcc-15.1.0/gcc/gcc.cc 2025-04-25 11:18:00.000000000 +0300 -+++ gcc-patched/gcc/gcc.cc 2025-07-26 09:12:09.498633227 +0300 -@@ -1023,7 +1023,7 @@ - #define NO_FPIE_AND_FPIC_SPEC NO_FPIE_SPEC "|" NO_FPIC_SPEC - #define FPIE_OR_FPIC_SPEC NO_FPIE_AND_FPIC_SPEC ":;" - #else --#define PIE_SPEC "pie" -+#define PIE_SPEC "pie|static-pie" - #define FPIE1_SPEC "fpie" - #define NO_FPIE1_SPEC FPIE1_SPEC ":;" - #define FPIE2_SPEC "fPIE" -@@ -1047,12 +1047,12 @@ - #ifndef LINK_PIE_SPEC - #ifdef HAVE_LD_PIE - #ifndef LD_PIE_SPEC --#define LD_PIE_SPEC "-pie" -+#define LD_PIE_SPEC "-pie %{static|static-pie:--no-dynamic-linker -z text -Bsymbolic}" - #endif - #else - #define LD_PIE_SPEC "" - #endif --#define LINK_PIE_SPEC "%{static|shared|r:;" PIE_SPEC ":" LD_PIE_SPEC "} " -+#define LINK_PIE_SPEC "%{shared|r:;" PIE_SPEC ":" LD_PIE_SPEC "} " - #endif - - #ifndef LINK_BUILDID_SPEC -diff -Naur gcc-15.1.0/libgcc/config.host gcc-patched/libgcc/config.host ---- gcc-15.1.0/libgcc/config.host 2025-04-25 11:18:04.000000000 +0300 -+++ gcc-patched/libgcc/config.host 2025-07-26 09:16:11.367660694 +0300 -@@ -750,6 +750,14 @@ - extra_parts="$extra_parts crtfastmath.o libheapt_w.a" - tmake_file="${tmake_file} i386/t-heap-trampoline" - ;; -+*-*-*-mlibc) -+ extra_parts="$extra_parts crti.o crtbegin.o crtend.o crtn.o crtbeginS.o crtendS.o" -+ tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic" -+ ;; -+x86_64-*-*-mlibc) -+ extra_parts="$extra_parts crti.o crtbegin.o crtend.o crtn.o crtbeginS.o crtendS.o" -+ tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic" -+ ;; - i[34567]86-*-elfiamcu) - tmake_file="$tmake_file i386/t-crtstuff t-softfp-sfdftf i386/32/t-softfp i386/32/t-iamcu i386/t-softfp t-softfp t-dfprules" - ;; -diff -Naur gcc-15.1.0/libstdc++-v3/crossconfig.m4 gcc-patched/libstdc++-v3/crossconfig.m4 ---- gcc-15.1.0/libstdc++-v3/crossconfig.m4 2025-04-25 11:18:05.000000000 +0300 -+++ gcc-patched/libstdc++-v3/crossconfig.m4 2025-07-26 09:14:05.187145188 +0300 -@@ -257,12 +257,19 @@ - AC_DEFINE(HAVE_ISNANL) - fi - ;; -+ - *-*vms*) - # Check for available headers. - # Don't call GLIBCXX_CHECK_LINKER_FEATURES, VMS doesn't have a GNU ld - GLIBCXX_CHECK_MATH_SUPPORT - GLIBCXX_CHECK_STDLIB_SUPPORT - ;; -+ *-mlibc*) -+ GLIBCXX_CHECK_COMPILER_FEATURES -+ GLIBCXX_CHECK_LINKER_FEATURES -+ GLIBCXX_CHECK_MATH_SUPPORT -+ GLIBCXX_CHECK_STDLIB_SUPPORT -+ ;; - *-vxworks*) - AC_DEFINE(HAVE_ACOSF) - AC_DEFINE(HAVE_ASINF)
\ No newline at end of file diff --git a/tools/diffs/gccn.diff b/tools/diffs/gccn.diff deleted file mode 100644 index 67de60d..0000000 --- a/tools/diffs/gccn.diff +++ /dev/null @@ -1,286 +0,0 @@ -diff --git gcc-host-clean/fixincludes/mkfixinc.sh gcc-host-workdir/fixincludes/mkfixinc.sh -index 7112f4d..7aadf83 100755 ---- gcc-host-clean/fixincludes/mkfixinc.sh -+++ gcc-host-workdir/fixincludes/mkfixinc.sh -@@ -12,6 +12,7 @@ target=fixinc.sh - # Check for special fix rules for particular targets - case $machine in - i?86-*-cygwin* | \ -+ *-mlibc* | \ - *-mingw32* | \ - powerpc-*-eabisim* | \ - powerpc-*-eabi* | \ -diff --git gcc-host-workdir/gcc/config/i386/orange.h gcc-host-workdir/gcc/config/i386/orange.h -new file mode 100644 -index 0000000..e3017a9 ---- /dev/null -+++ gcc-host-workdir/gcc/config/i386/orange.h -@@ -0,0 +1,30 @@ -+#undef TARGET_ORANGE -+#define TARGET_ORANGE 1 -+ -+#undef LIB_SPEC -+#define LIB_SPEC "-lc" -+ -+#undef STARTFILE_SPEC -+#define STARTFILE_SPEC "%{!shared: %{static-pie|pie|!no-pie:Scrt1.o%s;:crt1.o%s}} crti.o%s %{shared|static-pie|pie|!no-pie:crtbeginS.o%s;:crtbegin.o%s}" -+ -+#undef ENDFILE_SPEC -+#define ENDFILE_SPEC "%{shared|static-pie|pie|!no-pie:crtendS.o%s;:crtend.o%s} crtn.o%s" -+ -+#define GNU_USER_LINK_EMULATION32 "elf_i386" -+#define GNU_USER_LINK_EMULATION64 "elf_x86_64" -+#define GNU_USER_LINK_EMULATIONX32 "elf32_x86_64" -+ -+#define GNU_USER_DYNAMIC_LINKER32 "/does_not_exist" -+#define GNU_USER_DYNAMIC_LINKER64 "/usr/lib/ld.so" -+#define GNU_USER_DYNAMIC_LINKERX32 "/does_not_exist" -+ -+#undef TARGET_OS_CPP_BUILTINS -+#define TARGET_OS_CPP_BUILTINS() \ -+ do { \ -+ builtin_define ("__orange__"); \ -+ builtin_define ("__mlibc__"); \ -+ builtin_define ("__unix__"); \ -+ builtin_assert ("system=orange"); \ -+ builtin_assert ("system=unix"); \ -+ builtin_assert ("system=posix"); \ -+ } while (0); -diff --git gcc-host-workdir/gcc/config/riscv/orange.h gcc-host-workdir/gcc/config/riscv/orange.h -new file mode 100644 -index 0000000..5fd4f00 ---- /dev/null -+++ gcc-host-workdir/gcc/config/riscv/orange.h -@@ -0,0 +1,46 @@ -+#undef TARGET_ORANGE -+#define TARGET_ORANGE 1 -+ -+#undef LIB_SPEC -+#define LIB_SPEC "-lc" -+ -+#define LD_EMUL_SUFFIX \ -+ "%{mabi=lp64d:}" \ -+ "%{mabi=lp64f:_lp64f}" \ -+ "%{mabi=lp64:_lp64}" \ -+ "%{mabi=ilp32d:}" \ -+ "%{mabi=ilp32f:_ilp32f}" \ -+ "%{mabi=ilp32:_ilp32}" -+ -+#define GNU_USER_LINK_EMULATION "elf64lriscv" -+#define GNU_USER_DYNAMIC_LINKER "/usr/lib/ld.so" -+ -+#define LINK_SPEC "\ -+-melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv" LD_EMUL_SUFFIX " \ -+%{mno-relax:--no-relax} \ -+%{mbig-endian:-EB} \ -+%{mlittle-endian:-EL} \ -+%{shared} \ -+ %{!shared: \ -+ %{!static: \ -+ %{!static-pie: \ -+ %{rdynamic:-export-dynamic} \ -+ -dynamic-linker " GNU_USER_DYNAMIC_LINKER "}} \ -+ %{static:-static} %{static-pie:-static -pie --no-dynamic-linker -z text}}" -+ -+#undef STARTFILE_SPEC -+#define STARTFILE_SPEC "%{!shared: %{static-pie|pie|!no-pie:Scrt1.o%s;:crt1.o%s}} crti.o%s %{shared|static-pie|pie|!no-pie:crtbeginS.o%s;:crtbegin.o%s}" -+ -+#undef ENDFILE_SPEC -+#define ENDFILE_SPEC "%{shared|static-pie|pie|!no-pie:crtendS.o%s;:crtend.o%s} crtn.o%s" -+ -+#undef TARGET_OS_CPP_BUILTINS -+#define TARGET_OS_CPP_BUILTINS() \ -+ do { \ -+ builtin_define ("__orange__"); \ -+ builtin_define ("__mlibc__"); \ -+ builtin_define ("__unix__"); \ -+ builtin_assert ("system=orange"); \ -+ builtin_assert ("system=unix"); \ -+ builtin_assert ("system=posix"); \ -+ } while (0); -diff --git gcc-host-clean/gcc/config.build gcc-host-workdir/gcc/config.build -index 7c80a0b..8fac7e4 100644 ---- gcc-host-clean/gcc/config.build -+++ gcc-host-workdir/gcc/config.build -@@ -45,7 +45,7 @@ - build_xm_file= - build_xm_defines= - build_exeext= --build_install_headers_dir=install-headers-tar -+build_install_headers_dir=install-headers-cp - build_file_translate= - - # System-specific settings. -diff --git gcc-host-clean/gcc/config.gcc gcc-host-workdir/gcc/config.gcc -index 087aaa7..0bee278 100644 ---- gcc-host-clean/gcc/config.gcc -+++ gcc-host-workdir/gcc/config.gcc -@@ -879,6 +879,15 @@ case ${target} in - rust_target_objs="${rust_target_objs} freebsd-rust.o" - target_has_targetrustm=yes - ;; -+*-*-*-mlibc) -+ extra_options="$extra_options gnu-user.opt" -+ gas=yes -+ gnu_ld=yes -+ default_use_cxa_atexit=yes -+ use_gcc_stdint=wrap -+ tmake_file="${tmake_file} t-slibgcc" -+ thread_file='posix' -+ ;; - *-*-fuchsia*) - native_system_header_dir=/include - tmake_file="t-fuchsia" -@@ -2320,6 +2329,9 @@ i[34567]86-*-mingw* | x86_64-*-mingw*) - ;; - esac - ;; -+x86_64-*-orange*) -+ tm_file="${tm_file} i386/unix.h i386/att.h elfos.h gnu-user.h glibc-stdint.h i386/x86-64.h i386/gnu-user-common.h i386/gnu-user64.h i386/orange.h" -+ ;; - x86_64-*-fuchsia*) - tmake_file="${tmake_file} i386/t-x86_64-elf" - tm_file="${tm_file} i386/unix.h i386/att.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h fuchsia.h" -@@ -2519,6 +2531,13 @@ microblaze*-*-elf) - cxx_target_objs="${cxx_target_objs} microblaze-c.o" - tmake_file="${tmake_file} microblaze/t-microblaze" - ;; -+riscv*-*-orange*) -+ tm_file="${tm_file} elfos.h gnu-user.h glibc-stdint.h riscv/orange.h" -+ tmake_file="${tmake_file} riscv/t-riscv" -+ gnu_ld=yes -+ gas=yes -+ gcc_cv_initfini_array=yes -+ ;; - riscv*-*-linux*) - tm_file="elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file} riscv/linux.h" - case "x${enable_multilib}" in -diff --git gcc-host-clean/gcc/cp/module.cc gcc-host-workdir/gcc/cp/module.cc -index 1deadcc..9b72332 100644 ---- gcc-host-clean/gcc/cp/module.cc -+++ gcc-host-workdir/gcc/cp/module.cc -@@ -1697,8 +1697,10 @@ elf_in::defrost (const char *name) - set_error (errno); - else - { -+#ifndef __orange__ - if (madvise (mapping, hdr.pos, MADV_RANDOM)) - goto fail; -+#endif - - /* These buffers are never NULL in this case. */ - strtab.buffer = mapping + strtab.pos; -@@ -1808,8 +1810,10 @@ elf_in::begin (location_t loc) - } - /* We'll be hopping over this randomly. Some systems declare the - first parm as char *, and other declare it as void *. */ -+#ifndef __orange__ - if (madvise (reinterpret_cast <char *> (mapping), size, MADV_RANDOM)) - goto fail; -+#endif - - hdr.buffer = (char *)mapping; - #else -diff --git gcc-host-clean/libatomic/configure.tgt gcc-host-workdir/libatomic/configure.tgt -index 6db039d..e4fc391 100644 ---- gcc-host-clean/libatomic/configure.tgt -+++ gcc-host-workdir/libatomic/configure.tgt -@@ -151,7 +151,7 @@ case "${target}" in - *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu \ - | *-*-netbsd* | *-*-freebsd* | *-*-openbsd* | *-*-dragonfly* \ - | *-*-solaris2* | *-*-sysv4* | *-*-irix6* | *-*-osf* | *-*-hpux11* \ -- | *-*-darwin* | *-*-aix* | *-*-cygwin*) -+ | *-*-darwin* | *-*-aix* | *-*-cygwin* | *-*-mlibc*) - # POSIX system. The OS is supported. - config_path="${config_path} posix" - ;; -diff --git gcc-host-clean/libcpp/Makefile.in gcc-host-workdir/libcpp/Makefile.in -index bb07e46..821fe80 100644 ---- gcc-host-clean/libcpp/Makefile.in -+++ gcc-host-workdir/libcpp/Makefile.in -@@ -32,10 +32,10 @@ AUTOCONF = @AUTOCONF@ - AUTOHEADER = @AUTOHEADER@ - CATALOGS = $(patsubst %,po/%,@CATALOGS@) - CC = @CC@ --CFLAGS = @CFLAGS@ -+override CFLAGS := @CFLAGS@ - WARN_CFLAGS = @warn@ @c_warn@ @WARN_PEDANTIC@ @WERROR@ - CXX = @CXX@ --CXXFLAGS = @CXXFLAGS@ -+override CXXFLAGS := @CXXFLAGS@ - WARN_CXXFLAGS = @warn@ @WARN_PEDANTIC@ @WERROR@ - CPP = @CPP@ - CPPFLAGS = @CPPFLAGS@ -@@ -45,7 +45,7 @@ INCINTL = @INCINTL@ - INSTALL_DATA = @INSTALL_DATA@ - INSTALL_PROGRAM = @INSTALL_PROGRAM@ - INSTALL_SCRIPT = @INSTALL_SCRIPT@ --LDFLAGS = @LDFLAGS@ -+override LDFLAGS := @LDFLAGS@ - LIBICONV = @LIBICONV@ - LIBINTL = @LIBINTL@ - PACKAGE = @PACKAGE@ -diff --git gcc-host-clean/libgcc/config.host gcc-host-workdir/libgcc/config.host -index 6a88ee5..86bd7f3 100644 ---- gcc-host-clean/libgcc/config.host -+++ gcc-host-workdir/libgcc/config.host -@@ -310,6 +310,11 @@ case ${host} in - tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-fuchsia" - extra_parts="crtbegin.o crtend.o" - ;; -+*-*-*-mlibc) -+ extra_parts="$extra_parts crtbegin.o crtbeginS.o crtend.o crtendS.o" -+ tmake_file="$tmake_file t-crtstuff-pic" -+ tmake_file="$tmake_file t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-libgcc-pic" -+ ;; - *-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu | *-*-uclinuxfdpiceabi) - tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-linux" - extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o" -@@ -767,6 +772,10 @@ x86_64-*-elf* | x86_64-*-rtems*) - x86_64-*-fuchsia*) - tmake_file="$tmake_file t-libgcc-pic" - ;; -+x86_64-*-*-mlibc) -+ extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" -+ tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-crtstuff t-dfprules" -+ ;; - i[34567]86-*-dragonfly*) - tmake_file="${tmake_file} i386/t-dragonfly i386/t-crtstuff" - md_unwind_header=i386/dragonfly-unwind.h -@@ -1349,6 +1358,10 @@ pru-*-*) - tmake_file="${tmake_file} t-softfp-sfdf t-softfp-excl t-softfp t-gnu-prefix pru/t-pru" - tm_file="$tm_file pru/pru-abi.h" - ;; -+riscv*-*-mlibc*) -+ tmake_file="${tmake_file} riscv/t-crtstuff riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address} t-slibgcc-libgcc" -+ extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o crtendS.o crtbeginT.o" -+ ;; - riscv*-*-linux*) - tmake_file="${tmake_file} riscv/t-crtstuff riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address} t-slibgcc-libgcc" - extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o crtendS.o crtbeginT.o" -diff --git gcc-host-clean/libstdc++-v3/configure gcc-host-workdir/libstdc++-v3/configure -index 819a1d8..52df448 100755 ---- gcc-host-clean/libstdc++-v3/configure -+++ gcc-host-workdir/libstdc++-v3/configure -@@ -38856,7 +38856,7 @@ $as_echo "#define HAVE_TLS 1" >>confdefs.h - - fi - ;; -- *-linux* | *-uclinux* | *-gnu* | *-kfreebsd*-gnu | *-cygwin* | *-solaris*) -+ *-linux* | *-uclinux* | *-gnu* | *-kfreebsd*-gnu | *-cygwin* | *-solaris* | *-mlibc*) - - # All these tests are for C++; save the language and the compiler flags. - # The CXXFLAGS thing is suspicious, but based on similar bits previously -diff --git gcc-host-clean/libstdc++-v3/include/bits/ios_base.h gcc-host-workdir/libstdc++-v3/include/bits/ios_base.h -index b94b2cd..1a5eaa5 100644 ---- gcc-host-clean/libstdc++-v3/include/bits/ios_base.h -+++ gcc-host-workdir/libstdc++-v3/include/bits/ios_base.h -@@ -225,7 +225,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION - - enum _Ios_Seekdir - { -- _S_beg = 0, -+ _S_beg = 1, - _S_cur = _GLIBCXX_STDIO_SEEK_CUR, - _S_end = _GLIBCXX_STDIO_SEEK_END, - _S_ios_seekdir_end = 1L << 16
\ No newline at end of file diff --git a/tools/fastfetch/config.jsonc b/tools/fastfetch/config.jsonc deleted file mode 100755 index 8c0874a..0000000 --- a/tools/fastfetch/config.jsonc +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/master/doc/json_schema.json", - "modules": [ - "title", - "separator", - "os", - "host", - "kernel", - "uptime", - "packages", - "shell", - "display", - "de", - "wm", - "wmtheme", - "theme", - "icons", - "font", - "cursor", - "terminal", - "terminalfont", - "cpu", - "memory", - "swap", - "disk", - "localip", - "battery", - "poweradapter", - "locale", - "break", - "colors" - ] -} diff --git a/tools/img/oldwork2.png b/tools/img/oldwork2.png Binary files differdeleted file mode 100644 index 6b324e8..0000000 --- a/tools/img/oldwork2.png +++ /dev/null diff --git a/tools/img/qemu.png b/tools/img/qemu.png Binary files differdeleted file mode 100644 index 4a8ae10..0000000 --- a/tools/img/qemu.png +++ /dev/null diff --git a/tools/img/work.png b/tools/img/work.png Binary files differdeleted file mode 100644 index 697c638..0000000 --- a/tools/img/work.png +++ /dev/null diff --git a/tools/img/workold.png b/tools/img/workold.png Binary files differdeleted file mode 100644 index 3ad7a97..0000000 --- a/tools/img/workold.png +++ /dev/null diff --git a/tools/initbase/etc/bg.jpg b/tools/initbase/etc/bg.jpg Binary files differdeleted file mode 100644 index 6080197..0000000 --- a/tools/initbase/etc/bg.jpg +++ /dev/null diff --git a/tools/initbase/etc/gaster b/tools/initbase/etc/gaster deleted file mode 100644 index 7a49fce..0000000 --- a/tools/initbase/etc/gaster +++ /dev/null @@ -1,33 +0,0 @@ - @@@@@@@ - @@@ @ - @ @ @ - @ @ @ - @ @@ @@@@@ @@ - @@ @@ @@ @@@@@@ @@ - @@ @ @@@ @@@@@@ @@ - @@ @ @@@@@ @@@@@@ @@ - @@ @@@@@ @@ @@ - @@ @@ @@ @@ - @ @ @@@ @@ - @ @@ @@@ @ - @ @@@@@@ @ - @@ @@@@@ @ - @@@@@ @@@@ - @@@@@@@@@@@@@@@@ - @@@@@@@@ @@@@@ - @@@@@@@@ @@@@@@@ - @@@@@@@@ @@@@@@@ - @@@@@@@@@ @@@@@@@@ - @@@@@@@@@@ @@@@@@@@ - @@@@@@@@@@ @@@@@@@@ - @@@@ @@@@@ @@@@@@@@@ - @% @@@@@@@@@ @@@ - @% @@@@@@@ @ @@ - @@@ @@@@@@@@ @@ - @@@@@@@@@@@@@@@@@ @@@ - @@@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@ - diff --git a/tools/initbase/etc/hostname b/tools/initbase/etc/hostname deleted file mode 100644 index adb2ca6..0000000 --- a/tools/initbase/etc/hostname +++ /dev/null @@ -1 +0,0 @@ -orange
\ No newline at end of file diff --git a/tools/initbase/etc/localtime b/tools/initbase/etc/localtime Binary files differdeleted file mode 100644 index 91558be..0000000 --- a/tools/initbase/etc/localtime +++ /dev/null diff --git a/tools/initbase/etc/twmbg.png b/tools/initbase/etc/twmbg.png Binary files differdeleted file mode 100644 index 6ed71a1..0000000 --- a/tools/initbase/etc/twmbg.png +++ /dev/null diff --git a/tools/limine.conf b/tools/limine.conf deleted file mode 100644 index 94cb6c1..0000000 --- a/tools/limine.conf +++ /dev/null @@ -1,6 +0,0 @@ - -timeout: 0 -/Orange - protocol: limine - path: boot():/boot/kernel - module_path: boot():/boot/initrd.tar
\ No newline at end of file diff --git a/tools/linux-headers.sh b/tools/linux-headers.sh deleted file mode 100644 index 22ee8be..0000000 --- a/tools/linux-headers.sh +++ /dev/null @@ -1,15 +0,0 @@ -if [ ! -d "./linux-headers" ]; then - mkdir -p temp - mkdir -p linux-headers - git clone https://github.com/torvalds/linux.git --depth=1 - cd linux - make headers_install ARCH=x86_64 INSTALL_HDR_PATH="$(realpath ../temp)" - cd .. - cp -rf temp/include/* linux-headers - rm -rf temp - rm -rf linux -fi - -echo Copying linux-headers... -mkdir -p "$1/initrd/usr/include" -cp -rf linux-headers/* "$1/initrd/usr/include"
\ No newline at end of file diff --git a/tools/pkg/0/glibc/pkg.sh b/tools/pkg/0/glibc/pkg.sh deleted file mode 100644 index d56b3e9..0000000 --- a/tools/pkg/0/glibc/pkg.sh +++ /dev/null @@ -1,69 +0,0 @@ -. ../../pkg-lib.sh - -if [ ! -d "./linux-headers" ]; then - mkdir -p temp - mkdir -p linux-headers - git clone https://github.com/torvalds/linux.git --depth=1 - cd linux - make headers_install ARCH=x86_64 INSTALL_HDR_PATH="$(realpath ../temp)" - cd .. - cp -rf temp/include/* linux-headers - rm -rf temp - rm -rf linux -fi - -echo Copying linux-headers... -mkdir -p "$1/usr/include" -cp -rf linux-headers/* "$1/usr/include" - -rm -rf pack -mkdir -p pack -cd pack - -mkdir -p "$1" - -wget $GNU_MIRROR/gnu/libc/glibc-2.42.tar.gz -tar -xvf glibc-2.42.tar.gz -cd glibc-2.42 - -T="$(pwd)" - -cd "$1" -rm -rf lib bin -echo "Creating symlinks" - -ln -sf usr/lib lib -ln -sf usr/bin bin - -cd usr - -cd "$T" - -mkdir -p glibc-build -cd glibc-build -../configure --prefix="/usr" --disable-debug --disable-multi-arch --disable-multilib --disable-nls --disable-profile --libdir=/usr/lib --disable-static --enable-shared --with-sysroot="$1" lt_cv_sys_lib_dlsearch_path_spec="/usr/lib" -make -j$(nproc) -make DESTDIR="$1" install -j$(nproc) -cd "$1/usr/lib" -#cp -rf "$1/lib64/*" "$1/usr/lib" -cp -rf "$HOME"/opt/cross/orange/x86_64-linux-gnu/lib/libs*.so* . -cp -rf "$HOME"/opt/cross/orange/lib64/libg*.so* . -cp -rf "$HOME"/opt/cross/orange/lib64/libs*.so* . -cd "$1/usr" -#ln -sf lib lib64 -cd "$1" -#rm -rf "lib64" -#ln -sf usr/lib lib64 - -cp -rf lib64/* "$1/usr/lib" -rm -rf lib64 -ln -sf usr/lib lib64 - -cd "$T" - -cp -rf "/usr/include/sys/sdt.h" "/usr/include/sys/sdt-config.h" "$1/usr/include/sys" # copy it if available - -rm -rf "$1/usr/lib/libc.a" "$1/usr/lib/libm-2.42.a" "$1/usr/lib/libmvec.a" -echo "glibc compile done" - -cd ..
\ No newline at end of file diff --git a/tools/pkg/0/mlibc/info.txt b/tools/pkg/0/mlibc/info.txt deleted file mode 100644 index a2a201a..0000000 --- a/tools/pkg/0/mlibc/info.txt +++ /dev/null @@ -1 +0,0 @@ -mlibc
\ No newline at end of file diff --git a/tools/pkg/0/mlibc/pkg.sh b/tools/pkg/0/mlibc/pkg.sh deleted file mode 100644 index c815c22..0000000 --- a/tools/pkg/0/mlibc/pkg.sh +++ /dev/null @@ -1,46 +0,0 @@ - -exit 0 -rm -rf pack -mkdir -p pack -mkdir -p cached - -mkdir -p "$1/usr/include" -mkdir -p "$1/usr/bin" -mkdir -p "$1/usr/lib" -mkdir -p "$1/lib" -mkdir -p "$1/bin" - -if [ ! -d "./linux-headers" ]; then - mkdir -p temp - mkdir -p linux-headers - git clone https://github.com/torvalds/linux.git --depth=1 - cd linux - make headers_install ARCH=x86_64 INSTALL_HDR_PATH="$(realpath ../temp)" - cd .. - cp -rf temp/include/* linux-headers - rm -rf temp - rm -rf linux -fi - -echo Copying linux-headers... -mkdir -p "$1/usr/include" -cp -rf linux-headers/* "$1/usr/include" - -cd pack - -export CFLAGS="-std=gnu11" - -# mlibc doesn't need to be cached -git clone https://github.com/cpplover0/orange-mlibc --depth=1 -cd orange-mlibc - -sh build_to_cross.sh "$(realpath $1/..)" - -T=$(realpath .) - -cd $1/usr/lib -ln -sf ld.so ld64.so.1 -cp -rf $HOME/opt/cross/orange/x86_64-orange-mlibc/lib/libs*.so* . - -cd "$T" -cd .. diff --git a/tools/pkg/1/liborange/include/dev.h b/tools/pkg/1/liborange/include/dev.h deleted file mode 100644 index 5fb10f3..0000000 --- a/tools/pkg/1/liborange/include/dev.h +++ /dev/null @@ -1,159 +0,0 @@ - -// liborange dev.h - -#include <stdint.h> - -#ifndef LIBORANGE_DEV_H -#define LIBORANGE_DEV_H - -#define DEVFS_PACKET_CREATE_DEV 1 -#define DEVFS_PACKET_READ_READRING 2 -#define DEVFS_PACKET_WRITE_READRING 3 -#define DEVFS_PACKET_READ_WRITERING 4 -#define DEVFS_PACKET_WRITE_WRITERING 5 -#define DEVFS_PACKET_CREATE_IOCTL 6 -#define DEVFS_PACKET_SIZE_IOCTL 7 -#define DEVFS_PACKET_IOCTL 8 -#define DEVFS_ENABLE_PIPE 9 -#define DEVFS_SETUP_MMAP 10 -#define DEVFS_PACKET_CREATE_PIPE_DEV 11 -#define DEVFS_PACKET_ISATTY 12 - -#define DEVFS_GETSLAVE_BY_MASTER 14 -#define DEVFS_PACKET_SETUP_RING_SIZE 15 - -typedef struct { - union { - struct { - uint8_t request; - uint8_t* cycle; - uint32_t* queue; - uint32_t size; - uint64_t value; - }; - struct { - uint8_t request; - uint64_t ioctlreq; - uint64_t arg; - } ioctl; - struct { - uint8_t request; - uint32_t writereg; - uint32_t readreg; - uint32_t size; - uint64_t pointer; - } create_ioctl; - struct { - uint8_t request; - uint8_t pipe_target; - uint64_t pipe_pointer; - } enable_pipe; - struct { - uint8_t request; - uint64_t dma_addr; - uint64_t size; - } setup_mmap; - }; -} __attribute__((packed)) devfs_packet_t; - -struct limine_video_mode { - uint64_t pitch; - uint64_t width; - uint64_t height; - uint16_t bpp; - uint8_t memory_model; - uint8_t red_mask_size; - uint8_t red_mask_shift; - uint8_t green_mask_size; - uint8_t green_mask_shift; - uint8_t blue_mask_size; - uint8_t blue_mask_shift; -}; - -struct limine_framebuffer { - uint64_t address; - uint64_t width; - uint64_t height; - uint64_t pitch; - uint16_t bpp; - uint8_t memory_model; - uint8_t red_mask_size; - uint8_t red_mask_shift; - uint8_t green_mask_size; - uint8_t green_mask_shift; - uint8_t blue_mask_size; - uint8_t blue_mask_shift; - uint8_t unused[7]; - uint64_t edid_size; - void* edid; - uint64_t reserved[4]; -}; - -#define PTE_PRESENT (1 << 0) -#define PTE_RW (1 << 1) -#define PTE_USER (1 << 2) -#define PTE_WC ((1 << 7) | (1 << 3)) -#define PTE_MMIO (1ull << 4) - -inline void liborange_create_dev(unsigned long long request, char* slave_path, char* master_path) { - asm volatile("syscall" : : "a"(18), "D"(request), "S"(slave_path), "d"(master_path) : "rcx","r11"); -} - -inline static void liborange_setup_iopl_3() { - asm volatile("syscall" : : "a"(19) : "rcx","r11"); -} - -// char* path, std::uint64_t write_and_read_req, std::uint32_t size -inline void liborange_setup_ioctl(char* path, uint64_t size, int32_t read_req, int32_t write_req) { - asm volatile("syscall" : : "a"(21), "D"(path), "S"((uint64_t)((uint64_t)write_req << 32) | read_req), "d"(size) : "rcx","r11"); -} - -inline void liborange_setup_tty(char* path) { - asm volatile("syscall" : : "a"(22), "D"(path) : "rcx","r11"); -} - -inline void liborange_setup_mmap(char* path, uint64_t addr, uint64_t size, uint64_t flags) { - register uint64_t r8 asm("r8") = flags; - asm volatile("syscall" : : "a"(24), "D"(path), "S"(addr), "d"(size), "r"(flags) : "rcx","r11"); -} - -inline void liborange_access_framebuffer(struct limine_framebuffer* out) { - asm volatile("syscall" : : "a"(25), "D"(out) : "rcx", "r11"); -} - -inline void liborange_setup_ring_bytelen(char* path, int bytelen) { - asm volatile("syscall" : : "a"(27), "D"(path), "S"(bytelen) : "rcx","r11"); -} - -inline uint64_t liborange_alloc_dma(uint64_t dma_size) { - uint64_t addr = 0; - asm volatile("syscall" : "=d"(addr) : "a"(38), "D"(dma_size) : "rcx","r11"); - return addr; -} - -void liborange_free_dma(uint64_t dma_addr) { - asm volatile("syscall" : : "a"(40), "D"(dma_addr) : "rcx","r11"); -} - -inline void* liborange_map_phys(uint64_t phys_addr,uint64_t flags,uint64_t size) { - uint64_t addr = 0; - asm volatile("syscall" : "=d"(addr) : "a"(39), "D"(phys_addr), "S"(flags), "d"(size) : "rcx","r11"); - return (void*)addr; -} - -#define PAGE_SIZE 4096 - -#define ROUNDUP(VALUE,ROUND) ((VALUE + (ROUND - 1)) / ROUND) -#define ALIGNPAGEUP(VALUE) (ROUNDUP(VALUE,PAGE_SIZE) * PAGE_SIZE) -#define ALIGNPAGEDOWN(VALUE) ((VALUE / PAGE_SIZE) * PAGE_SIZE) - -#define CROUNDUP(VALUE,ROUND) ((VALUE + (ROUND - 1)) / ROUND) -#define CALIGNPAGEUP(VALUE,c) ((VALUE + c - 1) & ~(c - 1)) -#define CALIGNPAGEDOWN(VALUE,c) ((VALUE / c) * c) - -typedef struct { - uint16_t irq; - uint64_t flags; -} __attribute__((packed)) liborange_pic_create_t; - -#endif
\ No newline at end of file diff --git a/tools/pkg/1/liborange/include/io.h b/tools/pkg/1/liborange/include/io.h deleted file mode 100644 index a1bef05..0000000 --- a/tools/pkg/1/liborange/include/io.h +++ /dev/null @@ -1,35 +0,0 @@ - -#ifndef LIBORANGE_IO_H -#define LIBORANGE_IO_H - -static inline void outb(unsigned short port, unsigned char val) { - __asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port)); -} - -static inline void outw(unsigned short port, unsigned short val) { - __asm__ volatile ("outw %0, %1" : : "a"(val), "Nd"(port)); -} - -static inline void outd(unsigned short port, unsigned int val) { - __asm__ volatile ("outl %0, %1" : : "a"(val), "Nd"(port)); -} - -static inline unsigned char inb(unsigned short port) { - unsigned char ret; - __asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -static inline unsigned short inw(unsigned short port) { - unsigned short ret; - __asm__ volatile ("inw %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -static inline unsigned int ind(unsigned short port) { - unsigned int ret; - __asm__ volatile ("inl %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -#endif
\ No newline at end of file diff --git a/tools/pkg/1/liborange/include/log.h b/tools/pkg/1/liborange/include/log.h deleted file mode 100644 index 0751266..0000000 --- a/tools/pkg/1/liborange/include/log.h +++ /dev/null @@ -1,18 +0,0 @@ - -#include <stdio.h> - -#pragma once - -#define LEVEL_MESSAGE_OK 0 -#define LEVEL_MESSAGE_FAIL 1 -#define LEVEL_MESSAGE_WARN 2 -#define LEVEL_MESSAGE_INFO 3 - -const char* level_messages[] = { - [LEVEL_MESSAGE_OK] = "[ \x1b[38;2;0;255;0mOK\033[0m ] ", - [LEVEL_MESSAGE_FAIL] = "[ \x1b[38;2;255;0;0mFAILED\033[0m ] ", - [LEVEL_MESSAGE_WARN] = "[ \x1b[38;2;255;165;0mWARN\033[0m ] ", - [LEVEL_MESSAGE_INFO] = "[ \x1b[38;2;0;191;255mINFO\033[0m ] " -}; - -#define log(level, format,...) printf("%s" format "", level_messages[level], ##__VA_ARGS__)
\ No newline at end of file diff --git a/tools/pkg/1/liborange/include/pci.h b/tools/pkg/1/liborange/include/pci.h deleted file mode 100644 index 305c9fe..0000000 --- a/tools/pkg/1/liborange/include/pci.h +++ /dev/null @@ -1,185 +0,0 @@ -#include <stdint.h> -#include <orange/io.h> - -#include <stdio.h> - -#ifndef LIBORANGE_PCI_H -#define LIBORANGE_PCI_H - -typedef struct { - uint16_t vendorID; - uint16_t deviceID; - uint16_t command; - uint16_t status; - uint8_t revisionID; - uint8_t progIF; - uint8_t subclass; - uint8_t _class; - uint8_t cacheLineSize; - uint8_t latencyTimer; - uint8_t headerType; - uint8_t bist; - uint32_t bar0; - uint32_t bar1; - uint32_t bar2; - uint32_t bar3; - uint32_t bar4; - uint32_t bar5; - uint32_t cardbusCISPointer; - uint16_t subsystemVendorID; - uint16_t subsystemID; - uint32_t expansionROMBaseAddress; - uint8_t capabilitiesPointer; - uint8_t reserved0; - uint16_t reserved1; - uint32_t reserved2; - uint8_t irq; - uint8_t interruptPIN; - uint8_t minGrant; - uint8_t maxLatency; -} __attribute__((packed)) pci_t; - -typedef struct pci_cap { - uint8_t id; - uint8_t off; - uint8_t bus; - uint8_t num; - uint8_t func; - uint16_t venID; - uint16_t devID; - uint8_t data[32]; - struct pci_cap* next; -} __attribute__((packed)) pci_cap_t; - -typedef struct { - int used; - uint8_t _class; - uint8_t subclass; - void (*pcidrv)(pci_t, uint8_t, uint8_t, uint8_t); -} __attribute__((packed)) pci_driver_t; - -#define PCI_BAR_MASK ((1 << 0) | (1 << 1)) - -uint32_t pci_read_config32(uint8_t bus, uint8_t num, uint8_t function, uint8_t offset) { - uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset); - outd(0xCF8, address); - return ind(0xCFC); -} - -uint16_t pci_read_config16(uint8_t bus, uint8_t num, uint8_t function, uint8_t offset) { - uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset & 0xfc); - outd(0xCF8, address); - return(uint16_t)((ind(0xCFC) >> ((offset & 2) * 8)) & 0xffff); -} - -uint8_t pci_read_config8(uint8_t bus, uint8_t num, uint8_t function, uint8_t offset) { - uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset); - outd(0xCF8, address); - return (uint8_t)((ind(0xCFC) >> ((offset & 3) * 8)) & 0xff); -} - -void pci_write_config32(uint8_t bus, uint8_t num, uint8_t function, uint8_t offset, uint32_t value) { - uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset); - outd(0xCF8, address); - outd(0xCFC, value); -} - -void pci_write_config16(uint8_t bus, uint8_t num, uint8_t function, uint8_t offset, uint32_t value) { - uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset & 0xfc); - outd(0xCF8, address); - outd(0xCFC,(ind(0xCFC) & ~(0xffff << ((offset & 2) * 8))) | (value << ((offset & 2) * 8))); -} - -void pci_write_config8(uint8_t bus, uint8_t num, uint8_t function, uint8_t offset, uint8_t value) { - uint32_t address = (1 << 31) | (bus << 16) | (num << 11) | (function << 8) | (offset & 0xfc); - outd(0xCF8, address); - outd(0xCFC, ((ind(0xCFC) & ~(0xFF << (offset & 3))) | (value << ((offset & 3) * 8)))); -} - -uint32_t pci_in(int8_t bus, uint8_t num, uint8_t function, uint8_t offset, uint8_t bytewidth) { - uint32_t value = 0; - switch(bytewidth) { - case 1: - value = pci_read_config8(bus,num,function,offset); - break; - case 2: - value = pci_read_config16(bus,num,function,offset); - break; - case 4: - value = pci_read_config32(bus,num,function,offset); - break; - default: - break; - } - - return value; - -} - -void pci_out(uint8_t bus, uint8_t num, uint8_t function, uint8_t offset, uint32_t value, uint8_t bytewidth) { - switch(bytewidth) { - case 1: - pci_write_config8(bus,num,function,offset,(uint8_t)value); - break; - case 2: - pci_write_config16(bus,num,function,offset,(uint16_t)value); - break; - case 4: - pci_write_config32(bus,num,function,offset,(uint32_t)value); - break; - default: - break; - } -} - -pci_t __pci_load(uint8_t bus, uint8_t num, uint8_t function) { - pci_t pciData; - uint16_t *p = (uint16_t *)&pciData; - for (uint8_t i = 0; i < 32; i++) { - p[i] = pci_read_config16(bus, num, function, i * 2); - } - return pciData; -} - -void pci_reg(pci_driver_t* pci_drivers,void (*pcidrv)(pci_t, uint8_t, uint8_t, uint8_t), uint8_t _class, uint8_t subclass) { - for (uint16_t i = 0; i < 256; i++) { - if (!pci_drivers[i].used) { - pci_drivers[i].used = true; - pci_drivers[i]._class = _class; - pci_drivers[i].subclass = subclass; - pci_drivers[i].pcidrv = pcidrv; - } - } -} - -void __pci_launch(pci_driver_t* pci_drivers,pci_t pci, uint8_t bus, uint8_t device, uint8_t function) { - for (uint16_t i = 0; i < 256; i++) { - if (pci_drivers[i].used && pci_drivers[i]._class == pci._class && pci_drivers[i].subclass == pci.subclass) { - pci_drivers[i].pcidrv(pci, bus, device, function); - return; - } - } -} - -void pci_initworkspace(pci_driver_t* pci_drivers) { - pci_t c_pci; - for (uint16_t bus = 0; bus < 256; bus++) { - c_pci = __pci_load(bus, 0, 0); - if (c_pci.vendorID != 0xFFFF) { - for (uint8_t device = 0; device < 32; device++) { - c_pci = __pci_load(bus, device, 0); - if (c_pci.vendorID != 0xFFFF) { - __pci_launch(pci_drivers,c_pci, bus, device, 0); - for (uint8_t function = 1; function < 8; function++) { - pci_t pci = __pci_load(bus, device, function); - if (pci.vendorID != 0xFFFF) { - __pci_launch(pci_drivers,pci, bus, device, function); - } - } - } - } - } - } -} - -#endif
\ No newline at end of file diff --git a/tools/pkg/1/liborange/info.txt b/tools/pkg/1/liborange/info.txt deleted file mode 100644 index 3dbf191..0000000 --- a/tools/pkg/1/liborange/info.txt +++ /dev/null @@ -1 +0,0 @@ -liborange
\ No newline at end of file diff --git a/tools/pkg/1/liborange/pkg.sh b/tools/pkg/1/liborange/pkg.sh deleted file mode 100644 index 572a687..0000000 --- a/tools/pkg/1/liborange/pkg.sh +++ /dev/null @@ -1,4 +0,0 @@ - -mkdir -p "$1/usr/include/orange" - -cp -rf include/* "$1/usr/include/orange/" diff --git a/tools/pkg/1/libtool/info.txt b/tools/pkg/1/libtool/info.txt deleted file mode 100644 index f898b81..0000000 --- a/tools/pkg/1/libtool/info.txt +++ /dev/null @@ -1 +0,0 @@ -libtool
\ No newline at end of file diff --git a/tools/pkg/1/libtool/pkg.sh b/tools/pkg/1/libtool/pkg.sh deleted file mode 100644 index d14dafc..0000000 --- a/tools/pkg/1/libtool/pkg.sh +++ /dev/null @@ -1,27 +0,0 @@ -# https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz - - -. ../../pkg-lib.sh - -mkdir -p cached - -rm -rf pack - -mkdir -p pack - -cd pack - -fast_install "$1" https://ftp.gnu.org/gnu/libtool/libtool-2.5.4.tar.xz - -# wget https://ftpmirror.gnu.org/gnu/libtool/libtool-2.5.4.tar.gz -# tar -xvf libtool-2.5.4.tar.gz -# cd libtool-2.5.4 - -# diff_patch ../../diff/libtool.diff -# ./configure --prefix="$HOME/opt/cross/orange" --with-gnu-ld --enable-shared --disable-static -# make -j$(nproc) -# make install - -# cd .. - -cd .. diff --git a/tools/pkg/1/nop/info.txt b/tools/pkg/1/nop/info.txt deleted file mode 100644 index cf50396..0000000 --- a/tools/pkg/1/nop/info.txt +++ /dev/null @@ -1 +0,0 @@ -nop-process
\ No newline at end of file diff --git a/tools/pkg/1/nop/pkg.sh b/tools/pkg/1/nop/pkg.sh deleted file mode 100644 index 15e089e..0000000 --- a/tools/pkg/1/nop/pkg.sh +++ /dev/null @@ -1,2 +0,0 @@ - -x86_64-orange-mlibc-gcc src/main.cpp -o "$1/usr/bin/nop"
\ No newline at end of file diff --git a/tools/pkg/1/nop/src/main.cpp b/tools/pkg/1/nop/src/main.cpp deleted file mode 100644 index fa419b2..0000000 --- a/tools/pkg/1/nop/src/main.cpp +++ /dev/null @@ -1,6 +0,0 @@ - -int main() { - while(1) { - asm volatile("nop"); - } -}
\ No newline at end of file diff --git a/tools/pkg/1/pkg-config/diff/libtool.diff b/tools/pkg/1/pkg-config/diff/libtool.diff deleted file mode 100644 index 6891c59..0000000 --- a/tools/pkg/1/pkg-config/diff/libtool.diff +++ /dev/null @@ -1,366 +0,0 @@ -diff -Naur libtool-2.5.4/build-aux/config.sub libtool-patched/build-aux/config.sub ---- libtool-2.5.4/build-aux/config.sub 2024-11-20 22:08:12.000000000 +0300 -+++ libtool-patched/build-aux/config.sub 2025-10-15 15:25:52.941696228 +0300 -@@ -2013,6 +2013,7 @@ - | gnu* \ - | go32* \ - | haiku* \ -+ | orange* \ - | hcos* \ - | hiux* \ - | hms* \ -diff -Naur libtool-2.5.4/configure libtool-patched/configure ---- libtool-2.5.4/configure 2024-11-20 22:41:01.000000000 +0300 -+++ libtool-patched/configure 2025-10-15 15:25:06.323056653 +0300 -@@ -7842,7 +7842,7 @@ - lt_cv_deplibs_check_method=pass_all - ;; - --*-mlibc) -+*-mlibc | orange*) - lt_cv_deplibs_check_method=pass_all - ;; - -@@ -11409,7 +11409,7 @@ - lt_prog_compiler_static='-Bstatic' - ;; - -- *-mlibc) -+ *-mlibc | orange*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' -@@ -12076,7 +12076,7 @@ - fi - ;; - -- *-mlibc) -+ *-mlibc | orange*) - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - ;; -@@ -12785,7 +12785,7 @@ - esac - ;; - -- *-mlibc) -+ *-mlibc | orange*) - ;; - - netbsd* | netbsdelf*-gnu) -@@ -13980,7 +13980,7 @@ - hardcode_into_libs=yes - ;; - --*-mlibc) -+*-mlibc | orange*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no -@@ -14457,7 +14457,7 @@ - lt_prog_compiler_static='-Bstatic' - ;; - -- *-mlibc) -+ *-mlibc | orange*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' -@@ -16278,7 +16278,7 @@ - # at 6.2 and later dlopen does load deplibs. - lt_cv_sys_dlopen_deplibs=yes - ;; -- *-mlibc) -+ *-mlibc | orange*) - lt_cv_sys_dlopen_deplibs=yes - ;; - netbsd* | netbsdelf*-gnu) -@@ -18356,7 +18356,7 @@ - esac - ;; - -- *-mlibc) -+ *-mlibc | orange*) - ld_shlibs_CXX=yes - ;; - -@@ -19081,7 +19081,7 @@ - ;; - netbsd* | netbsdelf*-gnu) - ;; -- *-mlibc) -+ *-mlibc | orange*) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise -@@ -20234,7 +20234,7 @@ - hardcode_into_libs=yes - ;; - --*-mlibc) -+*-mlibc | orange*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no -@@ -20681,7 +20681,7 @@ - ;; - netbsd* | netbsdelf*-gnu) - ;; -- *-mlibc) -+ *-mlibc | orange*) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise -@@ -21689,7 +21689,7 @@ - lt_prog_compiler_static_F77='-Bstatic' - ;; - -- *-mlibc) -+ *-mlibc | orange*) - lt_prog_compiler_wl_F77='-Wl,' - lt_prog_compiler_pic_F77='-fPIC' - lt_prog_compiler_static_F77='-static' -@@ -22341,7 +22341,7 @@ - fi - ;; - -- *-mlibc) -+ *-mlibc | orange*) - archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - ;; -@@ -22998,7 +22998,7 @@ - esac - ;; - -- *-mlibc) -+ *-mlibc | orange*) - ;; - - netbsd* | netbsdelf*-gnu) -@@ -24014,7 +24014,7 @@ - hardcode_into_libs=yes - ;; - --*-mlibc) -+*-mlibc | orange*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no -@@ -24491,7 +24491,7 @@ - lt_prog_compiler_static_F77='-Bstatic' - ;; - -- *-mlibc) -+ *-mlibc | orange*) - lt_prog_compiler_wl_F77='-Wl,' - lt_prog_compiler_pic_F77='-fPIC' - lt_prog_compiler_static_F77='-static' -@@ -25628,7 +25628,7 @@ - lt_prog_compiler_static_FC='-Bstatic' - ;; - -- *-mlibc) -+ *-mlibc | orange*) - lt_prog_compiler_wl_FC='-Wl,' - lt_prog_compiler_pic_FC='-fPIC' - lt_prog_compiler_static_FC='-static' -@@ -26280,7 +26280,7 @@ - fi - ;; - -- *-mlibc) -+ *-mlibc | orange*) - archive_cmds_FC='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds_FC='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - ;; -@@ -26937,7 +26937,7 @@ - esac - ;; - -- *-mlibc) -+ *-mlibc | orange*) - ;; - - netbsd* | netbsdelf*-gnu) -@@ -27953,7 +27953,7 @@ - hardcode_into_libs=yes - ;; - --*-mlibc) -+*-mlibc | orange*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no -@@ -28430,7 +28430,7 @@ - lt_prog_compiler_static_FC='-Bstatic' - ;; - -- *-mlibc) -+ *-mlibc | orange*) - lt_prog_compiler_wl_FC='-Wl,' - lt_prog_compiler_pic_FC='-fPIC' - lt_prog_compiler_static_FC='-static' -@@ -29277,7 +29277,7 @@ - lt_prog_compiler_static_GO='-Bstatic' - ;; - -- *-mlibc) -+ *-mlibc | orange*) - lt_prog_compiler_wl_GO='-Wl,' - lt_prog_compiler_pic_GO='-fPIC' - lt_prog_compiler_static_GO='-static' -@@ -29929,7 +29929,7 @@ - fi - ;; - -- *-mlibc) -+ *-mlibc | orange*) - archive_cmds_GO='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds_GO='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - ;; -@@ -30597,7 +30597,7 @@ - esac - ;; - -- *-mlibc) -+ *-mlibc | orange*) - ;; - - netbsd* | netbsdelf*-gnu) -@@ -31568,7 +31568,7 @@ - lt_prog_compiler_static_GCJ='-Bstatic' - ;; - -- *-mlibc) -+ *-mlibc | orange*) - lt_prog_compiler_wl_GCJ='-Wl,' - lt_prog_compiler_pic_GCJ='-fPIC' - lt_prog_compiler_static_GCJ='-static' -@@ -32220,7 +32220,7 @@ - fi - ;; - -- *-mlibc) -+ *-mlibc | orange*) - archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - ;; -@@ -32888,7 +32888,7 @@ - esac - ;; - -- *-mlibc) -+ *-mlibc | orange*) - ;; - - netbsd* | netbsdelf*-gnu) -diff -Naur libtool-2.5.4/libtoolize.in libtool-patched/libtoolize.in ---- libtool-2.5.4/libtoolize.in 2024-11-20 22:01:08.000000000 +0300 -+++ libtool-patched/libtoolize.in 2025-10-15 15:25:06.323056653 +0300 -@@ -1922,7 +1922,7 @@ - # Do not remove config.guess, config.sub or install-sh, we don't - # install them without --install, and the project may not be using - # Automake. Similarly, do not remove Gnulib files. -- all_pkgaux_files="compile depcomp missing ltmain.sh" -+ all_pkgaux_files="" - all_pkgmacro_files="libtool.m4 ltargz.m4 ltdl.m4 ltoptions.m4 ltsugar.m4 ltversion.in ltversion.m4 lt~obsolete.m4" - all_pkgltdl_files="COPYING.LIB Makefile Makefile.in Makefile.inc Makefile.am README acinclude.m4 aclocal.m4 argz_.h argz.c config.h.in config-h.in configure configure.ac configure.in libltdl/lt__alloc.h libltdl/lt__argz.h libltdl/lt__dirent.h libltdl/lt__glibc.h libltdl/lt__private.h libltdl/lt__strl.h libltdl/lt_dlloader.h libltdl/lt_error.h libltdl/lt_system.h libltdl/slist.h loaders/dld_link.c loaders/dlopen.c loaders/dyld.c loaders/load_add_on.c loaders/loadlibrary.c loaders/preopen.c loaders/shl_load.c lt__alloc.c lt__argz.c lt__dirent.c lt__strl.c lt_dlloader.c lt_error.c ltdl.c ltdl.h ltdl.mk slist.c" - -diff -Naur libtool-2.5.4/m4/libtool.m4 libtool-patched/m4/libtool.m4 ---- libtool-2.5.4/m4/libtool.m4 2024-11-20 22:01:08.000000000 +0300 -+++ libtool-patched/m4/libtool.m4 2025-10-15 15:25:06.324056688 +0300 -@@ -1725,7 +1725,7 @@ - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - -- gnu* | ironclad*) -+ gnu* | ironclad* | orange*) - # Under GNU Hurd and Ironclad, this test is not required because there - # is no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever -@@ -2550,6 +2550,18 @@ - esac - ;; - -+orange*) -+ version_type=linux -+ need_lib_prefix=no -+ need_version=no -+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' -+ soname_spec='$libname$release$shared_ext$major' -+ dynamic_linker='mlibc ld.so' -+ shlibpath_var=LD_LIBRARY_PATH -+ shlibpath_overrides_runpath=no -+ hardcode_into_libs=yes -+ ;; -+ - beos*) - library_names_spec='$libname$shared_ext' - dynamic_linker="$host_os ld.so" -@@ -3576,6 +3588,10 @@ - lt_cv_deplibs_check_method=pass_all - ;; - -+orange*) -+ lt_cv_deplibs_check_method=pass_all -+ ;; -+ - beos*) - lt_cv_deplibs_check_method=pass_all - ;; -@@ -4427,6 +4443,8 @@ - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; -+ orange*) -+ ;; - chorus*) - case $cc_basename in - cxch68*) -@@ -4682,6 +4700,12 @@ - ;; - esac - ;; -+ -+ orange*) -+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' -+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' -+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' -+ ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. -@@ -5239,6 +5263,11 @@ - ;; - esac - ;; -+ -+ orange*) -+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' -+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' -+ ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then -@@ -5710,7 +5739,8 @@ - ;; - esac - ;; -- -+ orange*) -+ ;; - bsdi[[45]]*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; -@@ -6776,6 +6806,10 @@ - fi - fi - ;; -+ -+ orange*) -+ _LT_TAGVAR(ld_shlibs, $1)=yes -+ ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then diff --git a/tools/pkg/1/pkg-config/diff/pkg-config.diff b/tools/pkg/1/pkg-config/diff/pkg-config.diff deleted file mode 100644 index b815c89..0000000 --- a/tools/pkg/1/pkg-config/diff/pkg-config.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff -Naur pkg-config-0.29.2/config.sub pkg-config-patched/config.sub ---- pkg-config-0.29.2/config.sub 2015-09-27 17:07:23.000000000 +0300 -+++ pkg-config-patched/config.sub 2025-10-14 19:04:15.422008115 +0300 -@@ -1393,7 +1393,7 @@ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ -- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) -+ | -skyos* | -haiku* | -orange* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) diff --git a/tools/pkg/1/pkg-config/info.txt b/tools/pkg/1/pkg-config/info.txt deleted file mode 100644 index 6d2c214..0000000 --- a/tools/pkg/1/pkg-config/info.txt +++ /dev/null @@ -1 +0,0 @@ -pkg-config diff --git a/tools/pkg/1/pkg-config/pkg.sh b/tools/pkg/1/pkg-config/pkg.sh deleted file mode 100644 index 222c20a..0000000 --- a/tools/pkg/1/pkg-config/pkg.sh +++ /dev/null @@ -1,54 +0,0 @@ -# https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz - - -. ../../pkg-lib.sh - -mkdir -p cached - -rm -rf pack - -mkdir -p pack - -cd pack - -wget https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz -tar -xvf pkg-config-0.29.2.tar.gz -cd pkg-config-0.29.2 - -diff_patch ../../diff/pkg-config.diff -./configure --prefix="$HOME/opt/cross/orange" --with-internal-glib --target=x86_64-orange -make -j$(nproc) -make install - -mkdir -p "$HOME/opt/cross/orange"/share/pkgconfig/personality.d - -cat > "$HOME/opt/cross/orange"/share/pkgconfig/personality.d/x86_64-orange.personality << EOF -Triplet: x86_64-orange -SysrootDir: $1 -DefaultSearchPaths: $1/usr/lib/pkgconfig:$1/usr/share/pkgconfig -SystemIncludePaths: $1/usr/include -SystemLibraryPaths: $1/usr/lib -EOF - -c="$(pwd)" - -cd "$HOME/opt/cross/orange/bin" - -ln -sf pkg-config x86_64-linux-gnu-pkg-config - -cd "$c" - -fast_install "$1" https://ftp.gnu.org/gnu/libtool/libtool-2.5.4.tar.xz - -# wget https://ftpmirror.gnu.org/gnu/libtool/libtool-2.5.4.tar.gz -# tar -xvf libtool-2.5.4.tar.gz -# cd libtool-2.5.4 - -# diff_patch ../../diff/libtool.diff -# ./configure --prefix="$HOME/opt/cross/orange" --with-gnu-ld --enable-shared --disable-static -# make -j$(nproc) -# make install - -# cd .. - -cd .. diff --git a/tools/pkg/10/gtk_final/info.txt b/tools/pkg/10/gtk_final/info.txt deleted file mode 100644 index 898531a..0000000 --- a/tools/pkg/10/gtk_final/info.txt +++ /dev/null @@ -1 +0,0 @@ -gtk :)
\ No newline at end of file diff --git a/tools/pkg/10/gtk_final/pkg.sh b/tools/pkg/10/gtk_final/pkg.sh deleted file mode 100644 index 792046f..0000000 --- a/tools/pkg/10/gtk_final/pkg.sh +++ /dev/null @@ -1,46 +0,0 @@ - -. ../../pkg-lib.sh - -rm -rf pack - -mkdir -p pack - -cd pack - -wget https://github.com/anholt/libepoxy/archive/refs/tags/1.5.10.tar.gz -tar -xvf 1.5.10.tar.gz -cd libepoxy-1.5.10 - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Degl=no -Dtests=false build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - - -wget https://codeload.github.com/GNOME/gtk/tar.gz/refs/tags/3.24.51 -mv 3.24.51 gtk-3.24.51.tar.gz - -tar -xvf gtk-3.24.51.tar.gz - -cd gtk-3.24.51 - -autotools_recursive_regen -mkdir -p build - -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dprint_backends=file -Dintrospection=false -Dx11_backend=true -Dbroadway_backend=true -Dwayland_backend=false -Dcolord=no build - -cd build -meson compile -j$(nproc) - -sudo chmod -R 777 "$1/usr/share/locale" - -DESTDIR="$1" meson install --no-rebuild - -glib-compile-schemas "$1/usr"/share/glib-2.0/schemas - -cd ../../..
\ No newline at end of file diff --git a/tools/pkg/10/mesa-demos/info.txt b/tools/pkg/10/mesa-demos/info.txt deleted file mode 100644 index 45d9c37..0000000 --- a/tools/pkg/10/mesa-demos/info.txt +++ /dev/null @@ -1 +0,0 @@ -mesa-demos
\ No newline at end of file diff --git a/tools/pkg/10/mesa-demos/pkg.sh b/tools/pkg/10/mesa-demos/pkg.sh deleted file mode 100644 index 5ce41ee..0000000 --- a/tools/pkg/10/mesa-demos/pkg.sh +++ /dev/null @@ -1,27 +0,0 @@ - -. ../../pkg-lib.sh - -rm -rf pack - -mkdir -p pack - -cd pack - -wget https://archive.mesa3d.org/demos/mesa-demos-9.0.0.tar.xz -tar -xvf mesa-demos-9.0.0.tar.xz - -cd mesa-demos-9.0.0 - -export CFLAGS="$CFLAGS -D_DEFAULT_SOURCE" - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dgles1=disabled -Dosmesa=disabled -Dlibdrm=disabled -Dx11=enabled -Dwith-system-data-files=true build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -cd ..
\ No newline at end of file diff --git a/tools/pkg/11/other-stuff/info.txt b/tools/pkg/11/other-stuff/info.txt deleted file mode 100644 index e225641..0000000 --- a/tools/pkg/11/other-stuff/info.txt +++ /dev/null @@ -1 +0,0 @@ -other-stuff
\ No newline at end of file diff --git a/tools/pkg/11/other-stuff/pkg.sh b/tools/pkg/11/other-stuff/pkg.sh deleted file mode 100644 index 83dfccd..0000000 --- a/tools/pkg/11/other-stuff/pkg.sh +++ /dev/null @@ -1,33 +0,0 @@ - -. ../../pkg-lib.sh - -mkdir -p "$1/usr/share/gtk-3.0/" -mkdir -p "$1/etc/gtk-3.0" -cp -rf settings.ini "$1/usr/share/gtk-3.0/settings.ini" -cp -rf settings.ini "$1/etc/gtk-3.0/settings.ini" - -rm -rf pack -mkdir -p pack - -cd pack - -fast_install "$1" https://github.com/scop/bash-completion/releases/download/2.17.0/bash-completion-2.17.0.tar.xz - -fast_install "$1" https://www.x.org/releases/individual/xcb/xcb-util-renderutil-0.3.10.tar.gz -fast_install "$1" https://www.x.org/releases/individual/xcb/xcb-util-cursor-0.1.6.tar.gz -fast_install "$1" https://www.x.org/releases/individual/xcb/xcb-util-keysyms-0.4.1.tar.gz -fast_install "$1" https://www.x.org/releases/individual/xcb/xcb-util-wm-0.4.2.tar.gz - - - -fast_install "$1" https://www.x.org/releases/individual/app/xrandr-1.5.2.tar.gz -fast_install "$1" https://www.x.org/releases/individual/app/xdpyinfo-1.3.4.tar.gz - -wget https://github.com/dejavu-fonts/dejavu-fonts/releases/download/version_2_37/dejavu-fonts-ttf-2.37.tar.bz2 -tar -xvf dejavu-fonts-ttf-2.37.tar.bz2 - -cd dejavu-fonts-ttf-2.37 -mkdir -p "$1/usr/share/fonts/truetype/dejavu" -cp -rf ttf/* "$1/usr/share/fonts/truetype/dejavu" - -cd ..
\ No newline at end of file diff --git a/tools/pkg/11/other-stuff/settings.ini b/tools/pkg/11/other-stuff/settings.ini deleted file mode 100644 index 06a485a..0000000 --- a/tools/pkg/11/other-stuff/settings.ini +++ /dev/null @@ -1,2 +0,0 @@ -[Settings] -gtk-font-name = DejaVu Sans 11
\ No newline at end of file diff --git a/tools/pkg/12/i3wm/info.txt b/tools/pkg/12/i3wm/info.txt deleted file mode 100644 index fbb3d90..0000000 --- a/tools/pkg/12/i3wm/info.txt +++ /dev/null @@ -1 +0,0 @@ -i3wm
\ No newline at end of file diff --git a/tools/pkg/12/i3wm/pkg.sh b/tools/pkg/12/i3wm/pkg.sh deleted file mode 100644 index 3251107..0000000 --- a/tools/pkg/12/i3wm/pkg.sh +++ /dev/null @@ -1,88 +0,0 @@ - -# - - -. ../../pkg-lib.sh - -rm -rf pack - -mkdir -p pack - -cd pack - -git clone https://github.com/lloyd/yajl.git --depth=1 - -cd yajl - -mkdir -p "$1/usr/include/yajl/api" - -cp -rf src/*.h "$1/usr/include/yajl" -cp -rf src/api/*.h "$1/usr/include/yajl/" - -cp -rf ../../yajl_version.h "$1/usr/include/yajl/yajl_version.h" - -x86_64-orange-mlibc-gcc -c src/*.c -Isrc - -x86_64-orange-mlibc-ar rcs "$1/usr/lib/libyajl.a" ./*.o - -cp -rf ../../yajl.pc "$1/usr/lib/pkgconfig" - -cd .. - -git clone https://github.com/Airblader/xcb-util-xrm.git --depth=1 -cd xcb-util-xrm - -cp -rf include/xcb_xrm.h "$1/usr/include/xcb" -x86_64-orange-mlibc-gcc -c src/database.c src/entry.c src/match.c src/resource.c src/util.c -Iinclude -Wno-implicit-function-declaration - -x86_64-orange-mlibc-ar rcs "$1/usr/lib/libxcb-xrm.a" database.o entry.o match.o resource.o util.o - -cp -rf ../../xcb-xrm.pc.in "$1/usr/lib/pkgconfig/xcb-xrm.pc" - -cd .. - -wget https://github.com/xkbcommon/libxkbcommon/archive/refs/tags/xkbcommon-1.13.0.tar.gz -tar -xvf xkbcommon-1.13.0.tar.gz - -cd libxkbcommon-xkbcommon-1.13.0 - -mkdir -p build - -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Denable-wayland=false -Denable-x11=true build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -fast_install "$1" http://www.freedesktop.org/software/startup-notification/releases/startup-notification-0.12.tar.gz "lf_cv_sane_realloc=1" - -git clone https://github.com/enki/libev.git --depth=1 -cd libev - -autotools_recursive_regen -./configure --host=x86_64-orange-mlibc --prefix=/usr -make -j$(nproc) -DESTDIR="$1" make install - -cd .. - -wget https://i3wm.org/downloads/i3-4.24.tar.xz -tar -xvf i3-4.24.tar.xz - -cd i3-4.24 - -mkdir -p build - -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -cd ..
\ No newline at end of file diff --git a/tools/pkg/12/i3wm/xcb-xrm.pc.in b/tools/pkg/12/i3wm/xcb-xrm.pc.in deleted file mode 100644 index 8afb94f..0000000 --- a/tools/pkg/12/i3wm/xcb-xrm.pc.in +++ /dev/null @@ -1,13 +0,0 @@ - -prefix=/usr -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include - -Name: XCB XRM library -Description: XCB X resource manager utility functions -Version: 52 -Requires: xcb -Requires.private: xcb-aux -Libs: -L${libdir} -lxcb-xrm -Cflags: -I${includedir} diff --git a/tools/pkg/12/i3wm/yajl.pc b/tools/pkg/12/i3wm/yajl.pc deleted file mode 100644 index f85c9a8..0000000 --- a/tools/pkg/12/i3wm/yajl.pc +++ /dev/null @@ -1,9 +0,0 @@ -prefix=/usr -libdir=/usr/lib -includedir=/usr/include - -Name: Yet Another JSON Library -Description: A Portable JSON parsing and serialization library in ANSI C -Version: old asf -Cflags: -Libs: -L/usr/lib -lyajl
\ No newline at end of file diff --git a/tools/pkg/12/i3wm/yajl_version.h b/tools/pkg/12/i3wm/yajl_version.h deleted file mode 100644 index 0ec9ed1..0000000 --- a/tools/pkg/12/i3wm/yajl_version.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef YAJL_VERSION_H_ -#define YAJL_VERSION_H_ - -#include <yajl/yajl_common.h> - -#define YAJL_VERSION 211 -#ifdef __cplusplus -extern "C" { -#endif - -extern int YAJL_API yajl_version(void); - -#ifdef __cplusplus -} -#endif - -#endif /* YAJL_VERSION_H_ */ - diff --git a/tools/pkg/12/sqlite/info.txt b/tools/pkg/12/sqlite/info.txt deleted file mode 100644 index a53f8aa..0000000 --- a/tools/pkg/12/sqlite/info.txt +++ /dev/null @@ -1 +0,0 @@ -sqlite3
\ No newline at end of file diff --git a/tools/pkg/12/sqlite/pkg.sh b/tools/pkg/12/sqlite/pkg.sh deleted file mode 100644 index 76b38e9..0000000 --- a/tools/pkg/12/sqlite/pkg.sh +++ /dev/null @@ -1,19 +0,0 @@ - -. ../../pkg-lib.sh - -rm -rf pack -mkdir -p pack -cd pack - -fast_install "$1" https://github.com/nghttp2/nghttp2/releases/download/v1.68.0/nghttp2-1.68.0.tar.gz - -wget https://github.com/sqlite/sqlite/archive/refs/tags/version-3.51.1.tar.gz -tar -xvf version-3.51.1.tar.gz -cd sqlite-version-3.51.1 -autotools_recursive_regen -./configure --prefix=/usr --host=x86_64-orange-mlibc --sysconfdir=/etc --localstatedir=/var --bindir=/usr/bin --sbindir=/usr/bin --libdir=/usr/lib --soname=legacy --disable-static --enable-shared --enable-fts4 --enable-fts5 --disable-tcl -make -j$(nproc) -make install DESTDIR="$1" -cd .. - -cd ..
\ No newline at end of file diff --git a/tools/pkg/12/xinerama/info.txt b/tools/pkg/12/xinerama/info.txt deleted file mode 100644 index bebedba..0000000 --- a/tools/pkg/12/xinerama/info.txt +++ /dev/null @@ -1 +0,0 @@ -xinerama
\ No newline at end of file diff --git a/tools/pkg/12/xinerama/pkg.sh b/tools/pkg/12/xinerama/pkg.sh deleted file mode 100644 index 35f92ba..0000000 --- a/tools/pkg/12/xinerama/pkg.sh +++ /dev/null @@ -1,15 +0,0 @@ - -# - -# https://archive.xfce.org/src/xfce/xfwm4/4.19/xfwm4-4.19.0.tar.bz2 - - -. ../../pkg-lib.sh - -rm -rf pack -mkdir -p pack -cd pack - -fast_install "$1" https://www.x.org/releases/individual/lib/libXinerama-1.1.5.tar.gz - -cd ..
\ No newline at end of file diff --git a/tools/pkg/13/dbus_test/a.out b/tools/pkg/13/dbus_test/a.out Binary files differdeleted file mode 100755 index 288dd23..0000000 --- a/tools/pkg/13/dbus_test/a.out +++ /dev/null diff --git a/tools/pkg/13/dbus_test/info.txt b/tools/pkg/13/dbus_test/info.txt deleted file mode 100644 index 033a0ca..0000000 --- a/tools/pkg/13/dbus_test/info.txt +++ /dev/null @@ -1 +0,0 @@ -dbus_test
\ No newline at end of file diff --git a/tools/pkg/13/dbus_test/main.c b/tools/pkg/13/dbus_test/main.c deleted file mode 100644 index bcbbc2f..0000000 --- a/tools/pkg/13/dbus_test/main.c +++ /dev/null @@ -1,72 +0,0 @@ -#include <dbus/dbus.h> -#include <stdio.h> -#include <stdlib.h> - -int main() { - DBusConnection *conn; - DBusError err; - DBusMessage *msg; - DBusMessage *reply; - DBusError err_reply; - - // Инициализация ошибок - dbus_error_init(&err); - dbus_error_init(&err_reply); - - // Получение соединения с сеансовым bus - int b = 0; - printf("breakpoint %d\n",b++); - conn = dbus_bus_get(DBUS_BUS_SESSION, &err); - printf("breakpoint %d\n",b++); - - if (dbus_error_is_set(&err)) { - fprintf(stderr, "Connection Error (%s)\n", err.message); - dbus_error_free(&err); - return 1; - } - printf("breakpoint %d\n",b++); - if (NULL == conn) { - fprintf(stderr, "Failed to connect to the D-Bus session bus\n"); - return 1; - } - printf("breakpoint %d\n",b++); - // Создаём сообщение для вызова метода - msg = dbus_message_new_method_call( - "com.example.Hello", // название сервиса - "/com/example/HelloObject", // объект - "com.example.Hello", // интерфейс - "SayHello" // метод - ); - printf("breakpoint %d\n",b++); - - if (NULL == msg) { - fprintf(stderr, "Message Null\n"); - return 1; - } - printf("breakpoint %d\n",b++); - // Отправка сообщения и ожидание ответа - reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); - printf("breakpoint %d\n",b++); - dbus_message_unref(msg); - printf("breakpoint %d\n",b++); - if (dbus_error_is_set(&err)) { - fprintf(stderr, "Error in method call: %s\n", err.message); - dbus_error_free(&err); - return 1; - } - printf("breakpoint %d\n",b++); - // Получение строки из ответа - const char *reply_str; - if (dbus_message_get_args(reply, &err, - DBUS_TYPE_STRING, &reply_str, - DBUS_TYPE_INVALID)) { - printf("Response: %s\n", reply_str); - } else { - fprintf(stderr, "Failed to get args: %s\n", err.message); - dbus_error_free(&err); - return 1; - } - printf("breakpoint %d\n",b++); - dbus_message_unref(reply); - return 0; -}
\ No newline at end of file diff --git a/tools/pkg/13/dbus_test/pkg.sh b/tools/pkg/13/dbus_test/pkg.sh deleted file mode 100644 index 91ce4cf..0000000 --- a/tools/pkg/13/dbus_test/pkg.sh +++ /dev/null @@ -1 +0,0 @@ -x86_64-orange-mlibc-g++ -o "$1/usr/bin/dbus_test" main.c -fPIC $(x86_64-orange-mlibc-pkg-config --cflags --libs dbus-1)
\ No newline at end of file diff --git a/tools/pkg/13/libsoup/info.txt b/tools/pkg/13/libsoup/info.txt deleted file mode 100644 index ed1af3c..0000000 --- a/tools/pkg/13/libsoup/info.txt +++ /dev/null @@ -1 +0,0 @@ -libsoup
\ No newline at end of file diff --git a/tools/pkg/13/libsoup/libsoup-2.4.pc b/tools/pkg/13/libsoup/libsoup-2.4.pc deleted file mode 100644 index c8e6bf8..0000000 --- a/tools/pkg/13/libsoup/libsoup-2.4.pc +++ /dev/null @@ -1,14 +0,0 @@ -prefix=/usr -includedir=${prefix}/include -libdir=${prefix}/lib - -exec_prefix=${prefix} - -Name: libsoup -Description: A glib-based HTTP library -Version: 2.40.0 -Requires: glib-2.0 >= 2.70.0, gmodule-no-export-2.0 >= 2.70.0, gobject-2.0 >= 2.70.0, gio-2.0 >= 2.70.0 -Requires.private: sqlite3, libpsl >= 0.20, zlib, libnghttp2 -Libs: -L${libdir} -lsoup-3.0 -Libs.private: -ldl -Cflags: -I${includedir}/libsoup-3.0 diff --git a/tools/pkg/13/libsoup/pkg.sh b/tools/pkg/13/libsoup/pkg.sh deleted file mode 100644 index 949062e..0000000 --- a/tools/pkg/13/libsoup/pkg.sh +++ /dev/null @@ -1,23 +0,0 @@ - -. ../../pkg-lib.sh - -rm -rf pack -mkdir -p pack -cd pack - -fast_install "$1" https://github.com/rockdaboot/libpsl/releases/download/0.21.5/libpsl-0.21.5.tar.gz - -wget https://mirrors.dotsrc.org/gnome/sources/libsoup/2.74/libsoup-2.74.0.tar.xz -tar -xvf libsoup-2.74.0.tar.xz -cd libsoup-2.74.0 -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dvapi=disabled -Dintrospection=disabled -Dgssapi=disabled -Dsysprof=disabled -Dtls_check=false build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -cd ..
\ No newline at end of file diff --git a/tools/pkg/13/xfwm/info.txt b/tools/pkg/13/xfwm/info.txt deleted file mode 100644 index 88b5565..0000000 --- a/tools/pkg/13/xfwm/info.txt +++ /dev/null @@ -1 +0,0 @@ -xfwm
\ No newline at end of file diff --git a/tools/pkg/13/xfwm/pkg.sh b/tools/pkg/13/xfwm/pkg.sh deleted file mode 100644 index 8bfc6f6..0000000 --- a/tools/pkg/13/xfwm/pkg.sh +++ /dev/null @@ -1,61 +0,0 @@ - -# https://archive.xfce.org/src/xfce/xfwm4/4.19/xfwm4-4.19.0.tar.bz2 - - -. ../../pkg-lib.sh - -rm -rf pack -mkdir -p pack -cd pack - -fast_install "$1" https://archive.xfce.org/src/xfce/libxfce4util/4.19/libxfce4util-4.19.0.tar.bz2 "--disable-shared --enable-static --disable-introspection" -fast_install "$1" https://archive.xfce.org/src/xfce/xfconf/4.19/xfconf-4.19.0.tar.bz2 "--disable-introspection" -fast_install "$1" https://archive.xfce.org/src/xfce/libxfce4ui/4.19/libxfce4ui-4.19.0.tar.bz2 "--disable-introspection" - -# why not to compile libwnck-4 -git clone https://gitlab.gnome.org/GNOME/libwnck.git --depth=1 -cd libwnck - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dintrospection=disabled build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -# now compile libwnck-3 -wget https://github.com/GNOME/libwnck/archive/refs/tags/3.36.0.tar.gz -tar -xvf 3.36.0.tar.gz -cd libwnck-3.36.0 - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dintrospection=disabled build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -fast_install "$1" https://archive.xfce.org/src/xfce/xfwm4/4.19/xfwm4-4.19.0.tar.bz2 "--disable-introspection" - - -wget https://gitlab.freedesktop.org/xdg/shared-mime-info/-/archive/2.4/shared-mime-info-2.4.tar.gz -tar -xvf shared-mime-info-2.4.tar.gz -cd shared-mime-info-2.4 - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -cd ..
\ No newline at end of file diff --git a/tools/pkg/14/mate/diff/marco.diff b/tools/pkg/14/mate/diff/marco.diff deleted file mode 100644 index e9b0ebc..0000000 --- a/tools/pkg/14/mate/diff/marco.diff +++ /dev/null @@ -1,26 +0,0 @@ -diff --git marco-clean/meson.build marco-workdir/meson.build -index 7c7467b..8e803cb 100644 ---- marco-clean/meson.build -+++ marco-workdir/meson.build -@@ -294,7 +294,7 @@ if get_option('sm') and sm_dep.found() and ice_dep.found() - endif - - gdk_pixbuf_csource = find_program('gdk-pixbuf-csource') --zenity = find_program('zenity') -+# zenity = find_program('zenity') - - libxext = cc.find_library('Xext', required: false) - if build_xsync -diff --git marco-clean/src/core/util.c marco-workdir/src/core/util.c -index baf485a..e9fad4f 100644 ---- marco-clean/src/core/util.c -+++ marco-workdir/src/core/util.c -@@ -39,7 +39,7 @@ - #include <X11/Xlib.h> /* must explicitly be included for Solaris; #326746 */ - #include <X11/Xutil.h> /* Just for the definition of the various gravities */ - --#ifdef HAVE_BACKTRACE -+#if defined(HAVE_BACKTRACE) && !defined(__mlibc__) - #include <execinfo.h> - void - meta_print_backtrace (void) diff --git a/tools/pkg/14/mate/diff/mate-themes.diff b/tools/pkg/14/mate/diff/mate-themes.diff deleted file mode 100644 index 9946d65..0000000 --- a/tools/pkg/14/mate/diff/mate-themes.diff +++ /dev/null @@ -1,191 +0,0 @@ -diff --git mate-themes-clean/configure mate-themes-workdir/configure -index 05c35ee..a3985d0 100755 ---- mate-themes-clean/configure -+++ mate-themes-workdir/configure -@@ -7176,96 +7176,96 @@ ACLOCAL_AMFLAGS="\${ACLOCAL_FLAGS}" - - # Check GTK+ theme engines - --pkg_failed=no --{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 " >&5 --printf %s "checking for gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 ... " >&6; } -- --if test -n "$THEME_ENGINE_CFLAGS"; then -- pkg_cv_THEME_ENGINE_CFLAGS="$THEME_ENGINE_CFLAGS" -- elif test -n "$PKG_CONFIG"; then -- if test -n "$PKG_CONFIG" && \ -- { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 \""; } >&5 -- ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 ") 2>&5 -- ac_status=$? -- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; }; then -- pkg_cv_THEME_ENGINE_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 " 2>/dev/null` -- test "x$?" != "x0" && pkg_failed=yes --else -- pkg_failed=yes --fi -- else -- pkg_failed=untried --fi --if test -n "$THEME_ENGINE_LIBS"; then -- pkg_cv_THEME_ENGINE_LIBS="$THEME_ENGINE_LIBS" -- elif test -n "$PKG_CONFIG"; then -- if test -n "$PKG_CONFIG" && \ -- { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 \""; } >&5 -- ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 ") 2>&5 -- ac_status=$? -- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; }; then -- pkg_cv_THEME_ENGINE_LIBS=`$PKG_CONFIG --libs "gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 " 2>/dev/null` -- test "x$?" != "x0" && pkg_failed=yes --else -- pkg_failed=yes --fi -- else -- pkg_failed=untried --fi -- -- -- --if test $pkg_failed = yes; then -- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 --printf "%s\n" "no" >&6; } -- --if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then -- _pkg_short_errors_supported=yes --else -- _pkg_short_errors_supported=no --fi -- if test $_pkg_short_errors_supported = yes; then -- THEME_ENGINE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 " 2>&1` -- else -- THEME_ENGINE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 " 2>&1` -- fi -- # Put the nasty error message in config.log where it belongs -- echo "$THEME_ENGINE_PKG_ERRORS" >&5 -- -- as_fn_error $? "Package requirements (gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 ) were not met: -- --$THEME_ENGINE_PKG_ERRORS -- --Consider adjusting the PKG_CONFIG_PATH environment variable if you --installed software in a non-standard prefix. -- --Alternatively, you may set the environment variables THEME_ENGINE_CFLAGS --and THEME_ENGINE_LIBS to avoid the need to call pkg-config. --See the pkg-config man page for more details." "$LINENO" 5 --elif test $pkg_failed = untried; then -- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 --printf "%s\n" "no" >&6; } -- { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 --printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it --is in your PATH or set the PKG_CONFIG environment variable to the full --path to pkg-config. -- --Alternatively, you may set the environment variables THEME_ENGINE_CFLAGS --and THEME_ENGINE_LIBS to avoid the need to call pkg-config. --See the pkg-config man page for more details. -- --To get pkg-config, see <http://pkg-config.freedesktop.org/>. --See \`config.log' for more details" "$LINENO" 5; } --else -- THEME_ENGINE_CFLAGS=$pkg_cv_THEME_ENGINE_CFLAGS -- THEME_ENGINE_LIBS=$pkg_cv_THEME_ENGINE_LIBS -- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 --printf "%s\n" "yes" >&6; } -- --fi -+# pkg_failed=no -+# { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 " >&5 -+# printf %s "checking for gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 ... " >&6; } -+ -+# if test -n "$THEME_ENGINE_CFLAGS"; then -+# pkg_cv_THEME_ENGINE_CFLAGS="$THEME_ENGINE_CFLAGS" -+# elif test -n "$PKG_CONFIG"; then -+# if test -n "$PKG_CONFIG" && \ -+# { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 \""; } >&5 -+# ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 ") 2>&5 -+# ac_status=$? -+# printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+# test $ac_status = 0; }; then -+# pkg_cv_THEME_ENGINE_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 " 2>/dev/null` -+# test "x$?" != "x0" && pkg_failed=yes -+# else -+# pkg_failed=yes -+# fi -+# else -+# pkg_failed=untried -+# fi -+# if test -n "$THEME_ENGINE_LIBS"; then -+# pkg_cv_THEME_ENGINE_LIBS="$THEME_ENGINE_LIBS" -+# elif test -n "$PKG_CONFIG"; then -+# if test -n "$PKG_CONFIG" && \ -+# { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 \""; } >&5 -+# ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 ") 2>&5 -+# ac_status=$? -+# printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+# test $ac_status = 0; }; then -+# pkg_cv_THEME_ENGINE_LIBS=`$PKG_CONFIG --libs "gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 " 2>/dev/null` -+# test "x$?" != "x0" && pkg_failed=yes -+# else -+# pkg_failed=yes -+# fi -+# else -+# pkg_failed=untried -+# fi -+ -+ -+ -+# if test $pkg_failed = yes; then -+# { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+# printf "%s\n" "no" >&6; } -+ -+# if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then -+# _pkg_short_errors_supported=yes -+# else -+# _pkg_short_errors_supported=no -+# fi -+# if test $_pkg_short_errors_supported = yes; then -+# THEME_ENGINE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 " 2>&1` -+# else -+# THEME_ENGINE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 " 2>&1` -+# fi -+# # Put the nasty error message in config.log where it belongs -+# echo "$THEME_ENGINE_PKG_ERRORS" >&5 -+ -+# as_fn_error $? "Package requirements (gtk+-2.0 >= 2.0.0 gdk-pixbuf-2.0 >= 2.0.0 ) were not met: -+ -+# $THEME_ENGINE_PKG_ERRORS -+ -+# Consider adjusting the PKG_CONFIG_PATH environment variable if you -+# installed software in a non-standard prefix. -+ -+# Alternatively, you may set the environment variables THEME_ENGINE_CFLAGS -+# and THEME_ENGINE_LIBS to avoid the need to call pkg-config. -+# See the pkg-config man page for more details." "$LINENO" 5 -+# elif test $pkg_failed = untried; then -+# { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+# printf "%s\n" "no" >&6; } -+# { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -+# printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -+# as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -+# is in your PATH or set the PKG_CONFIG environment variable to the full -+# path to pkg-config. -+ -+# Alternatively, you may set the environment variables THEME_ENGINE_CFLAGS -+# and THEME_ENGINE_LIBS to avoid the need to call pkg-config. -+# See the pkg-config man page for more details. -+ -+# To get pkg-config, see <http://pkg-config.freedesktop.org/>. -+# See \`config.log' for more details" "$LINENO" 5; } -+# else -+# THEME_ENGINE_CFLAGS=$pkg_cv_THEME_ENGINE_CFLAGS -+# THEME_ENGINE_LIBS=$pkg_cv_THEME_ENGINE_LIBS -+# { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+# printf "%s\n" "yes" >&6; } -+ -+# fi - - ac_config_files="$ac_config_files Makefile cursor-themes/Makefile cursor-themes/mate-white/Makefile cursor-themes/mate-white/cursors/Makefile cursor-themes/mate-black/Makefile cursor-themes/mate-black/cursors/Makefile desktop-themes/Makefile desktop-themes/BlackMATE/Makefile desktop-themes/BlackMATE/apps/Makefile desktop-themes/BlackMATE/gtk-2.0/Makefile desktop-themes/BlackMATE/gtk-2.0/assets/Makefile desktop-themes/BlackMATE/gtk-2.0/Styles/Makefile desktop-themes/BlackMATE/gtk-3.0/Makefile desktop-themes/BlackMATE/gtk-3.0/assets/Makefile desktop-themes/BlackMATE/gtk-3.0/window-controls/Makefile desktop-themes/BlackMATE/metacity-1/Makefile desktop-themes/BlackMATE/cinnamon/Makefile desktop-themes/BlackMATE/unity/Makefile desktop-themes/BlackMATE-border/Makefile desktop-themes/BlackMATE-border/metacity-1/Makefile desktop-themes/BlueMenta/Makefile desktop-themes/BlueMenta/cinnamon/Makefile desktop-themes/BlueMenta/emerald/Makefile desktop-themes/BlueMenta/gtk-2.0/Makefile desktop-themes/BlueMenta/gtk-2.0/apps/Makefile desktop-themes/BlueMenta/gtk-2.0/apps/Caja/Makefile desktop-themes/BlueMenta/gtk-2.0/apps/Handles/Makefile desktop-themes/BlueMenta/gtk-2.0/apps/Null/Makefile desktop-themes/BlueMenta/gtk-2.0/apps/Others/Makefile desktop-themes/BlueMenta/gtk-2.0/widgets/Makefile desktop-themes/BlueMenta/gtk-2.0/widgets/Null/Makefile desktop-themes/BlueMenta/gtk-2.0/widgets/Others/Makefile desktop-themes/BlueMenta/gtk-2.0/widgets/Panel/Makefile desktop-themes/BlueMenta/gtk-2.0/widgets/Scale/Makefile desktop-themes/BlueMenta/gtk-3.0/Makefile desktop-themes/BlueMenta/gtk-3.0/assets/Makefile desktop-themes/BlueMenta/gtk-3.0/borders/Makefile desktop-themes/BlueMenta/gtk-3.0/window-controls/Makefile desktop-themes/BlueMenta/metacity-1/Makefile desktop-themes/BlueMenta/unity/Makefile desktop-themes/BlueMenta/xfwm4/Makefile desktop-themes/BlueMenta-border/Makefile desktop-themes/BlueMenta-border/metacity-1/Makefile desktop-themes/Blue-Submarine/Makefile desktop-themes/Blue-Submarine/cinnamon/Makefile desktop-themes/Blue-Submarine/emerald/Makefile desktop-themes/Blue-Submarine/gtk-2.0/Makefile desktop-themes/Blue-Submarine/gtk-2.0/apps/Makefile desktop-themes/Blue-Submarine/gtk-2.0/apps/Handles/Makefile desktop-themes/Blue-Submarine/gtk-2.0/apps/Panel/Makefile desktop-themes/Blue-Submarine/gtk-2.0/assets/Makefile desktop-themes/Blue-Submarine/gtk-3.0/Makefile desktop-themes/Blue-Submarine/gtk-3.0/assets/Makefile desktop-themes/Blue-Submarine/metacity-1/Makefile desktop-themes/Blue-Submarine-border/Makefile desktop-themes/Blue-Submarine-border/metacity-1/Makefile desktop-themes/ContrastHigh/Makefile desktop-themes/GreenLaguna/Makefile desktop-themes/GreenLaguna/gtk-2.0/Makefile desktop-themes/GreenLaguna/gtk-2.0/Styles/Makefile desktop-themes/GreenLaguna/gtk-3.0/Makefile desktop-themes/GreenLaguna/gtk-3.0/assets/Makefile desktop-themes/GreenLaguna/gtk-3.0/window-controls/Makefile desktop-themes/GreenLaguna/metacity-1/Makefile desktop-themes/GreenLaguna/unity/Makefile desktop-themes/GreenLaguna-border/Makefile desktop-themes/GreenLaguna-border/metacity-1/Makefile desktop-themes/Green-Submarine/Makefile desktop-themes/Green-Submarine/cinnamon/Makefile desktop-themes/Green-Submarine/emerald/Makefile desktop-themes/Green-Submarine/gtk-2.0/Makefile desktop-themes/Green-Submarine/gtk-2.0/apps/Makefile desktop-themes/Green-Submarine/gtk-2.0/apps/Handles/Makefile desktop-themes/Green-Submarine/gtk-2.0/apps/Panel/Makefile desktop-themes/Green-Submarine/gtk-2.0/assets/Makefile desktop-themes/Green-Submarine/gtk-3.0/Makefile desktop-themes/Green-Submarine/gtk-3.0/assets/Makefile desktop-themes/Green-Submarine/metacity-1/Makefile desktop-themes/Green-Submarine-border/Makefile desktop-themes/Green-Submarine-border/metacity-1/Makefile desktop-themes/HighContrastInverse/Makefile desktop-themes/HighContrastInverse/gtk-2.0/Makefile desktop-themes/HighContrastInverse/gtk-2.0/gtkrc desktop-themes/HighContrastInverse/metacity-1/Makefile desktop-themes/HighContrastInverse/pixmaps/Makefile desktop-themes/Menta/Makefile desktop-themes/Menta/cinnamon/Makefile desktop-themes/Menta/emerald/Makefile desktop-themes/Menta/gtk-2.0/Makefile desktop-themes/Menta/gtk-2.0/apps/Makefile desktop-themes/Menta/gtk-2.0/apps/Caja/Makefile desktop-themes/Menta/gtk-2.0/apps/Handles/Makefile desktop-themes/Menta/gtk-2.0/apps/Null/Makefile desktop-themes/Menta/gtk-2.0/apps/Others/Makefile desktop-themes/Menta/gtk-2.0/widgets/Makefile desktop-themes/Menta/gtk-2.0/widgets/Null/Makefile desktop-themes/Menta/gtk-2.0/widgets/Others/Makefile desktop-themes/Menta/gtk-2.0/widgets/Panel/Makefile desktop-themes/Menta/gtk-2.0/widgets/Scale/Makefile desktop-themes/Menta/gtk-3.0/Makefile desktop-themes/Menta/gtk-3.0/assets/Makefile desktop-themes/Menta/gtk-3.0/borders/Makefile desktop-themes/Menta/gtk-3.0/window-controls/Makefile desktop-themes/Menta/metacity-1/Makefile desktop-themes/Menta/unity/Makefile desktop-themes/Menta/xfwm4/Makefile desktop-themes/Menta-border/Makefile desktop-themes/Menta-border/metacity-1/Makefile desktop-themes/TraditionalGreen/Makefile desktop-themes/TraditionalGreen/gtk-2.0/Makefile desktop-themes/TraditionalGreen/gtk-3.0/Makefile desktop-themes/TraditionalGreen/gtk-3.0/img/Makefile desktop-themes/TraditionalGreen/metacity-1/Makefile desktop-themes/TraditionalOk/Makefile desktop-themes/TraditionalOk/gtk-2.0/Makefile desktop-themes/TraditionalOk/gtk-3.0/Makefile desktop-themes/TraditionalOk/gtk-3.0/img/Makefile desktop-themes/TraditionalOk/metacity-1/Makefile desktop-themes/TraditionalOk/openbox-3/Makefile desktop-themes/TraditionalOk/xfwm4/Makefile desktop-themes/TraditionalOk/xfwm4/png/Makefile desktop-themes/YaruOk/Makefile desktop-themes/YaruOk/gtk-2.0/Makefile desktop-themes/YaruOk/gtk-3.0/Makefile desktop-themes/YaruOk/gtk-3.0/assets/Makefile desktop-themes/YaruOk/metacity-1/Makefile desktop-themes/YaruOk/openbox-3/Makefile desktop-themes/YaruOk/xfwm4/Makefile desktop-themes/YaruOk/xfwm4/png/Makefile desktop-themes/YaruGreen/Makefile desktop-themes/YaruGreen/gtk-2.0/Makefile desktop-themes/YaruGreen/gtk-3.0/Makefile desktop-themes/YaruGreen/gtk-3.0/assets/Makefile desktop-themes/YaruGreen/metacity-1/Makefile marco-themes/Makefile icon-themes/Makefile icon-themes/ContrastHigh/Makefile icon-themes/ContrastHigh/16x16/Makefile icon-themes/ContrastHigh/16x16/actions/Makefile icon-themes/ContrastHigh/16x16/apps/Makefile icon-themes/ContrastHigh/16x16/categories/Makefile icon-themes/ContrastHigh/16x16/devices/Makefile icon-themes/ContrastHigh/16x16/emblems/Makefile icon-themes/ContrastHigh/16x16/emotes/Makefile icon-themes/ContrastHigh/16x16/mimetypes/Makefile icon-themes/ContrastHigh/16x16/places/Makefile icon-themes/ContrastHigh/16x16/status/Makefile icon-themes/ContrastHigh/16x16/stock/Makefile icon-themes/ContrastHigh/22x22/Makefile icon-themes/ContrastHigh/22x22/actions/Makefile icon-themes/ContrastHigh/22x22/apps/Makefile icon-themes/ContrastHigh/22x22/categories/Makefile icon-themes/ContrastHigh/22x22/devices/Makefile icon-themes/ContrastHigh/22x22/emblems/Makefile icon-themes/ContrastHigh/22x22/emotes/Makefile icon-themes/ContrastHigh/22x22/mimetypes/Makefile icon-themes/ContrastHigh/22x22/places/Makefile icon-themes/ContrastHigh/22x22/status/Makefile icon-themes/ContrastHigh/22x22/stock/Makefile icon-themes/ContrastHigh/24x24/Makefile icon-themes/ContrastHigh/24x24/actions/Makefile icon-themes/ContrastHigh/24x24/apps/Makefile icon-themes/ContrastHigh/24x24/categories/Makefile icon-themes/ContrastHigh/24x24/devices/Makefile icon-themes/ContrastHigh/24x24/emblems/Makefile icon-themes/ContrastHigh/24x24/emotes/Makefile icon-themes/ContrastHigh/24x24/mimetypes/Makefile icon-themes/ContrastHigh/24x24/places/Makefile icon-themes/ContrastHigh/24x24/status/Makefile icon-themes/ContrastHigh/24x24/stock/Makefile icon-themes/ContrastHigh/32x32/Makefile icon-themes/ContrastHigh/32x32/actions/Makefile icon-themes/ContrastHigh/32x32/apps/Makefile icon-themes/ContrastHigh/32x32/categories/Makefile icon-themes/ContrastHigh/32x32/devices/Makefile icon-themes/ContrastHigh/32x32/emblems/Makefile icon-themes/ContrastHigh/32x32/emotes/Makefile icon-themes/ContrastHigh/32x32/mimetypes/Makefile icon-themes/ContrastHigh/32x32/places/Makefile icon-themes/ContrastHigh/32x32/status/Makefile icon-themes/ContrastHigh/32x32/stock/Makefile icon-themes/ContrastHigh/48x48/Makefile icon-themes/ContrastHigh/48x48/actions/Makefile icon-themes/ContrastHigh/48x48/animations/Makefile icon-themes/ContrastHigh/48x48/apps/Makefile icon-themes/ContrastHigh/48x48/categories/Makefile icon-themes/ContrastHigh/48x48/devices/Makefile icon-themes/ContrastHigh/48x48/emblems/Makefile icon-themes/ContrastHigh/48x48/emotes/Makefile icon-themes/ContrastHigh/48x48/mimetypes/Makefile icon-themes/ContrastHigh/48x48/places/Makefile icon-themes/ContrastHigh/48x48/status/Makefile icon-themes/ContrastHigh/48x48/stock/Makefile icon-themes/ContrastHigh/256x256/Makefile icon-themes/ContrastHigh/256x256/actions/Makefile icon-themes/ContrastHigh/256x256/apps/Makefile icon-themes/ContrastHigh/256x256/categories/Makefile icon-themes/ContrastHigh/256x256/devices/Makefile icon-themes/ContrastHigh/256x256/emblems/Makefile icon-themes/ContrastHigh/256x256/emotes/Makefile icon-themes/ContrastHigh/256x256/mimetypes/Makefile icon-themes/ContrastHigh/256x256/places/Makefile icon-themes/ContrastHigh/256x256/status/Makefile icon-themes/ContrastHigh/256x256/stock/Makefile icon-themes/ContrastHigh/scalable/Makefile icon-themes/ContrastHigh/scalable/actions/Makefile icon-themes/ContrastHigh/scalable/actions-extra/Makefile icon-themes/ContrastHigh/scalable/apps/Makefile icon-themes/ContrastHigh/scalable/apps-extra/Makefile icon-themes/ContrastHigh/scalable/categories/Makefile icon-themes/ContrastHigh/scalable/devices/Makefile icon-themes/ContrastHigh/scalable/emblems/Makefile icon-themes/ContrastHigh/scalable/mimetypes/Makefile icon-themes/ContrastHigh/scalable/places/Makefile icon-themes/ContrastHigh/scalable/places-extra/Makefile icon-themes/ContrastHigh/scalable/status/Makefile icon-themes/ContrastHigh/scalable/status-extra/Makefile po/Makefile.in" - diff --git a/tools/pkg/14/mate/info.txt b/tools/pkg/14/mate/info.txt deleted file mode 100644 index af75450..0000000 --- a/tools/pkg/14/mate/info.txt +++ /dev/null @@ -1 +0,0 @@ -mate
\ No newline at end of file diff --git a/tools/pkg/14/mate/pkg.sh b/tools/pkg/14/mate/pkg.sh deleted file mode 100644 index 982c06d..0000000 --- a/tools/pkg/14/mate/pkg.sh +++ /dev/null @@ -1,87 +0,0 @@ - -# https://archive.xfce.org/src/xfce/xfwm4/4.19/xfwm4-4.19.0.tar.bz2 - - -. ../../pkg-lib.sh - -rm -rf pack -mkdir -p pack -cd pack - -# wget https://archive.fr.xfce.org/src/xfce/libxfce4ui/4.21/libxfce4ui-4.21.3.tar.xz -# tar -xvf libxfce4ui-4.21.3.tar.xz -# cd libxfce4ui-4.21.3 - -# mkdir build -# meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dintrospection=false build - -# cd build - -# meson compile -j$(nproc) -# DESTDIR="$1" meson install --no-rebuild - -# cd ../.. - -git clone https://gitlab.gnome.org/GNOME/dconf.git --depth=1 --recursive -cd dconf - -sed -i 's/install_dir: systemd_userunitdir,//' service/meson.build - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dvapi=false build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild -cd ../.. - - -fast_install "$1" https://downloads.xiph.org/releases/ogg/libogg-1.3.6.tar.xz -fast_install "$1" https://downloads.xiph.org/releases/vorbis/libvorbis-1.3.7.tar.xz -fast_install "$1" https://github.com/Distrotech/libcanberra/archive/refs/tags/v0.30.tar.gz "--disable-oss --disable-gtk --disable-gstreamer --disable-pulse --disable-alsa" -fast_install "$1" https://salsa.debian.org/iso-codes-team/iso-codes/-/archive/v4.19.0/iso-codes-v4.19.0.tar.gz -fast_install "$1" https://www.x.org/releases/individual/lib/libXres-1.2.3.tar.gz -fast_install "$1" https://github.com/mate-desktop/mate-desktop/releases/download/v1.28.2/mate-desktop-1.28.2.tar.xz "--disable-introspection" -export CFLAGS="-lXRes -O2" - -wget https://github.com/GNOME/libwnck/archive/refs/tags/43.0.tar.gz -tar -xvf 43.0.tar.gz -cd libwnck-43.0 - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dintrospection=disabled build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -git clone https://gitlab.gnome.org/GNOME/libnotify.git -cd libnotify -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dintrospection=disabled -Dtests=false -Dgtk_doc=false build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -fast_install "$1" https://github.com/mate-desktop/marco/releases/download/v1.29.1/marco-1.29.1.tar.xz "--disable-compositor --disable-introspection" "../../diff/marco.diff" -fast_install "$1" https://github.com/mate-desktop/mate-themes/releases/download/v3.22.26/mate-themes-3.22.26.tar.xz "--enable-shared" "../../diff/mate-themes.diff" - -fast_install "$1" https://github.com/mate-desktop/libmateweather/releases/download/v1.28.0/libmateweather-1.28.0.tar.xz "--enable-locations-compression --disable-all-translations-in-one-xml --disable-icon-update" -fast_install "$1" https://github.com/mate-desktop/mate-menus/releases/download/v1.28.1/mate-menus-1.28.1.tar.xz "--disable-introspection" -fast_install "$1" https://github.com/mate-desktop/mate-panel/releases/download/v1.28.7/mate-panel-1.28.7.tar.xz "--disable-introspection" -fast_install "$1" https://github.com/mate-desktop/caja/releases/download/v1.28.0/caja-1.28.0.tar.xz "--disable-update-mimedb --disable-xmp --without-libnotify --enable-introspection=no" -glib-compile-schemas "$1/usr"/share/glib-2.0/schemas - -fast_install "$1" https://people.freedesktop.org/~svu/libxklavier-5.4.tar.bz2 "--disable-gtk-doc --disable-introspection --disable-vala --with-xkb-base=/usr/share/X11/xkb --with-xkb-bin-base=/usr/bin" -fast_install "$1" https://github.com/mate-desktop/libmatekbd/releases/download/v1.28.0/libmatekbd-1.28.0.tar.xz "--with-x --disable-introspection --without-tests" -fast_install "$1" https://github.com/mate-desktop/mate-settings-daemon/releases/download/v1.28.0/mate-settings-daemon-1.28.0.tar.xz " --with-x --without-libnotify --with-libcanberra --without-libmatemixer --disable-debug --disable-polkit --disable-pulse --disable-rfkill --disable-smartcard-support" - -cd ..
\ No newline at end of file diff --git a/tools/pkg/14/xfce4-panel/info.txt b/tools/pkg/14/xfce4-panel/info.txt deleted file mode 100644 index 36ca0ab..0000000 --- a/tools/pkg/14/xfce4-panel/info.txt +++ /dev/null @@ -1 +0,0 @@ -xfce4-panel
\ No newline at end of file diff --git a/tools/pkg/14/xfce4-panel/pkg.sh b/tools/pkg/14/xfce4-panel/pkg.sh deleted file mode 100644 index 5274e82..0000000 --- a/tools/pkg/14/xfce4-panel/pkg.sh +++ /dev/null @@ -1,71 +0,0 @@ - -# https://archive.xfce.org/src/xfce/xfwm4/4.19/xfwm4-4.19.0.tar.bz2 - - -. ../../pkg-lib.sh - -rm -rf pack -mkdir -p pack -cd pack - -wget https://archive.fr.xfce.org/src/xfce/libxfce4ui/4.21/libxfce4ui-4.21.3.tar.xz -tar -xvf libxfce4ui-4.21.3.tar.xz -cd libxfce4ui-4.21.3 - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dintrospection=false build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -wget https://archive.xfce.org/src/xfce/garcon/4.21/garcon-4.21.0.tar.xz -tar -xvf garcon-4.21.0.tar.xz -cd garcon-4.21.0 - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dintrospection=false build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -wget https://gitlab.freedesktop.org/emersion/libdisplay-info/-/archive/0.3.0/libdisplay-info-0.3.0.tar.bz2 -tar -xvf libdisplay-info-0.3.0.tar.bz2 -cd libdisplay-info-0.3.0 - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -fast_install "$1" https://archive.xfce.org/src/xfce/libxfce4windowing/4.20/libxfce4windowing-4.20.5.tar.bz2 "--disable-introspection" - -wget https://archive.xfce.org/src/xfce/xfce4-panel/4.21/xfce4-panel-4.21.1.tar.xz -tar -xvf xfce4-panel-4.21.1.tar.xz -cd xfce4-panel-4.21.1 - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dintrospection=false build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -#fast_install "$1" https://archive.xfce.org/src/art/xfwm4-themes/4.10/xfwm4-themes-4.10.0.tar.bz2 "--sysconfdir=/etc" - -cd ..
\ No newline at end of file diff --git a/tools/pkg/15/luau/info.txt b/tools/pkg/15/luau/info.txt deleted file mode 100644 index f3f2587..0000000 --- a/tools/pkg/15/luau/info.txt +++ /dev/null @@ -1 +0,0 @@ -luau
\ No newline at end of file diff --git a/tools/pkg/15/luau/pkg.sh b/tools/pkg/15/luau/pkg.sh deleted file mode 100644 index 67e1b1e..0000000 --- a/tools/pkg/15/luau/pkg.sh +++ /dev/null @@ -1,25 +0,0 @@ - -# my friend asked so why not... -. ../../pkg-lib.sh - -rm -rf pack -mkdir -p pack -cd pack - -git clone https://github.com/luau-lang/luau.git --depth=1 -cd luau - -mkdir -p luau-build -cd luau-build - -export CFLAGS="$CFLAGS -D_XOPEN_SOURCE=700" -export CXXFLAGS="$CXXFLAGS -D_XOPEN_SOURCE=700" - -cmake .. -DCMAKE_TOOLCHAIN_FILE=$(realpath ../../../../../toolchain.cmake) -DCMAKE_INSTALL_PREFIX="$1/usr" - -make -j$(nproc) -cp -rf luau* "$1/usr/bin" -cp -rf libLuau* libisocline.a "$1/usr/lib" -cd .. - -cd ..
\ No newline at end of file diff --git a/tools/pkg/15/mate-session/info.txt b/tools/pkg/15/mate-session/info.txt deleted file mode 100644 index 7901d94..0000000 --- a/tools/pkg/15/mate-session/info.txt +++ /dev/null @@ -1 +0,0 @@ -mate-session
\ No newline at end of file diff --git a/tools/pkg/15/mate-session/pkg.sh b/tools/pkg/15/mate-session/pkg.sh deleted file mode 100644 index 31085b3..0000000 --- a/tools/pkg/15/mate-session/pkg.sh +++ /dev/null @@ -1,17 +0,0 @@ -# - - -# https://archive.xfce.org/src/xfce/xfwm4/4.19/xfwm4-4.19.0.tar.bz2 - - -. ../../pkg-lib.sh - -rm -rf pack -mkdir -p pack -cd pack - -fast_install "$1" https://www.x.org/archive/individual/lib/libXcomposite-0.4.6.tar.gz -fast_install "$1" https://dbus.freedesktop.org/releases/dbus-glib/dbus-glib-0.114.tar.gz "--disable-gtk-doc --with-dbus-binding-tool=dbus-binding-tool" -fast_install "$1" https://github.com/mate-desktop/mate-session-manager/releases/download/v1.28.0/mate-session-manager-1.28.0.tar.xz - -cd ..
\ No newline at end of file diff --git a/tools/pkg/2/dbus_daemon/dbus-start-all.sh b/tools/pkg/2/dbus_daemon/dbus-start-all.sh deleted file mode 100644 index 1920190..0000000 --- a/tools/pkg/2/dbus_daemon/dbus-start-all.sh +++ /dev/null @@ -1,3 +0,0 @@ - -dbus-launch /usr/libexec/at-spi-bus-launcher & -dbus-launch /usr/lib/xfce4/xfconf/xfconfd &
\ No newline at end of file diff --git a/tools/pkg/2/dbus_daemon/info.txt b/tools/pkg/2/dbus_daemon/info.txt deleted file mode 100644 index 7a73bb2..0000000 --- a/tools/pkg/2/dbus_daemon/info.txt +++ /dev/null @@ -1 +0,0 @@ -dbus_daemon
\ No newline at end of file diff --git a/tools/pkg/2/dbus_daemon/main.c b/tools/pkg/2/dbus_daemon/main.c deleted file mode 100644 index 5380e02..0000000 --- a/tools/pkg/2/dbus_daemon/main.c +++ /dev/null @@ -1,15 +0,0 @@ - -#include <unistd.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> - -#include <orange/dev.h> -#include <orange/io.h> -#include <orange/log.h> - -int main() { - log(LEVEL_MESSAGE_INFO,"Starting DBus\n"); - system("dbus-daemon --system --fork"); - exit(0); -}
\ No newline at end of file diff --git a/tools/pkg/2/dbus_daemon/pkg.sh b/tools/pkg/2/dbus_daemon/pkg.sh deleted file mode 100644 index eec2061..0000000 --- a/tools/pkg/2/dbus_daemon/pkg.sh +++ /dev/null @@ -1 +0,0 @@ -exit 0
\ No newline at end of file diff --git a/tools/pkg/2/gettext/pkg.sh b/tools/pkg/2/gettext/pkg.sh deleted file mode 100644 index f4766ab..0000000 --- a/tools/pkg/2/gettext/pkg.sh +++ /dev/null @@ -1,14 +0,0 @@ -. ../../pkg-lib.sh - -mkdir -p cached - -rm -rf pack - -mkdir -p pack - -cd pack - -fast_install "$1" $GNU_MIRROR/gnu/libiconv/libiconv-1.18.tar.gz -fast_install "$1" $GNU_MIRROR/gnu/gettext/gettext-0.26.tar.gz "--enable-shared" ../../diff/gettext.diff - -cd .. diff --git a/tools/pkg/2/init/info.txt b/tools/pkg/2/init/info.txt deleted file mode 100644 index b1131f2..0000000 --- a/tools/pkg/2/init/info.txt +++ /dev/null @@ -1 +0,0 @@ -tty
\ No newline at end of file diff --git a/tools/pkg/2/init/pkg.sh b/tools/pkg/2/init/pkg.sh deleted file mode 100644 index 55c51d6..0000000 --- a/tools/pkg/2/init/pkg.sh +++ /dev/null @@ -1,20 +0,0 @@ - -rm -rf pack -mkdir -p pack/lib - -cd pack/lib/ -git clone https://codeberg.org/Mintsuki/Flanterm.git -cd ../../ - -x86_64-linux-gnu-g++ -c src/main.cpp -o "pack/init.o" -Ipack/lib/Flanterm/src -Isrc/include -I"$1/usr/include" -echo "donex" - -x86_64-linux-gnu-gcc -c pack/lib/Flanterm/src/flanterm.c -o pack/flanterm.o -Ipack/lib/Flanterm/src -I"$1/usr/include" -echo "donez" - -x86_64-linux-gnu-gcc -c pack/lib/Flanterm/src/flanterm_backends/fb.c -o pack/flanterm_backends.o -Ipack/lib/Flanterm/src -I"$1/usr/include" -echo "donev" - - -x86_64-linux-gnu-g++ -o "$1/usr/bin/init" pack/init.o pack/flanterm.o pack/flanterm_backends.o -echo "done" diff --git a/tools/pkg/2/init/src/include/etc.hpp b/tools/pkg/2/init/src/include/etc.hpp deleted file mode 100644 index c153727..0000000 --- a/tools/pkg/2/init/src/include/etc.hpp +++ /dev/null @@ -1,162 +0,0 @@ - -#include <linux/fb.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <linux/fb.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <unistd.h> -#include <string.h> -#include <stdint.h> -#include <termios.h> -#include <signal.h> - -#include <poll.h> -#include <fcntl.h> - -#include <dirent.h> -#include <string.h> -#include <sys/types.h> - -#include <pthread.h> - -#include <orange/dev.h> - -#include <flanterm.h> -#include <flanterm_backends/fb.h> - -#include <font.hpp> - -#pragma once - -#define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" - -void scale_image_nn(unsigned char* src, int src_w, int src_h, - unsigned char* dst, int dst_w, int dst_h, int channels) { - for (int y = 0; y < dst_h; y++) { - int src_y = y * src_h / dst_h; - for (int x = 0; x < dst_w; x++) { - int src_x = x * src_w / dst_w; - for (int c = 0; c < channels; c++) { - dst[(y*dst_w + x)*channels + c] = src[(src_y*src_w + src_x)*channels + c]; - } - } - } -} - -uint32_t rgb_to_pixel(uint8_t r, uint8_t g, uint8_t b, - int r_len, int r_off, - int g_len, int g_off, - int b_len, int b_off) { - uint32_t pixel = 0; - uint32_t R = (r >> (8 - r_len)) << r_off; - uint32_t G = (g >> (8 - g_len)) << g_off; - uint32_t B = (b >> (8 - b_len)) << b_off; - pixel = R | G | B; - return pixel; -} - -static uint32_t blend_pixel(uint32_t dst, uint8_t r_src, uint8_t g_src, uint8_t b_src, float alpha, - int r_len, int r_off, int g_len, int g_off, int b_len, int b_off) { - uint8_t r_dst = (dst >> r_off) & ((1 << r_len) - 1); - uint8_t g_dst = (dst >> g_off) & ((1 << g_len) - 1); - uint8_t b_dst = (dst >> b_off) & ((1 << b_len) - 1); - - r_dst = (r_dst << (8 - r_len)) | (r_dst >> (2 * r_len - 8)); - g_dst = (g_dst << (8 - g_len)) | (g_dst >> (2 * g_len - 8)); - b_dst = (b_dst << (8 - b_len)) | (b_dst >> (2 * b_len - 8)); - - uint8_t r = (uint8_t)(r_src * alpha + r_dst * (1.0f - alpha)); - uint8_t g = (uint8_t)(g_src * alpha + g_dst * (1.0f - alpha)); - uint8_t b = (uint8_t)(b_src * alpha + b_dst * (1.0f - alpha)); - - uint32_t pixel = 0; - pixel |= ((r >> (8 - r_len)) << r_off); - pixel |= ((g >> (8 - g_len)) << g_off); - pixel |= ((b >> (8 - b_len)) << b_off); - - return pixel; -} - -static void draw_transparent_black_square(uint32_t* canvas, int width, int height, - int r_len, int r_off, - int g_len, int g_off, - int b_len, int b_off, - int margin) { - int square_w = width - 2 * margin; - int square_h = height - 2 * margin; - int start_x = margin; - int start_y = margin; - float alpha = 0.5f; - - for (int y = start_y; y < start_y + square_h; y++) { - for (int x = start_x; x < start_x + square_w; x++) { - int idx = y * width + x; - - canvas[idx] = blend_pixel(canvas[idx], 0, 0, 0, alpha, - r_len, r_off, g_len, g_off, b_len, b_off); - } - } -} - -void debug_log(const char* msg) { - asm volatile("syscall" : : "a"(9), "D"(msg) : "rcx","r11"); -} - -extern "C" void* __flanterm_malloc(size_t size) { - return malloc(size); -} - -extern "C" void __flanterm_free(void* ptr,size_t size) { - free(ptr); -} - -/* My init will contain fbdev,tty,input0 initialization */ - -uint32_t default_fg = 0xEEEEEEEE; -uint32_t default_fg_bright = 0xFFFFFFFF; - -char is_shift_pressed = 0; -char is_ctrl_pressed = 0; - -const char en_layout_translation[] = { - '\0', '\e', '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', ' ' -}; - -const char en_layout_translation_shift[] = { - '\0', '\e', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\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', ' ' -}; -\ -#define ASCII_CTRL_OFFSET 96 - -#define SHIFT_PRESSED 0x2A -#define SHIFT_RELEASED 0xAA -#define CTRL_PRESSED 29 -#define CTRL_RELEASED 157 - -#include <emmintrin.h> - -#define LEVEL_MESSAGE_OK 0 -#define LEVEL_MESSAGE_FAIL 1 -#define LEVEL_MESSAGE_WARN 2 -#define LEVEL_MESSAGE_INFO 3 - -const char* level_messages[] = { - [LEVEL_MESSAGE_OK] = "[ \x1b[38;2;0;255;0mOK\033[0m ] ", - [LEVEL_MESSAGE_FAIL] = "[ \x1b[38;2;255;0;0mFAILED\033[0m ] ", - [LEVEL_MESSAGE_WARN] = "[ \x1b[38;2;255;165;0mWARN\033[0m ] ", - [LEVEL_MESSAGE_INFO] = "[ \x1b[38;2;0;191;255mINFO\033[0m ] " -}; - -#define log(level, format,...) printf("%s" format "\n", level_messages[level], ##__VA_ARGS__) - -#define DIR_PATH "/etc/drivers/" -#define EXT ".sys" diff --git a/tools/pkg/2/init/src/include/font.hpp b/tools/pkg/2/init/src/include/font.hpp deleted file mode 100644 index 96d25a8..0000000 --- a/tools/pkg/2/init/src/include/font.hpp +++ /dev/null @@ -1,609 +0,0 @@ - -#pragma once - -#define FONT_WIDTH 8 -#define FONT_HEIGHT 16 - -static const uint8_t builtin_font[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x42, 0x81, 0x81, 0xa5, 0xa5, 0x81, 0x81, 0xa5, 0x99, 0x81, 0x42, 0x3c, 0x00, 0x00, - 0x00, 0x3c, 0x7e, 0xff, 0xff, 0xdb, 0xdb, 0xff, 0xff, 0xdb, 0xe7, 0xff, 0x7e, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xdb, 0xff, 0xff, 0xdb, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0xff, 0x66, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0x84, 0x84, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x1e, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x18, 0x1c, 0x1e, 0x16, 0x12, 0x10, 0x10, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x38, 0x2c, 0x26, 0x32, 0x3a, 0x2e, 0x26, 0x22, 0x62, 0xe2, 0xc6, 0x0e, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, - 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e, 0xfe, 0x7e, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, 0x30, 0xfc, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0x78, 0x78, 0x78, 0x30, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x0c, 0x0c, 0x18, 0x38, 0x30, 0x60, 0x60, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x30, 0x76, 0xde, 0xcc, 0xcc, 0xde, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x30, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0xfe, 0x38, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x38, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x04, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xde, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xee, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xe6, 0xe6, 0xf6, 0xde, 0xce, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xf6, 0xda, 0x6c, 0x06, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0xd8, 0xcc, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0x60, 0x60, 0x30, 0x38, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xe6, 0xdc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x06, 0x06, 0x76, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xce, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0xf0, 0xf0, 0xd8, 0xcc, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xe6, 0xdc, 0xc0, 0xc0, 0xc0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xce, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0x06, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0x70, 0x1c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x30, 0xfe, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x30, 0x30, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0x30, 0x30, 0x30, 0x30, 0x1c, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x18, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x38, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x00, 0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x36, 0x36, 0x76, 0xde, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x3c, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, - 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x30, 0x30, 0x78, 0xcc, 0xc0, 0xc0, 0xcc, 0x78, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x60, 0x60, 0x60, 0xf8, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x76, 0xdc, 0x00, 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x78, 0xd8, 0xd8, 0x6c, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc2, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc2, 0xc6, 0xcc, 0xd8, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x30, 0x78, 0x78, 0x78, 0x78, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0xf6, 0x06, 0x06, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x06, 0x06, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0xf6, 0x06, 0x06, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x30, 0x30, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x30, 0x30, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0xf7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x30, 0x30, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0xf7, 0x00, 0x00, 0xf7, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xd6, 0xdc, 0xc8, 0xc8, 0xdc, 0xd6, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xd8, 0xc0, 0xc0, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xfe, 0x24, 0x24, 0x24, 0x24, 0x66, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xfe, 0xc2, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc2, 0xfe, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x76, 0x6c, 0x60, 0xc0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xfc, 0x98, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x30, 0x30, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0x60, 0x30, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xbb, 0x99, 0x99, 0xdd, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x06, 0x3c, 0x6c, 0xce, 0xd6, 0xd6, 0xe6, 0x6c, 0x78, 0xc0, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x30, 0x60, 0xc0, 0xc0, 0xfe, 0xc0, 0xc0, 0x60, 0x30, 0x1e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x36, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c, 0x00, 0x00, - 0x00, 0xd8, 0xec, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x0c, 0x18, 0x30, 0x60, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -unsigned char unifont_arr[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x81, 0xa5, - 0x81, 0xa5, 0x99, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3c, 0x7e, 0xff, 0xdb, 0xff, 0xdb, 0xe7, 0x7e, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x7f, 0x7f, 0x7f, 0x7f, 0x3e, 0x1c, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x1c, 0x1c, - 0x3e, 0x3e, 0x1c, 0x1c, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1c, 0x1c, 0x1c, 0x08, 0x7f, 0x7f, 0x6b, 0x08, 0x08, 0x1c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x1c, 0x3e, 0x7f, 0x7f, 0x7f, 0x3e, - 0x08, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, - 0x7c, 0x7c, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x22, 0x1c, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xdb, 0xbd, - 0xbd, 0xdb, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x07, 0x03, 0x05, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x08, 0x3e, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0c, 0x0a, 0x0a, - 0x08, 0x08, 0x08, 0x38, 0x78, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, - 0x17, 0x11, 0x11, 0x11, 0x11, 0x71, 0xf1, 0xe7, 0x0f, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x2a, 0x1c, 0x77, 0x1c, 0x2a, 0x49, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, - 0x78, 0x7e, 0x78, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x1e, 0x7e, 0x1e, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x08, 0x1c, 0x2a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x2a, - 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x24, - 0x24, 0x24, 0x24, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3f, 0x7a, 0x7a, 0x7a, 0x3a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x3c, 0x42, 0x42, 0x3c, 0x02, - 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, - 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, - 0x2a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x2a, 0x1c, 0x08, 0x3e, 0x00, 0x00, - 0x00, 0x00, 0x08, 0x1c, 0x2a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x2a, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x04, 0xfe, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x7f, 0x20, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x24, 0x42, 0xff, 0x42, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x7e, 0x7e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x3c, - 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x12, 0x12, 0x12, 0x7e, 0x24, 0x24, 0x7e, 0x48, 0x48, 0x48, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x3e, 0x49, 0x48, 0x38, 0x0e, 0x09, 0x49, - 0x3e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x4a, 0x4a, 0x34, - 0x08, 0x08, 0x16, 0x29, 0x29, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1c, 0x22, 0x22, 0x14, 0x18, 0x29, 0x45, 0x42, 0x46, 0x39, 0x00, 0x00, - 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x08, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, - 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x49, 0x2a, 0x1c, 0x2a, 0x49, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, - 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x46, 0x4a, 0x52, 0x62, 0x42, - 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x18, 0x28, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3c, 0x42, 0x42, 0x02, 0x0c, 0x10, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x1c, 0x02, 0x02, 0x42, - 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x14, 0x24, - 0x44, 0x44, 0x7e, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x02, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, - 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, - 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x02, - 0x04, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, - 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, - 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x04, 0x08, 0x08, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x4a, 0x56, - 0x52, 0x52, 0x52, 0x4e, 0x20, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x42, 0x42, 0x42, - 0x42, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, - 0x40, 0x40, 0x40, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x78, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, - 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, - 0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3c, 0x42, 0x42, 0x40, 0x40, 0x4e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x42, 0x44, 0x48, 0x50, 0x60, 0x60, 0x50, 0x48, - 0x44, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x42, 0x42, 0x66, 0x66, 0x5a, 0x5a, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x42, 0x62, 0x62, 0x52, 0x52, 0x4a, 0x4a, 0x46, - 0x46, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x5a, - 0x66, 0x3c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, - 0x7c, 0x48, 0x44, 0x44, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3c, 0x42, 0x42, 0x40, 0x30, 0x0c, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x41, 0x41, 0x41, 0x22, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x5a, 0x5a, 0x66, 0x66, - 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x24, 0x24, - 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x41, 0x41, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, - 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x70, 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, - 0x00, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, - 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, - 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x40, - 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x3a, 0x46, - 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3a, 0x44, - 0x44, 0x44, 0x38, 0x20, 0x3c, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x40, - 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x0c, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x48, 0x30, 0x00, 0x00, 0x00, 0x40, - 0x40, 0x40, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x49, - 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, - 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, - 0x40, 0x30, 0x0c, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, - 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x41, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x24, 0x18, 0x18, 0x24, - 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x02, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x10, 0x10, 0x08, 0x08, 0x10, 0x20, 0x10, 0x08, - 0x08, 0x10, 0x10, 0x0c, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x30, - 0x08, 0x08, 0x10, 0x10, 0x08, 0x04, 0x08, 0x10, 0x10, 0x08, 0x08, 0x30, - 0x00, 0x00, 0x00, 0x31, 0x49, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3c, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3c, 0x08, 0x30, - 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, - 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, - 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, - 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, - 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x3c, 0x42, - 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x18, 0x24, 0x18, - 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x40, - 0x42, 0x3c, 0x08, 0x30, 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x3c, 0x42, - 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, - 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, - 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, - 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x3e, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, - 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x18, 0x24, 0x18, 0x00, - 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, - 0x0c, 0x30, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, - 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x49, - 0x09, 0x3f, 0x48, 0x48, 0x49, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1f, 0x28, 0x48, 0x48, 0x7f, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x3c, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, - 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, - 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x02, 0x3c, - 0x24, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x3c, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x3e, 0x49, 0x48, 0x48, 0x49, 0x3e, 0x08, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, - 0x3e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, - 0x7f, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x68, 0x58, 0x5f, 0x5c, 0x6c, 0x4a, 0x49, 0x49, 0x49, 0x4e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x60, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, - 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, - 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x32, 0x4c, - 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, - 0x32, 0x4c, 0x00, 0x00, 0x42, 0x62, 0x62, 0x52, 0x52, 0x4a, 0x4a, 0x46, - 0x46, 0x42, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x02, 0x1e, 0x22, 0x1e, 0x00, - 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, - 0x22, 0x22, 0x1c, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x20, 0x40, 0x42, - 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x22, 0x62, 0x24, 0x28, 0x28, 0x14, 0x1a, 0x22, - 0x44, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x62, 0x24, 0x28, - 0x28, 0x12, 0x16, 0x2a, 0x4e, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x24, 0x24, 0x48, 0x24, 0x24, - 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x48, 0x24, - 0x24, 0x12, 0x24, 0x24, 0x48, 0x48, 0x00, 0x00, 0x88, 0x22, 0x88, 0x22, - 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, - 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, - 0xaa, 0x55, 0xaa, 0x55, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, - 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, - 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x14, 0xf4, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, - 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0xf4, 0x04, 0xf4, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x04, - 0xf4, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0xf4, 0x04, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, - 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x17, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x17, 0x10, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x10, 0x17, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xf7, 0x00, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x00, 0xf7, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x17, 0x10, 0x17, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0xf7, 0x00, 0xf7, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x00, 0xff, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x0f, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x14, 0xff, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xff, 0x08, 0xff, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x32, 0x4a, 0x44, 0x44, 0x44, 0x44, 0x4a, 0x32, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x48, 0x58, 0x44, 0x42, 0x42, - 0x52, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x42, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x20, 0x10, 0x08, 0x08, 0x10, 0x20, - 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x48, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x66, 0x59, 0x40, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x08, 0x3e, 0x49, - 0x49, 0x49, 0x49, 0x3e, 0x08, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3c, 0x42, 0x42, 0x42, 0x5a, 0x5a, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3e, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x14, - 0x14, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x20, 0x20, - 0x18, 0x24, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x36, 0x49, 0x49, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x49, 0x49, 0x49, 0x49, 0x49, - 0x49, 0x3e, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, - 0x40, 0x3c, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x7e, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, - 0x08, 0x08, 0x08, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x60, 0x18, 0x06, 0x18, 0x60, 0x00, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x18, 0x60, 0x18, 0x06, 0x00, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0a, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x28, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x7e, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, - 0x4c, 0x00, 0x32, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x74, 0x14, 0x14, 0x0c, 0x0c, 0x04, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x64, 0x44, 0x44, 0x44, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x04, 0x18, 0x20, - 0x40, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; diff --git a/tools/pkg/2/init/src/include/stb_image.h b/tools/pkg/2/init/src/include/stb_image.h deleted file mode 100644 index 9eedabe..0000000 --- a/tools/pkg/2/init/src/include/stb_image.h +++ /dev/null @@ -1,7988 +0,0 @@ -/* stb_image - v2.30 - public domain image loader - http://nothings.org/stb - no warranty implied; use at your own risk - - Do this: - #define STB_IMAGE_IMPLEMENTATION - before you include this file in *one* C or C++ file to create the implementation. - - // i.e. it should look like this: - #include ... - #include ... - #include ... - #define STB_IMAGE_IMPLEMENTATION - #include "stb_image.h" - - You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. - And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free - - - QUICK NOTES: - Primarily of interest to game developers and other people who can - avoid problematic images and only need the trivial interface - - JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) - PNG 1/2/4/8/16-bit-per-channel - - TGA (not sure what subset, if a subset) - BMP non-1bpp, non-RLE - PSD (composited view only, no extra channels, 8/16 bit-per-channel) - - GIF (*comp always reports as 4-channel) - HDR (radiance rgbE format) - PIC (Softimage PIC) - PNM (PPM and PGM binary only) - - Animated GIF still needs a proper API, but here's one way to do it: - http://gist.github.com/urraka/685d9a6340b26b830d49 - - - decode from memory or through FILE (define STBI_NO_STDIO to remove code) - - decode from arbitrary I/O callbacks - - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) - - Full documentation under "DOCUMENTATION" below. - - -LICENSE - - See end of file for license information. - -RECENT REVISION HISTORY: - - 2.30 (2024-05-31) avoid erroneous gcc warning - 2.29 (2023-05-xx) optimizations - 2.28 (2023-01-29) many error fixes, security errors, just tons of stuff - 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes - 2.26 (2020-07-13) many minor fixes - 2.25 (2020-02-02) fix warnings - 2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically - 2.23 (2019-08-11) fix clang static analysis warning - 2.22 (2019-03-04) gif fixes, fix warnings - 2.21 (2019-02-25) fix typo in comment - 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs - 2.19 (2018-02-11) fix warning - 2.18 (2018-01-30) fix warnings - 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings - 2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes - 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC - 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs - 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes - 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes - 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 - RGB-format JPEG; remove white matting in PSD; - allocate large structures on the stack; - correct channel count for PNG & BMP - 2.10 (2016-01-22) avoid warning introduced in 2.09 - 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED - - See end of file for full revision history. - - - ============================ Contributors ========================= - - Image formats Extensions, features - Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) - Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) - Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) - Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) - Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) - Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) - Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) - github:urraka (animated gif) Junggon Kim (PNM comments) - Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA) - socks-the-fox (16-bit PNG) - Jeremy Sawicki (handle all ImageNet JPGs) - Optimizations & bugfixes Mikhail Morozov (1-bit BMP) - Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) - Arseny Kapoulkine Simon Breuss (16-bit PNM) - John-Mark Allen - Carmelo J Fdez-Aguera - - Bug & warning fixes - Marc LeBlanc David Woo Guillaume George Martins Mozeiko - Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski - Phil Jordan Dave Moore Roy Eltham - Hayaki Saito Nathan Reed Won Chun - Luke Graham Johan Duparc Nick Verigakis the Horde3D community - Thomas Ruf Ronny Chevalier github:rlyeh - Janez Zemva John Bartholomew Michal Cichon github:romigrou - Jonathan Blow Ken Hamada Tero Hanninen github:svdijk - Eugene Golushkov Laurent Gomila Cort Stratton github:snagar - Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex - Cass Everitt Ryamond Barbiero github:grim210 - Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw - Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus - Josh Tobin Neil Bickford Matthew Gregan github:poppolopoppo - Julian Raschke Gregory Mullen Christian Floisand github:darealshinji - Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007 - Brad Weinberger Matvey Cherevko github:mosra - Luca Sas Alexander Veselov Zack Middleton [reserved] - Ryan C. Gordon [reserved] [reserved] - DO NOT ADD YOUR NAME HERE - - Jacko Dirks - - To add your name to the credits, pick a random blank space in the middle and fill it. - 80% of merge conflicts on stb PRs are due to people adding their name at the end - of the credits. -*/ - -#ifndef STBI_INCLUDE_STB_IMAGE_H -#define STBI_INCLUDE_STB_IMAGE_H - -// DOCUMENTATION -// -// Limitations: -// - no 12-bit-per-channel JPEG -// - no JPEGs with arithmetic coding -// - GIF always returns *comp=4 -// -// Basic usage (see HDR discussion below for HDR usage): -// int x,y,n; -// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); -// // ... process data if not NULL ... -// // ... x = width, y = height, n = # 8-bit components per pixel ... -// // ... replace '0' with '1'..'4' to force that many components per pixel -// // ... but 'n' will always be the number that it would have been if you said 0 -// stbi_image_free(data); -// -// Standard parameters: -// int *x -- outputs image width in pixels -// int *y -- outputs image height in pixels -// int *channels_in_file -- outputs # of image components in image file -// int desired_channels -- if non-zero, # of image components requested in result -// -// The return value from an image loader is an 'unsigned char *' which points -// to the pixel data, or NULL on an allocation failure or if the image is -// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, -// with each pixel consisting of N interleaved 8-bit components; the first -// pixel pointed to is top-left-most in the image. There is no padding between -// image scanlines or between pixels, regardless of format. The number of -// components N is 'desired_channels' if desired_channels is non-zero, or -// *channels_in_file otherwise. If desired_channels is non-zero, -// *channels_in_file has the number of components that _would_ have been -// output otherwise. E.g. if you set desired_channels to 4, you will always -// get RGBA output, but you can check *channels_in_file to see if it's trivially -// opaque because e.g. there were only 3 channels in the source image. -// -// An output image with N components has the following components interleaved -// in this order in each pixel: -// -// N=#comp components -// 1 grey -// 2 grey, alpha -// 3 red, green, blue -// 4 red, green, blue, alpha -// -// If image loading fails for any reason, the return value will be NULL, -// and *x, *y, *channels_in_file will be unchanged. The function -// stbi_failure_reason() can be queried for an extremely brief, end-user -// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS -// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly -// more user-friendly ones. -// -// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. -// -// To query the width, height and component count of an image without having to -// decode the full file, you can use the stbi_info family of functions: -// -// int x,y,n,ok; -// ok = stbi_info(filename, &x, &y, &n); -// // returns ok=1 and sets x, y, n if image is a supported format, -// // 0 otherwise. -// -// Note that stb_image pervasively uses ints in its public API for sizes, -// including sizes of memory buffers. This is now part of the API and thus -// hard to change without causing breakage. As a result, the various image -// loaders all have certain limits on image size; these differ somewhat -// by format but generally boil down to either just under 2GB or just under -// 1GB. When the decoded image would be larger than this, stb_image decoding -// will fail. -// -// Additionally, stb_image will reject image files that have any of their -// dimensions set to a larger value than the configurable STBI_MAX_DIMENSIONS, -// which defaults to 2**24 = 16777216 pixels. Due to the above memory limit, -// the only way to have an image with such dimensions load correctly -// is for it to have a rather extreme aspect ratio. Either way, the -// assumption here is that such larger images are likely to be malformed -// or malicious. If you do need to load an image with individual dimensions -// larger than that, and it still fits in the overall size limit, you can -// #define STBI_MAX_DIMENSIONS on your own to be something larger. -// -// =========================================================================== -// -// UNICODE: -// -// If compiling for Windows and you wish to use Unicode filenames, compile -// with -// #define STBI_WINDOWS_UTF8 -// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert -// Windows wchar_t filenames to utf8. -// -// =========================================================================== -// -// Philosophy -// -// stb libraries are designed with the following priorities: -// -// 1. easy to use -// 2. easy to maintain -// 3. good performance -// -// Sometimes I let "good performance" creep up in priority over "easy to maintain", -// and for best performance I may provide less-easy-to-use APIs that give higher -// performance, in addition to the easy-to-use ones. Nevertheless, it's important -// to keep in mind that from the standpoint of you, a client of this library, -// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. -// -// Some secondary priorities arise directly from the first two, some of which -// provide more explicit reasons why performance can't be emphasized. -// -// - Portable ("ease of use") -// - Small source code footprint ("easy to maintain") -// - No dependencies ("ease of use") -// -// =========================================================================== -// -// I/O callbacks -// -// I/O callbacks allow you to read from arbitrary sources, like packaged -// files or some other source. Data read from callbacks are processed -// through a small internal buffer (currently 128 bytes) to try to reduce -// overhead. -// -// The three functions you must define are "read" (reads some bytes of data), -// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). -// -// =========================================================================== -// -// SIMD support -// -// The JPEG decoder will try to automatically use SIMD kernels on x86 when -// supported by the compiler. For ARM Neon support, you must explicitly -// request it. -// -// (The old do-it-yourself SIMD API is no longer supported in the current -// code.) -// -// On x86, SSE2 will automatically be used when available based on a run-time -// test; if not, the generic C versions are used as a fall-back. On ARM targets, -// the typical path is to have separate builds for NEON and non-NEON devices -// (at least this is true for iOS and Android). Therefore, the NEON support is -// toggled by a build flag: define STBI_NEON to get NEON loops. -// -// If for some reason you do not want to use any of SIMD code, or if -// you have issues compiling it, you can disable it entirely by -// defining STBI_NO_SIMD. -// -// =========================================================================== -// -// HDR image support (disable by defining STBI_NO_HDR) -// -// stb_image supports loading HDR images in general, and currently the Radiance -// .HDR file format specifically. You can still load any file through the existing -// interface; if you attempt to load an HDR file, it will be automatically remapped -// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; -// both of these constants can be reconfigured through this interface: -// -// stbi_hdr_to_ldr_gamma(2.2f); -// stbi_hdr_to_ldr_scale(1.0f); -// -// (note, do not use _inverse_ constants; stbi_image will invert them -// appropriately). -// -// Additionally, there is a new, parallel interface for loading files as -// (linear) floats to preserve the full dynamic range: -// -// float *data = stbi_loadf(filename, &x, &y, &n, 0); -// -// If you load LDR images through this interface, those images will -// be promoted to floating point values, run through the inverse of -// constants corresponding to the above: -// -// stbi_ldr_to_hdr_scale(1.0f); -// stbi_ldr_to_hdr_gamma(2.2f); -// -// Finally, given a filename (or an open file or memory block--see header -// file for details) containing image data, you can query for the "most -// appropriate" interface to use (that is, whether the image is HDR or -// not), using: -// -// stbi_is_hdr(char *filename); -// -// =========================================================================== -// -// iPhone PNG support: -// -// We optionally support converting iPhone-formatted PNGs (which store -// premultiplied BGRA) back to RGB, even though they're internally encoded -// differently. To enable this conversion, call -// stbi_convert_iphone_png_to_rgb(1). -// -// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per -// pixel to remove any premultiplied alpha *only* if the image file explicitly -// says there's premultiplied data (currently only happens in iPhone images, -// and only if iPhone convert-to-rgb processing is on). -// -// =========================================================================== -// -// ADDITIONAL CONFIGURATION -// -// - You can suppress implementation of any of the decoders to reduce -// your code footprint by #defining one or more of the following -// symbols before creating the implementation. -// -// STBI_NO_JPEG -// STBI_NO_PNG -// STBI_NO_BMP -// STBI_NO_PSD -// STBI_NO_TGA -// STBI_NO_GIF -// STBI_NO_HDR -// STBI_NO_PIC -// STBI_NO_PNM (.ppm and .pgm) -// -// - You can request *only* certain decoders and suppress all other ones -// (this will be more forward-compatible, as addition of new decoders -// doesn't require you to disable them explicitly): -// -// STBI_ONLY_JPEG -// STBI_ONLY_PNG -// STBI_ONLY_BMP -// STBI_ONLY_PSD -// STBI_ONLY_TGA -// STBI_ONLY_GIF -// STBI_ONLY_HDR -// STBI_ONLY_PIC -// STBI_ONLY_PNM (.ppm and .pgm) -// -// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still -// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB -// -// - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater -// than that size (in either width or height) without further processing. -// This is to let programs in the wild set an upper bound to prevent -// denial-of-service attacks on untrusted data, as one could generate a -// valid image of gigantic dimensions and force stb_image to allocate a -// huge block of memory and spend disproportionate time decoding it. By -// default this is set to (1 << 24), which is 16777216, but that's still -// very big. - -#ifndef STBI_NO_STDIO -#include <stdio.h> -#endif // STBI_NO_STDIO - -#define STBI_VERSION 1 - -enum -{ - STBI_default = 0, // only used for desired_channels - - STBI_grey = 1, - STBI_grey_alpha = 2, - STBI_rgb = 3, - STBI_rgb_alpha = 4 -}; - -#include <stdlib.h> -typedef unsigned char stbi_uc; -typedef unsigned short stbi_us; - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef STBIDEF -#ifdef STB_IMAGE_STATIC -#define STBIDEF static -#else -#define STBIDEF extern -#endif -#endif - -////////////////////////////////////////////////////////////////////////////// -// -// PRIMARY API - works on images of any type -// - -// -// load image by filename, open file, or memory buffer -// - -typedef struct -{ - int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read - void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative - int (*eof) (void *user); // returns nonzero if we are at end of file/data -} stbi_io_callbacks; - -//////////////////////////////////// -// -// 8-bits-per-channel interface -// - -STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels); -STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels); - -#ifndef STBI_NO_STDIO -STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); -STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); -// for stbi_load_from_file, file pointer is left pointing immediately after image -#endif - -#ifndef STBI_NO_GIF -STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp); -#endif - -#ifdef STBI_WINDOWS_UTF8 -STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); -#endif - -//////////////////////////////////// -// -// 16-bits-per-channel interface -// - -STBIDEF stbi_us *stbi_load_16_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); -STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); - -#ifndef STBI_NO_STDIO -STBIDEF stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); -STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); -#endif - -//////////////////////////////////// -// -// float-per-channel interface -// -#ifndef STBI_NO_LINEAR - STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); - STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); - - #ifndef STBI_NO_STDIO - STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); - STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); - #endif -#endif - -#ifndef STBI_NO_HDR - STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); - STBIDEF void stbi_hdr_to_ldr_scale(float scale); -#endif // STBI_NO_HDR - -#ifndef STBI_NO_LINEAR - STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); - STBIDEF void stbi_ldr_to_hdr_scale(float scale); -#endif // STBI_NO_LINEAR - -// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR -STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); -STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); -#ifndef STBI_NO_STDIO -STBIDEF int stbi_is_hdr (char const *filename); -STBIDEF int stbi_is_hdr_from_file(FILE *f); -#endif // STBI_NO_STDIO - - -// get a VERY brief reason for failure -// on most compilers (and ALL modern mainstream compilers) this is threadsafe -STBIDEF const char *stbi_failure_reason (void); - -// free the loaded image -- this is just free() -STBIDEF void stbi_image_free (void *retval_from_stbi_load); - -// get image dimensions & components without fully decoding -STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); -STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); -STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len); -STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user); - -#ifndef STBI_NO_STDIO -STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); -STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); -STBIDEF int stbi_is_16_bit (char const *filename); -STBIDEF int stbi_is_16_bit_from_file(FILE *f); -#endif - - - -// for image formats that explicitly notate that they have premultiplied alpha, -// we just return the colors as stored in the file. set this flag to force -// unpremultiplication. results are undefined if the unpremultiply overflow. -STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); - -// indicate whether we should process iphone images back to canonical format, -// or just pass them through "as-is" -STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); - -// flip the image vertically, so the first pixel in the output array is the bottom left -STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); - -// as above, but only applies to images loaded on the thread that calls the function -// this function is only available if your compiler supports thread-local variables; -// calling it will fail to link if your compiler doesn't -STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply); -STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert); -STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); - -// ZLIB client - used by PNG, available for other purposes - -STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); -STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); -STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); -STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); - -STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); -STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); - - -#ifdef __cplusplus -} -#endif - -// -// -//// end header file ///////////////////////////////////////////////////// -#endif // STBI_INCLUDE_STB_IMAGE_H - -#ifdef STB_IMAGE_IMPLEMENTATION - -#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ - || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ - || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ - || defined(STBI_ONLY_ZLIB) - #ifndef STBI_ONLY_JPEG - #define STBI_NO_JPEG - #endif - #ifndef STBI_ONLY_PNG - #define STBI_NO_PNG - #endif - #ifndef STBI_ONLY_BMP - #define STBI_NO_BMP - #endif - #ifndef STBI_ONLY_PSD - #define STBI_NO_PSD - #endif - #ifndef STBI_ONLY_TGA - #define STBI_NO_TGA - #endif - #ifndef STBI_ONLY_GIF - #define STBI_NO_GIF - #endif - #ifndef STBI_ONLY_HDR - #define STBI_NO_HDR - #endif - #ifndef STBI_ONLY_PIC - #define STBI_NO_PIC - #endif - #ifndef STBI_ONLY_PNM - #define STBI_NO_PNM - #endif -#endif - -#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) -#define STBI_NO_ZLIB -#endif - - -#include <stdarg.h> -#include <stddef.h> // ptrdiff_t on osx -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) -#include <math.h> // ldexp, pow -#endif - -#ifndef STBI_NO_STDIO -#include <stdio.h> -#endif - -#ifndef STBI_ASSERT -#include <assert.h> -#define STBI_ASSERT(x) assert(x) -#endif - -#ifdef __cplusplus -#define STBI_EXTERN extern "C" -#else -#define STBI_EXTERN extern -#endif - - -#ifndef _MSC_VER - #ifdef __cplusplus - #define stbi_inline inline - #else - #define stbi_inline - #endif -#else - #define stbi_inline __forceinline -#endif - -#ifndef STBI_NO_THREAD_LOCALS - #if defined(__cplusplus) && __cplusplus >= 201103L - #define STBI_THREAD_LOCAL thread_local - #elif defined(__GNUC__) && __GNUC__ < 5 - #define STBI_THREAD_LOCAL __thread - #elif defined(_MSC_VER) - #define STBI_THREAD_LOCAL __declspec(thread) - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) - #define STBI_THREAD_LOCAL _Thread_local - #endif - - #ifndef STBI_THREAD_LOCAL - #if defined(__GNUC__) - #define STBI_THREAD_LOCAL __thread - #endif - #endif -#endif - -#if defined(_MSC_VER) || defined(__SYMBIAN32__) -typedef unsigned short stbi__uint16; -typedef signed short stbi__int16; -typedef unsigned int stbi__uint32; -typedef signed int stbi__int32; -#else -#include <stdint.h> -typedef uint16_t stbi__uint16; -typedef int16_t stbi__int16; -typedef uint32_t stbi__uint32; -typedef int32_t stbi__int32; -#endif - -// should produce compiler error if size is wrong -typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; - -#ifdef _MSC_VER -#define STBI_NOTUSED(v) (void)(v) -#else -#define STBI_NOTUSED(v) (void)sizeof(v) -#endif - -#ifdef _MSC_VER -#define STBI_HAS_LROTL -#endif - -#ifdef STBI_HAS_LROTL - #define stbi_lrot(x,y) _lrotl(x,y) -#else - #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31))) -#endif - -#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) -// ok -#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) -// ok -#else -#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." -#endif - -#ifndef STBI_MALLOC -#define STBI_MALLOC(sz) malloc(sz) -#define STBI_REALLOC(p,newsz) realloc(p,newsz) -#define STBI_FREE(p) free(p) -#endif - -#ifndef STBI_REALLOC_SIZED -#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) -#endif - -// x86/x64 detection -#if defined(__x86_64__) || defined(_M_X64) -#define STBI__X64_TARGET -#elif defined(__i386) || defined(_M_IX86) -#define STBI__X86_TARGET -#endif - -#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) -// gcc doesn't support sse2 intrinsics unless you compile with -msse2, -// which in turn means it gets to use SSE2 everywhere. This is unfortunate, -// but previous attempts to provide the SSE2 functions with runtime -// detection caused numerous issues. The way architecture extensions are -// exposed in GCC/Clang is, sadly, not really suited for one-file libs. -// New behavior: if compiled with -msse2, we use SSE2 without any -// detection; if not, we don't use it at all. -#define STBI_NO_SIMD -#endif - -#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) -// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET -// -// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the -// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. -// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not -// simultaneously enabling "-mstackrealign". -// -// See https://github.com/nothings/stb/issues/81 for more information. -// -// So default to no SSE2 on 32-bit MinGW. If you've read this far and added -// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. -#define STBI_NO_SIMD -#endif - -#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) -#define STBI_SSE2 -#include <emmintrin.h> - -#ifdef _MSC_VER - -#if _MSC_VER >= 1400 // not VC6 -#include <intrin.h> // __cpuid -static int stbi__cpuid3(void) -{ - int info[4]; - __cpuid(info,1); - return info[3]; -} -#else -static int stbi__cpuid3(void) -{ - int res; - __asm { - mov eax,1 - cpuid - mov res,edx - } - return res; -} -#endif - -#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name - -#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) -static int stbi__sse2_available(void) -{ - int info3 = stbi__cpuid3(); - return ((info3 >> 26) & 1) != 0; -} -#endif - -#else // assume GCC-style if not VC++ -#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) - -#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) -static int stbi__sse2_available(void) -{ - // If we're even attempting to compile this on GCC/Clang, that means - // -msse2 is on, which means the compiler is allowed to use SSE2 - // instructions at will, and so are we. - return 1; -} -#endif - -#endif -#endif - -// ARM NEON -#if defined(STBI_NO_SIMD) && defined(STBI_NEON) -#undef STBI_NEON -#endif - -#ifdef STBI_NEON -#include <arm_neon.h> -#ifdef _MSC_VER -#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name -#else -#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) -#endif -#endif - -#ifndef STBI_SIMD_ALIGN -#define STBI_SIMD_ALIGN(type, name) type name -#endif - -#ifndef STBI_MAX_DIMENSIONS -#define STBI_MAX_DIMENSIONS (1 << 24) -#endif - -/////////////////////////////////////////////// -// -// stbi__context struct and start_xxx functions - -// stbi__context structure is our basic context used by all images, so it -// contains all the IO context, plus some basic image information -typedef struct -{ - stbi__uint32 img_x, img_y; - int img_n, img_out_n; - - stbi_io_callbacks io; - void *io_user_data; - - int read_from_callbacks; - int buflen; - stbi_uc buffer_start[128]; - int callback_already_read; - - stbi_uc *img_buffer, *img_buffer_end; - stbi_uc *img_buffer_original, *img_buffer_original_end; -} stbi__context; - - -static void stbi__refill_buffer(stbi__context *s); - -// initialize a memory-decode context -static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) -{ - s->io.read = NULL; - s->read_from_callbacks = 0; - s->callback_already_read = 0; - s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; - s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; -} - -// initialize a callback-based context -static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user) -{ - s->io = *c; - s->io_user_data = user; - s->buflen = sizeof(s->buffer_start); - s->read_from_callbacks = 1; - s->callback_already_read = 0; - s->img_buffer = s->img_buffer_original = s->buffer_start; - stbi__refill_buffer(s); - s->img_buffer_original_end = s->img_buffer_end; -} - -#ifndef STBI_NO_STDIO - -static int stbi__stdio_read(void *user, char *data, int size) -{ - return (int) fread(data,1,size,(FILE*) user); -} - -static void stbi__stdio_skip(void *user, int n) -{ - int ch; - fseek((FILE*) user, n, SEEK_CUR); - ch = fgetc((FILE*) user); /* have to read a byte to reset feof()'s flag */ - if (ch != EOF) { - ungetc(ch, (FILE *) user); /* push byte back onto stream if valid. */ - } -} - -static int stbi__stdio_eof(void *user) -{ - return feof((FILE*) user) || ferror((FILE *) user); -} - -static stbi_io_callbacks stbi__stdio_callbacks = -{ - stbi__stdio_read, - stbi__stdio_skip, - stbi__stdio_eof, -}; - -static void stbi__start_file(stbi__context *s, FILE *f) -{ - stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); -} - -//static void stop_file(stbi__context *s) { } - -#endif // !STBI_NO_STDIO - -static void stbi__rewind(stbi__context *s) -{ - // conceptually rewind SHOULD rewind to the beginning of the stream, - // but we just rewind to the beginning of the initial buffer, because - // we only use it after doing 'test', which only ever looks at at most 92 bytes - s->img_buffer = s->img_buffer_original; - s->img_buffer_end = s->img_buffer_original_end; -} - -enum -{ - STBI_ORDER_RGB, - STBI_ORDER_BGR -}; - -typedef struct -{ - int bits_per_channel; - int num_channels; - int channel_order; -} stbi__result_info; - -#ifndef STBI_NO_JPEG -static int stbi__jpeg_test(stbi__context *s); -static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_PNG -static int stbi__png_test(stbi__context *s); -static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); -static int stbi__png_is16(stbi__context *s); -#endif - -#ifndef STBI_NO_BMP -static int stbi__bmp_test(stbi__context *s); -static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_TGA -static int stbi__tga_test(stbi__context *s); -static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_PSD -static int stbi__psd_test(stbi__context *s); -static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc); -static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); -static int stbi__psd_is16(stbi__context *s); -#endif - -#ifndef STBI_NO_HDR -static int stbi__hdr_test(stbi__context *s); -static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_PIC -static int stbi__pic_test(stbi__context *s); -static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_GIF -static int stbi__gif_test(stbi__context *s); -static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp); -static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_PNM -static int stbi__pnm_test(stbi__context *s); -static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); -static int stbi__pnm_is16(stbi__context *s); -#endif - -static -#ifdef STBI_THREAD_LOCAL -STBI_THREAD_LOCAL -#endif -const char *stbi__g_failure_reason; - -STBIDEF const char *stbi_failure_reason(void) -{ - return stbi__g_failure_reason; -} - -#ifndef STBI_NO_FAILURE_STRINGS -static int stbi__err(const char *str) -{ - stbi__g_failure_reason = str; - return 0; -} -#endif - -static void *stbi__malloc(size_t size) -{ - return STBI_MALLOC(size); -} - -// stb_image uses ints pervasively, including for offset calculations. -// therefore the largest decoded image size we can support with the -// current code, even on 64-bit targets, is INT_MAX. this is not a -// significant limitation for the intended use case. -// -// we do, however, need to make sure our size calculations don't -// overflow. hence a few helper functions for size calculations that -// multiply integers together, making sure that they're non-negative -// and no overflow occurs. - -// return 1 if the sum is valid, 0 on overflow. -// negative terms are considered invalid. -static int stbi__addsizes_valid(int a, int b) -{ - if (b < 0) return 0; - // now 0 <= b <= INT_MAX, hence also - // 0 <= INT_MAX - b <= INTMAX. - // And "a + b <= INT_MAX" (which might overflow) is the - // same as a <= INT_MAX - b (no overflow) - return a <= INT_MAX - b; -} - -// returns 1 if the product is valid, 0 on overflow. -// negative factors are considered invalid. -static int stbi__mul2sizes_valid(int a, int b) -{ - if (a < 0 || b < 0) return 0; - if (b == 0) return 1; // mul-by-0 is always safe - // portable way to check for no overflows in a*b - return a <= INT_MAX/b; -} - -#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) -// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow -static int stbi__mad2sizes_valid(int a, int b, int add) -{ - return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add); -} -#endif - -// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow -static int stbi__mad3sizes_valid(int a, int b, int c, int add) -{ - return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && - stbi__addsizes_valid(a*b*c, add); -} - -// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow -#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) -static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) -{ - return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && - stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add); -} -#endif - -#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) -// mallocs with size overflow checking -static void *stbi__malloc_mad2(int a, int b, int add) -{ - if (!stbi__mad2sizes_valid(a, b, add)) return NULL; - return stbi__malloc(a*b + add); -} -#endif - -static void *stbi__malloc_mad3(int a, int b, int c, int add) -{ - if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; - return stbi__malloc(a*b*c + add); -} - -#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) -static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) -{ - if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; - return stbi__malloc(a*b*c*d + add); -} -#endif - -// returns 1 if the sum of two signed ints is valid (between -2^31 and 2^31-1 inclusive), 0 on overflow. -static int stbi__addints_valid(int a, int b) -{ - if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow - if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0. - return a <= INT_MAX - b; -} - -// returns 1 if the product of two ints fits in a signed short, 0 on overflow. -static int stbi__mul2shorts_valid(int a, int b) -{ - if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow - if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid - if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN - return a >= SHRT_MIN / b; -} - -// stbi__err - error -// stbi__errpf - error returning pointer to float -// stbi__errpuc - error returning pointer to unsigned char - -#ifdef STBI_NO_FAILURE_STRINGS - #define stbi__err(x,y) 0 -#elif defined(STBI_FAILURE_USERMSG) - #define stbi__err(x,y) stbi__err(y) -#else - #define stbi__err(x,y) stbi__err(x) -#endif - -#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) -#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) - -STBIDEF void stbi_image_free(void *retval_from_stbi_load) -{ - STBI_FREE(retval_from_stbi_load); -} - -#ifndef STBI_NO_LINEAR -static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); -#endif - -#ifndef STBI_NO_HDR -static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); -#endif - -static int stbi__vertically_flip_on_load_global = 0; - -STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) -{ - stbi__vertically_flip_on_load_global = flag_true_if_should_flip; -} - -#ifndef STBI_THREAD_LOCAL -#define stbi__vertically_flip_on_load stbi__vertically_flip_on_load_global -#else -static STBI_THREAD_LOCAL int stbi__vertically_flip_on_load_local, stbi__vertically_flip_on_load_set; - -STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip) -{ - stbi__vertically_flip_on_load_local = flag_true_if_should_flip; - stbi__vertically_flip_on_load_set = 1; -} - -#define stbi__vertically_flip_on_load (stbi__vertically_flip_on_load_set \ - ? stbi__vertically_flip_on_load_local \ - : stbi__vertically_flip_on_load_global) -#endif // STBI_THREAD_LOCAL - -static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) -{ - memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields - ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed - ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order - ri->num_channels = 0; - - // test the formats with a very explicit header first (at least a FOURCC - // or distinctive magic number first) - #ifndef STBI_NO_PNG - if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri); - #endif - #ifndef STBI_NO_BMP - if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri); - #endif - #ifndef STBI_NO_GIF - if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri); - #endif - #ifndef STBI_NO_PSD - if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc); - #else - STBI_NOTUSED(bpc); - #endif - #ifndef STBI_NO_PIC - if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri); - #endif - - // then the formats that can end up attempting to load with just 1 or 2 - // bytes matching expectations; these are prone to false positives, so - // try them later - #ifndef STBI_NO_JPEG - if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); - #endif - #ifndef STBI_NO_PNM - if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri); - #endif - - #ifndef STBI_NO_HDR - if (stbi__hdr_test(s)) { - float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri); - return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); - } - #endif - - #ifndef STBI_NO_TGA - // test tga last because it's a crappy test! - if (stbi__tga_test(s)) - return stbi__tga_load(s,x,y,comp,req_comp, ri); - #endif - - return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); -} - -static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels) -{ - int i; - int img_len = w * h * channels; - stbi_uc *reduced; - - reduced = (stbi_uc *) stbi__malloc(img_len); - if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); - - for (i = 0; i < img_len; ++i) - reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling - - STBI_FREE(orig); - return reduced; -} - -static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels) -{ - int i; - int img_len = w * h * channels; - stbi__uint16 *enlarged; - - enlarged = (stbi__uint16 *) stbi__malloc(img_len*2); - if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); - - for (i = 0; i < img_len; ++i) - enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff - - STBI_FREE(orig); - return enlarged; -} - -static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel) -{ - int row; - size_t bytes_per_row = (size_t)w * bytes_per_pixel; - stbi_uc temp[2048]; - stbi_uc *bytes = (stbi_uc *)image; - - for (row = 0; row < (h>>1); row++) { - stbi_uc *row0 = bytes + row*bytes_per_row; - stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row; - // swap row0 with row1 - size_t bytes_left = bytes_per_row; - while (bytes_left) { - size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); - memcpy(temp, row0, bytes_copy); - memcpy(row0, row1, bytes_copy); - memcpy(row1, temp, bytes_copy); - row0 += bytes_copy; - row1 += bytes_copy; - bytes_left -= bytes_copy; - } - } -} - -#ifndef STBI_NO_GIF -static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel) -{ - int slice; - int slice_size = w * h * bytes_per_pixel; - - stbi_uc *bytes = (stbi_uc *)image; - for (slice = 0; slice < z; ++slice) { - stbi__vertical_flip(bytes, w, h, bytes_per_pixel); - bytes += slice_size; - } -} -#endif - -static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - stbi__result_info ri; - void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); - - if (result == NULL) - return NULL; - - // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. - STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); - - if (ri.bits_per_channel != 8) { - result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp); - ri.bits_per_channel = 8; - } - - // @TODO: move stbi__convert_format to here - - if (stbi__vertically_flip_on_load) { - int channels = req_comp ? req_comp : *comp; - stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); - } - - return (unsigned char *) result; -} - -static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - stbi__result_info ri; - void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16); - - if (result == NULL) - return NULL; - - // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. - STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); - - if (ri.bits_per_channel != 16) { - result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp); - ri.bits_per_channel = 16; - } - - // @TODO: move stbi__convert_format16 to here - // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision - - if (stbi__vertically_flip_on_load) { - int channels = req_comp ? req_comp : *comp; - stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16)); - } - - return (stbi__uint16 *) result; -} - -#if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR) -static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) -{ - if (stbi__vertically_flip_on_load && result != NULL) { - int channels = req_comp ? req_comp : *comp; - stbi__vertical_flip(result, *x, *y, channels * sizeof(float)); - } -} -#endif - -#ifndef STBI_NO_STDIO - -#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) -STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); -STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); -#endif - -#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) -STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) -{ - return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); -} -#endif - -static FILE *stbi__fopen(char const *filename, char const *mode) -{ - FILE *f; -#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) - wchar_t wMode[64]; - wchar_t wFilename[1024]; - if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename))) - return 0; - - if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode))) - return 0; - -#if defined(_MSC_VER) && _MSC_VER >= 1400 - if (0 != _wfopen_s(&f, wFilename, wMode)) - f = 0; -#else - f = _wfopen(wFilename, wMode); -#endif - -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - if (0 != fopen_s(&f, filename, mode)) - f=0; -#else - f = fopen(filename, mode); -#endif - return f; -} - - -STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) -{ - FILE *f = stbi__fopen(filename, "rb"); - unsigned char *result; - if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); - result = stbi_load_from_file(f,x,y,comp,req_comp); - fclose(f); - return result; -} - -STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - unsigned char *result; - stbi__context s; - stbi__start_file(&s,f); - result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); - if (result) { - // need to 'unget' all the characters in the IO buffer - fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); - } - return result; -} - -STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - stbi__uint16 *result; - stbi__context s; - stbi__start_file(&s,f); - result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp); - if (result) { - // need to 'unget' all the characters in the IO buffer - fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); - } - return result; -} - -STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp) -{ - FILE *f = stbi__fopen(filename, "rb"); - stbi__uint16 *result; - if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file"); - result = stbi_load_from_file_16(f,x,y,comp,req_comp); - fclose(f); - return result; -} - - -#endif //!STBI_NO_STDIO - -STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels) -{ - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); -} - -STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); - return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); -} - -STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); -} - -STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); -} - -#ifndef STBI_NO_GIF -STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp) -{ - unsigned char *result; - stbi__context s; - stbi__start_mem(&s,buffer,len); - - result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp); - if (stbi__vertically_flip_on_load) { - stbi__vertical_flip_slices( result, *x, *y, *z, *comp ); - } - - return result; -} -#endif - -#ifndef STBI_NO_LINEAR -static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - unsigned char *data; - #ifndef STBI_NO_HDR - if (stbi__hdr_test(s)) { - stbi__result_info ri; - float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri); - if (hdr_data) - stbi__float_postprocess(hdr_data,x,y,comp,req_comp); - return hdr_data; - } - #endif - data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); - if (data) - return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); - return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); -} - -STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__loadf_main(&s,x,y,comp,req_comp); -} - -STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi__loadf_main(&s,x,y,comp,req_comp); -} - -#ifndef STBI_NO_STDIO -STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) -{ - float *result; - FILE *f = stbi__fopen(filename, "rb"); - if (!f) return stbi__errpf("can't fopen", "Unable to open file"); - result = stbi_loadf_from_file(f,x,y,comp,req_comp); - fclose(f); - return result; -} - -STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_file(&s,f); - return stbi__loadf_main(&s,x,y,comp,req_comp); -} -#endif // !STBI_NO_STDIO - -#endif // !STBI_NO_LINEAR - -// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is -// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always -// reports false! - -STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) -{ - #ifndef STBI_NO_HDR - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__hdr_test(&s); - #else - STBI_NOTUSED(buffer); - STBI_NOTUSED(len); - return 0; - #endif -} - -#ifndef STBI_NO_STDIO -STBIDEF int stbi_is_hdr (char const *filename) -{ - FILE *f = stbi__fopen(filename, "rb"); - int result=0; - if (f) { - result = stbi_is_hdr_from_file(f); - fclose(f); - } - return result; -} - -STBIDEF int stbi_is_hdr_from_file(FILE *f) -{ - #ifndef STBI_NO_HDR - long pos = ftell(f); - int res; - stbi__context s; - stbi__start_file(&s,f); - res = stbi__hdr_test(&s); - fseek(f, pos, SEEK_SET); - return res; - #else - STBI_NOTUSED(f); - return 0; - #endif -} -#endif // !STBI_NO_STDIO - -STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) -{ - #ifndef STBI_NO_HDR - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi__hdr_test(&s); - #else - STBI_NOTUSED(clbk); - STBI_NOTUSED(user); - return 0; - #endif -} - -#ifndef STBI_NO_LINEAR -static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; - -STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } -STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } -#endif - -static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; - -STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } -STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } - - -////////////////////////////////////////////////////////////////////////////// -// -// Common code used by all image loaders -// - -enum -{ - STBI__SCAN_load=0, - STBI__SCAN_type, - STBI__SCAN_header -}; - -static void stbi__refill_buffer(stbi__context *s) -{ - int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); - s->callback_already_read += (int) (s->img_buffer - s->img_buffer_original); - if (n == 0) { - // at end of file, treat same as if from memory, but need to handle case - // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file - s->read_from_callbacks = 0; - s->img_buffer = s->buffer_start; - s->img_buffer_end = s->buffer_start+1; - *s->img_buffer = 0; - } else { - s->img_buffer = s->buffer_start; - s->img_buffer_end = s->buffer_start + n; - } -} - -stbi_inline static stbi_uc stbi__get8(stbi__context *s) -{ - if (s->img_buffer < s->img_buffer_end) - return *s->img_buffer++; - if (s->read_from_callbacks) { - stbi__refill_buffer(s); - return *s->img_buffer++; - } - return 0; -} - -#if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) -// nothing -#else -stbi_inline static int stbi__at_eof(stbi__context *s) -{ - if (s->io.read) { - if (!(s->io.eof)(s->io_user_data)) return 0; - // if feof() is true, check if buffer = end - // special case: we've only got the special 0 character at the end - if (s->read_from_callbacks == 0) return 1; - } - - return s->img_buffer >= s->img_buffer_end; -} -#endif - -#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) -// nothing -#else -static void stbi__skip(stbi__context *s, int n) -{ - if (n == 0) return; // already there! - if (n < 0) { - s->img_buffer = s->img_buffer_end; - return; - } - if (s->io.read) { - int blen = (int) (s->img_buffer_end - s->img_buffer); - if (blen < n) { - s->img_buffer = s->img_buffer_end; - (s->io.skip)(s->io_user_data, n - blen); - return; - } - } - s->img_buffer += n; -} -#endif - -#if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) -// nothing -#else -static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) -{ - if (s->io.read) { - int blen = (int) (s->img_buffer_end - s->img_buffer); - if (blen < n) { - int res, count; - - memcpy(buffer, s->img_buffer, blen); - - count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); - res = (count == (n-blen)); - s->img_buffer = s->img_buffer_end; - return res; - } - } - - if (s->img_buffer+n <= s->img_buffer_end) { - memcpy(buffer, s->img_buffer, n); - s->img_buffer += n; - return 1; - } else - return 0; -} -#endif - -#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) -// nothing -#else -static int stbi__get16be(stbi__context *s) -{ - int z = stbi__get8(s); - return (z << 8) + stbi__get8(s); -} -#endif - -#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) -// nothing -#else -static stbi__uint32 stbi__get32be(stbi__context *s) -{ - stbi__uint32 z = stbi__get16be(s); - return (z << 16) + stbi__get16be(s); -} -#endif - -#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) -// nothing -#else -static int stbi__get16le(stbi__context *s) -{ - int z = stbi__get8(s); - return z + (stbi__get8(s) << 8); -} -#endif - -#ifndef STBI_NO_BMP -static stbi__uint32 stbi__get32le(stbi__context *s) -{ - stbi__uint32 z = stbi__get16le(s); - z += (stbi__uint32)stbi__get16le(s) << 16; - return z; -} -#endif - -#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings - -#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) -// nothing -#else -////////////////////////////////////////////////////////////////////////////// -// -// generic converter from built-in img_n to req_comp -// individual types do this automatically as much as possible (e.g. jpeg -// does all cases internally since it needs to colorspace convert anyway, -// and it never has alpha, so very few cases ). png can automatically -// interleave an alpha=255 channel, but falls back to this for other cases -// -// assume data buffer is malloced, so malloc a new one and free that one -// only failure mode is malloc failing - -static stbi_uc stbi__compute_y(int r, int g, int b) -{ - return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); -} -#endif - -#if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) -// nothing -#else -static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y) -{ - int i,j; - unsigned char *good; - - if (req_comp == img_n) return data; - STBI_ASSERT(req_comp >= 1 && req_comp <= 4); - - good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0); - if (good == NULL) { - STBI_FREE(data); - return stbi__errpuc("outofmem", "Out of memory"); - } - - for (j=0; j < (int) y; ++j) { - unsigned char *src = data + j * x * img_n ; - unsigned char *dest = good + j * x * req_comp; - - #define STBI__COMBO(a,b) ((a)*8+(b)) - #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) - // convert source image with img_n components to one with req_comp components; - // avoid switch per pixel, so use switch per scanline and massive macros - switch (STBI__COMBO(img_n, req_comp)) { - STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break; - STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break; - STBI__CASE(2,1) { dest[0]=src[0]; } break; - STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; - STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255; } break; - STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; - STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break; - STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; - STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break; - STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; - default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); - } - #undef STBI__CASE - } - - STBI_FREE(data); - return good; -} -#endif - -#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) -// nothing -#else -static stbi__uint16 stbi__compute_y_16(int r, int g, int b) -{ - return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8); -} -#endif - -#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) -// nothing -#else -static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y) -{ - int i,j; - stbi__uint16 *good; - - if (req_comp == img_n) return data; - STBI_ASSERT(req_comp >= 1 && req_comp <= 4); - - good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2); - if (good == NULL) { - STBI_FREE(data); - return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); - } - - for (j=0; j < (int) y; ++j) { - stbi__uint16 *src = data + j * x * img_n ; - stbi__uint16 *dest = good + j * x * req_comp; - - #define STBI__COMBO(a,b) ((a)*8+(b)) - #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) - // convert source image with img_n components to one with req_comp components; - // avoid switch per pixel, so use switch per scanline and massive macros - switch (STBI__COMBO(img_n, req_comp)) { - STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff; } break; - STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff; } break; - STBI__CASE(2,1) { dest[0]=src[0]; } break; - STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; - STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff; } break; - STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; - STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break; - STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; - STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break; - STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; - default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*) stbi__errpuc("unsupported", "Unsupported format conversion"); - } - #undef STBI__CASE - } - - STBI_FREE(data); - return good; -} -#endif - -#ifndef STBI_NO_LINEAR -static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) -{ - int i,k,n; - float *output; - if (!data) return NULL; - output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0); - if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } - // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp-1; - for (i=0; i < x*y; ++i) { - for (k=0; k < n; ++k) { - output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); - } - } - if (n < comp) { - for (i=0; i < x*y; ++i) { - output[i*comp + n] = data[i*comp + n]/255.0f; - } - } - STBI_FREE(data); - return output; -} -#endif - -#ifndef STBI_NO_HDR -#define stbi__float2int(x) ((int) (x)) -static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) -{ - int i,k,n; - stbi_uc *output; - if (!data) return NULL; - output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0); - if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } - // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp-1; - for (i=0; i < x*y; ++i) { - for (k=0; k < n; ++k) { - float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i*comp + k] = (stbi_uc) stbi__float2int(z); - } - if (k < comp) { - float z = data[i*comp+k] * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i*comp + k] = (stbi_uc) stbi__float2int(z); - } - } - STBI_FREE(data); - return output; -} -#endif - -////////////////////////////////////////////////////////////////////////////// -// -// "baseline" JPEG/JFIF decoder -// -// simple implementation -// - doesn't support delayed output of y-dimension -// - simple interface (only one output format: 8-bit interleaved RGB) -// - doesn't try to recover corrupt jpegs -// - doesn't allow partial loading, loading multiple at once -// - still fast on x86 (copying globals into locals doesn't help x86) -// - allocates lots of intermediate memory (full size of all components) -// - non-interleaved case requires this anyway -// - allows good upsampling (see next) -// high-quality -// - upsampled channels are bilinearly interpolated, even across blocks -// - quality integer IDCT derived from IJG's 'slow' -// performance -// - fast huffman; reasonable integer IDCT -// - some SIMD kernels for common paths on targets with SSE2/NEON -// - uses a lot of intermediate memory, could cache poorly - -#ifndef STBI_NO_JPEG - -// huffman decoding acceleration -#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache - -typedef struct -{ - stbi_uc fast[1 << FAST_BITS]; - // weirdly, repacking this into AoS is a 10% speed loss, instead of a win - stbi__uint16 code[256]; - stbi_uc values[256]; - stbi_uc size[257]; - unsigned int maxcode[18]; - int delta[17]; // old 'firstsymbol' - old 'firstcode' -} stbi__huffman; - -typedef struct -{ - stbi__context *s; - stbi__huffman huff_dc[4]; - stbi__huffman huff_ac[4]; - stbi__uint16 dequant[4][64]; - stbi__int16 fast_ac[4][1 << FAST_BITS]; - -// sizes for components, interleaved MCUs - int img_h_max, img_v_max; - int img_mcu_x, img_mcu_y; - int img_mcu_w, img_mcu_h; - -// definition of jpeg image component - struct - { - int id; - int h,v; - int tq; - int hd,ha; - int dc_pred; - - int x,y,w2,h2; - stbi_uc *data; - void *raw_data, *raw_coeff; - stbi_uc *linebuf; - short *coeff; // progressive only - int coeff_w, coeff_h; // number of 8x8 coefficient blocks - } img_comp[4]; - - stbi__uint32 code_buffer; // jpeg entropy-coded buffer - int code_bits; // number of valid bits - unsigned char marker; // marker seen while filling entropy buffer - int nomore; // flag if we saw a marker so must stop - - int progressive; - int spec_start; - int spec_end; - int succ_high; - int succ_low; - int eob_run; - int jfif; - int app14_color_transform; // Adobe APP14 tag - int rgb; - - int scan_n, order[4]; - int restart_interval, todo; - -// kernels - void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]); - void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step); - stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs); -} stbi__jpeg; - -static int stbi__build_huffman(stbi__huffman *h, int *count) -{ - int i,j,k=0; - unsigned int code; - // build size list for each symbol (from JPEG spec) - for (i=0; i < 16; ++i) { - for (j=0; j < count[i]; ++j) { - h->size[k++] = (stbi_uc) (i+1); - if(k >= 257) return stbi__err("bad size list","Corrupt JPEG"); - } - } - h->size[k] = 0; - - // compute actual symbols (from jpeg spec) - code = 0; - k = 0; - for(j=1; j <= 16; ++j) { - // compute delta to add to code to compute symbol id - h->delta[j] = k - code; - if (h->size[k] == j) { - while (h->size[k] == j) - h->code[k++] = (stbi__uint16) (code++); - if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG"); - } - // compute largest code + 1 for this size, preshifted as needed later - h->maxcode[j] = code << (16-j); - code <<= 1; - } - h->maxcode[j] = 0xffffffff; - - // build non-spec acceleration table; 255 is flag for not-accelerated - memset(h->fast, 255, 1 << FAST_BITS); - for (i=0; i < k; ++i) { - int s = h->size[i]; - if (s <= FAST_BITS) { - int c = h->code[i] << (FAST_BITS-s); - int m = 1 << (FAST_BITS-s); - for (j=0; j < m; ++j) { - h->fast[c+j] = (stbi_uc) i; - } - } - } - return 1; -} - -// build a table that decodes both magnitude and value of small ACs in -// one go. -static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) -{ - int i; - for (i=0; i < (1 << FAST_BITS); ++i) { - stbi_uc fast = h->fast[i]; - fast_ac[i] = 0; - if (fast < 255) { - int rs = h->values[fast]; - int run = (rs >> 4) & 15; - int magbits = rs & 15; - int len = h->size[fast]; - - if (magbits && len + magbits <= FAST_BITS) { - // magnitude code followed by receive_extend code - int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); - int m = 1 << (magbits - 1); - if (k < m) k += (~0U << magbits) + 1; - // if the result is small enough, we can fit it in fast_ac table - if (k >= -128 && k <= 127) - fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits)); - } - } - } -} - -static void stbi__grow_buffer_unsafe(stbi__jpeg *j) -{ - do { - unsigned int b = j->nomore ? 0 : stbi__get8(j->s); - if (b == 0xff) { - int c = stbi__get8(j->s); - while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes - if (c != 0) { - j->marker = (unsigned char) c; - j->nomore = 1; - return; - } - } - j->code_buffer |= b << (24 - j->code_bits); - j->code_bits += 8; - } while (j->code_bits <= 24); -} - -// (1 << n) - 1 -static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; - -// decode a jpeg huffman value from the bitstream -stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) -{ - unsigned int temp; - int c,k; - - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - - // look at the top FAST_BITS and determine what symbol ID it is, - // if the code is <= FAST_BITS - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); - k = h->fast[c]; - if (k < 255) { - int s = h->size[k]; - if (s > j->code_bits) - return -1; - j->code_buffer <<= s; - j->code_bits -= s; - return h->values[k]; - } - - // naive test is to shift the code_buffer down so k bits are - // valid, then test against maxcode. To speed this up, we've - // preshifted maxcode left so that it has (16-k) 0s at the - // end; in other words, regardless of the number of bits, it - // wants to be compared against something shifted to have 16; - // that way we don't need to shift inside the loop. - temp = j->code_buffer >> 16; - for (k=FAST_BITS+1 ; ; ++k) - if (temp < h->maxcode[k]) - break; - if (k == 17) { - // error! code not found - j->code_bits -= 16; - return -1; - } - - if (k > j->code_bits) - return -1; - - // convert the huffman code to the symbol id - c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; - if(c < 0 || c >= 256) // symbol id out of bounds! - return -1; - STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); - - // convert the id to a symbol - j->code_bits -= k; - j->code_buffer <<= k; - return h->values[c]; -} - -// bias[n] = (-1<<n) + 1 -static const int stbi__jbias[16] = {0,-1,-3,-7,-15,-31,-63,-127,-255,-511,-1023,-2047,-4095,-8191,-16383,-32767}; - -// combined JPEG 'receive' and JPEG 'extend', since baseline -// always extends everything it receives. -stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n) -{ - unsigned int k; - int sgn; - if (j->code_bits < n) stbi__grow_buffer_unsafe(j); - if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing - - sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) - k = stbi_lrot(j->code_buffer, n); - j->code_buffer = k & ~stbi__bmask[n]; - k &= stbi__bmask[n]; - j->code_bits -= n; - return k + (stbi__jbias[n] & (sgn - 1)); -} - -// get some unsigned bits -stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) -{ - unsigned int k; - if (j->code_bits < n) stbi__grow_buffer_unsafe(j); - if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing - k = stbi_lrot(j->code_buffer, n); - j->code_buffer = k & ~stbi__bmask[n]; - k &= stbi__bmask[n]; - j->code_bits -= n; - return k; -} - -stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) -{ - unsigned int k; - if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); - if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing - k = j->code_buffer; - j->code_buffer <<= 1; - --j->code_bits; - return k & 0x80000000; -} - -// given a value that's at position X in the zigzag stream, -// where does it appear in the 8x8 matrix coded as row-major? -static const stbi_uc stbi__jpeg_dezigzag[64+15] = -{ - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63, - // let corrupt input sample past end - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63 -}; - -// decode one 64-entry block-- -static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant) -{ - int diff,dc,k; - int t; - - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - t = stbi__jpeg_huff_decode(j, hdc); - if (t < 0 || t > 15) return stbi__err("bad huffman code","Corrupt JPEG"); - - // 0 all the ac values now so we can do it 32-bits at a time - memset(data,0,64*sizeof(data[0])); - - diff = t ? stbi__extend_receive(j, t) : 0; - if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta","Corrupt JPEG"); - dc = j->img_comp[b].dc_pred + diff; - j->img_comp[b].dc_pred = dc; - if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - data[0] = (short) (dc * dequant[0]); - - // decode AC components, see JPEG spec - k = 1; - do { - unsigned int zig; - int c,r,s; - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); - r = fac[c]; - if (r) { // fast-AC path - k += (r >> 4) & 15; // run - s = r & 15; // combined length - if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); - j->code_buffer <<= s; - j->code_bits -= s; - // decode into unzigzag'd location - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) ((r >> 8) * dequant[zig]); - } else { - int rs = stbi__jpeg_huff_decode(j, hac); - if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (rs != 0xf0) break; // end block - k += 16; - } else { - k += r; - // decode into unzigzag'd location - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]); - } - } - } while (k < 64); - return 1; -} - -static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) -{ - int diff,dc; - int t; - if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - - if (j->succ_high == 0) { - // first scan for DC coefficient, must be first - memset(data,0,64*sizeof(data[0])); // 0 all the ac values now - t = stbi__jpeg_huff_decode(j, hdc); - if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - diff = t ? stbi__extend_receive(j, t) : 0; - - if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); - dc = j->img_comp[b].dc_pred + diff; - j->img_comp[b].dc_pred = dc; - if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - data[0] = (short) (dc * (1 << j->succ_low)); - } else { - // refinement scan for DC coefficient - if (stbi__jpeg_get_bit(j)) - data[0] += (short) (1 << j->succ_low); - } - return 1; -} - -// @OPTIMIZE: store non-zigzagged during the decode passes, -// and only de-zigzag when dequantizing -static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) -{ - int k; - if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - - if (j->succ_high == 0) { - int shift = j->succ_low; - - if (j->eob_run) { - --j->eob_run; - return 1; - } - - k = j->spec_start; - do { - unsigned int zig; - int c,r,s; - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); - r = fac[c]; - if (r) { // fast-AC path - k += (r >> 4) & 15; // run - s = r & 15; // combined length - if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); - j->code_buffer <<= s; - j->code_bits -= s; - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) ((r >> 8) * (1 << shift)); - } else { - int rs = stbi__jpeg_huff_decode(j, hac); - if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (r < 15) { - j->eob_run = (1 << r); - if (r) - j->eob_run += stbi__jpeg_get_bits(j, r); - --j->eob_run; - break; - } - k += 16; - } else { - k += r; - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) (stbi__extend_receive(j,s) * (1 << shift)); - } - } - } while (k <= j->spec_end); - } else { - // refinement scan for these AC coefficients - - short bit = (short) (1 << j->succ_low); - - if (j->eob_run) { - --j->eob_run; - for (k = j->spec_start; k <= j->spec_end; ++k) { - short *p = &data[stbi__jpeg_dezigzag[k]]; - if (*p != 0) - if (stbi__jpeg_get_bit(j)) - if ((*p & bit)==0) { - if (*p > 0) - *p += bit; - else - *p -= bit; - } - } - } else { - k = j->spec_start; - do { - int r,s; - int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh - if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (r < 15) { - j->eob_run = (1 << r) - 1; - if (r) - j->eob_run += stbi__jpeg_get_bits(j, r); - r = 64; // force end of block - } else { - // r=15 s=0 should write 16 0s, so we just do - // a run of 15 0s and then write s (which is 0), - // so we don't have to do anything special here - } - } else { - if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); - // sign bit - if (stbi__jpeg_get_bit(j)) - s = bit; - else - s = -bit; - } - - // advance by r - while (k <= j->spec_end) { - short *p = &data[stbi__jpeg_dezigzag[k++]]; - if (*p != 0) { - if (stbi__jpeg_get_bit(j)) - if ((*p & bit)==0) { - if (*p > 0) - *p += bit; - else - *p -= bit; - } - } else { - if (r == 0) { - *p = (short) s; - break; - } - --r; - } - } - } while (k <= j->spec_end); - } - } - return 1; -} - -// take a -128..127 value and stbi__clamp it and convert to 0..255 -stbi_inline static stbi_uc stbi__clamp(int x) -{ - // trick to use a single test to catch both cases - if ((unsigned int) x > 255) { - if (x < 0) return 0; - if (x > 255) return 255; - } - return (stbi_uc) x; -} - -#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) -#define stbi__fsh(x) ((x) * 4096) - -// derived from jidctint -- DCT_ISLOW -#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ - int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ - p2 = s2; \ - p3 = s6; \ - p1 = (p2+p3) * stbi__f2f(0.5411961f); \ - t2 = p1 + p3*stbi__f2f(-1.847759065f); \ - t3 = p1 + p2*stbi__f2f( 0.765366865f); \ - p2 = s0; \ - p3 = s4; \ - t0 = stbi__fsh(p2+p3); \ - t1 = stbi__fsh(p2-p3); \ - x0 = t0+t3; \ - x3 = t0-t3; \ - x1 = t1+t2; \ - x2 = t1-t2; \ - t0 = s7; \ - t1 = s5; \ - t2 = s3; \ - t3 = s1; \ - p3 = t0+t2; \ - p4 = t1+t3; \ - p1 = t0+t3; \ - p2 = t1+t2; \ - p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ - t0 = t0*stbi__f2f( 0.298631336f); \ - t1 = t1*stbi__f2f( 2.053119869f); \ - t2 = t2*stbi__f2f( 3.072711026f); \ - t3 = t3*stbi__f2f( 1.501321110f); \ - p1 = p5 + p1*stbi__f2f(-0.899976223f); \ - p2 = p5 + p2*stbi__f2f(-2.562915447f); \ - p3 = p3*stbi__f2f(-1.961570560f); \ - p4 = p4*stbi__f2f(-0.390180644f); \ - t3 += p1+p4; \ - t2 += p2+p3; \ - t1 += p2+p4; \ - t0 += p1+p3; - -static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) -{ - int i,val[64],*v=val; - stbi_uc *o; - short *d = data; - - // columns - for (i=0; i < 8; ++i,++d, ++v) { - // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing - if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 - && d[40]==0 && d[48]==0 && d[56]==0) { - // no shortcut 0 seconds - // (1|2|3|4|5|6|7)==0 0 seconds - // all separate -0.047 seconds - // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds - int dcterm = d[0]*4; - v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; - } else { - STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) - // constants scaled things up by 1<<12; let's bring them back - // down, but keep 2 extra bits of precision - x0 += 512; x1 += 512; x2 += 512; x3 += 512; - v[ 0] = (x0+t3) >> 10; - v[56] = (x0-t3) >> 10; - v[ 8] = (x1+t2) >> 10; - v[48] = (x1-t2) >> 10; - v[16] = (x2+t1) >> 10; - v[40] = (x2-t1) >> 10; - v[24] = (x3+t0) >> 10; - v[32] = (x3-t0) >> 10; - } - } - - for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { - // no fast case since the first 1D IDCT spread components out - STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) - // constants scaled things up by 1<<12, plus we had 1<<2 from first - // loop, plus horizontal and vertical each scale by sqrt(8) so together - // we've got an extra 1<<3, so 1<<17 total we need to remove. - // so we want to round that, which means adding 0.5 * 1<<17, - // aka 65536. Also, we'll end up with -128 to 127 that we want - // to encode as 0..255 by adding 128, so we'll add that before the shift - x0 += 65536 + (128<<17); - x1 += 65536 + (128<<17); - x2 += 65536 + (128<<17); - x3 += 65536 + (128<<17); - // tried computing the shifts into temps, or'ing the temps to see - // if any were out of range, but that was slower - o[0] = stbi__clamp((x0+t3) >> 17); - o[7] = stbi__clamp((x0-t3) >> 17); - o[1] = stbi__clamp((x1+t2) >> 17); - o[6] = stbi__clamp((x1-t2) >> 17); - o[2] = stbi__clamp((x2+t1) >> 17); - o[5] = stbi__clamp((x2-t1) >> 17); - o[3] = stbi__clamp((x3+t0) >> 17); - o[4] = stbi__clamp((x3-t0) >> 17); - } -} - -#ifdef STBI_SSE2 -// sse2 integer IDCT. not the fastest possible implementation but it -// produces bit-identical results to the generic C version so it's -// fully "transparent". -static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) -{ - // This is constructed to match our regular (generic) integer IDCT exactly. - __m128i row0, row1, row2, row3, row4, row5, row6, row7; - __m128i tmp; - - // dot product constant: even elems=x, odd elems=y - #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) - - // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) - // out(1) = c1[even]*x + c1[odd]*y - #define dct_rot(out0,out1, x,y,c0,c1) \ - __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ - __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ - __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ - __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ - __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ - __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) - - // out = in << 12 (in 16-bit, out 32-bit) - #define dct_widen(out, in) \ - __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ - __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) - - // wide add - #define dct_wadd(out, a, b) \ - __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ - __m128i out##_h = _mm_add_epi32(a##_h, b##_h) - - // wide sub - #define dct_wsub(out, a, b) \ - __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ - __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) - - // butterfly a/b, add bias, then shift by "s" and pack - #define dct_bfly32o(out0, out1, a,b,bias,s) \ - { \ - __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ - __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ - dct_wadd(sum, abiased, b); \ - dct_wsub(dif, abiased, b); \ - out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ - out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ - } - - // 8-bit interleave step (for transposes) - #define dct_interleave8(a, b) \ - tmp = a; \ - a = _mm_unpacklo_epi8(a, b); \ - b = _mm_unpackhi_epi8(tmp, b) - - // 16-bit interleave step (for transposes) - #define dct_interleave16(a, b) \ - tmp = a; \ - a = _mm_unpacklo_epi16(a, b); \ - b = _mm_unpackhi_epi16(tmp, b) - - #define dct_pass(bias,shift) \ - { \ - /* even part */ \ - dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ - __m128i sum04 = _mm_add_epi16(row0, row4); \ - __m128i dif04 = _mm_sub_epi16(row0, row4); \ - dct_widen(t0e, sum04); \ - dct_widen(t1e, dif04); \ - dct_wadd(x0, t0e, t3e); \ - dct_wsub(x3, t0e, t3e); \ - dct_wadd(x1, t1e, t2e); \ - dct_wsub(x2, t1e, t2e); \ - /* odd part */ \ - dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ - dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ - __m128i sum17 = _mm_add_epi16(row1, row7); \ - __m128i sum35 = _mm_add_epi16(row3, row5); \ - dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ - dct_wadd(x4, y0o, y4o); \ - dct_wadd(x5, y1o, y5o); \ - dct_wadd(x6, y2o, y5o); \ - dct_wadd(x7, y3o, y4o); \ - dct_bfly32o(row0,row7, x0,x7,bias,shift); \ - dct_bfly32o(row1,row6, x1,x6,bias,shift); \ - dct_bfly32o(row2,row5, x2,x5,bias,shift); \ - dct_bfly32o(row3,row4, x3,x4,bias,shift); \ - } - - __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); - __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f)); - __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); - __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); - __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f)); - __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f)); - __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f)); - __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f)); - - // rounding biases in column/row passes, see stbi__idct_block for explanation. - __m128i bias_0 = _mm_set1_epi32(512); - __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); - - // load - row0 = _mm_load_si128((const __m128i *) (data + 0*8)); - row1 = _mm_load_si128((const __m128i *) (data + 1*8)); - row2 = _mm_load_si128((const __m128i *) (data + 2*8)); - row3 = _mm_load_si128((const __m128i *) (data + 3*8)); - row4 = _mm_load_si128((const __m128i *) (data + 4*8)); - row5 = _mm_load_si128((const __m128i *) (data + 5*8)); - row6 = _mm_load_si128((const __m128i *) (data + 6*8)); - row7 = _mm_load_si128((const __m128i *) (data + 7*8)); - - // column pass - dct_pass(bias_0, 10); - - { - // 16bit 8x8 transpose pass 1 - dct_interleave16(row0, row4); - dct_interleave16(row1, row5); - dct_interleave16(row2, row6); - dct_interleave16(row3, row7); - - // transpose pass 2 - dct_interleave16(row0, row2); - dct_interleave16(row1, row3); - dct_interleave16(row4, row6); - dct_interleave16(row5, row7); - - // transpose pass 3 - dct_interleave16(row0, row1); - dct_interleave16(row2, row3); - dct_interleave16(row4, row5); - dct_interleave16(row6, row7); - } - - // row pass - dct_pass(bias_1, 17); - - { - // pack - __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 - __m128i p1 = _mm_packus_epi16(row2, row3); - __m128i p2 = _mm_packus_epi16(row4, row5); - __m128i p3 = _mm_packus_epi16(row6, row7); - - // 8bit 8x8 transpose pass 1 - dct_interleave8(p0, p2); // a0e0a1e1... - dct_interleave8(p1, p3); // c0g0c1g1... - - // transpose pass 2 - dct_interleave8(p0, p1); // a0c0e0g0... - dct_interleave8(p2, p3); // b0d0f0h0... - - // transpose pass 3 - dct_interleave8(p0, p2); // a0b0c0d0... - dct_interleave8(p1, p3); // a4b4c4d4... - - // store - _mm_storel_epi64((__m128i *) out, p0); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i *) out, p2); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i *) out, p1); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i *) out, p3); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); - } - -#undef dct_const -#undef dct_rot -#undef dct_widen -#undef dct_wadd -#undef dct_wsub -#undef dct_bfly32o -#undef dct_interleave8 -#undef dct_interleave16 -#undef dct_pass -} - -#endif // STBI_SSE2 - -#ifdef STBI_NEON - -// NEON integer IDCT. should produce bit-identical -// results to the generic C version. -static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) -{ - int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; - - int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); - int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); - int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f)); - int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f)); - int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); - int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); - int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); - int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); - int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f)); - int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f)); - int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f)); - int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f)); - -#define dct_long_mul(out, inq, coeff) \ - int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ - int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) - -#define dct_long_mac(out, acc, inq, coeff) \ - int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ - int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) - -#define dct_widen(out, inq) \ - int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ - int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) - -// wide add -#define dct_wadd(out, a, b) \ - int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ - int32x4_t out##_h = vaddq_s32(a##_h, b##_h) - -// wide sub -#define dct_wsub(out, a, b) \ - int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ - int32x4_t out##_h = vsubq_s32(a##_h, b##_h) - -// butterfly a/b, then shift using "shiftop" by "s" and pack -#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ - { \ - dct_wadd(sum, a, b); \ - dct_wsub(dif, a, b); \ - out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ - out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ - } - -#define dct_pass(shiftop, shift) \ - { \ - /* even part */ \ - int16x8_t sum26 = vaddq_s16(row2, row6); \ - dct_long_mul(p1e, sum26, rot0_0); \ - dct_long_mac(t2e, p1e, row6, rot0_1); \ - dct_long_mac(t3e, p1e, row2, rot0_2); \ - int16x8_t sum04 = vaddq_s16(row0, row4); \ - int16x8_t dif04 = vsubq_s16(row0, row4); \ - dct_widen(t0e, sum04); \ - dct_widen(t1e, dif04); \ - dct_wadd(x0, t0e, t3e); \ - dct_wsub(x3, t0e, t3e); \ - dct_wadd(x1, t1e, t2e); \ - dct_wsub(x2, t1e, t2e); \ - /* odd part */ \ - int16x8_t sum15 = vaddq_s16(row1, row5); \ - int16x8_t sum17 = vaddq_s16(row1, row7); \ - int16x8_t sum35 = vaddq_s16(row3, row5); \ - int16x8_t sum37 = vaddq_s16(row3, row7); \ - int16x8_t sumodd = vaddq_s16(sum17, sum35); \ - dct_long_mul(p5o, sumodd, rot1_0); \ - dct_long_mac(p1o, p5o, sum17, rot1_1); \ - dct_long_mac(p2o, p5o, sum35, rot1_2); \ - dct_long_mul(p3o, sum37, rot2_0); \ - dct_long_mul(p4o, sum15, rot2_1); \ - dct_wadd(sump13o, p1o, p3o); \ - dct_wadd(sump24o, p2o, p4o); \ - dct_wadd(sump23o, p2o, p3o); \ - dct_wadd(sump14o, p1o, p4o); \ - dct_long_mac(x4, sump13o, row7, rot3_0); \ - dct_long_mac(x5, sump24o, row5, rot3_1); \ - dct_long_mac(x6, sump23o, row3, rot3_2); \ - dct_long_mac(x7, sump14o, row1, rot3_3); \ - dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ - dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ - dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ - dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ - } - - // load - row0 = vld1q_s16(data + 0*8); - row1 = vld1q_s16(data + 1*8); - row2 = vld1q_s16(data + 2*8); - row3 = vld1q_s16(data + 3*8); - row4 = vld1q_s16(data + 4*8); - row5 = vld1q_s16(data + 5*8); - row6 = vld1q_s16(data + 6*8); - row7 = vld1q_s16(data + 7*8); - - // add DC bias - row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); - - // column pass - dct_pass(vrshrn_n_s32, 10); - - // 16bit 8x8 transpose - { -// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. -// whether compilers actually get this is another story, sadly. -#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } -#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } -#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } - - // pass 1 - dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 - dct_trn16(row2, row3); - dct_trn16(row4, row5); - dct_trn16(row6, row7); - - // pass 2 - dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 - dct_trn32(row1, row3); - dct_trn32(row4, row6); - dct_trn32(row5, row7); - - // pass 3 - dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 - dct_trn64(row1, row5); - dct_trn64(row2, row6); - dct_trn64(row3, row7); - -#undef dct_trn16 -#undef dct_trn32 -#undef dct_trn64 - } - - // row pass - // vrshrn_n_s32 only supports shifts up to 16, we need - // 17. so do a non-rounding shift of 16 first then follow - // up with a rounding shift by 1. - dct_pass(vshrn_n_s32, 16); - - { - // pack and round - uint8x8_t p0 = vqrshrun_n_s16(row0, 1); - uint8x8_t p1 = vqrshrun_n_s16(row1, 1); - uint8x8_t p2 = vqrshrun_n_s16(row2, 1); - uint8x8_t p3 = vqrshrun_n_s16(row3, 1); - uint8x8_t p4 = vqrshrun_n_s16(row4, 1); - uint8x8_t p5 = vqrshrun_n_s16(row5, 1); - uint8x8_t p6 = vqrshrun_n_s16(row6, 1); - uint8x8_t p7 = vqrshrun_n_s16(row7, 1); - - // again, these can translate into one instruction, but often don't. -#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } -#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } -#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } - - // sadly can't use interleaved stores here since we only write - // 8 bytes to each scan line! - - // 8x8 8-bit transpose pass 1 - dct_trn8_8(p0, p1); - dct_trn8_8(p2, p3); - dct_trn8_8(p4, p5); - dct_trn8_8(p6, p7); - - // pass 2 - dct_trn8_16(p0, p2); - dct_trn8_16(p1, p3); - dct_trn8_16(p4, p6); - dct_trn8_16(p5, p7); - - // pass 3 - dct_trn8_32(p0, p4); - dct_trn8_32(p1, p5); - dct_trn8_32(p2, p6); - dct_trn8_32(p3, p7); - - // store - vst1_u8(out, p0); out += out_stride; - vst1_u8(out, p1); out += out_stride; - vst1_u8(out, p2); out += out_stride; - vst1_u8(out, p3); out += out_stride; - vst1_u8(out, p4); out += out_stride; - vst1_u8(out, p5); out += out_stride; - vst1_u8(out, p6); out += out_stride; - vst1_u8(out, p7); - -#undef dct_trn8_8 -#undef dct_trn8_16 -#undef dct_trn8_32 - } - -#undef dct_long_mul -#undef dct_long_mac -#undef dct_widen -#undef dct_wadd -#undef dct_wsub -#undef dct_bfly32o -#undef dct_pass -} - -#endif // STBI_NEON - -#define STBI__MARKER_none 0xff -// if there's a pending marker from the entropy stream, return that -// otherwise, fetch from the stream and get a marker. if there's no -// marker, return 0xff, which is never a valid marker value -static stbi_uc stbi__get_marker(stbi__jpeg *j) -{ - stbi_uc x; - if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } - x = stbi__get8(j->s); - if (x != 0xff) return STBI__MARKER_none; - while (x == 0xff) - x = stbi__get8(j->s); // consume repeated 0xff fill bytes - return x; -} - -// in each scan, we'll have scan_n components, and the order -// of the components is specified by order[] -#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) - -// after a restart interval, stbi__jpeg_reset the entropy decoder and -// the dc prediction -static void stbi__jpeg_reset(stbi__jpeg *j) -{ - j->code_bits = 0; - j->code_buffer = 0; - j->nomore = 0; - j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; - j->marker = STBI__MARKER_none; - j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; - j->eob_run = 0; - // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, - // since we don't even allow 1<<30 pixels -} - -static int stbi__parse_entropy_coded_data(stbi__jpeg *z) -{ - stbi__jpeg_reset(z); - if (!z->progressive) { - if (z->scan_n == 1) { - int i,j; - STBI_SIMD_ALIGN(short, data[64]); - int n = z->order[0]; - // non-interleaved data, we just need to process one block at a time, - // in trivial scanline order - // number of blocks to do just depends on how many actual "pixels" this - // component has, independent of interleaved MCU blocking and such - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; - z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); - // every data block is an MCU, so countdown the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - // if it's NOT a restart, then just bail, so we get corrupt data - // rather than no data - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } else { // interleaved - int i,j,k,x,y; - STBI_SIMD_ALIGN(short, data[64]); - for (j=0; j < z->img_mcu_y; ++j) { - for (i=0; i < z->img_mcu_x; ++i) { - // scan an interleaved mcu... process scan_n components in order - for (k=0; k < z->scan_n; ++k) { - int n = z->order[k]; - // scan out an mcu's worth of this component; that's just determined - // by the basic H and V specified for the component - for (y=0; y < z->img_comp[n].v; ++y) { - for (x=0; x < z->img_comp[n].h; ++x) { - int x2 = (i*z->img_comp[n].h + x)*8; - int y2 = (j*z->img_comp[n].v + y)*8; - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; - z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); - } - } - } - // after all interleaved components, that's an interleaved MCU, - // so now count down the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } - } else { - if (z->scan_n == 1) { - int i,j; - int n = z->order[0]; - // non-interleaved data, we just need to process one block at a time, - // in trivial scanline order - // number of blocks to do just depends on how many actual "pixels" this - // component has, independent of interleaved MCU blocking and such - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { - short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); - if (z->spec_start == 0) { - if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) - return 0; - } else { - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) - return 0; - } - // every data block is an MCU, so countdown the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } else { // interleaved - int i,j,k,x,y; - for (j=0; j < z->img_mcu_y; ++j) { - for (i=0; i < z->img_mcu_x; ++i) { - // scan an interleaved mcu... process scan_n components in order - for (k=0; k < z->scan_n; ++k) { - int n = z->order[k]; - // scan out an mcu's worth of this component; that's just determined - // by the basic H and V specified for the component - for (y=0; y < z->img_comp[n].v; ++y) { - for (x=0; x < z->img_comp[n].h; ++x) { - int x2 = (i*z->img_comp[n].h + x); - int y2 = (j*z->img_comp[n].v + y); - short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); - if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) - return 0; - } - } - } - // after all interleaved components, that's an interleaved MCU, - // so now count down the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } - } -} - -static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant) -{ - int i; - for (i=0; i < 64; ++i) - data[i] *= dequant[i]; -} - -static void stbi__jpeg_finish(stbi__jpeg *z) -{ - if (z->progressive) { - // dequantize and idct the data - int i,j,n; - for (n=0; n < z->s->img_n; ++n) { - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { - short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); - stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); - z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); - } - } - } - } -} - -static int stbi__process_marker(stbi__jpeg *z, int m) -{ - int L; - switch (m) { - case STBI__MARKER_none: // no marker found - return stbi__err("expected marker","Corrupt JPEG"); - - case 0xDD: // DRI - specify restart interval - if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG"); - z->restart_interval = stbi__get16be(z->s); - return 1; - - case 0xDB: // DQT - define quantization table - L = stbi__get16be(z->s)-2; - while (L > 0) { - int q = stbi__get8(z->s); - int p = q >> 4, sixteen = (p != 0); - int t = q & 15,i; - if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG"); - if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); - - for (i=0; i < 64; ++i) - z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); - L -= (sixteen ? 129 : 65); - } - return L==0; - - case 0xC4: // DHT - define huffman table - L = stbi__get16be(z->s)-2; - while (L > 0) { - stbi_uc *v; - int sizes[16],i,n=0; - int q = stbi__get8(z->s); - int tc = q >> 4; - int th = q & 15; - if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG"); - for (i=0; i < 16; ++i) { - sizes[i] = stbi__get8(z->s); - n += sizes[i]; - } - if(n > 256) return stbi__err("bad DHT header","Corrupt JPEG"); // Loop over i < n would write past end of values! - L -= 17; - if (tc == 0) { - if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0; - v = z->huff_dc[th].values; - } else { - if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0; - v = z->huff_ac[th].values; - } - for (i=0; i < n; ++i) - v[i] = stbi__get8(z->s); - if (tc != 0) - stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); - L -= n; - } - return L==0; - } - - // check for comment block or APP blocks - if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { - L = stbi__get16be(z->s); - if (L < 2) { - if (m == 0xFE) - return stbi__err("bad COM len","Corrupt JPEG"); - else - return stbi__err("bad APP len","Corrupt JPEG"); - } - L -= 2; - - if (m == 0xE0 && L >= 5) { // JFIF APP0 segment - static const unsigned char tag[5] = {'J','F','I','F','\0'}; - int ok = 1; - int i; - for (i=0; i < 5; ++i) - if (stbi__get8(z->s) != tag[i]) - ok = 0; - L -= 5; - if (ok) - z->jfif = 1; - } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment - static const unsigned char tag[6] = {'A','d','o','b','e','\0'}; - int ok = 1; - int i; - for (i=0; i < 6; ++i) - if (stbi__get8(z->s) != tag[i]) - ok = 0; - L -= 6; - if (ok) { - stbi__get8(z->s); // version - stbi__get16be(z->s); // flags0 - stbi__get16be(z->s); // flags1 - z->app14_color_transform = stbi__get8(z->s); // color transform - L -= 6; - } - } - - stbi__skip(z->s, L); - return 1; - } - - return stbi__err("unknown marker","Corrupt JPEG"); -} - -// after we see SOS -static int stbi__process_scan_header(stbi__jpeg *z) -{ - int i; - int Ls = stbi__get16be(z->s); - z->scan_n = stbi__get8(z->s); - if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG"); - if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG"); - for (i=0; i < z->scan_n; ++i) { - int id = stbi__get8(z->s), which; - int q = stbi__get8(z->s); - for (which = 0; which < z->s->img_n; ++which) - if (z->img_comp[which].id == id) - break; - if (which == z->s->img_n) return 0; // no match - z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG"); - z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG"); - z->order[i] = which; - } - - { - int aa; - z->spec_start = stbi__get8(z->s); - z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 - aa = stbi__get8(z->s); - z->succ_high = (aa >> 4); - z->succ_low = (aa & 15); - if (z->progressive) { - if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) - return stbi__err("bad SOS", "Corrupt JPEG"); - } else { - if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG"); - if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG"); - z->spec_end = 63; - } - } - - return 1; -} - -static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) -{ - int i; - for (i=0; i < ncomp; ++i) { - if (z->img_comp[i].raw_data) { - STBI_FREE(z->img_comp[i].raw_data); - z->img_comp[i].raw_data = NULL; - z->img_comp[i].data = NULL; - } - if (z->img_comp[i].raw_coeff) { - STBI_FREE(z->img_comp[i].raw_coeff); - z->img_comp[i].raw_coeff = 0; - z->img_comp[i].coeff = 0; - } - if (z->img_comp[i].linebuf) { - STBI_FREE(z->img_comp[i].linebuf); - z->img_comp[i].linebuf = NULL; - } - } - return why; -} - -static int stbi__process_frame_header(stbi__jpeg *z, int scan) -{ - stbi__context *s = z->s; - int Lf,p,i,q, h_max=1,v_max=1,c; - Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG - p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline - s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG - s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires - if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); - if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); - c = stbi__get8(s); - if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG"); - s->img_n = c; - for (i=0; i < c; ++i) { - z->img_comp[i].data = NULL; - z->img_comp[i].linebuf = NULL; - } - - if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG"); - - z->rgb = 0; - for (i=0; i < s->img_n; ++i) { - static const unsigned char rgb[3] = { 'R', 'G', 'B' }; - z->img_comp[i].id = stbi__get8(s); - if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) - ++z->rgb; - q = stbi__get8(s); - z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); - z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); - z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG"); - } - - if (scan != STBI__SCAN_load) return 1; - - if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); - - for (i=0; i < s->img_n; ++i) { - if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; - if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; - } - - // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios - // and I've never seen a non-corrupted JPEG file actually use them - for (i=0; i < s->img_n; ++i) { - if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H","Corrupt JPEG"); - if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V","Corrupt JPEG"); - } - - // compute interleaved mcu info - z->img_h_max = h_max; - z->img_v_max = v_max; - z->img_mcu_w = h_max * 8; - z->img_mcu_h = v_max * 8; - // these sizes can't be more than 17 bits - z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; - z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; - - for (i=0; i < s->img_n; ++i) { - // number of effective pixels (e.g. for non-interleaved MCU) - z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; - z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; - // to simplify generation, we'll allocate enough memory to decode - // the bogus oversized data from using interleaved MCUs and their - // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't - // discard the extra data until colorspace conversion - // - // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) - // so these muls can't overflow with 32-bit ints (which we require) - z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; - z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; - z->img_comp[i].coeff = 0; - z->img_comp[i].raw_coeff = 0; - z->img_comp[i].linebuf = NULL; - z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); - if (z->img_comp[i].raw_data == NULL) - return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); - // align blocks for idct using mmx/sse - z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); - if (z->progressive) { - // w2, h2 are multiples of 8 (see above) - z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; - z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; - z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); - if (z->img_comp[i].raw_coeff == NULL) - return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); - z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); - } - } - - return 1; -} - -// use comparisons since in some cases we handle more than one case (e.g. SOF) -#define stbi__DNL(x) ((x) == 0xdc) -#define stbi__SOI(x) ((x) == 0xd8) -#define stbi__EOI(x) ((x) == 0xd9) -#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) -#define stbi__SOS(x) ((x) == 0xda) - -#define stbi__SOF_progressive(x) ((x) == 0xc2) - -static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) -{ - int m; - z->jfif = 0; - z->app14_color_transform = -1; // valid values are 0,1,2 - z->marker = STBI__MARKER_none; // initialize cached marker to empty - m = stbi__get_marker(z); - if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); - if (scan == STBI__SCAN_type) return 1; - m = stbi__get_marker(z); - while (!stbi__SOF(m)) { - if (!stbi__process_marker(z,m)) return 0; - m = stbi__get_marker(z); - while (m == STBI__MARKER_none) { - // some files have extra padding after their blocks, so ok, we'll scan - if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); - m = stbi__get_marker(z); - } - } - z->progressive = stbi__SOF_progressive(m); - if (!stbi__process_frame_header(z, scan)) return 0; - return 1; -} - -static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg *j) -{ - // some JPEGs have junk at end, skip over it but if we find what looks - // like a valid marker, resume there - while (!stbi__at_eof(j->s)) { - stbi_uc x = stbi__get8(j->s); - while (x == 0xff) { // might be a marker - if (stbi__at_eof(j->s)) return STBI__MARKER_none; - x = stbi__get8(j->s); - if (x != 0x00 && x != 0xff) { - // not a stuffed zero or lead-in to another marker, looks - // like an actual marker, return it - return x; - } - // stuffed zero has x=0 now which ends the loop, meaning we go - // back to regular scan loop. - // repeated 0xff keeps trying to read the next byte of the marker. - } - } - return STBI__MARKER_none; -} - -// decode image to YCbCr format -static int stbi__decode_jpeg_image(stbi__jpeg *j) -{ - int m; - for (m = 0; m < 4; m++) { - j->img_comp[m].raw_data = NULL; - j->img_comp[m].raw_coeff = NULL; - } - j->restart_interval = 0; - if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; - m = stbi__get_marker(j); - while (!stbi__EOI(m)) { - if (stbi__SOS(m)) { - if (!stbi__process_scan_header(j)) return 0; - if (!stbi__parse_entropy_coded_data(j)) return 0; - if (j->marker == STBI__MARKER_none ) { - j->marker = stbi__skip_jpeg_junk_at_end(j); - // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 - } - m = stbi__get_marker(j); - if (STBI__RESTART(m)) - m = stbi__get_marker(j); - } else if (stbi__DNL(m)) { - int Ld = stbi__get16be(j->s); - stbi__uint32 NL = stbi__get16be(j->s); - if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); - if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); - m = stbi__get_marker(j); - } else { - if (!stbi__process_marker(j, m)) return 1; - m = stbi__get_marker(j); - } - } - if (j->progressive) - stbi__jpeg_finish(j); - return 1; -} - -// static jfif-centered resampling (across block boundaries) - -typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, - int w, int hs); - -#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) - -static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - STBI_NOTUSED(out); - STBI_NOTUSED(in_far); - STBI_NOTUSED(w); - STBI_NOTUSED(hs); - return in_near; -} - -static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // need to generate two samples vertically for every one in input - int i; - STBI_NOTUSED(hs); - for (i=0; i < w; ++i) - out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2); - return out; -} - -static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // need to generate two samples horizontally for every one in input - int i; - stbi_uc *input = in_near; - - if (w == 1) { - // if only one sample, can't do any interpolation - out[0] = out[1] = input[0]; - return out; - } - - out[0] = input[0]; - out[1] = stbi__div4(input[0]*3 + input[1] + 2); - for (i=1; i < w-1; ++i) { - int n = 3*input[i]+2; - out[i*2+0] = stbi__div4(n+input[i-1]); - out[i*2+1] = stbi__div4(n+input[i+1]); - } - out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2); - out[i*2+1] = input[w-1]; - - STBI_NOTUSED(in_far); - STBI_NOTUSED(hs); - - return out; -} - -#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) - -static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // need to generate 2x2 samples for every one in input - int i,t0,t1; - if (w == 1) { - out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); - return out; - } - - t1 = 3*in_near[0] + in_far[0]; - out[0] = stbi__div4(t1+2); - for (i=1; i < w; ++i) { - t0 = t1; - t1 = 3*in_near[i]+in_far[i]; - out[i*2-1] = stbi__div16(3*t0 + t1 + 8); - out[i*2 ] = stbi__div16(3*t1 + t0 + 8); - } - out[w*2-1] = stbi__div4(t1+2); - - STBI_NOTUSED(hs); - - return out; -} - -#if defined(STBI_SSE2) || defined(STBI_NEON) -static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // need to generate 2x2 samples for every one in input - int i=0,t0,t1; - - if (w == 1) { - out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); - return out; - } - - t1 = 3*in_near[0] + in_far[0]; - // process groups of 8 pixels for as long as we can. - // note we can't handle the last pixel in a row in this loop - // because we need to handle the filter boundary conditions. - for (; i < ((w-1) & ~7); i += 8) { -#if defined(STBI_SSE2) - // load and perform the vertical filtering pass - // this uses 3*x + y = 4*x + (y - x) - __m128i zero = _mm_setzero_si128(); - __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); - __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); - __m128i farw = _mm_unpacklo_epi8(farb, zero); - __m128i nearw = _mm_unpacklo_epi8(nearb, zero); - __m128i diff = _mm_sub_epi16(farw, nearw); - __m128i nears = _mm_slli_epi16(nearw, 2); - __m128i curr = _mm_add_epi16(nears, diff); // current row - - // horizontal filter works the same based on shifted vers of current - // row. "prev" is current row shifted right by 1 pixel; we need to - // insert the previous pixel value (from t1). - // "next" is current row shifted left by 1 pixel, with first pixel - // of next block of 8 pixels added in. - __m128i prv0 = _mm_slli_si128(curr, 2); - __m128i nxt0 = _mm_srli_si128(curr, 2); - __m128i prev = _mm_insert_epi16(prv0, t1, 0); - __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); - - // horizontal filter, polyphase implementation since it's convenient: - // even pixels = 3*cur + prev = cur*4 + (prev - cur) - // odd pixels = 3*cur + next = cur*4 + (next - cur) - // note the shared term. - __m128i bias = _mm_set1_epi16(8); - __m128i curs = _mm_slli_epi16(curr, 2); - __m128i prvd = _mm_sub_epi16(prev, curr); - __m128i nxtd = _mm_sub_epi16(next, curr); - __m128i curb = _mm_add_epi16(curs, bias); - __m128i even = _mm_add_epi16(prvd, curb); - __m128i odd = _mm_add_epi16(nxtd, curb); - - // interleave even and odd pixels, then undo scaling. - __m128i int0 = _mm_unpacklo_epi16(even, odd); - __m128i int1 = _mm_unpackhi_epi16(even, odd); - __m128i de0 = _mm_srli_epi16(int0, 4); - __m128i de1 = _mm_srli_epi16(int1, 4); - - // pack and write output - __m128i outv = _mm_packus_epi16(de0, de1); - _mm_storeu_si128((__m128i *) (out + i*2), outv); -#elif defined(STBI_NEON) - // load and perform the vertical filtering pass - // this uses 3*x + y = 4*x + (y - x) - uint8x8_t farb = vld1_u8(in_far + i); - uint8x8_t nearb = vld1_u8(in_near + i); - int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); - int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); - int16x8_t curr = vaddq_s16(nears, diff); // current row - - // horizontal filter works the same based on shifted vers of current - // row. "prev" is current row shifted right by 1 pixel; we need to - // insert the previous pixel value (from t1). - // "next" is current row shifted left by 1 pixel, with first pixel - // of next block of 8 pixels added in. - int16x8_t prv0 = vextq_s16(curr, curr, 7); - int16x8_t nxt0 = vextq_s16(curr, curr, 1); - int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); - int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); - - // horizontal filter, polyphase implementation since it's convenient: - // even pixels = 3*cur + prev = cur*4 + (prev - cur) - // odd pixels = 3*cur + next = cur*4 + (next - cur) - // note the shared term. - int16x8_t curs = vshlq_n_s16(curr, 2); - int16x8_t prvd = vsubq_s16(prev, curr); - int16x8_t nxtd = vsubq_s16(next, curr); - int16x8_t even = vaddq_s16(curs, prvd); - int16x8_t odd = vaddq_s16(curs, nxtd); - - // undo scaling and round, then store with even/odd phases interleaved - uint8x8x2_t o; - o.val[0] = vqrshrun_n_s16(even, 4); - o.val[1] = vqrshrun_n_s16(odd, 4); - vst2_u8(out + i*2, o); -#endif - - // "previous" value for next iter - t1 = 3*in_near[i+7] + in_far[i+7]; - } - - t0 = t1; - t1 = 3*in_near[i] + in_far[i]; - out[i*2] = stbi__div16(3*t1 + t0 + 8); - - for (++i; i < w; ++i) { - t0 = t1; - t1 = 3*in_near[i]+in_far[i]; - out[i*2-1] = stbi__div16(3*t0 + t1 + 8); - out[i*2 ] = stbi__div16(3*t1 + t0 + 8); - } - out[w*2-1] = stbi__div4(t1+2); - - STBI_NOTUSED(hs); - - return out; -} -#endif - -static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // resample with nearest-neighbor - int i,j; - STBI_NOTUSED(in_far); - for (i=0; i < w; ++i) - for (j=0; j < hs; ++j) - out[i*hs+j] = in_near[i]; - return out; -} - -// this is a reduced-precision calculation of YCbCr-to-RGB introduced -// to make sure the code produces the same results in both SIMD and scalar -#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) -static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) -{ - int i; - for (i=0; i < count; ++i) { - int y_fixed = (y[i] << 20) + (1<<19); // rounding - int r,g,b; - int cr = pcr[i] - 128; - int cb = pcb[i] - 128; - r = y_fixed + cr* stbi__float2fixed(1.40200f); - g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb* stbi__float2fixed(1.77200f); - r >>= 20; - g >>= 20; - b >>= 20; - if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } - out[0] = (stbi_uc)r; - out[1] = (stbi_uc)g; - out[2] = (stbi_uc)b; - out[3] = 255; - out += step; - } -} - -#if defined(STBI_SSE2) || defined(STBI_NEON) -static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) -{ - int i = 0; - -#ifdef STBI_SSE2 - // step == 3 is pretty ugly on the final interleave, and i'm not convinced - // it's useful in practice (you wouldn't use it for textures, for example). - // so just accelerate step == 4 case. - if (step == 4) { - // this is a fairly straightforward implementation and not super-optimized. - __m128i signflip = _mm_set1_epi8(-0x80); - __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); - __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); - __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); - __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); - __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); - __m128i xw = _mm_set1_epi16(255); // alpha channel - - for (; i+7 < count; i += 8) { - // load - __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); - __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); - __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); - __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 - __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 - - // unpack to short (and left-shift cr, cb by 8) - __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); - __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); - __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); - - // color transform - __m128i yws = _mm_srli_epi16(yw, 4); - __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); - __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); - __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); - __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); - __m128i rws = _mm_add_epi16(cr0, yws); - __m128i gwt = _mm_add_epi16(cb0, yws); - __m128i bws = _mm_add_epi16(yws, cb1); - __m128i gws = _mm_add_epi16(gwt, cr1); - - // descale - __m128i rw = _mm_srai_epi16(rws, 4); - __m128i bw = _mm_srai_epi16(bws, 4); - __m128i gw = _mm_srai_epi16(gws, 4); - - // back to byte, set up for transpose - __m128i brb = _mm_packus_epi16(rw, bw); - __m128i gxb = _mm_packus_epi16(gw, xw); - - // transpose to interleave channels - __m128i t0 = _mm_unpacklo_epi8(brb, gxb); - __m128i t1 = _mm_unpackhi_epi8(brb, gxb); - __m128i o0 = _mm_unpacklo_epi16(t0, t1); - __m128i o1 = _mm_unpackhi_epi16(t0, t1); - - // store - _mm_storeu_si128((__m128i *) (out + 0), o0); - _mm_storeu_si128((__m128i *) (out + 16), o1); - out += 32; - } - } -#endif - -#ifdef STBI_NEON - // in this version, step=3 support would be easy to add. but is there demand? - if (step == 4) { - // this is a fairly straightforward implementation and not super-optimized. - uint8x8_t signflip = vdup_n_u8(0x80); - int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); - int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); - int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); - int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); - - for (; i+7 < count; i += 8) { - // load - uint8x8_t y_bytes = vld1_u8(y + i); - uint8x8_t cr_bytes = vld1_u8(pcr + i); - uint8x8_t cb_bytes = vld1_u8(pcb + i); - int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); - int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); - - // expand to s16 - int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); - int16x8_t crw = vshll_n_s8(cr_biased, 7); - int16x8_t cbw = vshll_n_s8(cb_biased, 7); - - // color transform - int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); - int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); - int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); - int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); - int16x8_t rws = vaddq_s16(yws, cr0); - int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); - int16x8_t bws = vaddq_s16(yws, cb1); - - // undo scaling, round, convert to byte - uint8x8x4_t o; - o.val[0] = vqrshrun_n_s16(rws, 4); - o.val[1] = vqrshrun_n_s16(gws, 4); - o.val[2] = vqrshrun_n_s16(bws, 4); - o.val[3] = vdup_n_u8(255); - - // store, interleaving r/g/b/a - vst4_u8(out, o); - out += 8*4; - } - } -#endif - - for (; i < count; ++i) { - int y_fixed = (y[i] << 20) + (1<<19); // rounding - int r,g,b; - int cr = pcr[i] - 128; - int cb = pcb[i] - 128; - r = y_fixed + cr* stbi__float2fixed(1.40200f); - g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb* stbi__float2fixed(1.77200f); - r >>= 20; - g >>= 20; - b >>= 20; - if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } - out[0] = (stbi_uc)r; - out[1] = (stbi_uc)g; - out[2] = (stbi_uc)b; - out[3] = 255; - out += step; - } -} -#endif - -// set up the kernels -static void stbi__setup_jpeg(stbi__jpeg *j) -{ - j->idct_block_kernel = stbi__idct_block; - j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; - j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; - -#ifdef STBI_SSE2 - if (stbi__sse2_available()) { - j->idct_block_kernel = stbi__idct_simd; - j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; - j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; - } -#endif - -#ifdef STBI_NEON - j->idct_block_kernel = stbi__idct_simd; - j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; - j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; -#endif -} - -// clean up the temporary component buffers -static void stbi__cleanup_jpeg(stbi__jpeg *j) -{ - stbi__free_jpeg_components(j, j->s->img_n, 0); -} - -typedef struct -{ - resample_row_func resample; - stbi_uc *line0,*line1; - int hs,vs; // expansion factor in each axis - int w_lores; // horizontal pixels pre-expansion - int ystep; // how far through vertical expansion we are - int ypos; // which pre-expansion row we're on -} stbi__resample; - -// fast 0..255 * 0..255 => 0..255 rounded multiplication -static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) -{ - unsigned int t = x*y + 128; - return (stbi_uc) ((t + (t >>8)) >> 8); -} - -static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) -{ - int n, decode_n, is_rgb; - z->s->img_n = 0; // make stbi__cleanup_jpeg safe - - // validate req_comp - if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); - - // load a jpeg image from whichever source, but leave in YCbCr format - if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } - - // determine actual number of components to generate - n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; - - is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); - - if (z->s->img_n == 3 && n < 3 && !is_rgb) - decode_n = 1; - else - decode_n = z->s->img_n; - - // nothing to do if no components requested; check this now to avoid - // accessing uninitialized coutput[0] later - if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } - - // resample and color-convert - { - int k; - unsigned int i,j; - stbi_uc *output; - stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL }; - - stbi__resample res_comp[4]; - - for (k=0; k < decode_n; ++k) { - stbi__resample *r = &res_comp[k]; - - // allocate line buffer big enough for upsampling off the edges - // with upsample factor of 4 - z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); - if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } - - r->hs = z->img_h_max / z->img_comp[k].h; - r->vs = z->img_v_max / z->img_comp[k].v; - r->ystep = r->vs >> 1; - r->w_lores = (z->s->img_x + r->hs-1) / r->hs; - r->ypos = 0; - r->line0 = r->line1 = z->img_comp[k].data; - - if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; - else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; - else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; - else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; - else r->resample = stbi__resample_row_generic; - } - - // can't error after this so, this is safe - output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); - if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } - - // now go ahead and resample - for (j=0; j < z->s->img_y; ++j) { - stbi_uc *out = output + n * z->s->img_x * j; - for (k=0; k < decode_n; ++k) { - stbi__resample *r = &res_comp[k]; - int y_bot = r->ystep >= (r->vs >> 1); - coutput[k] = r->resample(z->img_comp[k].linebuf, - y_bot ? r->line1 : r->line0, - y_bot ? r->line0 : r->line1, - r->w_lores, r->hs); - if (++r->ystep >= r->vs) { - r->ystep = 0; - r->line0 = r->line1; - if (++r->ypos < z->img_comp[k].y) - r->line1 += z->img_comp[k].w2; - } - } - if (n >= 3) { - stbi_uc *y = coutput[0]; - if (z->s->img_n == 3) { - if (is_rgb) { - for (i=0; i < z->s->img_x; ++i) { - out[0] = y[i]; - out[1] = coutput[1][i]; - out[2] = coutput[2][i]; - out[3] = 255; - out += n; - } - } else { - z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); - } - } else if (z->s->img_n == 4) { - if (z->app14_color_transform == 0) { // CMYK - for (i=0; i < z->s->img_x; ++i) { - stbi_uc m = coutput[3][i]; - out[0] = stbi__blinn_8x8(coutput[0][i], m); - out[1] = stbi__blinn_8x8(coutput[1][i], m); - out[2] = stbi__blinn_8x8(coutput[2][i], m); - out[3] = 255; - out += n; - } - } else if (z->app14_color_transform == 2) { // YCCK - z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); - for (i=0; i < z->s->img_x; ++i) { - stbi_uc m = coutput[3][i]; - out[0] = stbi__blinn_8x8(255 - out[0], m); - out[1] = stbi__blinn_8x8(255 - out[1], m); - out[2] = stbi__blinn_8x8(255 - out[2], m); - out += n; - } - } else { // YCbCr + alpha? Ignore the fourth channel for now - z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); - } - } else - for (i=0; i < z->s->img_x; ++i) { - out[0] = out[1] = out[2] = y[i]; - out[3] = 255; // not used if n==3 - out += n; - } - } else { - if (is_rgb) { - if (n == 1) - for (i=0; i < z->s->img_x; ++i) - *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); - else { - for (i=0; i < z->s->img_x; ++i, out += 2) { - out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); - out[1] = 255; - } - } - } else if (z->s->img_n == 4 && z->app14_color_transform == 0) { - for (i=0; i < z->s->img_x; ++i) { - stbi_uc m = coutput[3][i]; - stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); - stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); - stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); - out[0] = stbi__compute_y(r, g, b); - out[1] = 255; - out += n; - } - } else if (z->s->img_n == 4 && z->app14_color_transform == 2) { - for (i=0; i < z->s->img_x; ++i) { - out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); - out[1] = 255; - out += n; - } - } else { - stbi_uc *y = coutput[0]; - if (n == 1) - for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; - else - for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } - } - } - } - stbi__cleanup_jpeg(z); - *out_x = z->s->img_x; - *out_y = z->s->img_y; - if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output - return output; - } -} - -static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - unsigned char* result; - stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); - if (!j) return stbi__errpuc("outofmem", "Out of memory"); - memset(j, 0, sizeof(stbi__jpeg)); - STBI_NOTUSED(ri); - j->s = s; - stbi__setup_jpeg(j); - result = load_jpeg_image(j, x,y,comp,req_comp); - STBI_FREE(j); - return result; -} - -static int stbi__jpeg_test(stbi__context *s) -{ - int r; - stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); - if (!j) return stbi__err("outofmem", "Out of memory"); - memset(j, 0, sizeof(stbi__jpeg)); - j->s = s; - stbi__setup_jpeg(j); - r = stbi__decode_jpeg_header(j, STBI__SCAN_type); - stbi__rewind(s); - STBI_FREE(j); - return r; -} - -static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) -{ - if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { - stbi__rewind( j->s ); - return 0; - } - if (x) *x = j->s->img_x; - if (y) *y = j->s->img_y; - if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; - return 1; -} - -static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) -{ - int result; - stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); - if (!j) return stbi__err("outofmem", "Out of memory"); - memset(j, 0, sizeof(stbi__jpeg)); - j->s = s; - result = stbi__jpeg_info_raw(j, x, y, comp); - STBI_FREE(j); - return result; -} -#endif - -// public domain zlib decode v0.2 Sean Barrett 2006-11-18 -// simple implementation -// - all input must be provided in an upfront buffer -// - all output is written to a single output buffer (can malloc/realloc) -// performance -// - fast huffman - -#ifndef STBI_NO_ZLIB - -// fast-way is faster to check than jpeg huffman, but slow way is slower -#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables -#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) -#define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet - -// zlib-style huffman encoding -// (jpegs packs from left, zlib from right, so can't share code) -typedef struct -{ - stbi__uint16 fast[1 << STBI__ZFAST_BITS]; - stbi__uint16 firstcode[16]; - int maxcode[17]; - stbi__uint16 firstsymbol[16]; - stbi_uc size[STBI__ZNSYMS]; - stbi__uint16 value[STBI__ZNSYMS]; -} stbi__zhuffman; - -stbi_inline static int stbi__bitreverse16(int n) -{ - n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); - n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); - n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); - n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); - return n; -} - -stbi_inline static int stbi__bit_reverse(int v, int bits) -{ - STBI_ASSERT(bits <= 16); - // to bit reverse n bits, reverse 16 and shift - // e.g. 11 bits, bit reverse and shift away 5 - return stbi__bitreverse16(v) >> (16-bits); -} - -static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num) -{ - int i,k=0; - int code, next_code[16], sizes[17]; - - // DEFLATE spec for generating codes - memset(sizes, 0, sizeof(sizes)); - memset(z->fast, 0, sizeof(z->fast)); - for (i=0; i < num; ++i) - ++sizes[sizelist[i]]; - sizes[0] = 0; - for (i=1; i < 16; ++i) - if (sizes[i] > (1 << i)) - return stbi__err("bad sizes", "Corrupt PNG"); - code = 0; - for (i=1; i < 16; ++i) { - next_code[i] = code; - z->firstcode[i] = (stbi__uint16) code; - z->firstsymbol[i] = (stbi__uint16) k; - code = (code + sizes[i]); - if (sizes[i]) - if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG"); - z->maxcode[i] = code << (16-i); // preshift for inner loop - code <<= 1; - k += sizes[i]; - } - z->maxcode[16] = 0x10000; // sentinel - for (i=0; i < num; ++i) { - int s = sizelist[i]; - if (s) { - int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; - stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i); - z->size [c] = (stbi_uc ) s; - z->value[c] = (stbi__uint16) i; - if (s <= STBI__ZFAST_BITS) { - int j = stbi__bit_reverse(next_code[s],s); - while (j < (1 << STBI__ZFAST_BITS)) { - z->fast[j] = fastv; - j += (1 << s); - } - } - ++next_code[s]; - } - } - return 1; -} - -// zlib-from-memory implementation for PNG reading -// because PNG allows splitting the zlib stream arbitrarily, -// and it's annoying structurally to have PNG call ZLIB call PNG, -// we require PNG read all the IDATs and combine them into a single -// memory buffer - -typedef struct -{ - stbi_uc *zbuffer, *zbuffer_end; - int num_bits; - int hit_zeof_once; - stbi__uint32 code_buffer; - - char *zout; - char *zout_start; - char *zout_end; - int z_expandable; - - stbi__zhuffman z_length, z_distance; -} stbi__zbuf; - -stbi_inline static int stbi__zeof(stbi__zbuf *z) -{ - return (z->zbuffer >= z->zbuffer_end); -} - -stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) -{ - return stbi__zeof(z) ? 0 : *z->zbuffer++; -} - -static void stbi__fill_bits(stbi__zbuf *z) -{ - do { - if (z->code_buffer >= (1U << z->num_bits)) { - z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ - return; - } - z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; - z->num_bits += 8; - } while (z->num_bits <= 24); -} - -stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) -{ - unsigned int k; - if (z->num_bits < n) stbi__fill_bits(z); - k = z->code_buffer & ((1 << n) - 1); - z->code_buffer >>= n; - z->num_bits -= n; - return k; -} - -static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) -{ - int b,s,k; - // not resolved by fast table, so compute it the slow way - // use jpeg approach, which requires MSbits at top - k = stbi__bit_reverse(a->code_buffer, 16); - for (s=STBI__ZFAST_BITS+1; ; ++s) - if (k < z->maxcode[s]) - break; - if (s >= 16) return -1; // invalid code! - // code size is s, so: - b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; - if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! - if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. - a->code_buffer >>= s; - a->num_bits -= s; - return z->value[b]; -} - -stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) -{ - int b,s; - if (a->num_bits < 16) { - if (stbi__zeof(a)) { - if (!a->hit_zeof_once) { - // This is the first time we hit eof, insert 16 extra padding btis - // to allow us to keep going; if we actually consume any of them - // though, that is invalid data. This is caught later. - a->hit_zeof_once = 1; - a->num_bits += 16; // add 16 implicit zero bits - } else { - // We already inserted our extra 16 padding bits and are again - // out, this stream is actually prematurely terminated. - return -1; - } - } else { - stbi__fill_bits(a); - } - } - b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; - if (b) { - s = b >> 9; - a->code_buffer >>= s; - a->num_bits -= s; - return b & 511; - } - return stbi__zhuffman_decode_slowpath(a, z); -} - -static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes -{ - char *q; - unsigned int cur, limit, old_limit; - z->zout = zout; - if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); - cur = (unsigned int) (z->zout - z->zout_start); - limit = old_limit = (unsigned) (z->zout_end - z->zout_start); - if (UINT_MAX - cur < (unsigned) n) return stbi__err("outofmem", "Out of memory"); - while (cur + n > limit) { - if(limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); - limit *= 2; - } - q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); - STBI_NOTUSED(old_limit); - if (q == NULL) return stbi__err("outofmem", "Out of memory"); - z->zout_start = q; - z->zout = q + cur; - z->zout_end = q + limit; - return 1; -} - -static const int stbi__zlength_base[31] = { - 3,4,5,6,7,8,9,10,11,13, - 15,17,19,23,27,31,35,43,51,59, - 67,83,99,115,131,163,195,227,258,0,0 }; - -static const int stbi__zlength_extra[31]= -{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; - -static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, -257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; - -static const int stbi__zdist_extra[32] = -{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -static int stbi__parse_huffman_block(stbi__zbuf *a) -{ - char *zout = a->zout; - for(;;) { - int z = stbi__zhuffman_decode(a, &a->z_length); - if (z < 256) { - if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes - if (zout >= a->zout_end) { - if (!stbi__zexpand(a, zout, 1)) return 0; - zout = a->zout; - } - *zout++ = (char) z; - } else { - stbi_uc *p; - int len,dist; - if (z == 256) { - a->zout = zout; - if (a->hit_zeof_once && a->num_bits < 16) { - // The first time we hit zeof, we inserted 16 extra zero bits into our bit - // buffer so the decoder can just do its speculative decoding. But if we - // actually consumed any of those bits (which is the case when num_bits < 16), - // the stream actually read past the end so it is malformed. - return stbi__err("unexpected end","Corrupt PNG"); - } - return 1; - } - if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data - z -= 257; - len = stbi__zlength_base[z]; - if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); - z = stbi__zhuffman_decode(a, &a->z_distance); - if (z < 0 || z >= 30) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data - dist = stbi__zdist_base[z]; - if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); - if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); - if (len > a->zout_end - zout) { - if (!stbi__zexpand(a, zout, len)) return 0; - zout = a->zout; - } - p = (stbi_uc *) (zout - dist); - if (dist == 1) { // run of one byte; common in images. - stbi_uc v = *p; - if (len) { do *zout++ = v; while (--len); } - } else { - if (len) { do *zout++ = *p++; while (--len); } - } - } - } -} - -static int stbi__compute_huffman_codes(stbi__zbuf *a) -{ - static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; - stbi__zhuffman z_codelength; - stbi_uc lencodes[286+32+137];//padding for maximum single op - stbi_uc codelength_sizes[19]; - int i,n; - - int hlit = stbi__zreceive(a,5) + 257; - int hdist = stbi__zreceive(a,5) + 1; - int hclen = stbi__zreceive(a,4) + 4; - int ntot = hlit + hdist; - - memset(codelength_sizes, 0, sizeof(codelength_sizes)); - for (i=0; i < hclen; ++i) { - int s = stbi__zreceive(a,3); - codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; - } - if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; - - n = 0; - while (n < ntot) { - int c = stbi__zhuffman_decode(a, &z_codelength); - if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); - if (c < 16) - lencodes[n++] = (stbi_uc) c; - else { - stbi_uc fill = 0; - if (c == 16) { - c = stbi__zreceive(a,2)+3; - if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); - fill = lencodes[n-1]; - } else if (c == 17) { - c = stbi__zreceive(a,3)+3; - } else if (c == 18) { - c = stbi__zreceive(a,7)+11; - } else { - return stbi__err("bad codelengths", "Corrupt PNG"); - } - if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); - memset(lencodes+n, fill, c); - n += c; - } - } - if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG"); - if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; - if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; - return 1; -} - -static int stbi__parse_uncompressed_block(stbi__zbuf *a) -{ - stbi_uc header[4]; - int len,nlen,k; - if (a->num_bits & 7) - stbi__zreceive(a, a->num_bits & 7); // discard - // drain the bit-packed data into header - k = 0; - while (a->num_bits > 0) { - header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check - a->code_buffer >>= 8; - a->num_bits -= 8; - } - if (a->num_bits < 0) return stbi__err("zlib corrupt","Corrupt PNG"); - // now fill header the normal way - while (k < 4) - header[k++] = stbi__zget8(a); - len = header[1] * 256 + header[0]; - nlen = header[3] * 256 + header[2]; - if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); - if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); - if (a->zout + len > a->zout_end) - if (!stbi__zexpand(a, a->zout, len)) return 0; - memcpy(a->zout, a->zbuffer, len); - a->zbuffer += len; - a->zout += len; - return 1; -} - -static int stbi__parse_zlib_header(stbi__zbuf *a) -{ - int cmf = stbi__zget8(a); - int cm = cmf & 15; - /* int cinfo = cmf >> 4; */ - int flg = stbi__zget8(a); - if (stbi__zeof(a)) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec - if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec - if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png - if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png - // window = 1 << (8 + cinfo)... but who cares, we fully buffer output - return 1; -} - -static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = -{ - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 -}; -static const stbi_uc stbi__zdefault_distance[32] = -{ - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 -}; -/* -Init algorithm: -{ - int i; // use <= to match clearly with spec - for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; - for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; - for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; - for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; - - for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; -} -*/ - -static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) -{ - int final, type; - if (parse_header) - if (!stbi__parse_zlib_header(a)) return 0; - a->num_bits = 0; - a->code_buffer = 0; - a->hit_zeof_once = 0; - do { - final = stbi__zreceive(a,1); - type = stbi__zreceive(a,2); - if (type == 0) { - if (!stbi__parse_uncompressed_block(a)) return 0; - } else if (type == 3) { - return 0; - } else { - if (type == 1) { - // use fixed code lengths - if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , STBI__ZNSYMS)) return 0; - if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; - } else { - if (!stbi__compute_huffman_codes(a)) return 0; - } - if (!stbi__parse_huffman_block(a)) return 0; - } - } while (!final); - return 1; -} - -static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) -{ - a->zout_start = obuf; - a->zout = obuf; - a->zout_end = obuf + olen; - a->z_expandable = exp; - - return stbi__parse_zlib(a, parse_header); -} - -STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) -{ - stbi__zbuf a; - char *p = (char *) stbi__malloc(initial_size); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer + len; - if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - STBI_FREE(a.zout_start); - return NULL; - } -} - -STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) -{ - return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); -} - -STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) -{ - stbi__zbuf a; - char *p = (char *) stbi__malloc(initial_size); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer + len; - if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - STBI_FREE(a.zout_start); - return NULL; - } -} - -STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) -{ - stbi__zbuf a; - a.zbuffer = (stbi_uc *) ibuffer; - a.zbuffer_end = (stbi_uc *) ibuffer + ilen; - if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) - return (int) (a.zout - a.zout_start); - else - return -1; -} - -STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) -{ - stbi__zbuf a; - char *p = (char *) stbi__malloc(16384); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer+len; - if (stbi__do_zlib(&a, p, 16384, 1, 0)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - STBI_FREE(a.zout_start); - return NULL; - } -} - -STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) -{ - stbi__zbuf a; - a.zbuffer = (stbi_uc *) ibuffer; - a.zbuffer_end = (stbi_uc *) ibuffer + ilen; - if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) - return (int) (a.zout - a.zout_start); - else - return -1; -} -#endif - -// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 -// simple implementation -// - only 8-bit samples -// - no CRC checking -// - allocates lots of intermediate memory -// - avoids problem of streaming data between subsystems -// - avoids explicit window management -// performance -// - uses stb_zlib, a PD zlib implementation with fast huffman decoding - -#ifndef STBI_NO_PNG -typedef struct -{ - stbi__uint32 length; - stbi__uint32 type; -} stbi__pngchunk; - -static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) -{ - stbi__pngchunk c; - c.length = stbi__get32be(s); - c.type = stbi__get32be(s); - return c; -} - -static int stbi__check_png_header(stbi__context *s) -{ - static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; - int i; - for (i=0; i < 8; ++i) - if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); - return 1; -} - -typedef struct -{ - stbi__context *s; - stbi_uc *idata, *expanded, *out; - int depth; -} stbi__png; - - -enum { - STBI__F_none=0, - STBI__F_sub=1, - STBI__F_up=2, - STBI__F_avg=3, - STBI__F_paeth=4, - // synthetic filter used for first scanline to avoid needing a dummy row of 0s - STBI__F_avg_first -}; - -static stbi_uc first_row_filter[5] = -{ - STBI__F_none, - STBI__F_sub, - STBI__F_none, - STBI__F_avg_first, - STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub -}; - -static int stbi__paeth(int a, int b, int c) -{ - // This formulation looks very different from the reference in the PNG spec, but is - // actually equivalent and has favorable data dependencies and admits straightforward - // generation of branch-free code, which helps performance significantly. - int thresh = c*3 - (a + b); - int lo = a < b ? a : b; - int hi = a < b ? b : a; - int t0 = (hi <= thresh) ? lo : c; - int t1 = (thresh <= lo) ? hi : t0; - return t1; -} - -static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; - -// adds an extra all-255 alpha channel -// dest == src is legal -// img_n must be 1 or 3 -static void stbi__create_png_alpha_expand8(stbi_uc *dest, stbi_uc *src, stbi__uint32 x, int img_n) -{ - int i; - // must process data backwards since we allow dest==src - if (img_n == 1) { - for (i=x-1; i >= 0; --i) { - dest[i*2+1] = 255; - dest[i*2+0] = src[i]; - } - } else { - STBI_ASSERT(img_n == 3); - for (i=x-1; i >= 0; --i) { - dest[i*4+3] = 255; - dest[i*4+2] = src[i*3+2]; - dest[i*4+1] = src[i*3+1]; - dest[i*4+0] = src[i*3+0]; - } - } -} - -// create the png data from post-deflated data -static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) -{ - int bytes = (depth == 16 ? 2 : 1); - stbi__context *s = a->s; - stbi__uint32 i,j,stride = x*out_n*bytes; - stbi__uint32 img_len, img_width_bytes; - stbi_uc *filter_buf; - int all_ok = 1; - int k; - int img_n = s->img_n; // copy it into a local for later - - int output_bytes = out_n*bytes; - int filter_bytes = img_n*bytes; - int width = x; - - STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); - a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into - if (!a->out) return stbi__err("outofmem", "Out of memory"); - - // note: error exits here don't need to clean up a->out individually, - // stbi__do_png always does on error. - if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); - img_width_bytes = (((img_n * x * depth) + 7) >> 3); - if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) return stbi__err("too large", "Corrupt PNG"); - img_len = (img_width_bytes + 1) * y; - - // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, - // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), - // so just check for raw_len < img_len always. - if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); - - // Allocate two scan lines worth of filter workspace buffer. - filter_buf = (stbi_uc *) stbi__malloc_mad2(img_width_bytes, 2, 0); - if (!filter_buf) return stbi__err("outofmem", "Out of memory"); - - // Filtering for low-bit-depth images - if (depth < 8) { - filter_bytes = 1; - width = img_width_bytes; - } - - for (j=0; j < y; ++j) { - // cur/prior filter buffers alternate - stbi_uc *cur = filter_buf + (j & 1)*img_width_bytes; - stbi_uc *prior = filter_buf + (~j & 1)*img_width_bytes; - stbi_uc *dest = a->out + stride*j; - int nk = width * filter_bytes; - int filter = *raw++; - - // check filter type - if (filter > 4) { - all_ok = stbi__err("invalid filter","Corrupt PNG"); - break; - } - - // if first row, use special filter that doesn't sample previous row - if (j == 0) filter = first_row_filter[filter]; - - // perform actual filtering - switch (filter) { - case STBI__F_none: - memcpy(cur, raw, nk); - break; - case STBI__F_sub: - memcpy(cur, raw, filter_bytes); - for (k = filter_bytes; k < nk; ++k) - cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); - break; - case STBI__F_up: - for (k = 0; k < nk; ++k) - cur[k] = STBI__BYTECAST(raw[k] + prior[k]); - break; - case STBI__F_avg: - for (k = 0; k < filter_bytes; ++k) - cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); - for (k = filter_bytes; k < nk; ++k) - cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); - break; - case STBI__F_paeth: - for (k = 0; k < filter_bytes; ++k) - cur[k] = STBI__BYTECAST(raw[k] + prior[k]); // prior[k] == stbi__paeth(0,prior[k],0) - for (k = filter_bytes; k < nk; ++k) - cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes], prior[k], prior[k-filter_bytes])); - break; - case STBI__F_avg_first: - memcpy(cur, raw, filter_bytes); - for (k = filter_bytes; k < nk; ++k) - cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); - break; - } - - raw += nk; - - // expand decoded bits in cur to dest, also adding an extra alpha channel if desired - if (depth < 8) { - stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range - stbi_uc *in = cur; - stbi_uc *out = dest; - stbi_uc inb = 0; - stbi__uint32 nsmp = x*img_n; - - // expand bits to bytes first - if (depth == 4) { - for (i=0; i < nsmp; ++i) { - if ((i & 1) == 0) inb = *in++; - *out++ = scale * (inb >> 4); - inb <<= 4; - } - } else if (depth == 2) { - for (i=0; i < nsmp; ++i) { - if ((i & 3) == 0) inb = *in++; - *out++ = scale * (inb >> 6); - inb <<= 2; - } - } else { - STBI_ASSERT(depth == 1); - for (i=0; i < nsmp; ++i) { - if ((i & 7) == 0) inb = *in++; - *out++ = scale * (inb >> 7); - inb <<= 1; - } - } - - // insert alpha=255 values if desired - if (img_n != out_n) - stbi__create_png_alpha_expand8(dest, dest, x, img_n); - } else if (depth == 8) { - if (img_n == out_n) - memcpy(dest, cur, x*img_n); - else - stbi__create_png_alpha_expand8(dest, cur, x, img_n); - } else if (depth == 16) { - // convert the image data from big-endian to platform-native - stbi__uint16 *dest16 = (stbi__uint16*)dest; - stbi__uint32 nsmp = x*img_n; - - if (img_n == out_n) { - for (i = 0; i < nsmp; ++i, ++dest16, cur += 2) - *dest16 = (cur[0] << 8) | cur[1]; - } else { - STBI_ASSERT(img_n+1 == out_n); - if (img_n == 1) { - for (i = 0; i < x; ++i, dest16 += 2, cur += 2) { - dest16[0] = (cur[0] << 8) | cur[1]; - dest16[1] = 0xffff; - } - } else { - STBI_ASSERT(img_n == 3); - for (i = 0; i < x; ++i, dest16 += 4, cur += 6) { - dest16[0] = (cur[0] << 8) | cur[1]; - dest16[1] = (cur[2] << 8) | cur[3]; - dest16[2] = (cur[4] << 8) | cur[5]; - dest16[3] = 0xffff; - } - } - } - } - } - - STBI_FREE(filter_buf); - if (!all_ok) return 0; - - return 1; -} - -static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) -{ - int bytes = (depth == 16 ? 2 : 1); - int out_bytes = out_n * bytes; - stbi_uc *final; - int p; - if (!interlaced) - return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); - - // de-interlacing - final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); - if (!final) return stbi__err("outofmem", "Out of memory"); - for (p=0; p < 7; ++p) { - int xorig[] = { 0,4,0,2,0,1,0 }; - int yorig[] = { 0,0,4,0,2,0,1 }; - int xspc[] = { 8,8,4,4,2,2,1 }; - int yspc[] = { 8,8,8,4,4,2,2 }; - int i,j,x,y; - // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 - x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; - y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; - if (x && y) { - stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; - if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { - STBI_FREE(final); - return 0; - } - for (j=0; j < y; ++j) { - for (i=0; i < x; ++i) { - int out_y = j*yspc[p]+yorig[p]; - int out_x = i*xspc[p]+xorig[p]; - memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes, - a->out + (j*x+i)*out_bytes, out_bytes); - } - } - STBI_FREE(a->out); - image_data += img_len; - image_data_len -= img_len; - } - } - a->out = final; - - return 1; -} - -static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) -{ - stbi__context *s = z->s; - stbi__uint32 i, pixel_count = s->img_x * s->img_y; - stbi_uc *p = z->out; - - // compute color-based transparency, assuming we've - // already got 255 as the alpha value in the output - STBI_ASSERT(out_n == 2 || out_n == 4); - - if (out_n == 2) { - for (i=0; i < pixel_count; ++i) { - p[1] = (p[0] == tc[0] ? 0 : 255); - p += 2; - } - } else { - for (i=0; i < pixel_count; ++i) { - if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) - p[3] = 0; - p += 4; - } - } - return 1; -} - -static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n) -{ - stbi__context *s = z->s; - stbi__uint32 i, pixel_count = s->img_x * s->img_y; - stbi__uint16 *p = (stbi__uint16*) z->out; - - // compute color-based transparency, assuming we've - // already got 65535 as the alpha value in the output - STBI_ASSERT(out_n == 2 || out_n == 4); - - if (out_n == 2) { - for (i = 0; i < pixel_count; ++i) { - p[1] = (p[0] == tc[0] ? 0 : 65535); - p += 2; - } - } else { - for (i = 0; i < pixel_count; ++i) { - if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) - p[3] = 0; - p += 4; - } - } - return 1; -} - -static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n) -{ - stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; - stbi_uc *p, *temp_out, *orig = a->out; - - p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); - if (p == NULL) return stbi__err("outofmem", "Out of memory"); - - // between here and free(out) below, exitting would leak - temp_out = p; - - if (pal_img_n == 3) { - for (i=0; i < pixel_count; ++i) { - int n = orig[i]*4; - p[0] = palette[n ]; - p[1] = palette[n+1]; - p[2] = palette[n+2]; - p += 3; - } - } else { - for (i=0; i < pixel_count; ++i) { - int n = orig[i]*4; - p[0] = palette[n ]; - p[1] = palette[n+1]; - p[2] = palette[n+2]; - p[3] = palette[n+3]; - p += 4; - } - } - STBI_FREE(a->out); - a->out = temp_out; - - STBI_NOTUSED(len); - - return 1; -} - -static int stbi__unpremultiply_on_load_global = 0; -static int stbi__de_iphone_flag_global = 0; - -STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) -{ - stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; -} - -STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) -{ - stbi__de_iphone_flag_global = flag_true_if_should_convert; -} - -#ifndef STBI_THREAD_LOCAL -#define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global -#define stbi__de_iphone_flag stbi__de_iphone_flag_global -#else -static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; -static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; - -STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) -{ - stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; - stbi__unpremultiply_on_load_set = 1; -} - -STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) -{ - stbi__de_iphone_flag_local = flag_true_if_should_convert; - stbi__de_iphone_flag_set = 1; -} - -#define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ - ? stbi__unpremultiply_on_load_local \ - : stbi__unpremultiply_on_load_global) -#define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ - ? stbi__de_iphone_flag_local \ - : stbi__de_iphone_flag_global) -#endif // STBI_THREAD_LOCAL - -static void stbi__de_iphone(stbi__png *z) -{ - stbi__context *s = z->s; - stbi__uint32 i, pixel_count = s->img_x * s->img_y; - stbi_uc *p = z->out; - - if (s->img_out_n == 3) { // convert bgr to rgb - for (i=0; i < pixel_count; ++i) { - stbi_uc t = p[0]; - p[0] = p[2]; - p[2] = t; - p += 3; - } - } else { - STBI_ASSERT(s->img_out_n == 4); - if (stbi__unpremultiply_on_load) { - // convert bgr to rgb and unpremultiply - for (i=0; i < pixel_count; ++i) { - stbi_uc a = p[3]; - stbi_uc t = p[0]; - if (a) { - stbi_uc half = a / 2; - p[0] = (p[2] * 255 + half) / a; - p[1] = (p[1] * 255 + half) / a; - p[2] = ( t * 255 + half) / a; - } else { - p[0] = p[2]; - p[2] = t; - } - p += 4; - } - } else { - // convert bgr to rgb - for (i=0; i < pixel_count; ++i) { - stbi_uc t = p[0]; - p[0] = p[2]; - p[2] = t; - p += 4; - } - } - } -} - -#define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) - -static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) -{ - stbi_uc palette[1024], pal_img_n=0; - stbi_uc has_trans=0, tc[3]={0}; - stbi__uint16 tc16[3]; - stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; - int first=1,k,interlace=0, color=0, is_iphone=0; - stbi__context *s = z->s; - - z->expanded = NULL; - z->idata = NULL; - z->out = NULL; - - if (!stbi__check_png_header(s)) return 0; - - if (scan == STBI__SCAN_type) return 1; - - for (;;) { - stbi__pngchunk c = stbi__get_chunk_header(s); - switch (c.type) { - case STBI__PNG_TYPE('C','g','B','I'): - is_iphone = 1; - stbi__skip(s, c.length); - break; - case STBI__PNG_TYPE('I','H','D','R'): { - int comp,filter; - if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); - first = 0; - if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); - s->img_x = stbi__get32be(s); - s->img_y = stbi__get32be(s); - if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); - if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); - z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); - color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); - if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); - if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); - comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); - filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); - interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); - if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); - if (!pal_img_n) { - s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); - if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); - } else { - // if paletted, then pal_n is our final components, and - // img_n is # components to decompress/filter. - s->img_n = 1; - if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); - } - // even with SCAN_header, have to scan to see if we have a tRNS - break; - } - - case STBI__PNG_TYPE('P','L','T','E'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); - pal_len = c.length / 3; - if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG"); - for (i=0; i < pal_len; ++i) { - palette[i*4+0] = stbi__get8(s); - palette[i*4+1] = stbi__get8(s); - palette[i*4+2] = stbi__get8(s); - palette[i*4+3] = 255; - } - break; - } - - case STBI__PNG_TYPE('t','R','N','S'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG"); - if (pal_img_n) { - if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } - if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG"); - if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG"); - pal_img_n = 4; - for (i=0; i < c.length; ++i) - palette[i*4+3] = stbi__get8(s); - } else { - if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG"); - if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); - has_trans = 1; - // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. - if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } - if (z->depth == 16) { - for (k = 0; k < s->img_n && k < 3; ++k) // extra loop test to suppress false GCC warning - tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is - } else { - for (k = 0; k < s->img_n && k < 3; ++k) - tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger - } - } - break; - } - - case STBI__PNG_TYPE('I','D','A','T'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG"); - if (scan == STBI__SCAN_header) { - // header scan definitely stops at first IDAT - if (pal_img_n) - s->img_n = pal_img_n; - return 1; - } - if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); - if ((int)(ioff + c.length) < (int)ioff) return 0; - if (ioff + c.length > idata_limit) { - stbi__uint32 idata_limit_old = idata_limit; - stbi_uc *p; - if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; - while (ioff + c.length > idata_limit) - idata_limit *= 2; - STBI_NOTUSED(idata_limit_old); - p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); - z->idata = p; - } - if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); - ioff += c.length; - break; - } - - case STBI__PNG_TYPE('I','E','N','D'): { - stbi__uint32 raw_len, bpl; - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (scan != STBI__SCAN_load) return 1; - if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG"); - // initial guess for decoded data size to avoid unnecessary reallocs - bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component - raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; - z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone); - if (z->expanded == NULL) return 0; // zlib should set error - STBI_FREE(z->idata); z->idata = NULL; - if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) - s->img_out_n = s->img_n+1; - else - s->img_out_n = s->img_n; - if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; - if (has_trans) { - if (z->depth == 16) { - if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; - } else { - if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; - } - } - if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) - stbi__de_iphone(z); - if (pal_img_n) { - // pal_img_n == 3 or 4 - s->img_n = pal_img_n; // record the actual colors we had - s->img_out_n = pal_img_n; - if (req_comp >= 3) s->img_out_n = req_comp; - if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) - return 0; - } else if (has_trans) { - // non-paletted image with tRNS -> source image has (constant) alpha - ++s->img_n; - } - STBI_FREE(z->expanded); z->expanded = NULL; - // end of PNG chunk, read and skip CRC - stbi__get32be(s); - return 1; - } - - default: - // if critical, fail - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if ((c.type & (1 << 29)) == 0) { - #ifndef STBI_NO_FAILURE_STRINGS - // not threadsafe - static char invalid_chunk[] = "XXXX PNG chunk not known"; - invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); - invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); - invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); - invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); - #endif - return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); - } - stbi__skip(s, c.length); - break; - } - // end of PNG chunk, read and skip CRC - stbi__get32be(s); - } -} - -static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) -{ - void *result=NULL; - if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); - if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { - if (p->depth <= 8) - ri->bits_per_channel = 8; - else if (p->depth == 16) - ri->bits_per_channel = 16; - else - return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); - result = p->out; - p->out = NULL; - if (req_comp && req_comp != p->s->img_out_n) { - if (ri->bits_per_channel == 8) - result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); - else - result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); - p->s->img_out_n = req_comp; - if (result == NULL) return result; - } - *x = p->s->img_x; - *y = p->s->img_y; - if (n) *n = p->s->img_n; - } - STBI_FREE(p->out); p->out = NULL; - STBI_FREE(p->expanded); p->expanded = NULL; - STBI_FREE(p->idata); p->idata = NULL; - - return result; -} - -static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - stbi__png p; - p.s = s; - return stbi__do_png(&p, x,y,comp,req_comp, ri); -} - -static int stbi__png_test(stbi__context *s) -{ - int r; - r = stbi__check_png_header(s); - stbi__rewind(s); - return r; -} - -static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) -{ - if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { - stbi__rewind( p->s ); - return 0; - } - if (x) *x = p->s->img_x; - if (y) *y = p->s->img_y; - if (comp) *comp = p->s->img_n; - return 1; -} - -static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp) -{ - stbi__png p; - p.s = s; - return stbi__png_info_raw(&p, x, y, comp); -} - -static int stbi__png_is16(stbi__context *s) -{ - stbi__png p; - p.s = s; - if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) - return 0; - if (p.depth != 16) { - stbi__rewind(p.s); - return 0; - } - return 1; -} -#endif - -// Microsoft/Windows BMP image - -#ifndef STBI_NO_BMP -static int stbi__bmp_test_raw(stbi__context *s) -{ - int r; - int sz; - if (stbi__get8(s) != 'B') return 0; - if (stbi__get8(s) != 'M') return 0; - stbi__get32le(s); // discard filesize - stbi__get16le(s); // discard reserved - stbi__get16le(s); // discard reserved - stbi__get32le(s); // discard data offset - sz = stbi__get32le(s); - r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); - return r; -} - -static int stbi__bmp_test(stbi__context *s) -{ - int r = stbi__bmp_test_raw(s); - stbi__rewind(s); - return r; -} - - -// returns 0..31 for the highest set bit -static int stbi__high_bit(unsigned int z) -{ - int n=0; - if (z == 0) return -1; - if (z >= 0x10000) { n += 16; z >>= 16; } - if (z >= 0x00100) { n += 8; z >>= 8; } - if (z >= 0x00010) { n += 4; z >>= 4; } - if (z >= 0x00004) { n += 2; z >>= 2; } - if (z >= 0x00002) { n += 1;/* >>= 1;*/ } - return n; -} - -static int stbi__bitcount(unsigned int a) -{ - a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 - a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 - a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits - a = (a + (a >> 8)); // max 16 per 8 bits - a = (a + (a >> 16)); // max 32 per 8 bits - return a & 0xff; -} - -// extract an arbitrarily-aligned N-bit value (N=bits) -// from v, and then make it 8-bits long and fractionally -// extend it to full full range. -static int stbi__shiftsigned(unsigned int v, int shift, int bits) -{ - static unsigned int mul_table[9] = { - 0, - 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, - 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, - }; - static unsigned int shift_table[9] = { - 0, 0,0,1,0,2,4,6,0, - }; - if (shift < 0) - v <<= -shift; - else - v >>= shift; - STBI_ASSERT(v < 256); - v >>= (8-bits); - STBI_ASSERT(bits >= 0 && bits <= 8); - return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits]; -} - -typedef struct -{ - int bpp, offset, hsz; - unsigned int mr,mg,mb,ma, all_a; - int extra_read; -} stbi__bmp_data; - -static int stbi__bmp_set_mask_defaults(stbi__bmp_data *info, int compress) -{ - // BI_BITFIELDS specifies masks explicitly, don't override - if (compress == 3) - return 1; - - if (compress == 0) { - if (info->bpp == 16) { - info->mr = 31u << 10; - info->mg = 31u << 5; - info->mb = 31u << 0; - } else if (info->bpp == 32) { - info->mr = 0xffu << 16; - info->mg = 0xffu << 8; - info->mb = 0xffu << 0; - info->ma = 0xffu << 24; - info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 - } else { - // otherwise, use defaults, which is all-0 - info->mr = info->mg = info->mb = info->ma = 0; - } - return 1; - } - return 0; // error -} - -static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) -{ - int hsz; - if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); - stbi__get32le(s); // discard filesize - stbi__get16le(s); // discard reserved - stbi__get16le(s); // discard reserved - info->offset = stbi__get32le(s); - info->hsz = hsz = stbi__get32le(s); - info->mr = info->mg = info->mb = info->ma = 0; - info->extra_read = 14; - - if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); - - if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); - if (hsz == 12) { - s->img_x = stbi__get16le(s); - s->img_y = stbi__get16le(s); - } else { - s->img_x = stbi__get32le(s); - s->img_y = stbi__get32le(s); - } - if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); - info->bpp = stbi__get16le(s); - if (hsz != 12) { - int compress = stbi__get32le(s); - if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); - if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes - if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel - stbi__get32le(s); // discard sizeof - stbi__get32le(s); // discard hres - stbi__get32le(s); // discard vres - stbi__get32le(s); // discard colorsused - stbi__get32le(s); // discard max important - if (hsz == 40 || hsz == 56) { - if (hsz == 56) { - stbi__get32le(s); - stbi__get32le(s); - stbi__get32le(s); - stbi__get32le(s); - } - if (info->bpp == 16 || info->bpp == 32) { - if (compress == 0) { - stbi__bmp_set_mask_defaults(info, compress); - } else if (compress == 3) { - info->mr = stbi__get32le(s); - info->mg = stbi__get32le(s); - info->mb = stbi__get32le(s); - info->extra_read += 12; - // not documented, but generated by photoshop and handled by mspaint - if (info->mr == info->mg && info->mg == info->mb) { - // ?!?!? - return stbi__errpuc("bad BMP", "bad BMP"); - } - } else - return stbi__errpuc("bad BMP", "bad BMP"); - } - } else { - // V4/V5 header - int i; - if (hsz != 108 && hsz != 124) - return stbi__errpuc("bad BMP", "bad BMP"); - info->mr = stbi__get32le(s); - info->mg = stbi__get32le(s); - info->mb = stbi__get32le(s); - info->ma = stbi__get32le(s); - if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs - stbi__bmp_set_mask_defaults(info, compress); - stbi__get32le(s); // discard color space - for (i=0; i < 12; ++i) - stbi__get32le(s); // discard color space parameters - if (hsz == 124) { - stbi__get32le(s); // discard rendering intent - stbi__get32le(s); // discard offset of profile data - stbi__get32le(s); // discard size of profile data - stbi__get32le(s); // discard reserved - } - } - } - return (void *) 1; -} - - -static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - stbi_uc *out; - unsigned int mr=0,mg=0,mb=0,ma=0, all_a; - stbi_uc pal[256][4]; - int psize=0,i,j,width; - int flip_vertically, pad, target; - stbi__bmp_data info; - STBI_NOTUSED(ri); - - info.all_a = 255; - if (stbi__bmp_parse_header(s, &info) == NULL) - return NULL; // error code already set - - flip_vertically = ((int) s->img_y) > 0; - s->img_y = abs((int) s->img_y); - - if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - - mr = info.mr; - mg = info.mg; - mb = info.mb; - ma = info.ma; - all_a = info.all_a; - - if (info.hsz == 12) { - if (info.bpp < 24) - psize = (info.offset - info.extra_read - 24) / 3; - } else { - if (info.bpp < 16) - psize = (info.offset - info.extra_read - info.hsz) >> 2; - } - if (psize == 0) { - // accept some number of extra bytes after the header, but if the offset points either to before - // the header ends or implies a large amount of extra data, reject the file as malformed - int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); - int header_limit = 1024; // max we actually read is below 256 bytes currently. - int extra_data_limit = 256*4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. - if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { - return stbi__errpuc("bad header", "Corrupt BMP"); - } - // we established that bytes_read_so_far is positive and sensible. - // the first half of this test rejects offsets that are either too small positives, or - // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn - // ensures the number computed in the second half of the test can't overflow. - if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { - return stbi__errpuc("bad offset", "Corrupt BMP"); - } else { - stbi__skip(s, info.offset - bytes_read_so_far); - } - } - - if (info.bpp == 24 && ma == 0xff000000) - s->img_n = 3; - else - s->img_n = ma ? 4 : 3; - if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 - target = req_comp; - else - target = s->img_n; // if they want monochrome, we'll post-convert - - // sanity-check size - if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) - return stbi__errpuc("too large", "Corrupt BMP"); - - out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - if (info.bpp < 16) { - int z=0; - if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } - for (i=0; i < psize; ++i) { - pal[i][2] = stbi__get8(s); - pal[i][1] = stbi__get8(s); - pal[i][0] = stbi__get8(s); - if (info.hsz != 12) stbi__get8(s); - pal[i][3] = 255; - } - stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); - if (info.bpp == 1) width = (s->img_x + 7) >> 3; - else if (info.bpp == 4) width = (s->img_x + 1) >> 1; - else if (info.bpp == 8) width = s->img_x; - else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } - pad = (-width)&3; - if (info.bpp == 1) { - for (j=0; j < (int) s->img_y; ++j) { - int bit_offset = 7, v = stbi__get8(s); - for (i=0; i < (int) s->img_x; ++i) { - int color = (v>>bit_offset)&0x1; - out[z++] = pal[color][0]; - out[z++] = pal[color][1]; - out[z++] = pal[color][2]; - if (target == 4) out[z++] = 255; - if (i+1 == (int) s->img_x) break; - if((--bit_offset) < 0) { - bit_offset = 7; - v = stbi__get8(s); - } - } - stbi__skip(s, pad); - } - } else { - for (j=0; j < (int) s->img_y; ++j) { - for (i=0; i < (int) s->img_x; i += 2) { - int v=stbi__get8(s),v2=0; - if (info.bpp == 4) { - v2 = v & 15; - v >>= 4; - } - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - if (i+1 == (int) s->img_x) break; - v = (info.bpp == 8) ? stbi__get8(s) : v2; - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - } - stbi__skip(s, pad); - } - } - } else { - int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; - int z = 0; - int easy=0; - stbi__skip(s, info.offset - info.extra_read - info.hsz); - if (info.bpp == 24) width = 3 * s->img_x; - else if (info.bpp == 16) width = 2*s->img_x; - else /* bpp = 32 and pad = 0 */ width=0; - pad = (-width) & 3; - if (info.bpp == 24) { - easy = 1; - } else if (info.bpp == 32) { - if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) - easy = 2; - } - if (!easy) { - if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } - // right shift amt to put high bit in position #7 - rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr); - gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); - bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); - ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); - if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } - } - for (j=0; j < (int) s->img_y; ++j) { - if (easy) { - for (i=0; i < (int) s->img_x; ++i) { - unsigned char a; - out[z+2] = stbi__get8(s); - out[z+1] = stbi__get8(s); - out[z+0] = stbi__get8(s); - z += 3; - a = (easy == 2 ? stbi__get8(s) : 255); - all_a |= a; - if (target == 4) out[z++] = a; - } - } else { - int bpp = info.bpp; - for (i=0; i < (int) s->img_x; ++i) { - stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); - unsigned int a; - out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); - out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); - out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); - a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); - all_a |= a; - if (target == 4) out[z++] = STBI__BYTECAST(a); - } - } - stbi__skip(s, pad); - } - } - - // if alpha channel is all 0s, replace with all 255s - if (target == 4 && all_a == 0) - for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) - out[i] = 255; - - if (flip_vertically) { - stbi_uc t; - for (j=0; j < (int) s->img_y>>1; ++j) { - stbi_uc *p1 = out + j *s->img_x*target; - stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; - for (i=0; i < (int) s->img_x*target; ++i) { - t = p1[i]; p1[i] = p2[i]; p2[i] = t; - } - } - } - - if (req_comp && req_comp != target) { - out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); - if (out == NULL) return out; // stbi__convert_format frees input on failure - } - - *x = s->img_x; - *y = s->img_y; - if (comp) *comp = s->img_n; - return out; -} -#endif - -// Targa Truevision - TGA -// by Jonathan Dummer -#ifndef STBI_NO_TGA -// returns STBI_rgb or whatever, 0 on error -static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) -{ - // only RGB or RGBA (incl. 16bit) or grey allowed - if (is_rgb16) *is_rgb16 = 0; - switch(bits_per_pixel) { - case 8: return STBI_grey; - case 16: if(is_grey) return STBI_grey_alpha; - // fallthrough - case 15: if(is_rgb16) *is_rgb16 = 1; - return STBI_rgb; - case 24: // fallthrough - case 32: return bits_per_pixel/8; - default: return 0; - } -} - -static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) -{ - int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; - int sz, tga_colormap_type; - stbi__get8(s); // discard Offset - tga_colormap_type = stbi__get8(s); // colormap type - if( tga_colormap_type > 1 ) { - stbi__rewind(s); - return 0; // only RGB or indexed allowed - } - tga_image_type = stbi__get8(s); // image type - if ( tga_colormap_type == 1 ) { // colormapped (paletted) image - if (tga_image_type != 1 && tga_image_type != 9) { - stbi__rewind(s); - return 0; - } - stbi__skip(s,4); // skip index of first colormap entry and number of entries - sz = stbi__get8(s); // check bits per palette color entry - if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) { - stbi__rewind(s); - return 0; - } - stbi__skip(s,4); // skip image x and y origin - tga_colormap_bpp = sz; - } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE - if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) { - stbi__rewind(s); - return 0; // only RGB or grey allowed, +/- RLE - } - stbi__skip(s,9); // skip colormap specification and image x/y origin - tga_colormap_bpp = 0; - } - tga_w = stbi__get16le(s); - if( tga_w < 1 ) { - stbi__rewind(s); - return 0; // test width - } - tga_h = stbi__get16le(s); - if( tga_h < 1 ) { - stbi__rewind(s); - return 0; // test height - } - tga_bits_per_pixel = stbi__get8(s); // bits per pixel - stbi__get8(s); // ignore alpha bits - if (tga_colormap_bpp != 0) { - if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { - // when using a colormap, tga_bits_per_pixel is the size of the indexes - // I don't think anything but 8 or 16bit indexes makes sense - stbi__rewind(s); - return 0; - } - tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); - } else { - tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); - } - if(!tga_comp) { - stbi__rewind(s); - return 0; - } - if (x) *x = tga_w; - if (y) *y = tga_h; - if (comp) *comp = tga_comp; - return 1; // seems to have passed everything -} - -static int stbi__tga_test(stbi__context *s) -{ - int res = 0; - int sz, tga_color_type; - stbi__get8(s); // discard Offset - tga_color_type = stbi__get8(s); // color type - if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed - sz = stbi__get8(s); // image type - if ( tga_color_type == 1 ) { // colormapped (paletted) image - if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 - stbi__skip(s,4); // skip index of first colormap entry and number of entries - sz = stbi__get8(s); // check bits per palette color entry - if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; - stbi__skip(s,4); // skip image x and y origin - } else { // "normal" image w/o colormap - if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE - stbi__skip(s,9); // skip colormap specification and image x/y origin - } - if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width - if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height - sz = stbi__get8(s); // bits per pixel - if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index - if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; - - res = 1; // if we got this far, everything's good and we can return 1 instead of 0 - -errorEnd: - stbi__rewind(s); - return res; -} - -// read 16bit value and convert to 24bit RGB -static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) -{ - stbi__uint16 px = (stbi__uint16)stbi__get16le(s); - stbi__uint16 fiveBitMask = 31; - // we have 3 channels with 5bits each - int r = (px >> 10) & fiveBitMask; - int g = (px >> 5) & fiveBitMask; - int b = px & fiveBitMask; - // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later - out[0] = (stbi_uc)((r * 255)/31); - out[1] = (stbi_uc)((g * 255)/31); - out[2] = (stbi_uc)((b * 255)/31); - - // some people claim that the most significant bit might be used for alpha - // (possibly if an alpha-bit is set in the "image descriptor byte") - // but that only made 16bit test images completely translucent.. - // so let's treat all 15 and 16bit TGAs as RGB with no alpha. -} - -static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - // read in the TGA header stuff - int tga_offset = stbi__get8(s); - int tga_indexed = stbi__get8(s); - int tga_image_type = stbi__get8(s); - int tga_is_RLE = 0; - int tga_palette_start = stbi__get16le(s); - int tga_palette_len = stbi__get16le(s); - int tga_palette_bits = stbi__get8(s); - int tga_x_origin = stbi__get16le(s); - int tga_y_origin = stbi__get16le(s); - int tga_width = stbi__get16le(s); - int tga_height = stbi__get16le(s); - int tga_bits_per_pixel = stbi__get8(s); - int tga_comp, tga_rgb16=0; - int tga_inverted = stbi__get8(s); - // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) - // image data - unsigned char *tga_data; - unsigned char *tga_palette = NULL; - int i, j; - unsigned char raw_data[4] = {0}; - int RLE_count = 0; - int RLE_repeating = 0; - int read_next_pixel = 1; - STBI_NOTUSED(ri); - STBI_NOTUSED(tga_x_origin); // @TODO - STBI_NOTUSED(tga_y_origin); // @TODO - - if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - - // do a tiny bit of precessing - if ( tga_image_type >= 8 ) - { - tga_image_type -= 8; - tga_is_RLE = 1; - } - tga_inverted = 1 - ((tga_inverted >> 5) & 1); - - // If I'm paletted, then I'll use the number of bits from the palette - if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); - else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); - - if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency - return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); - - // tga info - *x = tga_width; - *y = tga_height; - if (comp) *comp = tga_comp; - - if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) - return stbi__errpuc("too large", "Corrupt TGA"); - - tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); - if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); - - // skip to the data's starting position (offset usually = 0) - stbi__skip(s, tga_offset ); - - if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) { - for (i=0; i < tga_height; ++i) { - int row = tga_inverted ? tga_height -i - 1 : i; - stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; - stbi__getn(s, tga_row, tga_width * tga_comp); - } - } else { - // do I need to load a palette? - if ( tga_indexed) - { - if (tga_palette_len == 0) { /* you have to have at least one entry! */ - STBI_FREE(tga_data); - return stbi__errpuc("bad palette", "Corrupt TGA"); - } - - // any data to skip? (offset usually = 0) - stbi__skip(s, tga_palette_start ); - // load the palette - tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); - if (!tga_palette) { - STBI_FREE(tga_data); - return stbi__errpuc("outofmem", "Out of memory"); - } - if (tga_rgb16) { - stbi_uc *pal_entry = tga_palette; - STBI_ASSERT(tga_comp == STBI_rgb); - for (i=0; i < tga_palette_len; ++i) { - stbi__tga_read_rgb16(s, pal_entry); - pal_entry += tga_comp; - } - } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { - STBI_FREE(tga_data); - STBI_FREE(tga_palette); - return stbi__errpuc("bad palette", "Corrupt TGA"); - } - } - // load the data - for (i=0; i < tga_width * tga_height; ++i) - { - // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? - if ( tga_is_RLE ) - { - if ( RLE_count == 0 ) - { - // yep, get the next byte as a RLE command - int RLE_cmd = stbi__get8(s); - RLE_count = 1 + (RLE_cmd & 127); - RLE_repeating = RLE_cmd >> 7; - read_next_pixel = 1; - } else if ( !RLE_repeating ) - { - read_next_pixel = 1; - } - } else - { - read_next_pixel = 1; - } - // OK, if I need to read a pixel, do it now - if ( read_next_pixel ) - { - // load however much data we did have - if ( tga_indexed ) - { - // read in index, then perform the lookup - int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); - if ( pal_idx >= tga_palette_len ) { - // invalid index - pal_idx = 0; - } - pal_idx *= tga_comp; - for (j = 0; j < tga_comp; ++j) { - raw_data[j] = tga_palette[pal_idx+j]; - } - } else if(tga_rgb16) { - STBI_ASSERT(tga_comp == STBI_rgb); - stbi__tga_read_rgb16(s, raw_data); - } else { - // read in the data raw - for (j = 0; j < tga_comp; ++j) { - raw_data[j] = stbi__get8(s); - } - } - // clear the reading flag for the next pixel - read_next_pixel = 0; - } // end of reading a pixel - - // copy data - for (j = 0; j < tga_comp; ++j) - tga_data[i*tga_comp+j] = raw_data[j]; - - // in case we're in RLE mode, keep counting down - --RLE_count; - } - // do I need to invert the image? - if ( tga_inverted ) - { - for (j = 0; j*2 < tga_height; ++j) - { - int index1 = j * tga_width * tga_comp; - int index2 = (tga_height - 1 - j) * tga_width * tga_comp; - for (i = tga_width * tga_comp; i > 0; --i) - { - unsigned char temp = tga_data[index1]; - tga_data[index1] = tga_data[index2]; - tga_data[index2] = temp; - ++index1; - ++index2; - } - } - } - // clear my palette, if I had one - if ( tga_palette != NULL ) - { - STBI_FREE( tga_palette ); - } - } - - // swap RGB - if the source data was RGB16, it already is in the right order - if (tga_comp >= 3 && !tga_rgb16) - { - unsigned char* tga_pixel = tga_data; - for (i=0; i < tga_width * tga_height; ++i) - { - unsigned char temp = tga_pixel[0]; - tga_pixel[0] = tga_pixel[2]; - tga_pixel[2] = temp; - tga_pixel += tga_comp; - } - } - - // convert to target component count - if (req_comp && req_comp != tga_comp) - tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); - - // the things I do to get rid of an error message, and yet keep - // Microsoft's C compilers happy... [8^( - tga_palette_start = tga_palette_len = tga_palette_bits = - tga_x_origin = tga_y_origin = 0; - STBI_NOTUSED(tga_palette_start); - // OK, done - return tga_data; -} -#endif - -// ************************************************************************************************* -// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB - -#ifndef STBI_NO_PSD -static int stbi__psd_test(stbi__context *s) -{ - int r = (stbi__get32be(s) == 0x38425053); - stbi__rewind(s); - return r; -} - -static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount) -{ - int count, nleft, len; - - count = 0; - while ((nleft = pixelCount - count) > 0) { - len = stbi__get8(s); - if (len == 128) { - // No-op. - } else if (len < 128) { - // Copy next len+1 bytes literally. - len++; - if (len > nleft) return 0; // corrupt data - count += len; - while (len) { - *p = stbi__get8(s); - p += 4; - len--; - } - } else if (len > 128) { - stbi_uc val; - // Next -len+1 bytes in the dest are replicated from next source byte. - // (Interpret len as a negative 8-bit int.) - len = 257 - len; - if (len > nleft) return 0; // corrupt data - val = stbi__get8(s); - count += len; - while (len) { - *p = val; - p += 4; - len--; - } - } - } - - return 1; -} - -static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) -{ - int pixelCount; - int channelCount, compression; - int channel, i; - int bitdepth; - int w,h; - stbi_uc *out; - STBI_NOTUSED(ri); - - // Check identifier - if (stbi__get32be(s) != 0x38425053) // "8BPS" - return stbi__errpuc("not PSD", "Corrupt PSD image"); - - // Check file type version. - if (stbi__get16be(s) != 1) - return stbi__errpuc("wrong version", "Unsupported version of PSD image"); - - // Skip 6 reserved bytes. - stbi__skip(s, 6 ); - - // Read the number of channels (R, G, B, A, etc). - channelCount = stbi__get16be(s); - if (channelCount < 0 || channelCount > 16) - return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); - - // Read the rows and columns of the image. - h = stbi__get32be(s); - w = stbi__get32be(s); - - if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - - // Make sure the depth is 8 bits. - bitdepth = stbi__get16be(s); - if (bitdepth != 8 && bitdepth != 16) - return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); - - // Make sure the color mode is RGB. - // Valid options are: - // 0: Bitmap - // 1: Grayscale - // 2: Indexed color - // 3: RGB color - // 4: CMYK color - // 7: Multichannel - // 8: Duotone - // 9: Lab color - if (stbi__get16be(s) != 3) - return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); - - // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) - stbi__skip(s,stbi__get32be(s) ); - - // Skip the image resources. (resolution, pen tool paths, etc) - stbi__skip(s, stbi__get32be(s) ); - - // Skip the reserved data. - stbi__skip(s, stbi__get32be(s) ); - - // Find out if the data is compressed. - // Known values: - // 0: no compression - // 1: RLE compressed - compression = stbi__get16be(s); - if (compression > 1) - return stbi__errpuc("bad compression", "PSD has an unknown compression format"); - - // Check size - if (!stbi__mad3sizes_valid(4, w, h, 0)) - return stbi__errpuc("too large", "Corrupt PSD"); - - // Create the destination image. - - if (!compression && bitdepth == 16 && bpc == 16) { - out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); - ri->bits_per_channel = 16; - } else - out = (stbi_uc *) stbi__malloc(4 * w*h); - - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - pixelCount = w*h; - - // Initialize the data to zero. - //memset( out, 0, pixelCount * 4 ); - - // Finally, the image data. - if (compression) { - // RLE as used by .PSD and .TIFF - // Loop until you get the number of unpacked bytes you are expecting: - // Read the next source byte into n. - // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. - // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. - // Else if n is 128, noop. - // Endloop - - // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, - // which we're going to just skip. - stbi__skip(s, h * channelCount * 2 ); - - // Read the RLE data by channel. - for (channel = 0; channel < 4; channel++) { - stbi_uc *p; - - p = out+channel; - if (channel >= channelCount) { - // Fill this channel with default data. - for (i = 0; i < pixelCount; i++, p += 4) - *p = (channel == 3 ? 255 : 0); - } else { - // Read the RLE data. - if (!stbi__psd_decode_rle(s, p, pixelCount)) { - STBI_FREE(out); - return stbi__errpuc("corrupt", "bad RLE data"); - } - } - } - - } else { - // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) - // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. - - // Read the data by channel. - for (channel = 0; channel < 4; channel++) { - if (channel >= channelCount) { - // Fill this channel with default data. - if (bitdepth == 16 && bpc == 16) { - stbi__uint16 *q = ((stbi__uint16 *) out) + channel; - stbi__uint16 val = channel == 3 ? 65535 : 0; - for (i = 0; i < pixelCount; i++, q += 4) - *q = val; - } else { - stbi_uc *p = out+channel; - stbi_uc val = channel == 3 ? 255 : 0; - for (i = 0; i < pixelCount; i++, p += 4) - *p = val; - } - } else { - if (ri->bits_per_channel == 16) { // output bpc - stbi__uint16 *q = ((stbi__uint16 *) out) + channel; - for (i = 0; i < pixelCount; i++, q += 4) - *q = (stbi__uint16) stbi__get16be(s); - } else { - stbi_uc *p = out+channel; - if (bitdepth == 16) { // input bpc - for (i = 0; i < pixelCount; i++, p += 4) - *p = (stbi_uc) (stbi__get16be(s) >> 8); - } else { - for (i = 0; i < pixelCount; i++, p += 4) - *p = stbi__get8(s); - } - } - } - } - } - - // remove weird white matte from PSD - if (channelCount >= 4) { - if (ri->bits_per_channel == 16) { - for (i=0; i < w*h; ++i) { - stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i; - if (pixel[3] != 0 && pixel[3] != 65535) { - float a = pixel[3] / 65535.0f; - float ra = 1.0f / a; - float inv_a = 65535.0f * (1 - ra); - pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a); - pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a); - pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a); - } - } - } else { - for (i=0; i < w*h; ++i) { - unsigned char *pixel = out + 4*i; - if (pixel[3] != 0 && pixel[3] != 255) { - float a = pixel[3] / 255.0f; - float ra = 1.0f / a; - float inv_a = 255.0f * (1 - ra); - pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); - pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); - pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); - } - } - } - } - - // convert to desired output format - if (req_comp && req_comp != 4) { - if (ri->bits_per_channel == 16) - out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h); - else - out = stbi__convert_format(out, 4, req_comp, w, h); - if (out == NULL) return out; // stbi__convert_format frees input on failure - } - - if (comp) *comp = 4; - *y = h; - *x = w; - - return out; -} -#endif - -// ************************************************************************************************* -// Softimage PIC loader -// by Tom Seddon -// -// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format -// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ - -#ifndef STBI_NO_PIC -static int stbi__pic_is4(stbi__context *s,const char *str) -{ - int i; - for (i=0; i<4; ++i) - if (stbi__get8(s) != (stbi_uc)str[i]) - return 0; - - return 1; -} - -static int stbi__pic_test_core(stbi__context *s) -{ - int i; - - if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) - return 0; - - for(i=0;i<84;++i) - stbi__get8(s); - - if (!stbi__pic_is4(s,"PICT")) - return 0; - - return 1; -} - -typedef struct -{ - stbi_uc size,type,channel; -} stbi__pic_packet; - -static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) -{ - int mask=0x80, i; - - for (i=0; i<4; ++i, mask>>=1) { - if (channel & mask) { - if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short"); - dest[i]=stbi__get8(s); - } - } - - return dest; -} - -static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src) -{ - int mask=0x80,i; - - for (i=0;i<4; ++i, mask>>=1) - if (channel&mask) - dest[i]=src[i]; -} - -static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result) -{ - int act_comp=0,num_packets=0,y,chained; - stbi__pic_packet packets[10]; - - // this will (should...) cater for even some bizarre stuff like having data - // for the same channel in multiple packets. - do { - stbi__pic_packet *packet; - - if (num_packets==sizeof(packets)/sizeof(packets[0])) - return stbi__errpuc("bad format","too many packets"); - - packet = &packets[num_packets++]; - - chained = stbi__get8(s); - packet->size = stbi__get8(s); - packet->type = stbi__get8(s); - packet->channel = stbi__get8(s); - - act_comp |= packet->channel; - - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)"); - if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp"); - } while (chained); - - *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? - - for(y=0; y<height; ++y) { - int packet_idx; - - for(packet_idx=0; packet_idx < num_packets; ++packet_idx) { - stbi__pic_packet *packet = &packets[packet_idx]; - stbi_uc *dest = result+y*width*4; - - switch (packet->type) { - default: - return stbi__errpuc("bad format","packet has bad compression type"); - - case 0: {//uncompressed - int x; - - for(x=0;x<width;++x, dest+=4) - if (!stbi__readval(s,packet->channel,dest)) - return 0; - break; - } - - case 1://Pure RLE - { - int left=width, i; - - while (left>0) { - stbi_uc count,value[4]; - - count=stbi__get8(s); - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)"); - - if (count > left) - count = (stbi_uc) left; - - if (!stbi__readval(s,packet->channel,value)) return 0; - - for(i=0; i<count; ++i,dest+=4) - stbi__copyval(packet->channel,dest,value); - left -= count; - } - } - break; - - case 2: {//Mixed RLE - int left=width; - while (left>0) { - int count = stbi__get8(s), i; - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)"); - - if (count >= 128) { // Repeated - stbi_uc value[4]; - - if (count==128) - count = stbi__get16be(s); - else - count -= 127; - if (count > left) - return stbi__errpuc("bad file","scanline overrun"); - - if (!stbi__readval(s,packet->channel,value)) - return 0; - - for(i=0;i<count;++i, dest += 4) - stbi__copyval(packet->channel,dest,value); - } else { // Raw - ++count; - if (count>left) return stbi__errpuc("bad file","scanline overrun"); - - for(i=0;i<count;++i, dest+=4) - if (!stbi__readval(s,packet->channel,dest)) - return 0; - } - left-=count; - } - break; - } - } - } - } - - return result; -} - -static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri) -{ - stbi_uc *result; - int i, x,y, internal_comp; - STBI_NOTUSED(ri); - - if (!comp) comp = &internal_comp; - - for (i=0; i<92; ++i) - stbi__get8(s); - - x = stbi__get16be(s); - y = stbi__get16be(s); - - if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); - if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); - - stbi__get32be(s); //skip `ratio' - stbi__get16be(s); //skip `fields' - stbi__get16be(s); //skip `pad' - - // intermediate buffer is RGBA - result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); - if (!result) return stbi__errpuc("outofmem", "Out of memory"); - memset(result, 0xff, x*y*4); - - if (!stbi__pic_load_core(s,x,y,comp, result)) { - STBI_FREE(result); - result=0; - } - *px = x; - *py = y; - if (req_comp == 0) req_comp = *comp; - result=stbi__convert_format(result,4,req_comp,x,y); - - return result; -} - -static int stbi__pic_test(stbi__context *s) -{ - int r = stbi__pic_test_core(s); - stbi__rewind(s); - return r; -} -#endif - -// ************************************************************************************************* -// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb - -#ifndef STBI_NO_GIF -typedef struct -{ - stbi__int16 prefix; - stbi_uc first; - stbi_uc suffix; -} stbi__gif_lzw; - -typedef struct -{ - int w,h; - stbi_uc *out; // output buffer (always 4 components) - stbi_uc *background; // The current "background" as far as a gif is concerned - stbi_uc *history; - int flags, bgindex, ratio, transparent, eflags; - stbi_uc pal[256][4]; - stbi_uc lpal[256][4]; - stbi__gif_lzw codes[8192]; - stbi_uc *color_table; - int parse, step; - int lflags; - int start_x, start_y; - int max_x, max_y; - int cur_x, cur_y; - int line_size; - int delay; -} stbi__gif; - -static int stbi__gif_test_raw(stbi__context *s) -{ - int sz; - if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; - sz = stbi__get8(s); - if (sz != '9' && sz != '7') return 0; - if (stbi__get8(s) != 'a') return 0; - return 1; -} - -static int stbi__gif_test(stbi__context *s) -{ - int r = stbi__gif_test_raw(s); - stbi__rewind(s); - return r; -} - -static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) -{ - int i; - for (i=0; i < num_entries; ++i) { - pal[i][2] = stbi__get8(s); - pal[i][1] = stbi__get8(s); - pal[i][0] = stbi__get8(s); - pal[i][3] = transp == i ? 0 : 255; - } -} - -static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) -{ - stbi_uc version; - if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') - return stbi__err("not GIF", "Corrupt GIF"); - - version = stbi__get8(s); - if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); - if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); - - stbi__g_failure_reason = ""; - g->w = stbi__get16le(s); - g->h = stbi__get16le(s); - g->flags = stbi__get8(s); - g->bgindex = stbi__get8(s); - g->ratio = stbi__get8(s); - g->transparent = -1; - - if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); - if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); - - if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments - - if (is_info) return 1; - - if (g->flags & 0x80) - stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); - - return 1; -} - -static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) -{ - stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); - if (!g) return stbi__err("outofmem", "Out of memory"); - if (!stbi__gif_header(s, g, comp, 1)) { - STBI_FREE(g); - stbi__rewind( s ); - return 0; - } - if (x) *x = g->w; - if (y) *y = g->h; - STBI_FREE(g); - return 1; -} - -static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) -{ - stbi_uc *p, *c; - int idx; - - // recurse to decode the prefixes, since the linked-list is backwards, - // and working backwards through an interleaved image would be nasty - if (g->codes[code].prefix >= 0) - stbi__out_gif_code(g, g->codes[code].prefix); - - if (g->cur_y >= g->max_y) return; - - idx = g->cur_x + g->cur_y; - p = &g->out[idx]; - g->history[idx / 4] = 1; - - c = &g->color_table[g->codes[code].suffix * 4]; - if (c[3] > 128) { // don't render transparent pixels; - p[0] = c[2]; - p[1] = c[1]; - p[2] = c[0]; - p[3] = c[3]; - } - g->cur_x += 4; - - if (g->cur_x >= g->max_x) { - g->cur_x = g->start_x; - g->cur_y += g->step; - - while (g->cur_y >= g->max_y && g->parse > 0) { - g->step = (1 << g->parse) * g->line_size; - g->cur_y = g->start_y + (g->step >> 1); - --g->parse; - } - } -} - -static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) -{ - stbi_uc lzw_cs; - stbi__int32 len, init_code; - stbi__uint32 first; - stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; - stbi__gif_lzw *p; - - lzw_cs = stbi__get8(s); - if (lzw_cs > 12) return NULL; - clear = 1 << lzw_cs; - first = 1; - codesize = lzw_cs + 1; - codemask = (1 << codesize) - 1; - bits = 0; - valid_bits = 0; - for (init_code = 0; init_code < clear; init_code++) { - g->codes[init_code].prefix = -1; - g->codes[init_code].first = (stbi_uc) init_code; - g->codes[init_code].suffix = (stbi_uc) init_code; - } - - // support no starting clear code - avail = clear+2; - oldcode = -1; - - len = 0; - for(;;) { - if (valid_bits < codesize) { - if (len == 0) { - len = stbi__get8(s); // start new block - if (len == 0) - return g->out; - } - --len; - bits |= (stbi__int32) stbi__get8(s) << valid_bits; - valid_bits += 8; - } else { - stbi__int32 code = bits & codemask; - bits >>= codesize; - valid_bits -= codesize; - // @OPTIMIZE: is there some way we can accelerate the non-clear path? - if (code == clear) { // clear code - codesize = lzw_cs + 1; - codemask = (1 << codesize) - 1; - avail = clear + 2; - oldcode = -1; - first = 0; - } else if (code == clear + 1) { // end of stream code - stbi__skip(s, len); - while ((len = stbi__get8(s)) > 0) - stbi__skip(s,len); - return g->out; - } else if (code <= avail) { - if (first) { - return stbi__errpuc("no clear code", "Corrupt GIF"); - } - - if (oldcode >= 0) { - p = &g->codes[avail++]; - if (avail > 8192) { - return stbi__errpuc("too many codes", "Corrupt GIF"); - } - - p->prefix = (stbi__int16) oldcode; - p->first = g->codes[oldcode].first; - p->suffix = (code == avail) ? p->first : g->codes[code].first; - } else if (code == avail) - return stbi__errpuc("illegal code in raster", "Corrupt GIF"); - - stbi__out_gif_code(g, (stbi__uint16) code); - - if ((avail & codemask) == 0 && avail <= 0x0FFF) { - codesize++; - codemask = (1 << codesize) - 1; - } - - oldcode = code; - } else { - return stbi__errpuc("illegal code in raster", "Corrupt GIF"); - } - } - } -} - -// this function is designed to support animated gifs, although stb_image doesn't support it -// two back is the image from two frames ago, used for a very specific disposal format -static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back) -{ - int dispose; - int first_frame; - int pi; - int pcount; - STBI_NOTUSED(req_comp); - - // on first frame, any non-written pixels get the background colour (non-transparent) - first_frame = 0; - if (g->out == 0) { - if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header - if (!stbi__mad3sizes_valid(4, g->w, g->h, 0)) - return stbi__errpuc("too large", "GIF image is too large"); - pcount = g->w * g->h; - g->out = (stbi_uc *) stbi__malloc(4 * pcount); - g->background = (stbi_uc *) stbi__malloc(4 * pcount); - g->history = (stbi_uc *) stbi__malloc(pcount); - if (!g->out || !g->background || !g->history) - return stbi__errpuc("outofmem", "Out of memory"); - - // image is treated as "transparent" at the start - ie, nothing overwrites the current background; - // background colour is only used for pixels that are not rendered first frame, after that "background" - // color refers to the color that was there the previous frame. - memset(g->out, 0x00, 4 * pcount); - memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent) - memset(g->history, 0x00, pcount); // pixels that were affected previous frame - first_frame = 1; - } else { - // second frame - how do we dispose of the previous one? - dispose = (g->eflags & 0x1C) >> 2; - pcount = g->w * g->h; - - if ((dispose == 3) && (two_back == 0)) { - dispose = 2; // if I don't have an image to revert back to, default to the old background - } - - if (dispose == 3) { // use previous graphic - for (pi = 0; pi < pcount; ++pi) { - if (g->history[pi]) { - memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 ); - } - } - } else if (dispose == 2) { - // restore what was changed last frame to background before that frame; - for (pi = 0; pi < pcount; ++pi) { - if (g->history[pi]) { - memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 ); - } - } - } else { - // This is a non-disposal case eithe way, so just - // leave the pixels as is, and they will become the new background - // 1: do not dispose - // 0: not specified. - } - - // background is what out is after the undoing of the previou frame; - memcpy( g->background, g->out, 4 * g->w * g->h ); - } - - // clear my history; - memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame - - for (;;) { - int tag = stbi__get8(s); - switch (tag) { - case 0x2C: /* Image Descriptor */ - { - stbi__int32 x, y, w, h; - stbi_uc *o; - - x = stbi__get16le(s); - y = stbi__get16le(s); - w = stbi__get16le(s); - h = stbi__get16le(s); - if (((x + w) > (g->w)) || ((y + h) > (g->h))) - return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); - - g->line_size = g->w * 4; - g->start_x = x * 4; - g->start_y = y * g->line_size; - g->max_x = g->start_x + w * 4; - g->max_y = g->start_y + h * g->line_size; - g->cur_x = g->start_x; - g->cur_y = g->start_y; - - // if the width of the specified rectangle is 0, that means - // we may not see *any* pixels or the image is malformed; - // to make sure this is caught, move the current y down to - // max_y (which is what out_gif_code checks). - if (w == 0) - g->cur_y = g->max_y; - - g->lflags = stbi__get8(s); - - if (g->lflags & 0x40) { - g->step = 8 * g->line_size; // first interlaced spacing - g->parse = 3; - } else { - g->step = g->line_size; - g->parse = 0; - } - - if (g->lflags & 0x80) { - stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); - g->color_table = (stbi_uc *) g->lpal; - } else if (g->flags & 0x80) { - g->color_table = (stbi_uc *) g->pal; - } else - return stbi__errpuc("missing color table", "Corrupt GIF"); - - o = stbi__process_gif_raster(s, g); - if (!o) return NULL; - - // if this was the first frame, - pcount = g->w * g->h; - if (first_frame && (g->bgindex > 0)) { - // if first frame, any pixel not drawn to gets the background color - for (pi = 0; pi < pcount; ++pi) { - if (g->history[pi] == 0) { - g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; - memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 ); - } - } - } - - return o; - } - - case 0x21: // Comment Extension. - { - int len; - int ext = stbi__get8(s); - if (ext == 0xF9) { // Graphic Control Extension. - len = stbi__get8(s); - if (len == 4) { - g->eflags = stbi__get8(s); - g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. - - // unset old transparent - if (g->transparent >= 0) { - g->pal[g->transparent][3] = 255; - } - if (g->eflags & 0x01) { - g->transparent = stbi__get8(s); - if (g->transparent >= 0) { - g->pal[g->transparent][3] = 0; - } - } else { - // don't need transparent - stbi__skip(s, 1); - g->transparent = -1; - } - } else { - stbi__skip(s, len); - break; - } - } - while ((len = stbi__get8(s)) != 0) { - stbi__skip(s, len); - } - break; - } - - case 0x3B: // gif stream termination code - return (stbi_uc *) s; // using '1' causes warning on some compilers - - default: - return stbi__errpuc("unknown code", "Corrupt GIF"); - } - } -} - -static void *stbi__load_gif_main_outofmem(stbi__gif *g, stbi_uc *out, int **delays) -{ - STBI_FREE(g->out); - STBI_FREE(g->history); - STBI_FREE(g->background); - - if (out) STBI_FREE(out); - if (delays && *delays) STBI_FREE(*delays); - return stbi__errpuc("outofmem", "Out of memory"); -} - -static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) -{ - if (stbi__gif_test(s)) { - int layers = 0; - stbi_uc *u = 0; - stbi_uc *out = 0; - stbi_uc *two_back = 0; - stbi__gif g; - int stride; - int out_size = 0; - int delays_size = 0; - - STBI_NOTUSED(out_size); - STBI_NOTUSED(delays_size); - - memset(&g, 0, sizeof(g)); - if (delays) { - *delays = 0; - } - - do { - u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); - if (u == (stbi_uc *) s) u = 0; // end of animated gif marker - - if (u) { - *x = g.w; - *y = g.h; - ++layers; - stride = g.w * g.h * 4; - - if (out) { - void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride ); - if (!tmp) - return stbi__load_gif_main_outofmem(&g, out, delays); - else { - out = (stbi_uc*) tmp; - out_size = layers * stride; - } - - if (delays) { - int *new_delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers ); - if (!new_delays) - return stbi__load_gif_main_outofmem(&g, out, delays); - *delays = new_delays; - delays_size = layers * sizeof(int); - } - } else { - out = (stbi_uc*)stbi__malloc( layers * stride ); - if (!out) - return stbi__load_gif_main_outofmem(&g, out, delays); - out_size = layers * stride; - if (delays) { - *delays = (int*) stbi__malloc( layers * sizeof(int) ); - if (!*delays) - return stbi__load_gif_main_outofmem(&g, out, delays); - delays_size = layers * sizeof(int); - } - } - memcpy( out + ((layers - 1) * stride), u, stride ); - if (layers >= 2) { - two_back = out - 2 * stride; - } - - if (delays) { - (*delays)[layers - 1U] = g.delay; - } - } - } while (u != 0); - - // free temp buffer; - STBI_FREE(g.out); - STBI_FREE(g.history); - STBI_FREE(g.background); - - // do the final conversion after loading everything; - if (req_comp && req_comp != 4) - out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h); - - *z = layers; - return out; - } else { - return stbi__errpuc("not GIF", "Image was not as a gif type."); - } -} - -static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - stbi_uc *u = 0; - stbi__gif g; - memset(&g, 0, sizeof(g)); - STBI_NOTUSED(ri); - - u = stbi__gif_load_next(s, &g, comp, req_comp, 0); - if (u == (stbi_uc *) s) u = 0; // end of animated gif marker - if (u) { - *x = g.w; - *y = g.h; - - // moved conversion to after successful load so that the same - // can be done for multiple frames. - if (req_comp && req_comp != 4) - u = stbi__convert_format(u, 4, req_comp, g.w, g.h); - } else if (g.out) { - // if there was an error and we allocated an image buffer, free it! - STBI_FREE(g.out); - } - - // free buffers needed for multiple frame loading; - STBI_FREE(g.history); - STBI_FREE(g.background); - - return u; -} - -static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) -{ - return stbi__gif_info_raw(s,x,y,comp); -} -#endif - -// ************************************************************************************************* -// Radiance RGBE HDR loader -// originally by Nicolas Schulz -#ifndef STBI_NO_HDR -static int stbi__hdr_test_core(stbi__context *s, const char *signature) -{ - int i; - for (i=0; signature[i]; ++i) - if (stbi__get8(s) != signature[i]) - return 0; - stbi__rewind(s); - return 1; -} - -static int stbi__hdr_test(stbi__context* s) -{ - int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); - stbi__rewind(s); - if(!r) { - r = stbi__hdr_test_core(s, "#?RGBE\n"); - stbi__rewind(s); - } - return r; -} - -#define STBI__HDR_BUFLEN 1024 -static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) -{ - int len=0; - char c = '\0'; - - c = (char) stbi__get8(z); - - while (!stbi__at_eof(z) && c != '\n') { - buffer[len++] = c; - if (len == STBI__HDR_BUFLEN-1) { - // flush to end of line - while (!stbi__at_eof(z) && stbi__get8(z) != '\n') - ; - break; - } - c = (char) stbi__get8(z); - } - - buffer[len] = 0; - return buffer; -} - -static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) -{ - if ( input[3] != 0 ) { - float f1; - // Exponent - f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); - if (req_comp <= 2) - output[0] = (input[0] + input[1] + input[2]) * f1 / 3; - else { - output[0] = input[0] * f1; - output[1] = input[1] * f1; - output[2] = input[2] * f1; - } - if (req_comp == 2) output[1] = 1; - if (req_comp == 4) output[3] = 1; - } else { - switch (req_comp) { - case 4: output[3] = 1; /* fallthrough */ - case 3: output[0] = output[1] = output[2] = 0; - break; - case 2: output[1] = 1; /* fallthrough */ - case 1: output[0] = 0; - break; - } - } -} - -static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - char buffer[STBI__HDR_BUFLEN]; - char *token; - int valid = 0; - int width, height; - stbi_uc *scanline; - float *hdr_data; - int len; - unsigned char count, value; - int i, j, k, c1,c2, z; - const char *headerToken; - STBI_NOTUSED(ri); - - // Check identifier - headerToken = stbi__hdr_gettoken(s,buffer); - if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) - return stbi__errpf("not HDR", "Corrupt HDR image"); - - // Parse header - for(;;) { - token = stbi__hdr_gettoken(s,buffer); - if (token[0] == 0) break; - if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; - } - - if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); - - // Parse width and height - // can't use sscanf() if we're not using stdio! - token = stbi__hdr_gettoken(s,buffer); - if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); - token += 3; - height = (int) strtol(token, &token, 10); - while (*token == ' ') ++token; - if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); - token += 3; - width = (int) strtol(token, NULL, 10); - - if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); - if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); - - *x = width; - *y = height; - - if (comp) *comp = 3; - if (req_comp == 0) req_comp = 3; - - if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) - return stbi__errpf("too large", "HDR image is too large"); - - // Read data - hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); - if (!hdr_data) - return stbi__errpf("outofmem", "Out of memory"); - - // Load image data - // image data is stored as some number of sca - if ( width < 8 || width >= 32768) { - // Read flat data - for (j=0; j < height; ++j) { - for (i=0; i < width; ++i) { - stbi_uc rgbe[4]; - main_decode_loop: - stbi__getn(s, rgbe, 4); - stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); - } - } - } else { - // Read RLE-encoded data - scanline = NULL; - - for (j = 0; j < height; ++j) { - c1 = stbi__get8(s); - c2 = stbi__get8(s); - len = stbi__get8(s); - if (c1 != 2 || c2 != 2 || (len & 0x80)) { - // not run-length encoded, so we have to actually use THIS data as a decoded - // pixel (note this can't be a valid pixel--one of RGB must be >= 128) - stbi_uc rgbe[4]; - rgbe[0] = (stbi_uc) c1; - rgbe[1] = (stbi_uc) c2; - rgbe[2] = (stbi_uc) len; - rgbe[3] = (stbi_uc) stbi__get8(s); - stbi__hdr_convert(hdr_data, rgbe, req_comp); - i = 1; - j = 0; - STBI_FREE(scanline); - goto main_decode_loop; // yes, this makes no sense - } - len <<= 8; - len |= stbi__get8(s); - if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } - if (scanline == NULL) { - scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0); - if (!scanline) { - STBI_FREE(hdr_data); - return stbi__errpf("outofmem", "Out of memory"); - } - } - - for (k = 0; k < 4; ++k) { - int nleft; - i = 0; - while ((nleft = width - i) > 0) { - count = stbi__get8(s); - if (count > 128) { - // Run - value = stbi__get8(s); - count -= 128; - if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = value; - } else { - // Dump - if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = stbi__get8(s); - } - } - } - for (i=0; i < width; ++i) - stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); - } - if (scanline) - STBI_FREE(scanline); - } - - return hdr_data; -} - -static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) -{ - char buffer[STBI__HDR_BUFLEN]; - char *token; - int valid = 0; - int dummy; - - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; - - if (stbi__hdr_test(s) == 0) { - stbi__rewind( s ); - return 0; - } - - for(;;) { - token = stbi__hdr_gettoken(s,buffer); - if (token[0] == 0) break; - if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; - } - - if (!valid) { - stbi__rewind( s ); - return 0; - } - token = stbi__hdr_gettoken(s,buffer); - if (strncmp(token, "-Y ", 3)) { - stbi__rewind( s ); - return 0; - } - token += 3; - *y = (int) strtol(token, &token, 10); - while (*token == ' ') ++token; - if (strncmp(token, "+X ", 3)) { - stbi__rewind( s ); - return 0; - } - token += 3; - *x = (int) strtol(token, NULL, 10); - *comp = 3; - return 1; -} -#endif // STBI_NO_HDR - -#ifndef STBI_NO_BMP -static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) -{ - void *p; - stbi__bmp_data info; - - info.all_a = 255; - p = stbi__bmp_parse_header(s, &info); - if (p == NULL) { - stbi__rewind( s ); - return 0; - } - if (x) *x = s->img_x; - if (y) *y = s->img_y; - if (comp) { - if (info.bpp == 24 && info.ma == 0xff000000) - *comp = 3; - else - *comp = info.ma ? 4 : 3; - } - return 1; -} -#endif - -#ifndef STBI_NO_PSD -static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) -{ - int channelCount, dummy, depth; - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; - if (stbi__get32be(s) != 0x38425053) { - stbi__rewind( s ); - return 0; - } - if (stbi__get16be(s) != 1) { - stbi__rewind( s ); - return 0; - } - stbi__skip(s, 6); - channelCount = stbi__get16be(s); - if (channelCount < 0 || channelCount > 16) { - stbi__rewind( s ); - return 0; - } - *y = stbi__get32be(s); - *x = stbi__get32be(s); - depth = stbi__get16be(s); - if (depth != 8 && depth != 16) { - stbi__rewind( s ); - return 0; - } - if (stbi__get16be(s) != 3) { - stbi__rewind( s ); - return 0; - } - *comp = 4; - return 1; -} - -static int stbi__psd_is16(stbi__context *s) -{ - int channelCount, depth; - if (stbi__get32be(s) != 0x38425053) { - stbi__rewind( s ); - return 0; - } - if (stbi__get16be(s) != 1) { - stbi__rewind( s ); - return 0; - } - stbi__skip(s, 6); - channelCount = stbi__get16be(s); - if (channelCount < 0 || channelCount > 16) { - stbi__rewind( s ); - return 0; - } - STBI_NOTUSED(stbi__get32be(s)); - STBI_NOTUSED(stbi__get32be(s)); - depth = stbi__get16be(s); - if (depth != 16) { - stbi__rewind( s ); - return 0; - } - return 1; -} -#endif - -#ifndef STBI_NO_PIC -static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) -{ - int act_comp=0,num_packets=0,chained,dummy; - stbi__pic_packet packets[10]; - - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; - - if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { - stbi__rewind(s); - return 0; - } - - stbi__skip(s, 88); - - *x = stbi__get16be(s); - *y = stbi__get16be(s); - if (stbi__at_eof(s)) { - stbi__rewind( s); - return 0; - } - if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { - stbi__rewind( s ); - return 0; - } - - stbi__skip(s, 8); - - do { - stbi__pic_packet *packet; - - if (num_packets==sizeof(packets)/sizeof(packets[0])) - return 0; - - packet = &packets[num_packets++]; - chained = stbi__get8(s); - packet->size = stbi__get8(s); - packet->type = stbi__get8(s); - packet->channel = stbi__get8(s); - act_comp |= packet->channel; - - if (stbi__at_eof(s)) { - stbi__rewind( s ); - return 0; - } - if (packet->size != 8) { - stbi__rewind( s ); - return 0; - } - } while (chained); - - *comp = (act_comp & 0x10 ? 4 : 3); - - return 1; -} -#endif - -// ************************************************************************************************* -// Portable Gray Map and Portable Pixel Map loader -// by Ken Miller -// -// PGM: http://netpbm.sourceforge.net/doc/pgm.html -// PPM: http://netpbm.sourceforge.net/doc/ppm.html -// -// Known limitations: -// Does not support comments in the header section -// Does not support ASCII image data (formats P2 and P3) - -#ifndef STBI_NO_PNM - -static int stbi__pnm_test(stbi__context *s) -{ - char p, t; - p = (char) stbi__get8(s); - t = (char) stbi__get8(s); - if (p != 'P' || (t != '5' && t != '6')) { - stbi__rewind( s ); - return 0; - } - return 1; -} - -static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - stbi_uc *out; - STBI_NOTUSED(ri); - - ri->bits_per_channel = stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n); - if (ri->bits_per_channel == 0) - return 0; - - if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - - *x = s->img_x; - *y = s->img_y; - if (comp) *comp = s->img_n; - - if (!stbi__mad4sizes_valid(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0)) - return stbi__errpuc("too large", "PNM too large"); - - out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - if (!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) { - STBI_FREE(out); - return stbi__errpuc("bad PNM", "PNM file truncated"); - } - - if (req_comp && req_comp != s->img_n) { - if (ri->bits_per_channel == 16) { - out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, s->img_n, req_comp, s->img_x, s->img_y); - } else { - out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); - } - if (out == NULL) return out; // stbi__convert_format frees input on failure - } - return out; -} - -static int stbi__pnm_isspace(char c) -{ - return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; -} - -static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) -{ - for (;;) { - while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) - *c = (char) stbi__get8(s); - - if (stbi__at_eof(s) || *c != '#') - break; - - while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' ) - *c = (char) stbi__get8(s); - } -} - -static int stbi__pnm_isdigit(char c) -{ - return c >= '0' && c <= '9'; -} - -static int stbi__pnm_getinteger(stbi__context *s, char *c) -{ - int value = 0; - - while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { - value = value*10 + (*c - '0'); - *c = (char) stbi__get8(s); - if((value > 214748364) || (value == 214748364 && *c > '7')) - return stbi__err("integer parse overflow", "Parsing an integer in the PPM header overflowed a 32-bit int"); - } - - return value; -} - -static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) -{ - int maxv, dummy; - char c, p, t; - - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; - - stbi__rewind(s); - - // Get identifier - p = (char) stbi__get8(s); - t = (char) stbi__get8(s); - if (p != 'P' || (t != '5' && t != '6')) { - stbi__rewind(s); - return 0; - } - - *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm - - c = (char) stbi__get8(s); - stbi__pnm_skip_whitespace(s, &c); - - *x = stbi__pnm_getinteger(s, &c); // read width - if(*x == 0) - return stbi__err("invalid width", "PPM image header had zero or overflowing width"); - stbi__pnm_skip_whitespace(s, &c); - - *y = stbi__pnm_getinteger(s, &c); // read height - if (*y == 0) - return stbi__err("invalid width", "PPM image header had zero or overflowing width"); - stbi__pnm_skip_whitespace(s, &c); - - maxv = stbi__pnm_getinteger(s, &c); // read max value - if (maxv > 65535) - return stbi__err("max value > 65535", "PPM image supports only 8-bit and 16-bit images"); - else if (maxv > 255) - return 16; - else - return 8; -} - -static int stbi__pnm_is16(stbi__context *s) -{ - if (stbi__pnm_info(s, NULL, NULL, NULL) == 16) - return 1; - return 0; -} -#endif - -static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) -{ - #ifndef STBI_NO_JPEG - if (stbi__jpeg_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_PNG - if (stbi__png_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_GIF - if (stbi__gif_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_BMP - if (stbi__bmp_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_PSD - if (stbi__psd_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_PIC - if (stbi__pic_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_PNM - if (stbi__pnm_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_HDR - if (stbi__hdr_info(s, x, y, comp)) return 1; - #endif - - // test tga last because it's a crappy test! - #ifndef STBI_NO_TGA - if (stbi__tga_info(s, x, y, comp)) - return 1; - #endif - return stbi__err("unknown image type", "Image not of any known type, or corrupt"); -} - -static int stbi__is_16_main(stbi__context *s) -{ - #ifndef STBI_NO_PNG - if (stbi__png_is16(s)) return 1; - #endif - - #ifndef STBI_NO_PSD - if (stbi__psd_is16(s)) return 1; - #endif - - #ifndef STBI_NO_PNM - if (stbi__pnm_is16(s)) return 1; - #endif - return 0; -} - -#ifndef STBI_NO_STDIO -STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) -{ - FILE *f = stbi__fopen(filename, "rb"); - int result; - if (!f) return stbi__err("can't fopen", "Unable to open file"); - result = stbi_info_from_file(f, x, y, comp); - fclose(f); - return result; -} - -STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) -{ - int r; - stbi__context s; - long pos = ftell(f); - stbi__start_file(&s, f); - r = stbi__info_main(&s,x,y,comp); - fseek(f,pos,SEEK_SET); - return r; -} - -STBIDEF int stbi_is_16_bit(char const *filename) -{ - FILE *f = stbi__fopen(filename, "rb"); - int result; - if (!f) return stbi__err("can't fopen", "Unable to open file"); - result = stbi_is_16_bit_from_file(f); - fclose(f); - return result; -} - -STBIDEF int stbi_is_16_bit_from_file(FILE *f) -{ - int r; - stbi__context s; - long pos = ftell(f); - stbi__start_file(&s, f); - r = stbi__is_16_main(&s); - fseek(f,pos,SEEK_SET); - return r; -} -#endif // !STBI_NO_STDIO - -STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) -{ - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__info_main(&s,x,y,comp); -} - -STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); - return stbi__info_main(&s,x,y,comp); -} - -STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len) -{ - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__is_16_main(&s); -} - -STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); - return stbi__is_16_main(&s); -} - -#endif // STB_IMAGE_IMPLEMENTATION - -/* - revision history: - 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs - 2.19 (2018-02-11) fix warning - 2.18 (2018-01-30) fix warnings - 2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug - 1-bit BMP - *_is_16_bit api - avoid warnings - 2.16 (2017-07-23) all functions have 16-bit variants; - STBI_NO_STDIO works again; - compilation fixes; - fix rounding in unpremultiply; - optimize vertical flip; - disable raw_len validation; - documentation fixes - 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode; - warning fixes; disable run-time SSE detection on gcc; - uniform handling of optional "return" values; - thread-safe initialization of zlib tables - 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs - 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now - 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes - 2.11 (2016-04-02) allocate large structures on the stack - remove white matting for transparent PSD - fix reported channel count for PNG & BMP - re-enable SSE2 in non-gcc 64-bit - support RGB-formatted JPEG - read 16-bit PNGs (only as 8-bit) - 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED - 2.09 (2016-01-16) allow comments in PNM files - 16-bit-per-pixel TGA (not bit-per-component) - info() for TGA could break due to .hdr handling - info() for BMP to shares code instead of sloppy parse - can use STBI_REALLOC_SIZED if allocator doesn't support realloc - code cleanup - 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA - 2.07 (2015-09-13) fix compiler warnings - partial animated GIF support - limited 16-bpc PSD support - #ifdef unused functions - bug with < 92 byte PIC,PNM,HDR,TGA - 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value - 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning - 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit - 2.03 (2015-04-12) extra corruption checking (mmozeiko) - stbi_set_flip_vertically_on_load (nguillemot) - fix NEON support; fix mingw support - 2.02 (2015-01-19) fix incorrect assert, fix warning - 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 - 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG - 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) - progressive JPEG (stb) - PGM/PPM support (Ken Miller) - STBI_MALLOC,STBI_REALLOC,STBI_FREE - GIF bugfix -- seemingly never worked - STBI_NO_*, STBI_ONLY_* - 1.48 (2014-12-14) fix incorrectly-named assert() - 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) - optimize PNG (ryg) - fix bug in interlaced PNG with user-specified channel count (stb) - 1.46 (2014-08-26) - fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG - 1.45 (2014-08-16) - fix MSVC-ARM internal compiler error by wrapping malloc - 1.44 (2014-08-07) - various warning fixes from Ronny Chevalier - 1.43 (2014-07-15) - fix MSVC-only compiler problem in code changed in 1.42 - 1.42 (2014-07-09) - don't define _CRT_SECURE_NO_WARNINGS (affects user code) - fixes to stbi__cleanup_jpeg path - added STBI_ASSERT to avoid requiring assert.h - 1.41 (2014-06-25) - fix search&replace from 1.36 that messed up comments/error messages - 1.40 (2014-06-22) - fix gcc struct-initialization warning - 1.39 (2014-06-15) - fix to TGA optimization when req_comp != number of components in TGA; - fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) - add support for BMP version 5 (more ignored fields) - 1.38 (2014-06-06) - suppress MSVC warnings on integer casts truncating values - fix accidental rename of 'skip' field of I/O - 1.37 (2014-06-04) - remove duplicate typedef - 1.36 (2014-06-03) - convert to header file single-file library - if de-iphone isn't set, load iphone images color-swapped instead of returning NULL - 1.35 (2014-05-27) - various warnings - fix broken STBI_SIMD path - fix bug where stbi_load_from_file no longer left file pointer in correct place - fix broken non-easy path for 32-bit BMP (possibly never used) - TGA optimization by Arseny Kapoulkine - 1.34 (unknown) - use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case - 1.33 (2011-07-14) - make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements - 1.32 (2011-07-13) - support for "info" function for all supported filetypes (SpartanJ) - 1.31 (2011-06-20) - a few more leak fixes, bug in PNG handling (SpartanJ) - 1.30 (2011-06-11) - added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) - removed deprecated format-specific test/load functions - removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway - error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) - fix inefficiency in decoding 32-bit BMP (David Woo) - 1.29 (2010-08-16) - various warning fixes from Aurelien Pocheville - 1.28 (2010-08-01) - fix bug in GIF palette transparency (SpartanJ) - 1.27 (2010-08-01) - cast-to-stbi_uc to fix warnings - 1.26 (2010-07-24) - fix bug in file buffering for PNG reported by SpartanJ - 1.25 (2010-07-17) - refix trans_data warning (Won Chun) - 1.24 (2010-07-12) - perf improvements reading from files on platforms with lock-heavy fgetc() - minor perf improvements for jpeg - deprecated type-specific functions so we'll get feedback if they're needed - attempt to fix trans_data warning (Won Chun) - 1.23 fixed bug in iPhone support - 1.22 (2010-07-10) - removed image *writing* support - stbi_info support from Jetro Lauha - GIF support from Jean-Marc Lienher - iPhone PNG-extensions from James Brown - warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) - 1.21 fix use of 'stbi_uc' in header (reported by jon blow) - 1.20 added support for Softimage PIC, by Tom Seddon - 1.19 bug in interlaced PNG corruption check (found by ryg) - 1.18 (2008-08-02) - fix a threading bug (local mutable static) - 1.17 support interlaced PNG - 1.16 major bugfix - stbi__convert_format converted one too many pixels - 1.15 initialize some fields for thread safety - 1.14 fix threadsafe conversion bug - header-file-only version (#define STBI_HEADER_FILE_ONLY before including) - 1.13 threadsafe - 1.12 const qualifiers in the API - 1.11 Support installable IDCT, colorspace conversion routines - 1.10 Fixes for 64-bit (don't use "unsigned long") - optimized upsampling by Fabian "ryg" Giesen - 1.09 Fix format-conversion for PSD code (bad global variables!) - 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz - 1.07 attempt to fix C++ warning/errors again - 1.06 attempt to fix C++ warning/errors again - 1.05 fix TGA loading to return correct *comp and use good luminance calc - 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free - 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR - 1.02 support for (subset of) HDR files, float interface for preferred access to them - 1.01 fix bug: possible bug in handling right-side up bmps... not sure - fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all - 1.00 interface to zlib that skips zlib header - 0.99 correct handling of alpha in palette - 0.98 TGA loader by lonesock; dynamically add loaders (untested) - 0.97 jpeg errors on too large a file; also catch another malloc failure - 0.96 fix detection of invalid v value - particleman@mollyrocket forum - 0.95 during header scan, seek to markers in case of padding - 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same - 0.93 handle jpegtran output; verbose errors - 0.92 read 4,8,16,24,32-bit BMP files of several formats - 0.91 output 24-bit Windows 3.0 BMP files - 0.90 fix a few more warnings; bump version number to approach 1.0 - 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd - 0.60 fix compiling as c++ - 0.59 fix warnings: merge Dave Moore's -Wall fixes - 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian - 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available - 0.56 fix bug: zlib uncompressed mode len vs. nlen - 0.55 fix bug: restart_interval not initialized to 0 - 0.54 allow NULL for 'int *comp' - 0.53 fix bug in png 3->4; speedup png decoding - 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments - 0.51 obey req_comp requests, 1-component jpegs return as 1-component, - on 'test' only check type, not whether we support this variant - 0.50 (2006-11-19) - first released version -*/ - - -/* ------------------------------------------------------------------------------- -This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------- -ALTERNATIVE A - MIT License -Copyright (c) 2017 Sean Barrett -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. ------------------------------------------------------------------------------- -ALTERNATIVE B - Public Domain (www.unlicense.org) -This is free and unencumbered software released into the public domain. -Anyone is free to copy, modify, publish, use, compile, sell, or distribute this -software, either in source code form or as a compiled binary, for any purpose, -commercial or non-commercial, and by any means. -In jurisdictions that recognize copyright laws, the author or authors of this -software dedicate any and all copyright interest in the software to the public -domain. We make this dedication for the benefit of the public at large and to -the detriment of our heirs and successors. We intend this dedication to be an -overt act of relinquishment in perpetuity of all present and future rights to -this software under copyright law. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------- -*/ diff --git a/tools/pkg/2/init/src/main.cpp b/tools/pkg/2/init/src/main.cpp deleted file mode 100644 index f79da6d..0000000 --- a/tools/pkg/2/init/src/main.cpp +++ /dev/null @@ -1,501 +0,0 @@ - -#define _POSIX_C_SOURCE 200809L -#define _XOPEN_SOURCE 700 -#include <linux/fb.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <linux/fb.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <unistd.h> -#include <string.h> -#include <stdint.h> -#include <termios.h> -#include <signal.h> -#include <fcntl.h> - -#include <orange/dev.h> -#include <orange/io.h> - -#include <flanterm.h> -#include <flanterm_backends/fb.h> - -#include <font.hpp> - -#include <etc.hpp> - -#include <sys/wait.h> - -int ends_with(const char *str, const char *suffix) { - if (!str || !suffix) - return 0; - size_t lenstr = strlen(str); - size_t lensuffix = strlen(suffix); - if (lensuffix > lenstr) - return 0; - return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0; -} - -void start_all_drivers() { - DIR *dir; - struct dirent *entry; - - dir = opendir(DIR_PATH); - if (!dir) { - exit(0); - } - - while ((entry = readdir(dir)) != NULL) { - if (ends_with(entry->d_name, ".wsys")) { - char filepath[1024]; - snprintf(filepath, sizeof(filepath), "%s%s", DIR_PATH, entry->d_name); - - log(LEVEL_MESSAGE_OK,"Starting %s",entry->d_name); - - pid_t pid = fork(); - if (pid < 0) { - continue; - } else if (pid == 0) { - execl(filepath, filepath, (char *)NULL); - } - } else if(ends_with(entry->d_name,".sys")) { - char filepath[1024]; - snprintf(filepath, sizeof(filepath), "%s%s", DIR_PATH, entry->d_name); - - log(LEVEL_MESSAGE_OK,"Starting %s",entry->d_name); - - pid_t pid = fork(); - if (pid != 0) { - char success = 0; - while(!success) { - int r_pid = wait(NULL); - if(pid == r_pid) - success = 1; - } - } else if (pid == 0) { - execl(filepath, filepath, (char *)NULL); - } - } - } - - closedir(dir); -} - -char* keybuffer; -int key_ptr = 0; - -int is_printable(char c) { - return (c >= 32 && c <= 126) || c == 10; -} - -static void doKeyWork(uint8_t key,int master_fd) { - struct termios tty_termios; - tcgetattr(0,&tty_termios); - - if(key == SHIFT_PRESSED) { - is_shift_pressed = 1; - return; - } else if(key == SHIFT_RELEASED) { - is_shift_pressed = 0; - return; - } - - if(key == CTRL_PRESSED) { - is_ctrl_pressed = 1; - return; - } else if(key == CTRL_RELEASED) { - is_ctrl_pressed = 0; - return; - } - - if(!(key & (1 << 7))) { - char layout_key; - - if(!is_shift_pressed) - layout_key = en_layout_translation[key]; - else - layout_key = en_layout_translation_shift[key]; - - if(is_ctrl_pressed) - layout_key = en_layout_translation[key] - ASCII_CTRL_OFFSET; - - write(master_fd,&layout_key,1); - - // if((tty_termios.c_lflag & ECHO) && is_printable(layout_key)) - // write(STDOUT_FILENO,&layout_key,1); - - // if((tty_termios.c_lflag & ICANON) && (is_printable(layout_key) || layout_key == '\b') && layout_key != 0) { - - // if(layout_key != '\b') { - // keybuffer[key_ptr++] = layout_key; - // if(layout_key == '\n') { - // write(master_fd,keybuffer,key_ptr); - // key_ptr = 0; - // } - // } else { - // if(key_ptr) { - // write(STDOUT_FILENO,"\b \b",sizeof("\b \b")); - - // keybuffer[key_ptr--] = '\0'; - // } - // } - // } else { - - // if(layout_key == '\n') - // layout_key = 13; - - // keybuffer[key_ptr++] = layout_key; - - // if(key_ptr >= tty_termios.c_cc[VMIN]) { - // write(master_fd,keybuffer,key_ptr); - // key_ptr = 0; - // } - // } - } -} - -int master_fd = 0; -int slave_fd = 0; -struct flanterm_context* ft_ctx; - -void* ptr; // fbdev target - -static int set_fd_nonblock(int fd, int nonblock) { - int flags = fcntl(fd, F_GETFL, 0); - if (flags == -1) { - perror("fcntl F_GETFL"); - return -1; - } - - if (nonblock) { - flags |= O_NONBLOCK; - } else { - flags &= ~O_NONBLOCK; - } - - if (fcntl(fd, F_SETFL, flags) == -1) { - perror("fcntl F_SETFL"); - return -1; - } - - return 0; -} - -void* tty_work(void* arg) { - - dup2(slave_fd,STDOUT_FILENO); - dup2(slave_fd,STDIN_FILENO); - dup2(slave_fd,STDERR_FILENO); - - struct winsize buf; - - size_t cols = 0; - size_t rows = 0; - flanterm_get_dimensions(ft_ctx,&cols,&rows); - buf.ws_col = cols; - buf.ws_row = rows; - - ioctl(STDIN_FILENO,TIOCSWINSZ,&buf); - struct termios t; - - t.c_lflag |= (ICANON | ECHO); - - t.c_iflag = IGNPAR | ICRNL; - t.c_oflag = OPOST; - t.c_cflag |= (CS8); - - ioctl(STDIN_FILENO, TCSETS, &t); - - int master_input = open("/dev/masterps2keyboard0", O_RDWR); - int slave_input = open("/dev/ps2keyboard0", O_RDWR); - keybuffer = (char*)malloc(1024); - - struct pollfd pfd[2]; - pfd[0].fd = slave_input; - pfd[0].events = POLLIN; - pfd[1].fd = master_fd; - pfd[1].events = POLLIN; - - // flush - char zbuffer[1024*128]; - memset(zbuffer,0,1024*128); - - set_fd_nonblock(master_fd,1); - read(master_fd,zbuffer,1024 * 128); - set_fd_nonblock(master_fd,0); - - while(1) { - int ret = poll(pfd, 2, -1); - if(ret > 0) { - if(pfd[0].revents & POLLIN) { - char buffer[32]; - memset(buffer, 0, 32); - int count = read(slave_input, buffer, 32); - if(count > 0) { - for(int i = 0; i < count; i++) { - doKeyWork(buffer[i], master_fd); - } - } - } - - if(pfd[1].revents & POLLIN) { - char buffer[1024*128]; - memset(buffer,0,1024*128); - int count = read(master_fd,buffer,1024*128); - if(count) flanterm_write(ft_ctx,buffer,count); - } - } - - } - -} - - -static void tty_init() { - struct fb_var_screeninfo vinfo; - struct fb_fix_screeninfo finfo; - int fb0_dev = open("/dev/fb0", O_RDWR); - ioctl(fb0_dev, FBIOGET_VSCREENINFO, &vinfo); - ioctl(fb0_dev, FBIOGET_FSCREENINFO, &finfo); - - void* address = mmap(0, vinfo.yres_virtual * vinfo.xres_virtual * vinfo.bits_per_pixel / 8, - PROT_READ | PROT_WRITE, MAP_SHARED, fb0_dev, 0); - - uint32_t* test_canvas = (uint32_t*)malloc(vinfo.yres_virtual * vinfo.xres_virtual * sizeof(uint32_t)); - if (!test_canvas) { - exit(1); - } - - int img_w, img_h, img_channels; - unsigned char* img_data = stbi_load("/etc/bg.jpg", &img_w, &img_h, &img_channels, 3); - if (!img_data) { - exit(2); - } - - unsigned char* scaled_rgb = (unsigned char*)malloc(vinfo.xres * vinfo.yres * 3); - if (!scaled_rgb) { - exit(3); - } - scale_image_nn(img_data, img_w, img_h, scaled_rgb, vinfo.xres, vinfo.yres, 3); - - for (int y = 0; y < vinfo.yres; y++) { - for (int x = 0; x < vinfo.xres; x++) { - int idx = (y * vinfo.xres + x) * 3; - uint8_t r = scaled_rgb[idx]; - uint8_t g = scaled_rgb[idx + 1]; - uint8_t b = scaled_rgb[idx + 2]; - test_canvas[y * vinfo.xres + x] = rgb_to_pixel(r, g, b, - vinfo.red.length, vinfo.red.offset, - vinfo.green.length, vinfo.green.offset, - vinfo.blue.length, vinfo.blue.offset); - } - } - - stbi_image_free(img_data); - free(scaled_rgb); - - int margin = 64; - - draw_transparent_black_square(test_canvas, vinfo.xres, vinfo.yres, - vinfo.red.length, vinfo.red.offset, - vinfo.green.length, vinfo.green.offset, - vinfo.blue.length, vinfo.blue.offset, - margin - 1); - - ft_ctx = flanterm_fb_init( - __flanterm_malloc, __flanterm_free, - (uint32_t*)address, vinfo.xres, vinfo.yres, - finfo.line_length, - vinfo.red.length, vinfo.red.offset, - vinfo.green.length, vinfo.green.offset, - vinfo.blue.length, vinfo.blue.offset, - test_canvas, - NULL, NULL, - NULL, &default_fg, - NULL, &default_fg_bright, - (void*)unifont_arr, FONT_WIDTH, FONT_HEIGHT, 0, - 1, 1, margin,0 - ); - master_fd = posix_openpt(O_RDWR | O_NOCTTY); - master_fd = posix_openpt(O_RDWR | O_NOCTTY); - master_fd = posix_openpt(O_RDWR | O_NOCTTY); - grantpt(master_fd); - unlockpt(master_fd); - char* name = ptsname(master_fd); - - slave_fd = open(name,O_RDWR); - - dup2(slave_fd,STDOUT_FILENO); - dup2(slave_fd,STDIN_FILENO); - dup2(slave_fd,STDERR_FILENO); - - struct winsize buf; - - size_t cols = 0; - size_t rows = 0; - flanterm_get_dimensions(ft_ctx,&cols,&rows); - buf.ws_col = cols; - buf.ws_row = rows; - - ioctl(STDIN_FILENO,TIOCSWINSZ,&buf); - struct termios t; - - t.c_lflag |= (ICANON | ECHO); - - t.c_iflag = IGNPAR | ICRNL; - t.c_oflag = OPOST; - t.c_cflag |= (CS8); - - ioctl(STDIN_FILENO, TCSETS, &t); - - int master_input = open("/dev/masterps2keyboard0", O_RDWR); - int slave_input = open("/dev/ps2keyboard0", O_RDWR); - keybuffer = (char*)malloc(1024); - pthread_t pth; - pthread_create(&pth,NULL,tty_work,0); - -} - -static inline void rep_movsb(void* dest, const void* src, size_t count) { - asm volatile( - "mov %0, %%rdi\n\t" - "mov %1, %%rsi\n\t" - "mov %2, %%rcx\n\t" - "rep movsb\n\t" - : - : "r"(dest), "r"(src), "r"(count) - : "%rdi", "%rsi", "%rcx", "memory"); -} - -inline void __cpuid(int code, int code2, uint32_t *a, uint32_t *b, uint32_t *c , uint32_t *d) { - __asm__ volatile("cpuid":"=a"(*a),"=b"(*b),"=c"(*c),"=d"(*d):"a"(code),"c"(code2)); -} - -int is_running_on_real_hw() { - int regs[4]; - - __asm__ volatile ( - "cpuid" - : "=a"(regs[0]), "=b"(regs[1]), "=c"(regs[2]), "=d"(regs[3]) - : "a"(0) - ); - - char vendor_id[13]; - *(uint32_t*)(vendor_id + 0) = regs[1]; - *(uint32_t*)(vendor_id + 4) = regs[3]; - *(uint32_t*)(vendor_id + 8) = regs[2]; - vendor_id[12] = '\0'; - - int is_vendor_virt = strncmp(vendor_id, "AuthenticAMD", 12) == 0 || - strncmp(vendor_id, "GenuineIntel", 12) == 0; - - if(is_vendor_virt) { - uint32_t a,b,c,d = 0; - __cpuid(0x40000000,0,&a,&b,&c,&d); - if(b != 0x4b4d564b || d != 0x4d || c != 0x564b4d56) - return 1; - - __cpuid(0x40000001,0,&a,&b,&c,&d); - if(!(a & (1 << 3))) - return 1; - is_vendor_virt = 0; - } - return is_vendor_virt; - -} - -void get_cpu(char* out) { - int regs[4]; - - __asm__ volatile ( - "cpuid" - : "=a"(regs[0]), "=b"(regs[1]), "=c"(regs[2]), "=d"(regs[3]) - : "a"(0) - ); - - char vendor_id[13]; - *(uint32_t*)(vendor_id + 0) = regs[1]; - *(uint32_t*)(vendor_id + 4) = regs[3]; - *(uint32_t*)(vendor_id + 8) = regs[2]; - vendor_id[12] = '\0'; - memcpy(out,vendor_id,13); -} - -void* refresh(void * arg) { - struct limine_framebuffer fb; - - void* real_fb = liborange_map_phys(fb.address, PTE_WC, fb.pitch * fb.height); - - while(1) { - memcpy(real_fb,ptr,fb.pitch * fb.height); - } -} - -void init_fbdev() { - return; - struct limine_framebuffer fb; - liborange_access_framebuffer(&fb); - liborange_create_dev(((uint64_t)DEVFS_PACKET_CREATE_PIPE_DEV << 32) | 0, "/fb", "/masterfb"); - - uint64_t doublebuffer_dma = liborange_alloc_dma(fb.pitch * fb.height); - void* mapped_dma = liborange_map_phys(doublebuffer_dma,0,fb.pitch * fb.height); - - ptr = mapped_dma; - - liborange_setup_mmap("/fb0",fb.address,fb.pitch * fb.height,PTE_WC); - struct fb_var_screeninfo vinfo; - struct fb_fix_screeninfo finfo; - liborange_setup_ioctl("/fb0",sizeof(struct fb_var_screeninfo),FBIOGET_VSCREENINFO,0x1); - liborange_setup_ioctl("/fb0",sizeof(struct fb_fix_screeninfo),FBIOGET_FSCREENINFO,0x2); - int fb0_dev = open("/dev/fb0",O_RDWR); - vinfo.red.length = fb.red_mask_size; - vinfo.red.offset = fb.red_mask_shift; - vinfo.blue.offset = fb.blue_mask_shift; - vinfo.blue.length = fb.blue_mask_size; - vinfo.green.length = fb.green_mask_size; - vinfo.green.offset = fb.green_mask_shift; - vinfo.xres = fb.width; - vinfo.yres = fb.height; - vinfo.bits_per_pixel = fb.bpp < 5 ? (fb.bpp * 8) : fb.bpp; - vinfo.xres_virtual = fb.width; - vinfo.yres_virtual = fb.height; - vinfo.red.msb_right = 1; - vinfo.green.msb_right = 1; - vinfo.blue.msb_right = 1; - vinfo.transp.msb_right = 1; - vinfo.height = -1; - vinfo.width = -1; - finfo.line_length = fb.pitch; - finfo.smem_len = fb.pitch * fb.height; - finfo.visual = FB_VISUAL_TRUECOLOR; - finfo.type = FB_TYPE_PACKED_PIXELS; - finfo.mmio_len = fb.pitch * fb.height; - - ioctl(fb0_dev,0x1,&vinfo); - ioctl(fb0_dev,0x2,&finfo); - close(fb0_dev); -} - -int main() { - tty_init(); - - char cpu[13]; - get_cpu(cpu); - - //log(LEVEL_MESSAGE_OK,"Trying to start drivers"); - //start_all_drivers(); - //log(LEVEL_MESSAGE_OK,"Initialization done"); - //printf("\n"); - putenv("TERM=linux"); - putenv("SHELL=/bin/bash"); - putenv("PATH=/usr/bin"); - int pid = fork(); - if(pid == 0) { - execl("/bin/bash", "/bin/bash", (char *)NULL); - } else { - while(1) { - - } - } -}
\ No newline at end of file diff --git a/tools/pkg/2/ncurses/diff/ncurses.diff b/tools/pkg/2/ncurses/diff/ncurses.diff deleted file mode 100644 index 0206e64..0000000 --- a/tools/pkg/2/ncurses/diff/ncurses.diff +++ /dev/null @@ -1,26 +0,0 @@ -diff -Naur ncurses-6.5/config.sub ncurses-patched/config.sub ---- ncurses-6.5/config.sub 2023-12-27 17:41:27.000000000 +0300 -+++ ncurses-patched/config.sub 2025-06-02 08:30:55.408408771 +0300 -@@ -1764,7 +1764,7 @@ - | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ - | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ - | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ -- | skyos* | haiku* | rdos* | toppers* | drops* | es* \ -+ | skyos* | orange* | haiku* | rdos* | toppers* | drops* | es* \ - | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ - | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ - | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ -diff -Naur ncurses-6.5/configure ncurses-patched/configure ---- ncurses-6.5/configure 2024-04-10 11:09:48.000000000 +0300 -+++ ncurses-patched/configure 2025-06-02 09:00:16.635459472 +0300 -@@ -6925,6 +6925,10 @@ - LINK_PROGS="$SHELL ${rel_builddir}/mk_prog.sh" - LINK_TESTS="$SHELL ${rel_builddir}/mk_prog.sh" - ;; -+ (orange*) -+ CC_SHARED_OPTS='-fPIC' -+ MK_SHARED_LIB='${CC} -shared -o $@' -+ ;; - (mingw*) - cf_cv_shlib_version=mingw - cf_cv_shlib_version_infix=mingw
\ No newline at end of file diff --git a/tools/pkg/2/ncurses/info.txt b/tools/pkg/2/ncurses/info.txt deleted file mode 100644 index ebb49ce..0000000 --- a/tools/pkg/2/ncurses/info.txt +++ /dev/null @@ -1 +0,0 @@ -ncurses
\ No newline at end of file diff --git a/tools/pkg/2/ncurses/pkg.sh b/tools/pkg/2/ncurses/pkg.sh deleted file mode 100644 index baf29b8..0000000 --- a/tools/pkg/2/ncurses/pkg.sh +++ /dev/null @@ -1,29 +0,0 @@ -. ../../pkg-lib.sh - -mkdir -p cached - -rm -rf pack - -mkdir -p pack - -cd pack - -installgnu ncurses ncurses 6.5 -mkdir -p ncurses-build - -cd ncurses-build -../ncurses-6.5/configure --host=x86_64-linux-gnu --prefix="/usr" --with-shared --without-ada CFLAGS="-std=gnu17 -Wno-implicit-function-declaration" -make -j$(nproc) -make install -j$(nproc) DESTDIR="$1" - -cd .. - -cz=$(pwd) - -cd "$1/usr/lib" -ln -sf libncursesw.so libcurses.so -ln -sf libncursesw.so libcursesw.so - -ln -sf libtinfow.so libtinfo.so - -cd "$cz" diff --git a/tools/pkg/2/ps2_driver/info.txt b/tools/pkg/2/ps2_driver/info.txt deleted file mode 100644 index 5e7818e..0000000 --- a/tools/pkg/2/ps2_driver/info.txt +++ /dev/null @@ -1 +0,0 @@ -ps2 driver
\ No newline at end of file diff --git a/tools/pkg/2/ps2_driver/src/main.c b/tools/pkg/2/ps2_driver/src/main.c deleted file mode 100644 index 4b848df..0000000 --- a/tools/pkg/2/ps2_driver/src/main.c +++ /dev/null @@ -1,278 +0,0 @@ - -#include <orange/dev.h> -#include <orange/io.h> -#include <orange/log.h> - -#include <stdio.h> -#include <fcntl.h> -#include <poll.h> - -#include <stdlib.h> - -#include <stdint.h> - -#include <sched.h> - -#include <string.h> - -#include <unistd.h> - -#define STATUS 0x64 -#define COMMAND 0x64 -#define DATA 0x60 -#define RESEND 0xFE -#define ACK 0xFA -#define ECHO 0xEE - -static inline char ps2_isfull() { - return (inb(0x64) & 2) == 2; -} - -static inline char ps2_wait() { - return (inb(0x64) & 1) == 0; -} - -void ps2_writecmd(uint8_t cmd) { - while(ps2_isfull()); - outb(0x64,cmd); -} - -void ps2_writedata(uint8_t cmd) { - while(ps2_isfull()); - outb(0x60,cmd); -} - -void ps2_flush() { - int timeout = 1000; - while((inb(STATUS) & 1) && --timeout > 0) inb(DATA); -} - -uint8_t ps2_read() { - while(ps2_wait()); - return inb(0x60); -} - -uint8_t ps2_readtimeout() { - int timeout = 100; - while(ps2_wait() && --timeout > 0) usleep(100); - if(timeout <= 0) - return 0; - return inb(0x60); -} - -uint8_t ps2_readlongtimeout() { - int timeout = 100; - while(ps2_wait() && --timeout > 0) usleep(1000); - if(timeout <= 0) - return 0; - return inb(0x60); -} - - - -void ps2_writeport(uint8_t port, uint8_t cmd) { - if(port == 2) - ps2_writecmd(0xD4); - - ps2_writedata(cmd); -} - -int dual_channel = 0; - -void ps2_disableport(uint8_t port) { - ps2_writeport(port,0xF5); - int retry = 0; - while(1) { - uint8_t response = ps2_readtimeout(); - if(!response) - break; - else if(response == RESEND) { - if(++retry == 10) - break; - ps2_writeport(port,0xF5); - } - } - ps2_flush(); -} - -void ps2_enableport(uint8_t port) { - ps2_writeport(port,0xF4); - int retry = 0; - while(1) { - uint8_t response = ps2_readtimeout(); - if(!response) - break; - else if(response == ACK) - break; - else if(response == RESEND) { - if(++retry == 10) - break; - ps2_writeport(port,0xF4); - } - } - ps2_flush(); -} - -char ps2_selftest(uint8_t port) { - ps2_disableport(port); - ps2_writeport(port,0xFF); - int retry = 0; - while(1) { - uint8_t response = ps2_readtimeout(); - if(!response) - break; - else if(response == RESEND) { - if(++retry == 10) - break; - ps2_writeport(port,0xFF); - } else if(response == ACK) - break; - } - - while(1) { - uint8_t response = ps2_readlongtimeout(); - if(!response) - break; - else if(response == 0xAA) - break; - else if(response == 0xFC) { - log(LEVEL_MESSAGE_FAIL,"Failed to test PS/2 port %d\n",port); - return 0; - } - } - - // used from astral src - while(1) { - if(!ps2_readtimeout()) - break; - } - - ps2_flush(); - return 1; -} - -#define MOUSE_LB (1 << 0) -#define MOUSE_RB (1 << 1) -#define MOUSE_MB (1 << 2) -#define MOUSE_B4 (1 << 3) -#define MOUSE_B5 (1 << 4) - -typedef struct { - unsigned char buttons; - unsigned char x; - unsigned char y; - unsigned char z; -} __attribute__((packed)) mouse_packet_t; - -int main() { - - int pid = fork(); - - if(pid > 0) - exit(0); - - int masterinput = open("/dev/masterps2keyboard",O_RDWR); - int mastermouse = open("/dev/mastermouse",O_RDWR); - - if(mastermouse < 0) { - perror("Can't open /dev/mastermouse device"); - exit(-1); - } - - if(masterinput < 0) { - perror("Can't open /dev/masterkeyboard device"); - exit(-1); - } - - liborange_setup_iopl_3(); - - int pic = open("/dev/pic",O_RDWR); - - if(pic < 0) { - perror("Can't open /dev/pic device"); - exit(-1); - } - - ps2_writecmd(0xAD); - ps2_writecmd(0xA7); - - ps2_writecmd(0x20); - uint8_t config = ps2_read(); - config |= (1 << 0) | (1 << 1) | (1 << 6); - ps2_writecmd(0x60); - ps2_writedata(config); - - ps2_enableport(1); - ps2_enableport(2); - - // dont need identify just know what port 1 is kbd port 2 is mouse - - liborange_pic_create_t irq_create_request; - irq_create_request.flags = 0; - - ps2_writecmd(0xAE); - - irq_create_request.irq = 1; - write(pic,&irq_create_request,sizeof(liborange_pic_create_t)); - - ps2_writecmd(0xA8); - - irq_create_request.irq = 12; - write(pic,&irq_create_request,sizeof(liborange_pic_create_t)); - - ps2_flush(); - - int mouse_seq = 0; - - if(1) { - - uint8_t mouse_buffer[4] = {0,0,0,0}; - - while(1) { - - if(1) { - - int val = 1; - - uint8_t status = inb(0x64); - while(status & 1) { - int data = inb(DATA); - - if(status & (1 << 5)) { - mouse_buffer[mouse_seq++] = data; - - if(mouse_seq == 3) { - mouse_packet_t packet = {0,0,0,0}; - - packet.x = mouse_buffer[1] - (mouse_buffer[0] & 0x10 ? 0x100 : 0); - packet.y = mouse_buffer[2] - (mouse_buffer[0] & 0x20 ? 0x100 : 0); - packet.z = (mouse_buffer[3] & 0x7) * (mouse_buffer[3] & 0x8 ? -1 : 1); - - packet.buttons |= (mouse_buffer[0] & 1) ? MOUSE_LB : 0; - packet.buttons |= (mouse_buffer[0] & 2) ? MOUSE_RB : 0; - packet.buttons |= (mouse_buffer[0] & 4) ? MOUSE_MB : 0; - - packet.buttons |= (mouse_buffer[0] & 0x10) ? MOUSE_B4 : 0; - packet.buttons |= (mouse_buffer[0] & 0x20) ? MOUSE_B5 : 0; - - write(mastermouse,&packet,4); - - mouse_seq = 0; - - } - - - - } else { - write(masterinput,&data,1); - } - - status = inb(0x64); - } - sched_yield(); - } - } - } - exit(0); - -}
\ No newline at end of file diff --git a/tools/pkg/2/xhci_driver/include/xhci.hpp b/tools/pkg/2/xhci_driver/include/xhci.hpp deleted file mode 100644 index da858b5..0000000 --- a/tools/pkg/2/xhci_driver/include/xhci.hpp +++ /dev/null @@ -1,689 +0,0 @@ -#include <stdint.h> - -#pragma once - -#define XHCI_RESET_TIMEOUT 1000 - -typedef struct { - uint32_t maxslots : 8; - uint32_t maxintrs : 11; - uint32_t reserved1 : 5; - uint32_t maxports : 8; -} __attribute__((packed)) hcsparams1_t; - -typedef struct { - uint32_t ist : 4; - uint32_t erstmax : 4; - uint32_t reserved1 : 13; - uint32_t max_scratchpad_hi : 5; - uint32_t spr : 1; - uint32_t max_scratchpad_lo : 5; -} __attribute__((packed)) hcsparams2_t; - -typedef struct { - uint32_t _64bitcap : 1; - uint32_t bnc : 1; - uint32_t contextsize : 1; - uint32_t portpowercontrol : 1; - uint32_t portindicator : 1; - uint32_t lhrc : 1; - uint32_t ltc : 1; - uint32_t nss : 1; - uint32_t pae : 1; - uint32_t spc : 1; - uint32_t sec : 1; - uint32_t cfc : 1; - uint32_t max_psa_size : 4; - uint32_t xECP : 16; -} __attribute__((packed)) hccparams1_t; - -typedef struct { - uint8_t caplength; - uint8_t reserved; - uint16_t hciversion; - hcsparams1_t hcsparams1; - hcsparams2_t hcsparams2; - uint32_t hcsparams3; - hccparams1_t hccparams1; - uint32_t dboff; - uint32_t rtsoff; - uint32_t hccparms2; -} xhci_cap_regs_t; - -typedef struct { - uint32_t usbcmd; - uint32_t usbsts; - uint32_t pagesize; - uint32_t reserved1[2]; - uint32_t dnctrl; - uint64_t crcr; - uint32_t reserved2[4]; - uint64_t dcbaap; - uint32_t config; -} xhci_op_regs_t; - -#define XHCI_USBCMD_RS (1 << 0) -#define XHCI_USBCMD_HOSTCONTROLLERREST (1 << 1) -#define XHCI_USB_SPEED_FULL_SPEED 1 -#define XHCI_USB_SPEED_LOW_SPEED 2 -#define XHCI_USB_SPEED_HIGH_SPEED 3 -#define XHCI_USB_SPEED_SUPER_SPEED 4 -#define XHCI_USB_SPEED_SUPER_SPEED_PLUS 5 - -typedef struct { - uint32_t portsc; - uint32_t portpmsc; - uint32_t portli; -} xhci_port_regs_t; - -typedef struct { - uint64_t erst_segment : 3; - uint64_t event_busy : 1; - uint64_t event_ring_pointer : 60; -} xhci_erdp_t; - -typedef struct { - uint32_t iman; - uint32_t imod; - uint32_t erstsz; - uint32_t reserved0; - uint64_t erstba; - union { - xhci_erdp_t erdp; - uint64_t erdp_val; - }; -} IR_t; - -typedef struct { - uint32_t mfindex; - uint32_t reserved1[7]; - IR_t int_regs[1024]; -} xhci_runtime_regs_t; - -typedef struct { - uint64_t base; - uint32_t size; - uint32_t reserved0; -} xhci_erst_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t nexttrb : 1; - uint32_t interruptonshort : 1; - uint32_t nosnoop : 1; - uint32_t chain : 1; - uint32_t intoncompletion : 1; - uint32_t immediate : 1; - uint32_t reserved1 : 2; - uint32_t blockeventint : 1; - uint32_t type : 6; - uint32_t reserved2 : 16; -} xhci_trb_info_t; - -typedef struct { - uint64_t base; - union { - struct { - uint32_t reserved0 : 24; - uint32_t ret_code : 8; - }; - uint32_t status; - }; - union { - xhci_trb_info_t info_s; - uint32_t info; - }; -} xhci_trb_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t reserved1 : 9; - uint32_t type : 6; - uint32_t vfid : 8; - uint32_t slotid : 8; -} xhci_slot_info_trb_t; - -typedef struct { - uint64_t base; - uint32_t CCP : 24; - uint32_t ret_code : 8; - union { - xhci_slot_info_trb_t info_s; - uint32_t info; - }; -} xhci_slot_trb_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t reserved0 : 8; - uint32_t bsr : 1; - uint32_t type : 6; - uint8_t reserved1; - uint8_t slotid; -} xhci_set_addr_info_trb_t; - -typedef struct { - uint64_t base; - uint32_t status; - union { - xhci_set_addr_info_trb_t info_s; - uint32_t info; - }; -} xhci_set_addr_trb_t; - -typedef struct { - uint8_t cycle; - uint16_t trb_limit; - uint64_t queue; - uint64_t phys; - xhci_trb_t* trb; -} xhci_command_ring_ctx_t; - -typedef struct { - uint16_t trb_limit; - uint64_t queue; - uint8_t cycle; - volatile IR_t* father; - xhci_trb_t* trb; - xhci_erst_t* table; -} xhci_event_ring_ctx_t; - -typedef struct { - uint16_t trb_limit; - uint64_t queue; - uint8_t cycle; - uint32_t slot; - uint64_t phys; - xhci_trb_t* trb; -} xhci_port_ring_ctx_t; - -typedef struct { - uint32_t D; - uint32_t A; - uint32_t reserved0[5]; - uint8_t configvalue; - uint8_t interfacenum; - uint8_t altsetting; - uint8_t reserved1; -} __attribute__((packed)) xhci_input_control_ctx_t; - -typedef struct { - uint32_t D; - uint32_t A; - uint32_t reserved0[5]; - uint8_t configvalue; - uint8_t interfacenum; - uint8_t altsetting; - uint8_t reserved1; - uint32_t align[8]; -} __attribute__((packed)) xhci_input_control_ctx64_t; - -typedef struct { - uint32_t routestring : 20; - uint8_t speed : 4; - uint8_t reserved0 : 1; - uint8_t multitt : 1; - uint8_t hub : 1; - uint8_t contextentries : 5; - uint16_t maxexitlat; - uint8_t porthubnum; - uint8_t numofports; - uint8_t parenthubslot; - uint8_t parentportnum; - uint8_t thinktime : 2; - uint8_t reserved1 : 4; - uint16_t irtarget : 10; - uint8_t address; - uint32_t reserved2 : 19; - uint8_t slotstate : 5; - uint32_t reserved3[4]; -} __attribute__((packed)) xhci_slot_ctx_t; - -typedef struct { - uint32_t routestring : 20; - uint8_t speed : 4; - uint8_t reserved0 : 1; - uint8_t multitt : 1; - uint8_t hub : 1; - uint8_t contextentries : 5; - uint16_t maxexitlat; - uint8_t porthubnum; - uint8_t numofports; - uint8_t parenthubslot; - uint8_t parentportnum; - uint8_t thinktime : 2; - uint8_t reserved1 : 4; - uint16_t irtarget : 10; - uint8_t address; - uint32_t reserved2 : 19; - uint8_t slotstate : 5; - uint32_t reserved3[4]; - uint32_t align[8]; -} __attribute__((packed)) xhci_slot_ctx64_t; - -typedef struct { - uint32_t state : 3; - uint32_t reserved0 : 5; - uint32_t mult : 2; - uint32_t maxprimarystreams : 5; - uint32_t linear : 1; - uint32_t interval : 8; - uint32_t some_shit_with_long_name : 8; - uint32_t reserved1 : 1; - uint32_t cerr : 2; - uint32_t endpointtype : 3; - uint32_t reserved2 : 1; - uint32_t hid : 1; - uint32_t maxburstsize : 8; - uint32_t maxpacketsize : 16; - uint64_t base; - uint16_t averagetrblen; - uint16_t some_shit_with_long_name_lo; - uint32_t align[3]; -} __attribute__((packed)) xhci_endpoint_ctx_t; - -typedef struct { - uint32_t state : 3; - uint32_t reserved0 : 5; - uint32_t mult : 2; - uint32_t maxprimarystreams : 5; - uint32_t linear : 1; - uint32_t interval : 8; - uint32_t some_shit_with_long_name : 8; - uint32_t reserved1 : 1; - uint32_t cerr : 2; - uint32_t endpointtype : 3; - uint32_t reserved2 : 1; - uint32_t hid : 1; - uint32_t maxburstsize : 8; - uint32_t maxpacketsize : 16; - uint64_t base; - uint16_t averagetrblen; - uint16_t some_shit_with_long_name_lo; - uint32_t align[11]; -} __attribute__((packed)) xhci_endpoint_ctx64_t; - -typedef struct { - xhci_input_control_ctx_t input_ctx; - xhci_slot_ctx_t slot; - xhci_endpoint_ctx_t ep0; - xhci_endpoint_ctx_t ep[30]; -} __attribute__((packed)) xhci_input_ctx_t; - -typedef struct { - xhci_input_control_ctx64_t input_ctx; - xhci_slot_ctx64_t slot; - xhci_endpoint_ctx64_t ep0; - xhci_endpoint_ctx64_t ep[30]; -} __attribute__((packed)) xhci_input_ctx64_t; - -typedef struct { - uint8_t len; - uint8_t type; -} xhci_usb_descriptor_header; - -typedef struct { - xhci_usb_descriptor_header head; - uint16_t usb; - uint8_t deviceclass; - uint8_t devicesubclass; - uint8_t protocol; - uint8_t maxpacketsize; - uint16_t vendor; - uint16_t product0; - uint16_t device; - uint8_t manufacter; - uint8_t product1; - uint8_t serialnum; - uint8_t numconfigs; -} xhci_usb_descriptor_t; - -typedef struct { - xhci_usb_descriptor_header head; - uint16_t lang[128]; -} xhci_lang_descriptor_t; - -typedef struct { - xhci_usb_descriptor_header head; - uint16_t str[128]; -} xhci_string_descriptor_t; - -typedef struct { - xhci_usb_descriptor_header head; - uint16_t len; - uint8_t numinterfaces; - uint8_t configval; - uint8_t config; - uint8_t attributes; - uint8_t maxpower; - uint8_t data[1024]; -} xhci_config_descriptor_t; - -typedef struct { - uint8_t desctype; - uint8_t desclen; -} xhci_hid_sub_desc; - -typedef struct { - xhci_usb_descriptor_header head; - uint16_t hid; - uint8_t country; - uint8_t numdesc; - xhci_hid_sub_desc desc[1024]; -} xhci_hid_descriptor_t; - -typedef struct { - xhci_usb_descriptor_header head; - uint8_t endpointaddr; - uint8_t attributes; - uint16_t maxpacketsize; - uint8_t interval; -} xhci_endpoint_descriptor_t; - -typedef struct { - xhci_usb_descriptor_header head; - uint8_t num; - uint8_t altsetting; - uint8_t numendpoints; - uint8_t interclass; - uint8_t intersubclass; - uint8_t protocol; - uint8_t interface; -} xhci_interface_descriptor_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t reserved0 : 8; - uint32_t deconfigure : 1; - uint32_t type : 6; - uint32_t reserved1 : 8; - uint32_t slot : 8; -} xhci_configure_endpoints_info_trb_t; - -typedef struct { - uint64_t base; - uint32_t status; - union { - xhci_configure_endpoints_info_trb_t info_s; - uint32_t info; - }; -} xhci_configure_endpoints_trb_t; - -typedef struct xhci_device { - uint64_t xhci_phys_base; - uint64_t xhci_virt_base; - uint64_t* dcbaa; - uint16_t calculated_scratchpad_count; - volatile xhci_cap_regs_t* cap; - volatile xhci_op_regs_t* op; - volatile xhci_port_regs_t* port; - volatile xhci_runtime_regs_t* runtime; - uint32_t* doorbell; - xhci_command_ring_ctx_t* com_ring; - xhci_event_ring_ctx_t* event_ring; - - uint32_t max_ports; - - uint8_t usb3ports[64]; - - struct xhci_device* next; -} __attribute__((packed)) xhci_device_t; - -typedef struct xhci_interface { - uint8_t type; - void* data; - - uint64_t len; - void* buffer; - - xhci_interface* next; -} xhci_interface_t; - -#define USB_TYPE_KEYBOARD 4 -#define USB_TYPE_MOUSE 3 - -typedef struct xhci_usb_device { - xhci_port_ring_ctx_t* transfer_ring; - xhci_usb_descriptor_t* desc; - xhci_config_descriptor_t* config; - xhci_device_t* dev; - xhci_input_ctx_t* input_ctx; - xhci_port_ring_ctx_t* ep_ctx[30]; - uint64_t phys_buffers[30]; - uint8_t* buffers[30]; - uint8_t main_ep; - uint16_t buffers_need_size[30]; - uint8_t doorbell_values[30]; - xhci_interface_t* interface; - struct xhci_usb_device* next; - uint64_t phys_input_ctx; - uint32_t slotid; - uint32_t portnum; - uint32_t type; - uint8_t _is64byte; - uint8_t add_buffer[8]; -} xhci_usb_device_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t reserved0 : 1; - uint32_t eventdata : 1; - uint32_t reserved1 : 7; - uint32_t type : 6; - uint32_t ep_id : 5; - uint32_t reserved2 : 3; - uint32_t slot : 8; -} xhci_done_info_trb_t; - -typedef struct { - uint64_t base; - struct { - uint32_t seek : 24; - uint32_t ret_code : 8; - }; - union { - xhci_done_info_trb_t info_s; - uint32_t info; - }; -} xhci_done_trb_t; - -typedef struct { - union { - struct { - uint8_t id; - uint8_t nextcap; - uint16_t info; - }; - uint32_t full; - }; -} xhci_ext_cap_t; - -typedef struct { - union { - struct { - uint8_t id; - uint8_t nextcap; - uint8_t minor; - uint8_t major; - }; - uint32_t firsthalf; - }; - - uint32_t name; - - union { - struct { - uint8_t portoffset; - uint8_t portcount; - uint8_t protocoldefine; - uint8_t protocolspeedid; - }; - uint32_t thirdhalf; - }; - - union { - struct { - uint8_t slottype : 4; - uint32_t reserved0 : 28; - }; - uint32_t fourhalf; - }; -} xhci_usb_cap_t; - -typedef struct { - uint8_t type; - uint8_t request; - uint16_t value; - uint16_t index; - uint16_t len; -} xhci_usb_command_t; - -typedef struct { - xhci_usb_command_t command; - uint32_t len : 17; - uint32_t reserved0 : 5; - uint32_t target : 10; - uint32_t cycle : 1; - uint32_t reserved1 : 4; - uint32_t intoncomp : 1; - uint32_t imdata : 1; - uint32_t reserved2 : 3; - uint32_t type : 6; - uint32_t trt : 2; - uint32_t reserved3 : 14; -} xhci_setupstage_trb_t; - -typedef struct { - uint64_t data; - uint32_t len : 17; - uint32_t tdsize : 5; - uint32_t target : 10; - uint32_t cycle : 1; - uint32_t evnexttrb : 1; - uint32_t intrshortpacket : 1; - uint32_t nosnoop : 1; - uint32_t chain : 1; - uint32_t introncomp : 1; - uint32_t imdata : 1; - uint32_t reserved0 : 3; - uint32_t type : 6; - uint32_t direction : 1; - uint32_t reserved1 : 15; -} xhci_datastage_trb_t; - -typedef struct { - uint64_t base; - uint32_t reserved0 : 22; - uint32_t target : 10; - uint32_t cycle : 1; - uint32_t evnext : 1; - uint32_t reserved1 : 2; - uint32_t chain : 1; - uint32_t intoncomp : 1; - uint32_t reserved2 : 3; - uint32_t blockevent : 1; - uint32_t type : 6; - uint32_t reserved3 : 16; -} xhci_eventdata_trb_t; - -typedef struct { - uint64_t reserved0; - uint32_t reserved1 : 22; - uint32_t target : 10; - uint32_t cycle : 1; - uint32_t evnext : 1; - uint32_t reserved2 : 2; - uint32_t chain : 1; - uint32_t intoncomp : 1; - uint32_t reserved3 : 4; - uint32_t type : 6; - uint32_t direction : 1; - uint32_t reserved4 : 15; -} xhci_statusstage_trb_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t ent : 1; - uint32_t isp : 1; - uint32_t nosnoop : 1; - uint32_t chain : 1; - uint32_t ioc : 1; - uint32_t imdata : 1; - uint32_t reserved0 : 2; - uint32_t bei : 1; - uint32_t type : 6; - uint32_t dir : 1; - uint32_t reserved1 : 15; -} xhci_normal_info_trb_t; - -typedef struct { - uint64_t base; - uint32_t trbtransferlen : 17; - uint32_t tdsize : 5; - uint32_t target : 10; - union { - xhci_normal_info_trb_t info_s; - uint32_t info; - }; -} xhci_normal_trb_t; - -typedef struct { - uint32_t cycle : 1; - uint32_t reserved0 : 9; - uint32_t type : 6; - uint32_t reserved1 : 16; -} xhci_port_change_info_t; - -typedef struct { - struct { - uint32_t reserved0 : 24; - uint32_t port : 8; - }; - uint32_t status; - union { - xhci_port_change_info_t info_s; - uint32_t info; - }; -} xhci_port_change_trb_t; - -typedef struct xhci_hid_driver { - void (*func)(xhci_usb_device_t* usbdev,xhci_done_trb_t* trb); - int type; - struct xhci_hid_driver* next; -} xhci_hid_driver_t; - -#define XHCI_ENDPOINTTYPE_ISOCHRONOUS_OUT 1 -#define XHCI_ENDPOINTTYPE_BULK_OUT 2 -#define XHCI_ENDPOINTTYPE_INTERRUPT_OUT 3 -#define XHCI_ENDPOINTTYPE_ISOCHRONOUS_IN 5 -#define XHCI_ENDPOINTTYPE_BULK_IN 6 -#define XHCI_ENDPOINTTYPE_INTERRUPT_IN 7 -#define TRB_NORMAL_TYPE 1 -#define TRB_SETUPSTAGE_TYPE 2 -#define TRB_DATASTAGE_TYPE 3 -#define TRB_STATUSSTAGE_TYPE 4 -#define TRB_ISOCH_TYPE 5 -#define TRB_LINK_TYPE 6 -#define TRB_EVENTDATA_TYPE 7 -#define TRB_NOOP_TYPE 8 -#define TRB_ENABLESLOTCOMMAND_TYPE 9 -#define TRB_DISABLESLOTCOMMAND_TYPE 10 -#define TRB_ADDRESSDEVICECOMMAND_TYPE 11 -#define TRB_CONFIGUREENDPOINTCOMMAND_TYPE 12 -#define TRB_EVALUATECONTEXTCOMMAND_TYPE 13 -#define TRB_RESETENDPOINTCOMMAND_TYPE 14 -#define TRB_STOPENDPOINTCOMMAND_TYPE 15 -#define TRB_SETTRDEQPOINTERCOMMAND_TYPE 16 -#define TRB_RESETDEVICECOMMAND_TYPE 17 -#define TRB_FORCEEVENTCOMMAND_TYPE 18 -#define TRB_NEGBANDWIDTHCOMMAND_TYPE 19 -#define TRB_SETLATENCYCOMMAND_TYPE 20 -#define TRB_GETPORTBANDWIDTHCOMMAND_TYPE 21 -#define TRB_FORCEHEADERCOMMAND_TYPE 22 -#define TRB_NOOPCOMMAND_TYPE 23 -#define TRB_TRANSFEREVENT_TYPE 32 -#define TRB_COMMANDCOMPLETIONEVENT_TYPE 33 -#define TRB_PORTSTATUSCHANGEEVENT_TYPE 34 -#define TRB_HOSTCONTROLLEREVENT_TYPE 37 -#define TRB_DEVICENOTIFICATIONEVENT_TYPE 38 -#define TRB_MFINDEXWARPEVENT_TYPE 39
\ No newline at end of file diff --git a/tools/pkg/2/xhci_driver/info.txt b/tools/pkg/2/xhci_driver/info.txt deleted file mode 100644 index 1c18649..0000000 --- a/tools/pkg/2/xhci_driver/info.txt +++ /dev/null @@ -1 +0,0 @@ -xhci_driver
\ No newline at end of file diff --git a/tools/pkg/2/xhci_driver/src/main.cpp b/tools/pkg/2/xhci_driver/src/main.cpp deleted file mode 100644 index 143ab53..0000000 --- a/tools/pkg/2/xhci_driver/src/main.cpp +++ /dev/null @@ -1,1503 +0,0 @@ - -#include <iostream> -#include <xhci.hpp> - -#define _DEFAULT_SOURCE - -#include <unistd.h> - -#include <orange/dev.h> -#include <orange/io.h> -#include <orange/pci.h> -#include <orange/log.h> - -#include <sched.h> - -#include <fcntl.h> - -#include <string.h> - -xhci_device_t* xhci_list; - -void __xhci_put_new_device(xhci_device_t* dev) { - if(!dev) { - return; - } - - if(!xhci_list) { - xhci_list = dev; - } else { - dev->next = xhci_list; - xhci_list = dev; - } - -} - -void __xhci_doorbell(xhci_device_t* dev,uint32_t value) { - *dev->doorbell = value; -} - -void __xhci_doorbell_id(xhci_device_t* dev,uint32_t idx,uint32_t val) { - dev->doorbell[idx] = val; -} - -void __xhci_reset(xhci_device_t* dev) { - - usleep(50*1000); // wait some time - - dev->op->usbcmd |= (1 << 1); - uint16_t timeout = XHCI_RESET_TIMEOUT; - while(dev->op->usbsts & (1 << 11)) { - if(!timeout) { - log(LEVEL_MESSAGE_FAIL,"Can't reset XHCI Controller, ignoring\n"); - break; - } - usleep(5 * 1000); - timeout = timeout - 1; - } - - usleep(5000); - -} - -void __xhci_enable(xhci_device_t* dev) { - usleep(50*1000); - dev->op->usbcmd |= (1 << 0) | (1 << 2); - uint16_t timeout = XHCI_RESET_TIMEOUT; - while(dev->op->usbsts & (1 << 0)) { - if(!timeout) { - log(LEVEL_MESSAGE_FAIL,"Can't start XHCI Controller, crying\n"); - break; - } - usleep(5 * 1000); - timeout = timeout - 1; - } - - usleep(5000); - -} - -void __xhci_reset_intr(xhci_device_t* dev, uint16_t intr) { - - if(intr > dev->cap->hcsparams1.maxintrs) { - log(LEVEL_MESSAGE_FAIL,"Intr is higher than maxintrs! Skipping"); - return; - } - - dev->op->usbsts = (1 << 3); - dev->runtime->int_regs[intr].iman |= (1 << 0); -} - -void __xhci_punch_intr(xhci_device_t* dev,uint16_t intr) { - dev->runtime->int_regs[intr].erdp.event_busy = 1; -} - -void __xhci_update_stepfather(xhci_device_t* dev,xhci_event_ring_ctx_t* grandpa) { - grandpa->father->erdp_val = grandpa->table[0].base + (grandpa->queue * sizeof(xhci_trb_t)); -} - -xhci_trb_t* __xhci_move_father(xhci_device_t* dev,xhci_event_ring_ctx_t* ctx) { - xhci_trb_t* trb = &ctx->trb[ctx->queue++]; - if(ctx->queue == ctx->trb_limit) { - ctx->cycle = !ctx->cycle; - ctx->queue = 0; - } - return trb; -} - -xhci_event_ring_ctx_t* __xhci_create_event_ring(xhci_device_t* dev,uint16_t trb_size,volatile IR_t* stepfather,uint16_t sons) { - xhci_event_ring_ctx_t* ring_info = new xhci_event_ring_ctx_t; - ring_info->cycle = 1; - ring_info->queue = 0; - ring_info->father = stepfather; // :pensive: - ring_info->trb_limit = trb_size; - ring_info->trb = 0; - - uint64_t new_table = liborange_alloc_dma(ALIGNPAGEUP(sons * sizeof(xhci_erst_t))); - void* virt_table = liborange_map_phys(new_table,0,ALIGNPAGEUP(sons * sizeof(xhci_erst_t))); - - ring_info->table = (xhci_erst_t*)virt_table; - - uint64_t phys_trb = liborange_alloc_dma(16 * PAGE_SIZE); - ring_info->table[0].base = phys_trb; - ring_info->table[0].size = trb_size; - - ring_info->trb = (xhci_trb_t*)liborange_map_phys(phys_trb,0,16 * PAGE_SIZE); - - stepfather->erstsz = sons; - __xhci_update_stepfather(dev,ring_info); - stepfather->erstba = new_table; - - return ring_info; - -} - -xhci_trb_t get_trb(xhci_event_ring_ctx_t* father,uint16_t idx) { - return father->trb[idx]; -} - -int __xhci_event_receive(xhci_device_t* dev,xhci_event_ring_ctx_t* father,xhci_trb_t** out) { // it will return trb virtual addresses - int len = 0; - while(get_trb(father,father->queue).info_s.cycle == father->cycle) - out[len++] = __xhci_move_father(dev,father); - __xhci_punch_intr(dev,0); - __xhci_update_stepfather(dev,father); - return len; -} - -xhci_command_ring_ctx_t* __xhci_create_command_ring(xhci_device_t* dev,uint16_t trb_size) { - xhci_command_ring_ctx_t* ring_info = new xhci_command_ring_ctx_t; - ring_info->cycle = 1; - ring_info->queue = 0; - ring_info->trb_limit = trb_size; - - uint64_t phys_trb = liborange_alloc_dma(ALIGNPAGEUP(trb_size * sizeof(xhci_trb_t))); - - ring_info->phys = phys_trb; - - ring_info->trb = (xhci_trb_t*)liborange_map_phys(phys_trb,0,ALIGNPAGEUP(trb_size * sizeof(xhci_trb_t))); - ring_info->trb[trb_size - 1].base = phys_trb; - ring_info->trb[trb_size - 1].info = (6 << 10) | (1 << 1) | (1 << 0); - return ring_info; -} - - -void __xhci_command_ring_queue(xhci_device_t* dev,xhci_command_ring_ctx_t* ctx,xhci_trb_t* trb) { - trb->info |= ctx->cycle; - memcpy(&ctx->trb[ctx->queue],trb,sizeof(xhci_trb_t)); - if(++ctx->queue == ctx->trb_limit - 1) { - ctx->queue = 0; - ctx->trb[ctx->trb_limit - 1].info = (6 << 10) | (1 << 1) | (ctx->cycle << 0); - ctx->cycle = !ctx->cycle; - } -} - -void __xhci_setup_run(xhci_device_t* dev) { - volatile IR_t* head = (volatile IR_t*)&dev->runtime->int_regs[0]; - head->iman |= (1 << 1); - - dev->event_ring = __xhci_create_event_ring(dev,256,head,1); - - __xhci_reset_intr(dev,0); -} - -void __xhci_fill_dcbaa(xhci_device_t* dev) { - - uint64_t phys_dcbaa = liborange_alloc_dma(ALIGNPAGEUP(8*dev->cap->hcsparams1.maxslots)); - - uint64_t* dcbaa = (uint64_t*)liborange_map_phys(phys_dcbaa,0,ALIGNPAGEUP(8*dev->cap->hcsparams1.maxslots)); - - if(dev->calculated_scratchpad_count) { - - uint64_t phys_list = liborange_alloc_dma(ALIGNPAGEUP(8*dev->calculated_scratchpad_count)); - - uint64_t* list = (uint64_t*)liborange_map_phys(phys_list,0,ALIGNPAGEUP(8*dev->calculated_scratchpad_count)); - for(uint16_t i = 0;i < dev->calculated_scratchpad_count;i++) { - uint64_t hi = liborange_alloc_dma(4096); - list[i] = hi; - } - dcbaa[0] = phys_list; - } - - dev->dcbaa = (uint64_t*)dcbaa; - dev->op->dcbaap = phys_dcbaa; - usleep(5000); -} - -void __xhci_setup_op(xhci_device_t* dev) { - __xhci_fill_dcbaa(dev); - dev->com_ring = __xhci_create_command_ring(dev,128); // i dont think what command ring will be fat - dev->op->crcr = dev->com_ring->phys | dev->com_ring->cycle; - dev->op->config = dev->cap->hcsparams1.maxslots; - dev->op->dnctrl = 0xFFFF; -} - -volatile uint32_t* __xhci_portsc(xhci_device_t* dev,uint32_t portnum) { - return ((volatile uint32_t*)(dev->xhci_virt_base + 0x400 + dev->cap->caplength + (0x10 * portnum))); -} - -void* __xhci_helper_map(uint64_t start,uint64_t pagelen) { - return liborange_map_phys(start,PTE_MMIO,pagelen); -} - -const char* trb_type_to_str(int type) { - switch(type) { - case TRB_COMMANDCOMPLETIONEVENT_TYPE: - return "TRB_COMMAND_COMPLETION_EVENT"; - case TRB_TRANSFEREVENT_TYPE: - return "TRB_TRANSFER_EVENT"; - default: - return "Unknown"; - } -} - -xhci_trb_t __xhci_event_wait(xhci_device_t* dev,int type) { - xhci_event_ring_ctx_t* father = dev->event_ring; - xhci_trb_t* buffer[1024]; - int timeout = 100; - while(1) { - int count = 0; - memset(buffer,0,sizeof(xhci_trb_t*) * 1024); - if(get_trb(father,father->queue).info_s.cycle == father->cycle) - count = __xhci_event_receive(dev,father,buffer); - - if(count) { - xhci_trb_t* current = 0; - for(int i = 0;i < count;i++) { - current = buffer[i]; - if(current->info_s.type == type) { - return *current; - } else { - log(LEVEL_MESSAGE_WARN,"Wait for wrong type %d\n",current->info_s.type); - } - } - } - - if(--timeout == 0) { - xhci_trb_t t; - t.base = 0xDEAD; - t.ret_code = 0; - return t; - } - - usleep(5000); - - } -} - -void __xhci_clear_event(xhci_device_t* dev) { - int count = 0; - xhci_trb_t* buffer[1024]; - if(get_trb(dev->event_ring,dev->event_ring->queue).info_s.cycle == dev->event_ring->cycle) - count = __xhci_event_receive(dev,dev->event_ring,buffer); -} - -xhci_port_ring_ctx_t* __xhci_setup_port_ring(uint16_t trb_count,uint16_t slot) { - xhci_port_ring_ctx_t* ring_info = new xhci_port_ring_ctx_t; - ring_info->cycle = 1; - ring_info->queue = 0; - ring_info->slot = slot; - ring_info->trb_limit = trb_count; - - uint64_t phys_trb = liborange_alloc_dma(16 * 4096); - ring_info->trb = (xhci_trb_t*)liborange_map_phys(phys_trb,0,16 * 4096); - - ring_info->phys = phys_trb; - ring_info->trb[trb_count - 1].base = phys_trb; - ring_info->trb[trb_count - 1].info = (6 << 10) | (1 << 1) | (1 << 0); - return ring_info; -} - -// its same as command ring -void __xhci_port_ring_queue(xhci_port_ring_ctx_t* ctx,xhci_trb_t* trb) { - trb->info |= ctx->cycle; - memcpy(&ctx->trb[ctx->queue],trb,sizeof(xhci_trb_t)); - if(++ctx->queue == ctx->trb_limit - 1) { - ctx->queue = 0; - ctx->trb[ctx->trb_limit - 1].info = (6 << 10) | (1 << 1) | (ctx->cycle << 0); - ctx->cycle = !ctx->cycle; - } -} - -void __xhci_create_dcbaa(xhci_device_t* dev,uint32_t slotid,uint64_t addr) { - dev->dcbaa[slotid] = addr; -} - -xhci_usb_device_t* usbdevs = 0; - -xhci_usb_device_t* __xhci_alloc_dev(uint32_t portnum,uint32_t slotid) { - xhci_usb_device_t* dev = new xhci_usb_device_t; - dev->next = 0; - dev->portnum = portnum; - dev->slotid = slotid; - dev->transfer_ring = __xhci_setup_port_ring(256,slotid); - dev->phys_input_ctx = liborange_alloc_dma(4096); - if(!usbdevs) { - usbdevs = dev; - } else { - dev->next = usbdevs; - usbdevs = dev; - } - return dev; -} - -int __xhci_enable_slot(xhci_device_t* dev, int portnum) { - xhci_trb_t trb; - - memset(&trb,0,sizeof(xhci_trb_t)); - - trb.info_s.intoncompletion = 1; - trb.info_s.type = TRB_ENABLESLOTCOMMAND_TYPE; - - __xhci_clear_event(dev); - - __xhci_command_ring_queue(dev,dev->com_ring,&trb); - __xhci_doorbell(dev,0); - usleep(25000); - - xhci_trb_t ret = __xhci_event_wait(dev,TRB_COMMANDCOMPLETIONEVENT_TYPE); - - if(ret.base == 0xDEAD) { - log(LEVEL_MESSAGE_FAIL,"Timeout for port %d in slot enabling\n",portnum); - return 0; - } - - xhci_slot_trb_t* slot_ret = (xhci_slot_trb_t*)&ret; - - if(ret.ret_code != 1) - log(LEVEL_MESSAGE_FAIL,"Can't allocate slot for port %d (ret %d)\n",portnum,ret.ret_code); - - return slot_ret->info_s.slotid; - -} - -int __xhci_set_addr(xhci_device_t* dev,uint64_t addr,uint32_t id,char bsr) { - xhci_set_addr_trb_t trb; - memset(&trb,0,sizeof(trb)); - trb.base = addr; - trb.info_s.bsr = 0; - trb.info_s.type = TRB_ADDRESSDEVICECOMMAND_TYPE; - trb.info_s.slotid = id; - __xhci_clear_event(dev); - - usleep(5000); - - __xhci_clear_event(dev); - - __xhci_command_ring_queue(dev,dev->com_ring,(xhci_trb_t*)&trb); - __xhci_doorbell(dev,0); - usleep(5000); - - xhci_trb_t ret = __xhci_event_wait(dev,TRB_COMMANDCOMPLETIONEVENT_TYPE); - - if(ret.ret_code != 1 && ret.ret_code != 0) - log(LEVEL_MESSAGE_FAIL,"Can't set XHCI port address (ret %d)\n",ret.ret_code); - - return ret.ret_code; - -} - -xhci_trb_t __xhci_send_usb_request_packet(xhci_device_t* dev,xhci_usb_device_t* usbdev,xhci_usb_command_t usbcommand,void* out,uint64_t len) { - - uint64_t phys_status_buf = liborange_alloc_dma(4096); - uint64_t phys_desc_buf = liborange_alloc_dma(4096); - - void* status_buf = liborange_map_phys(phys_status_buf,0,4096); - void* desc_buf = liborange_map_phys(phys_desc_buf,0,4096); - - memset(out,0,len); - - xhci_setupstage_trb_t setup; - xhci_datastage_trb_t data; - xhci_eventdata_trb_t event0; - xhci_statusstage_trb_t status; - xhci_eventdata_trb_t event1; - - memset(&setup,0,sizeof(xhci_trb_t)); - memset(&data,0, sizeof(xhci_trb_t)); - memset(&event0,0,sizeof(xhci_trb_t)); - memset(&status,0,sizeof(xhci_trb_t)); - memset(&event1,0,sizeof(xhci_trb_t)); - - memcpy(&setup.command,&usbcommand,sizeof(xhci_usb_command_t)); - - setup.type = TRB_SETUPSTAGE_TYPE; - setup.trt = 3; - setup.imdata = 1; - setup.len = 8; - - data.type = TRB_DATASTAGE_TYPE; - data.data = phys_desc_buf; - data.len = len; - data.chain = 1; - data.direction = 1; - - event0.type = TRB_EVENTDATA_TYPE; - event0.base = phys_status_buf; - event0.intoncomp = 1; - - status.type = TRB_STATUSSTAGE_TYPE; - status.chain = 1; - - event1.type = TRB_EVENTDATA_TYPE; - event1.intoncomp = 1; - - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&setup); - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&data); - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&event0); - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&status); - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&event1); - - __xhci_clear_event(dev); - - __xhci_doorbell_id(dev,usbdev->slotid,1); - usleep(5000); - - xhci_trb_t ret = __xhci_event_wait(dev,TRB_TRANSFEREVENT_TYPE); - - if(ret.base == 0xDEAD) { - ret.ret_code = 0; - return ret; - } - - if(ret.ret_code != 1) { - log(LEVEL_MESSAGE_FAIL,"Failed to request xhci device, idx: %p, val: %p, type: %p, len: %p, request: %d ret_code %d\n",usbcommand.index,usbcommand.value,usbcommand.type,usbcommand.len,usbcommand.request,ret.ret_code); - ret.ret_code = 0; - return ret; - } - - usleep(5000); - - memcpy(out,desc_buf,len); - - liborange_free_dma(phys_desc_buf); - liborange_free_dma(phys_status_buf); - - return ret; - -} - -xhci_trb_t __xhci_send_usb_packet(xhci_device_t* dev,xhci_usb_device_t* usbdev,xhci_usb_command_t com) { - - xhci_setupstage_trb_t setup; - xhci_statusstage_trb_t status; - - memset(&setup,0,sizeof(xhci_setupstage_trb_t)); - memset(&status,0,sizeof(xhci_statusstage_trb_t)); - - memcpy(&setup.command,&com,sizeof(xhci_usb_command_t)); - - setup.imdata = 1; - setup.len = 8; - setup.type = TRB_SETUPSTAGE_TYPE; - - status.direction = 1; - status.intoncomp = 1; - status.type = TRB_STATUSSTAGE_TYPE; - - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&setup); - __xhci_port_ring_queue(usbdev->transfer_ring,(xhci_trb_t*)&status); - - __xhci_clear_event(dev); - - __xhci_doorbell_id(dev,usbdev->slotid,1); - usleep(5000); - - xhci_trb_t ret = __xhci_event_wait(dev,TRB_TRANSFEREVENT_TYPE); - - return ret; - -} - -int __xhci_get_usb_descriptor(xhci_device_t* dev,xhci_usb_device_t* usbdev,void* out,uint64_t len) { - xhci_usb_command_t usbcommand; - usbcommand.type = 0x80; - usbcommand.request = 6; - usbcommand.value = 1 << 8; - usbcommand.index = 0; - usbcommand.len = len; - - xhci_trb_t ret = __xhci_send_usb_request_packet(dev,usbdev,usbcommand,out,len); - if(ret.ret_code != 1) - return 0; - - return 1; - -} - -uint16_t __xhci_get_speed(xhci_device_t* dev,uint32_t portsc) { - uint8_t extracted_speed = (portsc & 0x3C00) >> 10; - switch (extracted_speed) { - case XHCI_USB_SPEED_LOW_SPEED: - return 8; - - case XHCI_USB_SPEED_FULL_SPEED: - return 64; - - case XHCI_USB_SPEED_HIGH_SPEED: - return 64; - - case XHCI_USB_SPEED_SUPER_SPEED: - return 512; - - case XHCI_USB_SPEED_SUPER_SPEED_PLUS: - return 512; - - default: - return 0; - } -} - -int __xhci_reset_dev(xhci_device_t* dev,uint32_t portnum) { - volatile uint32_t* portsc = (volatile uint32_t*)__xhci_portsc(dev,portnum); - uint32_t load_portsc = *portsc; - - if(!(*portsc & (1 << 9))) { - load_portsc |= (1 << 9); - *portsc = load_portsc; - usleep(5000); - if(!(*portsc & (1 << 9))) { - return 0; - } - } - - uint8_t old_bit = load_portsc & (1 << 1); - - if(dev->usb3ports[portnum]) { - load_portsc |= (1 << 31); - *portsc = load_portsc; - } else { - load_portsc |= 0x10; - *portsc = load_portsc; - } - - uint16_t time = 50; - - if(dev->usb3ports[portnum]) { - while(*portsc & (1 << 19)) { - if(time-- == 0) { - log(LEVEL_MESSAGE_FAIL,"Can't reset USB 3.0 device with port %d, ignoring\n",portnum); - return 0; - } - usleep(5000); - } - } else { - while((*portsc & (1 << 1)) == old_bit) { - if(time-- == 0) { - log(LEVEL_MESSAGE_FAIL,"Can't reset USB 2.0 device with port %d, ignoring\n",portnum); - return 1; - } - usleep(5000); - } - } - - usleep(5000); - return 1; - -} - -void __xhci_unicode_to_ascii(uint16_t* src,char* dest) { - uint16_t src_ptr = 0; - uint16_t dest_ptr = 0; - - uint16_t* ptr = (uint16_t*)src; - while(ptr[src_ptr]) { - - if(ptr[src_ptr] < 128) - dest[dest_ptr++] = ptr[src_ptr++]; - else - dest[dest_ptr++] = '?'; - } - dest[dest_ptr] = '\0'; -} - -int __xhci_read_usb_string(xhci_device_t* dev,xhci_usb_device_t* usbdev,xhci_string_descriptor_t* out,uint8_t index,uint8_t lang) { - xhci_usb_command_t usbcommand; - usbcommand.type = 0x80; - usbcommand.request = 6; - usbcommand.value = (3 << 8) | index; - usbcommand.index = lang; - usbcommand.len = sizeof(xhci_usb_descriptor_header); - - xhci_trb_t ret = __xhci_send_usb_request_packet(dev,usbdev,usbcommand,out,usbcommand.len); - if(ret.ret_code != 1) - return 0; - - usbcommand.len = out->head.len; - - if(usbcommand.len < 8) { - return 1; - } - - ret = __xhci_send_usb_request_packet(dev,usbdev,usbcommand,out,usbcommand.len); - if(ret.ret_code != 1) - return 0; - - return 1; - -} - - - -int __xhci_read_usb_lang_string(xhci_device_t* dev,xhci_usb_device_t* usbdev,xhci_lang_descriptor_t* out) { - xhci_usb_command_t usbcommand; - usbcommand.type = 0x80; - usbcommand.request = 6; - usbcommand.value = (3 << 8); - usbcommand.index = 0; - usbcommand.len = sizeof(xhci_usb_descriptor_header); - - xhci_trb_t ret = __xhci_send_usb_request_packet(dev,usbdev,usbcommand,out,usbcommand.len); - if(ret.ret_code != 1) - return 0; - - usbcommand.len = out->head.len; - - ret = __xhci_send_usb_request_packet(dev,usbdev,usbcommand,out,usbcommand.len); - if(ret.ret_code != 1) - return 0; - - return 1; - -} - -int __xhci_print_device_info(xhci_device_t* dev,xhci_usb_device_t* usb_dev,char* product0,char* manufacter0) { - xhci_lang_descriptor_t lang; - - int status = __xhci_read_usb_lang_string(dev,usb_dev,&lang); - - if(!status) - return 0; - - uint16_t lang0 = lang.lang[0]; - - xhci_string_descriptor_t product; - xhci_string_descriptor_t manufacter; - - memset(&product,0,sizeof(product)); - memset(&manufacter,0,sizeof(manufacter)); - - status = __xhci_read_usb_string(dev,usb_dev,&product,usb_dev->desc->product1,lang0); - - if(!status) - return 0; - - status = __xhci_read_usb_string(dev,usb_dev,&manufacter,usb_dev->desc->manufacter,lang0); - - if(!status) - return 0; - - memset(product0,0,256); - memset(manufacter0,0,256); - - __xhci_unicode_to_ascii(product.str,product0); - __xhci_unicode_to_ascii(manufacter.str,manufacter0); - - return 1; - -} - -void __xhci_setup_config(xhci_device_t* dev,xhci_usb_device_t* usbdev,uint16_t value) { - xhci_usb_command_t command; - command.type = 0; - command.index = 0; - command.len = 0; - command.request = 9; - command.value = value; - - int ret = __xhci_send_usb_packet(dev,usbdev,command).ret_code; - - if(ret != 1) - log(LEVEL_MESSAGE_FAIL,"Can't set configuration on port %d with val %d (ret %d)\n",usbdev->portnum,value,ret); -} - -void __xhci_get_config_descriptor(xhci_device_t* dev,xhci_usb_device_t* usbdev, xhci_config_descriptor_t* out) { - xhci_usb_command_t com; - com.type = 0x80; - com.value = 2 << 8; - com.index = 0; - com.len = sizeof(xhci_usb_descriptor_header); - com.request = 6; - - __xhci_send_usb_request_packet(dev,usbdev,com,out,sizeof(xhci_usb_descriptor_header)); - com.len = out->head.len; - __xhci_send_usb_request_packet(dev,usbdev,com,out,out->head.len); - com.len = out->len; - __xhci_send_usb_request_packet(dev,usbdev,com,out,out->len); - -} - -void __xhci_get_hid_report(xhci_device_t* dev,xhci_usb_device_t* usbdev,uint8_t idx,uint8_t internum,void* data,uint32_t len) { - xhci_usb_command_t cmd; - cmd.index = internum; - cmd.request = 6; - cmd.type = 0x81; - cmd.len = len; - cmd.value = (0x22 << 8) | idx; - __xhci_send_usb_request_packet(dev,usbdev,cmd,data,len); -} - -void __xhci_set_boot_protocol(xhci_device_t* dev, xhci_usb_device_t* usbdev, int internum) { - xhci_usb_command_t cmd; - cmd.index = internum; - cmd.request = 0x0B; - cmd.type = 0x21; - cmd.len = 0; - cmd.value = 0; - - char data[4096]; - __xhci_send_usb_request_packet(dev,usbdev,cmd,data,0); -} - -int __xhci_ep_to_type(xhci_endpoint_descriptor_t* desc) { - uint8_t direction = (desc->endpointaddr & 0x80) ? 1 : 0; - uint8_t type = desc->attributes & 3; - - switch (type) { - case 1: - return direction == 1 ? XHCI_ENDPOINTTYPE_ISOCHRONOUS_IN : XHCI_ENDPOINTTYPE_ISOCHRONOUS_OUT; - - case 2: - return direction == 1 ? XHCI_ENDPOINTTYPE_BULK_IN : XHCI_ENDPOINTTYPE_BULK_OUT; - - case 3: - return direction == 1 ? XHCI_ENDPOINTTYPE_INTERRUPT_IN : XHCI_ENDPOINTTYPE_INTERRUPT_OUT; - } - - return 0; // without it i will got UB -} - -void __xhci_ask_for_help_hid(xhci_device_t* dev,xhci_usb_device_t* usbdev) { - - for(int i = 0;i < 30;i++) { - - if(!usbdev->doorbell_values[i]) - continue; - - xhci_port_ring_ctx_t* transfer_ring = usbdev->ep_ctx[i]; - xhci_normal_trb_t trb; - memset(&trb,0,sizeof(xhci_normal_trb_t)); - trb.info_s.type = 1; - trb.info_s.ioc = 1; - trb.base = (uint64_t)usbdev->phys_buffers[i]; - trb.trbtransferlen = usbdev->buffers_need_size[i]; - - __xhci_port_ring_queue(transfer_ring,(xhci_trb_t*)&trb); - __xhci_doorbell_id(dev,usbdev->slotid,usbdev->doorbell_values[i]); - } - -} - -const char* __xhci_usb_type_to_str(int type) { - switch(type) { - case USB_TYPE_KEYBOARD: - return "USB Keyboard"; - case USB_TYPE_MOUSE: - return "USB Mouse"; - default: - return "Unsupported"; - }; -} - -int log2(unsigned int x) { - int result = -1; - while (x) { - x >>= 1; - result++; - } - return result; -} - -void __xhci_init_dev(xhci_device_t* dev,int portnum) { - - volatile uint32_t* portsc = __xhci_portsc(dev,portnum); - uint32_t load_portsc = *portsc; - if(!(load_portsc & 1)) - return; - - int status = __xhci_reset_dev(dev,portnum); - if(!status) - return; - - int id = __xhci_enable_slot(dev,portnum); - - xhci_usb_device_t* usb_dev = __xhci_alloc_dev(portnum,id); - //String::memset(usb_dev,0,sizeof(xhci_usb_device_t)); - - memset(usb_dev->doorbell_values,0,30); - - usb_dev->interface = 0; - - uint64_t addr = liborange_alloc_dma(4096); - __xhci_create_dcbaa(dev,usb_dev->slotid,addr); - - uint32_t* hccparams = (uint32_t*)(&dev->cap->hccparams1); - char context_size = ((hccparams1_t*)hccparams)->contextsize; - - if(!context_size) - dev->dcbaa[id] += 64; - else - dev->dcbaa[id] += 128; - - if(!context_size) - usb_dev->_is64byte = 0; - else - usb_dev->_is64byte = 1; - - usb_dev->dev = dev; - - load_portsc = *portsc; // load it again - - uint16_t speed = __xhci_get_speed(dev,load_portsc); - - const char* speed_to_str[7] = { - "(0 MB/s - USB ?)", - "(12 MB/s - USB 2.0)", - "(1.5 Mb/s - USB 2.0)", - "(480 Mb/s - USB 2.0)", - "(5 Gb/s - USB3.0)", - "(10 Gb/s - USB 3.1)" - }; - - if(!context_size) { - xhci_input_ctx_t* input_ctx = (xhci_input_ctx_t*)liborange_map_phys(addr,0,4096); - - memset(input_ctx,0,4096); - input_ctx->input_ctx.A = (1 << 0) | (1 << 1); - input_ctx->slot.contextentries = 1; - input_ctx->slot.speed = (load_portsc & 0x3C00) >> 10; - input_ctx->slot.porthubnum = portnum + 1; - input_ctx->ep0.endpointtype = 4; - input_ctx->ep0.cerr = 3; - input_ctx->ep0.maxpacketsize = speed; - input_ctx->ep0.base = usb_dev->transfer_ring->phys | usb_dev->transfer_ring->cycle; - input_ctx->ep0.averagetrblen = 0x8; - usb_dev->input_ctx = (xhci_input_ctx_t*)input_ctx; - - } else { - xhci_input_ctx64_t* input_ctx = (xhci_input_ctx64_t*)liborange_map_phys(addr,0,4096); - - memset(input_ctx,0,4096); - input_ctx->input_ctx.A = (1 << 0) | (1 << 1); - input_ctx->slot.contextentries = 1; - input_ctx->slot.speed = (load_portsc & 0x3C00) >> 10; - input_ctx->slot.porthubnum = portnum + 1; - input_ctx->ep0.endpointtype = 4; - input_ctx->ep0.cerr = 3; - input_ctx->ep0.maxpacketsize = speed; - input_ctx->ep0.base = usb_dev->transfer_ring->phys | usb_dev->transfer_ring->cycle; - input_ctx->ep0.averagetrblen = 8; - - usb_dev->input_ctx = (xhci_input_ctx_t*)input_ctx; - - } - - int status_addr = __xhci_set_addr(dev,addr,id,0); - - if(status_addr == 0) { - log(LEVEL_MESSAGE_WARN,"zero ret from xhci_set_addr (broken xhci ?)\n"); - } else if(status_addr != 1) - return; - - xhci_usb_descriptor_t* descriptor = (xhci_usb_descriptor_t*)malloc(4096); - int status2 = __xhci_get_usb_descriptor(dev,usb_dev,(void*)descriptor,8); - - if(!status2) - return; - - ((xhci_input_ctx_t*)liborange_map_phys(dev->dcbaa[id],0,4096))->ep0.maxpacketsize = descriptor->maxpacketsize; - - status2 = __xhci_get_usb_descriptor(dev,usb_dev,(void*)descriptor,descriptor->head.len); - if(!status2) - return; - usb_dev->desc = descriptor; - - usb_dev->type = 0; - - if(!speed) { - log(LEVEL_MESSAGE_FAIL,"Broken USB Device/Firmware, can't continue work. skipping\n"); - return; - } - - char product[1024]; - char manufacter[1024]; - - memset(product,0,1024); - memset(manufacter,0,1024); - - int status4 = __xhci_print_device_info(dev,usb_dev,product,manufacter); - if(!status4) - return; - - xhci_config_descriptor_t* cfg = (xhci_config_descriptor_t*)malloc(4096); - usb_dev->config = cfg; - - __xhci_get_config_descriptor(dev,usb_dev,cfg); - - __xhci_setup_config(dev,usb_dev,cfg->configval); - - if(!context_size) { - usb_dev->input_ctx->input_ctx.A = (1 << 0); - } else { - xhci_input_ctx64_t* input = (xhci_input_ctx64_t*)liborange_map_phys(addr,0,4096); - input->input_ctx.A = (1 << 0); - } - - uint16_t i = 0; - while(i < (cfg->len - cfg->head.len)) { - xhci_usb_descriptor_header* current = (xhci_usb_descriptor_header*)(&cfg->data[i]); - //INFO("Found descriptor with type %d (0x%p) and len %d (i %d)!\n",current->type,current->type,current->len,i); - - xhci_interface_t* inter = new xhci_interface_t; - inter->type = current->type; - inter->data = current; - memset(inter,0,sizeof(xhci_interface_t)); - if(!usb_dev->interface) - usb_dev->interface = inter; - else { - inter->next = usb_dev->interface; - usb_dev->interface = inter; - } - - switch(current->type) { - - case 0x04: { - xhci_interface_descriptor_t* interface = (xhci_interface_descriptor_t*)current; - //INFO("interface interclass %d, interface intersubclass %d, protocol %d\n",interface->interclass,interface->intersubclass,interface->protocol); - if(interface->interclass == 3 && interface->intersubclass == 1 && !usb_dev->type) { - switch(interface->protocol) { - case 2: { - usb_dev->type = USB_TYPE_MOUSE; - break; - } - - case 1: { - usb_dev->type = USB_TYPE_KEYBOARD; - break; - } - } - } - break; - } - - case 0x21: { - xhci_hid_descriptor_t* hid = (xhci_hid_descriptor_t*)current; - for(int i = 0; i < hid->numdesc;i++) { - xhci_hid_sub_desc* desc = &hid->desc[i]; - if(desc->desctype == 0x22) { - - xhci_interface_t* need_interface = usb_dev->interface; - while(need_interface) { - if(need_interface->type = 0x04) - break; - need_interface = need_interface->next; - } - - if(!need_interface) - continue; - - need_interface->buffer = malloc(desc->desclen + 1); - memset(need_interface->buffer,0,desc->desclen + 1); - need_interface->len = desc->desclen; - - xhci_interface_descriptor_t* interface = (xhci_interface_descriptor_t*)need_interface; - - __xhci_set_boot_protocol(dev,usb_dev,interface->num); - __xhci_get_hid_report(dev,usb_dev,0,interface->num,need_interface->buffer,need_interface->len); - - } - } - break; - } - // __xhci_setup_port_ring(256,slotid); - case 0x05: { - xhci_endpoint_descriptor_t* ep = (xhci_endpoint_descriptor_t*)current; - - int idx = ((ep->endpointaddr >> 7) & 1) + ((ep->endpointaddr & 0x0F) << 1); - usb_dev->main_ep = idx; - idx -= 2; - usb_dev->ep_ctx[idx] = __xhci_setup_port_ring(256,usb_dev->slotid); - - usb_dev->buffers_need_size[idx] = ep->maxpacketsize; - - usb_dev->phys_buffers[idx] = liborange_alloc_dma(4096); - usb_dev->buffers[idx] = (uint8_t*)liborange_map_phys(usb_dev->phys_buffers[idx],0,4096); - usb_dev->doorbell_values[idx] = idx + 2; - - if(!context_size) { - xhci_input_ctx_t* input = (xhci_input_ctx_t*)liborange_map_phys(addr,0,4096); - xhci_endpoint_ctx_t* ep1 = &input->ep[idx]; - memset(ep1,0,sizeof(xhci_endpoint_ctx_t)); - usb_dev->input_ctx->input_ctx.A |= (1 << (idx + 2)); - - input->slot.contextentries += 2; - ep1->state = 0; - ep1->endpointtype = __xhci_ep_to_type(ep); - ep1->maxpacketsize = ep->maxpacketsize; - ep1->some_shit_with_long_name_lo = ep->maxpacketsize; - ep1->cerr = 3; - ep1->maxburstsize = 0; - ep1->averagetrblen = ep->maxpacketsize; - ep1->base = usb_dev->ep_ctx[idx]->phys | usb_dev->ep_ctx[idx]->cycle; - uint8_t port_speed = (load_portsc & 0x3C00) >> 10; - uint8_t interval = ep->interval; - uint8_t epty = ep1->endpointtype; - - /* thanks n00byedge for tips */ - - if(port_speed == XHCI_USB_SPEED_HIGH_SPEED || port_speed == XHCI_USB_SPEED_SUPER_SPEED || port_speed == XHCI_USB_SPEED_SUPER_SPEED_PLUS) - ep1->interval = interval - 1; - else if(port_speed == XHCI_USB_SPEED_FULL_SPEED && (epty == XHCI_ENDPOINTTYPE_ISOCHRONOUS_IN || epty == XHCI_ENDPOINTTYPE_ISOCHRONOUS_OUT)) - ep1->interval = interval + 2; - else if((port_speed == XHCI_USB_SPEED_FULL_SPEED || port_speed == XHCI_USB_SPEED_LOW_SPEED) && (epty == XHCI_ENDPOINTTYPE_INTERRUPT_IN || epty == XHCI_ENDPOINTTYPE_INTERRUPT_OUT)) { - ep1->interval = log2(interval) + 4; - } - - - } else { - xhci_input_ctx64_t* input = (xhci_input_ctx64_t*)liborange_map_phys(addr,0,4096); - xhci_endpoint_ctx_t* ep1 = (xhci_endpoint_ctx_t*)(&input->ep[idx]); - memset(ep1,0,sizeof(xhci_endpoint_ctx_t)); - - input->slot.contextentries += 2; - input->input_ctx.A |= (1 << (idx + 2)); - ep1->state = 0; - ep1->endpointtype = __xhci_ep_to_type(ep); - ep1->maxpacketsize = ep->maxpacketsize; - ep1->some_shit_with_long_name_lo = ep->maxpacketsize; - ep1->cerr = 3; - ep1->maxburstsize = 0; - ep1->averagetrblen = ep->maxpacketsize; - ep1->base = (uint64_t)usb_dev->ep_ctx[idx]->phys | usb_dev->ep_ctx[idx]->cycle; - uint8_t port_speed = (load_portsc & 0x3C00) >> 10; - uint8_t interval = ep->interval; - uint8_t epty = ep1->endpointtype; - - if(port_speed == XHCI_USB_SPEED_HIGH_SPEED || port_speed == XHCI_USB_SPEED_SUPER_SPEED || port_speed == XHCI_USB_SPEED_SUPER_SPEED_PLUS) - ep1->interval = interval - 1; - else if(port_speed == XHCI_USB_SPEED_FULL_SPEED && (epty == XHCI_ENDPOINTTYPE_ISOCHRONOUS_IN || epty == XHCI_ENDPOINTTYPE_ISOCHRONOUS_OUT)) - ep1->interval = interval + 2; - else if((port_speed == XHCI_USB_SPEED_FULL_SPEED || port_speed == XHCI_USB_SPEED_LOW_SPEED) && (epty == XHCI_ENDPOINTTYPE_INTERRUPT_IN || epty == XHCI_ENDPOINTTYPE_INTERRUPT_OUT)) { - ep1->interval = log2(interval) + 4; - } - } - - break; - } - } - - i += current->len; - } - - xhci_configure_endpoints_trb_t ep_trb; - memset(&ep_trb,0,sizeof(xhci_trb_t)); - - ep_trb.info_s.type = 12; - ep_trb.base = addr; - ep_trb.info_s.slot = usb_dev->slotid; - - __xhci_clear_event(dev); - - __xhci_command_ring_queue(dev,dev->com_ring,(xhci_trb_t*)&ep_trb); - __xhci_doorbell(dev,0); - usleep(5000); - - xhci_trb_t ret = __xhci_event_wait(dev,TRB_COMMANDCOMPLETIONEVENT_TYPE); - - if(ret.ret_code > 1) { - log(LEVEL_MESSAGE_FAIL,"Can't configure endpoints for port %d (ret %d base %p), context_size: %d, given addr %p\n",portnum,ret.ret_code,ret.base,usb_dev->_is64byte,ep_trb.base); - return; - } else if(ret.ret_code == 0) { - log(LEVEL_MESSAGE_WARN,"Endpoint configure TRB ret_code is 0 (it shouldn't)\n"); - } - - __xhci_ask_for_help_hid(dev,usb_dev); - - usleep(1000); - - log(LEVEL_MESSAGE_INFO,"Found USB%s Device %s (%d, %d, %d) %s %s on port %d and slot %d\n",dev->usb3ports[portnum] == 1 ? "3.0" : "2.0",((load_portsc & 0x3C00) >> 10) < 7 ? speed_to_str[(load_portsc & 0x3C00) >> 10] : "Broken (0 MB/S - USB ?)",(load_portsc & 0x3C00) >> 10,speed,descriptor->maxpacketsize,manufacter,product,portnum,usb_dev->slotid); - -} - -void __xhci_init_ports(xhci_device_t* dev) { - for(int i = 0;i <= dev->max_ports;i++) { - __xhci_init_dev(dev,i); - } -} - -void __xhci_iterate_usb_ports(xhci_device_t* dev) { - - volatile uint32_t* cap = (volatile uint32_t*)(dev->xhci_virt_base + dev->cap->hccparams1.xECP * 4); - - xhci_ext_cap_t load_cap; - load_cap.full = *cap; - //INFO("0x%p\n",cap); - while(1) { - //INFO("Found cap with id %d\n",load_cap.id); - - if(load_cap.id == 2) { - - xhci_usb_cap_t usb_cap; - - usb_cap.firsthalf = cap[0]; - usb_cap.name = cap[1]; - usb_cap.thirdhalf = cap[2]; - usb_cap.fourhalf = cap[3]; - - if(usb_cap.major == 3) { - for(uint8_t i = usb_cap.portoffset - 1;i <= (usb_cap.portoffset - 1) + usb_cap.portcount - 1;i++) { - dev->usb3ports[i] = 1; - //log(LEVEL_MESSAGE_INFO,"Found USB 3.0 Port %d !\n",i); - } - } else { - for(uint8_t i = usb_cap.portoffset - 1;i <= (usb_cap.portoffset - 1) + usb_cap.portcount - 1;i++) { - dev->usb3ports[i] = 0; - //log(LEVEL_MESSAGE_INFO,"Found USB 2.0 Port %d !\n",i); - } - } - - } else if(load_cap.id == 1) { - *((uint32_t*)((uint64_t)cap + 4)) &= ~((1 << 0) | (1 << 13) | (1 << 4) | (1 << 14) | (1 << 15)); - *cap |= (1 << 24); - - usleep(500 * 1000); - - } - - - - if(!load_cap.nextcap) - break; - - - cap = (uint32_t*)((uint64_t)cap + (load_cap.nextcap * 4)); - load_cap.full = *cap; - - } -} - -xhci_hid_driver_t* hid_drv = 0; - -void xhci_hid_register(void (*func)(xhci_usb_device_t* usbdev,xhci_done_trb_t* trb),int type) { - xhci_hid_driver_t* drv = new xhci_hid_driver_t; - drv->func = func; - drv->type = type; - - if(!hid_drv) - hid_drv = drv; - else { - drv->next = hid_drv; - hid_drv = drv; - } -} - -void __xhci_process_fetch(xhci_device_t* dev) { - xhci_event_ring_ctx_t* father = dev->event_ring; - xhci_trb_t* buffer[1024]; - - xhci_usb_device_t* usbdev = usbdevs; - - while(1) { - //Paging::EnableKernel(); - int count = 0; - memset(buffer,0,sizeof(xhci_trb_t*) * 1024); - if(get_trb(father,father->queue).info_s.cycle == father->cycle) - count = __xhci_event_receive(dev,father,buffer); - - if(!count) - sched_yield(); - - if(count) { - xhci_trb_t* current = 0; - for(int i = 0;i < count;i++) { - current = buffer[i]; - switch(current->info_s.type) { - case TRB_TRANSFEREVENT_TYPE: { - xhci_usb_device_t* usbdev = usbdevs; - xhci_done_trb_t* trb = (xhci_done_trb_t*)current; - while(usbdev) { - if(usbdev->dev == dev) { - if(usbdev->slotid == trb->info_s.slot) { - xhci_hid_driver_t* drv = hid_drv; - while(drv) { - if(drv->type == usbdev->type) - drv->func(usbdev,trb); - drv = drv->next; - } - __xhci_ask_for_help_hid(dev,usbdev); - } - } - usbdev = usbdev->next; - } - break; - } - default: { - log(LEVEL_MESSAGE_WARN,"xhci unsupported trb: %d\n",current->info_s.type); - } - } - } - } - - } -} - -void __xhci_device(pci_t pci_dev,uint8_t a, uint8_t b,uint8_t c) { - if(pci_dev.progIF != 0x30) { - //INFO("Current USB device with progIF 0x%p is not XHCI !\n",pci_dev.progIF); - return; - } - - xhci_device_t* dev = (xhci_device_t*)malloc(4096); - memset(dev,0,4096); - - uint32_t usb3_ports = pci_in(a,b,c,0xDC,4); - pci_out(a,b,c,0xD8,usb3_ports,4); - - auto usb2_ports = pci_in(a,b,c,0xD4,4); - pci_out(a,b,c,0xD0,usb2_ports,4); - - uint64_t addr = pci_dev.bar0 & ~4; // clear upper 2 bits - addr |= ((uint64_t)pci_dev.bar1 << 32); - - dev->xhci_phys_base = addr; - dev->xhci_virt_base = (uint64_t)liborange_map_phys(addr,PTE_MMIO,128 * PAGE_SIZE); // map everything - - dev->cap = (xhci_cap_regs_t*)dev->xhci_virt_base; - dev->op = (xhci_op_regs_t*)(dev->xhci_virt_base + dev->cap->caplength); - dev->runtime = (xhci_runtime_regs_t*)(dev->xhci_virt_base + dev->cap->rtsoff); - dev->doorbell = (uint32_t*)(dev->xhci_virt_base + dev->cap->dboff); - - __xhci_put_new_device(dev); - if(dev->op->usbcmd & XHCI_USBCMD_RS) { // wtf how does it running - uint16_t timeout = XHCI_RESET_TIMEOUT; - //INFO("XHCI is already running, stopping it.\n"); - dev->op->usbcmd &= ~(XHCI_USBCMD_RS); - usleep(20 * 1000); - while(!(dev->op->usbsts & (1 << 0))) { - if(!timeout) { - printf("Can't disable XHCI. Ignoring\n"); - return; - } - usleep(20 * 1000); - timeout = timeout - 1; - } - } - //DEBUG("Resetting XHCI device\n"); - __xhci_reset(dev); - - dev->calculated_scratchpad_count = (uint16_t)((dev->cap->hcsparams2.max_scratchpad_hi << 5) | dev->cap->hcsparams2.max_scratchpad_lo); - - uint32_t hcsparams1 = *(uint32_t*)(&dev->cap->hcsparams1); - - dev->max_ports = ((hcsparams1_t*)&hcsparams1)->maxports; - - //INFO("Configuring XHCI OPER\n"); - __xhci_setup_op(dev); - //INFO("Configuring XHCI Runtime\n"); - __xhci_setup_run(dev); - //INFO("Starting XHCI Device\n"); - __xhci_enable(dev); - //INFO("Iterating USB Ports\n"); - __xhci_iterate_usb_ports(dev); - //INFO("Configuring XHCI Ports\n"); - __xhci_init_ports(dev); - - int pid = fork(); - if(pid == 0) - __xhci_process_fetch(dev); - -} - -pci_driver_t pci_drivers[256]; - -char hid_to_ps2_layout[0x48]; - -int input0_fd = 0; -int mouse_fd = 0; - -void hid_layout_init() { - hid_to_ps2_layout[0x04] = 0x1E; - hid_to_ps2_layout[0x05] = 0x30; - hid_to_ps2_layout[0x06] = 0x2E; - hid_to_ps2_layout[0x07] = 0x20; - hid_to_ps2_layout[0x08] = 0x12; - hid_to_ps2_layout[0x09] = 0x21; - hid_to_ps2_layout[0x0A] = 0x22; - hid_to_ps2_layout[0x0B] = 0x23; - hid_to_ps2_layout[0x0C] = 0x17; - hid_to_ps2_layout[0x0D] = 0x24; - hid_to_ps2_layout[0x0E] = 0x25; - hid_to_ps2_layout[0x0F] = 0x26; - hid_to_ps2_layout[0x10] = 0x32; - hid_to_ps2_layout[0x11] = 0x31; - hid_to_ps2_layout[0x12] = 0x18; - hid_to_ps2_layout[0x13] = 0x19; - hid_to_ps2_layout[0x14] = 0x10; - hid_to_ps2_layout[0x15] = 0x13; - hid_to_ps2_layout[0x16] = 0x1F; - hid_to_ps2_layout[0x17] = 0x14; - hid_to_ps2_layout[0x18] = 0x16; - hid_to_ps2_layout[0x19] = 0x2F; - hid_to_ps2_layout[0x1A] = 0x11; - hid_to_ps2_layout[0x1B] = 0x2D; - hid_to_ps2_layout[0x1C] = 0x15; - hid_to_ps2_layout[0x1D] = 0x2C; - hid_to_ps2_layout[0x1E] = 0x02; - hid_to_ps2_layout[0x1F] = 0x03; - hid_to_ps2_layout[0x20] = 0x04; - hid_to_ps2_layout[0x21] = 0x05; - hid_to_ps2_layout[0x22] = 0x06; - hid_to_ps2_layout[0x23] = 0x07; - hid_to_ps2_layout[0x24] = 0x08; - hid_to_ps2_layout[0x25] = 0x09; - hid_to_ps2_layout[0x26] = 0x0A; - hid_to_ps2_layout[0x27] = 0x0B; - hid_to_ps2_layout[0x28] = 0x1C; - hid_to_ps2_layout[0x29] = 0x01; - hid_to_ps2_layout[0x2A] = 0x0E; - hid_to_ps2_layout[0x2B] = 0x0F; - hid_to_ps2_layout[0x2C] = 0x39; - hid_to_ps2_layout[0x2D] = 0x0C; - hid_to_ps2_layout[0x2E] = 0x0D; - hid_to_ps2_layout[0x2F] = 0x1A; - hid_to_ps2_layout[0x30] = 0x1B; - hid_to_ps2_layout[0x31] = 0x2B; - hid_to_ps2_layout[0x32] = 0x2B; - hid_to_ps2_layout[0x33] = 0x27; - hid_to_ps2_layout[0x34] = 0x28; - hid_to_ps2_layout[0x35] = 0x29; - hid_to_ps2_layout[0x36] = 0x33; - hid_to_ps2_layout[0x37] = 0x34; - hid_to_ps2_layout[0x38] = 0x35; - hid_to_ps2_layout[0x39] = 0x3A; - hid_to_ps2_layout[0x3B] = 0x3C; - hid_to_ps2_layout[0x3C] = 0x3D; - hid_to_ps2_layout[0x3D] = 0x3E; - hid_to_ps2_layout[0x3E] = 0x3F; - hid_to_ps2_layout[0x3F] = 0x40; - hid_to_ps2_layout[0x40] = 0x41; - hid_to_ps2_layout[0x41] = 0x42; - hid_to_ps2_layout[0x42] = 0x43; - hid_to_ps2_layout[0x43] = 0x44; - hid_to_ps2_layout[0x44] = 0x57; - hid_to_ps2_layout[0x45] = 0x58; - hid_to_ps2_layout[0x46] = 0x00; - hid_to_ps2_layout[0x47] = 0x46; -} - -void input_send(uint8_t key) { - write(input0_fd,&key,1); -} - -uint8_t hid_mods_to_ps2[8] = { - 0x1D, - 0x2A, - 0x38, - 0x5B, - 0x1D, - 0x36, - 0x38, - 0x5C -}; - -void __usbkeyboard_handler(xhci_usb_device_t* usbdev, xhci_done_trb_t* trb) { - uint8_t* data = usbdev->buffers[trb->info_s.ep_id - 2]; - uint8_t mods = data[0]; - uint8_t prev_mods = usbdev->add_buffer[0]; - - for (int i = 0; i < 8; i++) { - uint8_t mask = 1 << i; - if ((mods & mask) && !(prev_mods & mask)) { - if (i >= 4) input_send(0xE0); - input_send(hid_mods_to_ps2[i]); - } else if (!(mods & mask) && (prev_mods & mask)) { - if (i >= 4) input_send(0xE0); - input_send(hid_mods_to_ps2[i] | 0x80); - } - } - - for (int i = 2; i < 8; i++) { - int isPressed = 0; - for (int j = 2; j < 8; j++) { - if (usbdev->add_buffer[j] == data[i]) { - isPressed = 1; - break; - } - } - if (!isPressed && data[i] != 0) { - if (data[i] < 0x47) { - input_send(hid_to_ps2_layout[data[i]]); - } else if(data[i] == 0x4F) { - input_send(0xE0); - input_send(0x4D); - } else if(data[i] == 0x50) { - input_send(0xE0); - input_send(0x4B); - } else if(data[i] == 0x51) { - input_send(0xE0); - input_send(0x50); - } else if(data[i] == 0x52) { - input_send(0xE0); - input_send(0x48); - } - } - } - - for (int i = 2; i < 8; i++) { - int isStillPressed = 0; - for (int j = 2; j < 8; j++) { - if (usbdev->add_buffer[i] == data[j]) { - isStillPressed = 1; - break; - } - } - if (!isStillPressed && usbdev->add_buffer[i] != 0) { - input_send(hid_to_ps2_layout[usbdev->add_buffer[i]] | 0x80); - } else if(usbdev->add_buffer[i] == 0x4F) { - input_send(0xE0 | 0x80); - input_send(0x4D | 0x80); - } else if(usbdev->add_buffer[i] == 0x50) { - input_send(0xE0 | 0x80); - input_send(0x4B | 0x80); - } else if(usbdev->add_buffer[i] == 0x51) { - input_send(0xE0 | 0x80); - input_send(0x50 | 0x80); - } else if(usbdev->add_buffer[i] == 0x52) { - input_send(0xE0 | 0x80); - input_send(0x48 | 0x80); - } - } - - memcpy(usbdev->add_buffer, data, 8); -} - - -#define MOUSE_LB (1 << 0) -#define MOUSE_RB (1 << 1) -#define MOUSE_MB (1 << 2) -#define MOUSE_B4 (1 << 3) -#define MOUSE_B5 (1 << 4) - -typedef struct { - unsigned char buttons; - unsigned char x; - unsigned char y; - unsigned char z; -} __attribute__((packed)) mouse_packet_t; - -void __usbmouse_handler(xhci_usb_device_t* usbdev, xhci_done_trb_t* trb) { - uint8_t* data = usbdev->buffers[trb->info_s.ep_id - 2]; - - mouse_packet_t packet; - - packet.buttons = 0; - - packet.buttons |= (data[0] & (1 << 0)) ? MOUSE_LB : 0; - packet.buttons |= (data[0] & (1 << 1)) ? MOUSE_RB : 0; - packet.buttons |= (data[0] & (1 << 2)) ? MOUSE_MB : 0; - - packet.x = data[1]; - packet.y = -data[2]; - packet.z = 0; // todo: figure out how to get mouse scroll wheel data - - write(mouse_fd,&packet,4); - - usleep(1000); // actually hid wants this only after 1 ms - -} - -int main() { - liborange_setup_iopl_3(); - - input0_fd = open("/dev/masterps2keyboard",O_RDWR); - mouse_fd = open("/dev/mastermouse",O_RDWR); - - xhci_hid_register(__usbkeyboard_handler,USB_TYPE_KEYBOARD); - xhci_hid_register(__usbmouse_handler,USB_TYPE_MOUSE); - - hid_layout_init(); - - memset(pci_drivers,0,sizeof(pci_drivers)); - pci_reg(pci_drivers,__xhci_device,0x0C,0x03); - pci_initworkspace(pci_drivers); -}
\ No newline at end of file diff --git a/tools/pkg/3/bash/diff/gettext.diff b/tools/pkg/3/bash/diff/gettext.diff deleted file mode 100644 index b5cc4bd..0000000 --- a/tools/pkg/3/bash/diff/gettext.diff +++ /dev/null @@ -1,39 +0,0 @@ -diff --git gettext-clean/gettext-runtime/gnulib-lib/getlocalename_l-unsafe.c gettext-workdir/gettext-runtime/gnulib-lib/getlocalename_l-unsafe.c -index 76dfec6..009f763 100644 ---- gettext-clean/gettext-runtime/gnulib-lib/getlocalename_l-unsafe.c -+++ gettext-workdir/gettext-runtime/gnulib-lib/getlocalename_l-unsafe.c -@@ -488,6 +488,8 @@ getlocalename_l_unsafe (int category, locale_t locale) - struct gl_locale_category_t *plc = - &locale->category[gl_log2_lcmask_to_index (gl_log2_lc_mask (category))]; - return (struct string_with_storage) { plc->name, STORAGE_OBJECT }; -+#elif defined __mlibc__ -+ return (struct string_with_storage) { "C", STORAGE_INDEFINITE }; - #elif __GLIBC__ >= 2 && !defined __UCLIBC__ - /* Work around an incorrect definition of the _NL_LOCALE_NAME macro in - glibc < 2.12. -diff --git gettext-clean/gettext-runtime/intl/gnulib-lib/getlocalename_l-unsafe.c gettext-workdir/gettext-runtime/intl/gnulib-lib/getlocalename_l-unsafe.c -index 76dfec6..009f763 100644 ---- gettext-clean/gettext-runtime/intl/gnulib-lib/getlocalename_l-unsafe.c -+++ gettext-workdir/gettext-runtime/intl/gnulib-lib/getlocalename_l-unsafe.c -@@ -488,6 +488,8 @@ getlocalename_l_unsafe (int category, locale_t locale) - struct gl_locale_category_t *plc = - &locale->category[gl_log2_lcmask_to_index (gl_log2_lc_mask (category))]; - return (struct string_with_storage) { plc->name, STORAGE_OBJECT }; -+#elif defined __mlibc__ -+ return (struct string_with_storage) { "C", STORAGE_INDEFINITE }; - #elif __GLIBC__ >= 2 && !defined __UCLIBC__ - /* Work around an incorrect definition of the _NL_LOCALE_NAME macro in - glibc < 2.12. -diff --git gettext-clean/gettext-tools/gnulib-lib/getlocalename_l-unsafe.c gettext-workdir/gettext-tools/gnulib-lib/getlocalename_l-unsafe.c -index 76dfec6..009f763 100644 ---- gettext-clean/gettext-tools/gnulib-lib/getlocalename_l-unsafe.c -+++ gettext-workdir/gettext-tools/gnulib-lib/getlocalename_l-unsafe.c -@@ -488,6 +488,8 @@ getlocalename_l_unsafe (int category, locale_t locale) - struct gl_locale_category_t *plc = - &locale->category[gl_log2_lcmask_to_index (gl_log2_lc_mask (category))]; - return (struct string_with_storage) { plc->name, STORAGE_OBJECT }; -+#elif defined __mlibc__ -+ return (struct string_with_storage) { "C", STORAGE_INDEFINITE }; - #elif __GLIBC__ >= 2 && !defined __UCLIBC__ - /* Work around an incorrect definition of the _NL_LOCALE_NAME macro in - glibc < 2.12. diff --git a/tools/pkg/3/bash/info.txt b/tools/pkg/3/bash/info.txt deleted file mode 100644 index 75cd71d..0000000 --- a/tools/pkg/3/bash/info.txt +++ /dev/null @@ -1 +0,0 @@ -bash-5.2.21
\ No newline at end of file diff --git a/tools/pkg/3/bash/pkg.sh b/tools/pkg/3/bash/pkg.sh deleted file mode 100644 index b742059..0000000 --- a/tools/pkg/3/bash/pkg.sh +++ /dev/null @@ -1,28 +0,0 @@ -. ../../pkg-lib.sh - -mkdir -p cached - -rm -rf pack - -mkdir -p pack - -cd pack - -# fast_install "$1" $GNU_MIRROR/gnu/libiconv/libiconv-1.18.tar.gz -# fast_install "$1" $GNU_MIRROR/gnu/gettext/gettext-0.26.tar.gz "--enable-shared" ../../diff/gettext.diff - -installgnu bash bash 5.2.21 -mkdir -p bash-build - -cd bash-build -../bash-5.2.21/configure --host=x86_64-linux-gnu --prefix="/usr" --disable-readline --with-curses --without-bash-malloc CFLAGS="-std=gnu17 -fPIC -Os" -make install-strip -j$(nproc) DESTDIR="$1" - -cz=$(pwd) - -cd "$1/usr/bin" -ln -sf bash sh - -cd "$cz" - -cd .. diff --git a/tools/pkg/3/coreutils/diff/coreutils.diff b/tools/pkg/3/coreutils/diff/coreutils.diff deleted file mode 100644 index 095d7bc..0000000 --- a/tools/pkg/3/coreutils/diff/coreutils.diff +++ /dev/null @@ -1,3106 +0,0 @@ -diff -Naur coreutils-9.8/build-aux/config.sub coreutils-patched/build-aux/config.sub ---- coreutils-9.8/build-aux/config.sub 2025-07-22 12:24:32.000000000 +0300 -+++ coreutils-patched/build-aux/config.sub 2026-01-11 10:31:29.166553543 +0300 -@@ -2018,6 +2018,7 @@ - | glidix* \ - | gnu* \ - | go32* \ -+ | orange* \ - | haiku* \ - | hcos* \ - | hiux* \ -diff -Naur coreutils-9.8/build-aux/config.sub.orig coreutils-patched/build-aux/config.sub.orig ---- coreutils-9.8/build-aux/config.sub.orig 1970-01-01 03:00:00.000000000 +0300 -+++ coreutils-patched/build-aux/config.sub.orig 2026-01-11 10:30:24.783333868 +0300 -@@ -0,0 +1,2364 @@ -+#! /bin/sh -+# Configuration validation subroutine script. -+# Copyright 1992-2025 Free Software Foundation, Inc. -+ -+# shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale -+ -+timestamp='2025-07-10' -+ -+# This file is free software; you can redistribute it and/or modify it -+# under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, but -+# WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+# General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, see <https://www.gnu.org/licenses/>. -+# -+# As a special exception to the GNU General Public License, if you -+# distribute this file as part of a program that contains a -+# configuration script generated by Autoconf, you may include it under -+# the same distribution terms that you use for the rest of that -+# program. This Exception is an additional permission under section 7 -+# of the GNU General Public License, version 3 ("GPLv3"). -+ -+ -+# Please send patches to <config-patches@gnu.org>. -+# -+# Configuration subroutine to validate and canonicalize a configuration type. -+# Supply the specified configuration type as an argument. -+# If it is invalid, we print an error message on stderr and exit with code 1. -+# Otherwise, we print the canonical config type on stdout and succeed. -+ -+# You can get the latest version of this script from: -+# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub -+ -+# This file is supposed to be the same for all GNU packages -+# and recognize all the CPU types, system types and aliases -+# that are meaningful with *any* GNU software. -+# Each package is responsible for reporting which valid configurations -+# it does not support. The user should be able to distinguish -+# a failure to support a valid configuration from a meaningless -+# configuration. -+ -+# The goal of this file is to map all the various variations of a given -+# machine specification into a single specification in the form: -+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -+# or in some cases, the newer four-part form: -+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -+# It is wrong to echo any other type of specification. -+ -+# The "shellcheck disable" line above the timestamp inhibits complaints -+# about features and limitations of the classic Bourne shell that were -+# superseded or lifted in POSIX. However, this script identifies a wide -+# variety of pre-POSIX systems that do not have POSIX shells at all, and -+# even some reasonably current systems (Solaris 10 as case-in-point) still -+# have a pre-POSIX /bin/sh. -+ -+me=`echo "$0" | sed -e 's,.*/,,'` -+ -+usage="\ -+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS -+ -+Canonicalize a configuration name. -+ -+Options: -+ -h, --help print this help, then exit -+ -t, --time-stamp print date of last modification, then exit -+ -v, --version print version number, then exit -+ -+Report bugs and patches to <config-patches@gnu.org>." -+ -+version="\ -+GNU config.sub ($timestamp) -+ -+Copyright 1992-2025 Free Software Foundation, Inc. -+ -+This is free software; see the source for copying conditions. There is NO -+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." -+ -+help=" -+Try '$me --help' for more information." -+ -+# Parse command line -+while test $# -gt 0 ; do -+ case $1 in -+ --time-stamp | --time* | -t ) -+ echo "$timestamp" ; exit ;; -+ --version | -v ) -+ echo "$version" ; exit ;; -+ --help | --h* | -h ) -+ echo "$usage"; exit ;; -+ -- ) # Stop option processing -+ shift; break ;; -+ - ) # Use stdin as input. -+ break ;; -+ -* ) -+ echo "$me: invalid option $1$help" >&2 -+ exit 1 ;; -+ -+ *local*) -+ # First pass through any local machine types. -+ echo "$1" -+ exit ;; -+ -+ * ) -+ break ;; -+ esac -+done -+ -+case $# in -+ 0) echo "$me: missing argument$help" >&2 -+ exit 1;; -+ 1) ;; -+ *) echo "$me: too many arguments$help" >&2 -+ exit 1;; -+esac -+ -+# Split fields of configuration type -+saved_IFS=$IFS -+IFS="-" read field1 field2 field3 field4 <<EOF -+$1 -+EOF -+IFS=$saved_IFS -+ -+# Separate into logical components for further validation -+case $1 in -+ *-*-*-*-*) -+ echo "Invalid configuration '$1': more than four components" >&2 -+ exit 1 -+ ;; -+ *-*-*-*) -+ basic_machine=$field1-$field2 -+ basic_os=$field3-$field4 -+ ;; -+ *-*-*) -+ # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two -+ # parts -+ maybe_os=$field2-$field3 -+ case $maybe_os in -+ cloudabi*-eabi* \ -+ | kfreebsd*-gnu* \ -+ | knetbsd*-gnu* \ -+ | kopensolaris*-gnu* \ -+ | ironclad-* \ -+ | linux-* \ -+ | managarm-* \ -+ | netbsd*-eabi* \ -+ | netbsd*-gnu* \ -+ | nto-qnx* \ -+ | os2-emx* \ -+ | rtmk-nova* \ -+ | storm-chaos* \ -+ | uclinux-gnu* \ -+ | uclinux-uclibc* \ -+ | windows-* ) -+ basic_machine=$field1 -+ basic_os=$maybe_os -+ ;; -+ android-linux) -+ basic_machine=$field1-unknown -+ basic_os=linux-android -+ ;; -+ *) -+ basic_machine=$field1-$field2 -+ basic_os=$field3 -+ ;; -+ esac -+ ;; -+ *-*) -+ case $field1-$field2 in -+ # Shorthands that happen to contain a single dash -+ convex-c[12] | convex-c3[248]) -+ basic_machine=$field2-convex -+ basic_os= -+ ;; -+ decstation-3100) -+ basic_machine=mips-dec -+ basic_os= -+ ;; -+ *-*) -+ # Second component is usually, but not always the OS -+ case $field2 in -+ # Do not treat sunos as a manufacturer -+ sun*os*) -+ basic_machine=$field1 -+ basic_os=$field2 -+ ;; -+ # Manufacturers -+ 3100* \ -+ | 32* \ -+ | 3300* \ -+ | 3600* \ -+ | 7300* \ -+ | acorn \ -+ | altos* \ -+ | apollo \ -+ | apple \ -+ | atari \ -+ | att* \ -+ | axis \ -+ | be \ -+ | bull \ -+ | cbm \ -+ | ccur \ -+ | cisco \ -+ | commodore \ -+ | convergent* \ -+ | convex* \ -+ | cray \ -+ | crds \ -+ | dec* \ -+ | delta* \ -+ | dg \ -+ | digital \ -+ | dolphin \ -+ | encore* \ -+ | gould \ -+ | harris \ -+ | highlevel \ -+ | hitachi* \ -+ | hp \ -+ | ibm* \ -+ | intergraph \ -+ | isi* \ -+ | knuth \ -+ | masscomp \ -+ | microblaze* \ -+ | mips* \ -+ | motorola* \ -+ | ncr* \ -+ | news \ -+ | next \ -+ | ns \ -+ | oki \ -+ | omron* \ -+ | pc533* \ -+ | rebel \ -+ | rom68k \ -+ | rombug \ -+ | semi \ -+ | sequent* \ -+ | sgi* \ -+ | siemens \ -+ | sim \ -+ | sni \ -+ | sony* \ -+ | stratus \ -+ | sun \ -+ | sun[234]* \ -+ | tektronix \ -+ | tti* \ -+ | ultra \ -+ | unicom* \ -+ | wec \ -+ | winbond \ -+ | wrs) -+ basic_machine=$field1-$field2 -+ basic_os= -+ ;; -+ tock* | zephyr*) -+ basic_machine=$field1-unknown -+ basic_os=$field2 -+ ;; -+ *) -+ basic_machine=$field1 -+ basic_os=$field2 -+ ;; -+ esac -+ ;; -+ esac -+ ;; -+ *) -+ # Convert single-component short-hands not valid as part of -+ # multi-component configurations. -+ case $field1 in -+ 386bsd) -+ basic_machine=i386-pc -+ basic_os=bsd -+ ;; -+ a29khif) -+ basic_machine=a29k-amd -+ basic_os=udi -+ ;; -+ adobe68k) -+ basic_machine=m68010-adobe -+ basic_os=scout -+ ;; -+ alliant) -+ basic_machine=fx80-alliant -+ basic_os= -+ ;; -+ altos | altos3068) -+ basic_machine=m68k-altos -+ basic_os= -+ ;; -+ am29k) -+ basic_machine=a29k-none -+ basic_os=bsd -+ ;; -+ amdahl) -+ basic_machine=580-amdahl -+ basic_os=sysv -+ ;; -+ amiga) -+ basic_machine=m68k-unknown -+ basic_os= -+ ;; -+ amigaos | amigados) -+ basic_machine=m68k-unknown -+ basic_os=amigaos -+ ;; -+ amigaunix | amix) -+ basic_machine=m68k-unknown -+ basic_os=sysv4 -+ ;; -+ apollo68) -+ basic_machine=m68k-apollo -+ basic_os=sysv -+ ;; -+ apollo68bsd) -+ basic_machine=m68k-apollo -+ basic_os=bsd -+ ;; -+ aros) -+ basic_machine=i386-pc -+ basic_os=aros -+ ;; -+ aux) -+ basic_machine=m68k-apple -+ basic_os=aux -+ ;; -+ balance) -+ basic_machine=ns32k-sequent -+ basic_os=dynix -+ ;; -+ blackfin) -+ basic_machine=bfin-unknown -+ basic_os=linux -+ ;; -+ cegcc) -+ basic_machine=arm-unknown -+ basic_os=cegcc -+ ;; -+ cray) -+ basic_machine=j90-cray -+ basic_os=unicos -+ ;; -+ crds | unos) -+ basic_machine=m68k-crds -+ basic_os= -+ ;; -+ da30) -+ basic_machine=m68k-da30 -+ basic_os= -+ ;; -+ decstation | pmax | pmin | dec3100 | decstatn) -+ basic_machine=mips-dec -+ basic_os= -+ ;; -+ delta88) -+ basic_machine=m88k-motorola -+ basic_os=sysv3 -+ ;; -+ dicos) -+ basic_machine=i686-pc -+ basic_os=dicos -+ ;; -+ djgpp) -+ basic_machine=i586-pc -+ basic_os=msdosdjgpp -+ ;; -+ ebmon29k) -+ basic_machine=a29k-amd -+ basic_os=ebmon -+ ;; -+ es1800 | OSE68k | ose68k | ose | OSE) -+ basic_machine=m68k-ericsson -+ basic_os=ose -+ ;; -+ gmicro) -+ basic_machine=tron-gmicro -+ basic_os=sysv -+ ;; -+ go32) -+ basic_machine=i386-pc -+ basic_os=go32 -+ ;; -+ h8300hms) -+ basic_machine=h8300-hitachi -+ basic_os=hms -+ ;; -+ h8300xray) -+ basic_machine=h8300-hitachi -+ basic_os=xray -+ ;; -+ h8500hms) -+ basic_machine=h8500-hitachi -+ basic_os=hms -+ ;; -+ harris) -+ basic_machine=m88k-harris -+ basic_os=sysv3 -+ ;; -+ hp300 | hp300hpux) -+ basic_machine=m68k-hp -+ basic_os=hpux -+ ;; -+ hp300bsd) -+ basic_machine=m68k-hp -+ basic_os=bsd -+ ;; -+ hppaosf) -+ basic_machine=hppa1.1-hp -+ basic_os=osf -+ ;; -+ hppro) -+ basic_machine=hppa1.1-hp -+ basic_os=proelf -+ ;; -+ i386mach) -+ basic_machine=i386-mach -+ basic_os=mach -+ ;; -+ isi68 | isi) -+ basic_machine=m68k-isi -+ basic_os=sysv -+ ;; -+ m68knommu) -+ basic_machine=m68k-unknown -+ basic_os=linux -+ ;; -+ magnum | m3230) -+ basic_machine=mips-mips -+ basic_os=sysv -+ ;; -+ merlin) -+ basic_machine=ns32k-utek -+ basic_os=sysv -+ ;; -+ mingw64) -+ basic_machine=x86_64-pc -+ basic_os=mingw64 -+ ;; -+ mingw32) -+ basic_machine=i686-pc -+ basic_os=mingw32 -+ ;; -+ mingw32ce) -+ basic_machine=arm-unknown -+ basic_os=mingw32ce -+ ;; -+ monitor) -+ basic_machine=m68k-rom68k -+ basic_os=coff -+ ;; -+ morphos) -+ basic_machine=powerpc-unknown -+ basic_os=morphos -+ ;; -+ moxiebox) -+ basic_machine=moxie-unknown -+ basic_os=moxiebox -+ ;; -+ msdos) -+ basic_machine=i386-pc -+ basic_os=msdos -+ ;; -+ msys) -+ basic_machine=i686-pc -+ basic_os=msys -+ ;; -+ mvs) -+ basic_machine=i370-ibm -+ basic_os=mvs -+ ;; -+ nacl) -+ basic_machine=le32-unknown -+ basic_os=nacl -+ ;; -+ ncr3000) -+ basic_machine=i486-ncr -+ basic_os=sysv4 -+ ;; -+ netbsd386) -+ basic_machine=i386-pc -+ basic_os=netbsd -+ ;; -+ netwinder) -+ basic_machine=armv4l-rebel -+ basic_os=linux -+ ;; -+ news | news700 | news800 | news900) -+ basic_machine=m68k-sony -+ basic_os=newsos -+ ;; -+ news1000) -+ basic_machine=m68030-sony -+ basic_os=newsos -+ ;; -+ necv70) -+ basic_machine=v70-nec -+ basic_os=sysv -+ ;; -+ nh3000) -+ basic_machine=m68k-harris -+ basic_os=cxux -+ ;; -+ nh[45]000) -+ basic_machine=m88k-harris -+ basic_os=cxux -+ ;; -+ nindy960) -+ basic_machine=i960-intel -+ basic_os=nindy -+ ;; -+ mon960) -+ basic_machine=i960-intel -+ basic_os=mon960 -+ ;; -+ nonstopux) -+ basic_machine=mips-compaq -+ basic_os=nonstopux -+ ;; -+ os400) -+ basic_machine=powerpc-ibm -+ basic_os=os400 -+ ;; -+ OSE68000 | ose68000) -+ basic_machine=m68000-ericsson -+ basic_os=ose -+ ;; -+ os68k) -+ basic_machine=m68k-none -+ basic_os=os68k -+ ;; -+ paragon) -+ basic_machine=i860-intel -+ basic_os=osf -+ ;; -+ parisc) -+ basic_machine=hppa-unknown -+ basic_os=linux -+ ;; -+ psp) -+ basic_machine=mipsallegrexel-sony -+ basic_os=psp -+ ;; -+ pw32) -+ basic_machine=i586-unknown -+ basic_os=pw32 -+ ;; -+ rdos | rdos64) -+ basic_machine=x86_64-pc -+ basic_os=rdos -+ ;; -+ rdos32) -+ basic_machine=i386-pc -+ basic_os=rdos -+ ;; -+ rom68k) -+ basic_machine=m68k-rom68k -+ basic_os=coff -+ ;; -+ sa29200) -+ basic_machine=a29k-amd -+ basic_os=udi -+ ;; -+ sei) -+ basic_machine=mips-sei -+ basic_os=seiux -+ ;; -+ sequent) -+ basic_machine=i386-sequent -+ basic_os= -+ ;; -+ sps7) -+ basic_machine=m68k-bull -+ basic_os=sysv2 -+ ;; -+ st2000) -+ basic_machine=m68k-tandem -+ basic_os= -+ ;; -+ stratus) -+ basic_machine=i860-stratus -+ basic_os=sysv4 -+ ;; -+ sun2) -+ basic_machine=m68000-sun -+ basic_os= -+ ;; -+ sun2os3) -+ basic_machine=m68000-sun -+ basic_os=sunos3 -+ ;; -+ sun2os4) -+ basic_machine=m68000-sun -+ basic_os=sunos4 -+ ;; -+ sun3) -+ basic_machine=m68k-sun -+ basic_os= -+ ;; -+ sun3os3) -+ basic_machine=m68k-sun -+ basic_os=sunos3 -+ ;; -+ sun3os4) -+ basic_machine=m68k-sun -+ basic_os=sunos4 -+ ;; -+ sun4) -+ basic_machine=sparc-sun -+ basic_os= -+ ;; -+ sun4os3) -+ basic_machine=sparc-sun -+ basic_os=sunos3 -+ ;; -+ sun4os4) -+ basic_machine=sparc-sun -+ basic_os=sunos4 -+ ;; -+ sun4sol2) -+ basic_machine=sparc-sun -+ basic_os=solaris2 -+ ;; -+ sun386 | sun386i | roadrunner) -+ basic_machine=i386-sun -+ basic_os= -+ ;; -+ sv1) -+ basic_machine=sv1-cray -+ basic_os=unicos -+ ;; -+ symmetry) -+ basic_machine=i386-sequent -+ basic_os=dynix -+ ;; -+ t3e) -+ basic_machine=alphaev5-cray -+ basic_os=unicos -+ ;; -+ t90) -+ basic_machine=t90-cray -+ basic_os=unicos -+ ;; -+ toad1) -+ basic_machine=pdp10-xkl -+ basic_os=tops20 -+ ;; -+ tpf) -+ basic_machine=s390x-ibm -+ basic_os=tpf -+ ;; -+ udi29k) -+ basic_machine=a29k-amd -+ basic_os=udi -+ ;; -+ ultra3) -+ basic_machine=a29k-nyu -+ basic_os=sym1 -+ ;; -+ v810 | necv810) -+ basic_machine=v810-nec -+ basic_os=none -+ ;; -+ vaxv) -+ basic_machine=vax-dec -+ basic_os=sysv -+ ;; -+ vms) -+ basic_machine=vax-dec -+ basic_os=vms -+ ;; -+ vsta) -+ basic_machine=i386-pc -+ basic_os=vsta -+ ;; -+ vxworks960) -+ basic_machine=i960-wrs -+ basic_os=vxworks -+ ;; -+ vxworks68) -+ basic_machine=m68k-wrs -+ basic_os=vxworks -+ ;; -+ vxworks29k) -+ basic_machine=a29k-wrs -+ basic_os=vxworks -+ ;; -+ xbox) -+ basic_machine=i686-pc -+ basic_os=mingw32 -+ ;; -+ ymp) -+ basic_machine=ymp-cray -+ basic_os=unicos -+ ;; -+ *) -+ basic_machine=$1 -+ basic_os= -+ ;; -+ esac -+ ;; -+esac -+ -+# Decode 1-component or ad-hoc basic machines -+case $basic_machine in -+ # Here we handle the default manufacturer of certain CPU types. It is in -+ # some cases the only manufacturer, in others, it is the most popular. -+ w89k) -+ cpu=hppa1.1 -+ vendor=winbond -+ ;; -+ op50n) -+ cpu=hppa1.1 -+ vendor=oki -+ ;; -+ op60c) -+ cpu=hppa1.1 -+ vendor=oki -+ ;; -+ ibm*) -+ cpu=i370 -+ vendor=ibm -+ ;; -+ orion105) -+ cpu=clipper -+ vendor=highlevel -+ ;; -+ mac | mpw | mac-mpw) -+ cpu=m68k -+ vendor=apple -+ ;; -+ pmac | pmac-mpw) -+ cpu=powerpc -+ vendor=apple -+ ;; -+ -+ # Recognize the various machine names and aliases which stand -+ # for a CPU type and a company and sometimes even an OS. -+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) -+ cpu=m68000 -+ vendor=att -+ ;; -+ 3b*) -+ cpu=we32k -+ vendor=att -+ ;; -+ bluegene*) -+ cpu=powerpc -+ vendor=ibm -+ basic_os=cnk -+ ;; -+ decsystem10* | dec10*) -+ cpu=pdp10 -+ vendor=dec -+ basic_os=tops10 -+ ;; -+ decsystem20* | dec20*) -+ cpu=pdp10 -+ vendor=dec -+ basic_os=tops20 -+ ;; -+ delta | 3300 | delta-motorola | 3300-motorola | motorola-delta | motorola-3300) -+ cpu=m68k -+ vendor=motorola -+ ;; -+ # This used to be dpx2*, but that gets the RS6000-based -+ # DPX/20 and the x86-based DPX/2-100 wrong. See -+ # https://oldskool.silicium.org/stations/bull_dpx20.htm -+ # https://www.feb-patrimoine.com/english/bull_dpx2.htm -+ # https://www.feb-patrimoine.com/english/unix_and_bull.htm -+ dpx2 | dpx2[23]00 | dpx2[23]xx) -+ cpu=m68k -+ vendor=bull -+ ;; -+ dpx2100 | dpx21xx) -+ cpu=i386 -+ vendor=bull -+ ;; -+ dpx20) -+ cpu=rs6000 -+ vendor=bull -+ ;; -+ encore | umax | mmax) -+ cpu=ns32k -+ vendor=encore -+ ;; -+ elxsi) -+ cpu=elxsi -+ vendor=elxsi -+ basic_os=${basic_os:-bsd} -+ ;; -+ fx2800) -+ cpu=i860 -+ vendor=alliant -+ ;; -+ genix) -+ cpu=ns32k -+ vendor=ns -+ ;; -+ h3050r* | hiux*) -+ cpu=hppa1.1 -+ vendor=hitachi -+ basic_os=hiuxwe2 -+ ;; -+ hp3k9[0-9][0-9] | hp9[0-9][0-9]) -+ cpu=hppa1.0 -+ vendor=hp -+ ;; -+ hp9k2[0-9][0-9] | hp9k31[0-9]) -+ cpu=m68000 -+ vendor=hp -+ ;; -+ hp9k3[2-9][0-9]) -+ cpu=m68k -+ vendor=hp -+ ;; -+ hp9k6[0-9][0-9] | hp6[0-9][0-9]) -+ cpu=hppa1.0 -+ vendor=hp -+ ;; -+ hp9k7[0-79][0-9] | hp7[0-79][0-9]) -+ cpu=hppa1.1 -+ vendor=hp -+ ;; -+ hp9k78[0-9] | hp78[0-9]) -+ # FIXME: really hppa2.0-hp -+ cpu=hppa1.1 -+ vendor=hp -+ ;; -+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) -+ # FIXME: really hppa2.0-hp -+ cpu=hppa1.1 -+ vendor=hp -+ ;; -+ hp9k8[0-9][13679] | hp8[0-9][13679]) -+ cpu=hppa1.1 -+ vendor=hp -+ ;; -+ hp9k8[0-9][0-9] | hp8[0-9][0-9]) -+ cpu=hppa1.0 -+ vendor=hp -+ ;; -+ i*86v32) -+ cpu=`echo "$1" | sed -e 's/86.*/86/'` -+ vendor=pc -+ basic_os=sysv32 -+ ;; -+ i*86v4*) -+ cpu=`echo "$1" | sed -e 's/86.*/86/'` -+ vendor=pc -+ basic_os=sysv4 -+ ;; -+ i*86v) -+ cpu=`echo "$1" | sed -e 's/86.*/86/'` -+ vendor=pc -+ basic_os=sysv -+ ;; -+ i*86sol2) -+ cpu=`echo "$1" | sed -e 's/86.*/86/'` -+ vendor=pc -+ basic_os=solaris2 -+ ;; -+ j90 | j90-cray) -+ cpu=j90 -+ vendor=cray -+ basic_os=${basic_os:-unicos} -+ ;; -+ iris | iris4d) -+ cpu=mips -+ vendor=sgi -+ case $basic_os in -+ irix*) -+ ;; -+ *) -+ basic_os=irix4 -+ ;; -+ esac -+ ;; -+ miniframe) -+ cpu=m68000 -+ vendor=convergent -+ ;; -+ *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) -+ cpu=m68k -+ vendor=atari -+ basic_os=mint -+ ;; -+ news-3600 | risc-news) -+ cpu=mips -+ vendor=sony -+ basic_os=newsos -+ ;; -+ next | m*-next) -+ cpu=m68k -+ vendor=next -+ ;; -+ np1) -+ cpu=np1 -+ vendor=gould -+ ;; -+ op50n-* | op60c-*) -+ cpu=hppa1.1 -+ vendor=oki -+ basic_os=proelf -+ ;; -+ pa-hitachi) -+ cpu=hppa1.1 -+ vendor=hitachi -+ basic_os=hiuxwe2 -+ ;; -+ pbd) -+ cpu=sparc -+ vendor=tti -+ ;; -+ pbb) -+ cpu=m68k -+ vendor=tti -+ ;; -+ pc532) -+ cpu=ns32k -+ vendor=pc532 -+ ;; -+ pn) -+ cpu=pn -+ vendor=gould -+ ;; -+ power) -+ cpu=power -+ vendor=ibm -+ ;; -+ ps2) -+ cpu=i386 -+ vendor=ibm -+ ;; -+ rm[46]00) -+ cpu=mips -+ vendor=siemens -+ ;; -+ rtpc | rtpc-*) -+ cpu=romp -+ vendor=ibm -+ ;; -+ sde) -+ cpu=mipsisa32 -+ vendor=sde -+ basic_os=${basic_os:-elf} -+ ;; -+ simso-wrs) -+ cpu=sparclite -+ vendor=wrs -+ basic_os=vxworks -+ ;; -+ tower | tower-32) -+ cpu=m68k -+ vendor=ncr -+ ;; -+ vpp*|vx|vx-*) -+ cpu=f301 -+ vendor=fujitsu -+ ;; -+ w65) -+ cpu=w65 -+ vendor=wdc -+ ;; -+ w89k-*) -+ cpu=hppa1.1 -+ vendor=winbond -+ basic_os=proelf -+ ;; -+ none) -+ cpu=none -+ vendor=none -+ ;; -+ leon|leon[3-9]) -+ cpu=sparc -+ vendor=$basic_machine -+ ;; -+ leon-*|leon[3-9]-*) -+ cpu=sparc -+ vendor=`echo "$basic_machine" | sed 's/-.*//'` -+ ;; -+ -+ *-*) -+ saved_IFS=$IFS -+ IFS="-" read cpu vendor <<EOF -+$basic_machine -+EOF -+ IFS=$saved_IFS -+ ;; -+ # We use 'pc' rather than 'unknown' -+ # because (1) that's what they normally are, and -+ # (2) the word "unknown" tends to confuse beginning users. -+ i*86 | x86_64) -+ cpu=$basic_machine -+ vendor=pc -+ ;; -+ # These rules are duplicated from below for sake of the special case above; -+ # i.e. things that normalized to x86 arches should also default to "pc" -+ pc98) -+ cpu=i386 -+ vendor=pc -+ ;; -+ x64 | amd64) -+ cpu=x86_64 -+ vendor=pc -+ ;; -+ # Recognize the basic CPU types without company name. -+ *) -+ cpu=$basic_machine -+ vendor=unknown -+ ;; -+esac -+ -+unset -v basic_machine -+ -+# Decode basic machines in the full and proper CPU-Company form. -+case $cpu-$vendor in -+ # Here we handle the default manufacturer of certain CPU types in canonical form. -+ # It is in some cases the only manufacturer, in others, it is the most popular. -+ c[12]-convex | c[12]-unknown | c3[248]-convex | c3[248]-unknown) -+ vendor=convex -+ basic_os=${basic_os:-bsd} -+ ;; -+ craynv-unknown) -+ vendor=cray -+ basic_os=${basic_os:-unicosmp} -+ ;; -+ c90-unknown | c90-cray) -+ vendor=cray -+ basic_os=${basic_os:-unicos} -+ ;; -+ fx80-unknown) -+ vendor=alliant -+ ;; -+ romp-unknown) -+ vendor=ibm -+ ;; -+ mmix-unknown) -+ vendor=knuth -+ ;; -+ microblaze-unknown | microblazeel-unknown) -+ vendor=xilinx -+ ;; -+ rs6000-unknown) -+ vendor=ibm -+ ;; -+ vax-unknown) -+ vendor=dec -+ ;; -+ pdp11-unknown) -+ vendor=dec -+ ;; -+ we32k-unknown) -+ vendor=att -+ ;; -+ cydra-unknown) -+ vendor=cydrome -+ ;; -+ i370-ibm*) -+ vendor=ibm -+ ;; -+ orion-unknown) -+ vendor=highlevel -+ ;; -+ xps-unknown | xps100-unknown) -+ cpu=xps100 -+ vendor=honeywell -+ ;; -+ -+ # Here we normalize CPU types with a missing or matching vendor -+ armh-unknown | armh-alt) -+ cpu=armv7l -+ vendor=alt -+ basic_os=${basic_os:-linux-gnueabihf} -+ ;; -+ -+ # Normalized CPU+vendor pairs that imply an OS, if not otherwise specified -+ m68k-isi) -+ basic_os=${basic_os:-sysv} -+ ;; -+ m68k-sony) -+ basic_os=${basic_os:-newsos} -+ ;; -+ m68k-tektronix) -+ basic_os=${basic_os:-bsd} -+ ;; -+ m88k-harris) -+ basic_os=${basic_os:-sysv3} -+ ;; -+ i386-bull | m68k-bull) -+ basic_os=${basic_os:-sysv3} -+ ;; -+ rs6000-bull) -+ basic_os=${basic_os:-bosx} -+ ;; -+ mips-sni) -+ basic_os=${basic_os:-sysv4} -+ ;; -+ -+ # Here we normalize CPU types irrespective of the vendor -+ amd64-*) -+ cpu=x86_64 -+ ;; -+ blackfin-*) -+ cpu=bfin -+ basic_os=${basic_os:-linux} -+ ;; -+ c54x-*) -+ cpu=tic54x -+ ;; -+ c55x-*) -+ cpu=tic55x -+ ;; -+ c6x-*) -+ cpu=tic6x -+ ;; -+ e500v[12]-*) -+ cpu=powerpc -+ basic_os=${basic_os}"spe" -+ ;; -+ mips3*-*) -+ cpu=mips64 -+ ;; -+ ms1-*) -+ cpu=mt -+ ;; -+ m68knommu-*) -+ cpu=m68k -+ basic_os=${basic_os:-linux} -+ ;; -+ m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*) -+ cpu=s12z -+ ;; -+ openrisc-*) -+ cpu=or32 -+ ;; -+ parisc-*) -+ cpu=hppa -+ basic_os=${basic_os:-linux} -+ ;; -+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) -+ cpu=i586 -+ ;; -+ pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*) -+ cpu=i686 -+ ;; -+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) -+ cpu=i686 -+ ;; -+ pentium4-*) -+ cpu=i786 -+ ;; -+ ppc-* | ppcbe-*) -+ cpu=powerpc -+ ;; -+ ppcle-* | powerpclittle-*) -+ cpu=powerpcle -+ ;; -+ ppc64-*) -+ cpu=powerpc64 -+ ;; -+ ppc64le-* | powerpc64little-*) -+ cpu=powerpc64le -+ ;; -+ sb1-*) -+ cpu=mipsisa64sb1 -+ ;; -+ sb1el-*) -+ cpu=mipsisa64sb1el -+ ;; -+ sh5e[lb]-*) -+ cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'` -+ ;; -+ spur-*) -+ cpu=spur -+ ;; -+ strongarm-* | thumb-*) -+ cpu=arm -+ ;; -+ tx39-*) -+ cpu=mipstx39 -+ ;; -+ tx39el-*) -+ cpu=mipstx39el -+ ;; -+ xscale-* | xscalee[bl]-*) -+ cpu=`echo "$cpu" | sed 's/^xscale/arm/'` -+ ;; -+ arm64-* | aarch64le-* | arm64_32-*) -+ cpu=aarch64 -+ ;; -+ -+ # Recognize the canonical CPU Types that limit and/or modify the -+ # company names they are paired with. -+ cr16-*) -+ basic_os=${basic_os:-elf} -+ ;; -+ crisv32-* | etraxfs*-*) -+ cpu=crisv32 -+ vendor=axis -+ ;; -+ cris-* | etrax*-*) -+ cpu=cris -+ vendor=axis -+ ;; -+ crx-*) -+ basic_os=${basic_os:-elf} -+ ;; -+ neo-tandem) -+ cpu=neo -+ vendor=tandem -+ ;; -+ nse-tandem) -+ cpu=nse -+ vendor=tandem -+ ;; -+ nsr-tandem) -+ cpu=nsr -+ vendor=tandem -+ ;; -+ nsv-tandem) -+ cpu=nsv -+ vendor=tandem -+ ;; -+ nsx-tandem) -+ cpu=nsx -+ vendor=tandem -+ ;; -+ mipsallegrexel-sony) -+ cpu=mipsallegrexel -+ vendor=sony -+ ;; -+ tile*-*) -+ basic_os=${basic_os:-linux-gnu} -+ ;; -+ -+ *) -+ # Recognize the canonical CPU types that are allowed with any -+ # company name. -+ case $cpu in -+ 1750a \ -+ | 580 \ -+ | [cjt]90 \ -+ | a29k \ -+ | aarch64 \ -+ | aarch64_be \ -+ | aarch64c \ -+ | abacus \ -+ | alpha \ -+ | alpha64 \ -+ | alpha64ev56 \ -+ | alpha64ev6[78] \ -+ | alpha64ev[4-8] \ -+ | alpha64pca5[67] \ -+ | alphaev56 \ -+ | alphaev6[78] \ -+ | alphaev[4-8] \ -+ | alphapca5[67] \ -+ | am33_2.0 \ -+ | amdgcn \ -+ | arc \ -+ | arc32 \ -+ | arc64 \ -+ | arceb \ -+ | arm \ -+ | arm64e \ -+ | arm64ec \ -+ | arm[lb]e \ -+ | arme[lb] \ -+ | armv* \ -+ | asmjs \ -+ | avr \ -+ | avr32 \ -+ | ba \ -+ | be32 \ -+ | be64 \ -+ | bfin \ -+ | bpf \ -+ | bs2000 \ -+ | c30 \ -+ | c4x \ -+ | c8051 \ -+ | c[123]* \ -+ | clipper \ -+ | craynv \ -+ | csky \ -+ | cydra \ -+ | d10v \ -+ | d30v \ -+ | dlx \ -+ | dsp16xx \ -+ | e2k \ -+ | elxsi \ -+ | epiphany \ -+ | f30[01] \ -+ | f700 \ -+ | fido \ -+ | fr30 \ -+ | frv \ -+ | ft32 \ -+ | fx80 \ -+ | h8300 \ -+ | h8500 \ -+ | hexagon \ -+ | hppa \ -+ | hppa1.[01] \ -+ | hppa2.0 \ -+ | hppa2.0[nw] \ -+ | hppa64 \ -+ | i*86 \ -+ | i370 \ -+ | i860 \ -+ | i960 \ -+ | ia16 \ -+ | ia64 \ -+ | intelgt \ -+ | ip2k \ -+ | iq2000 \ -+ | javascript \ -+ | k1om \ -+ | kvx \ -+ | le32 \ -+ | le64 \ -+ | lm32 \ -+ | loongarch32 \ -+ | loongarch64 \ -+ | m32c \ -+ | m32r \ -+ | m32rle \ -+ | m5200 \ -+ | m68000 \ -+ | m680[012346]0 \ -+ | m6811 \ -+ | m6812 \ -+ | m68360 \ -+ | m683?2 \ -+ | m68hc11 \ -+ | m68hc12 \ -+ | m68hcs12x \ -+ | m68k \ -+ | m88110 \ -+ | m88k \ -+ | maxq \ -+ | mb \ -+ | mcore \ -+ | mep \ -+ | metag \ -+ | microblaze \ -+ | microblazeel \ -+ | mips* \ -+ | mmix \ -+ | mn10200 \ -+ | mn10300 \ -+ | moxie \ -+ | msp430 \ -+ | mt \ -+ | nanomips* \ -+ | nds32 \ -+ | nds32be \ -+ | nds32le \ -+ | nfp \ -+ | nios \ -+ | nios2 \ -+ | nios2eb \ -+ | nios2el \ -+ | none \ -+ | np1 \ -+ | ns16k \ -+ | ns32k \ -+ | nvptx \ -+ | open8 \ -+ | or1k* \ -+ | or32 \ -+ | orion \ -+ | pdp10 \ -+ | pdp11 \ -+ | picochip \ -+ | pj \ -+ | pjl \ -+ | pn \ -+ | power \ -+ | powerpc \ -+ | powerpc64 \ -+ | powerpc64le \ -+ | powerpcle \ -+ | powerpcspe \ -+ | pru \ -+ | pyramid \ -+ | riscv \ -+ | riscv32 \ -+ | riscv32be \ -+ | riscv64 \ -+ | riscv64be \ -+ | rl78 \ -+ | romp \ -+ | rs6000 \ -+ | rx \ -+ | s390 \ -+ | s390x \ -+ | score \ -+ | sh \ -+ | sh64 \ -+ | sh64le \ -+ | sh[12345][lb]e \ -+ | sh[1234] \ -+ | sh[1234]e[lb] \ -+ | sh[23]e \ -+ | sh[23]ele \ -+ | sh[24]a \ -+ | sh[24]ae[lb] \ -+ | sh[lb]e \ -+ | she[lb] \ -+ | shl \ -+ | sparc \ -+ | sparc64 \ -+ | sparc64b \ -+ | sparc64v \ -+ | sparc86x \ -+ | sparclet \ -+ | sparclite \ -+ | sparcv8 \ -+ | sparcv9 \ -+ | sparcv9b \ -+ | sparcv9v \ -+ | spu \ -+ | sv1 \ -+ | sx* \ -+ | tahoe \ -+ | thumbv7* \ -+ | tic30 \ -+ | tic4x \ -+ | tic54x \ -+ | tic55x \ -+ | tic6x \ -+ | tic80 \ -+ | tron \ -+ | ubicom32 \ -+ | v70 \ -+ | v810 \ -+ | v850 \ -+ | v850e \ -+ | v850e1 \ -+ | v850e2 \ -+ | v850e2v3 \ -+ | v850es \ -+ | vax \ -+ | vc4 \ -+ | visium \ -+ | w65 \ -+ | wasm32 \ -+ | wasm64 \ -+ | we32k \ -+ | x86 \ -+ | x86_64 \ -+ | xc16x \ -+ | xgate \ -+ | xps100 \ -+ | xstormy16 \ -+ | xtensa* \ -+ | ymp \ -+ | z80 \ -+ | z8k) -+ ;; -+ -+ *) -+ echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2 -+ exit 1 -+ ;; -+ esac -+ ;; -+esac -+ -+# Here we canonicalize certain aliases for manufacturers. -+case $vendor in -+ digital*) -+ vendor=dec -+ ;; -+ commodore*) -+ vendor=cbm -+ ;; -+ *) -+ ;; -+esac -+ -+# Decode manufacturer-specific aliases for certain operating systems. -+ -+if test x"$basic_os" != x -+then -+ -+# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just -+# set os. -+obj= -+case $basic_os in -+ gnu/linux*) -+ kernel=linux -+ os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` -+ ;; -+ os2-emx) -+ kernel=os2 -+ os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` -+ ;; -+ nto-qnx*) -+ kernel=nto -+ os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` -+ ;; -+ *-*) -+ saved_IFS=$IFS -+ IFS="-" read kernel os <<EOF -+$basic_os -+EOF -+ IFS=$saved_IFS -+ ;; -+ # Default OS when just kernel was specified -+ nto*) -+ kernel=nto -+ os=`echo "$basic_os" | sed -e 's|nto|qnx|'` -+ ;; -+ ironclad*) -+ kernel=ironclad -+ os=`echo "$basic_os" | sed -e 's|ironclad|mlibc|'` -+ ;; -+ linux*) -+ kernel=linux -+ os=`echo "$basic_os" | sed -e 's|linux|gnu|'` -+ ;; -+ managarm*) -+ kernel=managarm -+ os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'` -+ ;; -+ *) -+ kernel= -+ os=$basic_os -+ ;; -+esac -+ -+# Now, normalize the OS (knowing we just have one component, it's not a kernel, -+# etc.) -+case $os in -+ # First match some system type aliases that might get confused -+ # with valid system types. -+ # solaris* is a basic system type, with this one exception. -+ auroraux) -+ os=auroraux -+ ;; -+ bluegene*) -+ os=cnk -+ ;; -+ solaris1 | solaris1.*) -+ os=`echo "$os" | sed -e 's|solaris1|sunos4|'` -+ ;; -+ solaris) -+ os=solaris2 -+ ;; -+ unixware*) -+ os=sysv4.2uw -+ ;; -+ # The marketing names for NeXT's operating systems were -+ # NeXTSTEP, NeXTSTEP 2, OpenSTEP 3, OpenSTEP 4. 'openstep' is -+ # mapped to 'openstep3', but 'openstep1' and 'openstep2' are -+ # mapped to 'nextstep' and 'nextstep2', consistent with the -+ # treatment of SunOS/Solaris. -+ ns | ns1 | nextstep | nextstep1 | openstep1) -+ os=nextstep -+ ;; -+ ns2 | nextstep2 | openstep2) -+ os=nextstep2 -+ ;; -+ ns3 | nextstep3 | openstep | openstep3) -+ os=openstep3 -+ ;; -+ ns4 | nextstep4 | openstep4) -+ os=openstep4 -+ ;; -+ # es1800 is here to avoid being matched by es* (a different OS) -+ es1800*) -+ os=ose -+ ;; -+ # Some version numbers need modification -+ chorusos*) -+ os=chorusos -+ ;; -+ isc) -+ os=isc2.2 -+ ;; -+ sco6) -+ os=sco5v6 -+ ;; -+ sco5) -+ os=sco3.2v5 -+ ;; -+ sco4) -+ os=sco3.2v4 -+ ;; -+ sco3.2.[4-9]*) -+ os=`echo "$os" | sed -e 's/sco3.2./sco3.2v/'` -+ ;; -+ sco*v* | scout) -+ # Don't match below -+ ;; -+ sco*) -+ os=sco3.2v2 -+ ;; -+ psos*) -+ os=psos -+ ;; -+ qnx*) -+ os=qnx -+ ;; -+ hiux*) -+ os=hiuxwe2 -+ ;; -+ lynx*178) -+ os=lynxos178 -+ ;; -+ lynx*5) -+ os=lynxos5 -+ ;; -+ lynxos*) -+ # don't get caught up in next wildcard -+ ;; -+ lynx*) -+ os=lynxos -+ ;; -+ mac[0-9]*) -+ os=`echo "$os" | sed -e 's|mac|macos|'` -+ ;; -+ opened*) -+ os=openedition -+ ;; -+ os400*) -+ os=os400 -+ ;; -+ sunos5*) -+ os=`echo "$os" | sed -e 's|sunos5|solaris2|'` -+ ;; -+ sunos6*) -+ os=`echo "$os" | sed -e 's|sunos6|solaris3|'` -+ ;; -+ wince*) -+ os=wince -+ ;; -+ utek*) -+ os=bsd -+ vendor=`echo "$vendor" | sed -e 's|^unknown$|tektronix|'` -+ ;; -+ dynix*) -+ os=bsd -+ ;; -+ acis*) -+ os=aos -+ ;; -+ atheos*) -+ os=atheos -+ ;; -+ syllable*) -+ os=syllable -+ ;; -+ 386bsd) -+ os=bsd -+ ;; -+ ctix*) -+ os=sysv -+ vendor=`echo "$vendor" | sed -e 's|^unknown$|convergent|'` -+ ;; -+ uts*) -+ os=sysv -+ ;; -+ nova*) -+ kernel=rtmk -+ os=nova -+ ;; -+ # Preserve the version number of sinix5. -+ sinix5.*) -+ os=`echo "$os" | sed -e 's|sinix|sysv|'` -+ vendor=`echo "$vendor" | sed -e 's|^unknown$|sni|'` -+ ;; -+ sinix*) -+ os=sysv4 -+ vendor=`echo "$vendor" | sed -e 's|^unknown$|sni|'` -+ ;; -+ tpf*) -+ os=tpf -+ ;; -+ triton*) -+ os=sysv3 -+ ;; -+ oss*) -+ os=sysv3 -+ ;; -+ svr4*) -+ os=sysv4 -+ ;; -+ svr3) -+ os=sysv3 -+ ;; -+ sysvr4) -+ os=sysv4 -+ ;; -+ ose*) -+ os=ose -+ ;; -+ *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) -+ os=mint -+ ;; -+ dicos*) -+ os=dicos -+ ;; -+ pikeos*) -+ # Until real need of OS specific support for -+ # particular features comes up, bare metal -+ # configurations are quite functional. -+ case $cpu in -+ arm*) -+ os=eabi -+ ;; -+ *) -+ os= -+ obj=elf -+ ;; -+ esac -+ ;; -+ aout* | coff* | elf* | pe*) -+ # These are machine code file formats, not OSes -+ obj=$os -+ os= -+ ;; -+ *) -+ # No normalization, but not necessarily accepted, that comes below. -+ ;; -+esac -+ -+else -+ -+# Here we handle the default operating systems that come with various machines. -+# The value should be what the vendor currently ships out the door with their -+# machine or put another way, the most popular os provided with the machine. -+ -+# Note that if you're going to try to match "-MANUFACTURER" here (say, -+# "-sun"), then you have to tell the case statement up towards the top -+# that MANUFACTURER isn't an operating system. Otherwise, code above -+# will signal an error saying that MANUFACTURER isn't an operating -+# system, and we'll never get to this point. -+ -+kernel= -+obj= -+case $cpu-$vendor in -+ score-*) -+ os= -+ obj=elf -+ ;; -+ spu-*) -+ os= -+ obj=elf -+ ;; -+ *-acorn) -+ os=riscix1.2 -+ ;; -+ arm*-rebel) -+ kernel=linux -+ os=gnu -+ ;; -+ arm*-semi) -+ os= -+ obj=aout -+ ;; -+ c4x-* | tic4x-*) -+ os= -+ obj=coff -+ ;; -+ c8051-*) -+ os= -+ obj=elf -+ ;; -+ clipper-intergraph) -+ os=clix -+ ;; -+ hexagon-*) -+ os= -+ obj=elf -+ ;; -+ tic54x-*) -+ os= -+ obj=coff -+ ;; -+ tic55x-*) -+ os= -+ obj=coff -+ ;; -+ tic6x-*) -+ os= -+ obj=coff -+ ;; -+ # This must come before the *-dec entry. -+ pdp10-*) -+ os=tops20 -+ ;; -+ pdp11-*) -+ os=none -+ ;; -+ *-dec | vax-*) -+ os=ultrix4.2 -+ ;; -+ m68*-apollo) -+ os=domain -+ ;; -+ i386-sun) -+ os=sunos4.0.2 -+ ;; -+ m68000-sun) -+ os=sunos3 -+ ;; -+ m68*-cisco) -+ os= -+ obj=aout -+ ;; -+ mep-*) -+ os= -+ obj=elf -+ ;; -+ # The -sgi and -siemens entries must be before the mips- entry -+ # or we get the wrong os. -+ *-sgi) -+ os=irix -+ ;; -+ *-siemens) -+ os=sysv4 -+ ;; -+ mips*-cisco) -+ os= -+ obj=elf -+ ;; -+ mips*-*|nanomips*-*) -+ os= -+ obj=elf -+ ;; -+ or32-*) -+ os= -+ obj=coff -+ ;; -+ # This must be before the sparc-* entry or we get the wrong os. -+ *-tti) -+ os=sysv3 -+ ;; -+ sparc-* | *-sun) -+ os=sunos4.1.1 -+ ;; -+ pru-*) -+ os= -+ obj=elf -+ ;; -+ *-be) -+ os=beos -+ ;; -+ *-ibm) -+ os=aix -+ ;; -+ *-knuth) -+ os=mmixware -+ ;; -+ *-wec) -+ os=proelf -+ ;; -+ *-winbond) -+ os=proelf -+ ;; -+ *-oki) -+ os=proelf -+ ;; -+ *-hp) -+ os=hpux -+ ;; -+ *-hitachi) -+ os=hiuxwe2 -+ ;; -+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) -+ os=sysv -+ ;; -+ *-cbm) -+ os=amigaos -+ ;; -+ *-dg) -+ os=dgux -+ ;; -+ *-dolphin) -+ os=sysv3 -+ ;; -+ m68k-ccur) -+ os=rtu -+ ;; -+ m88k-omron*) -+ os=luna -+ ;; -+ *-next) -+ os=nextstep -+ ;; -+ *-sequent) -+ os=ptx -+ ;; -+ *-crds) -+ os=unos -+ ;; -+ *-ns) -+ os=genix -+ ;; -+ i370-*) -+ os=mvs -+ ;; -+ *-gould) -+ os=sysv -+ ;; -+ *-highlevel) -+ os=bsd -+ ;; -+ *-encore) -+ os=bsd -+ ;; -+ *-masscomp) -+ os=rtu -+ ;; -+ f30[01]-fujitsu | f700-fujitsu) -+ os=uxpv -+ ;; -+ *-rom68k) -+ os= -+ obj=coff -+ ;; -+ *-*bug) -+ os= -+ obj=coff -+ ;; -+ *-apple) -+ os=macos -+ ;; -+ *-atari*) -+ os=mint -+ ;; -+ *-wrs) -+ os=vxworks -+ ;; -+ *) -+ os=none -+ ;; -+esac -+ -+fi -+ -+# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ). -+ -+case $os in -+ # Sometimes we do "kernel-libc", so those need to count as OSes. -+ llvm* | musl* | newlib* | relibc* | uclibc*) -+ ;; -+ # Likewise for "kernel-abi" -+ eabi* | gnueabi*) -+ ;; -+ # VxWorks passes extra cpu info in the 4th filed. -+ simlinux | simwindows | spe) -+ ;; -+ # See `case $cpu-$os` validation below -+ ghcjs) -+ ;; -+ # Now accept the basic system types. -+ # Each alternative MUST end in a * to match a version number. -+ abug \ -+ | aix* \ -+ | amdhsa* \ -+ | amigados* \ -+ | amigaos* \ -+ | android* \ -+ | aof* \ -+ | aos* \ -+ | aros* \ -+ | atheos* \ -+ | auroraux* \ -+ | aux* \ -+ | banan_os* \ -+ | beos* \ -+ | bitrig* \ -+ | bme* \ -+ | bosx* \ -+ | bsd* \ -+ | cegcc* \ -+ | chorusos* \ -+ | chorusrdb* \ -+ | clix* \ -+ | cloudabi* \ -+ | cnk* \ -+ | conix* \ -+ | cos* \ -+ | cxux* \ -+ | cygwin* \ -+ | darwin* \ -+ | dgux* \ -+ | dicos* \ -+ | dnix* \ -+ | domain* \ -+ | dragonfly* \ -+ | drops* \ -+ | ebmon* \ -+ | ecoff* \ -+ | ekkobsd* \ -+ | emscripten* \ -+ | emx* \ -+ | es* \ -+ | fiwix* \ -+ | freebsd* \ -+ | fuchsia* \ -+ | genix* \ -+ | genode* \ -+ | glidix* \ -+ | gnu* \ -+ | go32* \ -+ | haiku* \ -+ | hcos* \ -+ | hiux* \ -+ | hms* \ -+ | hpux* \ -+ | ieee* \ -+ | interix* \ -+ | ios* \ -+ | iris* \ -+ | irix* \ -+ | isc* \ -+ | its* \ -+ | l4re* \ -+ | libertybsd* \ -+ | lites* \ -+ | lnews* \ -+ | luna* \ -+ | lynxos* \ -+ | mach* \ -+ | macos* \ -+ | magic* \ -+ | mbr* \ -+ | midipix* \ -+ | midnightbsd* \ -+ | mingw32* \ -+ | mingw64* \ -+ | minix* \ -+ | mint* \ -+ | mirbsd* \ -+ | mks* \ -+ | mlibc* \ -+ | mmixware* \ -+ | mon960* \ -+ | morphos* \ -+ | moss* \ -+ | moxiebox* \ -+ | mpeix* \ -+ | mpw* \ -+ | msdos* \ -+ | msys* \ -+ | mvs* \ -+ | nacl* \ -+ | netbsd* \ -+ | netware* \ -+ | newsos* \ -+ | nextstep* \ -+ | nindy* \ -+ | nonstopux* \ -+ | nova* \ -+ | nsk* \ -+ | nucleus* \ -+ | nx6 \ -+ | nx7 \ -+ | oabi* \ -+ | ohos* \ -+ | onefs* \ -+ | openbsd* \ -+ | openedition* \ -+ | openstep* \ -+ | os108* \ -+ | os2* \ -+ | os400* \ -+ | os68k* \ -+ | os9* \ -+ | ose* \ -+ | osf* \ -+ | oskit* \ -+ | osx* \ -+ | palmos* \ -+ | phoenix* \ -+ | plan9* \ -+ | powermax* \ -+ | powerunix* \ -+ | proelf* \ -+ | psos* \ -+ | psp* \ -+ | ptx* \ -+ | pw32* \ -+ | qnx* \ -+ | rdos* \ -+ | redox* \ -+ | rhapsody* \ -+ | riscix* \ -+ | riscos* \ -+ | rtems* \ -+ | rtmk* \ -+ | rtu* \ -+ | scout* \ -+ | secbsd* \ -+ | sei* \ -+ | serenity* \ -+ | sim* \ -+ | skyos* \ -+ | solaris* \ -+ | solidbsd* \ -+ | sortix* \ -+ | storm-chaos* \ -+ | sunos \ -+ | sunos[34]* \ -+ | superux* \ -+ | syllable* \ -+ | sym* \ -+ | sysv* \ -+ | tenex* \ -+ | tirtos* \ -+ | tock* \ -+ | toppers* \ -+ | tops10* \ -+ | tops20* \ -+ | tpf* \ -+ | tvos* \ -+ | twizzler* \ -+ | uclinux* \ -+ | udi* \ -+ | udk* \ -+ | ultrix* \ -+ | unicos* \ -+ | uniplus* \ -+ | unleashed* \ -+ | unos* \ -+ | uwin* \ -+ | uxpv* \ -+ | v88r* \ -+ |*vms* \ -+ | vos* \ -+ | vsta* \ -+ | vxsim* \ -+ | vxworks* \ -+ | wasi* \ -+ | watchos* \ -+ | wince* \ -+ | windiss* \ -+ | windows* \ -+ | winnt* \ -+ | xenix* \ -+ | xray* \ -+ | zephyr* \ -+ | zvmoe* ) -+ ;; -+ # This one is extra strict with allowed versions -+ sco3.2v2 | sco3.2v[4-9]* | sco5v6*) -+ # Don't forget version if it is 3.2v4 or newer. -+ ;; -+ # This refers to builds using the UEFI calling convention -+ # (which depends on the architecture) and PE file format. -+ # Note that this is both a different calling convention and -+ # different file format than that of GNU-EFI -+ # (x86_64-w64-mingw32). -+ uefi) -+ ;; -+ none) -+ ;; -+ kernel* | msvc* ) -+ # Restricted further below -+ ;; -+ '') -+ if test x"$obj" = x -+ then -+ echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2 -+ fi -+ ;; -+ *) -+ echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 -+ exit 1 -+ ;; -+esac -+ -+case $obj in -+ aout* | coff* | elf* | pe*) -+ ;; -+ '') -+ # empty is fine -+ ;; -+ *) -+ echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 -+ exit 1 -+ ;; -+esac -+ -+# Here we handle the constraint that a (synthetic) cpu and os are -+# valid only in combination with each other and nowhere else. -+case $cpu-$os in -+ # The "javascript-unknown-ghcjs" triple is used by GHC; we -+ # accept it here in order to tolerate that, but reject any -+ # variations. -+ javascript-ghcjs) -+ ;; -+ javascript-* | *-ghcjs) -+ echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 -+ exit 1 -+ ;; -+esac -+ -+# As a final step for OS-related things, validate the OS-kernel combination -+# (given a valid OS), if there is a kernel. -+case $kernel-$os-$obj in -+ linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ -+ | linux-mlibc*- | linux-musl*- | linux-newlib*- \ -+ | linux-relibc*- | linux-uclibc*- | linux-ohos*- ) -+ ;; -+ uclinux-uclibc*- | uclinux-gnu*- ) -+ ;; -+ ironclad-mlibc*-) -+ ;; -+ managarm-mlibc*- | managarm-kernel*- ) -+ ;; -+ windows*-msvc*-) -+ ;; -+ -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ -+ | -uclibc*- ) -+ # These are just libc implementations, not actual OSes, and thus -+ # require a kernel. -+ echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 -+ exit 1 -+ ;; -+ -kernel*- ) -+ echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 -+ exit 1 -+ ;; -+ *-kernel*- ) -+ echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 -+ exit 1 -+ ;; -+ *-msvc*- ) -+ echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 -+ exit 1 -+ ;; -+ kfreebsd*-gnu*- | knetbsd*-gnu*- | netbsd*-gnu*- | kopensolaris*-gnu*-) -+ ;; -+ vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) -+ ;; -+ nto-qnx*-) -+ ;; -+ os2-emx-) -+ ;; -+ rtmk-nova-) -+ ;; -+ *-eabi*- | *-gnueabi*-) -+ ;; -+ ios*-simulator- | tvos*-simulator- | watchos*-simulator- ) -+ ;; -+ none--*) -+ # None (no kernel, i.e. freestanding / bare metal), -+ # can be paired with an machine code file format -+ ;; -+ -*-) -+ # Blank kernel with real OS is always fine. -+ ;; -+ --*) -+ # Blank kernel and OS with real machine code file format is always fine. -+ ;; -+ *-*-*) -+ echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 -+ exit 1 -+ ;; -+esac -+ -+# Here we handle the case where we know the os, and the CPU type, but not the -+# manufacturer. We pick the logical manufacturer. -+case $vendor in -+ unknown) -+ case $cpu-$os in -+ *-riscix*) -+ vendor=acorn -+ ;; -+ *-sunos* | *-solaris*) -+ vendor=sun -+ ;; -+ *-cnk* | *-aix*) -+ vendor=ibm -+ ;; -+ *-beos*) -+ vendor=be -+ ;; -+ *-hpux*) -+ vendor=hp -+ ;; -+ *-mpeix*) -+ vendor=hp -+ ;; -+ *-hiux*) -+ vendor=hitachi -+ ;; -+ *-unos*) -+ vendor=crds -+ ;; -+ *-dgux*) -+ vendor=dg -+ ;; -+ *-luna*) -+ vendor=omron -+ ;; -+ *-genix*) -+ vendor=ns -+ ;; -+ *-clix*) -+ vendor=intergraph -+ ;; -+ *-mvs* | *-opened*) -+ vendor=ibm -+ ;; -+ *-os400*) -+ vendor=ibm -+ ;; -+ s390-* | s390x-*) -+ vendor=ibm -+ ;; -+ *-ptx*) -+ vendor=sequent -+ ;; -+ *-tpf*) -+ vendor=ibm -+ ;; -+ *-vxsim* | *-vxworks* | *-windiss*) -+ vendor=wrs -+ ;; -+ *-aux*) -+ vendor=apple -+ ;; -+ *-hms*) -+ vendor=hitachi -+ ;; -+ *-mpw* | *-macos*) -+ vendor=apple -+ ;; -+ *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) -+ vendor=atari -+ ;; -+ *-vos*) -+ vendor=stratus -+ ;; -+ esac -+ ;; -+esac -+ -+echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" -+exit -+ -+# Local variables: -+# eval: (add-hook 'before-save-hook 'time-stamp nil t) -+# time-stamp-start: "timestamp='" -+# time-stamp-format: "%Y-%02m-%02d" -+# time-stamp-end: "'" -+# End: -diff -Naur coreutils-9.8/lib/getlocalename_l-unsafe.c coreutils-patched/lib/getlocalename_l-unsafe.c ---- coreutils-9.8/lib/getlocalename_l-unsafe.c 2025-08-19 18:57:38.000000000 +0300 -+++ coreutils-patched/lib/getlocalename_l-unsafe.c 2026-01-11 10:32:23.467416529 +0300 -@@ -473,6 +473,10 @@ - struct gl_locale_category_t *plc = - &locale->category[gl_log2_lcmask_to_index (gl_log2_lc_mask (category))]; - return (struct string_with_storage) { plc->name, STORAGE_OBJECT }; -+#elif defined __mlibc__ -+ return (struct string_with_storage) { "C", STORAGE_INDEFINITE }; -+#elif defined __orange__ -+ return (struct string_with_storage) { "C", STORAGE_INDEFINITE }; - #elif __GLIBC__ >= 2 && !defined __UCLIBC__ - /* Work around an incorrect definition of the _NL_LOCALE_NAME macro in - glibc < 2.12. -diff -Naur coreutils-9.8/lib/getlocalename_l-unsafe.c.orig coreutils-patched/lib/getlocalename_l-unsafe.c.orig ---- coreutils-9.8/lib/getlocalename_l-unsafe.c.orig 1970-01-01 03:00:00.000000000 +0300 -+++ coreutils-patched/lib/getlocalename_l-unsafe.c.orig 2026-01-11 10:30:24.816335009 +0300 -@@ -0,0 +1,695 @@ -+/* Return name of a single locale category. -+ Copyright (C) 1995-2025 Free Software Foundation, Inc. -+ -+ This file is free software: you can redistribute it and/or modify -+ it under the terms of the GNU Lesser General Public License as -+ published by the Free Software Foundation; either version 2.1 of the -+ License, or (at your option) any later version. -+ -+ This file is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public License -+ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -+ -+/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc -+ optimizes away the locale == NULL tests below. */ -+#define _GL_ARG_NONNULL(params) -+ -+#include <config.h> -+ -+/* Specification. */ -+#include "getlocalename_l-unsafe.h" -+ -+#include <locale.h> -+#include <limits.h> -+#include <stddef.h> -+#include <stdlib.h> -+#include <string.h> -+ -+#if LC_MESSAGES == 1729 || defined __ANDROID__ -+# include "setlocale-fixes.h" -+#endif -+#include "setlocale_null.h" -+ -+#if (__GLIBC__ >= 2 && !defined __UCLIBC__) || (defined __linux__ && HAVE_LANGINFO_H) || defined __CYGWIN__ -+# include <langinfo.h> -+#endif -+#if defined __sun -+# if HAVE_SOLARIS114_LOCALES -+# include <sys/localedef.h> -+# endif -+#endif -+#if HAVE_NAMELESS_LOCALES -+# include "localename-table.h" -+#endif -+#if defined __HAIKU__ -+# include <dlfcn.h> -+#endif -+ -+ -+#if LOCALENAME_ENHANCE_LOCALE_FUNCS -+ -+# include "flexmember.h" -+# include "glthread/lock.h" -+# include "thread-optim.h" -+ -+/* Define a local struniq() function. */ -+# include "struniq.h" -+ -+/* The 'locale_t' object does not contain the names of the locale categories. -+ We have to associate them with the object through a hash table. -+ The hash table is defined in localename-table.[hc]. */ -+ -+/* Returns the name of a given locale category in a given locale_t object. */ -+static struct string_with_storage -+get_locale_t_name_unsafe (int category, locale_t locale) -+{ -+ if (category == LC_ALL) -+ /* Invalid argument. */ -+ abort (); -+ if (locale == LC_GLOBAL_LOCALE) -+ { -+ /* Query the global locale. */ -+ const char *name = setlocale_null (category); -+ if (name != NULL) -+ return (struct string_with_storage) { name, STORAGE_GLOBAL }; -+ else -+ /* Should normally not happen. */ -+ return (struct string_with_storage) { "", STORAGE_INDEFINITE }; -+ } -+ else -+ { -+# if HAVE_AIX72_LOCALES -+ if (category == LC_MESSAGES) -+ { -+ const char *name = ((__locale_t) locale)->locale_name; -+ if (name != NULL) -+ return (struct string_with_storage) { name, STORAGE_OBJECT }; -+ } -+# endif -+ /* Look up the names in the hash table. */ -+ size_t hashcode = locale_hash_function (locale); -+ size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE; -+ /* If the locale was not found in the table, return "". This can -+ happen if the application uses the original newlocale()/duplocale() -+ functions instead of the overridden ones. */ -+ const char *name = ""; -+ struct locale_hash_node *p; -+ /* Lock while looking up the hash node. */ -+ gl_rwlock_rdlock (locale_lock); -+ for (p = locale_hash_table[slot]; p != NULL; p = p->next) -+ if (p->locale == locale) -+ { -+ name = p->names.category_name[category - LCMIN]; -+ break; -+ } -+ gl_rwlock_unlock (locale_lock); -+ return (struct string_with_storage) { name, STORAGE_INDEFINITE }; -+ } -+} -+ -+/* Returns the name of a given locale category in a given locale_t object, -+ allocated as a string with indefinite extent. */ -+static const char * -+get_locale_t_name (int category, locale_t locale) -+{ -+ struct string_with_storage ret = get_locale_t_name_unsafe (category, locale); -+ return (ret.storage != STORAGE_INDEFINITE -+ ? struniq (ret.value) -+ : ret.value); -+} -+ -+# if !(defined newlocale && defined duplocale && defined freelocale) -+# error "newlocale, duplocale, freelocale not being replaced as expected!" -+# endif -+ -+/* newlocale() override. */ -+locale_t -+newlocale (int category_mask, const char *name, locale_t base) -+#undef newlocale -+{ -+ struct locale_categories_names names; -+ struct locale_hash_node *node; -+ locale_t result; -+ -+ /* Make sure name has indefinite extent. */ -+ if (((LC_CTYPE_MASK | LC_NUMERIC_MASK | LC_TIME_MASK | LC_COLLATE_MASK -+ | LC_MONETARY_MASK | LC_MESSAGES_MASK) -+ & category_mask) != 0) -+ name = struniq (name); -+ -+ /* Determine the category names of the result. */ -+ if (((LC_CTYPE_MASK | LC_NUMERIC_MASK | LC_TIME_MASK | LC_COLLATE_MASK -+ | LC_MONETARY_MASK | LC_MESSAGES_MASK) -+ & ~category_mask) == 0) -+ { -+ /* Use name, ignore base. */ -+ int i; -+ -+ name = struniq (name); -+ for (i = 0; i < 6; i++) -+ names.category_name[i] = name; -+ } -+ else -+ { -+ /* Use base, possibly also name. */ -+ if (base == NULL) -+ { -+ int i; -+ -+ for (i = 0; i < 6; i++) -+ { -+ int category = i + LCMIN; -+ int mask; -+ -+ switch (category) -+ { -+ case LC_CTYPE: -+ mask = LC_CTYPE_MASK; -+ break; -+ case LC_NUMERIC: -+ mask = LC_NUMERIC_MASK; -+ break; -+ case LC_TIME: -+ mask = LC_TIME_MASK; -+ break; -+ case LC_COLLATE: -+ mask = LC_COLLATE_MASK; -+ break; -+ case LC_MONETARY: -+ mask = LC_MONETARY_MASK; -+ break; -+ case LC_MESSAGES: -+ mask = LC_MESSAGES_MASK; -+ break; -+ default: -+ abort (); -+ } -+ names.category_name[i] = -+ ((mask & category_mask) != 0 ? name : "C"); -+ } -+ } -+ else if (base == LC_GLOBAL_LOCALE) -+ { -+ int i; -+ -+ for (i = 0; i < 6; i++) -+ { -+ int category = i + LCMIN; -+ int mask; -+ -+ switch (category) -+ { -+ case LC_CTYPE: -+ mask = LC_CTYPE_MASK; -+ break; -+ case LC_NUMERIC: -+ mask = LC_NUMERIC_MASK; -+ break; -+ case LC_TIME: -+ mask = LC_TIME_MASK; -+ break; -+ case LC_COLLATE: -+ mask = LC_COLLATE_MASK; -+ break; -+ case LC_MONETARY: -+ mask = LC_MONETARY_MASK; -+ break; -+ case LC_MESSAGES: -+ mask = LC_MESSAGES_MASK; -+ break; -+ default: -+ abort (); -+ } -+ names.category_name[i] = -+ ((mask & category_mask) != 0 -+ ? name -+ : get_locale_t_name (category, LC_GLOBAL_LOCALE)); -+ } -+ } -+ else -+ { -+ /* Look up the names of base in the hash table. Like multiple calls -+ of get_locale_t_name, but locking only once. */ -+ struct locale_hash_node *p; -+ -+ /* Lock while looking up the hash node. */ -+ gl_rwlock_rdlock (locale_lock); -+ for (p = locale_hash_table[locale_hash_function (base) % LOCALE_HASH_TABLE_SIZE]; -+ p != NULL; -+ p = p->next) -+ if (p->locale == base) -+ break; -+ -+ int i; -+ for (i = 0; i < 6; i++) -+ { -+ int category = i + LCMIN; -+ int mask; -+ -+ switch (category) -+ { -+ case LC_CTYPE: -+ mask = LC_CTYPE_MASK; -+ break; -+ case LC_NUMERIC: -+ mask = LC_NUMERIC_MASK; -+ break; -+ case LC_TIME: -+ mask = LC_TIME_MASK; -+ break; -+ case LC_COLLATE: -+ mask = LC_COLLATE_MASK; -+ break; -+ case LC_MONETARY: -+ mask = LC_MONETARY_MASK; -+ break; -+ case LC_MESSAGES: -+ mask = LC_MESSAGES_MASK; -+ break; -+ default: -+ abort (); -+ } -+ names.category_name[i] = -+ ((mask & category_mask) != 0 -+ ? name -+ : (p != NULL ? p->names.category_name[i] : "")); -+ } -+ -+ gl_rwlock_unlock (locale_lock); -+ } -+ } -+ -+ node = (struct locale_hash_node *) malloc (sizeof (struct locale_hash_node)); -+ if (node == NULL) -+ /* errno is set to ENOMEM. */ -+ return NULL; -+ -+ result = newlocale (category_mask, name, base); -+ if (result == NULL) -+ { -+ free (node); -+ return NULL; -+ } -+ -+ /* Fill the hash node. */ -+ node->locale = result; -+ node->names = names; -+ -+ /* Insert it in the hash table. */ -+ { -+ size_t hashcode = locale_hash_function (result); -+ size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE; -+ struct locale_hash_node *p; -+ -+ /* Lock while inserting the new node. */ -+ gl_rwlock_wrlock (locale_lock); -+ for (p = locale_hash_table[slot]; p != NULL; p = p->next) -+ if (p->locale == result) -+ { -+ /* This can happen if the application uses the original freelocale() -+ function instead of the overridden one. */ -+ p->names = node->names; -+ break; -+ } -+ if (p == NULL) -+ { -+ node->next = locale_hash_table[slot]; -+ locale_hash_table[slot] = node; -+ } -+ -+ gl_rwlock_unlock (locale_lock); -+ -+ if (p != NULL) -+ free (node); -+ } -+ -+ return result; -+} -+ -+/* duplocale() override. */ -+locale_t -+duplocale (locale_t locale) -+#undef duplocale -+{ -+ struct locale_hash_node *node; -+ locale_t result; -+ -+ if (locale == NULL) -+ /* Invalid argument. */ -+ abort (); -+ -+ node = (struct locale_hash_node *) malloc (sizeof (struct locale_hash_node)); -+ if (node == NULL) -+ /* errno is set to ENOMEM. */ -+ return NULL; -+ -+ result = duplocale (locale); -+ if (result == NULL) -+ { -+ free (node); -+ return NULL; -+ } -+ -+ /* Fill the hash node. */ -+ node->locale = result; -+ if (locale == LC_GLOBAL_LOCALE) -+ { -+ int i; -+ -+ for (i = 0; i < 6; i++) -+ { -+ int category = i + LCMIN; -+ node->names.category_name[i] = -+ get_locale_t_name (category, LC_GLOBAL_LOCALE); -+ } -+ -+ /* Lock before inserting the new node. */ -+ gl_rwlock_wrlock (locale_lock); -+ } -+ else -+ { -+ struct locale_hash_node *p; -+ -+ /* Lock once, for the lookup and the insertion. */ -+ gl_rwlock_wrlock (locale_lock); -+ -+ for (p = locale_hash_table[locale_hash_function (locale) % LOCALE_HASH_TABLE_SIZE]; -+ p != NULL; -+ p = p->next) -+ if (p->locale == locale) -+ break; -+ if (p != NULL) -+ node->names = p->names; -+ else -+ { -+ /* This can happen if the application uses the original -+ newlocale()/duplocale() functions instead of the overridden -+ ones. */ -+ int i; -+ -+ for (i = 0; i < 6; i++) -+ node->names.category_name[i] = ""; -+ } -+ } -+ -+ /* Insert it in the hash table. */ -+ { -+ size_t hashcode = locale_hash_function (result); -+ size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE; -+ struct locale_hash_node *p; -+ -+ for (p = locale_hash_table[slot]; p != NULL; p = p->next) -+ if (p->locale == result) -+ { -+ /* This can happen if the application uses the original freelocale() -+ function instead of the overridden one. */ -+ p->names = node->names; -+ break; -+ } -+ if (p == NULL) -+ { -+ node->next = locale_hash_table[slot]; -+ locale_hash_table[slot] = node; -+ } -+ -+ gl_rwlock_unlock (locale_lock); -+ -+ if (p != NULL) -+ free (node); -+ } -+ -+ return result; -+} -+ -+/* freelocale() override. */ -+void -+freelocale (locale_t locale) -+#undef freelocale -+{ -+ if (locale == NULL || locale == LC_GLOBAL_LOCALE) -+ /* Invalid argument. */ -+ abort (); -+ -+ { -+ size_t hashcode = locale_hash_function (locale); -+ size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE; -+ struct locale_hash_node *found; -+ struct locale_hash_node **p; -+ -+ found = NULL; -+ /* Lock while removing the hash node. */ -+ gl_rwlock_wrlock (locale_lock); -+ for (p = &locale_hash_table[slot]; *p != NULL; p = &(*p)->next) -+ if ((*p)->locale == locale) -+ { -+ found = *p; -+ *p = (*p)->next; -+ break; -+ } -+ gl_rwlock_unlock (locale_lock); -+ free (found); -+ } -+ -+ freelocale (locale); -+} -+ -+#endif -+ -+ -+struct string_with_storage -+getlocalename_l_unsafe (int category, locale_t locale) -+{ -+ if (category == LC_ALL) -+ /* Unsupported in this simple implementation. */ -+ abort (); -+ -+ if (locale != LC_GLOBAL_LOCALE) -+ { -+#if GNULIB_defined_locale_t -+ struct gl_locale_category_t *plc = -+ &locale->category[gl_log2_lcmask_to_index (gl_log2_lc_mask (category))]; -+ return (struct string_with_storage) { plc->name, STORAGE_OBJECT }; -+#elif __GLIBC__ >= 2 && !defined __UCLIBC__ -+ /* Work around an incorrect definition of the _NL_LOCALE_NAME macro in -+ glibc < 2.12. -+ See <https://sourceware.org/PR10968>. */ -+ const char *name = -+ nl_langinfo_l (_NL_ITEM ((category), _NL_ITEM_INDEX (-1)), locale); -+ if (name[0] == '\0') -+ /* Fallback code for glibc < 2.4, which did not implement -+ nl_langinfo_l (_NL_LOCALE_NAME (category), locale). */ -+ name = locale->__names[category]; -+ return (struct string_with_storage) { name, STORAGE_OBJECT }; -+#elif defined __linux__ && HAVE_LANGINFO_H && defined NL_LOCALE_NAME -+ /* musl libc */ -+ const char *name = nl_langinfo_l (NL_LOCALE_NAME (category), locale); -+ return (struct string_with_storage) { name, STORAGE_OBJECT }; -+#elif (defined __FreeBSD__ || defined __DragonFly__) || (defined __APPLE__ && defined __MACH__) -+ /* FreeBSD >= 9.1, Mac OS X */ -+ int mask; -+ -+ switch (category) -+ { -+ case LC_CTYPE: -+ mask = LC_CTYPE_MASK; -+ break; -+ case LC_NUMERIC: -+ mask = LC_NUMERIC_MASK; -+ break; -+ case LC_TIME: -+ mask = LC_TIME_MASK; -+ break; -+ case LC_COLLATE: -+ mask = LC_COLLATE_MASK; -+ break; -+ case LC_MONETARY: -+ mask = LC_MONETARY_MASK; -+ break; -+ case LC_MESSAGES: -+ mask = LC_MESSAGES_MASK; -+ break; -+ default: /* We shouldn't get here. */ -+ return (struct string_with_storage) { "", STORAGE_INDEFINITE }; -+ } -+ const char *name = querylocale (mask, locale); -+ return (struct string_with_storage) { name, STORAGE_OBJECT }; -+#elif defined __NetBSD__ -+ /* NetBSD >= 7.0 */ -+ #define _LOCALENAME_LEN_MAX 33 -+ struct _locale { -+ void *cache; -+ char query[_LOCALENAME_LEN_MAX * 6]; -+ const char *part_name[7]; -+ }; -+ const char *name = ((struct _locale *) locale)->part_name[category]; -+ return (struct string_with_storage) { name, STORAGE_OBJECT }; -+#elif defined __sun -+# if HAVE_SOLARIS114_LOCALES -+ /* Solaris >= 11.4. */ -+ void *lcp = (*locale)->core.data->lcp; -+ if (lcp != NULL) -+ switch (category) -+ { -+ case LC_CTYPE: -+ case LC_NUMERIC: -+ case LC_TIME: -+ case LC_COLLATE: -+ case LC_MONETARY: -+ case LC_MESSAGES: -+ { -+ const char *name = ((const char * const *) lcp)[category]; -+ return (struct string_with_storage) { name, STORAGE_OBJECT }; -+ } -+ default: /* We shouldn't get here. */ -+ return (struct string_with_storage) { "", STORAGE_INDEFINITE }; -+ } -+ /* We shouldn't get here. */ -+ return (struct string_with_storage) { "", STORAGE_INDEFINITE }; -+# else -+ /* Solaris 11 OpenIndiana or Solaris 11 OmniOS. */ -+# if HAVE_GETLOCALENAME_L -+ /* illumos after April 2025. */ -+# undef getlocalename_l -+ const char *name = getlocalename_l (category, locale); -+ return (struct string_with_storage) { name, STORAGE_OBJECT }; -+# else -+ /* For the internal structure of locale objects, see -+ https://github.com/OpenIndiana/illumos-gate/blob/master/usr/src/lib/libc/port/locale/localeimpl.h */ -+ switch (category) -+ { -+ case LC_CTYPE: -+ case LC_NUMERIC: -+ case LC_TIME: -+ case LC_COLLATE: -+ case LC_MONETARY: -+ case LC_MESSAGES: -+ { -+ const char *name = ((const char * const *) locale)[category]; -+ return (struct string_with_storage) { name, STORAGE_OBJECT }; -+ } -+ default: /* We shouldn't get here. */ -+ return (struct string_with_storage) { "", STORAGE_INDEFINITE }; -+ } -+# endif -+# endif -+#elif HAVE_NAMELESS_LOCALES -+ /* OpenBSD >= 6.2, AIX >= 7.1 */ -+ return get_locale_t_name_unsafe (category, locale); -+#elif defined __OpenBSD__ && HAVE_FAKE_LOCALES -+ /* OpenBSD >= 6.2 has only fake locales. */ -+ if (locale == (locale_t) 2) -+ return (struct string_with_storage) { "C.UTF-8", STORAGE_INDEFINITE }; -+ return (struct string_with_storage) { "C", STORAGE_INDEFINITE }; -+#elif defined __CYGWIN__ -+ /* Cygwin >= 2.6. -+ Cygwin <= 2.6.1 lacks NL_LOCALE_NAME, requiring peeking inside -+ an opaque struct. */ -+# ifdef NL_LOCALE_NAME -+ const char *name = nl_langinfo_l (NL_LOCALE_NAME (category), locale); -+# else -+ /* FIXME: Remove when we can assume new-enough Cygwin. */ -+ struct __locale_t { -+ char categories[7][32]; -+ }; -+ const char *name = ((struct __locale_t *) locale)->categories[category]; -+# endif -+ return (struct string_with_storage) { name, STORAGE_OBJECT }; -+#elif defined __HAIKU__ -+ /* Since 2022, Haiku has per-thread locales. locale_t is 'void *', -+ but in fact a 'LocaleBackendData *'. */ -+ struct LocaleBackendData { -+ int magic; -+ void /*BPrivate::Libroot::LocaleBackend*/ *backend; -+ void /*BPrivate::Libroot::LocaleDataBridge*/ *databridge; -+ }; -+ void *locale_backend = -+ ((struct LocaleBackendData *) locale)->backend; -+ if (locale_backend != NULL) -+ { -+ /* The only existing concrete subclass of -+ BPrivate::Libroot::LocaleBackend is -+ BPrivate::Libroot::ICULocaleBackend. -+ Invoke the (non-virtual) method -+ BPrivate::Libroot::ICULocaleBackend::_QueryLocale on it. -+ This method is located in a separate shared library, -+ libroot-addon-icu.so. */ -+ static void * volatile querylocale_method /* = NULL */; -+ static int volatile querylocale_found /* = 0 */; -+ /* Attempt to open this shared library, the first time we get -+ here. */ -+ if (querylocale_found == 0) -+ { -+ void *handle = -+ dlopen ("/boot/system/lib/libroot-addon-icu.so", 0); -+ if (handle != NULL) -+ { -+ void *sym = -+ dlsym (handle, "_ZN8BPrivate7Libroot16ICULocaleBackend12_QueryLocaleEi"); -+ if (sym != NULL) -+ { -+ querylocale_method = sym; -+ querylocale_found = 1; -+ } -+ else -+ /* Could not find the symbol. */ -+ querylocale_found = -1; -+ } -+ else -+ /* Could not open the separate shared library. */ -+ querylocale_found = -1; -+ } -+ if (querylocale_found > 0) -+ { -+ /* The _QueryLocale method is a non-static C++ method with -+ parameters (int category) and return type 'const char *'. -+ See -+ haiku/headers/private/libroot/locale/ICULocaleBackend.h -+ haiku/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp -+ This is the same as a C function with parameters -+ (BPrivate::Libroot::LocaleBackend* this, int category) -+ and return type 'const char *'. Invoke it. */ -+ const char * (*querylocale_func) (void *, int) = -+ (const char * (*) (void *, int)) querylocale_method; -+ const char *name = querylocale_func (locale_backend, category); -+ return (struct string_with_storage) { name, STORAGE_OBJECT }; -+ } -+ } -+ else -+ /* It's the "C" or "POSIX" locale. */ -+ return (struct string_with_storage) { "C", STORAGE_INDEFINITE }; -+#elif defined __ANDROID__ -+ /* Android API level >= 21 */ -+ struct __locale_t { -+ size_t mb_cur_max; -+ }; -+ const char *name = ((struct __locale_t *) locale)->mb_cur_max == 4 ? "C.UTF-8" : "C"; -+ return (struct string_with_storage) { name, STORAGE_INDEFINITE }; -+#else -+ #error "Please port gnulib getlocalename_l-unsafe.c to your platform! Report this to bug-gnulib." -+#endif -+ } -+ else -+ { -+ /* Query the global locale. */ -+ const char *name; -+#if LC_MESSAGES == 1729 -+ if (category == LC_MESSAGES) -+ name = setlocale_messages_null (); -+ else -+#endif -+#if defined __ANDROID__ -+ name = setlocale_fixed_null (category); -+#else -+ name = setlocale_null (category); -+#endif -+ if (name != NULL) -+ return (struct string_with_storage) { name, STORAGE_GLOBAL }; -+ else -+ /* Should normally not happen. */ -+ return (struct string_with_storage) { "", STORAGE_INDEFINITE }; -+ } -+} -diff -Naur coreutils-9.8/lib/mountlist.c coreutils-patched/lib/mountlist.c ---- coreutils-9.8/lib/mountlist.c 2025-09-17 22:35:53.000000000 +0300 -+++ coreutils-patched/lib/mountlist.c 2026-01-11 10:32:40.870011977 +0300 -@@ -1284,10 +1284,6 @@ - } - #endif - --#if MOUNTED_NOT_PORTED --# error "Please port gnulib mountlist.c to your platform!" --#endif -- - *mtail = NULL; - return mount_list; - diff --git a/tools/pkg/3/coreutils/info.txt b/tools/pkg/3/coreutils/info.txt deleted file mode 100644 index a4b710b..0000000 --- a/tools/pkg/3/coreutils/info.txt +++ /dev/null @@ -1 +0,0 @@ -coreutils
\ No newline at end of file diff --git a/tools/pkg/3/coreutils/pkg.sh b/tools/pkg/3/coreutils/pkg.sh deleted file mode 100644 index 811dc93..0000000 --- a/tools/pkg/3/coreutils/pkg.sh +++ /dev/null @@ -1,18 +0,0 @@ -. ../../pkg-lib.sh - -mkdir -p cached - -rm -rf pack - -mkdir -p pack - -cd pack - -installgnu coreutils coreutils 9.8 -mkdir -p coreutils-build - -cd coreutils-build -../coreutils-9.8/configure --host=x86_64-linux-gnu --prefix="/usr" -make install-strip -j$(nproc) DESTDIR="$1" - -cd .. diff --git a/tools/pkg/3/doomgeneric/diff/doomgeneric.diff b/tools/pkg/3/doomgeneric/diff/doomgeneric.diff deleted file mode 100644 index b94f13c..0000000 --- a/tools/pkg/3/doomgeneric/diff/doomgeneric.diff +++ /dev/null @@ -1,250 +0,0 @@ -diff -Naur doomgeneric/doomgeneric/doomgeneric_orange.c doomgeneric-patched/doomgeneric/doomgeneric_orange.c ---- doomgeneric/doomgeneric/doomgeneric_orange.c 1970-01-01 03:00:00.000000000 +0300 -+++ doomgeneric-patched/doomgeneric/doomgeneric_orange.c 2025-06-28 10:04:14.713386809 +0300 -@@ -0,0 +1,178 @@ -+#include <stdio.h> -+#include <stdlib.h> -+#include <fcntl.h> -+#include <linux/fb.h> -+#include <sys/ioctl.h> -+#include <sys/mman.h> -+#include <unistd.h> -+#include <string.h> -+#include <stdint.h> -+#include <termios.h> -+#include <signal.h> -+ -+#include "doomkeys.h" -+ -+#include "doomgeneric.h" -+ -+int fb_fd; -+int kbd_fd; -+ -+struct fb_var_screeninfo vinfo; -+struct fb_fix_screeninfo finfo; -+unsigned char *fb_ptr;void* old_fb; -+ -+ -+struct termios back; -+ -+#include <time.h> -+ -+void __restore() { -+ memset(fb_ptr,0,vinfo.yres * vinfo.xres * vinfo.bits_per_pixel / 8); -+ char dummy[1024]; -+ for(int i = 0;i < 128;i++) { -+ read(STDIN_FILENO,dummy,128); -+ } // clear the queue and go to the latest queue -+ tcsetattr(STDIN_FILENO, TCSANOW, &back);memcpy(fb_ptr,old_fb,vinfo.yres * vinfo.xres * vinfo.bits_per_pixel / 8); -+ -+} -+ -+void DG_Init() { -+ fb_fd = open("/dev/fb0", O_RDWR); -+ kbd_fd = open("/dev/ps2keyboard", O_RDWR); -+ -+ char dummy[1024]; -+ for(int i = 0;i < 128;i++) { -+ read(kbd_fd,dummy,128); -+ } // clear the queue and go to the latest queue -+ ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo); -+ ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo); -+ -+ fb_ptr = (unsigned char *)mmap(0, vinfo.yres_virtual * vinfo.xres_virtual * vinfo.bits_per_pixel / 8, -+ PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);old_fb = (void*)malloc(vinfo.yres * vinfo.xres * vinfo.bits_per_pixel / 8); -+ -+ struct termios newt; -+ tcgetattr(STDIN_FILENO, &back); -+ tcgetattr(STDIN_FILENO, &newt); -+ newt.c_lflag &= ~(ICANON | ECHO); -+ tcsetattr(STDIN_FILENO, TCSANOW, &newt); -+ atexit(__restore); -+ -+} -+ int is_saved = 0; -+void DG_DrawFrame() { -+ if(!is_saved) { memcpy(old_fb,fb_ptr,vinfo.yres * vinfo.xres * vinfo.bits_per_pixel / 8); is_saved = 1; } -+ int screen_width = vinfo.xres; -+ int screen_height = vinfo.yres; -+ -+ -+ float x_scale = (float)screen_width / DOOMGENERIC_RESX; -+ float y_scale = (float)screen_height / DOOMGENERIC_RESY; -+ -+ -+ for (int i = 0; i < screen_height; i++) { -+ -+ int src_y = (int)(i / y_scale); -+ if (src_y >= DOOMGENERIC_RESY) { -+ src_y = DOOMGENERIC_RESY - 1; -+ } -+ -+ -+ for (int j = 0; j < screen_width; j++) { -+ -+ int src_x = (int)(j / x_scale); -+ if (src_x >= DOOMGENERIC_RESX) { -+ src_x = DOOMGENERIC_RESX - 1; -+ } -+ -+ uint64_t fb = (uint64_t)fb_ptr; -+ fb += (finfo.line_length * i); -+ memcpy((void*)(fb + j * 4), DG_ScreenBuffer + (DOOMGENERIC_RESX * src_y + src_x), 4); -+ } -+ } -+} -+ -+void DG_SleepMs(uint32_t ms) { -+ usleep(ms * 1000); -+} -+ -+uint32_t DG_GetTicksMs() { -+ struct timespec ts; -+ clock_gettime(1,&ts); -+ long ms = (ts.tv_nsec / 1000) / 1000; -+ return ms + (ts.tv_sec * 1000); -+ // hello -+} -+ -+const char en_layout_translation[] = { -+ '\0', '\e', '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', ' ' -+}; -+ -+int DG_GetKey(int* pressed, unsigned char* key) { -+ uint8_t key0 = 0; -+ int status = read(kbd_fd,&key0,1); -+ if(status <= 0) -+ return 0; -+ -+ if(key0 & (1 << 7)) { -+ *pressed = 0; -+ key0 &= ~(1 << 7); // clear release bit -+ } else -+ *pressed = 1; -+ -+ uint8_t doom_key; -+ switch(key0) { -+ case 0x1E: -+ doom_key = KEY_LEFTARROW; -+ break; -+ case 0x20: -+ doom_key = KEY_RIGHTARROW; -+ break; -+ case 0x1F: -+ doom_key = KEY_DOWNARROW; -+ break; -+ case 0x11: -+ doom_key = KEY_UPARROW; -+ break; -+ case 0x12: -+ doom_key = KEY_USE; -+ break; -+ case 0x2A: -+ case 0x37: -+ doom_key = KEY_RSHIFT; -+ break; -+ case 0x01: -+ doom_key = KEY_ESCAPE; -+ break; -+ case 0x39: -+ doom_key = KEY_FIRE; -+ break; -+ default: { -+ doom_key = en_layout_translation[key0]; -+ if(doom_key == '\n') -+ doom_key = 13; -+ break; -+ } -+ } -+ *key = doom_key; -+ return 1; -+} -+ -+void DG_SetWindowTitle(const char * title) { -+ -+} -+ -+int main(int argc, char **argv) -+{ -+ doomgeneric_Create(argc, argv); -+ -+ while (1) -+ { -+ doomgeneric_Tick(); -+ } -+ -+ return 0; -+} -+ -diff -Naur doomgeneric/doomgeneric/i_system.c doomgeneric-patched/doomgeneric/i_system.c ---- doomgeneric/doomgeneric/i_system.c 2025-06-19 16:12:59.641729634 +0300 -+++ doomgeneric-patched/doomgeneric/i_system.c 2025-06-20 20:27:17.156598938 +0300 -@@ -257,11 +257,7 @@ - entry = entry->next; - } - --#if ORIGCODE -- SDL_Quit(); -- - exit(0); --#endif - } - - #if !defined(_WIN32) && !defined(__MACOSX__) && !defined(__DJGPP__) -@@ -460,16 +456,7 @@ - } - #endif - -- // abort(); --#if ORIGCODE -- SDL_Quit(); -- - exit(-1); --#else -- while (true) -- { -- } --#endif - } - - // -diff -Naur doomgeneric/doomgeneric/Makefile doomgeneric-patched/doomgeneric/Makefile ---- doomgeneric/doomgeneric/Makefile 2025-06-19 16:12:59.634729371 +0300 -+++ doomgeneric-patched/doomgeneric/Makefile 2025-06-20 20:57:21.688983500 +0300 -@@ -12,17 +12,17 @@ - endif - - --CC=clang # gcc or g++ --CFLAGS+=-ggdb3 -Os -+CC=x86_64-linux-gnu-gcc # gcc or g++ -+CFLAGS+=-ggdb3 -Os -std=gnu17 - LDFLAGS+=-Wl,--gc-sections - CFLAGS+=-ggdb3 -Wall -DNORMALUNIX -DLINUX -DSNDSERV -D_DEFAULT_SOURCE # -DUSEASM --LIBS+=-lm -lc -lX11 -+LIBS+=-lm -lc - - # subdirectory for objects - OBJDIR=build - OUTPUT=doomgeneric - --SRC_DOOM = dummy.o am_map.o doomdef.o doomstat.o dstrings.o d_event.o d_items.o d_iwad.o d_loop.o d_main.o d_mode.o d_net.o f_finale.o f_wipe.o g_game.o hu_lib.o hu_stuff.o info.o i_cdmus.o i_endoom.o i_joystick.o i_scale.o i_sound.o i_system.o i_timer.o memio.o m_argv.o m_bbox.o m_cheat.o m_config.o m_controls.o m_fixed.o m_menu.o m_misc.o m_random.o p_ceilng.o p_doors.o p_enemy.o p_floor.o p_inter.o p_lights.o p_map.o p_maputl.o p_mobj.o p_plats.o p_pspr.o p_saveg.o p_setup.o p_sight.o p_spec.o p_switch.o p_telept.o p_tick.o p_user.o r_bsp.o r_data.o r_draw.o r_main.o r_plane.o r_segs.o r_sky.o r_things.o sha1.o sounds.o statdump.o st_lib.o st_stuff.o s_sound.o tables.o v_video.o wi_stuff.o w_checksum.o w_file.o w_main.o w_wad.o z_zone.o w_file_stdc.o i_input.o i_video.o doomgeneric.o doomgeneric_xlib.o -+SRC_DOOM = dummy.o am_map.o doomdef.o doomstat.o dstrings.o d_event.o d_items.o d_iwad.o d_loop.o d_main.o d_mode.o d_net.o f_finale.o f_wipe.o g_game.o hu_lib.o hu_stuff.o info.o i_cdmus.o i_endoom.o i_joystick.o i_scale.o i_sound.o i_system.o i_timer.o memio.o m_argv.o m_bbox.o m_cheat.o m_config.o m_controls.o m_fixed.o m_menu.o m_misc.o m_random.o p_ceilng.o p_doors.o p_enemy.o p_floor.o p_inter.o p_lights.o p_map.o p_maputl.o p_mobj.o p_plats.o p_pspr.o p_saveg.o p_setup.o p_sight.o p_spec.o p_switch.o p_telept.o p_tick.o p_user.o r_bsp.o r_data.o r_draw.o r_main.o r_plane.o r_segs.o r_sky.o r_things.o sha1.o sounds.o statdump.o st_lib.o st_stuff.o s_sound.o tables.o v_video.o wi_stuff.o w_checksum.o w_file.o w_main.o w_wad.o z_zone.o w_file_stdc.o i_input.o i_video.o doomgeneric.o doomgeneric_orange.o - OBJS += $(addprefix $(OBJDIR)/, $(SRC_DOOM)) - - all: $(OUTPUT) -diff -Naur doomgeneric/doomgeneric/.vscode/settings.json doomgeneric-patched/doomgeneric/.vscode/settings.json ---- doomgeneric/doomgeneric/.vscode/settings.json 1970-01-01 03:00:00.000000000 +0300 -+++ doomgeneric-patched/doomgeneric/.vscode/settings.json 2025-06-27 18:48:57.784407657 +0300 -@@ -0,0 +1,6 @@ -+{ -+ "files.associations": { -+ "compare": "c", -+ "cstdint": "c" -+ } -+} -\ В конце файла нет новой строки
\ No newline at end of file diff --git a/tools/pkg/3/doomgeneric/info.txt b/tools/pkg/3/doomgeneric/info.txt deleted file mode 100644 index 8f4c7c9..0000000 --- a/tools/pkg/3/doomgeneric/info.txt +++ /dev/null @@ -1 +0,0 @@ -doomgeneric
\ No newline at end of file diff --git a/tools/pkg/3/doomgeneric/pkg.sh b/tools/pkg/3/doomgeneric/pkg.sh deleted file mode 100644 index 6a9952c..0000000 --- a/tools/pkg/3/doomgeneric/pkg.sh +++ /dev/null @@ -1,28 +0,0 @@ -. ../../pkg-lib.sh - -rm -rf pack - -mkdir -p pack - -cd pack - -echo $1 - -git clone https://github.com/ozkl/doomgeneric.git --depth=1 -cd doomgeneric - -diff_patch ../../diff/doomgeneric.diff -cd doomgeneric -make -j$(nproc) - -rm -rf "$1/usr/bin/doomgeneric" -cp -rf doomgeneric "$1/usr/bin/doomgeneric-fbdev" - -old="$(pwd)" -cd "$1/usr/share" -curl -O https://ia804501.us.archive.org/24/items/theultimatedoom_doom2_doom.wad/DOOM.WAD%20%28For%20GZDoom%29/DOOM.WAD -cd "$old" - -cd .. - -cd ../
\ No newline at end of file diff --git a/tools/pkg/3/fastfetch/diff/fastfetch.diff b/tools/pkg/3/fastfetch/diff/fastfetch.diff deleted file mode 100644 index 637265a..0000000 --- a/tools/pkg/3/fastfetch/diff/fastfetch.diff +++ /dev/null @@ -1,463 +0,0 @@ -diff -Naur fastfetch-2.44.0/CMakeLists.txt fastfetch-patched/CMakeLists.txt ---- fastfetch-2.44.0/CMakeLists.txt 2025-05-23 11:10:12.000000000 +0300 -+++ fastfetch-patched/CMakeLists.txt 2025-11-12 15:16:34.839273771 +0300 -@@ -28,6 +28,8 @@ - elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly") - set(FreeBSD TRUE CACHE BOOL "..." FORCE) - set(DragonFly TRUE CACHE BOOL "..." FORCE) -+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Orange") -+ set(Orange TRUE CACHE BOOL "..." FORCE) - elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS") - set(SunOS TRUE CACHE BOOL "..." FORCE) - elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Haiku") -@@ -1038,6 +1040,85 @@ - src/util/binary_windows.c - src/util/debug_windows.c - ) -+elseif(Orange) -+ list(APPEND LIBFASTFETCH_SRC -+ src/detection/battery/battery_nosupport.c -+ src/detection/bios/bios_nosupport.c -+ src/common/dbus.c -+ src/common/io/io_unix.c -+ src/common/netif/netif_linux.c -+ src/common/networking/networking_linux.c -+ src/common/processing_linux.c -+ src/detection/bluetooth/bluetooth_nosupport.c -+ src/detection/bluetoothradio/bluetoothradio_nosupport.c -+ src/detection/board/board_nosupport.c -+ src/detection/bootmgr/bootmgr_nosupport.c -+ src/detection/brightness/brightness_nosupport.c -+ src/detection/btrfs/btrfs_nosupport.c -+ src/detection/chassis/chassis_nosupport.c -+ src/detection/cpu/cpu_linux.c -+ src/detection/cpucache/cpucache_nosupport.c -+ src/detection/cpuusage/cpuusage_nosupport.c -+ src/detection/cursor/cursor_nosupport.c -+ src/detection/disk/disk_nosupport.c -+ src/detection/dns/dns_linux.c -+ src/detection/physicaldisk/physicaldisk_nosupport.c -+ src/detection/physicalmemory/physicalmemory_nosupport.c -+ src/detection/diskio/diskio_nosupport.c -+ src/detection/font/font_nosupport.c -+ src/detection/host/host_nosupport.c -+ src/detection/initsystem/initsystem_nosupport.c -+ src/detection/keyboard/keyboard_linux.c -+ src/detection/libc/libc_linux.c -+ src/detection/lm/lm_linux.c -+ src/detection/loadavg/loadavg_nosupport.c -+ src/detection/locale/locale_linux.c -+ src/detection/gamepad/gamepad_nosupport.c -+ src/detection/displayserver/linux/displayserver_linux.c -+ src/detection/displayserver/linux/drm.c -+ src/detection/displayserver/linux/wayland/wayland.c -+ src/detection/displayserver/linux/wayland/global-output.c -+ src/detection/displayserver/linux/wayland/zwlr-output.c -+ src/detection/displayserver/linux/wayland/kde-output.c -+ src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c -+ src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c -+ src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c -+ src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c -+ src/detection/displayserver/linux/wmde.c -+ src/detection/displayserver/linux/xcb.c -+ src/detection/displayserver/linux/xlib.c -+ src/detection/media/media_linux.c -+ src/detection/memory/memory_linux.c -+ src/detection/mouse/mouse_linux.c -+ src/detection/netio/netio_linux.c -+ src/detection/opengl/opengl_linux.c -+ src/detection/packages/packages_linux.c -+ src/detection/poweradapter/poweradapter_linux.c -+ src/detection/processes/processes_linux.c -+ src/detection/gtk_qt/qt.c -+ src/detection/sound/sound_linux.c -+ src/detection/swap/swap_linux.c -+ src/detection/terminalfont/terminalfont_linux.c -+ src/detection/terminalshell/terminalshell_linux.c -+ src/detection/terminalsize/terminalsize_linux.c -+ src/detection/theme/theme_nosupport.c -+ src/detection/tpm/tpm_linux.c -+ src/detection/uptime/uptime_linux.c -+ src/detection/users/users_nosupport.c -+ src/detection/wallpaper/wallpaper_nosupport.c -+ src/detection/wifi/wifi_nosupport.c -+ src/detection/wm/wm_nosupport.c -+ src/detection/de/de_nosupport.c -+ src/detection/wmtheme/wmtheme_nosupport.c -+ src/detection/camera/camera_linux.c -+ src/detection/zpool/zpool_linux.c -+ src/util/platform/FFPlatform_unix.c -+ src/util/binary_linux.c -+ src/detection/gpu/gpu_nosupport.c -+ src/detection/localip/localip_linux.c -+ src/detection/icons/icons_nosupport.c -+ src/detection/os/os_orange.c -+) - elseif(SunOS) - list(APPEND LIBFASTFETCH_SRC - src/common/dbus.c -@@ -1306,6 +1387,8 @@ - target_compile_definitions(libfastfetch PUBLIC __FreeBSD__) - elseif(SunOS) - target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 __EXTENSIONS__ _POSIX_C_SOURCE) -+elseif(Orange) -+ target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE) - elseif(NetBSD) - target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-char-subscripts") -diff -Naur fastfetch-2.44.0/src/detection/os/os_orange.c fastfetch-patched/src/detection/os/os_orange.c ---- fastfetch-2.44.0/src/detection/os/os_orange.c 1970-01-01 03:00:00.000000000 +0300 -+++ fastfetch-patched/src/detection/os/os_orange.c 2025-11-12 15:16:34.839273771 +0300 -@@ -0,0 +1,6 @@ -+#include "os.h" -+ -+void ffDetectOSImpl(FFOSResult* os) { -+ ffStrbufSetStatic(&os->name,"Orange"); -+ ffStrbufSet(&os->version,&instance.state.platform.sysinfo.release); -+} -diff -Naur fastfetch-2.44.0/src/detection/terminalshell/terminalshell.c fastfetch-patched/src/detection/terminalshell/terminalshell.c ---- fastfetch-2.44.0/src/detection/terminalshell/terminalshell.c 2025-05-23 11:10:12.000000000 +0300 -+++ fastfetch-patched/src/detection/terminalshell/terminalshell.c 2025-11-12 15:21:40.744281707 +0300 -@@ -65,6 +65,11 @@ - - static bool getShellVersionBash(FFstrbuf* exe, FFstrbuf* exePath, FFstrbuf* version) - { -+ -+ memcpy(version->chars,"5.2.21\0",strlen("5.2.21\0") + 1); -+ version->length = strlen("5.2.21\0") + 1; -+ return true; -+ - const char* path = exePath->chars; - if (*path == '\0') - path = exe->chars; -diff -Naur fastfetch-2.44.0/src/logo/ascii/orange.txt fastfetch-patched/src/logo/ascii/orange.txt ---- fastfetch-2.44.0/src/logo/ascii/orange.txt 1970-01-01 03:00:00.000000000 +0300 -+++ fastfetch-patched/src/logo/ascii/orange.txt 2025-11-12 15:16:34.839273771 +0300 -@@ -0,0 +1,29 @@ -+ -+ -+ -+ $2::: -+ $2-===+++- -+ $2++++++++ -+ $2=+++++** -+ $2 ******* -+ $1--============= $2 *** **+ -+ $1 ---===---==========++ $2 +*- -+ $1 :--=-:-------=====+++++$2** -+ $1 -===----------======+*$2**$1++++ -+ $1 -====:--------========++++++++ -+ $1 ======-----==========++++++++++ -+ $1-====================+++++++++++ -+ $1-===================++++++++++++ -+ $1:=================++++++++++++++ -+ $1 -===============++++++++++++++++ -+ $1 ============++++++++++++++++++* -+ $1 -=====++++++++++++++++++++++*** -+ $1 +++++++++++++++++++++++****** -+ $1 +++++++++++++++++++++**** -+ $1 +++++++++++++++++++*** -+ $1 +++++++++++++***: -+ $1 *+++++= -+ -+ -+ -+ -diff -Naur fastfetch-2.44.0/src/logo/builtin.c fastfetch-patched/src/logo/builtin.c ---- fastfetch-2.44.0/src/logo/builtin.c 2025-05-23 11:10:12.000000000 +0300 -+++ fastfetch-patched/src/logo/builtin.c 2025-11-12 15:16:34.840273817 +0300 -@@ -3552,6 +3552,7 @@ - .colorKeys = FF_COLOR_FG_RED, - .colorTitle = FF_COLOR_FG_WHITE, - }, -+ - // Orchid - { - .names = {"orchid"}, -@@ -3586,6 +3587,15 @@ - FF_COLOR_FG_DEFAULT, - }, - }, -+ // Orange -+ { -+ .names = {"Orange","orange","OrangeOS","orangeos"}, -+ .lines = FASTFETCH_DATATEXT_LOGO_ORANGE, -+ .colors = { -+ FF_COLOR_FG_RGB "255;140;0", -+ FF_COLOR_FG_RGB "0;255;0", -+ } -+ }, - // OS_Elbrus - { - .names = {"OS Elbrus"}, -diff -Naur fastfetch-2.44.0/src/options/general.h fastfetch-patched/src/options/general.h ---- fastfetch-2.44.0/src/options/general.h 2025-05-23 11:10:12.000000000 +0300 -+++ fastfetch-patched/src/options/general.h 2025-11-12 15:16:34.840273817 +0300 -@@ -16,7 +16,7 @@ - bool detectVersion; - - // Module options that cannot be put in module option structure -- #if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) -+ #if defined(__linux__) || defined(__orange__) || defined(__FreeBSD__) || defined(__sun) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) - FFstrbuf playerName; - FFDsForceDrmType dsForceDrm; - #elif defined(_WIN32) -diff -Naur fastfetch-2.44.0/src/util/platform/FFPlatform_unix.c fastfetch-patched/src/util/platform/FFPlatform_unix.c ---- fastfetch-2.44.0/src/util/platform/FFPlatform_unix.c 2025-05-23 11:10:12.000000000 +0300 -+++ fastfetch-patched/src/util/platform/FFPlatform_unix.c 2025-11-12 15:16:34.840273817 +0300 -@@ -22,7 +22,7 @@ - static void getExePath(FFPlatform* platform) - { - char exePath[PATH_MAX + 1]; -- #ifdef __linux__ -+ #if defined(__linux__) || defined(__orange__) - ssize_t exePathLen = readlink("/proc/self/exe", exePath, sizeof(exePath) - 1); - if (exePathLen >= 0) - exePath[exePathLen] = '\0'; -diff -Naur fastfetch-2.44.0/src/util/platform/FFPlatform_unix.c.orig fastfetch-patched/src/util/platform/FFPlatform_unix.c.orig ---- fastfetch-2.44.0/src/util/platform/FFPlatform_unix.c.orig 1970-01-01 03:00:00.000000000 +0300 -+++ fastfetch-patched/src/util/platform/FFPlatform_unix.c.orig 2025-11-12 15:16:14.586507269 +0300 -@@ -0,0 +1,243 @@ -+#include "FFPlatform_private.h" -+#include "util/stringUtils.h" -+#include "fastfetch_config.h" -+#include "common/io/io.h" -+ -+#include <unistd.h> -+#include <pwd.h> -+#include <limits.h> -+#include <sys/utsname.h> -+#include <paths.h> -+ -+#ifdef __APPLE__ -+ #include <libproc.h> -+ #include <sys/sysctl.h> -+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -+ #include <sys/sysctl.h> -+#elif defined(__HAIKU__) -+ #include <image.h> -+ #include <OS.h> -+#endif -+ -+static void getExePath(FFPlatform* platform) -+{ -+ char exePath[PATH_MAX + 1]; -+ #ifdef __linux__ -+ ssize_t exePathLen = readlink("/proc/self/exe", exePath, sizeof(exePath) - 1); -+ if (exePathLen >= 0) -+ exePath[exePathLen] = '\0'; -+ #elif defined(__APPLE__) -+ int exePathLen = proc_pidpath((int) getpid(), exePath, sizeof(exePath)); -+ #elif defined(__FreeBSD__) || defined(__NetBSD__) -+ size_t exePathLen = sizeof(exePath); -+ if(sysctl( -+ (int[]){CTL_KERN, -+ #ifdef __FreeBSD__ -+ KERN_PROC, KERN_PROC_PATHNAME, (int) getpid() -+ #else -+ KERN_PROC_ARGS, (int) getpid(), KERN_PROC_PATHNAME -+ #endif -+ }, 4, -+ exePath, &exePathLen, -+ NULL, 0 -+ ) < 0) -+ exePathLen = 0; -+ else -+ exePathLen--; // remove terminating NUL -+ #elif defined(__OpenBSD__) -+ size_t exePathLen = 0; -+ #elif defined(__sun) -+ ssize_t exePathLen = readlink("/proc/self/path/a.out", exePath, sizeof(exePath) - 1); -+ if (exePathLen >= 0) -+ exePath[exePathLen] = '\0'; -+ #elif defined(__HAIKU__) -+ size_t exePathLen = 0; -+ image_info info; -+ int32 cookie = 0; -+ -+ while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) { -+ if (info.type == B_APP_IMAGE) { -+ exePathLen = strlcpy(exePath, info.name, PATH_MAX); -+ break; -+ } -+ } -+ #endif -+ if (exePathLen > 0) -+ { -+ ffStrbufEnsureFree(&platform->exePath, PATH_MAX); -+ if (realpath(exePath, platform->exePath.chars)) -+ ffStrbufRecalculateLength(&platform->exePath); -+ else -+ ffStrbufSetNS(&platform->exePath, (uint32_t) exePathLen, exePath); -+ } -+} -+ -+static void platformPathAddEnv(FFlist* dirs, const char* env) -+{ -+ const char* envValue = getenv(env); -+ if(!ffStrSet(envValue)) -+ return; -+ -+ FF_STRBUF_AUTO_DESTROY value = ffStrbufCreateA(64); -+ ffStrbufAppendS(&value, envValue); -+ -+ uint32_t startIndex = 0; -+ while (startIndex < value.length) -+ { -+ uint32_t colonIndex = ffStrbufNextIndexC(&value, startIndex, ':'); -+ value.chars[colonIndex] = '\0'; -+ -+ if(!ffStrSet(value.chars + startIndex)) -+ { -+ startIndex = colonIndex + 1; -+ continue; -+ } -+ -+ ffPlatformPathAddAbsolute(dirs, value.chars + startIndex); -+ -+ startIndex = colonIndex + 1; -+ } -+} -+ -+static void getHomeDir(FFPlatform* platform, const struct passwd* pwd) -+{ -+ const char* home = pwd ? pwd->pw_dir : getenv("HOME"); -+ ffStrbufAppendS(&platform->homeDir, home); -+ ffStrbufEnsureEndsWithC(&platform->homeDir, '/'); -+} -+ -+static void getCacheDir(FFPlatform* platform) -+{ -+ const char* cache = getenv("XDG_CACHE_HOME"); -+ if(ffStrSet(cache)) -+ { -+ ffStrbufAppendS(&platform->cacheDir, cache); -+ ffStrbufEnsureEndsWithC(&platform->cacheDir, '/'); -+ } -+ else -+ { -+ ffStrbufAppend(&platform->cacheDir, &platform->homeDir); -+ ffStrbufAppendS(&platform->cacheDir, ".cache/"); -+ } -+} -+ -+static void getConfigDirs(FFPlatform* platform) -+{ -+ // Always make sure `${XDG_CONFIG_HOME:-$HOME/.config}` is the first entry -+ platformPathAddEnv(&platform->configDirs, "XDG_CONFIG_HOME"); -+ ffPlatformPathAddHome(&platform->configDirs, platform, ".config/"); -+ -+ #if defined(__APPLE__) -+ ffPlatformPathAddHome(&platform->configDirs, platform, "Library/Preferences/"); -+ ffPlatformPathAddHome(&platform->configDirs, platform, "Library/Application Support/"); -+ #endif -+ #if defined(__HAIKU__) -+ ffPlatformPathAddHome(&platform->configDirs, platform, "config/settings/"); -+ #endif -+ -+ ffPlatformPathAddHome(&platform->configDirs, platform, ""); -+ platformPathAddEnv(&platform->configDirs, "XDG_CONFIG_DIRS"); -+ -+ #if !defined(__APPLE__) -+ ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_ETC "/xdg/"); -+ #endif -+ -+ ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_ETC "/"); -+ ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_INSTALL_SYSCONF "/"); -+} -+ -+static void getDataDirs(FFPlatform* platform) -+{ -+ platformPathAddEnv(&platform->dataDirs, "XDG_DATA_HOME"); -+ ffPlatformPathAddHome(&platform->dataDirs, platform, ".local/share/"); -+ -+ // Add ${currentExePath}/../share -+ if (platform->exePath.length > 0) -+ { -+ FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateCopy(&platform->exePath); -+ ffStrbufSubstrBeforeLastC(&path, '/'); -+ ffStrbufSubstrBeforeLastC(&path, '/'); -+ ffStrbufAppendS(&path, "/share"); -+ ffPlatformPathAddAbsolute(&platform->dataDirs, path.chars); -+ } -+ -+ #ifdef __APPLE__ -+ ffPlatformPathAddHome(&platform->dataDirs, platform, "Library/Application Support/"); -+ #endif -+ -+ ffPlatformPathAddHome(&platform->dataDirs, platform, ""); -+ platformPathAddEnv(&platform->dataDirs, "XDG_DATA_DIRS"); -+#ifdef _PATH_LOCALBASE -+ ffPlatformPathAddAbsolute(&platform->dataDirs, _PATH_LOCALBASE "/share/"); -+#endif -+ ffPlatformPathAddAbsolute(&platform->dataDirs, FASTFETCH_TARGET_DIR_USR "/local/share/"); -+ ffPlatformPathAddAbsolute(&platform->dataDirs, FASTFETCH_TARGET_DIR_USR "/share/"); -+} -+ -+static void getUserName(FFPlatform* platform, const struct passwd* pwd) -+{ -+ const char* user = getenv("USER"); -+ if(!ffStrSet(user) && pwd) -+ user = pwd->pw_name; -+ -+ ffStrbufAppendS(&platform->userName, user); -+ -+ if (pwd) ffStrbufAppendS(&platform->fullUserName, pwd->pw_gecos); -+} -+ -+static void getHostName(FFPlatform* platform, const struct utsname* uts) -+{ -+ ffStrbufAppendS(&platform->hostName, uts->nodename); -+} -+ -+static void getUserShell(FFPlatform* platform, const struct passwd* pwd) -+{ -+ const char* shell = getenv("SHELL"); -+ if(!ffStrSet(shell) && pwd) -+ shell = pwd->pw_shell; -+ -+ ffStrbufAppendS(&platform->userShell, shell); -+} -+ -+static void getSysinfo(FFPlatformSysinfo* info, const struct utsname* uts) -+{ -+ ffStrbufAppendS(&info->name, uts->sysname); -+ ffStrbufAppendS(&info->release, uts->release); -+ ffStrbufAppendS(&info->version, uts->version); -+ #ifdef __HAIKU__ -+ /* historical reason */ -+ if (ffStrEquals(uts->machine, "BePC")) -+ ffStrbufSetStatic(&info->architecture, "i386"); -+ else -+ #endif -+ ffStrbufAppendS(&info->architecture, uts->machine); -+ ffStrbufInit(&info->displayVersion); -+ -+ #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__) -+ size_t length = sizeof(info->pageSize); -+ sysctl((int[]){ CTL_HW, HW_PAGESIZE }, 2, &info->pageSize, &length, NULL, 0); -+ #else -+ info->pageSize = (uint32_t) sysconf(_SC_PAGESIZE); -+ #endif -+} -+ -+void ffPlatformInitImpl(FFPlatform* platform) -+{ -+ struct passwd* pwd = getpwuid(getuid()); -+ -+ struct utsname uts; -+ if(uname(&uts) < 0) -+ memset(&uts, 0, sizeof(uts)); -+ -+ getExePath(platform); -+ getHomeDir(platform, pwd); -+ getCacheDir(platform); -+ getConfigDirs(platform); -+ getDataDirs(platform); -+ -+ getUserName(platform, pwd); -+ getHostName(platform, &uts); -+ getUserShell(platform, pwd); -+ -+ getSysinfo(&platform->sysinfo, &uts); -+} diff --git a/tools/pkg/3/fastfetch/info.txt b/tools/pkg/3/fastfetch/info.txt deleted file mode 100644 index 7758cf8..0000000 --- a/tools/pkg/3/fastfetch/info.txt +++ /dev/null @@ -1 +0,0 @@ -fastfetch
\ No newline at end of file diff --git a/tools/pkg/3/fastfetch/pkg.sh b/tools/pkg/3/fastfetch/pkg.sh deleted file mode 100644 index fa8a3bb..0000000 --- a/tools/pkg/3/fastfetch/pkg.sh +++ /dev/null @@ -1,29 +0,0 @@ -. ../../pkg-lib.sh - -rm -rf pack - -mkdir -p pack - -cd pack - -echo $1 - -wget https://github.com/fastfetch-cli/fastfetch/archive/refs/tags/2.44.0.tar.gz - -tar -xvf 2.44.0.tar.gz - -cd fastfetch-2.44.0 -diff_patch ../../diff/fastfetch.diff -patch_config_sub "$(realpath $1/..)" -cd .. - -LDFLAGS="$LDFLAGS -lm" - -mkdir -p fastfetch-build -cd fastfetch-build -cmake ../fastfetch-2.44.0 -DCMAKE_TOOLCHAIN_FILE=$(realpath ../../../../toolchain.cmake) -DCMAKE_INSTALL_PREFIX="$1/usr" - -make -j$(nproc) -make install - -cd ..
\ No newline at end of file diff --git a/tools/pkg/3/lua/info.txt b/tools/pkg/3/lua/info.txt deleted file mode 100644 index 9ad5171..0000000 --- a/tools/pkg/3/lua/info.txt +++ /dev/null @@ -1 +0,0 @@ -lua
\ No newline at end of file diff --git a/tools/pkg/3/lua/pkg.sh b/tools/pkg/3/lua/pkg.sh deleted file mode 100644 index 6eb1065..0000000 --- a/tools/pkg/3/lua/pkg.sh +++ /dev/null @@ -1,17 +0,0 @@ -. ../../pkg-lib.sh - -rm -rf pack -mkdir -p pack - -cd pack - -wget https://www.lua.org/ftp/lua-5.4.7.tar.gz - -tar -xvf lua-5.4.7.tar.gz -cd lua-5.4.7 - -make CC=x86_64-linux-gnu-gcc LD=x86_64-linux-gnu-ld generic -j$(nproc) -cp -rf src/lua "$1/usr/bin" -cp -rf src/luac "$1/usr/bin" - -cd ..
\ No newline at end of file diff --git a/tools/pkg/3/mouse_test/info.txt b/tools/pkg/3/mouse_test/info.txt deleted file mode 100644 index c50b1e4..0000000 --- a/tools/pkg/3/mouse_test/info.txt +++ /dev/null @@ -1 +0,0 @@ -mousetest
\ No newline at end of file diff --git a/tools/pkg/3/mouse_test/main.c b/tools/pkg/3/mouse_test/main.c deleted file mode 100644 index 51f6c4b..0000000 --- a/tools/pkg/3/mouse_test/main.c +++ /dev/null @@ -1,194 +0,0 @@ -#include <stdio.h> -#include <poll.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <sys/ioctl.h> -#include <linux/fb.h> -#include <stdlib.h> -#include <string.h> - -#define MOUSE_LB (1 << 0) -#define MOUSE_RB (1 << 1) -#define MOUSE_MB (1 << 2) -#define MOUSE_B4 (1 << 3) -#define MOUSE_B5 (1 << 4) - -typedef struct { - unsigned char buttons; - unsigned char x; - unsigned char y; - unsigned char z; -} __attribute__((packed)) mouse_packet_t; - -typedef struct { - int fd; - char *fbp; - struct fb_fix_screeninfo finfo; - struct fb_var_screeninfo vinfo; - long int screensize; - int cursor_x, cursor_y; - int cursor_visible; -} fb_info_t; - -int init_fb(fb_info_t *fb) { - fb->fd = open("/dev/fb0", O_RDWR); - if (fb->fd == -1) { - perror("Error: cannot open framebuffer device"); - return -1; - } - - if (ioctl(fb->fd, FBIOGET_FSCREENINFO, &fb->finfo)) { - perror("Error reading fixed information"); - close(fb->fd); - return -1; - } - - if (ioctl(fb->fd, FBIOGET_VSCREENINFO, &fb->vinfo)) { - perror("Error reading variable information"); - close(fb->fd); - return -1; - } - - fb->screensize = fb->vinfo.yres_virtual * fb->finfo.line_length; - - fb->fbp = (char *)mmap(0, fb->screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb->fd, 0); - if ((long)fb->fbp == -1) { - perror("Error: failed to map framebuffer device to memory"); - close(fb->fd); - return -1; - } - - fb->cursor_x = fb->vinfo.xres / 2; - fb->cursor_y = fb->vinfo.yres / 2; - fb->cursor_visible = 1; - - printf("Framebuffer initialized: %dx%d, %dbpp\n", - fb->vinfo.xres, fb->vinfo.yres, fb->vinfo.bits_per_pixel); - - return 0; -} - -void put_pixel(fb_info_t *fb, int x, int y, unsigned int color) { - if (x < 0 || x >= fb->vinfo.xres || y < 0 || y >= fb->vinfo.yres) - return; - - long location = (x + fb->vinfo.xoffset) * (fb->vinfo.bits_per_pixel / 8) + - (y + fb->vinfo.yoffset) * fb->finfo.line_length; - - if (fb->vinfo.bits_per_pixel == 32) { - *((unsigned int *)(fb->fbp + location)) = color; - } else if (fb->vinfo.bits_per_pixel == 16) { - *((unsigned short *)(fb->fbp + location)) = color & 0xFFFF; - } else { - *((unsigned char *)(fb->fbp + location)) = color & 0xFF; - } -} - -void draw_cursor(fb_info_t *fb) { - int x = fb->cursor_x; - int y = fb->cursor_y; - unsigned int color = 0xFFFFFF; - - for (int i = -5; i <= 5; i++) { - if (i != 0) { - put_pixel(fb, x, y + i, color); - } - } - - for (int i = -5; i <= 5; i++) { - if (i != 0) { - put_pixel(fb, x + i, y, color); - } - } - - put_pixel(fb, x, y, 0xFF0000); -} - -void clear_cursor_area(fb_info_t *fb) { - int size = 10; - for (int i = -size; i <= size; i++) { - for (int j = -size; j <= size; j++) { - put_pixel(fb, fb->cursor_x + i, fb->cursor_y + j, 0x000000); - } - } -} - -void update_cursor(fb_info_t *fb, int dx, int dy) { - - if (fb->cursor_visible) { - clear_cursor_area(fb); - } - - fb->cursor_x += dx; - fb->cursor_y += dy; - - if (fb->cursor_x < 0) fb->cursor_x = 0; - if (fb->cursor_x >= fb->vinfo.xres) fb->cursor_x = fb->vinfo.xres - 1; - if (fb->cursor_y < 0) fb->cursor_y = 0; - if (fb->cursor_y >= fb->vinfo.yres) fb->cursor_y = fb->vinfo.yres - 1; - - draw_cursor(fb); -} - -void clear_screen(fb_info_t *fb) { - memset(fb->fbp, 0, fb->screensize); -} - -int main() { - int mouse_fd = open("/dev/mouse", O_RDWR); - if (mouse_fd == -1) { - perror("Error: cannot open mouse device"); - return 1; - } - - fb_info_t fb; - if (init_fb(&fb) == -1) { - close(mouse_fd); - return 1; - } - - clear_screen(&fb); - - draw_cursor(&fb); - - struct pollfd fd; - fd.events = POLLIN; - fd.fd = mouse_fd; - - while(1) { - int num = poll(&fd, 1, -1); - if (num > 0 && (fd.revents & POLLIN)) { - mouse_packet_t packets[256]; - memset(packets,0,sizeof(mouse_packet_t) * 256); - int bytes_read = read(mouse_fd, &packets, sizeof(mouse_packet_t) * 256); - - for(int i = 0; i < bytes_read / (sizeof(mouse_packet_t));i++) { - mouse_packet_t packet = packets[i]; - if (1) { - - int dx = (signed char)packet.x; - int dy = (signed char)packet.y; - - - update_cursor(&fb, dx, -dy); - if(packet.buttons & MOUSE_LB) { - printf("pressed left button\n"); - } - - if(packet.buttons & MOUSE_RB) { - printf("pressed right button\n"); - } - - if(packet.buttons & MOUSE_MB) { - printf("pressed middle button\n"); - } - - } - } - - } - } - - return 0; -}
\ No newline at end of file diff --git a/tools/pkg/3/mouse_test/pkg.sh b/tools/pkg/3/mouse_test/pkg.sh deleted file mode 100644 index 8de3ae2..0000000 --- a/tools/pkg/3/mouse_test/pkg.sh +++ /dev/null @@ -1,2 +0,0 @@ - -x86_64-linux-gnu-gcc main.c -o "$1/usr/bin/mouse_test"
\ No newline at end of file diff --git a/tools/pkg/3/nano/diff/nano.diff b/tools/pkg/3/nano/diff/nano.diff deleted file mode 100644 index 65d6cba..0000000 --- a/tools/pkg/3/nano/diff/nano.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff -Naur nano-8.4/config.sub nano-patched/config.sub ---- nano-8.4/config.sub 2022-01-31 17:43:17.000000000 +0300 -+++ nano-patched/config.sub 2025-06-02 10:06:02.670396019 +0300 -@@ -1750,7 +1750,7 @@ - | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ - | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ - | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ -- | skyos* | haiku* | rdos* | toppers* | drops* | es* \ -+ | skyos* | orange* | haiku* | rdos* | toppers* | drops* | es* \ - | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ - | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ - | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
\ No newline at end of file diff --git a/tools/pkg/3/nano/info.txt b/tools/pkg/3/nano/info.txt deleted file mode 100644 index 0f0ddd3..0000000 --- a/tools/pkg/3/nano/info.txt +++ /dev/null @@ -1 +0,0 @@ -nano
\ No newline at end of file diff --git a/tools/pkg/3/nano/pkg.sh b/tools/pkg/3/nano/pkg.sh deleted file mode 100644 index 7ec956a..0000000 --- a/tools/pkg/3/nano/pkg.sh +++ /dev/null @@ -1,23 +0,0 @@ -. ../../pkg-lib.sh - -mkdir -p cached - -rm -rf pack - -mkdir -p pack - -cd pack - -installgnu nano nano 8.4 -mkdir -p nano-build - -cd nano-8.4 -diff_patch ../../diff/nano.diff -patch_config_sub "$(realpath $1/..)" -cd .. - -cd nano-build -../nano-8.4/configure --host=x86_64-linux-gnu --prefix="/usr" gl_cv_func_strcasecmp_works=yes CFLAGS="-std=gnu17" -make install -j$(nproc) DESTDIR="$1" - -cd ..
\ No newline at end of file diff --git a/tools/pkg/3/poll_test/info.txt b/tools/pkg/3/poll_test/info.txt deleted file mode 100644 index e251bd2..0000000 --- a/tools/pkg/3/poll_test/info.txt +++ /dev/null @@ -1 +0,0 @@ -poll_test
\ No newline at end of file diff --git a/tools/pkg/3/poll_test/pkg.sh b/tools/pkg/3/poll_test/pkg.sh deleted file mode 100644 index d99379d..0000000 --- a/tools/pkg/3/poll_test/pkg.sh +++ /dev/null @@ -1,2 +0,0 @@ - -x86_64-orange-mlibc-g++ -o "$1/usr/bin/poll_test" src/main.c
\ No newline at end of file diff --git a/tools/pkg/3/poll_test/src/main.c b/tools/pkg/3/poll_test/src/main.c deleted file mode 100644 index 4d6fdd2..0000000 --- a/tools/pkg/3/poll_test/src/main.c +++ /dev/null @@ -1,44 +0,0 @@ -#include <stdio.h> -#include <poll.h> -#include <unistd.h> - -#include <termios.h> - -#include <string.h> - -int main() { - struct pollfd fds[1]; - fds[0].fd = 0; - fds[0].events = POLLIN; - - struct termios newt; - tcgetattr(STDIN_FILENO, &newt); - newt.c_lflag &= ~(ICANON | ECHO); - tcsetattr(STDIN_FILENO, TCSANOW, &newt); - - printf("Waiting for input (5 second timeout)...\n"); - int ret = poll(fds, 1, 5000); - - if (ret == -1) { - perror("poll"); - return 1; - } else if (ret == 0) { - printf("Timeout !\n"); - } else { - if (fds[0].revents & POLLIN) { - printf("Input ! waiting for string\n"); - char buf[100]; - read(STDIN_FILENO,buf,100); - memset(buf,0,100); - newt.c_lflag |= ICANON | ECHO; - tcsetattr(STDIN_FILENO, TCSANOW, &newt); - read(STDIN_FILENO,buf,100); - printf("You enter: %s", buf); - } - } - - newt.c_lflag |= ICANON | ECHO; - tcsetattr(STDIN_FILENO, TCSANOW, &newt); - - return 0; -}
\ No newline at end of file diff --git a/tools/pkg/3/pthread_test/a.out b/tools/pkg/3/pthread_test/a.out Binary files differdeleted file mode 100755 index 1ad887d..0000000 --- a/tools/pkg/3/pthread_test/a.out +++ /dev/null diff --git a/tools/pkg/3/pthread_test/alarm_test.c b/tools/pkg/3/pthread_test/alarm_test.c deleted file mode 100644 index 893c20d..0000000 --- a/tools/pkg/3/pthread_test/alarm_test.c +++ /dev/null @@ -1,35 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <signal.h> -#include <time.h> - -void alarm_handler(int signum) { - printf("\nALARM! Time's up!\n"); - printf("\a"); // System beep - exit(0); -} - -int main() { - int seconds; - - // Set up signal handler - signal(SIGALRM, alarm_handler); - - printf("Simple Alarm Clock\n"); - printf("Enter alarm time in seconds: "); - scanf("%d", &seconds); - - printf("Alarm set for %d seconds.\n", seconds); - printf("Waiting... (Press Ctrl+C to cancel)\n"); - - // Set alarm - alarm(seconds); - - // Wait indefinitely - while(1) { - pause(); // Wait for signal - } - - return 0; -}
\ No newline at end of file diff --git a/tools/pkg/3/pthread_test/fdpass.c b/tools/pkg/3/pthread_test/fdpass.c deleted file mode 100644 index 7dfdd3b..0000000 --- a/tools/pkg/3/pthread_test/fdpass.c +++ /dev/null @@ -1,128 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <pthread.h> -#include <fcntl.h> - -#define THREAD_COUNT 2 - -// Shared socket pair file descriptors -int socket_pair[2]; - -// Thread to send a file descriptor -void* sender_thread(void* arg) { - // Open a file to pass its descriptor - int fd = open("/etc/hostname", O_RDONLY); - if (fd < 0) { - perror("open"); - return NULL; - } - - // Prepare message to send - struct msghdr msg = {0}; - char buf[CMSG_SPACE(sizeof(int))]; - memset(buf, 0, sizeof(buf)); - struct iovec io = {.iov_base = (void*)"FD", .iov_len = 2}; - - msg.msg_iov = &io; - msg.msg_iovlen = 1; - - // Set control message to pass the file descriptor - struct cmsghdr* cmsg = (struct cmsghdr*)buf; - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - - // Copy the fd into the control message - memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); - - msg.msg_control = cmsg; - msg.msg_controllen = CMSG_LEN(sizeof(int)); - - // Send message with the file descriptor - if (sendmsg(socket_pair[0], &msg, 0) < 0) { - perror("sendmsg"); - } else { - printf("Sender: sent file descriptor\n"); - } - - close(fd); - return NULL; -} - -// Thread to receive a file descriptor -void* receiver_thread(void* arg) { - char buf[1]; - struct msghdr msg = {0}; - char ctrl_buf[CMSG_SPACE(sizeof(int))]; - - struct iovec io = {.iov_base = buf, .iov_len = 1}; - msg.msg_iov = &io; - msg.msg_iovlen = 1; - msg.msg_control = ctrl_buf; - msg.msg_controllen = sizeof(ctrl_buf); - - // Receive message and ancillary data - if (recvmsg(socket_pair[1], &msg, 0) < 0) { - perror("recvmsg"); - return NULL; - } - - // Extract the file descriptor from the control message - struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); - int received_fd = -1; - - if (cmsg && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { - memcpy(&received_fd, CMSG_DATA(cmsg), sizeof(int)); - printf("Receiver: received file descriptor %d\n", received_fd); - - // Read from the received file descriptor - char read_buf[128]; - ssize_t n = read(received_fd, read_buf, sizeof(read_buf)-1); - if (n > 0) { - read_buf[n] = '\0'; - printf("Content of the file: %s\n", read_buf); - } else { - perror("read"); - } - - close(received_fd); - } else { - printf("No file descriptor received (size %d)\n",0); - } - return NULL; -} - -int main() { - pthread_t threads[THREAD_COUNT]; - - // Create a socket pair for communication - if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair) < 0) { - perror("socketpair"); - exit(EXIT_FAILURE); - } - - // Create sender thread - if (pthread_create(&threads[0], NULL, sender_thread, NULL) != 0) { - perror("pthread_create sender"); - exit(EXIT_FAILURE); - } - - // Create receiver thread - if (pthread_create(&threads[1], NULL, receiver_thread, NULL) != 0) { - perror("pthread_create receiver"); - exit(EXIT_FAILURE); - } - - // Wait for threads to finish - pthread_join(threads[0], NULL); - pthread_join(threads[1], NULL); - - close(socket_pair[0]); - close(socket_pair[1]); - - return 0; -}
\ No newline at end of file diff --git a/tools/pkg/3/pthread_test/info.txt b/tools/pkg/3/pthread_test/info.txt deleted file mode 100644 index 8d3b30e..0000000 --- a/tools/pkg/3/pthread_test/info.txt +++ /dev/null @@ -1 +0,0 @@ -ptherad_test
\ No newline at end of file diff --git a/tools/pkg/3/pthread_test/pkg.sh b/tools/pkg/3/pthread_test/pkg.sh deleted file mode 100644 index 4947a86..0000000 --- a/tools/pkg/3/pthread_test/pkg.sh +++ /dev/null @@ -1,9 +0,0 @@ -x86_64-linux-gnu-g++ -o "$1/usr/bin/fdpass_test" fdpass.c -fPIC -x86_64-linux-gnu-g++ -o "$1/usr/bin/ucred_test" ucred.c -fPIC -x86_64-linux-gnu-g++ -o "$1/usr/bin/signal_test" signaltest.c -fPIC -x86_64-linux-gnu-g++ -o "$1/usr/bin/shm_test" shm_test.c -fPIC -x86_64-linux-gnu-g++ -o "$1/usr/bin/print_test" print_test.c -fPIC -x86_64-linux-gnu-gcc -o "$1/usr/bin/statx_test" statx_test.c -fPIC -Wno-implicit-function-declaration -x86_64-linux-gnu-gcc -o "$1/usr/bin/alarm_test" alarm_test.c -fPIC -x86_64-linux-gnu-gcc -o "$1/usr/bin/setitimer_test" setitimer_test.c -fPIC -x86_64-linux-gnu-gcc -o "$1/usr/bin/socket_test" socket_test.c -fPIC
\ No newline at end of file diff --git a/tools/pkg/3/pthread_test/print_test.c b/tools/pkg/3/pthread_test/print_test.c deleted file mode 100644 index 50acb7c..0000000 --- a/tools/pkg/3/pthread_test/print_test.c +++ /dev/null @@ -1,37 +0,0 @@ -#define _GNU_SOURCE -#include <dirent.h> /* Содержит структуру linux_dirent64 */ -#include <fcntl.h> -#include <stdio.h> -#include <unistd.h> -#include <sys/syscall.h> - -#define BUF_SIZE 1024 - -struct linux_dirent64 { - unsigned long long d_ino; /* Inode number */ - long long d_off; /* Offset to next dirent */ - unsigned short d_reclen; /* Length of this dirent */ - unsigned char d_type; /* File type */ - char d_name[]; /* Filename (null-terminated) */ -}; - -int main() { - int fd = open(".", O_RDONLY | O_DIRECTORY); - char buf[BUF_SIZE]; - int nread; - - while ((nread = syscall(SYS_getdents64, fd, buf, BUF_SIZE)) > 0) { - for (int bpos = 0; bpos < nread; ) { - struct linux_dirent64 *d = (struct linux_dirent64 *) (buf + bpos); - - // Выводим тип и имя (DT_DIR = каталог, DT_REG = обычный файл) - printf("%-10s %s\n", - (d->d_type == DT_DIR) ? "directory" : "file", - d->d_name); - - bpos += d->d_reclen; // Смещение к следующей записи - } - } - close(fd); - return 0; -}
\ No newline at end of file diff --git a/tools/pkg/3/pthread_test/setitimer_test.c b/tools/pkg/3/pthread_test/setitimer_test.c deleted file mode 100644 index 50ce1c6..0000000 --- a/tools/pkg/3/pthread_test/setitimer_test.c +++ /dev/null @@ -1,98 +0,0 @@ -#include <stdio.h> -#include <sys/time.h> -#include <signal.h> -#include <unistd.h> -#include <string.h> - -volatile sig_atomic_t real_count = 0; -volatile sig_atomic_t virt_count = 0; -volatile sig_atomic_t prof_count = 0; - -void real_timer_handler(int signum) { - real_count++; - printf("REAL timer tick: %d\n", real_count); -} - -void virt_timer_handler(int signum) { - virt_count++; - printf("VIRTUAL timer tick: %d (process CPU time)\n", virt_count); -} - -void prof_timer_handler(int signum) { - prof_count++; - printf("PROF timer tick: %d (process + system CPU time)\n", prof_count); -} - -int main() { - struct sigaction sa; - struct itimerval real_timer, virt_timer, prof_timer; - - // Set up handlers for different timer types - memset(&sa, 0, sizeof(sa)); - - // REAL timer (wall-clock time) - sa.sa_handler = &real_timer_handler; - sigaction(SIGALRM, &sa, NULL); - - // VIRTUAL timer (process CPU time) - sa.sa_handler = &virt_timer_handler; - sigaction(SIGVTALRM, &sa, NULL); - - // PROF timer (process + system CPU time) - sa.sa_handler = &prof_timer_handler; - sigaction(SIGPROF, &sa, NULL); - - // Configure REAL timer (wall-clock) - real_timer.it_value.tv_sec = 1; - real_timer.it_value.tv_usec = 0; - real_timer.it_interval.tv_sec = 2; - real_timer.it_interval.tv_usec = 0; - - // Configure VIRTUAL timer (user CPU time) - virt_timer.it_value.tv_sec = 0; - virt_timer.it_value.tv_usec = 500000; // 0.5 seconds - virt_timer.it_interval.tv_sec = 0; - virt_timer.it_interval.tv_usec = 500000; - - // Configure PROF timer (total CPU time) - prof_timer.it_value.tv_sec = 0; - prof_timer.it_value.tv_usec = 300000; // 0.3 seconds - prof_timer.it_interval.tv_sec = 0; - prof_timer.it_interval.tv_usec = 300000; - - printf("Starting three different timers:\n"); - printf("1. REAL timer: every 2 seconds (SIGALRM)\n"); - printf("2. VIRTUAL timer: every 0.5 seconds of process CPU time (SIGVTALRM)\n"); - printf("3. PROF timer: every 0.3 seconds of total CPU time (SIGPROF)\n"); - - // Start all timers - if (setitimer(ITIMER_REAL, &real_timer, NULL) == -1) { - perror("setitimer REAL"); - return 1; - } - - if (setitimer(ITIMER_VIRTUAL, &virt_timer, NULL) == -1) { - perror("setitimer VIRTUAL"); - return 1; - } - - if (setitimer(ITIMER_PROF, &prof_timer, NULL) == -1) { - perror("setitimer PROF"); - return 1; - } - - // Simulate some CPU work to trigger VIRTUAL and PROF timers - printf("\nDoing CPU-intensive work...\n"); - volatile long i; - while(1) { - asm volatile("nop"); - } - - printf("\nCPU work completed.\n"); - printf("Final counts:\n"); - printf(" REAL timer ticks: %d\n", real_count); - printf(" VIRTUAL timer ticks: %d\n", virt_count); - printf(" PROF timer ticks: %d\n", prof_count); - - return 0; -}
\ No newline at end of file diff --git a/tools/pkg/3/pthread_test/shm_test.c b/tools/pkg/3/pthread_test/shm_test.c deleted file mode 100644 index 5a66d37..0000000 --- a/tools/pkg/3/pthread_test/shm_test.c +++ /dev/null @@ -1,46 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <sys/ipc.h> -#include <sys/shm.h> -#include <string.h> - -#define SHM_SIZE 1024 // size of shared memory segment - -int main() { - key_t key; - int shmid; - char *shmaddr; - - // Generate a unique key for shared memory - key = 100; - - // Create shared memory segment with shmget() - shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0644); - if (shmid == -1) { - perror("shmget"); - exit(1); - } - printf("Shared memory ID: %d\n", shmid); - - // Attach to the shared memory segment with shmat() - shmaddr = (char*) shmat(shmid, NULL, 0); - if (shmaddr == (char*) -1) { - perror("shmat"); - exit(1); - } - - // Write to shared memory - strcpy(shmaddr, "Hello from shared memory!"); - - printf("Data written to shared memory: %s\n", shmaddr); - - // Detach from shared memory with shmdt() - if (shmdt(shmaddr) == -1) { - perror("shmdt"); - exit(1); - } - - // Note: To remove the shared memory segment, use shmctl(shmid, IPC_RMID, NULL); - - return 0; -}
\ No newline at end of file diff --git a/tools/pkg/3/pthread_test/signaltest.c b/tools/pkg/3/pthread_test/signaltest.c deleted file mode 100644 index 1f1f2f8..0000000 --- a/tools/pkg/3/pthread_test/signaltest.c +++ /dev/null @@ -1,72 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <signal.h> -#include <sys/types.h> - -void handle_sigusr1(int sig) { - printf("got SIGUSR1!\n"); - void *ret_addr = __builtin_return_address(0); -} - -void handle_sigusr2(int sig) { - printf("got SIGUSR2!\n"); - void *ret_addr = __builtin_return_address(0); -} - -void test() { - void *ret_addr = __builtin_return_address(0); -} - -int main() { - pid_t pid; - - signal(SIGUSR1, handle_sigusr1); - signal(SIGUSR2, handle_sigusr2); - test(); - - pid = fork(); - - if (pid < 0) { - perror("fork"); - exit(EXIT_FAILURE); - } - - if (pid == 0) { - - printf("child start. pid = %d\n", getpid()); - while (1) { - pause(); - } - } else { - - printf("parent start. pid = %d, child pid = %d\n", getpid(), pid); - sleep(2); - - - printf("parent send SIGUSR1\n"); - kill(pid, SIGUSR1); - - sleep(2); - - printf("parent send SIGUSR2\n"); - kill(pid, SIGUSR2); - - sleep(2); - - printf("parent send SIGUSR1\n"); - kill(pid, SIGUSR1); - - sleep(2); - - printf("parent send SIGUSR2\n"); - kill(pid, SIGUSR2); - - sleep(2); - - kill(pid, SIGTERM); - printf("parent end.\n"); - } - - return 0; -}
\ No newline at end of file diff --git a/tools/pkg/3/pthread_test/socket_test.c b/tools/pkg/3/pthread_test/socket_test.c deleted file mode 100644 index 4f08e08..0000000 --- a/tools/pkg/3/pthread_test/socket_test.c +++ /dev/null @@ -1,175 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <errno.h> - -#define SOCKET_PATH "/tmp/example_socket" -#define BUFFER_SIZE 1024 - -void run_server() { - printf("Starting server...\n"); - - int server_fd, client_fd; - struct sockaddr_un server_addr, client_addr; - socklen_t client_len = sizeof(client_addr); - char buffer[BUFFER_SIZE]; - ssize_t bytes_read; - - // Create socket - server_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (server_fd == -1) { - perror("socket"); - exit(EXIT_FAILURE); - } - - // Remove old socket file if it exists - unlink(SOCKET_PATH); - - // Configure server address - memset(&server_addr, 0, sizeof(server_addr)); - server_addr.sun_family = AF_UNIX; - strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1); - - // Bind socket to address - if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) { - perror("bind"); - close(server_fd); - exit(EXIT_FAILURE); - } - - // Start listening for connections - if (listen(server_fd, 5) == -1) { - perror("listen"); - close(server_fd); - exit(EXIT_FAILURE); - } - - printf("Server listening on %s\n", SOCKET_PATH); - - // Accept connections in a loop - while (1) { - printf("Waiting for connection...\n"); - - client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_len); - if (client_fd == -1) { - perror("accept"); - continue; - } - - printf("Client connected\n"); - - // Read data from client - while ((bytes_read = read(client_fd, buffer, sizeof(buffer) - 1)) > 0) { - buffer[bytes_read] = '\0'; - printf("Received from client: %s", buffer); - - // Send response - char response[BUFFER_SIZE]; - snprintf(response, sizeof(response), "Server received: %s", buffer); - write(client_fd, response, strlen(response)); - - // If client sent "exit", close connection - if (strncmp(buffer, "exit", 4) == 0) { - printf("Client requested exit\n"); - break; - } - } - - if (bytes_read == -1) { - perror("read"); - } - - close(client_fd); - printf("Connection closed\n"); - } - - close(server_fd); - unlink(SOCKET_PATH); -} - -void run_client() { - printf("Starting client...\n"); - - int sock_fd; - struct sockaddr_un server_addr; - char buffer[BUFFER_SIZE]; - ssize_t bytes_read; - - // Create socket - sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock_fd == -1) { - perror("socket"); - exit(EXIT_FAILURE); - } - - // Configure server address - memset(&server_addr, 0, sizeof(server_addr)); - server_addr.sun_family = AF_UNIX; - strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1); - - // Connect to server - if (connect(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) { - perror("connect"); - close(sock_fd); - exit(EXIT_FAILURE); - } - - printf("Connected to server. Enter messages (type 'exit' to quit):\n"); - - // Read user input and send to server - while (1) { - printf("> "); - fflush(stdout); - - if (fgets(buffer, sizeof(buffer), stdin) == NULL) { - break; - } - - // Send message - write(sock_fd, buffer, strlen(buffer)); - - // If user entered "exit", quit - if (strncmp(buffer, "exit", 4) == 0) { - break; - } - - // Read response from server - bytes_read = read(sock_fd, buffer, sizeof(buffer) - 1); - if (bytes_read > 0) { - buffer[bytes_read] = '\0'; - printf("Server response: %s\n", buffer); - } else if (bytes_read == 0) { - printf("Server closed connection\n"); - break; - } else { - perror("read"); - break; - } - } - - close(sock_fd); - printf("Client finished\n"); -} - -int main(int argc, char *argv[]) { - if (argc != 2) { - printf("Usage:\n"); - printf(" %s server - run as server\n", argv[0]); - printf(" %s client - run as client\n", argv[0]); - return EXIT_FAILURE; - } - - if (strcmp(argv[1], "server") == 0) { - run_server(); - } else if (strcmp(argv[1], "client") == 0) { - run_client(); - } else { - printf("Unknown argument: %s\n", argv[1]); - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -}
\ No newline at end of file diff --git a/tools/pkg/3/pthread_test/statx_test.c b/tools/pkg/3/pthread_test/statx_test.c deleted file mode 100644 index 53b6d91..0000000 --- a/tools/pkg/3/pthread_test/statx_test.c +++ /dev/null @@ -1,84 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <time.h> -#include <errno.h> -#include <linux/stat.h> // Required for struct statx definition and constants - -// Helper function to print timestamp in a readable format -void print_timestamp(const char* label, struct statx_timestamp ts) { - char buf[100]; - time_t t = ts.tv_sec; - struct tm tm; - if (localtime_r(&t, &tm) != NULL) { - strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm); - printf("%s: %s.%09u\n", label, buf, ts.tv_nsec); - } else { - printf("%s: [Error converting time]\n", label); - } -} - -int main(int argc, char *argv[]) { - if (argc < 2) { - fprintf(stderr, "Usage: %s <filename>\n", argv[0]); - return EXIT_FAILURE; - } - - const char *pathname = argv[1]; - int dirfd = AT_FDCWD; // Use current working directory - int flags = AT_SYMLINK_NOFOLLOW; // Do not follow symbolic links - unsigned int mask = STATX_ALL; // Request all available information - struct statx stxbuf; - - // Zero out the structure before the call - memset(&stxbuf, 0, sizeof(stxbuf)); - - // Perform the statx system call - long ret = statx(dirfd, pathname, flags, mask, &stxbuf); - - if (ret < 0) { - perror("statx"); - return EXIT_FAILURE; - } - - printf("File: %s\n", pathname); - printf("Mask of returned fields: 0x%x\n", stxbuf.stx_mask); - - if (stxbuf.stx_mask & STATX_SIZE) { - printf("Size: %llu bytes\n", (unsigned long long)stxbuf.stx_size); - } - - if (stxbuf.stx_mask & STATX_BLOCKS) { - printf("Blocks: %llu\n", (unsigned long long)stxbuf.stx_blocks); - } - - if (stxbuf.stx_mask & STATX_MODE) { - printf("Mode: 0%o\n", stxbuf.stx_mode); - } - - if (stxbuf.stx_mask & STATX_UID) { - printf("UID: %u\n", stxbuf.stx_uid); - } - - if (stxbuf.stx_mask & STATX_GID) { - printf("GID: %u\n", stxbuf.stx_gid); - } - - if (stxbuf.stx_mask & STATX_BTIME) { - print_timestamp("Birth Time", stxbuf.stx_btime); - } - - if (stxbuf.stx_mask & STATX_ATIME) { - print_timestamp("Access Time", stxbuf.stx_atime); - } - - if (stxbuf.stx_mask & STATX_MTIME) { - print_timestamp("Modification Time", stxbuf.stx_mtime); - } - - return EXIT_SUCCESS; -} diff --git a/tools/pkg/3/pthread_test/ucred.c b/tools/pkg/3/pthread_test/ucred.c deleted file mode 100644 index e2ba317..0000000 --- a/tools/pkg/3/pthread_test/ucred.c +++ /dev/null @@ -1,173 +0,0 @@ -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <pthread.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/types.h> - -#define SOCKET_PATH "/tmp/my_unix_socket" -#define BUFFER_SIZE 128 - -void* server_thread(void *arg) { - int server_fd, client_fd; - struct sockaddr_un addr; - - server_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (server_fd == -1) { - perror("socket"); - pthread_exit(NULL); - } - - unlink(SOCKET_PATH); - memset(&addr, 0, sizeof(struct sockaddr_un)); - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1); - - if (bind(server_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) { - perror("bind"); - close(server_fd); - pthread_exit(NULL); - } - - if (listen(server_fd, 5) == -1) { - perror("listen"); - close(server_fd); - pthread_exit(NULL); - } - - printf("server start\n"); - - client_fd = accept(server_fd, NULL, NULL); - if (client_fd == -1) { - perror("accept"); - close(server_fd); - pthread_exit(NULL); - } - printf("client connect\n"); - - struct msghdr msg = {0}; - struct iovec iov; - char buf[BUFFER_SIZE]; - - char cmsg_buf[CMSG_SPACE(sizeof(struct ucred))]; - - iov.iov_base = buf; - iov.iov_len = sizeof(buf); - - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = cmsg_buf; - msg.msg_controllen = sizeof(cmsg_buf); - - ssize_t num_bytes = recvmsg(client_fd, &msg, 0); - if (num_bytes == -1) { - perror("recvmsg"); - close(client_fd); - close(server_fd); - unlink(SOCKET_PATH); - pthread_exit(NULL); - } - - printf("got msg: %.*s\n", (int)num_bytes, buf); - - struct ucred *cred = NULL; - struct cmsghdr *cmsg; - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg,cmsg)) { - if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) { - cred = (struct ucred *)CMSG_DATA(cmsg); - break; - } - } - if (cred != NULL) { - printf("uid: %d\n", cred->uid); - printf("gid: %d\n", cred->gid); - printf("pid: %d\n", cred->pid); - } else { - printf("rip\n"); - } - - close(client_fd); - close(server_fd); - unlink(SOCKET_PATH); - pthread_exit(NULL); -} - -void* client_thread(void *arg) { - sleep(1); - - int sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock == -1) { - perror("socket"); - pthread_exit(NULL); - } - - struct sockaddr_un addr; - memset(&addr, 0, sizeof(struct sockaddr_un)); - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1); - - if (connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) { - perror("connect"); - close(sock); - pthread_exit(NULL); - } - - // Внутри client_thread после установки соединения: - struct msghdr msg = {0}; - struct iovec iov; - char message[] = "hi."; - - iov.iov_base = message; - iov.iov_len = strlen(message); - - char cmsg_buf[CMSG_SPACE(sizeof(struct ucred))]; - struct cmsghdr *cmsg; - - struct ucred cred; - cred.pid = getpid(); // текущий pid - cred.uid = getuid(); // текущий uid - cred.gid = getgid(); // текущий gid - - // Формируем управляющее сообщение с учетными данными - msg.msg_control = cmsg_buf; - msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred)); - - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_CREDENTIALS; - cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred)); - - memcpy(CMSG_DATA(cmsg), &cred, sizeof(struct ucred)); - - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - if (sendmsg(sock, &msg, 0) == -1) { - perror("sendmsg"); - } - printf("send manual creds\n"); - close(sock); - pthread_exit(NULL); -} - -int main() { - pthread_t server_tid, client_tid; - - if (pthread_create(&server_tid, NULL, server_thread, NULL) != 0) { - perror("pthread_create server"); - return 1; - } - - if (pthread_create(&client_tid, NULL, client_thread, NULL) != 0) { - perror("pthread_create client"); - return 1; - } - - pthread_join(server_tid, NULL); - pthread_join(client_tid, NULL); - - return 0; -}
\ No newline at end of file diff --git a/tools/pkg/4/xorg-server/diff/1.diff b/tools/pkg/4/xorg-server/diff/1.diff deleted file mode 100644 index 76d9c84..0000000 --- a/tools/pkg/4/xorg-server/diff/1.diff +++ /dev/null @@ -1,401 +0,0 @@ -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Bus.c xorg-server-patched/hw/xfree86/common/xf86Bus.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Bus.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Bus.c 2025-10-23 12:44:22.775506715 +0300 -@@ -556,21 +556,7 @@ - void - xf86PostProbe(void) - { -- if (fbSlotClaimed && ( --#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) -- sbusSlotClaimed || --#endif --#ifdef XSERVER_PLATFORM_BUS -- platformSlotClaimed || --#endif --#ifdef XSERVER_LIBPCIACCESS -- pciSlotClaimed --#else -- TRUE --#endif -- )) -- FatalError("Cannot run in framebuffer mode. Please specify busIDs " -- " for all framebuffer devices\n"); -+ - } - - Bool -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Config.c xorg-server-patched/hw/xfree86/common/xf86Config.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Config.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Config.c 2025-10-18 14:14:41.313332537 +0300 -@@ -49,6 +49,8 @@ - #include <sys/types.h> - #include <grp.h> - -+#include <sys/stat.h> -+ - #include "xf86.h" - #include "xf86Modes.h" - #include "xf86Parser.h" -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Configure.c xorg-server-patched/hw/xfree86/common/xf86Configure.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Configure.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Configure.c 2025-10-18 14:15:07.924147512 +0300 -@@ -27,6 +27,8 @@ - #include <xorg-config.h> - #endif - -+#include <errno.h> -+ - #include "xf86.h" - #include "xf86Config.h" - #include "xf86_OSlib.h" -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Events.c xorg-server-patched/hw/xfree86/common/xf86Events.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Events.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Events.c 2025-10-18 14:15:29.363803215 +0300 -@@ -53,6 +53,8 @@ - #include <xorg-config.h> - #endif - -+#include <errno.h> -+ - #include <X11/X.h> - #include <X11/Xproto.h> - #include <X11/Xatom.h> -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Helper.c xorg-server-patched/hw/xfree86/common/xf86Helper.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Helper.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Helper.c 2025-10-23 14:57:42.305808491 +0300 -@@ -34,6 +34,8 @@ - * different drivers. - */ - -+#include <sys/stat.h> -+ - #ifdef HAVE_XORG_CONFIG_H - #include <xorg-config.h> - #endif -@@ -851,49 +853,65 @@ - xf86SetDpi(ScrnInfoPtr pScrn, int x, int y) - { - MessageType from = X_DEFAULT; -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - xf86MonPtr DDC = (xf86MonPtr) (pScrn->monitor->DDC); -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - int probedWidthmm, probedHeightmm; - int widthErr, heightErr; -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - xf86OutputPtr compat = xf86CompatOutput(pScrn); -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - - /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */ - pScrn->widthmm = pScrn->monitor->widthmm; - pScrn->heightmm = pScrn->monitor->heightmm; -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - - if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0)) { - /* DDC gives display size in mm for individual modes, - * but cm for monitor - */ -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy1\n"); - probedWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */ - probedHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */ -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy1\n"); - } - else if (compat && compat->mm_width > 0 && compat->mm_height > 0) { -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy2\n"); - probedWidthmm = compat->mm_width; - probedHeightmm = compat->mm_height; -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy2\n"); - } - else { -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy3\n"); - probedWidthmm = probedHeightmm = 0; - } - - if (monitorResolution > 0) { -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy4\n"); - pScrn->xDpi = monitorResolution; - pScrn->yDpi = monitorResolution; - from = X_CMDLINE; -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy5\n"); - } - else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) { -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy6\n"); - from = X_CONFIG; - if (pScrn->widthmm > 0) { - pScrn->xDpi = - (int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm); - } -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - if (pScrn->heightmm > 0) { - pScrn->yDpi = - (int) ((double) pScrn->virtualY * MMPERINCH / pScrn->heightmm); - } -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - if (pScrn->xDpi > 0 && pScrn->yDpi <= 0) - pScrn->yDpi = pScrn->xDpi; - if (pScrn->yDpi > 0 && pScrn->xDpi <= 0) - pScrn->xDpi = pScrn->yDpi; -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n", - pScrn->widthmm, pScrn->heightmm); - -@@ -919,8 +937,10 @@ - pScrn->heightmm); - } - } -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - } - else if (probedWidthmm && probedHeightmm) { -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guyZ\n"); - from = X_PROBED; - xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n", - probedWidthmm, probedHeightmm); -@@ -940,6 +960,7 @@ - pScrn->xDpi = pScrn->yDpi; - } - else { -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guyX\n"); - if (x > 0) - pScrn->xDpi = x; - else -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Init.c xorg-server-patched/hw/xfree86/common/xf86Init.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Init.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Init.c 2025-10-18 14:17:21.699226880 +0300 -@@ -34,6 +34,8 @@ - #include <xorg-config.h> - #endif - -+#include <sys/stat.h> -+ - #include <stdlib.h> - #include <errno.h> - -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Mode.c xorg-server-patched/hw/xfree86/common/xf86Mode.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Mode.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Mode.c 2025-10-23 14:29:02.407987453 +0300 -@@ -2118,5 +2118,6 @@ - if (hsync != 0 && refresh != 0) - xf86PrintModeline(scrp->scrnIndex, p); - p = p->next; -+ - } while (p != NULL && p != scrp->modes); - } -diff -Naur xorg-server-21.1.0/hw/xfree86/fbdevhw/fbdevhw.c xorg-server-patched/hw/xfree86/fbdevhw/fbdevhw.c ---- xorg-server-21.1.0/hw/xfree86/fbdevhw/fbdevhw.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/fbdevhw/fbdevhw.c 2025-10-19 09:37:47.188152245 +0300 -@@ -9,13 +9,10 @@ - #include "xf86Modes.h" - #include "xf86_OSproc.h" - --/* pci stuff */ --#include "xf86Pci.h" -- - #include "xf86cmap.h" - - #include "fbdevhw.h" --#include "fbpriv.h" -+#include <linux/fb.h> - #include "globals.h" - #include <X11/extensions/dpmsconst.h> - -@@ -253,57 +250,6 @@ - mode->CrtcVAdjusted = FALSE; - } - --/* -------------------------------------------------------------------- */ --/* open correct framebuffer device */ -- --/** -- * Try to find the framebuffer device for a given PCI device -- */ --static int --fbdev_open_pci(struct pci_device *pPci, char **namep) --{ -- struct fb_fix_screeninfo fix; -- char filename[256]; -- int fd, i; -- -- for (i = 0; i < 8; i++) { -- snprintf(filename, sizeof(filename), -- "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics/fb%d", -- pPci->domain, pPci->bus, pPci->dev, pPci->func, i); -- -- fd = open(filename, O_RDONLY, 0); -- if (fd < 0) { -- snprintf(filename, sizeof(filename), -- "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics:fb%d", -- pPci->domain, pPci->bus, pPci->dev, pPci->func, i); -- fd = open(filename, O_RDONLY, 0); -- } -- if (fd >= 0) { -- close(fd); -- snprintf(filename, sizeof(filename), "/dev/fb%d", i); -- -- fd = open(filename, O_RDWR, 0); -- if (fd != -1) { -- if (ioctl(fd, FBIOGET_FSCREENINFO, (void *) &fix) != -1) { -- if (namep) { -- *namep = xnfalloc(16); -- strncpy(*namep, fix.id, 16); -- } -- -- return fd; -- } -- close(fd); -- } -- } -- } -- -- if (namep) -- *namep = NULL; -- -- xf86DrvMsg(-1, X_ERROR, "Unable to find a valid framebuffer device\n"); -- return -1; --} -- - static int - fbdev_open(int scrnIndex, const char *dev, char **namep) - { -@@ -329,22 +275,6 @@ - return -1; - } - -- /* only touch non-PCI devices on this path */ -- { -- char buf[PATH_MAX] = {0}; -- char *sysfs_path = NULL; -- char *node = strrchr(dev, '/') + 1; -- -- if (asprintf(&sysfs_path, "/sys/class/graphics/%s", node) < 0 || -- readlink(sysfs_path, buf, sizeof(buf) - 1) < 0 || -- strstr(buf, "devices/pci")) { -- free(sysfs_path); -- close(fd); -- return -1; -- } -- free(sysfs_path); -- } -- - if (namep) { - if (-1 == ioctl(fd, FBIOGET_FSCREENINFO, (void *) (&fix))) { - *namep = NULL; -@@ -363,14 +293,12 @@ - /* -------------------------------------------------------------------- */ - - Bool --fbdevHWProbe(struct pci_device *pPci, char *device, char **namep) -+fbdevHWProbe(void *pPci, char *device, char **namep) - { - int fd; -- -- if (pPci) -- fd = fbdev_open_pci(pPci, namep); -- else -- fd = fbdev_open(-1, device, namep); -+ -+ fd = fbdev_open(-1, device, namep); -+ - - if (-1 == fd) - return FALSE; -@@ -379,18 +307,15 @@ - } - - Bool --fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device *pPci, char *device) -+fbdevHWInit(ScrnInfoPtr pScrn, void *pPci, char *device) - { - fbdevHWPtr fPtr; - - fbdevHWGetRec(pScrn); - fPtr = FBDEVHWPTR(pScrn); - -- /* open device */ -- if (pPci) -- fPtr->fd = fbdev_open_pci(pPci, NULL); -- else -- fPtr->fd = fbdev_open(pScrn->scrnIndex, device, NULL); -+ fPtr->fd = fbdev_open(pScrn->scrnIndex, device, NULL); -+ - if (-1 == fPtr->fd) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to open framebuffer device, consult warnings" -diff -Naur xorg-server-21.1.0/hw/xfree86/fbdevhw/fbdevhw.h xorg-server-patched/hw/xfree86/fbdevhw/fbdevhw.h ---- xorg-server-21.1.0/hw/xfree86/fbdevhw/fbdevhw.h 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/fbdevhw/fbdevhw.h 2025-10-19 09:38:08.190818849 +0300 -@@ -16,9 +16,9 @@ - - extern _X_EXPORT int fbdevHWGetFD(ScrnInfoPtr pScrn); - --extern _X_EXPORT Bool fbdevHWProbe(struct pci_device *pPci, char *device, -+extern _X_EXPORT Bool fbdevHWProbe(void *pPci, char *device, - char **namep); --extern _X_EXPORT Bool fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device *pPci, -+extern _X_EXPORT Bool fbdevHWInit(ScrnInfoPtr pScrn, void *pPci, - char *device); - - extern _X_EXPORT char *fbdevHWGetName(ScrnInfoPtr pScrn); -diff -Naur xorg-server-21.1.0/hw/xfree86/os-support/shared/posix_tty.c xorg-server-patched/hw/xfree86/os-support/shared/posix_tty.c ---- xorg-server-21.1.0/hw/xfree86/os-support/shared/posix_tty.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/os-support/shared/posix_tty.c 2025-10-18 14:18:16.925903537 +0300 -@@ -56,6 +56,9 @@ - #include <xorg-config.h> - #endif - -+#include <termios.h> -+#include <errno.h> -+ - #include <X11/X.h> - #include <xserver_poll.h> - #include "xf86.h" -diff -Naur xorg-server-21.1.0/hw/xfree86/os-support/shared/sigio.c xorg-server-patched/hw/xfree86/os-support/shared/sigio.c ---- xorg-server-21.1.0/hw/xfree86/os-support/shared/sigio.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/os-support/shared/sigio.c 2025-10-18 14:18:36.612500292 +0300 -@@ -56,6 +56,9 @@ - #include <xorg-config.h> - #endif - -+#include <sys/stat.h> -+#include <errno.h> -+ - #include <X11/X.h> - #include <xserver_poll.h> - #include "xf86.h" -diff -Naur xorg-server-21.1.0/include/os.h xorg-server-patched/include/os.h ---- xorg-server-21.1.0/include/os.h 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/include/os.h 2025-10-18 14:19:09.429494076 +0300 -@@ -51,6 +51,7 @@ - #include <stdarg.h> - #include <stdint.h> - #include <string.h> -+#include <strings.h> - #ifdef MONOTONIC_CLOCK - #include <time.h> - #endif -diff -Naur xorg-server-21.1.0/os/access.c xorg-server-patched/os/access.c ---- xorg-server-21.1.0/os/access.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/os/access.c 2025-10-18 14:19:29.654105938 +0300 -@@ -116,7 +116,7 @@ - #endif - #endif - --#if defined(SVR4) || (defined(SYSV) && defined(__i386__)) || defined(__GNU__) -+#if defined(SVR4) || (defined(SYSV) && defined(__i386__)) || defined(__GNU__) || defined(__orange__) - #include <sys/utsname.h> - #endif - #if defined(SYSV) && defined(__i386__) -diff -Naur xorg-server-21.1.0/os/ospoll.c xorg-server-patched/os/ospoll.c ---- xorg-server-21.1.0/os/ospoll.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/os/ospoll.c 2025-10-18 14:20:06.530220468 +0300 -@@ -45,12 +45,6 @@ - #define HAVE_OSPOLL 1 - #endif - --#if !HAVE_OSPOLL && defined(HAVE_EPOLL_CREATE1) --#include <sys/epoll.h> --#define EPOLL 1 --#define HAVE_OSPOLL 1 --#endif -- - #if !HAVE_OSPOLL - #include "xserver_poll.h" - #define POLL 1 diff --git a/tools/pkg/4/xorg-server/diff/libgpg-error.diff b/tools/pkg/4/xorg-server/diff/libgpg-error.diff deleted file mode 100644 index f936e08..0000000 --- a/tools/pkg/4/xorg-server/diff/libgpg-error.diff +++ /dev/null @@ -1,53 +0,0 @@ -diff -Naur libgpg-error-1.45/build-aux/config.sub libgpg-error-patched3/build-aux/config.sub ---- libgpg-error-1.45/build-aux/config.sub 2018-10-24 11:00:20.000000000 +0300 -+++ libgpg-error-patched3/build-aux/config.sub 2025-10-15 14:39:02.553948824 +0300 -@@ -1358,7 +1358,7 @@ - | os2* | vos* | palmos* | uclinux* | nucleus* \ - | morphos* | superux* | rtmk* | windiss* \ - | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ -- | skyos* | haiku* | rdos* | toppers* | drops* | es* \ -+ | skyos* | orange* | haiku* | rdos* | toppers* | drops* | es* \ - | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ - | midnightbsd*) - # Remember, each alternative MUST END IN *, to match a version number. -diff -Naur libgpg-error-1.45/src/syscfg/lock-obj-pub.orange.h libgpg-error-patched3/src/syscfg/lock-obj-pub.orange.h ---- libgpg-error-1.45/src/syscfg/lock-obj-pub.orange.h 1970-01-01 03:00:00.000000000 +0300 -+++ libgpg-error-patched3/src/syscfg/lock-obj-pub.orange.h 2018-10-12 18:12:38.000000000 +0300 -@@ -0,0 +1,25 @@ -+## lock-obj-pub.x86_64-pc-linux-gnu.h -+## File created by gen-posix-lock-obj - DO NOT EDIT -+## To be included by mkheader into gpg-error.h -+ -+typedef struct -+{ -+ long _vers; -+ union { -+ volatile char _priv[40]; -+ long _x_align; -+ long *_xp_align; -+ } u; -+} gpgrt_lock_t; -+ -+#define GPGRT_LOCK_INITIALIZER {1,{{0,0,0,0,0,0,0,0, \ -+ 0,0,0,0,0,0,0,0, \ -+ 0,0,0,0,0,0,0,0, \ -+ 0,0,0,0,0,0,0,0, \ -+ 0,0,0,0,0,0,0,0}}} -+## -+## Local Variables: -+## mode: c -+## buffer-read-only: t -+## End: -+## -diff -Naur libgpg-error-1.45/tests/t-printf.c libgpg-error-patched3/tests/t-printf.c ---- libgpg-error-1.45/tests/t-printf.c 2018-12-12 11:14:31.000000000 +0300 -+++ libgpg-error-patched3/tests/t-printf.c 2025-10-15 14:44:20.729513269 +0300 -@@ -449,7 +449,7 @@ - static void - check_fprintf_sf (void) - { -- volatile char *nullptr = NULL; /* Avoid compiler warning. */ -+ - struct sfstate_s sfstate = {NULL}; - gpgrt_stream_t stream; - const char *expect; diff --git a/tools/pkg/4/xorg-server/diff/openssl.diff b/tools/pkg/4/xorg-server/diff/openssl.diff deleted file mode 100644 index c1c65a5..0000000 --- a/tools/pkg/4/xorg-server/diff/openssl.diff +++ /dev/null @@ -1,40 +0,0 @@ -diff --git openssl-clean/Configurations/10-main.conf openssl-workdir/Configurations/10-main.conf -index 2a047ca..357fd04 100644 ---- openssl-clean/Configurations/10-main.conf -+++ openssl-workdir/Configurations/10-main.conf -@@ -192,6 +192,35 @@ my %targets = ( - thread_scheme => "(unknown)", - }, - -+#### Oranges config -+ "orange-generic64" => { -+ inherit_from => [ "BASE_unix" ], -+ CFLAGS => picker(default => "-Wall", -+ debug => "-O0 -g", -+ release => "-O3"), -+ CXXFLAGS => picker(default => "-Wall", -+ debug => "-O0 -g", -+ release => "-O3"), -+ cxxflags => add("-std=c++11"), -+ lib_cppflags => combine("-DOPENSSL_USE_NODELETE", "-DL_ENDIAN"), -+ bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ shared_target => "linux-shared", -+ shared_cflag => "-fPIC", -+ shared_ldflag => sub { $disabled{pinshared} ? () : "-Wl,-znodelete" }, -+ shared_extension => ".so.\$(SHLIB_VERSION_NUMBER)", -+ }, -+ -+ "x86_64-orange-mlibc" => { -+ inherit_from => [ "orange-generic64", asm("x86_64_asm") ], -+ perlasm_scheme => "elf", -+ -+ CC => "x86_64-orange-mlibc-gcc", -+ CXX => "x86_64-orange-mlibcss-g++", -+ -+ }, -+ - #### VOS Configurations - "vos-gcc" => { - inherit_from => [ "BASE_unix" ],
\ No newline at end of file diff --git a/tools/pkg/4/xorg-server/diff/xfbdev.diff b/tools/pkg/4/xorg-server/diff/xfbdev.diff deleted file mode 100644 index 602adc5..0000000 --- a/tools/pkg/4/xorg-server/diff/xfbdev.diff +++ /dev/null @@ -1,51 +0,0 @@ -diff --git xf86-video-fbdev-clean/src/Makefile.in xf86-video-fbdev-workdir/src/Makefile.in -index 016d61d..84213a5 100644 ---- xf86-video-fbdev-clean/src/Makefile.in -+++ xf86-video-fbdev-workdir/src/Makefile.in -@@ -373,7 +373,7 @@ top_srcdir = @top_srcdir@ - # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. - AM_CFLAGS = $(BASE_CFLAGS) $(XORG_CFLAGS) - fbdev_drv_la_LTLIBRARIES = fbdev_drv.la --fbdev_drv_la_LDFLAGS = -module -avoid-version -+fbdev_drv_la_LDFLAGS = -module -avoid-version -L/ -lfbdevhw -lshadow - fbdev_drv_ladir = @moduledir@/drivers - fbdev_drv_la_SOURCES = \ - fbdev.c -diff --git xf86-video-fbdev-clean/src/fbdev.c xf86-video-fbdev-workdir/src/fbdev.c -index 939c5b8..4ec1ccb 100644 ---- xf86-video-fbdev-clean/src/fbdev.c -+++ xf86-video-fbdev-workdir/src/fbdev.c -@@ -331,7 +331,7 @@ FBDevProbe(DriverPtr drv, int flags) - - dev = xf86FindOptionValue(devSections[i]->options,"fbdev"); - if (devSections[i]->busID) { --#ifndef XSERVER_LIBPCIACCESS -+#ifdef XSERVER_LIBPCIACCESS - if (xf86ParsePciBusString(devSections[i]->busID,&bus,&device, - &func)) { - if (!xf86CheckPciSlot(bus,device,func)) -@@ -343,7 +343,7 @@ FBDevProbe(DriverPtr drv, int flags) - if (fbdevHWProbe(NULL,dev,NULL)) { - pScrn = NULL; - if (isPci) { --#ifndef XSERVER_LIBPCIACCESS -+#ifdef XSERVER_LIBPCIACCESS - /* XXX what about when there's no busID set? */ - int entity; - -@@ -419,6 +419,7 @@ FBDevPreInit(ScrnInfoPtr pScrn, int flags) - fPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); - - #ifndef XSERVER_LIBPCIACCESS -+#if 0 - pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; - /* XXX Is this right? Can probably remove RAC_FB */ - pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; -@@ -429,6 +430,7 @@ FBDevPreInit(ScrnInfoPtr pScrn, int flags) - "xf86RegisterResources() found resource conflicts\n"); - return FALSE; - } -+#endif - #else - if (fPtr->pEnt->location.type == BUS_PCI) - pci_dev = fPtr->pEnt->location.id.pci;
\ No newline at end of file diff --git a/tools/pkg/4/xorg-server/diff/xkeyboard.diff b/tools/pkg/4/xorg-server/diff/xkeyboard.diff deleted file mode 100644 index f3cbff5..0000000 --- a/tools/pkg/4/xorg-server/diff/xkeyboard.diff +++ /dev/null @@ -1,246 +0,0 @@ -diff --git xf86-input-keyboard-clean/configure xf86-input-keyboard-workdir/configure -index 76f1212..c2b8867 100755 ---- xf86-input-keyboard-clean/configure -+++ xf86-input-keyboard-workdir/configure -@@ -664,6 +664,8 @@ SOLARIS_FALSE - SOLARIS_TRUE - BSD_FALSE - BSD_TRUE -+ORANGE_FALSE -+ORANGE_TRUE - OS_FLAGS - inputdir - XORG_LIBS -@@ -19840,6 +19842,10 @@ inputdir=${moduledir}/input - - # The keyboard driver code is O/S specific - case $host_os in -+ orange*) -+ IS_ORANGE="yes" -+ ;; -+ - linux*) - as_fn_error $? "This is not the keyboard driver you are looking for. Use evdev or libinput." "$LINENO" 5 - ;; -@@ -19878,6 +19884,14 @@ case $host_os in - esac - - -+ if test "x$IS_ORANGE" = xyes; then -+ ORANGE_TRUE= -+ ORANGE_FALSE='#' -+else -+ ORANGE_TRUE='#' -+ ORANGE_FALSE= -+fi -+ - if test "x$IS_BSD" = xyes; then - BSD_TRUE= - BSD_FALSE='#' -@@ -20053,6 +20067,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ORANGE_TRUE}" && test -z "${ORANGE_FALSE}"; then -+ as_fn_error $? "conditional \"ORANGE\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${BSD_TRUE}" && test -z "${BSD_FALSE}"; then - as_fn_error $? "conditional \"BSD\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git xf86-input-keyboard-clean/src/Makefile.in xf86-input-keyboard-workdir/src/Makefile.in -index 6daf679..9a63513 100644 ---- xf86-input-keyboard-clean/src/Makefile.in -+++ xf86-input-keyboard-workdir/src/Makefile.in -@@ -113,6 +113,7 @@ host_triplet = @host@ - @BSD_TRUE@am__append_1 = $(BSD_SRCS) - @SOLARIS_TRUE@am__append_2 = $(SOLARIS_SRCS) - @HURD_TRUE@am__append_3 = $(HURD_SRCS) -+@ORANGE_TRUE@am__append_4 = $(ORANGE_SRCS) - subdir = src - ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 - am__aclocal_m4_deps = $(top_srcdir)/configure.ac -@@ -155,15 +156,17 @@ am__DEPENDENCIES_1 = - kbd_drv_la_DEPENDENCIES = $(am__DEPENDENCIES_1) - am__kbd_drv_la_SOURCES_DIST = kbd.c xf86OSKbd.h xf86Keymap.h \ - atKeynames.h bsd_KbdMap.c bsd_kbd.c bsd_kbd.h at_scancode.c \ -- sun_kbd.c sun_kbd.h sun_kbdMap.c hurd_kbd.c -+ sun_kbd.c sun_kbd.h sun_kbdMap.c hurd_kbd.c orange_kbd.c - am__objects_1 = bsd_KbdMap.lo bsd_kbd.lo at_scancode.lo - @BSD_TRUE@am__objects_2 = $(am__objects_1) - am__objects_3 = sun_kbd.lo sun_kbdMap.lo - @SOLARIS_TRUE@am__objects_4 = $(am__objects_3) - am__objects_5 = hurd_kbd.lo at_scancode.lo - @HURD_TRUE@am__objects_6 = $(am__objects_5) -+am__objects_7 = orange_kbd.lo at_scancode.lo -+@ORANGE_TRUE@am__objects_8 = $(am__objects_7) - am_kbd_drv_la_OBJECTS = kbd.lo $(am__objects_2) $(am__objects_4) \ -- $(am__objects_6) -+ $(am__objects_6) $(am__objects_8) - kbd_drv_la_OBJECTS = $(am_kbd_drv_la_OBJECTS) - AM_V_lt = $(am__v_lt_@AM_V@) - am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -@@ -189,7 +192,7 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp - am__maybe_remake_depfiles = depfiles - am__depfiles_remade = ./$(DEPDIR)/at_scancode.Plo \ - ./$(DEPDIR)/bsd_KbdMap.Plo ./$(DEPDIR)/bsd_kbd.Plo \ -- ./$(DEPDIR)/hurd_kbd.Plo ./$(DEPDIR)/kbd.Plo \ -+ ./$(DEPDIR)/hurd_kbd.Plo ./$(DEPDIR)/orange_kbd.Plo ./$(DEPDIR)/kbd.Plo \ - ./$(DEPDIR)/sun_kbd.Plo ./$(DEPDIR)/sun_kbdMap.Plo - am__mv = mv -f - COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ -@@ -388,13 +391,14 @@ AM_CFLAGS = $(XORG_CFLAGS) $(CWARNFLAGS) $(OS_FLAGS) - kbd_drv_la_LTLIBRARIES = kbd_drv.la - kbd_drv_la_LDFLAGS = -avoid-version -module - kbd_drv_la_SOURCES = kbd.c xf86OSKbd.h xf86Keymap.h atKeynames.h \ -- $(am__append_1) $(am__append_2) $(am__append_3) -+ $(am__append_1) $(am__append_2) $(am__append_3) $(am__append_4) - kbd_drv_la_LIBADD = $(XORG_LIBS) - kbd_drv_ladir = @inputdir@ -+ORANGE_SRCS = orange_kbd.c at_scancode.c - BSD_SRCS = bsd_KbdMap.c bsd_kbd.c bsd_kbd.h at_scancode.c - HURD_SRCS = hurd_kbd.c at_scancode.c - SOLARIS_SRCS = sun_kbd.c sun_kbd.h sun_kbdMap.c --EXTRA_DIST = $(BSD_SRCS) $(HURD_SRCS) $(SOLARIS_SRCS) -+EXTRA_DIST = $(ORANGE_SRCS) $(BSD_SRCS) $(HURD_SRCS) $(SOLARIS_SRCS) - all: all-am - - .SUFFIXES: -@@ -475,6 +479,7 @@ distclean-compile: - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd_KbdMap.Plo@am__quote@ # am--include-marker - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd_kbd.Plo@am__quote@ # am--include-marker - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hurd_kbd.Plo@am__quote@ # am--include-marker -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orange_kbd.Plo@am__quote@ # am--include-marker - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbd.Plo@am__quote@ # am--include-marker - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sun_kbd.Plo@am__quote@ # am--include-marker - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sun_kbdMap.Plo@am__quote@ # am--include-marker -@@ -643,6 +648,7 @@ distclean: distclean-am - -rm -f ./$(DEPDIR)/bsd_KbdMap.Plo - -rm -f ./$(DEPDIR)/bsd_kbd.Plo - -rm -f ./$(DEPDIR)/hurd_kbd.Plo -+ -rm -f ./$(DEPDIR)/orange_kbd.Plo - -rm -f ./$(DEPDIR)/kbd.Plo - -rm -f ./$(DEPDIR)/sun_kbd.Plo - -rm -f ./$(DEPDIR)/sun_kbdMap.Plo -@@ -695,6 +701,7 @@ maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/bsd_KbdMap.Plo - -rm -f ./$(DEPDIR)/bsd_kbd.Plo - -rm -f ./$(DEPDIR)/hurd_kbd.Plo -+ -rm -f ./$(DEPDIR)/orange_kbd.Plo - -rm -f ./$(DEPDIR)/kbd.Plo - -rm -f ./$(DEPDIR)/sun_kbd.Plo - -rm -f ./$(DEPDIR)/sun_kbdMap.Plo -diff --git xf86-input-keyboard-workdir/src/orange_kbd.c xf86-input-keyboard-workdir/src/orange_kbd.c -new file mode 100644 -index 0000000..3f20d5c ---- /dev/null -+++ xf86-input-keyboard-workdir/src/orange_kbd.c -@@ -0,0 +1,108 @@ -+#ifdef HAVE_CONFIG_H -+#include <config.h> -+#endif -+ -+#include <X11/X.h> -+#include <xorg-server.h> -+ -+#include "compiler.h" -+ -+#include "xf86.h" -+#include "xf86Priv.h" -+#include "xf86_OSlib.h" -+ -+#include "atKeynames.h" -+#include "xf86Keymap.h" -+#include "xf86OSKbd.h" -+#include "xf86Xinput.h" -+ -+#include <assert.h> -+#include <errno.h> -+#include <stdio.h> -+#include <sys/file.h> -+#include <sys/ioctl.h> -+#include <sys/time.h> -+ -+static int KbdOn(InputInfoPtr pInfo, int what) { -+ return Success; -+} -+ -+static int KbdOff(InputInfoPtr pInfo, int what) { -+ printf("kbdOff is a stub!\n"); -+ return -1; -+} -+ -+static void SoundKbdBell(InputInfoPtr pInfo, int loudness, int pitch, int duration) { -+ printf("SoundKbdBell is a stub!\n"); -+} -+ -+static void SetKbdLeds(InputInfoPtr pInfo, int leds) { -+ printf("SetKbdLeds: is a stub!\n"); -+} -+ -+static int GetKbdLeds(InputInfoPtr pInfo) { -+ printf("GetKbdLeds is a stub!\n"); -+ return -1; -+} -+ -+// Save the initial keyboard state. This function is called at the start -+// of each server generation. -+static int KbdInit(InputInfoPtr pInfo, int what) { -+ return Success; -+} -+ -+static void KbdGetMapping(InputInfoPtr pInfo, KeySymsPtr pKeySyms, CARD8 *pModMap) { -+ printf("KbdGetMapping is a stub!\n"); -+} -+ -+static void ReadInput(InputInfoPtr pInfo) { -+ KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; -+ -+ uint8_t scancodes[64]; -+ ssize_t result = read(pInfo->fd, scancodes, sizeof(scancodes)); -+ if (result > 0) { -+ for (ssize_t i = 0; i < result; i++) { -+ pKbd->PostEvent(pInfo, scancodes[i] & 0x7f, scancodes[i] & 0x80 ? FALSE : TRUE); -+ } -+ } -+} -+ -+static Bool OpenKeyboard(InputInfoPtr pInfo) { -+ char *kbdPath = xf86SetStrOption(pInfo->options, "Device", "/dev/ps2keyboard"); -+ Bool ret; -+ -+ pInfo->fd = open(kbdPath, O_RDONLY | O_NONBLOCK); -+ -+ if (pInfo->fd == -1) { -+ xf86Msg(X_ERROR, "%s: cannot open \"%s\"\n", pInfo->name, kbdPath); -+ ret = FALSE; -+ } else { -+ xf86MsgVerb(X_INFO, 3, "%s: opened device \"%s\"\n", pInfo->name, kbdPath); -+ pInfo->read_input = ReadInput; -+ ret = TRUE; -+ -+ // in case it wasn't set and we fell back to default. -+ xf86ReplaceStrOption(pInfo->options, "Device", kbdPath); -+ } -+ -+ free(kbdPath); -+ return ret; -+} -+ -+Bool xf86OSKbdPreInit(InputInfoPtr pInfo) { -+ KbdDevPtr pKbd = pInfo->private; -+ -+ pKbd->KbdInit = KbdInit; -+ pKbd->KbdOn = KbdOn; -+ pKbd->KbdOff = KbdOff; -+ pKbd->Bell = SoundKbdBell; -+ pKbd->SetLeds = SetKbdLeds; -+ pKbd->GetLeds = GetKbdLeds; -+ pKbd->KbdGetMapping = KbdGetMapping; -+ pKbd->OpenKeyboard = OpenKeyboard; -+ -+ pKbd->RemapScanCode = NULL; -+ pKbd->private = NULL; -+ -+ return TRUE; -+} diff --git a/tools/pkg/4/xorg-server/diff/xorgproto.diff b/tools/pkg/4/xorg-server/diff/xorgproto.diff deleted file mode 100644 index 3e9a617..0000000 --- a/tools/pkg/4/xorg-server/diff/xorgproto.diff +++ /dev/null @@ -1,196 +0,0 @@ -diff -Naur xorgproto-2022.2/include/X11/Xfuncs.h xorgproto-patched/include/X11/Xfuncs.h ---- xorgproto-2022.2/include/X11/Xfuncs.h 2022-08-11 03:16:33.000000000 +0300 -+++ xorgproto-patched/include/X11/Xfuncs.h 2025-11-21 18:56:53.536537225 +0300 -@@ -32,25 +32,10 @@ - /* the old Xfuncs.h, for pre-R6 */ - # if !(defined(XFree86LOADER) && defined(IN_MODULE)) - --# ifdef X_USEBFUNCS --void bcopy(); --void bzero(); --int bcmp(); --# else --# if defined(SYSV) && !defined(__SCO__) && !defined(__sun) && !defined(__UNIXWARE__) && !defined(_AIX) --# include <memory.h> --void bcopy(); --# define bzero(b,len) memset(b, 0, len) --# define bcmp(b1,b2,len) memcmp(b1, b2, len) --# else --# include <string.h> --# if defined(__SCO__) || defined(__sun) || defined(__UNIXWARE__) || defined(__CYGWIN__) || defined(_AIX) || defined(__APPLE__) --# include <strings.h> --# endif --# define _XFUNCS_H_INCLUDED_STRING_H --# endif --# endif /* X_USEBFUNCS */ -+#include <string.h> -+#include <strings.h> - -+#define _XFUNCS_H_INCLUDED_STRING_H - /* the new Xfuncs.h */ - - /* the ANSI C way */ -diff -Naur xorgproto-2022.2/include/X11/Xos.h xorgproto-patched/include/X11/Xos.h ---- xorgproto-2022.2/include/X11/Xos.h 2022-08-11 03:16:33.000000000 +0300 -+++ xorgproto-patched/include/X11/Xos.h 2025-11-21 18:30:22.452371100 +0300 -@@ -60,7 +60,7 @@ - */ - - # include <string.h> --# if defined(__SCO__) || defined(__UNIXWARE__) || defined(__sun) || defined(__CYGWIN__) || defined(_AIX) || defined(__APPLE__) -+# if defined(__SCO__) || defined(__UNIXWARE__) || defined(__sun) || defined(__CYGWIN__) || defined(_AIX) || defined(__APPLE__) || defined(__orange__) - # include <strings.h> - # else - # ifndef index -diff -Naur xorgproto-2022.2/include/X11/Xos.h.orig xorgproto-patched/include/X11/Xos.h.orig ---- xorgproto-2022.2/include/X11/Xos.h.orig 1970-01-01 03:00:00.000000000 +0300 -+++ xorgproto-patched/include/X11/Xos.h.orig 2025-11-21 18:29:57.017706783 +0300 -@@ -0,0 +1,148 @@ -+/* -+ * -+Copyright 1987, 1998 The Open Group -+ -+Permission to use, copy, modify, distribute, and sell this software and its -+documentation for any purpose is hereby granted without fee, provided that -+the above copyright notice appear in all copies and that both that -+copyright notice and this permission notice appear in supporting -+documentation. -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+Except as contained in this notice, the name of The Open Group shall not be -+used in advertising or otherwise to promote the sale, use or other dealings -+in this Software without prior written authorization from The Open Group. -+ * -+ * The X Window System is a Trademark of The Open Group. -+ * -+ */ -+ -+/* This is a collection of things to try and minimize system dependencies -+ * in a "significant" number of source files. -+ */ -+ -+#ifndef _XOS_H_ -+# define _XOS_H_ -+ -+# include <X11/Xosdefs.h> -+ -+/* -+ * Get major data types (esp. caddr_t) -+ */ -+ -+# include <sys/types.h> -+ -+# if defined(__SCO__) || defined(__UNIXWARE__) -+# include <stdint.h> -+# endif -+ -+ -+/* -+ * Just about everyone needs the strings routines. We provide both forms here, -+ * index/rindex and strchr/strrchr, so any systems that don't provide them all -+ * need to have #defines here. -+ * -+ * These macros are defined this way, rather than, e.g.: -+ * #defined index(s,c) strchr(s,c) -+ * because someone might be using them as function pointers, and such -+ * a change would break compatibility for anyone who's relying on them -+ * being the way they currently are. So we're stuck with them this way, -+ * which can be really inconvenient. :-( -+ */ -+ -+# include <string.h> -+# if defined(__SCO__) || defined(__UNIXWARE__) || defined(__sun) || defined(__CYGWIN__) || defined(_AIX) || defined(__APPLE__) -+# include <strings.h> -+# else -+# ifndef index -+# define index(s,c) (strchr((s),(c))) -+# endif -+# ifndef rindex -+# define rindex(s,c) (strrchr((s),(c))) -+# endif -+# endif -+ -+/* -+ * Get open(2) constants -+ */ -+# if defined(X_NOT_POSIX) -+# include <fcntl.h> -+# if defined(USL) || defined(__i386__) && (defined(SYSV) || defined(SVR4)) -+# include <unistd.h> -+# endif -+# ifdef WIN32 -+# include <X11/Xw32defs.h> -+# else -+# include <sys/file.h> -+# endif -+# else /* X_NOT_POSIX */ -+# include <fcntl.h> -+# include <unistd.h> -+# endif /* X_NOT_POSIX else */ -+ -+/* -+ * Get struct timeval and struct tm -+ */ -+ -+# if defined(_POSIX_SOURCE) && defined(SVR4) -+/* need to omit _POSIX_SOURCE in order to get what we want in SVR4 */ -+# undef _POSIX_SOURCE -+# include <sys/time.h> -+# define _POSIX_SOURCE -+# elif defined(WIN32) -+# include <time.h> -+# if !defined(_WINSOCKAPI_) && !defined(_WILLWINSOCK_) && !defined(_TIMEVAL_DEFINED) && !defined(_STRUCT_TIMEVAL) -+struct timeval { -+ long tv_sec; /* seconds */ -+ long tv_usec; /* and microseconds */ -+}; -+# define _TIMEVAL_DEFINED -+# endif -+# include <sys/timeb.h> -+# define gettimeofday(t) \ -+{ \ -+ struct _timeb _gtodtmp; \ -+ _ftime (&_gtodtmp); \ -+ (t)->tv_sec = _gtodtmp.time; \ -+ (t)->tv_usec = _gtodtmp.millitm * 1000; \ -+} -+# else -+# include <sys/time.h> -+# include <time.h> -+# endif /* defined(_POSIX_SOURCE) && defined(SVR4) */ -+ -+/* define X_GETTIMEOFDAY macro, a portable gettimeofday() */ -+# if defined(_XOPEN_XPG4) || defined(_XOPEN_UNIX) /* _XOPEN_UNIX is XPG4.2 */ -+# define X_GETTIMEOFDAY(t) gettimeofday(t, (struct timezone*)0) -+# else -+# if defined(SVR4) || defined(__SVR4) || defined(WIN32) -+# define X_GETTIMEOFDAY(t) gettimeofday(t) -+# else -+# define X_GETTIMEOFDAY(t) gettimeofday(t, (struct timezone*)0) -+# endif -+# endif /* XPG4 else */ -+ -+ -+# ifdef __GNU__ -+# define PATH_MAX 4096 -+# define MAXPATHLEN 4096 -+# define OPEN_MAX 256 /* We define a reasonable limit. */ -+# endif -+ -+/* use POSIX name for signal */ -+# if defined(X_NOT_POSIX) && defined(SYSV) && !defined(SIGCHLD) -+# define SIGCHLD SIGCLD -+# endif -+ -+# include <X11/Xarch.h> -+ -+#endif /* _XOS_H_ */ diff --git a/tools/pkg/4/xorg-server/diff/xorgserver.diff b/tools/pkg/4/xorg-server/diff/xorgserver.diff deleted file mode 100644 index 741c5f9..0000000 --- a/tools/pkg/4/xorg-server/diff/xorgserver.diff +++ /dev/null @@ -1,426 +0,0 @@ -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Bus.c xorg-server-patched/hw/xfree86/common/xf86Bus.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Bus.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Bus.c 2025-10-23 12:44:22.775506715 +0300 -@@ -556,21 +556,7 @@ - void - xf86PostProbe(void) - { -- if (fbSlotClaimed && ( --#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) -- sbusSlotClaimed || --#endif --#ifdef XSERVER_PLATFORM_BUS -- platformSlotClaimed || --#endif --#ifdef XSERVER_LIBPCIACCESS -- pciSlotClaimed --#else -- TRUE --#endif -- )) -- FatalError("Cannot run in framebuffer mode. Please specify busIDs " -- " for all framebuffer devices\n"); -+ - } - - Bool -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Config.c xorg-server-patched/hw/xfree86/common/xf86Config.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Config.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Config.c 2025-10-18 14:14:41.313332537 +0300 -@@ -49,6 +49,8 @@ - #include <sys/types.h> - #include <grp.h> - -+#include <sys/stat.h> -+ - #include "xf86.h" - #include "xf86Modes.h" - #include "xf86Parser.h" -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Configure.c xorg-server-patched/hw/xfree86/common/xf86Configure.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Configure.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Configure.c 2025-10-18 14:15:07.924147512 +0300 -@@ -27,6 +27,8 @@ - #include <xorg-config.h> - #endif - -+#include <errno.h> -+ - #include "xf86.h" - #include "xf86Config.h" - #include "xf86_OSlib.h" -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Events.c xorg-server-patched/hw/xfree86/common/xf86Events.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Events.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Events.c 2025-10-18 14:15:29.363803215 +0300 -@@ -53,6 +53,8 @@ - #include <xorg-config.h> - #endif - -+#include <errno.h> -+ - #include <X11/X.h> - #include <X11/Xproto.h> - #include <X11/Xatom.h> -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Helper.c xorg-server-patched/hw/xfree86/common/xf86Helper.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Helper.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Helper.c 2025-10-23 14:57:42.305808491 +0300 -@@ -34,6 +34,8 @@ - * different drivers. - */ - -+#include <sys/stat.h> -+ - #ifdef HAVE_XORG_CONFIG_H - #include <xorg-config.h> - #endif -@@ -851,49 +853,65 @@ - xf86SetDpi(ScrnInfoPtr pScrn, int x, int y) - { - MessageType from = X_DEFAULT; -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - xf86MonPtr DDC = (xf86MonPtr) (pScrn->monitor->DDC); -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - int probedWidthmm, probedHeightmm; - int widthErr, heightErr; -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - xf86OutputPtr compat = xf86CompatOutput(pScrn); -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - - /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */ - pScrn->widthmm = pScrn->monitor->widthmm; - pScrn->heightmm = pScrn->monitor->heightmm; -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - - if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0)) { - /* DDC gives display size in mm for individual modes, - * but cm for monitor - */ -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy1\n"); - probedWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */ - probedHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */ -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy1\n"); - } - else if (compat && compat->mm_width > 0 && compat->mm_height > 0) { -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy2\n"); - probedWidthmm = compat->mm_width; - probedHeightmm = compat->mm_height; -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy2\n"); - } - else { -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy3\n"); - probedWidthmm = probedHeightmm = 0; - } - - if (monitorResolution > 0) { -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy4\n"); - pScrn->xDpi = monitorResolution; - pScrn->yDpi = monitorResolution; - from = X_CMDLINE; -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy5\n"); - } - else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) { -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy6\n"); - from = X_CONFIG; - if (pScrn->widthmm > 0) { - pScrn->xDpi = - (int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm); - } -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - if (pScrn->heightmm > 0) { - pScrn->yDpi = - (int) ((double) pScrn->virtualY * MMPERINCH / pScrn->heightmm); - } -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - if (pScrn->xDpi > 0 && pScrn->yDpi <= 0) - pScrn->yDpi = pScrn->xDpi; - if (pScrn->yDpi > 0 && pScrn->xDpi <= 0) - pScrn->xDpi = pScrn->yDpi; -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n", - pScrn->widthmm, pScrn->heightmm); - -@@ -919,8 +937,10 @@ - pScrn->heightmm); - } - } -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guy\n"); - } - else if (probedWidthmm && probedHeightmm) { -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guyZ\n"); - from = X_PROBED; - xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n", - probedWidthmm, probedHeightmm); -@@ -940,6 +960,7 @@ - pScrn->xDpi = pScrn->yDpi; - } - else { -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "guyX\n"); - if (x > 0) - pScrn->xDpi = x; - else -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Init.c xorg-server-patched/hw/xfree86/common/xf86Init.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Init.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Init.c 2025-10-18 14:17:21.699226880 +0300 -@@ -34,6 +34,8 @@ - #include <xorg-config.h> - #endif - -+#include <sys/stat.h> -+ - #include <stdlib.h> - #include <errno.h> - -diff -Naur xorg-server-21.1.0/hw/xfree86/common/xf86Mode.c xorg-server-patched/hw/xfree86/common/xf86Mode.c ---- xorg-server-21.1.0/hw/xfree86/common/xf86Mode.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/common/xf86Mode.c 2025-10-23 14:29:02.407987453 +0300 -@@ -2118,5 +2118,6 @@ - if (hsync != 0 && refresh != 0) - xf86PrintModeline(scrp->scrnIndex, p); - p = p->next; -+ - } while (p != NULL && p != scrp->modes); - } -diff -Naur xorg-server-21.1.0/hw/xfree86/fbdevhw/fbdevhw.c xorg-server-patched/hw/xfree86/fbdevhw/fbdevhw.c ---- xorg-server-21.1.0/hw/xfree86/fbdevhw/fbdevhw.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/fbdevhw/fbdevhw.c 2025-10-19 09:37:47.188152245 +0300 -@@ -9,13 +9,10 @@ - #include "xf86Modes.h" - #include "xf86_OSproc.h" - --/* pci stuff */ --#include "xf86Pci.h" -- - #include "xf86cmap.h" - - #include "fbdevhw.h" --#include "fbpriv.h" -+#include <linux/fb.h> - #include "globals.h" - #include <X11/extensions/dpmsconst.h> - -@@ -253,57 +250,6 @@ - mode->CrtcVAdjusted = FALSE; - } - --/* -------------------------------------------------------------------- */ --/* open correct framebuffer device */ -- --/** -- * Try to find the framebuffer device for a given PCI device -- */ --static int --fbdev_open_pci(struct pci_device *pPci, char **namep) --{ -- struct fb_fix_screeninfo fix; -- char filename[256]; -- int fd, i; -- -- for (i = 0; i < 8; i++) { -- snprintf(filename, sizeof(filename), -- "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics/fb%d", -- pPci->domain, pPci->bus, pPci->dev, pPci->func, i); -- -- fd = open(filename, O_RDONLY, 0); -- if (fd < 0) { -- snprintf(filename, sizeof(filename), -- "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics:fb%d", -- pPci->domain, pPci->bus, pPci->dev, pPci->func, i); -- fd = open(filename, O_RDONLY, 0); -- } -- if (fd >= 0) { -- close(fd); -- snprintf(filename, sizeof(filename), "/dev/fb%d", i); -- -- fd = open(filename, O_RDWR, 0); -- if (fd != -1) { -- if (ioctl(fd, FBIOGET_FSCREENINFO, (void *) &fix) != -1) { -- if (namep) { -- *namep = xnfalloc(16); -- strncpy(*namep, fix.id, 16); -- } -- -- return fd; -- } -- close(fd); -- } -- } -- } -- -- if (namep) -- *namep = NULL; -- -- xf86DrvMsg(-1, X_ERROR, "Unable to find a valid framebuffer device\n"); -- return -1; --} -- - static int - fbdev_open(int scrnIndex, const char *dev, char **namep) - { -@@ -329,22 +275,6 @@ - return -1; - } - -- /* only touch non-PCI devices on this path */ -- { -- char buf[PATH_MAX] = {0}; -- char *sysfs_path = NULL; -- char *node = strrchr(dev, '/') + 1; -- -- if (asprintf(&sysfs_path, "/sys/class/graphics/%s", node) < 0 || -- readlink(sysfs_path, buf, sizeof(buf) - 1) < 0 || -- strstr(buf, "devices/pci")) { -- free(sysfs_path); -- close(fd); -- return -1; -- } -- free(sysfs_path); -- } -- - if (namep) { - if (-1 == ioctl(fd, FBIOGET_FSCREENINFO, (void *) (&fix))) { - *namep = NULL; -@@ -363,14 +293,12 @@ - /* -------------------------------------------------------------------- */ - - Bool --fbdevHWProbe(struct pci_device *pPci, char *device, char **namep) -+fbdevHWProbe(void *pPci, char *device, char **namep) - { - int fd; -- -- if (pPci) -- fd = fbdev_open_pci(pPci, namep); -- else -- fd = fbdev_open(-1, device, namep); -+ -+ fd = fbdev_open(-1, device, namep); -+ - - if (-1 == fd) - return FALSE; -@@ -379,18 +307,15 @@ - } - - Bool --fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device *pPci, char *device) -+fbdevHWInit(ScrnInfoPtr pScrn, void *pPci, char *device) - { - fbdevHWPtr fPtr; - - fbdevHWGetRec(pScrn); - fPtr = FBDEVHWPTR(pScrn); - -- /* open device */ -- if (pPci) -- fPtr->fd = fbdev_open_pci(pPci, NULL); -- else -- fPtr->fd = fbdev_open(pScrn->scrnIndex, device, NULL); -+ fPtr->fd = fbdev_open(pScrn->scrnIndex, device, NULL); -+ - if (-1 == fPtr->fd) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to open framebuffer device, consult warnings" -diff -Naur xorg-server-21.1.0/hw/xfree86/fbdevhw/fbdevhw.h xorg-server-patched/hw/xfree86/fbdevhw/fbdevhw.h ---- xorg-server-21.1.0/hw/xfree86/fbdevhw/fbdevhw.h 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/fbdevhw/fbdevhw.h 2025-10-19 09:38:08.190818849 +0300 -@@ -16,9 +16,9 @@ - - extern _X_EXPORT int fbdevHWGetFD(ScrnInfoPtr pScrn); - --extern _X_EXPORT Bool fbdevHWProbe(struct pci_device *pPci, char *device, -+extern _X_EXPORT Bool fbdevHWProbe(void *pPci, char *device, - char **namep); --extern _X_EXPORT Bool fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device *pPci, -+extern _X_EXPORT Bool fbdevHWInit(ScrnInfoPtr pScrn, void *pPci, - char *device); - - extern _X_EXPORT char *fbdevHWGetName(ScrnInfoPtr pScrn); -diff -Naur xorg-server-21.1.0/hw/xfree86/modes/xf86Crtc.h xorg-server-patched/hw/xfree86/modes/xf86Crtc.h ---- xorg-server-21.1.0/hw/xfree86/modes/xf86Crtc.h 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/modes/xf86Crtc.h 2025-10-23 18:17:12.719700281 +0300 -@@ -837,8 +837,12 @@ - static _X_INLINE xf86OutputPtr - xf86CompatOutput(ScrnInfoPtr pScrn) - { -+ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - -+ if(!config) -+ return NULL; -+ - if (config->compat_output < 0) - return NULL; - return config->output[config->compat_output]; -@@ -849,6 +853,8 @@ - { - xf86OutputPtr compat_output = xf86CompatOutput(pScrn); - -+ -+ - if (!compat_output) - return NULL; - return compat_output->crtc; -diff -Naur xorg-server-21.1.0/hw/xfree86/os-support/shared/posix_tty.c xorg-server-patched/hw/xfree86/os-support/shared/posix_tty.c ---- xorg-server-21.1.0/hw/xfree86/os-support/shared/posix_tty.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/os-support/shared/posix_tty.c 2025-10-18 14:18:16.925903537 +0300 -@@ -56,6 +56,9 @@ - #include <xorg-config.h> - #endif - -+#include <termios.h> -+#include <errno.h> -+ - #include <X11/X.h> - #include <xserver_poll.h> - #include "xf86.h" -diff -Naur xorg-server-21.1.0/hw/xfree86/os-support/shared/sigio.c xorg-server-patched/hw/xfree86/os-support/shared/sigio.c ---- xorg-server-21.1.0/hw/xfree86/os-support/shared/sigio.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/hw/xfree86/os-support/shared/sigio.c 2025-10-18 14:18:36.612500292 +0300 -@@ -56,6 +56,9 @@ - #include <xorg-config.h> - #endif - -+#include <sys/stat.h> -+#include <errno.h> -+ - #include <X11/X.h> - #include <xserver_poll.h> - #include "xf86.h" -diff -Naur xorg-server-21.1.0/include/os.h xorg-server-patched/include/os.h ---- xorg-server-21.1.0/include/os.h 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/include/os.h 2025-10-18 14:19:09.429494076 +0300 -@@ -51,6 +51,7 @@ - #include <stdarg.h> - #include <stdint.h> - #include <string.h> -+#include <strings.h> - #ifdef MONOTONIC_CLOCK - #include <time.h> - #endif -diff -Naur xorg-server-21.1.0/os/access.c xorg-server-patched/os/access.c ---- xorg-server-21.1.0/os/access.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/os/access.c 2025-10-18 14:19:29.654105938 +0300 -@@ -116,7 +116,7 @@ - #endif - #endif - --#if defined(SVR4) || (defined(SYSV) && defined(__i386__)) || defined(__GNU__) -+#if defined(SVR4) || (defined(SYSV) && defined(__i386__)) || defined(__GNU__) || defined(__orange__) - #include <sys/utsname.h> - #endif - #if defined(SYSV) && defined(__i386__) -diff -Naur xorg-server-21.1.0/os/ospoll.c xorg-server-patched/os/ospoll.c ---- xorg-server-21.1.0/os/ospoll.c 2021-10-27 13:47:08.000000000 +0300 -+++ xorg-server-patched/os/ospoll.c 2025-10-18 14:20:06.530220468 +0300 -@@ -45,12 +45,6 @@ - #define HAVE_OSPOLL 1 - #endif - --#if !HAVE_OSPOLL && defined(HAVE_EPOLL_CREATE1) --#include <sys/epoll.h> --#define EPOLL 1 --#define HAVE_OSPOLL 1 --#endif -- - #if !HAVE_OSPOLL - #include "xserver_poll.h" - #define POLL 1 diff --git a/tools/pkg/4/xorg-server/info.txt b/tools/pkg/4/xorg-server/info.txt deleted file mode 100644 index 0e680f2..0000000 --- a/tools/pkg/4/xorg-server/info.txt +++ /dev/null @@ -1 +0,0 @@ -xorg-server
\ No newline at end of file diff --git a/tools/pkg/4/xorg-server/pkg.sh b/tools/pkg/4/xorg-server/pkg.sh deleted file mode 100644 index cbb6c1e..0000000 --- a/tools/pkg/4/xorg-server/pkg.sh +++ /dev/null @@ -1,171 +0,0 @@ - -. ../../pkg-lib.sh -export PKG_CONFIG_PATh - -mkdir -p cached - -cd pack - -tar -xvf xkeyboard-config-2.36.tar.xz - -pushd xkeyboard-config-2.36 -sed -i -E "s/(ln -s)/\1f/" rules/meson.build -popd - -cd xkeyboard-config-2.36 - -mkdir -p build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix="/usr" build -Dxorg-rules-symlinks=true - -cd build -meson compile -DESTDIR="$1" meson install -cd ../.. -exit 0 - -rm -rf pack - -mkdir -p pack - -cd pack - - wget https://www.zlib.net/fossils/zlib-1.3.tar.gz - - tar -xvf zlib-1.3.tar.gz - - cd zlib-1.3 - -CHOST=x86_64-linux-gnu prefix="/usr" ./configure -make -j$(nproc) -make install DESTDIR="$1" - -rm -rf "$1/usr/lib"/libz.so* - -cd .. - -wget https://downloads.sourceforge.net/libpng/libpng-1.6.37.tar.gz -tar -xvf libpng-1.6.37.tar.gz -cd libpng-1.6.37 - -autotools_recursive_regen - -./configure --host=x86_64-linux-gnu --prefix=/usr --disable-shared --enable-static -make -j$(nproc) -make install DESTDIR="$1" - -cd .. - -fast_install "$1" https://downloads.sourceforge.net/freetype/freetype-2.12.1.tar.gz - -wget https://www.x.org/pub/individual/util/util-macros-1.20.0.tar.gz -tar -xvf util-macros-1.20.0.tar.gz - -cd util-macros-1.20.0 - -./configure --prefix="$HOME/opt/cross/orange" -make -j$(nproc) -make install - -cd .. - -wget https://www.openssl.org/source/openssl-1.1.1q.tar.gz -tar -xvf openssl-1.1.1q.tar.gz - -cd openssl-1.1.1q -diff_patch ../../diff/openssl.diff - -CFLAGS="-Wno-implicit-function-declaration" CC=x86_64-linux-gnu-gcc CXX=x86_64-linux-gnu-gcc ./Configure --prefix=/usr --openssldir=/etc/ssl --libdir=lib "linux-x86_64" shared zlib-dynamic no-afalgeng - -make -j$(nproc) - -make install MANSUFFIX=ssl DESTDIR="$1" - -cd .. - -fast_install "$1" https://www.x.org/archive/individual/lib/xtrans-1.4.0.tar.gz - -fast_install "$1" https://www.x.org/releases/individual/proto/xproto-7.0.31.tar.gz "--enable-shared" "../../diff/libxproto.diff" - -fast_install "$1" https://www.x.org/releases/individual/proto/fontsproto-2.1.3.tar.gz - -fast_install "$1" https://www.x.org/archive/individual/lib/libfontenc-1.1.8.tar.gz -fast_install "$1" https://www.x.org/archive/individual/lib/libXfont2-2.0.6.tar.gz -fast_install "$1" https://cairographics.org/releases/pixman-0.40.0.tar.gz -wget https://www.x.org/releases/individual/proto/xorgproto-2022.2.tar.gz - -tar -xvf xorgproto-2022.2.tar.gz - -cd xorgproto-2022.2 - -diff_patch ../../diff/xorgproto.diff -patch_config_sub "$(realpath $1/..)" - -mkdir -p build0 - -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dlegacy=true build0 - -cd build0 - -meson compile -DESTDIR="$1" ninja install - -cd ../.. - -#exit 0 -fast_install "$1" https://www.x.org/releases/individual/xcb/libpthread-stubs-0.5.tar.gz - -fast_install "$1" https://www.x.org/releases/individual/xcb/xcb-proto-1.15.tar.gz - -fast_install "$1" https://www.x.org/releases/individual/lib/libXau-1.0.9.tar.gz -fast_install "$1" https://www.x.org/releases/individual/xcb/libxcb-1.15.tar.gz - -mkdir -p "$1/usr/share/X11" -sudo chmod 777 -R "$1/usr/share/X11" - -fast_install "$1" https://www.x.org/releases/individual/lib/libX11-1.8.1.tar.gz --with-keysymdefdir="$1/usr/include/X11" - -fast_install "$1" https://www.x.org/archive/individual/lib/libxkbfile-1.1.1.tar.gz - -fast_install "$1" https://www.x.org/releases/individual/lib/libXfixes-6.0.0.tar.gz - -wget https://www.x.org/releases/individual/lib/libxcvt-0.1.2.tar.xz -tar -xvf libxcvt-0.1.2.tar.xz - -cd libxcvt-0.1.2 - -mkdir -p build - -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix="/usr" build - -cd build -ninja -DESTDIR="$1" ninja install -cd ../.. - -fast_install "$1" https://www.x.org/archive/individual/app/xkbcomp-1.4.5.tar.gz - -wget http://www.x.org/releases/individual/data/xkeyboard-config/xkeyboard-config-2.36.tar.xz -tar -xvf xkeyboard-config-2.36.tar.xz - -pushd xkeyboard-config-2.36 -sed -i -E "s/(ln -s)/\1f/" rules/meson.build -popd - -cd xkeyboard-config-2.36 - -mkdir -p build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix="/usr" build -Dxorg-rules-symlinks=true - -cd build -meson compile -DESTDIR="$1" meson install -cd ../.. -exit 0 -sudo chmod 777 -R "$1/usr/share/X11/xkb" - -fast_install "$1" https://www.x.org/releases/individual/xserver/xorg-server-21.1.4.tar.gz "--with-xkb-bin-directory=/usr/bin --disable-pciaccess --disable-libdrm --disable-glx --disable-int10-module --disable-glamor --disable-vgahw --disable-dri3 --disable-dri2 --disable-dri --disable-xephyr --disable-xwayland --disable-xnest --disable-dmx --with-fontrootdir=/usr/share/fonts/X11 --disable-strict-compilation" "../../diff/xorgserver.diff" - - -# at this point i just tired so ill use ironclad patches - -mkdir -p "$1"/usr/lib/xorg/modules/extensions diff --git a/tools/pkg/5/orangeutils/info.txt b/tools/pkg/5/orangeutils/info.txt deleted file mode 100644 index e69de29..0000000 --- a/tools/pkg/5/orangeutils/info.txt +++ /dev/null diff --git a/tools/pkg/5/orangeutils/pkg.sh b/tools/pkg/5/orangeutils/pkg.sh deleted file mode 100644 index 5356787..0000000 --- a/tools/pkg/5/orangeutils/pkg.sh +++ /dev/null @@ -1,5 +0,0 @@ -x86_64-orange-mlibc-gcc src/orangedebugenable.c -o "$1/usr/bin/orangedebugenable" -Wno-implicit-function-declaration -x86_64-orange-mlibc-gcc src/orangeprintinfo.c -o "$1/usr/bin/orangeprintinfo" -Wno-implicit-function-declaration -x86_64-orange-mlibc-gcc src/orangedebug.c -o "$1/usr/bin/orangedebug" -Wno-implicit-function-declaration -x86_64-orange-mlibc-gcc src/dmesg.c -o "$1/usr/bin/dmesg" -Wno-implicit-function-declaration -x86_64-orange-mlibc-gcc src/nologin.c -o "$1/usr/bin/nologin" -Wno-implicit-function-declaration
\ No newline at end of file diff --git a/tools/pkg/5/orangeutils/src/dmesg.c b/tools/pkg/5/orangeutils/src/dmesg.c deleted file mode 100644 index 2af80c4..0000000 --- a/tools/pkg/5/orangeutils/src/dmesg.c +++ /dev/null @@ -1,24 +0,0 @@ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdint.h> - -uint64_t dmesg(char* buffer, uint64_t count) { - int ret; - uint64_t size; - asm volatile("syscall" : "=a"(ret), "=d"(size) : "a"(64), "D"(buffer), "S"(count) : "rcx","r11"); - return size; -} - -int main() { - printf("Orange dmesg utility\n"); - uint64_t size = dmesg(0,0); - char* buffer = malloc(size + 1); - memset(buffer,0,size); - dmesg(buffer,size); - write(STDOUT_FILENO,buffer,size); - return 0; -}
\ No newline at end of file diff --git a/tools/pkg/5/orangeutils/src/nologin.c b/tools/pkg/5/orangeutils/src/nologin.c deleted file mode 100644 index 7bb8221..0000000 --- a/tools/pkg/5/orangeutils/src/nologin.c +++ /dev/null @@ -1,7 +0,0 @@ - -#include <stdio.h> - -int main() { - printf("fuck off\n"); - return -1; -}
\ No newline at end of file diff --git a/tools/pkg/5/orangeutils/src/orangedebug.c b/tools/pkg/5/orangeutils/src/orangedebug.c deleted file mode 100644 index 7a90c9f..0000000 --- a/tools/pkg/5/orangeutils/src/orangedebug.c +++ /dev/null @@ -1,15 +0,0 @@ -#include <unistd.h> -#include <stdio.h> - -int main(int argc, char *argv[]) { - if (argc < 2) { - printf("Usage: %s <program> [args...]\n", argv[0]); - return 1; - } - - asm volatile("syscall" : : "a"(53) : "rcx","r11"); - - execvp(argv[1], &argv[1]); - perror("execvp"); - return 1; -}
\ No newline at end of file diff --git a/tools/pkg/5/orangeutils/src/orangedebugenable.c b/tools/pkg/5/orangeutils/src/orangedebugenable.c deleted file mode 100644 index 113b330..0000000 --- a/tools/pkg/5/orangeutils/src/orangedebugenable.c +++ /dev/null @@ -1,15 +0,0 @@ -#include <unistd.h> -#include <stdio.h> - -int main(int argc, char *argv[]) { - if (argc < 2) { - printf("Usage: %s <pid> \n", argv[0]); - return 1; - } - - int pid = atoi(argv[1]); - - asm volatile("syscall" : : "a"(65), "D"(pid) : "rcx","r11"); - - return 0; -}
\ No newline at end of file diff --git a/tools/pkg/5/orangeutils/src/orangeprintinfo.c b/tools/pkg/5/orangeutils/src/orangeprintinfo.c deleted file mode 100644 index 69c3dd4..0000000 --- a/tools/pkg/5/orangeutils/src/orangeprintinfo.c +++ /dev/null @@ -1,15 +0,0 @@ -#include <unistd.h> -#include <stdio.h> - -int main(int argc, char *argv[]) { - if (argc < 2) { - printf("Usage: %s <pid> \n", argv[0]); - return 1; - } - - int pid = atoi(argv[1]); - - asm volatile("syscall" : : "a"(63), "D"(pid) : "rcx","r11"); - - return 0; -}
\ No newline at end of file diff --git a/tools/pkg/5/orangex/info.txt b/tools/pkg/5/orangex/info.txt deleted file mode 100644 index e5c9be7..0000000 --- a/tools/pkg/5/orangex/info.txt +++ /dev/null @@ -1 +0,0 @@ -orangeX - x start script for orange
\ No newline at end of file diff --git a/tools/pkg/5/orangex/main.sh b/tools/pkg/5/orangex/main.sh deleted file mode 100644 index e84709d..0000000 --- a/tools/pkg/5/orangex/main.sh +++ /dev/null @@ -1,9 +0,0 @@ - -stty -echo -echo Compiling glib schemas -glib-compile-schemas /usr/share/glib-2.0/schemas -echo Generating gdk loaders.cache -gdk-pixbuf-query-loaders > /usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache -echo Launching MATE -chmod +x /etc/X11/materc -xinit /etc/X11/materc > /dev/null 2> /dev/null
\ No newline at end of file diff --git a/tools/pkg/5/orangex/pkg.sh b/tools/pkg/5/orangex/pkg.sh deleted file mode 100644 index 62ddf7c..0000000 --- a/tools/pkg/5/orangex/pkg.sh +++ /dev/null @@ -1,3 +0,0 @@ - -cp -rf main.sh "$1/usr/bin/orangeX" -chmod +x "$1/usr/bin/orangeX"
\ No newline at end of file diff --git a/tools/pkg/5/twm/diff/fontconfig.diff b/tools/pkg/5/twm/diff/fontconfig.diff deleted file mode 100644 index fa0bb11..0000000 --- a/tools/pkg/5/twm/diff/fontconfig.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff -Naur fontconfig-2.13.94/src/fcstat.c fontconfig-patched/src/fcstat.c ---- fontconfig-2.13.94/src/fcstat.c 2020-12-03 14:45:00.000000000 +0300 -+++ fontconfig-patched/src/fcstat.c 2025-10-26 08:27:40.889979729 +0300 -@@ -386,7 +386,7 @@ - # endif - # if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) - p = buf.f_fstypename; --# elif defined(__linux__) -+# elif defined(__linux__) || defined(__orange__) - switch (buf.f_type) - { - case 0x6969: /* nfs */ diff --git a/tools/pkg/5/twm/diff/libxt.diff b/tools/pkg/5/twm/diff/libxt.diff deleted file mode 100644 index 228f540..0000000 --- a/tools/pkg/5/twm/diff/libxt.diff +++ /dev/null @@ -1,16 +0,0 @@ -diff -Naur libXt-1.2.1/src/Shell.c libXt-patched/src/Shell.c ---- libXt-1.2.1/src/Shell.c 2021-01-24 17:47:39.000000000 +0300 -+++ libXt-patched/src/Shell.c 2025-10-26 08:06:07.473650705 +0300 -@@ -1003,10 +1003,10 @@ - static void - _XtShellAncestorSensitive(Widget widget, int closure, XrmValue *value) - { -- static Boolean true = True; -+ int xx = 1; - - if (widget->core.parent == NULL) -- value->addr = (XPointer) (&true); -+ value->addr = (XPointer) (&xx); - else - _XtCopyFromParent(widget, closure, value); - } diff --git a/tools/pkg/5/twm/info.txt b/tools/pkg/5/twm/info.txt deleted file mode 100644 index 3047a9f..0000000 --- a/tools/pkg/5/twm/info.txt +++ /dev/null @@ -1 +0,0 @@ -twm and xapps
\ No newline at end of file diff --git a/tools/pkg/5/twm/pkg.sh b/tools/pkg/5/twm/pkg.sh deleted file mode 100644 index 4cbca19..0000000 --- a/tools/pkg/5/twm/pkg.sh +++ /dev/null @@ -1,30 +0,0 @@ - -. ../../pkg-lib.sh - -rm -rf pack -mkdir -p pack - -cd pack - -fast_install "$1" https://www.x.org/releases/individual/lib/libXext-1.3.4.tar.gz -fast_install "$1" https://www.x.org/releases/individual/lib/libICE-1.1.0.tar.gz -fast_install "$1" https://www.x.org/releases/individual/lib/libSM-1.2.4.tar.gz -fast_install "$1" https://www.x.org/releases/individual/lib/libXt-1.2.1.tar.gz "--enable-shared" "../../diff/libxt.diff" -fast_install "$1" https://www.x.org/releases/individual/lib/libXmu-1.1.3.tar.gz - -fast_install "$1" https://www.x.org/archive//individual/app/twm-1.0.11.tar.gz - -fast_install "$1" https://www.x.org/releases/individual/lib/libXpm-3.5.14.tar.gz -fast_install "$1" https://www.x.org/releases/individual/lib/libXaw-1.0.14.tar.gz - -fast_install "$1" https://github.com/libexpat/libexpat/releases/download/R_2_4_9/expat-2.4.9.tar.xz -fast_install "$1" https://www.freedesktop.org/software/fontconfig/release/fontconfig-2.13.94.tar.gz "--enable-shared" "../../diff/fontconfig.diff" -fast_install "$1" https://www.x.org/releases/individual/lib/libXrender-0.9.11.tar.gz -fast_install "$1" https://www.x.org/releases/individual/lib/libXft-2.3.4.tar.gz - -fast_install "$1" https://www.x.org/releases/individual/lib/libXi-1.8.1.tar.gz - -fast_install "$1" https://www.x.org/pub/individual/app/xclock-1.1.1.tar.xz -fast_install "$1" https://www.x.org/releases/individual/app/xeyes-1.2.0.tar.gz - -fast_install "$1" https://www.x.org/releases/individual/app/xinit-1.4.1.tar.gz diff --git a/tools/pkg/5/xorg-modules/diff/xfbdev.diff b/tools/pkg/5/xorg-modules/diff/xfbdev.diff deleted file mode 100644 index e2e13e5..0000000 --- a/tools/pkg/5/xorg-modules/diff/xfbdev.diff +++ /dev/null @@ -1,51 +0,0 @@ -diff --git xf86-video-fbdev-clean/src/Makefile.in xf86-video-fbdev-workdir/src/Makefile.in -index 016d61d..84213a5 100644 ---- xf86-video-fbdev-clean/src/Makefile.in -+++ xf86-video-fbdev-workdir/src/Makefile.in -@@ -373,7 +373,7 @@ top_srcdir = @top_srcdir@ - # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. - AM_CFLAGS = $(BASE_CFLAGS) $(XORG_CFLAGS) - fbdev_drv_la_LTLIBRARIES = fbdev_drv.la --fbdev_drv_la_LDFLAGS = -module -avoid-version -+fbdev_drv_la_LDFLAGS = -module -avoid-version -lfbdevhw -lshadow - fbdev_drv_ladir = @moduledir@/drivers - fbdev_drv_la_SOURCES = \ - fbdev.c -diff --git xf86-video-fbdev-clean/src/fbdev.c xf86-video-fbdev-workdir/src/fbdev.c -index 939c5b8..4ec1ccb 100644 ---- xf86-video-fbdev-clean/src/fbdev.c -+++ xf86-video-fbdev-workdir/src/fbdev.c -@@ -331,7 +331,7 @@ FBDevProbe(DriverPtr drv, int flags) - - dev = xf86FindOptionValue(devSections[i]->options,"fbdev"); - if (devSections[i]->busID) { --#ifndef XSERVER_LIBPCIACCESS -+#ifdef XSERVER_LIBPCIACCESS - if (xf86ParsePciBusString(devSections[i]->busID,&bus,&device, - &func)) { - if (!xf86CheckPciSlot(bus,device,func)) -@@ -343,7 +343,7 @@ FBDevProbe(DriverPtr drv, int flags) - if (fbdevHWProbe(NULL,dev,NULL)) { - pScrn = NULL; - if (isPci) { --#ifndef XSERVER_LIBPCIACCESS -+#ifdef XSERVER_LIBPCIACCESS - /* XXX what about when there's no busID set? */ - int entity; - -@@ -419,6 +419,7 @@ FBDevPreInit(ScrnInfoPtr pScrn, int flags) - fPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); - - #ifndef XSERVER_LIBPCIACCESS -+#if 0 - pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; - /* XXX Is this right? Can probably remove RAC_FB */ - pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; -@@ -429,6 +430,7 @@ FBDevPreInit(ScrnInfoPtr pScrn, int flags) - "xf86RegisterResources() found resource conflicts\n"); - return FALSE; - } -+#endif - #else - if (fPtr->pEnt->location.type == BUS_PCI) - pci_dev = fPtr->pEnt->location.id.pci;
\ No newline at end of file diff --git a/tools/pkg/5/xorg-modules/diff/xkeyboard.diff b/tools/pkg/5/xorg-modules/diff/xkeyboard.diff deleted file mode 100644 index f3cbff5..0000000 --- a/tools/pkg/5/xorg-modules/diff/xkeyboard.diff +++ /dev/null @@ -1,246 +0,0 @@ -diff --git xf86-input-keyboard-clean/configure xf86-input-keyboard-workdir/configure -index 76f1212..c2b8867 100755 ---- xf86-input-keyboard-clean/configure -+++ xf86-input-keyboard-workdir/configure -@@ -664,6 +664,8 @@ SOLARIS_FALSE - SOLARIS_TRUE - BSD_FALSE - BSD_TRUE -+ORANGE_FALSE -+ORANGE_TRUE - OS_FLAGS - inputdir - XORG_LIBS -@@ -19840,6 +19842,10 @@ inputdir=${moduledir}/input - - # The keyboard driver code is O/S specific - case $host_os in -+ orange*) -+ IS_ORANGE="yes" -+ ;; -+ - linux*) - as_fn_error $? "This is not the keyboard driver you are looking for. Use evdev or libinput." "$LINENO" 5 - ;; -@@ -19878,6 +19884,14 @@ case $host_os in - esac - - -+ if test "x$IS_ORANGE" = xyes; then -+ ORANGE_TRUE= -+ ORANGE_FALSE='#' -+else -+ ORANGE_TRUE='#' -+ ORANGE_FALSE= -+fi -+ - if test "x$IS_BSD" = xyes; then - BSD_TRUE= - BSD_FALSE='#' -@@ -20053,6 +20067,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ORANGE_TRUE}" && test -z "${ORANGE_FALSE}"; then -+ as_fn_error $? "conditional \"ORANGE\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${BSD_TRUE}" && test -z "${BSD_FALSE}"; then - as_fn_error $? "conditional \"BSD\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git xf86-input-keyboard-clean/src/Makefile.in xf86-input-keyboard-workdir/src/Makefile.in -index 6daf679..9a63513 100644 ---- xf86-input-keyboard-clean/src/Makefile.in -+++ xf86-input-keyboard-workdir/src/Makefile.in -@@ -113,6 +113,7 @@ host_triplet = @host@ - @BSD_TRUE@am__append_1 = $(BSD_SRCS) - @SOLARIS_TRUE@am__append_2 = $(SOLARIS_SRCS) - @HURD_TRUE@am__append_3 = $(HURD_SRCS) -+@ORANGE_TRUE@am__append_4 = $(ORANGE_SRCS) - subdir = src - ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 - am__aclocal_m4_deps = $(top_srcdir)/configure.ac -@@ -155,15 +156,17 @@ am__DEPENDENCIES_1 = - kbd_drv_la_DEPENDENCIES = $(am__DEPENDENCIES_1) - am__kbd_drv_la_SOURCES_DIST = kbd.c xf86OSKbd.h xf86Keymap.h \ - atKeynames.h bsd_KbdMap.c bsd_kbd.c bsd_kbd.h at_scancode.c \ -- sun_kbd.c sun_kbd.h sun_kbdMap.c hurd_kbd.c -+ sun_kbd.c sun_kbd.h sun_kbdMap.c hurd_kbd.c orange_kbd.c - am__objects_1 = bsd_KbdMap.lo bsd_kbd.lo at_scancode.lo - @BSD_TRUE@am__objects_2 = $(am__objects_1) - am__objects_3 = sun_kbd.lo sun_kbdMap.lo - @SOLARIS_TRUE@am__objects_4 = $(am__objects_3) - am__objects_5 = hurd_kbd.lo at_scancode.lo - @HURD_TRUE@am__objects_6 = $(am__objects_5) -+am__objects_7 = orange_kbd.lo at_scancode.lo -+@ORANGE_TRUE@am__objects_8 = $(am__objects_7) - am_kbd_drv_la_OBJECTS = kbd.lo $(am__objects_2) $(am__objects_4) \ -- $(am__objects_6) -+ $(am__objects_6) $(am__objects_8) - kbd_drv_la_OBJECTS = $(am_kbd_drv_la_OBJECTS) - AM_V_lt = $(am__v_lt_@AM_V@) - am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -@@ -189,7 +192,7 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp - am__maybe_remake_depfiles = depfiles - am__depfiles_remade = ./$(DEPDIR)/at_scancode.Plo \ - ./$(DEPDIR)/bsd_KbdMap.Plo ./$(DEPDIR)/bsd_kbd.Plo \ -- ./$(DEPDIR)/hurd_kbd.Plo ./$(DEPDIR)/kbd.Plo \ -+ ./$(DEPDIR)/hurd_kbd.Plo ./$(DEPDIR)/orange_kbd.Plo ./$(DEPDIR)/kbd.Plo \ - ./$(DEPDIR)/sun_kbd.Plo ./$(DEPDIR)/sun_kbdMap.Plo - am__mv = mv -f - COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ -@@ -388,13 +391,14 @@ AM_CFLAGS = $(XORG_CFLAGS) $(CWARNFLAGS) $(OS_FLAGS) - kbd_drv_la_LTLIBRARIES = kbd_drv.la - kbd_drv_la_LDFLAGS = -avoid-version -module - kbd_drv_la_SOURCES = kbd.c xf86OSKbd.h xf86Keymap.h atKeynames.h \ -- $(am__append_1) $(am__append_2) $(am__append_3) -+ $(am__append_1) $(am__append_2) $(am__append_3) $(am__append_4) - kbd_drv_la_LIBADD = $(XORG_LIBS) - kbd_drv_ladir = @inputdir@ -+ORANGE_SRCS = orange_kbd.c at_scancode.c - BSD_SRCS = bsd_KbdMap.c bsd_kbd.c bsd_kbd.h at_scancode.c - HURD_SRCS = hurd_kbd.c at_scancode.c - SOLARIS_SRCS = sun_kbd.c sun_kbd.h sun_kbdMap.c --EXTRA_DIST = $(BSD_SRCS) $(HURD_SRCS) $(SOLARIS_SRCS) -+EXTRA_DIST = $(ORANGE_SRCS) $(BSD_SRCS) $(HURD_SRCS) $(SOLARIS_SRCS) - all: all-am - - .SUFFIXES: -@@ -475,6 +479,7 @@ distclean-compile: - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd_KbdMap.Plo@am__quote@ # am--include-marker - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd_kbd.Plo@am__quote@ # am--include-marker - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hurd_kbd.Plo@am__quote@ # am--include-marker -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orange_kbd.Plo@am__quote@ # am--include-marker - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbd.Plo@am__quote@ # am--include-marker - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sun_kbd.Plo@am__quote@ # am--include-marker - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sun_kbdMap.Plo@am__quote@ # am--include-marker -@@ -643,6 +648,7 @@ distclean: distclean-am - -rm -f ./$(DEPDIR)/bsd_KbdMap.Plo - -rm -f ./$(DEPDIR)/bsd_kbd.Plo - -rm -f ./$(DEPDIR)/hurd_kbd.Plo -+ -rm -f ./$(DEPDIR)/orange_kbd.Plo - -rm -f ./$(DEPDIR)/kbd.Plo - -rm -f ./$(DEPDIR)/sun_kbd.Plo - -rm -f ./$(DEPDIR)/sun_kbdMap.Plo -@@ -695,6 +701,7 @@ maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/bsd_KbdMap.Plo - -rm -f ./$(DEPDIR)/bsd_kbd.Plo - -rm -f ./$(DEPDIR)/hurd_kbd.Plo -+ -rm -f ./$(DEPDIR)/orange_kbd.Plo - -rm -f ./$(DEPDIR)/kbd.Plo - -rm -f ./$(DEPDIR)/sun_kbd.Plo - -rm -f ./$(DEPDIR)/sun_kbdMap.Plo -diff --git xf86-input-keyboard-workdir/src/orange_kbd.c xf86-input-keyboard-workdir/src/orange_kbd.c -new file mode 100644 -index 0000000..3f20d5c ---- /dev/null -+++ xf86-input-keyboard-workdir/src/orange_kbd.c -@@ -0,0 +1,108 @@ -+#ifdef HAVE_CONFIG_H -+#include <config.h> -+#endif -+ -+#include <X11/X.h> -+#include <xorg-server.h> -+ -+#include "compiler.h" -+ -+#include "xf86.h" -+#include "xf86Priv.h" -+#include "xf86_OSlib.h" -+ -+#include "atKeynames.h" -+#include "xf86Keymap.h" -+#include "xf86OSKbd.h" -+#include "xf86Xinput.h" -+ -+#include <assert.h> -+#include <errno.h> -+#include <stdio.h> -+#include <sys/file.h> -+#include <sys/ioctl.h> -+#include <sys/time.h> -+ -+static int KbdOn(InputInfoPtr pInfo, int what) { -+ return Success; -+} -+ -+static int KbdOff(InputInfoPtr pInfo, int what) { -+ printf("kbdOff is a stub!\n"); -+ return -1; -+} -+ -+static void SoundKbdBell(InputInfoPtr pInfo, int loudness, int pitch, int duration) { -+ printf("SoundKbdBell is a stub!\n"); -+} -+ -+static void SetKbdLeds(InputInfoPtr pInfo, int leds) { -+ printf("SetKbdLeds: is a stub!\n"); -+} -+ -+static int GetKbdLeds(InputInfoPtr pInfo) { -+ printf("GetKbdLeds is a stub!\n"); -+ return -1; -+} -+ -+// Save the initial keyboard state. This function is called at the start -+// of each server generation. -+static int KbdInit(InputInfoPtr pInfo, int what) { -+ return Success; -+} -+ -+static void KbdGetMapping(InputInfoPtr pInfo, KeySymsPtr pKeySyms, CARD8 *pModMap) { -+ printf("KbdGetMapping is a stub!\n"); -+} -+ -+static void ReadInput(InputInfoPtr pInfo) { -+ KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; -+ -+ uint8_t scancodes[64]; -+ ssize_t result = read(pInfo->fd, scancodes, sizeof(scancodes)); -+ if (result > 0) { -+ for (ssize_t i = 0; i < result; i++) { -+ pKbd->PostEvent(pInfo, scancodes[i] & 0x7f, scancodes[i] & 0x80 ? FALSE : TRUE); -+ } -+ } -+} -+ -+static Bool OpenKeyboard(InputInfoPtr pInfo) { -+ char *kbdPath = xf86SetStrOption(pInfo->options, "Device", "/dev/ps2keyboard"); -+ Bool ret; -+ -+ pInfo->fd = open(kbdPath, O_RDONLY | O_NONBLOCK); -+ -+ if (pInfo->fd == -1) { -+ xf86Msg(X_ERROR, "%s: cannot open \"%s\"\n", pInfo->name, kbdPath); -+ ret = FALSE; -+ } else { -+ xf86MsgVerb(X_INFO, 3, "%s: opened device \"%s\"\n", pInfo->name, kbdPath); -+ pInfo->read_input = ReadInput; -+ ret = TRUE; -+ -+ // in case it wasn't set and we fell back to default. -+ xf86ReplaceStrOption(pInfo->options, "Device", kbdPath); -+ } -+ -+ free(kbdPath); -+ return ret; -+} -+ -+Bool xf86OSKbdPreInit(InputInfoPtr pInfo) { -+ KbdDevPtr pKbd = pInfo->private; -+ -+ pKbd->KbdInit = KbdInit; -+ pKbd->KbdOn = KbdOn; -+ pKbd->KbdOff = KbdOff; -+ pKbd->Bell = SoundKbdBell; -+ pKbd->SetLeds = SetKbdLeds; -+ pKbd->GetLeds = GetKbdLeds; -+ pKbd->KbdGetMapping = KbdGetMapping; -+ pKbd->OpenKeyboard = OpenKeyboard; -+ -+ pKbd->RemapScanCode = NULL; -+ pKbd->private = NULL; -+ -+ return TRUE; -+} diff --git a/tools/pkg/5/xorg-modules/diff/xmouse.diff b/tools/pkg/5/xorg-modules/diff/xmouse.diff deleted file mode 100644 index 6b0ee9f..0000000 --- a/tools/pkg/5/xorg-modules/diff/xmouse.diff +++ /dev/null @@ -1,154 +0,0 @@ -diff -Naur xf86-input-mouse-1.9.5/configure xf86-input-mouse-patched/configure ---- xf86-input-mouse-1.9.5/configure 2023-05-05 03:25:26.000000000 +0300 -+++ xf86-input-mouse-patched/configure 2025-11-07 16:18:50.878312976 +0300 -@@ -19591,7 +19591,7 @@ - - # X Server SDK location is required to install xf86-mouse-properties.h - # This location is also relayed in the xorg-mouse.pc file --sdkdir=`$PKG_CONFIG --variable=sdkdir xorg-server` -+sdkdir="$includedir" - - # Workaround overriding sdkdir to be able to create a tarball when user has no - # write permission in sdkdir. See DISTCHECK_CONFIGURE_FLAGS in Makefile.am -@@ -19619,6 +19619,9 @@ - gnu*) - OS_MOUSE_NAME=hurd - ;; -+ orange*) -+ OS_MOUSE_NAME=orange -+ ;; - esac - - -diff -Naur xf86-input-mouse-1.9.5/src/orange_mouse.c xf86-input-mouse-patched/src/orange_mouse.c ---- xf86-input-mouse-1.9.5/src/orange_mouse.c 1970-01-01 03:00:00.000000000 +0300 -+++ xf86-input-mouse-patched/src/orange_mouse.c 2025-11-08 17:39:27.721764644 +0300 -@@ -0,0 +1,128 @@ -+#ifdef HAVE_XORG_CONFIG_H -+#include <xorg-config.h> -+#endif -+ -+#include <xorg-server.h> -+#include <X11/X.h> -+#include <X11/Xproto.h> -+#include "inputstr.h" -+#include "scrnintstr.h" -+#include "mipointer.h" -+ -+#include "xf86.h" -+#include "xf86Xinput.h" -+#include "mouse.h" -+#include "xf86_OSlib.h" -+#include "xisb.h" -+ -+#include <stdio.h> -+#include <errno.h> -+#include <stdbool.h> -+#include <stdint.h> -+#include <string.h> -+ -+#include <sys/stat.h> -+ -+#define MOUSE_LB (1 << 0) -+#define MOUSE_RB (1 << 1) -+#define MOUSE_MB (1 << 2) -+#define MOUSE_B4 (1 << 3) -+#define MOUSE_B5 (1 << 4) -+ -+typedef struct { -+ unsigned char buttons; -+ unsigned char x; -+ unsigned char y; -+ unsigned char z; -+} __attribute__((packed)) mouse_packet_t; -+ -+static void orangeReadInput(InputInfoPtr pInfo) { -+ MouseDevPtr mouse = pInfo->private; -+ mouse_packet_t packet; -+ int x = 0; -+ int y = 0; -+ int z = 0; -+ unsigned char buttons = 0; -+ while(read(pInfo->fd, &packet, sizeof(packet)) == sizeof(packet)){ -+ x += (char)packet.x; -+ y += (char)packet.y; -+ z += (char)packet.z; -+ buttons |= packet.buttons; -+ -+ } -+ -+ int b = mouse->lastButtons; -+ b &= ~0x7; -+b |= (buttons & MOUSE_RB) ? 1 : 0; -+ b |= (buttons & MOUSE_MB) ? 2 : 0; -+ b |= (buttons & MOUSE_LB) ? 4 : 0; -+ -+ mouse->PostEvent(pInfo, b, x, -y, z, 0); -+ -+ -+ -+} -+ -+static Bool orangePreInit(InputInfoPtr pInfo, const char *proto, int flag) { -+ MouseDevPtr mouse; -+ -+ mouse = pInfo->private; -+ -+ mouse->protocol = proto; -+ -+ xf86ProcessCommonOptions(pInfo, pInfo->options); -+ -+ pInfo->fd = xf86OpenSerial(pInfo->options); -+ if (pInfo->fd == -1) { -+ xf86Msg(X_ERROR, "%s: cannot open mouse device!\n", pInfo->name); -+ return FALSE; -+ } -+ -+ mouse->CommonOptions(pInfo); -+ pInfo->read_input = orangeReadInput; -+ return true; -+} -+ -+#define DEVPATH "/dev/mouse" -+ -+static const char *getdevice(InputInfoPtr pInfo, const char *proto, int flag){ -+ pInfo->options = xf86AddNewOption(pInfo->options, "Device", DEVPATH); -+ return DEVPATH; -+} -+ -+static int interfacesupport() { -+ return MSE_PS2; -+} -+ -+static const char *names[] = { -+ "orangeMouseDev", NULL -+}; -+ -+static const char **protonames() { -+ return names; -+} -+ -+static const char *defaultproto() { -+ return "orangeMouseDev"; -+} -+ -+static Bool isdefault(const char *protocol) { -+ return strcmp(protocol, defaultproto()) == 0; -+} -+ -+OSMouseInfoPtr OSMouseInit(int flag) { -+ OSMouseInfoPtr p; -+ -+ p = calloc(sizeof(OSMouseInfoRec), 1); -+ -+ if (p == NULL) -+ return NULL; -+ -+ p->SupportedInterfaces = interfacesupport; -+ p->BuiltinNames = protonames; -+ p->FindDevice = getdevice; -+ p->DefaultProtocol = defaultproto; -+ p->CheckProtocol = isdefault; -+ p->PreInit = orangePreInit; -+ return p; -+} diff --git a/tools/pkg/5/xorg-modules/info.txt b/tools/pkg/5/xorg-modules/info.txt deleted file mode 100644 index 1a7e25d..0000000 --- a/tools/pkg/5/xorg-modules/info.txt +++ /dev/null @@ -1 +0,0 @@ -xorg-modules
\ No newline at end of file diff --git a/tools/pkg/5/xorg-modules/pkg.sh b/tools/pkg/5/xorg-modules/pkg.sh deleted file mode 100644 index 5fad2e9..0000000 --- a/tools/pkg/5/xorg-modules/pkg.sh +++ /dev/null @@ -1,86 +0,0 @@ - -. ../../pkg-lib.sh - -rm -rf pack -mkdir -p pack - -cd pack - -ca="$(pwd)" - -cd "$1/usr/lib" - -for file in xorg/modules/*.so; do ln -s "$file" .; done - -cd "$ca" - -fast_install "$1" https://www.x.org/archive//individual/font/font-util-1.4.1.tar.xz - -fast_install "$1" https://www.x.org/pub/individual/font/font-alias-1.0.5.tar.xz - -CFLAGS="-fPIC" SYSROOT="$1/" fast_install "$1" https://www.x.org/releases/individual/driver/xf86-video-fbdev-0.5.1.tar.gz "--disable-pciaccess --disable-static --enable-shared" "../../diff/xfbdev.diff" - -git clone https://gitlab.freedesktop.org/libevdev/libevdev.git -cd libevdev - -mkdir build -meson -Ddocumentation=disabled -Dtests=disabled --prefix=/usr build -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -git clone https://github.com/illiliti/libudev-zero.git -cd libudev-zero - -export CC=x86_64-linux-gnu-gcc -export AR=x86_64-linux-gnu-ar - -make -j$(nproc) -DESTDIR="$1" make install - -cd .. - -git clone https://gitlab.gnome.org/GNOME/libgudev.git --depth=1 -cd libgudev - -mkdir build -meson --prefix=/usr build -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -fast_install "$1" https://bitmath.org/code/mtdev/mtdev-1.1.7.tar.gz - -git clone https://github.com/linuxwacom/libwacom.git --depth=1 -cd libwacom - -mkdir build -meson --prefix=/usr build -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -git clone https://gitlab.freedesktop.org/libinput/libinput.git --depth=1 -cd libinput - -mkdir build -meson -Dtests=false --prefix=/usr build -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - - -CFLAGS="-fPIC" SYSROOT="$1/" fast_install "$1" https://www.x.org/releases/individual/driver/xf86-input-libinput-1.5.0.tar.gz -CFLAGS="-fPIC" SYSROOT="$1/" fast_install "$1" https://www.x.org/releases/individual/driver/xf86-input-evdev-2.11.0.tar.gz "--disable-static --enable-shared --disable-udev --without-libudev"
\ No newline at end of file diff --git a/tools/pkg/6/terms/diff/xloadimage.diff b/tools/pkg/6/terms/diff/xloadimage.diff deleted file mode 100644 index 4d8729b..0000000 --- a/tools/pkg/6/terms/diff/xloadimage.diff +++ /dev/null @@ -1,25 +0,0 @@ -diff -Naur xloadimage.4.1/Makefile xloadimage-patched/Makefile ---- xloadimage.4.1/Makefile 1993-11-10 01:25:12.000000000 +0300 -+++ xloadimage-patched/Makefile 2025-11-12 17:18:16.608965209 +0300 -@@ -9,9 +9,11 @@ - include Make.conf - - CFLAGS=$(OPT_FLAGS) $(CC_FLAGS) $(CC_CONFIG_FLAGS) $(X11_INC_DIR) \ -- -DSYSPATHFILE=\"$(SYSPATHFILE)\" -+ -DSYSPATHFILE=\"$(SYSPATHFILE)\" -Wno-implicit-int -Wno-implicit-function-declaration -fPIC - LIBS=$(X11_LIB_DIR) $(X11_LIB_NAME) $(SYS_LIBS) -lm - -+CC=x86_64-orange-mlibc-gcc -+ - # stuff that should eventually make the configuration file - SYSPATHFILE=/usr/lib/X11/Xloadimage - -@@ -23,7 +25,7 @@ - # the Make.conf file and recursively calls make. - - autoconfig: autoconfig.c -- $(CC) -g -o autoconfig autoconfig.c -+ $(CC) -Wno-implicit-int -Wno-implicit-function-declaration -fPIC -g -o autoconfig autoconfig.c - - # manual configuration target - configure:: autoconfig diff --git a/tools/pkg/6/terms/diff/xterm.diff b/tools/pkg/6/terms/diff/xterm.diff deleted file mode 100644 index c2d2714..0000000 --- a/tools/pkg/6/terms/diff/xterm.diff +++ /dev/null @@ -1,148 +0,0 @@ -diff --git xterm-clean/Makefile.in xterm-workdir/Makefile.in -index bb6da23..9500664 100644 ---- xterm-clean/Makefile.in -+++ xterm-workdir/Makefile.in -@@ -68,7 +68,7 @@ PIXMAPDIR_DEF = @no_pixmapdir@-DPIXMAP_ROOTDIR=\"@PIXMAPDIR@/\" - CPPFLAGS = -I. -I$(srcdir) -DHAVE_CONFIG_H @CPPFLAGS@ -DDEFCLASS=\"@APP_CLASS@\" $(PIXMAPDIR_DEF) $(EXTRA_CPPFLAGS) - CFLAGS = @CFLAGS@ $(EXTRA_CFLAGS) - LDFLAGS = @LDFLAGS@ @EXTRA_LDFLAGS@ --LIBS = @LIBS@ -+LIBS = @LIBS@ -lncursesw -ltinfow - - prefix = @prefix@ - exec_prefix = @exec_prefix@ -diff --git xterm-clean/main.c xterm-workdir/main.c -index 3d2ad4c..3f235d0 100644 ---- xterm-clean/main.c -+++ xterm-workdir/main.c -@@ -92,6 +92,7 @@ - #include <xterm.h> - #include <version.h> - #include <graphics.h> -+#include <termios.h> - - /* xterm uses these X Toolkit resource names, which are exported in array */ - #undef XtNborderWidth -@@ -172,7 +173,7 @@ static GCC_NORETURN void HsSysError(int); - #define KANJI - #endif - --#ifdef linux -+#if defined(linux) || defined(__orange__) - #define USE_SYSV_PGRP - #define USE_SYSV_SIGNALS - #define WTMP -@@ -315,7 +316,7 @@ ttyslot(void) - #ifndef NOFILE - #define NOFILE OPEN_MAX - #endif --#elif !(defined(VMS) || defined(WIN32) || defined(Lynx) || defined(__GNU__) || defined(__MVS__)) -+#elif !(defined(VMS) || defined(WIN32) || defined(Lynx) || defined(__GNU__) || defined(__MVS__) || defined(__orange__)) - #include <sys/param.h> /* for NOFILE */ - #endif - -@@ -716,11 +717,12 @@ static struct { - #endif - - #ifndef TAB3 --#if defined(OXTABS) --#define TAB3 OXTABS --#elif defined(XTABS) --#define TAB3 XTABS --#endif -+#define TAB3 0014000 -+//#if defined(OXTABS) -+//#define TAB3 OXTABS -+//#elif defined(XTABS) -+//#define TAB3 XTABS -+//#endif - #endif - - #ifndef TABDLY -@@ -3011,7 +3013,7 @@ main(int argc, char *argv[]ENVP_ARG) - } - #endif - #endif --#if defined(USE_ANY_SYSV_TERMIO) || defined(__MVS__) || defined(__minix) -+#if defined(USE_ANY_SYSV_TERMIO) || defined(__MVS__) || defined(__minix) || defined(__orange__) - if (0 > (mode = fcntl(screen->respond, F_GETFL, 0))) - SysError(ERROR_F_GETFL); - #ifdef O_NDELAY -@@ -3753,7 +3755,7 @@ ourValidShell(const char *pathname) - return findValidShell(x_strtrim(resource.valid_shells), pathname); - } - --#if defined(HAVE_GETUSERSHELL) && defined(HAVE_ENDUSERSHELL) -+#if defined(HAVE_GETUSERSHELL) && defined(HAVE_ENDUSERSHELL) && 0 - static Boolean - validShell(const char *pathname) - { -@@ -4356,7 +4358,7 @@ spawnXTerm(XtermWidget xw, unsigned line_speed) - /* - * now in child process - */ --#if defined(_POSIX_SOURCE) || defined(SVR4) || defined(__convex__) || defined(__SCO__) || defined(__QNX__) -+#if defined(_POSIX_SOURCE) || defined(SVR4) || defined(__convex__) || defined(__SCO__) || defined(__QNX__) || defined(__orange__) - int pgrp = setsid(); /* variable may not be used... */ - #else - int pgrp = getpid(); -@@ -4496,7 +4498,7 @@ spawnXTerm(XtermWidget xw, unsigned line_speed) - /* make /dev/tty work */ - ioctl(ttyfd, TCSETCTTY, 0); - #endif --#if ((defined(__GLIBC__) && defined(__FreeBSD_kernel__)) || defined(__GNU__)) && defined(TIOCSCTTY) -+#if ((defined(__GLIBC__) && defined(__FreeBSD_kernel__)) || defined(__GNU__) || defined(__orange__)) && defined(TIOCSCTTY) - /* make /dev/tty work */ - ioctl(ttyfd, TIOCSCTTY, 0); - #endif -diff --git xterm-clean/xterm.h xterm-workdir/xterm.h -index 89590cb..9a99f0c 100644 ---- xterm-clean/xterm.h -+++ xterm-workdir/xterm.h -@@ -80,7 +80,7 @@ - #define HAVE_PUTENV 1 - #endif - --#if defined(CSRG_BASED) || defined(__GNU__) || defined(__minix) -+#if defined(CSRG_BASED) || defined(__GNU__) || defined(__minix) || defined(__orange__) - #define USE_POSIX_TERMIOS 1 - #endif - -@@ -176,7 +176,7 @@ - #define USE_SYSV_UTMP - #endif - --#if defined(__GNU__) || defined(__MVS__) || defined(__osf__) -+#if defined(__GNU__) || defined(__MVS__) || defined(__osf__) || defined(__orange__) - #define USE_TTY_GROUP - #endif - -diff --git xterm-clean/xterm_io.h xterm-workdir/xterm_io.h -index 130d365..72ebd01 100644 ---- xterm-clean/xterm_io.h -+++ xterm-workdir/xterm_io.h -@@ -92,13 +92,14 @@ - #undef SYSV /* pretend to be bsd (sgtty.h) */ - #endif /* macII */ - --#ifdef __GNU__ -+#if defined(__GNU__) || defined(__orange__) - #define USE_POSIX_TERMIOS - #define HAVE_POSIX_OPENPT 1 - #define HAVE_PTSNAME 1 - #define HAVE_GRANTPT_PTY_ISATTY 1 - #endif - -+ - #if defined(__GLIBC__) && !(defined(linux) || defined(__GNU__)) - #define USE_POSIX_TERMIOS /* GNU/KFreeBSD and GNU/KNetBSD */ - #endif -@@ -212,7 +213,7 @@ - #undef FIONCLEX - #endif /* macII */ - --#if defined(__QNX__) || defined(__GNU__) || defined(__MVS__) || defined(__osf__) -+#if defined(__QNX__) || defined(__GNU__) || defined(__MVS__) || defined(__osf__) || defined(__orange__) - #undef TIOCSLTC /* <sgtty.h> conflicts with <termios.h> */ - #undef TIOCSLTC - #endif
\ No newline at end of file diff --git a/tools/pkg/6/terms/diff/xv.diff b/tools/pkg/6/terms/diff/xv.diff deleted file mode 100644 index f3e8b25..0000000 --- a/tools/pkg/6/terms/diff/xv.diff +++ /dev/null @@ -1,190 +0,0 @@ -diff -Naur xv-3.10a/fix.c xv-patched/fix.c ---- xv-3.10a/fix.c 1970-01-01 03:00:00.000000000 +0300 -+++ xv-patched/fix.c 2025-11-12 16:28:44.068915138 +0300 -@@ -0,0 +1,138 @@ -+ -+const char *sys_errlist[] = { -+ "Success", // 0 -+ "Operation not permitted", // EPERM 1 -+ "No such file or directory", // ENOENT 2 -+ "No such process", // ESRCH 3 -+ "Interrupted system call", // EINTR 4 -+ "Input/output error", // EIO 5 -+ "No such device or address", // ENXIO 6 -+ "Argument list too long", // E2BIG 7 -+ "Exec format error", // ENOEXEC 8 -+ "Bad file descriptor", // EBADF 9 -+ "No child processes", // ECHILD 10 -+ "Resource temporarily unavailable",// EAGAIN 11 -+ "Cannot allocate memory", // ENOMEM 12 -+ "Permission denied", // EACCES 13 -+ "Bad address", // EFAULT 14 -+ "Block device required", // ENOTBLK 15 -+ "Device or resource busy", // EBUSY 16 -+ "File exists", // EEXIST 17 -+ "Invalid cross-device link", // EXDEV 18 -+ "No such device", // ENODEV 19 -+ "Not a directory", // ENOTDIR 20 -+ "Is a directory", // EISDIR 21 -+ "Invalid argument", // EINVAL 22 -+ "Too many open files in system", // ENFILE 23 -+ "Too many open files", // EMFILE 24 -+ "Inappropriate ioctl for device", // ENOTTY 25 -+ "Text file busy", // ETXTBSY 26 -+ "File too large", // EFBIG 27 -+ "No space left on device", // ENOSPC 28 -+ "Illegal seek", // ESPIPE 29 -+ "Read-only file system", // EROFS 30 -+ "Too many links", // EMLINK 31 -+ "Broken pipe", // EPIPE 32 -+ "Numerical argument out of domain",// EDOM 33 -+ "Numerical result out of range", // ERANGE 34 -+ "Resource deadlock avoided", // EDEADLK 35 -+ "File name too long", // ENAMETOOLONG 36 -+ "No locks available", // ENOLCK 37 -+ "Function not implemented", // ENOSYS 38 -+ "Directory not empty", // ENOTEMPTY 39 -+ "Too many levels of symbolic links", // ELOOP 40 -+ "Unknown error 41", // (reserved) -+ "No message of desired type", // ENOMSG 42 -+ "Identifier removed", // EIDRM 43 -+ "Channel number out of range", // ECHRNG 44 -+ "Level 2 not synchronized", // EL2NSYNC 45 -+ "Level 3 halted", // EL3HLT 46 -+ "Level 3 reset", // EL3RST 47 -+ "Link number out of range", // ELNRNG 48 -+ "Protocol driver not attached", // EUNATCH 49 -+ "No CSI structure available", // ENOCSI 50 -+ "Level 2 halted", // EL2HLT 51 -+ "Invalid exchange", // EBADE 52 -+ "Invalid request descriptor", // EBADR 53 -+ "Exchange full", // EXFULL 54 -+ "No anode", // ENOANO 55 -+ "Invalid request code", // EBADRQC 56 -+ "Invalid slot", // EBADSLT 57 -+ "Unknown error 58", // (reserved) -+ "Bad font file format", // EBFONT 59 -+ "Device not a stream", // ENOSTR 60 -+ "No data available", // ENODATA 61 -+ "Timer expired", // ETIME 62 -+ "Out of streams resources", // ENOSR 63 -+ "Machine is not on the network", // ENONET 64 -+ "Package not installed", // ENOPKG 65 -+ "Object is remote", // EREMOTE 66 -+ "Link has been severed", // ENOLINK 67 -+ "Advertise error", // EADV 68 -+ "Srmount error", // ESRMNT 69 -+ "Communication error on send", // ECOMM 70 -+ "Protocol error", // EPROTO 71 -+ "Multihop attempted", // EMULTIHOP 72 -+ "RFS specific error", // EDOTDOT 73 -+ "Bad message", // EBADMSG 74 -+ "Value too large for defined data type", // EOVERFLOW 75 -+ "Name not unique on network", // ENOTUNIQ 76 -+ "File descriptor in bad state", // EBADFD 77 -+ "Remote address changed", // EREMCHG 78 -+ "Can not access a needed shared library", // ELIBACC 79 -+ "Accessing a corrupted shared library", // ELIBBAD 80 -+ "Attempting to link in too many shared libraries", // ELIBSCN 81 -+ "Cannot exec a shared library directly", // ELIBMAX 82 -+ "Invalid or incomplete multibyte or wide character", // ELIBEXEC 83 -+ "Interrupted system call should be restarted", // EILSEQ 84 -+ "Streams pipe error", // ERESTART 85 -+ "Too many users", // ESTRPIPE 86 -+ "Too many levels of remote in path", // EUSERS 87 -+ "Not a data message", // ENOTSOCK 88 -+ "Value too large for defined data type", // EDESTADDRREQ 89 -+ "Message too long", // EMSGSIZE 90 -+ "Protocol wrong type for socket", // EPROTOTYPE 91 -+ "Protocol not available", // ENOPROTOOPT 92 -+ "Protocol not supported", // EPROTONOSUPPORT 93 -+ "Socket type not supported", // ESOCKTNOSUPPORT 94 -+ "Operation not supported", // ENOTSUP 95 -+ "Protocol family not supported", // EPFNOSUPPORT 96 -+ "Address family not supported by protocol", // EAFNOSUPPORT 97 -+ "Address already in use", // EADDRINUSE 98 -+ "Cannot assign requested address", // EADDRNOTAVAIL 99 -+ "Network is down", // ENETDOWN 100 -+ "Network is unreachable", // ENETUNREACH 101 -+ "Network dropped connection on reset", // ENETRESET 102 -+ "Software caused connection abort", // ECONNABORTED 103 -+ "Connection reset by peer", // ECONNRESET 104 -+ "No buffer space available", // ENOBUFS 105 -+ "Transport endpoint is already connected", // EISCONN 106 -+ "Transport endpoint is not connected", // ENOTCONN 107 -+ "Cannot send after transport endpoint shutdown", // ESHUTDOWN 108 -+ "Too many references: cannot splice", // ETOOMANYREFS 109 -+ "Connection timed out", // ETIMEDOUT 110 -+ "Connection refused", // ECONNREFUSED 111 -+ "Host is down", // EHOSTDOWN 112 -+ "No route to host", // EHOSTUNREACH 113 -+ "Operation already in progress", // EALREADY 114 -+ "Operation now in progress", // EINPROGRESS 115 -+ "Stale file handle", // ESTALE 116 -+ "Structure needs cleaning", // EUCLEAN 117 -+ "Not a XENIX named type file", // ENOTNAM 118 -+ "No XENIX semaphores available", // ENAVAIL 119 -+ "Is a named type file", // EISNAM 120 -+ "Remote I/O error", // EREMOTEIO 121 -+ "Quota exceeded", // EDQUOT 122 -+ "No medium found", // ENOMEDIUM 123 -+ "Wrong medium type", // EMEDIUMTYPE 124 -+ "Operation Canceled", // ECANCELED 125 -+ "Required key not available", // ENOKEY 126 -+ "Key has expired", // EKEYEXPIRED 127 -+ "Key has been revoked", // EKEYREVOKED 128 -+ "Key was rejected by service", // EKEYREJECTED 129 -+ "Owner died", // EOWNERDEAD 130 -+ "State not recoverable" // ENOTRECOVERABLE 131 -+}; -+ -+const int sys_nerr = sizeof(sys_errlist) / sizeof(sys_errlist[0]); -+ -diff -Naur xv-3.10a/jpeg/jinclude.h xv-patched/jpeg/jinclude.h ---- xv-3.10a/jpeg/jinclude.h 1994-12-23 01:35:06.000000000 +0300 -+++ xv-patched/jpeg/jinclude.h 2025-11-12 15:59:23.515849947 +0300 -@@ -30,6 +30,10 @@ - * But we must pull it in because of the references to FILE in jpeglib.h. - * You can remove those references if you want to compile without <stdio.h>. - */ -+ -+#define HAVE_STDDEF_H -+#define HAVE_STDLIB_H -+#define HAVE_SYS_TYPES_H - - #ifdef HAVE_STDDEF_H - #include <stddef.h> -diff -Naur xv-3.10a/Makefile xv-patched/Makefile ---- xv-3.10a/Makefile 1995-01-23 23:20:54.000000000 +0300 -+++ xv-patched/Makefile 2025-11-12 16:26:55.784061363 +0300 -@@ -196,7 +196,7 @@ - xvdial.o xvgraf.o xvsunras.o xvjpeg.o xvps.o xvpopup.o xvdflt.o \ - xvtiff.o xvtiffwr.o xvpds.o xvrle.o xviris.o xvgrab.o vprintf.o \ - xvbrowse.o xvtext.o xvpcx.o xviff.o xvtarga.o xvxpm.o xvcut.o \ -- xvxwd.o xvfits.o -+ xvxwd.o xvfits.o fix.o - - MISC = README INSTALL CHANGELOG IDEAS - -diff -Naur xv-3.10a/xv.c xv-patched/xv.c ---- xv-3.10a/xv.c 1995-01-19 21:08:43.000000000 +0300 -+++ xv-patched/xv.c 2025-11-12 16:26:03.214754085 +0300 -@@ -48,6 +48,7 @@ - - - -+ - static int revvideo = 0; /* true if we should reverse video */ - static int dfltkludge = 0; /* true if we want dfltpic dithered */ - static int clearonload; /* clear window/root (on colormap visuals) */ -diff -Naur xv-3.10a/xv.h xv-patched/xv.h ---- xv-3.10a/xv.h 1995-01-23 23:22:23.000000000 +0300 -+++ xv-patched/xv.h 2025-11-12 16:32:18.017055828 +0300 -@@ -120,6 +120,7 @@ - # endif - #endif - -+extern int sys_nerr; - - /* not everyone has the strerror() function, or so I'm told */ - #ifndef VMS diff --git a/tools/pkg/6/terms/info.txt b/tools/pkg/6/terms/info.txt deleted file mode 100644 index 60d89d6..0000000 --- a/tools/pkg/6/terms/info.txt +++ /dev/null @@ -1 +0,0 @@ -xterms
\ No newline at end of file diff --git a/tools/pkg/6/terms/pkg.sh b/tools/pkg/6/terms/pkg.sh deleted file mode 100644 index ddd5ba9..0000000 --- a/tools/pkg/6/terms/pkg.sh +++ /dev/null @@ -1,54 +0,0 @@ -. ../../pkg-lib.sh - -rm -rf pack -mkdir -p pack - -cd pack - -git clone https://github.com/Shourai/st.git -cd st - -mkdir build - -CC=x86_64-orange-mlibc-gcc CXX=x86_64-orange-mlibc-g++ CPP=x86_64-orange-mlibc-g++ LD=x86_64-orange-mlibc-ld PKGCONFIG=x86_64-orange-mlibc-pkg-config PKG_CONFIG=x86_64-orange-mlibc-pkg-config make -j$(nproc) CFLAGS="-Wno-implicit-function-declaration -fPIC" -CC=x86_64-orange-mlibc-gcc CXX=x86_64-orange-mlibc-g++ CPP=x86_64-orange-mlibc-g++ LD=x86_64-orange-mlibc-ld PKGCONFIG=x86_64-orange-mlibc-pkg-config PKG_CONFIG=x86_64-orange-mlibc-pkg-config make install DESTDIR="$(realpath build)" - -cp -rf build/usr/local/* "$1/usr/" - -cd .. - -CFLAGS="$CFLAGS -D_XOPEN_SOURCE" - -fast_install "$1" https://invisible-mirror.net/archives/xterm/xterm-390.tgz "--disable-tcap-fkeys --disable-tcap-query --enable-256-color" "../../diff/xterm.diff" -fast_install "$1" https://www.x.org/archive/individual/lib/libXrandr-1.5.3.tar.gz -fast_install "$1" https://www.x.org/archive/individual/app/xev-1.2.5.tar.gz - -#fuck xv - -# wget https://xv.trilon.com/dist/xv-3.10a.tar.gz -# tar -xvf xv-3.10a.tar.gz -# cd xv-3.10a - -# diff_patch ../../diff/xv.diff - -# CC=x86_64-orange-mlibc-gcc CXX=x86_64-orange-mlibc-g++ CPP=x86_64-orange-mlibc-g++ LD=x86_64-orange-mlibc-ld PKGCONFIG=x86_64-orange-mlibc-pkg-config PKG_CONFIG=x86_64-orange-mlibc-pkg-config make -j$(nproc) CFLAGS="-Wno-implicit-function-declaration -fPIC -DHAVE_STDLIB_H -Wno-implicit-int -Wno-implicit-function-declaration" -# echo installing xv -# CC=x86_64-orange-mlibc-gcc CXX=x86_64-orange-mlibc-g++ CPP=x86_64-orange-mlibc-g++ LD=x86_64-orange-mlibc-ld PKGCONFIG=x86_64-orange-mlibc-pkg-config PKG_CONFIG=x86_64-orange-mlibc-pkg-config make install DESTDIR="$(realpath build)" - -# cd .. - -# wget http://deb.debian.org/debian/pool/main/x/xloadimage/xloadimage_4.1.orig.tar.gz -# tar -xvf xloadimage_4.1.orig.tar.gz - -# cd xloadimage.4.1 - -# autotools_recursive_regen -# diff_patch ../../diff/xloadimage.diff - -# CC=x86_64-orange-mlibc-gcc CXX=x86_64-orange-mlibc-g++ CPP=x86_64-orange-mlibc-g++ LD=x86_64-orange-mlibc-ld PKGCONFIG=x86_64-orange-mlibc-pkg-config PKG_CONFIG=x86_64-orange-mlibc-pkg-config make -j$(nproc) -# CC=x86_64-orange-mlibc-gcc CXX=x86_64-orange-mlibc-g++ CPP=x86_64-orange-mlibc-g++ LD=x86_64-orange-mlibc-ld PKGCONFIG=x86_64-orange-mlibc-pkg-config PKG_CONFIG=x86_64-orange-mlibc-pkg-config make install DESTDIR="$1" SYSPATHFILE="$1/usr/lib/X11/Xloadimage" INSTALLDIR="$1/usr/bin" - - -# cd .. - -cd .. diff --git a/tools/pkg/6/xcb-stuff/info.txt b/tools/pkg/6/xcb-stuff/info.txt deleted file mode 100644 index 784cd6b..0000000 --- a/tools/pkg/6/xcb-stuff/info.txt +++ /dev/null @@ -1 +0,0 @@ -xcb-stuff
\ No newline at end of file diff --git a/tools/pkg/6/xcb-stuff/pkg.sh b/tools/pkg/6/xcb-stuff/pkg.sh deleted file mode 100644 index 20d0073..0000000 --- a/tools/pkg/6/xcb-stuff/pkg.sh +++ /dev/null @@ -1,42 +0,0 @@ - -. ../../pkg-lib.sh - -rm -rf pack -mkdir pack - -cd pack - -fast_install "$1" https://www.x.org/releases/individual/xcb/xcb-util-0.4.1.tar.gz -fast_install "$1" https://www.x.org/releases/individual/xcb/xcb-util-image-0.4.1.tar.gz - -git clone https://github.com/libjpeg-turbo/libjpeg-turbo.git --depth=1 -cd libjpeg-turbo - -autotools_recursive_regen - -cd .. - -mkdir -p libjpeg-build -cd libjpeg-build - - -CFLAGS="-fPIC -Wno-implicit-function-declaration -O2" cmake ../libjpeg-turbo -DBUILD_SHARED_LIBS=OFF -DCMAKE_TOOLCHAIN_FILE=$(realpath ../../../../toolchain.cmake) -DCMAKE_INSTALL_PREFIX="$1/usr" - -make -j$(nproc) -make install - -rm -rf "$1/usr/lib/libjpeg.so" - -cd .. - -git clone https://github.com/stoeckmann/xwallpaper.git - -cd xwallpaper - -./autogen.sh -autotools_recursive_regen -./configure --host=x86_64-orange-mlibc --prefix="/usr" -make -j$(nproc) -make install DESTDIR="$1" - -cd .. diff --git a/tools/pkg/7/benchmark/a.out b/tools/pkg/7/benchmark/a.out Binary files differdeleted file mode 100755 index 4288311..0000000 --- a/tools/pkg/7/benchmark/a.out +++ /dev/null diff --git a/tools/pkg/7/benchmark/info.txt b/tools/pkg/7/benchmark/info.txt deleted file mode 100644 index e69de29..0000000 --- a/tools/pkg/7/benchmark/info.txt +++ /dev/null diff --git a/tools/pkg/7/benchmark/main.c b/tools/pkg/7/benchmark/main.c deleted file mode 100644 index bead0ff..0000000 --- a/tools/pkg/7/benchmark/main.c +++ /dev/null @@ -1,185 +0,0 @@ - -#define _GNU_SOURCE - -#include <string.h> -#include <sys/types.h> -#include <sys/mman.h> - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <time.h> - -#include <stdint.h> - -void pipe_rw_test() { - int fd[2]; - pipe(fd); - printf("OS pipe test\n"); - - char buffer[5]; - - for(int i = 0;i < 5;i++) { - struct timespec start; - struct timespec end; - clock_gettime(CLOCK_MONOTONIC,&start); - write(fd[1],"test\n",4); - read(fd[0],buffer,5); - clock_gettime(CLOCK_MONOTONIC,&end); - printf("OS pipe test %d - %llu ns\n",i,end.tv_nsec - start.tv_nsec); - - } - -} - -void rw_test() { - printf("OS r/w test\n"); - int fd = open("/tmp/testfd",O_RDWR | O_CREAT | O_TRUNC); - char buffer[5]; - - for(int i = 0;i < 5;i++) { - struct timespec start; - struct timespec end; - clock_gettime(CLOCK_MONOTONIC,&start); - write(fd,"test\n",4); - lseek(fd,0,SEEK_SET); - read(fd,buffer,5); - lseek(fd,0,SEEK_SET); - clock_gettime(CLOCK_MONOTONIC,&end); - printf("OS pipe test %d - %llu ns\n",i,end.tv_nsec - start.tv_nsec); - - } -} - -void open_test() { - printf("OS open test\n"); - for(int i = 0;i < 5;i++) { - struct timespec start; - struct timespec end; - clock_gettime(CLOCK_MONOTONIC,&start); - int fd = open("/tmp/testfd",O_RDWR | O_CREAT | O_TRUNC); - close(fd); - clock_gettime(CLOCK_MONOTONIC,&end); - printf("OS pipe test %d - %llu ns\n",i,end.tv_nsec - start.tv_nsec); - - } -} - -void mmap_test() { - printf("OS mmap test\n"); - for(int i = 0;i < 5;i++) { - struct timespec start; - struct timespec end; - clock_gettime(CLOCK_MONOTONIC,&start); - void* addr = mmap(NULL, 0x80000, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - if (addr == MAP_FAILED) { - perror("mmap failed"); - continue; - }memset(addr,1,0x80000); - clock_gettime(CLOCK_MONOTONIC,&end); - printf("OS mmap test %d - %llu ns\n",i,end.tv_nsec - start.tv_nsec); - - } -} - -typedef unsigned long long op_t; -#define OPSIZ 8 -#define byte char - -void * __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns"))) t_memset (void *dstpp, int c, size_t len) -{ - long int dstp = (long int) dstpp; - - if (len >= 8) - { - size_t xlen; - op_t cccc; - - cccc = (unsigned char) c; - cccc |= cccc << 8; - cccc |= cccc << 16; - if (OPSIZ > 4) - /* Do the shift in two steps to avoid warning if long has 32 bits. */ - cccc |= (cccc << 16) << 16; - - /* There are at least some bytes to set. - No need to test for LEN == 0 in this alignment loop. */ - while (dstp % OPSIZ != 0) - { - ((byte *) dstp)[0] = c; - dstp += 1; - len -= 1; - } - - /* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */ - xlen = len / (OPSIZ * 8); - while (xlen > 0) - { - ((op_t *) dstp)[0] = cccc; - ((op_t *) dstp)[1] = cccc; - ((op_t *) dstp)[2] = cccc; - ((op_t *) dstp)[3] = cccc; - ((op_t *) dstp)[4] = cccc; - ((op_t *) dstp)[5] = cccc; - ((op_t *) dstp)[6] = cccc; - ((op_t *) dstp)[7] = cccc; - dstp += 8 * OPSIZ; - xlen -= 1; - } - len %= OPSIZ * 8; - - /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */ - xlen = len / OPSIZ; - while (xlen > 0) - { - ((op_t *) dstp)[0] = cccc; - dstp += OPSIZ; - xlen -= 1; - } - len %= OPSIZ; - } - - /* Write the last few bytes. */ - while (len > 0) - { - ((byte *) dstp)[0] = c; - dstp += 1; - len -= 1; - } - - return dstpp; -} - -int memset_test() { - for(int i = 0; i < 16;i++) { - struct timespec start; - struct timespec end; - - clock_gettime(CLOCK_MONOTONIC,&start); - char buf[1024*1024]; - memset(buf,1,1024*1024); - clock_gettime(CLOCK_MONOTONIC,&end); - - printf("memset test %d - %llu ns\n",i,end.tv_nsec - start.tv_nsec); - } - for(int i = 0; i < 16;i++) { - struct timespec start; - struct timespec end; - - clock_gettime(CLOCK_MONOTONIC,&start); - char buf[1024*1024]; - t_memset(buf,0,1024*1024); - clock_gettime(CLOCK_MONOTONIC,&end); - - printf("opt memset test %d - %llu ns\n",i,end.tv_nsec - start.tv_nsec); - } -} - -int main() { - pipe_rw_test(); - rw_test(); - open_test(); - mmap_test(); - memset_test(); -}
\ No newline at end of file diff --git a/tools/pkg/7/benchmark/pkg.sh b/tools/pkg/7/benchmark/pkg.sh deleted file mode 100644 index d55e12c..0000000 --- a/tools/pkg/7/benchmark/pkg.sh +++ /dev/null @@ -1,2 +0,0 @@ - -x86_64-orange-mlibc-gcc main.c -o "$1/usr/bin/benchmark"
\ No newline at end of file diff --git a/tools/pkg/7/doomgeneric/diff/doomgeneric.diff b/tools/pkg/7/doomgeneric/diff/doomgeneric.diff deleted file mode 100644 index 1574959..0000000 --- a/tools/pkg/7/doomgeneric/diff/doomgeneric.diff +++ /dev/null @@ -1,250 +0,0 @@ -diff -Naur doomgeneric/doomgeneric/doomgeneric_orange.c doomgeneric-patched/doomgeneric/doomgeneric_orange.c ---- doomgeneric/doomgeneric/doomgeneric_orange.c 1970-01-01 03:00:00.000000000 +0300 -+++ doomgeneric-patched/doomgeneric/doomgeneric_orange.c 2025-06-28 10:04:14.713386809 +0300 -@@ -0,0 +1,178 @@ -+#include <stdio.h> -+#include <stdlib.h> -+#include <fcntl.h> -+#include <linux/fb.h> -+#include <sys/ioctl.h> -+#include <sys/mman.h> -+#include <unistd.h> -+#include <string.h> -+#include <stdint.h> -+#include <termios.h> -+#include <signal.h> -+ -+#include "doomkeys.h" -+ -+#include "doomgeneric.h" -+ -+int fb_fd; -+int kbd_fd; -+ -+struct fb_var_screeninfo vinfo; -+struct fb_fix_screeninfo finfo; -+unsigned char *fb_ptr;void* old_fb; -+ -+ -+struct termios back; -+ -+#include <time.h> -+ -+void __restore() { -+ memset(fb_ptr,0,vinfo.yres * vinfo.xres * vinfo.bits_per_pixel / 8); -+ char dummy[1024]; -+ for(int i = 0;i < 128;i++) { -+ read(STDIN_FILENO,dummy,128); -+ } // clear the queue and go to the latest queue -+ tcsetattr(STDIN_FILENO, TCSANOW, &back);memcpy(fb_ptr,old_fb,vinfo.yres * vinfo.xres * vinfo.bits_per_pixel / 8); -+ -+} -+ -+void DG_Init() { -+ fb_fd = open("/dev/fb0", O_RDWR); -+ kbd_fd = open("/dev/ps2keyboard", O_RDWR); -+ -+ char dummy[1024]; -+ for(int i = 0;i < 128;i++) { -+ read(kbd_fd,dummy,128); -+ } // clear the queue and go to the latest queue -+ ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo); -+ ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo); -+ -+ fb_ptr = (unsigned char *)mmap(0, vinfo.yres_virtual * vinfo.xres_virtual * vinfo.bits_per_pixel / 8, -+ PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);old_fb = (void*)malloc(vinfo.yres * vinfo.xres * vinfo.bits_per_pixel / 8); -+ -+ struct termios newt; -+ tcgetattr(STDIN_FILENO, &back); -+ tcgetattr(STDIN_FILENO, &newt); -+ newt.c_lflag &= ~(ICANON | ECHO); -+ tcsetattr(STDIN_FILENO, TCSANOW, &newt); -+ atexit(__restore); -+ -+} -+ int is_saved = 0; -+void DG_DrawFrame() { -+ if(!is_saved) { memcpy(old_fb,fb_ptr,vinfo.yres * vinfo.xres * vinfo.bits_per_pixel / 8); is_saved = 1; } -+ int screen_width = vinfo.xres; -+ int screen_height = vinfo.yres; -+ -+ -+ float x_scale = (float)screen_width / DOOMGENERIC_RESX; -+ float y_scale = (float)screen_height / DOOMGENERIC_RESY; -+ -+ -+ for (int i = 0; i < screen_height; i++) { -+ -+ int src_y = (int)(i / y_scale); -+ if (src_y >= DOOMGENERIC_RESY) { -+ src_y = DOOMGENERIC_RESY - 1; -+ } -+ -+ -+ for (int j = 0; j < screen_width; j++) { -+ -+ int src_x = (int)(j / x_scale); -+ if (src_x >= DOOMGENERIC_RESX) { -+ src_x = DOOMGENERIC_RESX - 1; -+ } -+ -+ uint64_t fb = (uint64_t)fb_ptr; -+ fb += (finfo.line_length * i); -+ memcpy((void*)(fb + j * 4), DG_ScreenBuffer + (DOOMGENERIC_RESX * src_y + src_x), 4); -+ } -+ } -+} -+ -+void DG_SleepMs(uint32_t ms) { -+ usleep(ms * 1000); -+} -+ -+uint32_t DG_GetTicksMs() { -+ struct timespec ts; -+ clock_gettime(0,&ts); -+ long ms = (ts.tv_nsec / 1000) / 1000; -+ return ms + (ts.tv_sec * 1000); -+ // hello -+} -+ -+const char en_layout_translation[] = { -+ '\0', '\e', '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', ' ' -+}; -+ -+int DG_GetKey(int* pressed, unsigned char* key) { -+ uint8_t key0 = 0; -+ int status = read(kbd_fd,&key0,1); -+ if(status <= 0) -+ return 0; -+ -+ if(key0 & (1 << 7)) { -+ *pressed = 0; -+ key0 &= ~(1 << 7); // clear release bit -+ } else -+ *pressed = 1; -+ -+ uint8_t doom_key; -+ switch(key0) { -+ case 0x1E: -+ doom_key = KEY_LEFTARROW; -+ break; -+ case 0x20: -+ doom_key = KEY_RIGHTARROW; -+ break; -+ case 0x1F: -+ doom_key = KEY_DOWNARROW; -+ break; -+ case 0x11: -+ doom_key = KEY_UPARROW; -+ break; -+ case 0x12: -+ doom_key = KEY_USE; -+ break; -+ case 0x2A: -+ case 0x37: -+ doom_key = KEY_RSHIFT; -+ break; -+ case 0x01: -+ doom_key = KEY_ESCAPE; -+ break; -+ case 0x39: -+ doom_key = KEY_FIRE; -+ break; -+ default: { -+ doom_key = en_layout_translation[key0]; -+ if(doom_key == '\n') -+ doom_key = 13; -+ break; -+ } -+ } -+ *key = doom_key; -+ return 1; -+} -+ -+void DG_SetWindowTitle(const char * title) { -+ -+} -+ -+int main(int argc, char **argv) -+{ -+ doomgeneric_Create(argc, argv); -+ -+ while (1) -+ { -+ doomgeneric_Tick(); -+ } -+ -+ return 0; -+} -+ -diff -Naur doomgeneric/doomgeneric/i_system.c doomgeneric-patched/doomgeneric/i_system.c ---- doomgeneric/doomgeneric/i_system.c 2025-06-19 16:12:59.641729634 +0300 -+++ doomgeneric-patched/doomgeneric/i_system.c 2025-06-20 20:27:17.156598938 +0300 -@@ -257,11 +257,7 @@ - entry = entry->next; - } - --#if ORIGCODE -- SDL_Quit(); -- - exit(0); --#endif - } - - #if !defined(_WIN32) && !defined(__MACOSX__) && !defined(__DJGPP__) -@@ -460,16 +456,7 @@ - } - #endif - -- // abort(); --#if ORIGCODE -- SDL_Quit(); -- - exit(-1); --#else -- while (true) -- { -- } --#endif - } - - // -diff -Naur doomgeneric/doomgeneric/Makefile doomgeneric-patched/doomgeneric/Makefile ---- doomgeneric/doomgeneric/Makefile 2025-06-19 16:12:59.634729371 +0300 -+++ doomgeneric-patched/doomgeneric/Makefile 2025-06-20 20:57:21.688983500 +0300 -@@ -12,17 +12,17 @@ - endif - - --CC=clang # gcc or g++ --CFLAGS+=-ggdb3 -Os -+CC=x86_64-orange-mlibc-gcc # gcc or g++ -+CFLAGS+=-ggdb3 -Os -std=gnu17 - LDFLAGS+=-Wl,--gc-sections - CFLAGS+=-ggdb3 -Wall -DNORMALUNIX -DLINUX -DSNDSERV -D_DEFAULT_SOURCE # -DUSEASM --LIBS+=-lm -lc -lX11 -+LIBS+=-lm -lc -lX11 - - # subdirectory for objects - OBJDIR=build - OUTPUT=doomgeneric - --SRC_DOOM = dummy.o am_map.o doomdef.o doomstat.o dstrings.o d_event.o d_items.o d_iwad.o d_loop.o d_main.o d_mode.o d_net.o f_finale.o f_wipe.o g_game.o hu_lib.o hu_stuff.o info.o i_cdmus.o i_endoom.o i_joystick.o i_scale.o i_sound.o i_system.o i_timer.o memio.o m_argv.o m_bbox.o m_cheat.o m_config.o m_controls.o m_fixed.o m_menu.o m_misc.o m_random.o p_ceilng.o p_doors.o p_enemy.o p_floor.o p_inter.o p_lights.o p_map.o p_maputl.o p_mobj.o p_plats.o p_pspr.o p_saveg.o p_setup.o p_sight.o p_spec.o p_switch.o p_telept.o p_tick.o p_user.o r_bsp.o r_data.o r_draw.o r_main.o r_plane.o r_segs.o r_sky.o r_things.o sha1.o sounds.o statdump.o st_lib.o st_stuff.o s_sound.o tables.o v_video.o wi_stuff.o w_checksum.o w_file.o w_main.o w_wad.o z_zone.o w_file_stdc.o i_input.o i_video.o doomgeneric.o doomgeneric_xlib.o -+SRC_DOOM = dummy.o am_map.o doomdef.o doomstat.o dstrings.o d_event.o d_items.o d_iwad.o d_loop.o d_main.o d_mode.o d_net.o f_finale.o f_wipe.o g_game.o hu_lib.o hu_stuff.o info.o i_cdmus.o i_endoom.o i_joystick.o i_scale.o i_sound.o i_system.o i_timer.o memio.o m_argv.o m_bbox.o m_cheat.o m_config.o m_controls.o m_fixed.o m_menu.o m_misc.o m_random.o p_ceilng.o p_doors.o p_enemy.o p_floor.o p_inter.o p_lights.o p_map.o p_maputl.o p_mobj.o p_plats.o p_pspr.o p_saveg.o p_setup.o p_sight.o p_spec.o p_switch.o p_telept.o p_tick.o p_user.o r_bsp.o r_data.o r_draw.o r_main.o r_plane.o r_segs.o r_sky.o r_things.o sha1.o sounds.o statdump.o st_lib.o st_stuff.o s_sound.o tables.o v_video.o wi_stuff.o w_checksum.o w_file.o w_main.o w_wad.o z_zone.o w_file_stdc.o i_input.o i_video.o doomgeneric.o doomgeneric_xlib.o - OBJS += $(addprefix $(OBJDIR)/, $(SRC_DOOM)) - - all: $(OUTPUT) -diff -Naur doomgeneric/doomgeneric/.vscode/settings.json doomgeneric-patched/doomgeneric/.vscode/settings.json ---- doomgeneric/doomgeneric/.vscode/settings.json 1970-01-01 03:00:00.000000000 +0300 -+++ doomgeneric-patched/doomgeneric/.vscode/settings.json 2025-06-27 18:48:57.784407657 +0300 -@@ -0,0 +1,6 @@ -+{ -+ "files.associations": { -+ "compare": "c", -+ "cstdint": "c" -+ } -+} -\ В конце файла нет новой строки
\ No newline at end of file diff --git a/tools/pkg/7/doomgeneric/pkg.sh b/tools/pkg/7/doomgeneric/pkg.sh deleted file mode 100644 index 95d4216..0000000 --- a/tools/pkg/7/doomgeneric/pkg.sh +++ /dev/null @@ -1,21 +0,0 @@ -. ../../pkg-lib.sh - -rm -rf pack - -mkdir -p pack - -cd pack - -echo $1 - -git clone https://github.com/ozkl/doomgeneric.git --depth=1 -cd doomgeneric - -diff_patch ../../diff/doomgeneric.diff -cd doomgeneric -make -j$(nproc) - -rm -rf "$1/usr/bin/doomgeneric" -cp -rf doomgeneric "$1/usr/bin/doomgeneric-x11" - -cd ../
\ No newline at end of file diff --git a/tools/pkg/7/games/diff/ace.diff b/tools/pkg/7/games/diff/ace.diff deleted file mode 100644 index 8cfc94f..0000000 --- a/tools/pkg/7/games/diff/ace.diff +++ /dev/null @@ -1,87 +0,0 @@ -diff --git ace-of-penguins-clean/lib/Makefile.am ace-of-penguins-workdir/lib/Makefile.am -index 2056424..e93f8bd 100644 ---- ace-of-penguins-clean/lib/Makefile.am -+++ ace-of-penguins-workdir/lib/Makefile.am -@@ -6,7 +6,7 @@ noinst_HEADERS = cards.h - CLEANFILES = images.c images.d - - INCLUDES = $(X_CFLAGS) @PDA@ --AM_LDFLAGS = $(X_LIBS) -+AM_LDFLAGS = $(X_LIBS) -lpng -lz -lm - - BUILD_CC = @BUILD_CC@ - AR = @AR@ -diff --git ace-of-penguins-clean/lib/make-imglib.c ace-of-penguins-workdir/lib/make-imglib.c -index 84cda12..8f12d4a 100644 ---- ace-of-penguins-clean/lib/make-imglib.c -+++ ace-of-penguins-workdir/lib/make-imglib.c -@@ -5,6 +5,7 @@ - #include <sys/stat.h> - #include <unistd.h> - #include <dirent.h> -+#include <ctype.h> - - #include <png.h> - -@@ -86,7 +87,7 @@ scan_image_directory () - png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0); - info_ptr = png_create_info_struct (png_ptr); - -- if (setjmp (png_ptr->jmpbuf)) { -+ if (setjmp (png_jmpbuf(png_ptr))) { - fclose (f); - continue; - } -@@ -202,7 +203,7 @@ tokenize(char *string) - char *rv; - if (string) { - next = string; -- return; -+ return NULL; - } - while (*next && !isgraph(*next)) next++; - if (!*next) return 0; -diff --git ace-of-penguins-clean/lib/xwin.c ace-of-penguins-workdir/lib/xwin.c -index e4bcca2..724be23 100644 ---- ace-of-penguins-clean/lib/xwin.c -+++ ace-of-penguins-workdir/lib/xwin.c -@@ -55,7 +55,7 @@ OptionDesc xwin_options_list[] = { - { "-visual", OPTION_INTEGER, &visual_id }, - { 0, 0, 0 } - }; --OptionDesc *xwin_options = xwin_options_list; -+//OptionDesc *xwin_options = xwin_options_list; - - Display *display=0; - int screen=0; -@@ -89,10 +89,10 @@ int help_background; - /* Motif window hints */ - typedef struct - { -- unsigned flags; -- unsigned functions; -- unsigned decorations; -- int inputMode; -+ unsigned long flags; -+ unsigned long functions; -+ unsigned long decorations; -+ long inputMode; - } PropMotifWmHints; - - typedef PropMotifWmHints PropMwmHints; -@@ -841,13 +841,13 @@ build_image (image *src) - png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0); - info_ptr = png_create_info_struct (png_ptr); - -- if (setjmp (png_ptr->jmpbuf)) { -+ if (setjmp (png_jmpbuf(png_ptr))) { - fprintf(stderr, "Invalid PNG image!\n"); - return; - } - - file_bytes = src->file_data; -- png_set_read_fn (png_ptr, (voidp)&file_bytes, (png_rw_ptr)png_reader); -+ png_set_read_fn (png_ptr, (void*)&file_bytes, (png_rw_ptr)png_reader); - - png_read_info (png_ptr, info_ptr); -
\ No newline at end of file diff --git a/tools/pkg/7/games/info.txt b/tools/pkg/7/games/info.txt deleted file mode 100644 index e69de29..0000000 --- a/tools/pkg/7/games/info.txt +++ /dev/null diff --git a/tools/pkg/7/games/pkg.sh b/tools/pkg/7/games/pkg.sh deleted file mode 100644 index 61240c5..0000000 --- a/tools/pkg/7/games/pkg.sh +++ /dev/null @@ -1,25 +0,0 @@ -. ../../pkg-lib.sh - -rm -rf pack - -mkdir -p pack - -cd pack - -wget https://downloads.sourceforge.net/libpng/libpng-1.6.37.tar.gz -tar -xvf libpng-1.6.37.tar.gz -cd libpng-1.6.37 - -autotools_recursive_regen - -./configure --host=x86_64-orange-mlibc --prefix=/usr --disable-shared --enable-static -make -j$(nproc) -make install DESTDIR="$1" - -cd .. - -export CFLAGS="-Wno-incompatible-pointer-types -Wno-error -fPIC -Wno-implicit-function-declaration" - -fast_install "$1" https://www.delorie.com/store/ace/ace-1.4.tar.gz "--enable-shared" "../../diff/ace.diff" - -cd ../
\ No newline at end of file diff --git a/tools/pkg/7/glib/diff/glib.diff b/tools/pkg/7/glib/diff/glib.diff deleted file mode 100644 index 1bbfe63..0000000 --- a/tools/pkg/7/glib/diff/glib.diff +++ /dev/null @@ -1,13 +0,0 @@ -diff --git glib2-clean/gio/gcredentialsprivate.h glib2-workdir/gio/gcredentialsprivate.h -index 0310a75..dba61e6 100644 ---- glib2-clean/gio/gcredentialsprivate.h -+++ glib2-workdir/gio/gcredentialsprivate.h -@@ -104,7 +104,7 @@ - */ - #undef G_CREDENTIALS_HAS_PID - --#ifdef __linux__ -+#if defined(__linux__) || defined(__orange__) - #define G_CREDENTIALS_SUPPORTED 1 - #define G_CREDENTIALS_USE_LINUX_UCRED 1 - #define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_LINUX_UCRED
\ No newline at end of file diff --git a/tools/pkg/7/glib/info.txt b/tools/pkg/7/glib/info.txt deleted file mode 100644 index 5ca6c3b..0000000 --- a/tools/pkg/7/glib/info.txt +++ /dev/null @@ -1 +0,0 @@ -glib
\ No newline at end of file diff --git a/tools/pkg/7/glib/pkg.sh b/tools/pkg/7/glib/pkg.sh deleted file mode 100644 index 186c85c..0000000 --- a/tools/pkg/7/glib/pkg.sh +++ /dev/null @@ -1,115 +0,0 @@ - -. ../../pkg-lib.sh - -rm -rf pack - -mkdir -p pack - -cd pack - -fast_install "$1" https://github.com/libffi/libffi/releases/download/v3.5.2/libffi-3.5.2.tar.gz -fast_install "$1" $GNU_MIRROR/gnu/libiconv/libiconv-1.18.tar.gz - -git clone https://github.com/PCRE2Project/pcre2.git --depth=1 -cd pcre2 - -autotools_recursive_regen -cd .. - -mkdir -p build2 -cd build2 -cmake ../pcre2 -DCMAKE_TOOLCHAIN_FILE=$(realpath ../../../../toolchain.cmake) -DCMAKE_INSTALL_PREFIX="/usr" - -cmake --build . -j$(nproc) -DESTDIR="$1" cmake --install . - -cd .. - -wget https://github.com/GNOME/glib/archive/refs/tags/2.86.1.tar.gz -mv 2.86.1.tar.gz glib2.tar.gz -tar -xvf glib2.tar.gz - -cd glib-2.86.1 - -cd subprojects -rm -rf gvdb -cd .. - -diff_patch ../../diff/glib.diff -autotools_recursive_regen - -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dglib_debug=disabled -Dsysprof=disabled -Dintrospection=disabled -Dxattr=false build - -cd build -meson compile -j$(nproc) - -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -wget https://cairographics.org/releases/cairo-1.18.4.tar.xz -tar -xvf cairo-1.18.4.tar.xz -cd cairo-1.18.4 - -mkdir -p build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dxlib-xcb=enabled -Dzlib=enabled -Dtee=enabled -Dtests=disabled build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -wget https://github.com/harfbuzz/harfbuzz/archive/refs/tags/5.0.0.tar.gz -mv 5.0.0.tar.gz harfbuzz-5.0.0.tar.gz -tar -xvf harfbuzz-5.0.0.tar.gz -cd harfbuzz-5.0.0 - -mkdir -p build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dgraphite2=disabled -Dglib=enabled -Dgobject=disabled -Dicu=disabled -Dfreetype=enabled -Dcairo=enabled -Dintrospection=disabled -Dtests=disabled build - -cd build -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -wget https://github.com/GNOME/pango/archive/refs/tags/1.49.2.tar.gz -mv 1.49.2.tar.gz pango-1.49.2.tar.gz -tar -xvf pango-1.49.2.tar.gz -cd pango-1.49.2 - -mkdir -p build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dintrospection=disabled build - -cd build -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -wget https://github.com/GNOME/gdk-pixbuf/archive/refs/tags/2.42.10.tar.gz -mv 2.42.10.tar.gz gdk-pixbuf-2.42.10.tar.gz -tar -xvf gdk-pixbuf-2.42.10.tar.gz -cd gdk-pixbuf-2.42.10 - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dgio_sniffing=false -Dman=false build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -# patch_config_sub "$(realpath $1/..)" - -# mkdir -p build0 - -# - -# cd build0 - -cd ..
\ No newline at end of file diff --git a/tools/pkg/7/python/diff/python.diff b/tools/pkg/7/python/diff/python.diff deleted file mode 100644 index 33892cf..0000000 --- a/tools/pkg/7/python/diff/python.diff +++ /dev/null @@ -1,126 +0,0 @@ -diff -Naur python/configure python-patched/configure ---- python/configure 2025-10-14 16:52:31.000000000 +0300 -+++ python-patched/configure 2025-11-16 12:02:51.627810642 +0300 -@@ -4067,6 +4067,9 @@ - *-*-wasi*) - ac_sys_system=WASI - ;; -+ *-*-mlibc*) -+ ac_sys_system=Mlibc -+ ;; - *) - # for now, limit cross builds to known configurations - MACHDEP="unknown" -@@ -4491,7 +4494,7 @@ - - if test "$cross_compiling" = yes; then - case "$host" in -- *-*-linux*) -+ *-*-linux*|*-*-mlibc*) - case "$host_cpu" in - arm*) - _host_ident=arm -@@ -7587,7 +7590,7 @@ - PY3LIBRARY=libpython3.so - fi - ;; -- Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*|VxWorks*) -+ Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*|VxWorks*|Mlibc*) - LDLIBRARY='libpython$(LDVERSION).so' - BLDLIBRARY='-L. -lpython$(LDVERSION)' - RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} -@@ -12983,7 +12986,7 @@ - Emscripten*|WASI*) - LDSHARED='$(CC) -shared' - LDCXXSHARED='$(CXX) -shared';; -- Linux*|GNU*|QNX*|VxWorks*|Haiku*) -+ Linux*|GNU*|QNX*|VxWorks*|Haiku*|Mlibc*) - LDSHARED='$(CC) -shared' - LDCXXSHARED='$(CXX) -shared';; - FreeBSD*) -@@ -13068,7 +13071,7 @@ - then CCSHARED="-fPIC"; - else CCSHARED="+z"; - fi;; -- Linux*|GNU*) CCSHARED="-fPIC";; -+ Linux*|GNU*|Mlibc*) CCSHARED="-fPIC";; - Emscripten*|WASI*) - if test "x$enable_wasm_dynamic_linking" = xyes - then : -@@ -13106,7 +13109,7 @@ - LINKFORSHARED="-Wl,-E -Wl,+s";; - # LINKFORSHARED="-Wl,-E -Wl,+s -Wl,+b\$(BINLIBDEST)/lib-dynload";; - Linux-android*) LINKFORSHARED="-pie -Xlinker -export-dynamic";; -- Linux*|GNU*) LINKFORSHARED="-Xlinker -export-dynamic";; -+ Linux*|GNU*|Mlibc*) LINKFORSHARED="-Xlinker -export-dynamic";; - # -u libsys_s pulls in all symbols in libsys - Darwin/*|iOS/*) - LINKFORSHARED="$extra_undefs -framework CoreFoundation" -diff -Naur python/Lib/site.py python-patched/Lib/site.py ---- python/Lib/site.py 2025-10-14 16:52:31.000000000 +0300 -+++ python-patched/Lib/site.py 2025-11-16 12:02:51.627810642 +0300 -@@ -409,6 +409,10 @@ - f"{implementation}{ver[0]}.{ver[1]}{abi_thread}", - "site-packages") - sitepackages.append(path) -+ path = os.path.join(prefix, libdir, -+ f"{implementation}{ver[0]}.{ver[1]}{abi_thread}", -+ "dist-packages") -+ sitepackages.append(path) - else: - sitepackages.append(prefix) - sitepackages.append(os.path.join(prefix, "Lib", "site-packages")) -diff -Naur python/Modules/timemodule.c python-patched/Modules/timemodule.c ---- python/Modules/timemodule.c 2025-10-14 16:52:31.000000000 +0300 -+++ python-patched/Modules/timemodule.c 2025-11-16 12:10:46.792330954 +0300 -@@ -185,13 +185,7 @@ - static int - time_clockid_converter(PyObject *obj, clockid_t *p) - { --#ifdef _AIX -- long long clk_id = PyLong_AsLongLong(obj); --#elif defined(__DragonFly__) -- long clk_id = PyLong_AsLong(obj); --#else -- int clk_id = PyLong_AsInt(obj); --#endif -+ int clk_id = PyLong_AsInt(obj); - if (clk_id == -1 && PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "clk_id should be integer, not %s", -diff -Naur python/Objects/mimalloc/prim/unix/prim.c python-patched/Objects/mimalloc/prim/unix/prim.c ---- python/Objects/mimalloc/prim/unix/prim.c 2025-10-14 16:52:31.000000000 +0300 -+++ python-patched/Objects/mimalloc/prim/unix/prim.c 2025-11-16 12:02:51.627810642 +0300 -@@ -29,6 +29,10 @@ - #include <unistd.h> // sysconf - #include <fcntl.h> // open, close, read, access - -+#if defined(__orange__) -+ #define MADV_DONTNEED 1 -+#endif -+ - #if defined(__linux__) - #include <features.h> - #include <fcntl.h> -@@ -51,11 +55,6 @@ - #include <sys/sysctl.h> - #endif - --#if !defined(__HAIKU__) && !defined(__APPLE__) && !defined(__CYGWIN__) && !defined(_AIX) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__sun) && !defined(__NetBSD__) -- #define MI_HAS_SYSCALL_H -- #include <sys/syscall.h> --#endif -- - //------------------------------------------------------------------------------------ - // Use syscalls for some primitives to allow for libraries that override open/read/close etc. - // and do allocation themselves; using syscalls prevents recursion when mimalloc is -@@ -156,6 +155,9 @@ - static int unix_madvise(void* addr, size_t size, int advice) { - #if defined(__sun) - return madvise((caddr_t)addr, size, advice); // Solaris needs cast (issue #520) -+ #elif defined(__orange__) -+ (void)addr; (void)size; (void)advice; -+ return 0; - #else - return madvise(addr, size, advice); - #endif diff --git a/tools/pkg/7/python/info.txt b/tools/pkg/7/python/info.txt deleted file mode 100644 index d8654aa..0000000 --- a/tools/pkg/7/python/info.txt +++ /dev/null @@ -1 +0,0 @@ -python
\ No newline at end of file diff --git a/tools/pkg/7/python/pkg.sh b/tools/pkg/7/python/pkg.sh deleted file mode 100644 index 1233804..0000000 --- a/tools/pkg/7/python/pkg.sh +++ /dev/null @@ -1,32 +0,0 @@ - -. ../../pkg-lib.sh - -rm -rf pack - -mkdir -p pack - -cd pack - -export ac_cv_file__dev_ptmx=yes -export ac_cv_file__dev_ptc=yes -export ac_cv_func_sched_setscheduler=no -export ac_cv_buggy_getaddrinfo=no - -rm -rf "$1/usr/bin/python" "$1/usr/bin/python3" "$1/usr/lib/python" "$1/usr/lib/python3" "$1/usr/lib/python3.13" - -mkdir -p "$1/usr/lib/python3.13" - -fast_install "$1" https://www.python.org/ftp/python/3.13.9/Python-3.13.9.tar.xz "--build=x86_64 --with-computed-gotos --disable-optimizations --disable-ipv6 --without-system-expat --enable-loadable-sqlite-extensions --without-ensurepip --with-tzpath=/usr/share/zoneinfo --with-build-python=python3 --without-static-libpython $BUILDPYTHON" "../../diff/python.diff" - -ln -sfv python3 "$1/usr"/bin/python -ln -sfv python3-config "$1/usr"/bin/python-config -ln -sfv pydoc3 "$1/usr"/bin/pydoc -ln -sfv idle3 "$1/usr"/bin/idle - -mv "$1/usr"/lib/python3.13 "$1/usr"/lib/python3 - -ln -sfv python3 "$1/usr"/lib/python3.13 - -# rm -r "$1"/usr/lib/python*/{test,ctypes/test,distutils/tests,idlelib/idle_test,lib2to3/tests,sqlite3/test,tkinter/test,unittest/test} # used from arch linux pkgbuild - -cd .. diff --git a/tools/pkg/8/gtk/diff/dbus.diff b/tools/pkg/8/gtk/diff/dbus.diff deleted file mode 100644 index 96e8339..0000000 --- a/tools/pkg/8/gtk/diff/dbus.diff +++ /dev/null @@ -1,52 +0,0 @@ -diff --git dbus-clean/dbus/dbus-sysdeps-unix.c dbus-workdir/dbus/dbus-sysdeps-unix.c -index 87ba2d8..c4ab364 100644 ---- dbus-clean/dbus/dbus-sysdeps-unix.c -+++ dbus-workdir/dbus/dbus-sysdeps-unix.c -@@ -2589,29 +2589,12 @@ DBusSocket - _dbus_accept (DBusSocket listen_fd) - { - DBusSocket client_fd; -- struct sockaddr addr; -- socklen_t addrlen; --#ifdef HAVE_ACCEPT4 -- dbus_bool_t cloexec_done; --#endif -- -- addrlen = sizeof (addr); -+ struct sockaddr_un addr; -+ socklen_t addrlen = sizeof (addr); - - retry: -- --#ifdef HAVE_ACCEPT4 -- /* -- * At compile-time, we assume that if accept4() is available in -- * libc headers, SOCK_CLOEXEC is too. At runtime, it is still -- * not necessarily true that either is supported by the running kernel. -- */ -- client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC); -- cloexec_done = client_fd.fd >= 0; -- -- if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL)) --#endif - { -- client_fd.fd = accept (listen_fd.fd, &addr, &addrlen); -+ client_fd.fd = accept (listen_fd.fd, (struct sockaddr *)&addr, &addrlen); - } - - if (client_fd.fd < 0) -@@ -2620,14 +2603,6 @@ _dbus_accept (DBusSocket listen_fd) - goto retry; - } - -- _dbus_verbose ("client fd %d accepted\n", client_fd.fd); -- --#ifdef HAVE_ACCEPT4 -- if (!cloexec_done) --#endif -- { -- _dbus_fd_set_close_on_exec(client_fd.fd); -- } - - return client_fd; - } diff --git a/tools/pkg/8/gtk/info.txt b/tools/pkg/8/gtk/info.txt deleted file mode 100644 index 8f7a9f2..0000000 --- a/tools/pkg/8/gtk/info.txt +++ /dev/null @@ -1 +0,0 @@ -gtk3
\ No newline at end of file diff --git a/tools/pkg/8/gtk/pkg.sh b/tools/pkg/8/gtk/pkg.sh deleted file mode 100644 index 9659416..0000000 --- a/tools/pkg/8/gtk/pkg.sh +++ /dev/null @@ -1,85 +0,0 @@ - -. ../../pkg-lib.sh - -rm -rf pack - -mkdir -p pack - -cd pack - -# git clone https://github.com/libexpat/libexpat.git -# cd libexpat -# mkdir build -# cd build - -# cmake ../expat -DCMAKE_TOOLCHAIN_FILE=$(realpath ../../../../../toolchain.cmake) -DCMAKE_INSTALL_PREFIX="/usr" - -# cmake --build . -j$(nproc) -# DESTDIR="$1" cmake --install . - -# cd ../.. - -fast_install "$1" https://www.x.org/archive/individual/lib/libXtst-1.2.5.tar.gz - -git clone https://gitlab.gnome.org/GNOME/libxml2.git --depth=1 -cd libxml2 - -mkdir build - -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dpython=disabled -Dhistory=disabled -Dicu=disabled -Dreadline=disabled -Dzlib=enabled build -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -wget https://gitlab.freedesktop.org/dbus/dbus/-/archive/dbus-1.16.2/dbus-dbus-1.16.2.tar.gz -tar -xvf dbus-dbus-1.16.2.tar.gz -cd dbus-dbus-1.16.2 - -diff_patch ../../diff/dbus.diff - -mkdir build - -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Druntime_dir=/run -Dsystemd_system_unitdir=no -Dsystemd_user_unitdir=no -Dsystem_pid_file=/run/dbus/pid -Dsystem_socket=/run/dbus/system_bus_socket -Dselinux=disabled -Dapparmor=disabled -Dlibaudit=disabled -Dkqueue=disabled -Dlaunchd=disabled -Dsystemd=disabled -Dmodular_tests=disabled -Depoll=disabled -Dverbose_mode=true build -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -touch "$1/usr/share/dbus-1/session.d/.keep" -touch "$1/var/lib/dbus/.keep" - -cd ../.. -wget https://gitlab.gnome.org/GNOME/at-spi2-core/-/archive/2.56.6/at-spi2-core-2.56.6.tar -tar -xvf at-spi2-core-2.56.6.tar -cd at-spi2-core-2.56.6 - -mkdir build - -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" -Dsystemd_user_dir=/tmp -Dintrospection=disabled --prefix=/usr build -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -wget https://github.com/GNOME/gobject-introspection/archive/refs/tags/1.86.0.tar.gz -mv 1.86.0.tar.gz intro.tar.gz -tar -xvf intro.tar.gz - -cd gobject-introspection-1.86.0 - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dgtk_doc=false -Dbuild_introspection_data=false build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - -cd ..
\ No newline at end of file diff --git a/tools/pkg/8/llvm/diff/llvm.diff b/tools/pkg/8/llvm/diff/llvm.diff deleted file mode 100644 index 91b0d37..0000000 --- a/tools/pkg/8/llvm/diff/llvm.diff +++ /dev/null @@ -1,512 +0,0 @@ -diff --git llvm-libs-clean/clang/lib/Basic/Targets/OSTargets.h llvm-libs-workdir/clang/lib/Basic/Targets/OSTargets.h -index c1a68f4..b94b913 100644 ---- llvm-libs-clean/clang/lib/Basic/Targets/OSTargets.h -+++ llvm-libs-workdir/clang/lib/Basic/Targets/OSTargets.h -@@ -428,6 +428,36 @@ public: - } - }; - -+// Orange Target -+template <typename Target> -+class LLVM_LIBRARY_VISIBILITY OrangeTargetInfo : public OSTargetInfo<Target> { -+protected: -+ void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, -+ MacroBuilder &Builder) const override { -+ DefineStd(Builder, "unix", Opts); -+ Builder.defineMacro("__orange__"); -+ if (Opts.POSIXThreads) -+ Builder.defineMacro("_REENTRANT"); -+ if (Opts.CPlusPlus) -+ Builder.defineMacro("_GNU_SOURCE"); -+ if (this->HasFloat128) -+ Builder.defineMacro("__FLOAT128__"); -+ } -+ -+public: -+ OrangeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) -+ : OSTargetInfo<Target>(Triple, Opts) { -+ switch (Triple.getArch()) { -+ default: -+ break; -+ case llvm::Triple::x86: -+ case llvm::Triple::x86_64: -+ this->HasFloat128 = true; -+ break; -+ } -+ } -+}; -+ - // NetBSD Target - template <typename Target> - class LLVM_LIBRARY_VISIBILITY NetBSDTargetInfo : public OSTargetInfo<Target> { -diff --git llvm-libs-clean/clang/lib/Basic/Targets.cpp llvm-libs-workdir/clang/lib/Basic/Targets.cpp -index 5d11578..785e846 100644 ---- llvm-libs-clean/clang/lib/Basic/Targets.cpp -+++ llvm-libs-workdir/clang/lib/Basic/Targets.cpp -@@ -167,6 +167,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple, - case llvm::Triple::Managarm: - return std::make_unique<ManagarmTargetInfo<AArch64leTargetInfo>>(Triple, - Opts); -+ case llvm::Triple::Orange: -+ return std::make_unique<OrangeTargetInfo<AArch64leTargetInfo>>(Triple, -+ Opts); - case llvm::Triple::NetBSD: - return std::make_unique<NetBSDTargetInfo<AArch64leTargetInfo>>(Triple, - Opts); -@@ -472,6 +475,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple, - case llvm::Triple::Managarm: - return std::make_unique<ManagarmTargetInfo<RISCV64TargetInfo>>(Triple, - Opts); -+ case llvm::Triple::Orange: -+ return std::make_unique<OrangeTargetInfo<RISCV64TargetInfo>>(Triple, -+ Opts); - default: - return std::make_unique<RISCV64TargetInfo>(Triple, Opts); - } -@@ -663,6 +669,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple, - case llvm::Triple::Managarm: - return std::make_unique<ManagarmTargetInfo<X86_64TargetInfo>>(Triple, - Opts); -+ case llvm::Triple::Orange: -+ return std::make_unique<OrangeTargetInfo<X86_64TargetInfo>>(Triple, -+ Opts); - default: - return std::make_unique<X86_64TargetInfo>(Triple, Opts); - } -diff --git llvm-libs-clean/clang/lib/Driver/CMakeLists.txt llvm-libs-workdir/clang/lib/Driver/CMakeLists.txt -index 0268ec4..a619016 100644 ---- llvm-libs-clean/clang/lib/Driver/CMakeLists.txt -+++ llvm-libs-workdir/clang/lib/Driver/CMakeLists.txt -@@ -67,6 +67,7 @@ add_clang_library(clangDriver - ToolChains/Hurd.cpp - ToolChains/Linux.cpp - ToolChains/Managarm.cpp -+ ToolChains/Orange.cpp - ToolChains/MipsLinux.cpp - ToolChains/MinGW.cpp - ToolChains/MSP430.cpp -diff --git llvm-libs-clean/clang/lib/Driver/Driver.cpp llvm-libs-workdir/clang/lib/Driver/Driver.cpp -index 55748c0..d2fbf76 100644 ---- llvm-libs-clean/clang/lib/Driver/Driver.cpp -+++ llvm-libs-workdir/clang/lib/Driver/Driver.cpp -@@ -34,6 +34,7 @@ - #include "ToolChains/MSP430.h" - #include "ToolChains/MSVC.h" - #include "ToolChains/Managarm.h" -+#include "ToolChains/Orange.h" - #include "ToolChains/MinGW.h" - #include "ToolChains/MipsLinux.h" - #include "ToolChains/NaCl.h" -@@ -6850,6 +6851,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, - case llvm::Triple::Managarm: - TC = std::make_unique<toolchains::Managarm>(*this, Target, Args); - break; -+ case llvm::Triple::Orange: -+ TC = std::make_unique<toolchains::Orange>(*this, Target, Args); -+ break; - case llvm::Triple::Solaris: - TC = std::make_unique<toolchains::Solaris>(*this, Target, Args); - break; -diff --git llvm-libs-workdir/clang/lib/Driver/ToolChains/Orange.cpp llvm-libs-workdir/clang/lib/Driver/ToolChains/Orange.cpp -new file mode 100644 -index 0000000..4c2060c ---- /dev/null -+++ llvm-libs-workdir/clang/lib/Driver/ToolChains/Orange.cpp -@@ -0,0 +1,227 @@ -+//===--- Orange.h - Orange ToolChain Implementations --------*- C++ -*-===// -+// -+// The LLVM Compiler Infrastructure -+// -+// This file is distributed under the University of Illinois Open Source -+// License. See LICENSE.TXT for details. -+// -+//===----------------------------------------------------------------------===// -+ -+#include "Orange.h" -+#include "Arch/ARM.h" -+#include "Arch/RISCV.h" -+#include "CommonArgs.h" -+#include "clang/Config/config.h" -+#include "clang/Driver/Driver.h" -+#include "clang/Driver/Options.h" -+#include "clang/Driver/SanitizerArgs.h" -+#include "llvm/Option/ArgList.h" -+#include "llvm/Support/Path.h" -+ -+using namespace clang::driver; -+using namespace clang::driver::toolchains; -+using namespace clang; -+using namespace llvm::opt; -+ -+using tools::addPathIfExists; -+ -+std::string Orange::getMultiarchTriple(const Driver &D, -+ const llvm::Triple &TargetTriple, -+ StringRef SysRoot) const { -+ // For most architectures, just use whatever we have rather than trying to be -+ // clever. -+ switch (TargetTriple.getArch()) { -+ default: -+ break; -+ -+ case llvm::Triple::x86_64: -+ // We don't want this for x32, otherwise it will match x86_64 libs -+ return "x86_64-orange-" + TargetTriple.getEnvironmentName().str(); -+ case llvm::Triple::aarch64: -+ return "aarch64-orange-" + TargetTriple.getEnvironmentName().str(); -+ case llvm::Triple::riscv64: -+ return "riscv64-orange-" + TargetTriple.getEnvironmentName().str(); -+ } -+ return TargetTriple.str(); -+} -+ -+static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { -+ // It happens that only x86, PPC and SPARC use the 'lib32' variant of -+ // oslibdir, and using that variant while targeting other architectures causes -+ // problems because the libraries are laid out in shared system roots that -+ // can't cope with a 'lib32' library search path being considered. So we only -+ // enable them when we know we may need it. -+ // -+ // FIXME: This is a bit of a hack. We should really unify this code for -+ // reasoning about oslibdir spellings with the lib dir spellings in the -+ // GCCInstallationDetector, but that is a more significant refactoring. -+ if (Triple.getArch() == llvm::Triple::x86 || Triple.isPPC32() || -+ Triple.getArch() == llvm::Triple::sparc) -+ return "lib32"; -+ -+ if (Triple.getArch() == llvm::Triple::x86_64 && Triple.isX32()) -+ return "libx32"; -+ -+ if (Triple.getArch() == llvm::Triple::riscv32) -+ return "lib32"; -+ -+ return Triple.isArch32Bit() ? "lib" : "lib64"; -+} -+ -+Orange::Orange(const Driver &D, const llvm::Triple &Triple, -+ const ArgList &Args) -+ : Generic_ELF(D, Triple, Args) { -+ GCCInstallation.init(Triple, Args); -+ Multilibs = GCCInstallation.getMultilibs(); -+ SelectedMultilibs.assign({GCCInstallation.getMultilib()}); -+ std::string SysRoot = computeSysRoot(); -+ -+ ToolChain::path_list &PPaths = getProgramPaths(); -+ -+ Generic_GCC::PushPPaths(PPaths); -+ -+#ifdef ENABLE_LINKER_BUILD_ID -+ ExtraOpts.push_back("--build-id"); -+#endif -+ -+ // The selection of paths to try here is designed to match the patterns which -+ // the GCC driver itself uses, as this is part of the GCC-compatible driver. -+ // This was determined by running GCC in a fake filesystem, creating all -+ // possible permutations of these directories, and seeing which ones it added -+ // to the link paths. -+ path_list &Paths = getFilePaths(); -+ -+ const std::string OSLibDir = std::string(getOSLibDir(Triple, Args)); -+ const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot); -+ -+ Generic_GCC::AddMultilibPaths(D, SysRoot, OSLibDir, MultiarchTriple, Paths); -+ -+ addPathIfExists(D, concat(SysRoot, "/lib", MultiarchTriple), Paths); -+ addPathIfExists(D, concat(SysRoot, "/lib/..", OSLibDir), Paths); -+ addPathIfExists(D, concat(SysRoot, "/usr/lib/", MultiarchTriple), Paths); -+ addPathIfExists(D, concat(SysRoot, "/usr/lib/../", OSLibDir), Paths); -+ -+ Generic_GCC::AddMultiarchPaths(D, SysRoot, OSLibDir, Paths); -+ -+ addPathIfExists(D, SysRoot + "/lib", Paths); -+ addPathIfExists(D, SysRoot + "/usr/lib", Paths); -+} -+ -+bool Orange::HasNativeLLVMSupport() const { return true; } -+ -+Tool *Orange::buildLinker() const { -+ return new tools::gnutools::Linker(*this); -+} -+ -+Tool *Orange::buildAssembler() const { -+ return new tools::gnutools::Assembler(*this); -+} -+ -+std::string Orange::computeSysRoot() const { -+ if (!getDriver().SysRoot.empty()) -+ return getDriver().SysRoot; -+ return std::string(); -+} -+ -+std::string Orange::getDynamicLinker(const ArgList &Args) const { -+ switch (getTriple().getArch()) { -+ case llvm::Triple::aarch64: -+ return "/usr/lib/ld.so"; -+ case llvm::Triple::riscv64: { -+ return "/usr/lib/ld.so"; -+ -+ } -+ case llvm::Triple::x86_64: -+ return "/usr/lib/ld.so"; -+ default: -+ llvm_unreachable("unsupported architecture"); -+ } -+} -+ -+void Orange::AddClangSystemIncludeArgs(const ArgList &DriverArgs, -+ ArgStringList &CC1Args) const { -+ const Driver &D = getDriver(); -+ std::string SysRoot = computeSysRoot(); -+ -+ if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) -+ return; -+ -+ if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) -+ addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include"); -+ -+ // Add 'include' in the resource directory, which is similar to -+ // GCC_INCLUDE_DIR (private headers) in GCC. -+ if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { -+ SmallString<128> ResourceDirInclude(D.ResourceDir); -+ llvm::sys::path::append(ResourceDirInclude, "include"); -+ addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude); -+ } -+ -+ if (DriverArgs.hasArg(options::OPT_nostdlibinc)) -+ return; -+ -+ // TOOL_INCLUDE_DIR -+ AddMultilibIncludeArgs(DriverArgs, CC1Args); -+ -+ // Check for configure-time C include directories. -+ StringRef CIncludeDirs(C_INCLUDE_DIRS); -+ if (CIncludeDirs != "") { -+ SmallVector<StringRef, 5> dirs; -+ CIncludeDirs.split(dirs, ":"); -+ for (StringRef dir : dirs) { -+ StringRef Prefix = -+ llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : ""; -+ addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); -+ } -+ return; -+ } -+ -+ // On systems using multiarch, add /usr/include/$triple before -+ // /usr/include. -+ std::string MultiarchIncludeDir = getMultiarchTriple(D, getTriple(), SysRoot); -+ if (!MultiarchIncludeDir.empty()) -+ addExternCSystemInclude( -+ DriverArgs, CC1Args, -+ concat(SysRoot, "/usr/include", MultiarchIncludeDir)); -+ -+ // Add an include of '/include' directly. This isn't provided by default by -+ // system GCCs, but is often used with cross-compiling GCCs, and harmless to -+ // add even when Clang is acting as-if it were a system compiler. -+ addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/include")); -+ -+ addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/include")); -+} -+ -+void Orange::addLibStdCxxIncludePaths( -+ const llvm::opt::ArgList &DriverArgs, -+ llvm::opt::ArgStringList &CC1Args) const { -+ // We need a detected GCC installation on Orange to provide libstdc++'s -+ // headers. -+ if (!GCCInstallation.isValid()) -+ return; -+ -+ StringRef TripleStr = GCCInstallation.getTriple().str(); -+ -+ // Try generic GCC detection. -+ Generic_GCC::addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args, TripleStr); -+} -+ -+SanitizerMask Orange::getSupportedSanitizers() const { -+ const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; -+ const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; -+ SanitizerMask Res = ToolChain::getSupportedSanitizers(); -+ Res |= SanitizerKind::PointerCompare; -+ Res |= SanitizerKind::PointerSubtract; -+ Res |= SanitizerKind::KernelAddress; -+ Res |= SanitizerKind::Vptr; -+ if (IsX86_64) -+ Res |= SanitizerKind::KernelMemory; -+ if (IsX86 || IsX86_64) -+ Res |= SanitizerKind::Function; -+ return Res; -+} -+ -+void Orange::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { -+ for (const auto &Opt : ExtraOpts) -+ CmdArgs.push_back(Opt.c_str()); -+} -diff --git llvm-libs-workdir/clang/lib/Driver/ToolChains/Orange.h llvm-libs-workdir/clang/lib/Driver/ToolChains/Orange.h -new file mode 100644 -index 0000000..8fcac48 ---- /dev/null -+++ llvm-libs-workdir/clang/lib/Driver/ToolChains/Orange.h -@@ -0,0 +1,55 @@ -+//===--- Orange.h - Orange ToolChain Implementations --------*- C++ -*-===// -+// -+// The LLVM Compiler Infrastructure -+// -+// This file is distributed under the University of Illinois Open Source -+// License. See LICENSE.TXT for details. -+// -+//===----------------------------------------------------------------------===// -+ -+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ORANGE_H -+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ORANGE_H -+ -+#include "Gnu.h" -+#include "clang/Driver/ToolChain.h" -+ -+namespace clang { -+namespace driver { -+namespace toolchains { -+ -+class LLVM_LIBRARY_VISIBILITY Orange : public Generic_ELF { -+public: -+ Orange(const Driver &D, const llvm::Triple &Triple, -+ const llvm::opt::ArgList &Args); -+ -+ bool HasNativeLLVMSupport() const override; -+ -+ std::string getMultiarchTriple(const Driver &D, -+ const llvm::Triple &TargetTriple, -+ StringRef SysRoot) const override; -+ -+ void -+ AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, -+ llvm::opt::ArgStringList &CC1Args) const override; -+ void -+ addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, -+ llvm::opt::ArgStringList &CC1Args) const override; -+ SanitizerMask getSupportedSanitizers() const override; -+ std::string computeSysRoot() const override; -+ -+ std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override; -+ -+ void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override; -+ -+ std::vector<std::string> ExtraOpts; -+ -+protected: -+ Tool *buildAssembler() const override; -+ Tool *buildLinker() const override; -+}; -+ -+} // end namespace toolchains -+} // end namespace driver -+} // end namespace clang -+ -+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ORANGE_H -diff --git llvm-libs-clean/llvm/include/llvm/ADT/bit.h llvm-libs-workdir/llvm/include/llvm/ADT/bit.h -index d6e33c3..611da93 100644 ---- llvm-libs-clean/llvm/include/llvm/ADT/bit.h -+++ llvm-libs-workdir/llvm/include/llvm/ADT/bit.h -@@ -30,7 +30,7 @@ - - #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \ - defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || \ -- defined(__OpenBSD__) || defined(__DragonFly__) || defined(__managarm__) -+ defined(__OpenBSD__) || defined(__DragonFly__) || defined(__managarm__) || defined(__orange__) - #include <endian.h> - #elif defined(_AIX) - #include <sys/machine.h> -diff --git llvm-libs-clean/llvm/include/llvm/TargetParser/Triple.h llvm-libs-workdir/llvm/include/llvm/TargetParser/Triple.h -index 657f423..6d826bc 100644 ---- llvm-libs-clean/llvm/include/llvm/TargetParser/Triple.h -+++ llvm-libs-workdir/llvm/include/llvm/TargetParser/Triple.h -@@ -212,6 +212,7 @@ public: - Lv2, // PS3 - MacOSX, - Managarm, -+ Orange, - NetBSD, - OpenBSD, - Solaris, -@@ -864,6 +865,8 @@ public: - - bool isOSManagarm() const { return getOS() == Triple::Managarm; } - -+ bool isOSOrange() const { return getOS() == Triple::Orange; } -+ - bool isShaderStageEnvironment() const { - EnvironmentType Env = getEnvironment(); - return Env == Triple::Pixel || Env == Triple::Vertex || -diff --git llvm-libs-clean/llvm/lib/Support/Unix/Path.inc llvm-libs-workdir/llvm/lib/Support/Unix/Path.inc -index 277247e..26a0c06 100644 ---- llvm-libs-clean/llvm/lib/Support/Unix/Path.inc -+++ llvm-libs-workdir/llvm/lib/Support/Unix/Path.inc -@@ -108,7 +108,7 @@ typedef uint_t uint; - #endif - - #if defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__) || \ -- defined(__MVS__) -+ defined(__MVS__) || defined(__orange__) - #define STATVFS_F_FLAG(vfs) (vfs).f_flag - #else - #define STATVFS_F_FLAG(vfs) (vfs).f_flags -@@ -127,7 +127,7 @@ const file_t kInvalidFile = -1; - defined(__CYGWIN__) || defined(__DragonFly__) || defined(_AIX) || \ - defined(__GNU__) || \ - (defined(__sun__) && defined(__svr4__) || defined(__HAIKU__)) || \ -- defined(__managarm__) -+ defined(__managarm__) || defined(__orange__) - static int test_dir(char ret[PATH_MAX], const char *dir, const char *bin) { - struct stat sb; - char fullpath[PATH_MAX]; -@@ -249,7 +249,7 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) { - if (getprogpath(exe_path, argv0) != NULL) - return exe_path; - #elif defined(__linux__) || defined(__CYGWIN__) || defined(__gnu_hurd__) || \ -- defined(__managarm__) -+ defined(__managarm__) || defined(__orange__) - char exe_path[PATH_MAX]; - const char *aPath = "/proc/self/exe"; - if (sys::fs::exists(aPath)) { -@@ -551,7 +551,7 @@ static bool is_local_impl(struct STATVFS &Vfs) { - - // vmount entry not found; "remote" is the conservative answer. - return false; --#elif defined(__MVS__) -+#elif defined(__MVS__) || defined(__orange__) - // The file system can have an arbitrary structure on z/OS; must go with the - // conservative answer. - return false; -diff --git llvm-libs-clean/llvm/lib/Support/Unix/Process.inc llvm-libs-workdir/llvm/lib/Support/Unix/Process.inc -index c6e79af..66f884f 100644 ---- llvm-libs-clean/llvm/lib/Support/Unix/Process.inc -+++ llvm-libs-workdir/llvm/lib/Support/Unix/Process.inc -@@ -38,6 +38,9 @@ - #include <sys/ioctl.h> - #endif - -+#include <asm/ioctls.h> -+#include <termios.h> -+ - //===----------------------------------------------------------------------===// - //=== WARNING: Implementation here must contain only generic UNIX code that - //=== is guaranteed to work on *all* UNIX variants. -diff --git llvm-libs-clean/llvm/lib/TargetParser/Triple.cpp llvm-libs-workdir/llvm/lib/TargetParser/Triple.cpp -index 0584c94..e8886ea 100644 ---- llvm-libs-clean/llvm/lib/TargetParser/Triple.cpp -+++ llvm-libs-workdir/llvm/lib/TargetParser/Triple.cpp -@@ -302,6 +302,8 @@ StringRef Triple::getOSTypeName(OSType Kind) { - case MacOSX: return "macosx"; - case Managarm: - return "managarm"; -+ case Orange: -+ return "orange"; - case Mesa3D: return "mesa3d"; - case NVCL: return "nvcl"; - case NaCl: return "nacl"; -@@ -684,6 +686,7 @@ static Triple::OSType parseOS(StringRef OSName) { - .StartsWith("lv2", Triple::Lv2) - .StartsWith("macos", Triple::MacOSX) - .StartsWith("managarm", Triple::Managarm) -+ .StartsWith("orange", Triple::Orange) - .StartsWith("netbsd", Triple::NetBSD) - .StartsWith("openbsd", Triple::OpenBSD) - .StartsWith("solaris", Triple::Solaris) diff --git a/tools/pkg/8/llvm/info.txt b/tools/pkg/8/llvm/info.txt deleted file mode 100644 index 0d68131..0000000 --- a/tools/pkg/8/llvm/info.txt +++ /dev/null @@ -1 +0,0 @@ -llvm
\ No newline at end of file diff --git a/tools/pkg/8/llvm/pkg.sh b/tools/pkg/8/llvm/pkg.sh deleted file mode 100644 index ed96c57..0000000 --- a/tools/pkg/8/llvm/pkg.sh +++ /dev/null @@ -1,32 +0,0 @@ - -. ../../pkg-lib.sh - -exit 0 #im not compiling this shit - -rm -rf pack - -mkdir -p pack - -cd pack - -wget https://github.com/llvm/llvm-project/releases/download/llvmorg-21.1.5/llvm-project-21.1.5.src.tar.xz -tar -xvf llvm-project-21.1.5.src.tar.xz -cd llvm-project-21.1.5.src - -diff_patch ../../diff/llvm.diff -mkdir build - -cd build -cmake ../llvm -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-D_GNU_SOURCE=1 -fPIC -O3" -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE -DCMAKE_CXX_STANDARD=17 -DUNIX=1 -DCMAKE_TOOLCHAIN_FILE=$(realpath ../../../../../toolchain.cmake) -DCMAKE_INSTALL_PREFIX="/usr" -UBUILD_SHARED_LIBS -UENABLE_STATIC -DLLVM_LINK_LLVM_DYLIB=ON -DLLVM_ENABLE_FFI=ON -DLLVM_ENABLE_EH=ON -DLLVM_ENABLE_RTTI=ON -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-orange-mlibc -DLLVM_HOST_TRIPLE=x86_64-orange-mlibc -Wno-dev - -mkdir temp_sysroot - -cmake --build . -j$(nproc) -DESTDIR="$(realpath temp_sysroot)" cmake --install . - -rm -rf temp_sysroot/bin -rm -rf temp_sysroot/lib/*.a - -cp -r temp_sysroot "$1" - -cd ../..
\ No newline at end of file diff --git a/tools/pkg/9/mesa/diff/mesa.diff b/tools/pkg/9/mesa/diff/mesa.diff deleted file mode 100644 index b9d0307..0000000 --- a/tools/pkg/9/mesa/diff/mesa.diff +++ /dev/null @@ -1,127 +0,0 @@ -diff --git mesa-clean/include/drm-uapi/drm.h mesa-workdir/include/drm-uapi/drm.h -index 4e4f7c2..2e4d3e2 100644 ---- mesa-clean/include/drm-uapi/drm.h -+++ mesa-workdir/include/drm-uapi/drm.h -@@ -44,7 +44,7 @@ typedef unsigned int drm_handle_t; - #else /* One of the BSDs */ - - #include <stdint.h> --#include <sys/ioccom.h> -+//#include <sys/ioccom.h> - #include <sys/types.h> - typedef int8_t __s8; - typedef uint8_t __u8; -diff --git mesa-clean/meson.build mesa-workdir/meson.build -index 9fb4160..1a1a827 100644 ---- mesa-clean/meson.build -+++ mesa-workdir/meson.build -@@ -1040,7 +1040,7 @@ if cc.has_function('fmemopen') - endif - - # TODO: this is very incomplete --if ['linux', 'cygwin', 'gnu', 'freebsd', 'gnu/kfreebsd', 'haiku', 'android', 'managarm'].contains(host_machine.system()) -+if ['linux', 'cygwin', 'gnu', 'freebsd', 'gnu/kfreebsd', 'haiku', 'android', 'managarm', 'orange'].contains(host_machine.system()) - pre_args += '-D_GNU_SOURCE' - elif host_machine.system() == 'sunos' - pre_args += '-D__EXTENSIONS__' -diff --git mesa-clean/src/gallium/drivers/llvmpipe/lp_screen.c mesa-workdir/src/gallium/drivers/llvmpipe/lp_screen.c -index 7daa531..6b6dd7b 100644 ---- mesa-clean/src/gallium/drivers/llvmpipe/lp_screen.c -+++ mesa-workdir/src/gallium/drivers/llvmpipe/lp_screen.c -@@ -128,7 +128,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) - #endif - - switch (param) { --#ifdef HAVE_LINUX_UDMABUF_H -+#if defined(HAVE_LINUX_UDMABUF_H) && defined(__linux__) - case PIPE_CAP_DMABUF: - if (lscreen->udmabuf_fd != -1) - return DRM_PRIME_CAP_IMPORT | DRM_PRIME_CAP_EXPORT; -@@ -1173,7 +1173,7 @@ llvmpipe_create_screen(struct sw_winsys *winsys) - screen->num_threads); - screen->num_threads = MIN2(screen->num_threads, LP_MAX_THREADS); - --#ifdef HAVE_LINUX_UDMABUF_H -+#if defined(HAVE_LINUX_UDMABUF_H) && defined(__linux__) - screen->udmabuf_fd = open("/dev/udmabuf", O_RDWR); - #endif - -diff --git mesa-clean/src/gallium/drivers/llvmpipe/lp_texture.c mesa-workdir/src/gallium/drivers/llvmpipe/lp_texture.c -index 2aab5bf..e8f9d69 100644 ---- mesa-clean/src/gallium/drivers/llvmpipe/lp_texture.c -+++ mesa-workdir/src/gallium/drivers/llvmpipe/lp_texture.c -@@ -63,6 +63,10 @@ - #include "drm-uapi/drm_fourcc.h" - #endif - -+#ifdef __orange__ -+#undef HAVE_LINUX_UDMABUF_H -+#endif -+ - #ifdef HAVE_LINUX_UDMABUF_H - #include <fcntl.h> - #include <sys/mman.h> -diff --git mesa-clean/src/util/detect_os.h mesa-workdir/src/util/detect_os.h -index 86286df..f3a5106 100644 ---- mesa-clean/src/util/detect_os.h -+++ mesa-workdir/src/util/detect_os.h -@@ -91,6 +91,11 @@ - #define DETECT_OS_POSIX 1 - #endif - -+#if defined(__orange__) -+#define DETECT_OS_ORANGE 1 -+#define DETECT_OS_POSIX 1 -+#endif -+ - - /* - * Make sure DETECT_OS_* are always defined, so that they can be used with #if -diff --git mesa-clean/src/util/os_misc.c mesa-workdir/src/util/os_misc.c -index f529318..a61cd93 100644 ---- mesa-clean/src/util/os_misc.c -+++ mesa-workdir/src/util/os_misc.c -@@ -57,7 +57,7 @@ - # include <unistd.h> - # include <log/log.h> - # include <cutils/properties.h> --#elif DETECT_OS_LINUX || DETECT_OS_CYGWIN || DETECT_OS_SOLARIS || DETECT_OS_HURD || DETECT_OS_MANAGARM -+#elif DETECT_OS_LINUX || DETECT_OS_CYGWIN || DETECT_OS_SOLARIS || DETECT_OS_HURD || DETECT_OS_MANAGARM || DETECT_OS_ORANGE - # include <unistd.h> - #elif DETECT_OS_OPENBSD || DETECT_OS_FREEBSD - # include <sys/resource.h> -@@ -274,7 +274,7 @@ exit_mutex: - bool - os_get_total_physical_memory(uint64_t *size) - { --#if DETECT_OS_LINUX || DETECT_OS_CYGWIN || DETECT_OS_SOLARIS || DETECT_OS_HURD || DETECT_OS_MANAGARM -+#if DETECT_OS_LINUX || DETECT_OS_CYGWIN || DETECT_OS_SOLARIS || DETECT_OS_HURD || DETECT_OS_MANAGARM || DETECT_OS_ORANGE - const long phys_pages = sysconf(_SC_PHYS_PAGES); - const long page_size = sysconf(_SC_PAGE_SIZE); - -diff --git mesa-clean/src/util/os_time.c mesa-workdir/src/util/os_time.c -index da8ad7a..001cc3a 100644 ---- mesa-clean/src/util/os_time.c -+++ mesa-workdir/src/util/os_time.c -@@ -65,7 +65,7 @@ os_time_get_nano(void) - void - os_time_sleep(int64_t usecs) - { --#if DETECT_OS_LINUX || DETECT_OS_MANAGARM || DETECT_OS_FUCHSIA -+#if DETECT_OS_LINUX || DETECT_OS_MANAGARM || DETECT_OS_FUCHSIA || DETECT_OS_ORANGE - struct timespec time; - time.tv_sec = usecs / 1000000; - time.tv_nsec = (usecs % 1000000) * 1000; -diff --git mesa-clean/src/util/u_thread.c mesa-workdir/src/util/u_thread.c -index 255c5f6..a532705 100644 ---- mesa-clean/src/util/u_thread.c -+++ mesa-workdir/src/util/u_thread.c -@@ -75,7 +75,7 @@ int u_thread_create(thrd_t *thrd, int (*routine)(void *), void *param) - void u_thread_setname( const char *name ) - { - #if defined(HAVE_PTHREAD) --#if DETECT_OS_LINUX || DETECT_OS_CYGWIN || DETECT_OS_SOLARIS || defined(__GLIBC__) || DETECT_OS_MANAGARM || DETECT_OS_FUCHSIA -+#if DETECT_OS_LINUX || DETECT_OS_CYGWIN || DETECT_OS_SOLARIS || defined(__GLIBC__) || DETECT_OS_MANAGARM || DETECT_OS_FUCHSIA || DETECT_OS_ORANGE - int ret = pthread_setname_np(pthread_self(), name); - if (ret == ERANGE) { - char buf[16]; diff --git a/tools/pkg/9/mesa/glx.pc b/tools/pkg/9/mesa/glx.pc deleted file mode 100644 index 48a4c7f..0000000 --- a/tools/pkg/9/mesa/glx.pc +++ /dev/null @@ -1,9 +0,0 @@ -prefix=/usr -includedir=${prefix}/include -libdir=${prefix}/lib - -Name: GLX -Description: GLX library and headers. -Version: 1.4 -Libs: -L${libdir} -lGL -Cflags: -I${includedir}
\ No newline at end of file diff --git a/tools/pkg/9/mesa/info.txt b/tools/pkg/9/mesa/info.txt deleted file mode 100644 index 1ad1bbe..0000000 --- a/tools/pkg/9/mesa/info.txt +++ /dev/null @@ -1 +0,0 @@ -mesa
\ No newline at end of file diff --git a/tools/pkg/9/mesa/pkg.sh b/tools/pkg/9/mesa/pkg.sh deleted file mode 100644 index 6575d45..0000000 --- a/tools/pkg/9/mesa/pkg.sh +++ /dev/null @@ -1,44 +0,0 @@ - -. ../../pkg-lib.sh - -rm -rf pack - -mkdir -p pack - -cd pack - -fast_install "$1" https://www.x.org/archive/individual/lib/libXext-1.3.4.tar.gz - -wget https://gitlab.freedesktop.org/mesa/mesa/-/archive/mesa-25.2.7/mesa-mesa-25.2.7.tar.gz -tar -xvf mesa-mesa-25.2.7.tar.gz -cd mesa-mesa-25.2.7 - -diff_patch ../../diff/mesa.diff - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dglx=xlib -Dplatforms=x11 -Dgallium-drivers=softpipe -Dllvm=false -Dvulkan-drivers= -Dvideo-codecs=all_free build -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cp -rf "../../../glx.pc" "$1/usr/lib/pkgconfig" - -cd ../.. - -wget https://archive.mesa3d.org/glu/glu-9.0.3.tar.xz -tar -xvf glu-9.0.3.tar.xz -cd glu-9.0.3 - -mkdir build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix=/usr -Dgl_provider=gl build - -cd build - -meson compile -j$(nproc) -DESTDIR="$1" meson install --no-rebuild - -cd ../.. - - -cd ..
\ No newline at end of file diff --git a/tools/pkg/build-pkg.sh b/tools/pkg/build-pkg.sh deleted file mode 100644 index c7550e7..0000000 --- a/tools/pkg/build-pkg.sh +++ /dev/null @@ -1,25 +0,0 @@ - -echo "Building orange's packages" - -export PATH="$HOME/opt/cross/orange/bin:$PATH" - -if [ ! "$(which x86_64-orange-mlibc-gcc)" ]; then - echo "It looks like you don't have the cross-compiler installed, or it isn't in your PATH." - echo "If you built your cross-compiler, add it to your PATH with:" - echo 'export PATH="$HOME/opt/cross/orange/bin:$PATH"' - echo 'Alternatively, you can build the cross-compiler with: sh build-cross.sh' - echo 'Also you should have host gcc ~13 or ~ 14' -fi - -for dir in {0..15}; do - cd "$dir" - for pkg_dir in */; do - cd "$pkg_dir" - echo "Building $(cat info.txt)" - bash pkg.sh "$1" - cd .. - done - cd .. -done - -echo Done diff --git a/tools/pkg/config.guess b/tools/pkg/config.guess deleted file mode 100644 index 344680a..0000000 --- a/tools/pkg/config.guess +++ /dev/null @@ -1,1818 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright 1992-2025 Free Software Foundation, Inc. - -# shellcheck disable=SC2006,SC2268 # see below for rationale - -timestamp='2025-07-10' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see <https://www.gnu.org/licenses/>. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). -# -# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. -# -# You can get the latest version of this script from: -# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess -# -# Please send patches to <config-patches@gnu.org>. - - -# The "shellcheck disable" line above the timestamp inhibits complaints -# about features and limitations of the classic Bourne shell that were -# superseded or lifted in POSIX. However, this script identifies a wide -# variety of pre-POSIX systems that do not have POSIX shells at all, and -# even some reasonably current systems (Solaris 10 as case-in-point) still -# have a pre-POSIX /bin/sh. - - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system '$me' is run on. - -Options: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright 1992-2025 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try '$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -# Just in case it came from the environment. -GUESS= - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still -# use 'HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -tmp= -# shellcheck disable=SC2172 -trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 - -set_cc_for_build() { - # prevent multiple calls if $tmp is already set - test "$tmp" && return 0 - : "${TMPDIR=/tmp}" - # shellcheck disable=SC2039,SC3028 - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } - dummy=$tmp/dummy - case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in - ,,) echo "int x;" > "$dummy.c" - for driver in cc gcc c17 c99 c89 ; do - if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then - CC_FOR_BUILD=$driver - break - fi - done - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; - esac -} - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if test -f /.attbin/uname ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -case $UNAME_SYSTEM in -Linux|GNU|GNU/*) - LIBC=unknown - - set_cc_for_build - cat <<-EOF > "$dummy.c" - #if defined(__ANDROID__) - LIBC=android - #else - #include <features.h> - #if defined(__UCLIBC__) - LIBC=uclibc - #elif defined(__dietlibc__) - LIBC=dietlibc - #elif defined(__GLIBC__) - LIBC=gnu - #elif defined(__LLVM_LIBC__) - LIBC=llvm - #else - #include <stdarg.h> - /* First heuristic to detect musl libc. */ - #ifdef __DEFINED_va_list - LIBC=musl - #endif - #endif - #endif - EOF - cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` - eval "$cc_set_libc" - - # Second heuristic to detect musl libc. - if [ "$LIBC" = unknown ] && - command -v ldd >/dev/null && - ldd --version 2>&1 | grep -q ^musl; then - LIBC=musl - fi - - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - if [ "$LIBC" = unknown ]; then - LIBC=gnu - fi - ;; -esac - -# Note: order is significant - the case branches are not exclusive. - -case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ - /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ - echo unknown)` - case $UNAME_MACHINE_ARCH in - aarch64eb) machine=aarch64_be-unknown ;; - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - earmv*) - arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` - machine=${arch}${endian}-unknown - ;; - *) machine=$UNAME_MACHINE_ARCH-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently (or will in the future) and ABI. - case $UNAME_MACHINE_ARCH in - earm*) - os=netbsdelf - ;; - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # Determine ABI tags. - case $UNAME_MACHINE_ARCH in - earm*) - expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case $UNAME_VERSION in - Debian*) - release='-gnu' - ;; - *) - release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - GUESS=$machine-${os}${release}${abi-} - ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE - ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE - ;; - *:SecBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` - GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE - ;; - *:LibertyBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` - GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE - ;; - *:MidnightBSD:*:*) - GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE - ;; - *:ekkoBSD:*:*) - GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE - ;; - *:SolidBSD:*:*) - GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE - ;; - *:OS108:*:*) - GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE - ;; - macppc:MirBSD:*:*) - GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE - ;; - *:MirBSD:*:*) - GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE - ;; - *:Sortix:*:*) - GUESS=$UNAME_MACHINE-unknown-sortix - ;; - *:Twizzler:*:*) - GUESS=$UNAME_MACHINE-unknown-twizzler - ;; - *:Redox:*:*) - GUESS=$UNAME_MACHINE-unknown-redox - ;; - mips:OSF1:*.*) - GUESS=mips-dec-osf1 - ;; - alpha:OSF1:*:*) - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - trap '' 0 - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case $ALPHA_CPU_TYPE in - "EV4 (21064)") - UNAME_MACHINE=alpha ;; - "EV4.5 (21064)") - UNAME_MACHINE=alpha ;; - "LCA4 (21066/21068)") - UNAME_MACHINE=alpha ;; - "EV5 (21164)") - UNAME_MACHINE=alphaev5 ;; - "EV5.6 (21164A)") - UNAME_MACHINE=alphaev56 ;; - "EV5.6 (21164PC)") - UNAME_MACHINE=alphapca56 ;; - "EV5.7 (21164PC)") - UNAME_MACHINE=alphapca57 ;; - "EV6 (21264)") - UNAME_MACHINE=alphaev6 ;; - "EV6.7 (21264A)") - UNAME_MACHINE=alphaev67 ;; - "EV6.8CB (21264C)") - UNAME_MACHINE=alphaev68 ;; - "EV6.8AL (21264B)") - UNAME_MACHINE=alphaev68 ;; - "EV6.8CX (21264D)") - UNAME_MACHINE=alphaev68 ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE=alphaev69 ;; - "EV7 (21364)") - UNAME_MACHINE=alphaev7 ;; - "EV7.9 (21364A)") - UNAME_MACHINE=alphaev79 ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` - GUESS=$UNAME_MACHINE-dec-osf$OSF_REL - ;; - Amiga*:UNIX_System_V:4.0:*) - GUESS=m68k-unknown-sysv4 - ;; - *:[Aa]miga[Oo][Ss]:*:*) - GUESS=$UNAME_MACHINE-unknown-amigaos - ;; - *:[Mm]orph[Oo][Ss]:*:*) - GUESS=$UNAME_MACHINE-unknown-morphos - ;; - *:OS/390:*:*) - GUESS=i370-ibm-openedition - ;; - *:z/VM:*:*) - GUESS=s390-ibm-zvmoe - ;; - *:OS400:*:*) - GUESS=powerpc-ibm-os400 - ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - GUESS=arm-acorn-riscix$UNAME_RELEASE - ;; - arm*:riscos:*:*|arm*:RISCOS:*:*) - GUESS=arm-unknown-riscos - ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - GUESS=hppa1.1-hitachi-hiuxmpp - ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - case `(/bin/universe) 2>/dev/null` in - att) GUESS=pyramid-pyramid-sysv3 ;; - *) GUESS=pyramid-pyramid-bsd ;; - esac - ;; - NILE*:*:*:dcosx) - GUESS=pyramid-pyramid-svr4 - ;; - DRS?6000:unix:4.0:6*) - GUESS=sparc-icl-nx6 - ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) GUESS=sparc-icl-nx7 ;; - esac - ;; - s390x:SunOS:*:*) - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` - GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL - ;; - sun4H:SunOS:5.*:*) - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` - GUESS=sparc-hal-solaris2$SUN_REL - ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` - GUESS=sparc-sun-solaris2$SUN_REL - ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - GUESS=i386-pc-auroraux$UNAME_RELEASE - ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - set_cc_for_build - SUN_ARCH=i386 - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if test "$CC_FOR_BUILD" != no_compiler_found; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH=x86_64 - fi - fi - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` - GUESS=$SUN_ARCH-pc-solaris2$SUN_REL - ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` - GUESS=sparc-sun-solaris3$SUN_REL - ;; - sun4*:SunOS:*:*) - case `/usr/bin/arch -k` in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like '4.1.3-JL'. - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` - GUESS=sparc-sun-sunos$SUN_REL - ;; - sun3*:SunOS:*:*) - GUESS=m68k-sun-sunos$UNAME_RELEASE - ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 - case `/bin/arch` in - sun3) - GUESS=m68k-sun-sunos$UNAME_RELEASE - ;; - sun4) - GUESS=sparc-sun-sunos$UNAME_RELEASE - ;; - esac - ;; - aushp:SunOS:*:*) - GUESS=sparc-auspex-sunos$UNAME_RELEASE - ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - GUESS=m68k-atari-mint$UNAME_RELEASE - ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - GUESS=m68k-atari-mint$UNAME_RELEASE - ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - GUESS=m68k-atari-mint$UNAME_RELEASE - ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - GUESS=m68k-milan-mint$UNAME_RELEASE - ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - GUESS=m68k-hades-mint$UNAME_RELEASE - ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - GUESS=m68k-unknown-mint$UNAME_RELEASE - ;; - m68k:machten:*:*) - GUESS=m68k-apple-machten$UNAME_RELEASE - ;; - powerpc:machten:*:*) - GUESS=powerpc-apple-machten$UNAME_RELEASE - ;; - RISC*:Mach:*:*) - GUESS=mips-dec-mach_bsd4.3 - ;; - RISC*:ULTRIX:*:*) - GUESS=mips-dec-ultrix$UNAME_RELEASE - ;; - VAX*:ULTRIX*:*:*) - GUESS=vax-dec-ultrix$UNAME_RELEASE - ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - GUESS=clipper-intergraph-clix$UNAME_RELEASE - ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - set_cc_for_build - sed 's/^ //' << EOF > "$dummy.c" -#ifdef __cplusplus -#include <stdio.h> /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o "$dummy" "$dummy.c" && - dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`"$dummy" "$dummyarg"` && - { echo "$SYSTEM_NAME"; exit; } - GUESS=mips-mips-riscos$UNAME_RELEASE - ;; - Motorola:PowerMAX_OS:*:*) - GUESS=powerpc-motorola-powermax - ;; - Motorola:*:4.3:PL8-*) - GUESS=powerpc-harris-powermax - ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - GUESS=powerpc-harris-powermax - ;; - Night_Hawk:Power_UNIX:*:*) - GUESS=powerpc-harris-powerunix - ;; - m88k:CX/UX:7*:*) - GUESS=m88k-harris-cxux7 - ;; - m88k:*:4*:R4*) - GUESS=m88k-motorola-sysv4 - ;; - m88k:*:3*:R3*) - GUESS=m88k-motorola-sysv3 - ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 - then - if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ - test "$TARGET_BINARY_INTERFACE"x = x - then - GUESS=m88k-dg-dgux$UNAME_RELEASE - else - GUESS=m88k-dg-dguxbcs$UNAME_RELEASE - fi - else - GUESS=i586-dg-dgux$UNAME_RELEASE - fi - ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - GUESS=m88k-dolphin-sysv3 - ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - GUESS=m88k-motorola-sysv3 - ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - GUESS=m88k-tektronix-sysv3 - ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - GUESS=m68k-tektronix-bsd - ;; - *:IRIX*:*:*) - IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` - GUESS=mips-sgi-irix$IRIX_REL - ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id - ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - GUESS=i386-ibm-aix - ;; - ia64:AIX:*:*) - if test -x /usr/bin/oslevel ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=$UNAME_VERSION.$UNAME_RELEASE - fi - GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV - ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - set_cc_for_build - sed 's/^ //' << EOF > "$dummy.c" - #include <sys/systemcfg.h> - - int - main () - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` - then - GUESS=$SYSTEM_NAME - else - GUESS=rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - GUESS=rs6000-ibm-aix3.2.4 - else - GUESS=rs6000-ibm-aix3.2 - fi - ;; - *:AIX:*:[4567]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if test -x /usr/bin/lslpp ; then - IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ - awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` - else - IBM_REV=$UNAME_VERSION.$UNAME_RELEASE - fi - GUESS=$IBM_ARCH-ibm-aix$IBM_REV - ;; - *:AIX:*:*) - GUESS=rs6000-ibm-aix - ;; - ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) - GUESS=romp-ibm-bsd4.4 - ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to - ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - GUESS=rs6000-bull-bosx - ;; - DPX/2?00:B.O.S.:*:*) - GUESS=m68k-bull-sysv3 - ;; - 9000/[34]??:4.3bsd:1.*:*) - GUESS=m68k-hp-bsd - ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - GUESS=m68k-hp-bsd4.4 - ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` - case $UNAME_MACHINE in - 9000/31?) HP_ARCH=m68000 ;; - 9000/[34]??) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if test -x /usr/bin/getconf; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case $sc_cpu_version in - 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 - 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case $sc_kernel_bits in - 32) HP_ARCH=hppa2.0n ;; - 64) HP_ARCH=hppa2.0w ;; - '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 - esac ;; - esac - fi - if test "$HP_ARCH" = ""; then - set_cc_for_build - sed 's/^ //' << EOF > "$dummy.c" - - #define _HPUX_SOURCE - #include <stdlib.h> - #include <unistd.h> - - int - main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if test "$HP_ARCH" = hppa2.0w - then - set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | - grep -q __LP64__ - then - HP_ARCH=hppa2.0w - else - HP_ARCH=hppa64 - fi - fi - GUESS=$HP_ARCH-hp-hpux$HPUX_REV - ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` - GUESS=ia64-hp-hpux$HPUX_REV - ;; - 3050*:HI-UX:*:*) - set_cc_for_build - sed 's/^ //' << EOF > "$dummy.c" - #include <unistd.h> - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && - { echo "$SYSTEM_NAME"; exit; } - GUESS=unknown-hitachi-hiuxwe2 - ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) - GUESS=hppa1.1-hp-bsd - ;; - 9000/8??:4.3bsd:*:*) - GUESS=hppa1.0-hp-bsd - ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - GUESS=hppa1.0-hp-mpeix - ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) - GUESS=hppa1.1-hp-osf - ;; - hp8??:OSF1:*:*) - GUESS=hppa1.0-hp-osf - ;; - i*86:OSF1:*:*) - if test -x /usr/sbin/sysversion ; then - GUESS=$UNAME_MACHINE-unknown-osf1mk - else - GUESS=$UNAME_MACHINE-unknown-osf1 - fi - ;; - parisc*:Lites*:*:*) - GUESS=hppa1.1-hp-lites - ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - GUESS=c1-convex-bsd - ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - GUESS=c34-convex-bsd - ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - GUESS=c38-convex-bsd - ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - GUESS=c4-convex-bsd - ;; - CRAY*Y-MP:*:*:*) - CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` - GUESS=ymp-cray-unicos$CRAY_REL - ;; - CRAY*[A-Z]90:*:*:*) - echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` - GUESS=t90-cray-unicos$CRAY_REL - ;; - CRAY*T3E:*:*:*) - CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` - GUESS=alphaev5-cray-unicosmk$CRAY_REL - ;; - CRAY*SV1:*:*:*) - CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` - GUESS=sv1-cray-unicos$CRAY_REL - ;; - *:UNICOS/mp:*:*) - CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` - GUESS=craynv-cray-unicosmp$CRAY_REL - ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` - GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} - ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` - GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} - ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE - ;; - sparc*:BSD/OS:*:*) - GUESS=sparc-unknown-bsdi$UNAME_RELEASE - ;; - *:BSD/OS:*:*) - GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE - ;; - arm:FreeBSD:*:*) - UNAME_PROCESSOR=`uname -p` - set_cc_for_build - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` - GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi - else - FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` - GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf - fi - ;; - *:FreeBSD:*:*) - UNAME_PROCESSOR=`uname -p` - case $UNAME_PROCESSOR in - amd64) - UNAME_PROCESSOR=x86_64 ;; - i386) - UNAME_PROCESSOR=i586 ;; - esac - FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` - GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL - ;; - i*:CYGWIN*:*) - GUESS=$UNAME_MACHINE-pc-cygwin - ;; - *:MINGW64*:*) - GUESS=$UNAME_MACHINE-pc-mingw64 - ;; - *:MINGW*:*) - GUESS=$UNAME_MACHINE-pc-mingw32 - ;; - *:MSYS*:*) - GUESS=$UNAME_MACHINE-pc-msys - ;; - i*:PW*:*) - GUESS=$UNAME_MACHINE-pc-pw32 - ;; - *:SerenityOS:*:*) - GUESS=$UNAME_MACHINE-pc-serenity - ;; - *:Interix*:*) - case $UNAME_MACHINE in - x86) - GUESS=i586-pc-interix$UNAME_RELEASE - ;; - authenticamd | genuineintel | EM64T) - GUESS=x86_64-unknown-interix$UNAME_RELEASE - ;; - IA64) - GUESS=ia64-unknown-interix$UNAME_RELEASE - ;; - esac ;; - i*:UWIN*:*) - GUESS=$UNAME_MACHINE-pc-uwin - ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - GUESS=x86_64-pc-cygwin - ;; - prep*:SunOS:5.*:*) - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` - GUESS=powerpcle-unknown-solaris2$SUN_REL - ;; - *:GNU:*:*) - # the GNU system - GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` - GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` - GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL - ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` - GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` - GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC - ;; - x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) - GUESS="$UNAME_MACHINE-pc-managarm-mlibc" - ;; - *:[Mm]anagarm:*:*) - GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" - ;; - *:Minix:*:*) - GUESS=$UNAME_MACHINE-unknown-minix - ;; - aarch64:Linux:*:*) - set_cc_for_build - CPU=$UNAME_MACHINE - LIBCABI=$LIBC - if test "$CC_FOR_BUILD" != no_compiler_found; then - ABI=64 - sed 's/^ //' << EOF > "$dummy.c" - #ifdef __ARM_EABI__ - #ifdef __ARM_PCS_VFP - ABI=eabihf - #else - ABI=eabi - #endif - #endif -EOF - cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` - eval "$cc_set_abi" - case $ABI in - eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; - esac - fi - GUESS=$CPU-unknown-linux-$LIBCABI - ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC=gnulibc1 ; fi - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - arm*:Linux:*:*) - set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi - else - GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf - fi - fi - ;; - avr32*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - cris:Linux:*:*) - GUESS=$UNAME_MACHINE-axis-linux-$LIBC - ;; - crisv32:Linux:*:*) - GUESS=$UNAME_MACHINE-axis-linux-$LIBC - ;; - e2k:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - frv:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - hexagon:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - i*86:Linux:*:*) - GUESS=$UNAME_MACHINE-pc-linux-$LIBC - ;; - ia64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - k1om:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - kvx:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - kvx:cos:*:*) - GUESS=$UNAME_MACHINE-unknown-cos - ;; - kvx:mbr:*:*) - GUESS=$UNAME_MACHINE-unknown-mbr - ;; - loongarch32:Linux:*:* | loongarch64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - m32r*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - m68*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - mips:Linux:*:* | mips64:Linux:*:*) - set_cc_for_build - IS_GLIBC=0 - test x"${LIBC}" = xgnu && IS_GLIBC=1 - sed 's/^ //' << EOF > "$dummy.c" - #undef CPU - #undef mips - #undef mipsel - #undef mips64 - #undef mips64el - #if ${IS_GLIBC} && defined(_ABI64) - LIBCABI=gnuabi64 - #else - #if ${IS_GLIBC} && defined(_ABIN32) - LIBCABI=gnuabin32 - #else - LIBCABI=${LIBC} - #endif - #endif - - #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 - CPU=mipsisa64r6 - #else - #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 - CPU=mipsisa32r6 - #else - #if defined(__mips64) - CPU=mips64 - #else - CPU=mips - #endif - #endif - #endif - - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - MIPS_ENDIAN=el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - MIPS_ENDIAN= - #else - MIPS_ENDIAN= - #endif - #endif -EOF - cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` - eval "$cc_set_vars" - test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } - ;; - mips64el:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - openrisc*:Linux:*:*) - GUESS=or1k-unknown-linux-$LIBC - ;; - or32:Linux:*:* | or1k*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - padre:Linux:*:*) - GUESS=sparc-unknown-linux-$LIBC - ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - GUESS=hppa64-unknown-linux-$LIBC - ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; - PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; - *) GUESS=hppa-unknown-linux-$LIBC ;; - esac - ;; - ppc64:Linux:*:*) - GUESS=powerpc64-unknown-linux-$LIBC - ;; - ppc:Linux:*:*) - GUESS=powerpc-unknown-linux-$LIBC - ;; - ppc64le:Linux:*:*) - GUESS=powerpc64le-unknown-linux-$LIBC - ;; - ppcle:Linux:*:*) - GUESS=powerpcle-unknown-linux-$LIBC - ;; - riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - s390:Linux:*:* | s390x:Linux:*:*) - GUESS=$UNAME_MACHINE-ibm-linux-$LIBC - ;; - sh64*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - sh*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - tile*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - vax:Linux:*:*) - GUESS=$UNAME_MACHINE-dec-linux-$LIBC - ;; - x86_64:Linux:*:*) - set_cc_for_build - CPU=$UNAME_MACHINE - LIBCABI=$LIBC - if test "$CC_FOR_BUILD" != no_compiler_found; then - ABI=64 - sed 's/^ //' << EOF > "$dummy.c" - #ifdef __i386__ - ABI=x86 - #else - #ifdef __ILP32__ - ABI=x32 - #endif - #endif -EOF - cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` - eval "$cc_set_abi" - case $ABI in - x86) CPU=i686 ;; - x32) LIBCABI=${LIBC}x32 ;; - esac - fi - GUESS=$CPU-pc-linux-$LIBCABI - ;; - xtensa*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - GUESS=i386-sequent-sysv4 - ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION - ;; - i*86:OS/2:*:*) - # If we were able to find 'uname', then EMX Unix compatibility - # is probably installed. - GUESS=$UNAME_MACHINE-pc-os2-emx - ;; - i*86:XTS-300:*:STOP) - GUESS=$UNAME_MACHINE-unknown-stop - ;; - i*86:atheos:*:*) - GUESS=$UNAME_MACHINE-unknown-atheos - ;; - i*86:syllable:*:*) - GUESS=$UNAME_MACHINE-pc-syllable - ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - GUESS=i386-unknown-lynxos$UNAME_RELEASE - ;; - i*86:*DOS:*:*) - GUESS=$UNAME_MACHINE-pc-msdosdjgpp - ;; - i*86:*:4.*:*) - UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL - else - GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL - fi - ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` - GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL - elif /bin/uname -X 2>/dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL - else - GUESS=$UNAME_MACHINE-pc-sysv32 - fi - ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configure will decide that - # this is a cross-build. - GUESS=i586-pc-msdosdjgpp - ;; - Intel:Mach:3*:*) - GUESS=i386-pc-mach3 - ;; - paragon:*:*:*) - GUESS=i860-intel-osf1 - ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 - fi - ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - GUESS=m68010-convergent-sysv - ;; - mc68k:UNIX:SYSTEM5:3.51m) - GUESS=m68k-convergent-sysv - ;; - M680?0:D-NIX:5.3:*) - GUESS=m68k-diab-dnix - ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - GUESS=m68k-unknown-lynxos$UNAME_RELEASE - ;; - mc68030:UNIX_System_V:4.*:*) - GUESS=m68k-atari-sysv4 - ;; - TSUNAMI:LynxOS:2.*:*) - GUESS=sparc-unknown-lynxos$UNAME_RELEASE - ;; - rs6000:LynxOS:2.*:*) - GUESS=rs6000-unknown-lynxos$UNAME_RELEASE - ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - GUESS=powerpc-unknown-lynxos$UNAME_RELEASE - ;; - SM[BE]S:UNIX_SV:*:*) - GUESS=mips-dde-sysv$UNAME_RELEASE - ;; - RM*:ReliantUNIX-*:*:*) - GUESS=mips-sni-sysv4 - ;; - RM*:SINIX-*:*:*) - GUESS=mips-sni-sysv4 - ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - GUESS=$UNAME_MACHINE-sni-sysv4 - else - GUESS=ns32k-sni-sysv - fi - ;; - PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort - # says <Richard.M.Bartel@ccMail.Census.GOV> - GUESS=i586-unisys-sysv4 - ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes <hewes@openmarket.com>. - # How about differentiating between stratus architectures? -djm - GUESS=hppa1.1-stratus-sysv4 - ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - GUESS=i860-stratus-sysv4 - ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - GUESS=$UNAME_MACHINE-stratus-vos - ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - GUESS=hppa1.1-stratus-vos - ;; - mc68*:A/UX:*:*) - GUESS=m68k-apple-aux$UNAME_RELEASE - ;; - news*:NEWS-OS:6*:*) - GUESS=mips-sony-newsos6 - ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if test -d /usr/nec; then - GUESS=mips-nec-sysv$UNAME_RELEASE - else - GUESS=mips-unknown-sysv$UNAME_RELEASE - fi - ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - GUESS=powerpc-be-beos - ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - GUESS=powerpc-apple-beos - ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - GUESS=i586-pc-beos - ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - GUESS=i586-pc-haiku - ;; - ppc:Haiku:*:*) # Haiku running on Apple PowerPC - GUESS=powerpc-apple-haiku - ;; - *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) - GUESS=$UNAME_MACHINE-unknown-haiku - ;; - SX-4:SUPER-UX:*:*) - GUESS=sx4-nec-superux$UNAME_RELEASE - ;; - SX-5:SUPER-UX:*:*) - GUESS=sx5-nec-superux$UNAME_RELEASE - ;; - SX-6:SUPER-UX:*:*) - GUESS=sx6-nec-superux$UNAME_RELEASE - ;; - SX-7:SUPER-UX:*:*) - GUESS=sx7-nec-superux$UNAME_RELEASE - ;; - SX-8:SUPER-UX:*:*) - GUESS=sx8-nec-superux$UNAME_RELEASE - ;; - SX-8R:SUPER-UX:*:*) - GUESS=sx8r-nec-superux$UNAME_RELEASE - ;; - SX-ACE:SUPER-UX:*:*) - GUESS=sxace-nec-superux$UNAME_RELEASE - ;; - Power*:Rhapsody:*:*) - GUESS=powerpc-apple-rhapsody$UNAME_RELEASE - ;; - *:Rhapsody:*:*) - GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE - ;; - arm64:Darwin:*:*) - GUESS=aarch64-apple-darwin$UNAME_RELEASE - ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` - case $UNAME_PROCESSOR in - unknown) UNAME_PROCESSOR=powerpc ;; - esac - if command -v xcode-select > /dev/null 2> /dev/null && \ - ! xcode-select --print-path > /dev/null 2> /dev/null ; then - # Avoid executing cc if there is no toolchain installed as - # cc will be a stub that puts up a graphical alert - # prompting the user to install developer tools. - CC_FOR_BUILD=no_compiler_found - else - set_cc_for_build - fi - if test "$CC_FOR_BUILD" != no_compiler_found; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi - # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc - if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_PPC >/dev/null - then - UNAME_PROCESSOR=powerpc - fi - elif test "$UNAME_PROCESSOR" = i386 ; then - # uname -m returns i386 or x86_64 - UNAME_PROCESSOR=$UNAME_MACHINE - fi - GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE - ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = x86; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE - ;; - *:QNX:*:4*) - GUESS=i386-pc-qnx - ;; - NEO-*:NONSTOP_KERNEL:*:*) - GUESS=neo-tandem-nsk$UNAME_RELEASE - ;; - NSE-*:NONSTOP_KERNEL:*:*) - GUESS=nse-tandem-nsk$UNAME_RELEASE - ;; - NSR-*:NONSTOP_KERNEL:*:*) - GUESS=nsr-tandem-nsk$UNAME_RELEASE - ;; - NSV-*:NONSTOP_KERNEL:*:*) - GUESS=nsv-tandem-nsk$UNAME_RELEASE - ;; - NSX-*:NONSTOP_KERNEL:*:*) - GUESS=nsx-tandem-nsk$UNAME_RELEASE - ;; - *:NonStop-UX:*:*) - GUESS=mips-compaq-nonstopux - ;; - BS2000:POSIX*:*:*) - GUESS=bs2000-siemens-sysv - ;; - DS/*:UNIX_System_V:*:*) - GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE - ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "${cputype-}" = 386; then - UNAME_MACHINE=i386 - elif test "x${cputype-}" != x; then - UNAME_MACHINE=$cputype - fi - GUESS=$UNAME_MACHINE-unknown-plan9 - ;; - *:TOPS-10:*:*) - GUESS=pdp10-unknown-tops10 - ;; - *:TENEX:*:*) - GUESS=pdp10-unknown-tenex - ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - GUESS=pdp10-dec-tops20 - ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - GUESS=pdp10-xkl-tops20 - ;; - *:TOPS-20:*:*) - GUESS=pdp10-unknown-tops20 - ;; - *:ITS:*:*) - GUESS=pdp10-unknown-its - ;; - SEI:*:*:SEIUX) - GUESS=mips-sei-seiux$UNAME_RELEASE - ;; - *:DragonFly:*:*) - DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` - GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL - ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case $UNAME_MACHINE in - A*) GUESS=alpha-dec-vms ;; - I*) GUESS=ia64-dec-vms ;; - V*) GUESS=vax-dec-vms ;; - esac ;; - *:XENIX:*:SysV) - GUESS=i386-pc-xenix - ;; - i*86:skyos:*:*) - SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` - GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL - ;; - i*86:rdos:*:*) - GUESS=$UNAME_MACHINE-pc-rdos - ;; - i*86:Fiwix:*:*) - GUESS=$UNAME_MACHINE-pc-fiwix - ;; - *:AROS:*:*) - GUESS=$UNAME_MACHINE-unknown-aros - ;; - x86_64:VMkernel:*:*) - GUESS=$UNAME_MACHINE-unknown-esx - ;; - amd64:Isilon\ OneFS:*:*) - GUESS=x86_64-unknown-onefs - ;; - *:Unleashed:*:*) - GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE - ;; - x86_64:[Oo]range:*:*|i?86:[Oo]range:*:*) - GUESS=x86_64-orange - ;; - *:[Oo]range:*:*) - GUESS=x86_64-orange - ;; -esac - -# Do we have a guess based on uname results? -if test "x$GUESS" != x; then - echo "$GUESS" - exit -fi - -# No uname command or uname output not recognized. -set_cc_for_build -cat > "$dummy.c" <<EOF -#ifdef _SEQUENT_ -#include <sys/types.h> -#include <sys/utsname.h> -#endif -#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) -#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) -#include <signal.h> -#if defined(_SIZE_T_) || defined(SIGLOST) -#include <sys/utsname.h> -#endif -#endif -#endif -int -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include <sys/param.h> - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); -#endif - -#if defined (vax) -#if !defined (ultrix) -#include <sys/param.h> -#if defined (BSD) -#if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -#else -#if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -#else - printf ("vax-dec-bsd\n"); exit (0); -#endif -#endif -#else - printf ("vax-dec-bsd\n"); exit (0); -#endif -#else -#if defined(_SIZE_T_) || defined(SIGLOST) - struct utsname un; - uname (&un); - printf ("vax-dec-ultrix%s\n", un.release); exit (0); -#else - printf ("vax-dec-ultrix\n"); exit (0); -#endif -#endif -#endif -#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) -#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) -#if defined(_SIZE_T_) || defined(SIGLOST) - struct utsname *un; - uname (&un); - printf ("mips-dec-ultrix%s\n", un.release); exit (0); -#else - printf ("mips-dec-ultrix\n"); exit (0); -#endif -#endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. -test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } - -echo "$0: unable to guess system type" >&2 - -case $UNAME_MACHINE:$UNAME_SYSTEM in - mips:Linux | mips64:Linux) - # If we got here on MIPS GNU/Linux, output extra information. - cat >&2 <<EOF - -NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize -the system type. Please install a C compiler and try again. -EOF - ;; -esac - -cat >&2 <<EOF - -This script (version $timestamp), has failed to recognize the -operating system you are using. If your script is old, overwrite *all* -copies of config.guess and config.sub with the latest versions from: - - https://git.savannah.gnu.org/cgit/config.git/plain/config.guess -and - https://git.savannah.gnu.org/cgit/config.git/plain/config.sub -EOF - -our_year=`echo $timestamp | sed 's,-.*,,'` -thisyear=`date +%Y` -# shellcheck disable=SC2003 -script_age=`expr "$thisyear" - "$our_year"` -if test "$script_age" -lt 3 ; then - cat >&2 <<EOF - -If $0 has already been updated, send the following data and any -information you think might be pertinent to config-patches@gnu.org to -provide the necessary information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = "$UNAME_MACHINE" -UNAME_RELEASE = "$UNAME_RELEASE" -UNAME_SYSTEM = "$UNAME_SYSTEM" -UNAME_VERSION = "$UNAME_VERSION" -EOF -fi - -exit 1 - -# Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp nil t) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%Y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/tools/pkg/config.sub b/tools/pkg/config.sub deleted file mode 100644 index 0917997..0000000 --- a/tools/pkg/config.sub +++ /dev/null @@ -1,2364 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright 1992-2025 Free Software Foundation, Inc. - -# shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale - -timestamp='2025-07-10' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see <https://www.gnu.org/licenses/>. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). - - -# Please send patches to <config-patches@gnu.org>. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# You can get the latest version of this script from: -# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -# The "shellcheck disable" line above the timestamp inhibits complaints -# about features and limitations of the classic Bourne shell that were -# superseded or lifted in POSIX. However, this script identifies a wide -# variety of pre-POSIX systems that do not have POSIX shells at all, and -# even some reasonably current systems (Solaris 10 as case-in-point) still -# have a pre-POSIX /bin/sh. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS - -Canonicalize a configuration name. - -Options: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.sub ($timestamp) - -Copyright 1992-2025 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try '$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo "$1" - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Split fields of configuration type -saved_IFS=$IFS -IFS="-" read field1 field2 field3 field4 <<EOF -$1 -EOF -IFS=$saved_IFS - -# Separate into logical components for further validation -case $1 in - *-*-*-*-*) - echo "Invalid configuration '$1': more than four components" >&2 - exit 1 - ;; - *-*-*-*) - basic_machine=$field1-$field2 - basic_os=$field3-$field4 - ;; - *-*-*) - # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two - # parts - maybe_os=$field2-$field3 - case $maybe_os in - cloudabi*-eabi* \ - | kfreebsd*-gnu* \ - | knetbsd*-gnu* \ - | kopensolaris*-gnu* \ - | orange-* \ - | linux-* \ - | managarm-* \ - | netbsd*-eabi* \ - | netbsd*-gnu* \ - | nto-qnx* \ - | os2-emx* \ - | rtmk-nova* \ - | storm-chaos* \ - | uclinux-gnu* \ - | uclinux-uclibc* \ - | windows-* ) - basic_machine=$field1 - basic_os=$maybe_os - ;; - android-linux) - basic_machine=$field1-unknown - basic_os=linux-android - ;; - *) - basic_machine=$field1-$field2 - basic_os=$field3 - ;; - esac - ;; - *-*) - case $field1-$field2 in - # Shorthands that happen to contain a single dash - convex-c[12] | convex-c3[248]) - basic_machine=$field2-convex - basic_os= - ;; - decstation-3100) - basic_machine=mips-dec - basic_os= - ;; - *-*) - # Second component is usually, but not always the OS - case $field2 in - # Do not treat sunos as a manufacturer - sun*os*) - basic_machine=$field1 - basic_os=$field2 - ;; - # Manufacturers - 3100* \ - | 32* \ - | 3300* \ - | 3600* \ - | 7300* \ - | acorn \ - | altos* \ - | apollo \ - | apple \ - | atari \ - | att* \ - | axis \ - | be \ - | bull \ - | cbm \ - | ccur \ - | cisco \ - | commodore \ - | convergent* \ - | convex* \ - | cray \ - | crds \ - | dec* \ - | delta* \ - | dg \ - | digital \ - | dolphin \ - | encore* \ - | gould \ - | harris \ - | highlevel \ - | hitachi* \ - | hp \ - | ibm* \ - | intergraph \ - | isi* \ - | knuth \ - | masscomp \ - | microblaze* \ - | mips* \ - | motorola* \ - | ncr* \ - | news \ - | next \ - | ns \ - | oki \ - | omron* \ - | pc533* \ - | rebel \ - | rom68k \ - | rombug \ - | semi \ - | sequent* \ - | sgi* \ - | siemens \ - | sim \ - | sni \ - | sony* \ - | stratus \ - | sun \ - | sun[234]* \ - | tektronix \ - | tti* \ - | ultra \ - | unicom* \ - | wec \ - | winbond \ - | wrs) - basic_machine=$field1-$field2 - basic_os= - ;; - tock* | zephyr*) - basic_machine=$field1-unknown - basic_os=$field2 - ;; - *) - basic_machine=$field1 - basic_os=$field2 - ;; - esac - ;; - esac - ;; - *) - # Convert single-component short-hands not valid as part of - # multi-component configurations. - case $field1 in - 386bsd) - basic_machine=i386-pc - basic_os=bsd - ;; - a29khif) - basic_machine=a29k-amd - basic_os=udi - ;; - adobe68k) - basic_machine=m68010-adobe - basic_os=scout - ;; - alliant) - basic_machine=fx80-alliant - basic_os= - ;; - altos | altos3068) - basic_machine=m68k-altos - basic_os= - ;; - am29k) - basic_machine=a29k-none - basic_os=bsd - ;; - amdahl) - basic_machine=580-amdahl - basic_os=sysv - ;; - amiga) - basic_machine=m68k-unknown - basic_os= - ;; - amigaos | amigados) - basic_machine=m68k-unknown - basic_os=amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - basic_os=sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - basic_os=sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - basic_os=bsd - ;; - aros) - basic_machine=i386-pc - basic_os=aros - ;; - aux) - basic_machine=m68k-apple - basic_os=aux - ;; - balance) - basic_machine=ns32k-sequent - basic_os=dynix - ;; - blackfin) - basic_machine=bfin-unknown - basic_os=linux - ;; - cegcc) - basic_machine=arm-unknown - basic_os=cegcc - ;; - cray) - basic_machine=j90-cray - basic_os=unicos - ;; - crds | unos) - basic_machine=m68k-crds - basic_os= - ;; - da30) - basic_machine=m68k-da30 - basic_os= - ;; - decstation | pmax | pmin | dec3100 | decstatn) - basic_machine=mips-dec - basic_os= - ;; - delta88) - basic_machine=m88k-motorola - basic_os=sysv3 - ;; - dicos) - basic_machine=i686-pc - basic_os=dicos - ;; - djgpp) - basic_machine=i586-pc - basic_os=msdosdjgpp - ;; - ebmon29k) - basic_machine=a29k-amd - basic_os=ebmon - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - basic_os=ose - ;; - gmicro) - basic_machine=tron-gmicro - basic_os=sysv - ;; - go32) - basic_machine=i386-pc - basic_os=go32 - ;; - h8300hms) - basic_machine=h8300-hitachi - basic_os=hms - ;; - h8300xray) - basic_machine=h8300-hitachi - basic_os=xray - ;; - h8500hms) - basic_machine=h8500-hitachi - basic_os=hms - ;; - harris) - basic_machine=m88k-harris - basic_os=sysv3 - ;; - hp300 | hp300hpux) - basic_machine=m68k-hp - basic_os=hpux - ;; - hp300bsd) - basic_machine=m68k-hp - basic_os=bsd - ;; - hppaosf) - basic_machine=hppa1.1-hp - basic_os=osf - ;; - hppro) - basic_machine=hppa1.1-hp - basic_os=proelf - ;; - i386mach) - basic_machine=i386-mach - basic_os=mach - ;; - isi68 | isi) - basic_machine=m68k-isi - basic_os=sysv - ;; - m68knommu) - basic_machine=m68k-unknown - basic_os=linux - ;; - magnum | m3230) - basic_machine=mips-mips - basic_os=sysv - ;; - merlin) - basic_machine=ns32k-utek - basic_os=sysv - ;; - mingw64) - basic_machine=x86_64-pc - basic_os=mingw64 - ;; - mingw32) - basic_machine=i686-pc - basic_os=mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - basic_os=mingw32ce - ;; - monitor) - basic_machine=m68k-rom68k - basic_os=coff - ;; - morphos) - basic_machine=powerpc-unknown - basic_os=morphos - ;; - moxiebox) - basic_machine=moxie-unknown - basic_os=moxiebox - ;; - msdos) - basic_machine=i386-pc - basic_os=msdos - ;; - msys) - basic_machine=i686-pc - basic_os=msys - ;; - mvs) - basic_machine=i370-ibm - basic_os=mvs - ;; - nacl) - basic_machine=le32-unknown - basic_os=nacl - ;; - ncr3000) - basic_machine=i486-ncr - basic_os=sysv4 - ;; - netbsd386) - basic_machine=i386-pc - basic_os=netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - basic_os=linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - basic_os=newsos - ;; - news1000) - basic_machine=m68030-sony - basic_os=newsos - ;; - necv70) - basic_machine=v70-nec - basic_os=sysv - ;; - nh3000) - basic_machine=m68k-harris - basic_os=cxux - ;; - nh[45]000) - basic_machine=m88k-harris - basic_os=cxux - ;; - nindy960) - basic_machine=i960-intel - basic_os=nindy - ;; - mon960) - basic_machine=i960-intel - basic_os=mon960 - ;; - nonstopux) - basic_machine=mips-compaq - basic_os=nonstopux - ;; - os400) - basic_machine=powerpc-ibm - basic_os=os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - basic_os=ose - ;; - os68k) - basic_machine=m68k-none - basic_os=os68k - ;; - paragon) - basic_machine=i860-intel - basic_os=osf - ;; - parisc) - basic_machine=hppa-unknown - basic_os=linux - ;; - psp) - basic_machine=mipsallegrexel-sony - basic_os=psp - ;; - pw32) - basic_machine=i586-unknown - basic_os=pw32 - ;; - rdos | rdos64) - basic_machine=x86_64-pc - basic_os=rdos - ;; - rdos32) - basic_machine=i386-pc - basic_os=rdos - ;; - rom68k) - basic_machine=m68k-rom68k - basic_os=coff - ;; - sa29200) - basic_machine=a29k-amd - basic_os=udi - ;; - sei) - basic_machine=mips-sei - basic_os=seiux - ;; - sequent) - basic_machine=i386-sequent - basic_os= - ;; - sps7) - basic_machine=m68k-bull - basic_os=sysv2 - ;; - st2000) - basic_machine=m68k-tandem - basic_os= - ;; - stratus) - basic_machine=i860-stratus - basic_os=sysv4 - ;; - sun2) - basic_machine=m68000-sun - basic_os= - ;; - sun2os3) - basic_machine=m68000-sun - basic_os=sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - basic_os=sunos4 - ;; - sun3) - basic_machine=m68k-sun - basic_os= - ;; - sun3os3) - basic_machine=m68k-sun - basic_os=sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - basic_os=sunos4 - ;; - sun4) - basic_machine=sparc-sun - basic_os= - ;; - sun4os3) - basic_machine=sparc-sun - basic_os=sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - basic_os=sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - basic_os=solaris2 - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - basic_os= - ;; - sv1) - basic_machine=sv1-cray - basic_os=unicos - ;; - symmetry) - basic_machine=i386-sequent - basic_os=dynix - ;; - t3e) - basic_machine=alphaev5-cray - basic_os=unicos - ;; - t90) - basic_machine=t90-cray - basic_os=unicos - ;; - toad1) - basic_machine=pdp10-xkl - basic_os=tops20 - ;; - tpf) - basic_machine=s390x-ibm - basic_os=tpf - ;; - udi29k) - basic_machine=a29k-amd - basic_os=udi - ;; - ultra3) - basic_machine=a29k-nyu - basic_os=sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - basic_os=none - ;; - vaxv) - basic_machine=vax-dec - basic_os=sysv - ;; - vms) - basic_machine=vax-dec - basic_os=vms - ;; - vsta) - basic_machine=i386-pc - basic_os=vsta - ;; - vxworks960) - basic_machine=i960-wrs - basic_os=vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - basic_os=vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - basic_os=vxworks - ;; - xbox) - basic_machine=i686-pc - basic_os=mingw32 - ;; - ymp) - basic_machine=ymp-cray - basic_os=unicos - ;; - *) - basic_machine=$1 - basic_os= - ;; - esac - ;; -esac - -# Decode 1-component or ad-hoc basic machines -case $basic_machine in - # Here we handle the default manufacturer of certain CPU types. It is in - # some cases the only manufacturer, in others, it is the most popular. - w89k) - cpu=hppa1.1 - vendor=winbond - ;; - op50n) - cpu=hppa1.1 - vendor=oki - ;; - op60c) - cpu=hppa1.1 - vendor=oki - ;; - ibm*) - cpu=i370 - vendor=ibm - ;; - orion105) - cpu=clipper - vendor=highlevel - ;; - mac | mpw | mac-mpw) - cpu=m68k - vendor=apple - ;; - pmac | pmac-mpw) - cpu=powerpc - vendor=apple - ;; - - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - cpu=m68000 - vendor=att - ;; - 3b*) - cpu=we32k - vendor=att - ;; - bluegene*) - cpu=powerpc - vendor=ibm - basic_os=cnk - ;; - decsystem10* | dec10*) - cpu=pdp10 - vendor=dec - basic_os=tops10 - ;; - decsystem20* | dec20*) - cpu=pdp10 - vendor=dec - basic_os=tops20 - ;; - delta | 3300 | delta-motorola | 3300-motorola | motorola-delta | motorola-3300) - cpu=m68k - vendor=motorola - ;; - # This used to be dpx2*, but that gets the RS6000-based - # DPX/20 and the x86-based DPX/2-100 wrong. See - # https://oldskool.silicium.org/stations/bull_dpx20.htm - # https://www.feb-patrimoine.com/english/bull_dpx2.htm - # https://www.feb-patrimoine.com/english/unix_and_bull.htm - dpx2 | dpx2[23]00 | dpx2[23]xx) - cpu=m68k - vendor=bull - ;; - dpx2100 | dpx21xx) - cpu=i386 - vendor=bull - ;; - dpx20) - cpu=rs6000 - vendor=bull - ;; - encore | umax | mmax) - cpu=ns32k - vendor=encore - ;; - elxsi) - cpu=elxsi - vendor=elxsi - basic_os=${basic_os:-bsd} - ;; - fx2800) - cpu=i860 - vendor=alliant - ;; - genix) - cpu=ns32k - vendor=ns - ;; - h3050r* | hiux*) - cpu=hppa1.1 - vendor=hitachi - basic_os=hiuxwe2 - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - cpu=hppa1.0 - vendor=hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - cpu=m68000 - vendor=hp - ;; - hp9k3[2-9][0-9]) - cpu=m68k - vendor=hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - cpu=hppa1.0 - vendor=hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - cpu=hppa1.1 - vendor=hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - cpu=hppa1.1 - vendor=hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - cpu=hppa1.1 - vendor=hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - cpu=hppa1.1 - vendor=hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - cpu=hppa1.0 - vendor=hp - ;; - i*86v32) - cpu=`echo "$1" | sed -e 's/86.*/86/'` - vendor=pc - basic_os=sysv32 - ;; - i*86v4*) - cpu=`echo "$1" | sed -e 's/86.*/86/'` - vendor=pc - basic_os=sysv4 - ;; - i*86v) - cpu=`echo "$1" | sed -e 's/86.*/86/'` - vendor=pc - basic_os=sysv - ;; - i*86sol2) - cpu=`echo "$1" | sed -e 's/86.*/86/'` - vendor=pc - basic_os=solaris2 - ;; - j90 | j90-cray) - cpu=j90 - vendor=cray - basic_os=${basic_os:-unicos} - ;; - iris | iris4d) - cpu=mips - vendor=sgi - case $basic_os in - irix*) - ;; - *) - basic_os=irix4 - ;; - esac - ;; - miniframe) - cpu=m68000 - vendor=convergent - ;; - *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) - cpu=m68k - vendor=atari - basic_os=mint - ;; - news-3600 | risc-news) - cpu=mips - vendor=sony - basic_os=newsos - ;; - next | m*-next) - cpu=m68k - vendor=next - ;; - np1) - cpu=np1 - vendor=gould - ;; - op50n-* | op60c-*) - cpu=hppa1.1 - vendor=oki - basic_os=proelf - ;; - pa-hitachi) - cpu=hppa1.1 - vendor=hitachi - basic_os=hiuxwe2 - ;; - pbd) - cpu=sparc - vendor=tti - ;; - pbb) - cpu=m68k - vendor=tti - ;; - pc532) - cpu=ns32k - vendor=pc532 - ;; - pn) - cpu=pn - vendor=gould - ;; - power) - cpu=power - vendor=ibm - ;; - ps2) - cpu=i386 - vendor=ibm - ;; - rm[46]00) - cpu=mips - vendor=siemens - ;; - rtpc | rtpc-*) - cpu=romp - vendor=ibm - ;; - sde) - cpu=mipsisa32 - vendor=sde - basic_os=${basic_os:-elf} - ;; - simso-wrs) - cpu=sparclite - vendor=wrs - basic_os=vxworks - ;; - tower | tower-32) - cpu=m68k - vendor=ncr - ;; - vpp*|vx|vx-*) - cpu=f301 - vendor=fujitsu - ;; - w65) - cpu=w65 - vendor=wdc - ;; - w89k-*) - cpu=hppa1.1 - vendor=winbond - basic_os=proelf - ;; - none) - cpu=none - vendor=none - ;; - leon|leon[3-9]) - cpu=sparc - vendor=$basic_machine - ;; - leon-*|leon[3-9]-*) - cpu=sparc - vendor=`echo "$basic_machine" | sed 's/-.*//'` - ;; - - *-*) - saved_IFS=$IFS - IFS="-" read cpu vendor <<EOF -$basic_machine -EOF - IFS=$saved_IFS - ;; - # We use 'pc' rather than 'unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - cpu=$basic_machine - vendor=pc - ;; - # These rules are duplicated from below for sake of the special case above; - # i.e. things that normalized to x86 arches should also default to "pc" - pc98) - cpu=i386 - vendor=pc - ;; - x64 | amd64) - cpu=x86_64 - vendor=pc - ;; - # Recognize the basic CPU types without company name. - *) - cpu=$basic_machine - vendor=unknown - ;; -esac - -unset -v basic_machine - -# Decode basic machines in the full and proper CPU-Company form. -case $cpu-$vendor in - # Here we handle the default manufacturer of certain CPU types in canonical form. - # It is in some cases the only manufacturer, in others, it is the most popular. - c[12]-convex | c[12]-unknown | c3[248]-convex | c3[248]-unknown) - vendor=convex - basic_os=${basic_os:-bsd} - ;; - craynv-unknown) - vendor=cray - basic_os=${basic_os:-unicosmp} - ;; - c90-unknown | c90-cray) - vendor=cray - basic_os=${basic_os:-unicos} - ;; - fx80-unknown) - vendor=alliant - ;; - romp-unknown) - vendor=ibm - ;; - mmix-unknown) - vendor=knuth - ;; - microblaze-unknown | microblazeel-unknown) - vendor=xilinx - ;; - rs6000-unknown) - vendor=ibm - ;; - vax-unknown) - vendor=dec - ;; - pdp11-unknown) - vendor=dec - ;; - we32k-unknown) - vendor=att - ;; - cydra-unknown) - vendor=cydrome - ;; - i370-ibm*) - vendor=ibm - ;; - orion-unknown) - vendor=highlevel - ;; - xps-unknown | xps100-unknown) - cpu=xps100 - vendor=honeywell - ;; - - # Here we normalize CPU types with a missing or matching vendor - armh-unknown | armh-alt) - cpu=armv7l - vendor=alt - basic_os=${basic_os:-linux-gnueabihf} - ;; - - # Normalized CPU+vendor pairs that imply an OS, if not otherwise specified - m68k-isi) - basic_os=${basic_os:-sysv} - ;; - m68k-sony) - basic_os=${basic_os:-newsos} - ;; - m68k-tektronix) - basic_os=${basic_os:-bsd} - ;; - m88k-harris) - basic_os=${basic_os:-sysv3} - ;; - i386-bull | m68k-bull) - basic_os=${basic_os:-sysv3} - ;; - rs6000-bull) - basic_os=${basic_os:-bosx} - ;; - mips-sni) - basic_os=${basic_os:-sysv4} - ;; - - # Here we normalize CPU types irrespective of the vendor - amd64-*) - cpu=x86_64 - ;; - blackfin-*) - cpu=bfin - basic_os=${basic_os:-linux} - ;; - c54x-*) - cpu=tic54x - ;; - c55x-*) - cpu=tic55x - ;; - c6x-*) - cpu=tic6x - ;; - e500v[12]-*) - cpu=powerpc - basic_os=${basic_os}"spe" - ;; - mips3*-*) - cpu=mips64 - ;; - ms1-*) - cpu=mt - ;; - m68knommu-*) - cpu=m68k - basic_os=${basic_os:-linux} - ;; - m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*) - cpu=s12z - ;; - openrisc-*) - cpu=or32 - ;; - parisc-*) - cpu=hppa - basic_os=${basic_os:-linux} - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - cpu=i586 - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*) - cpu=i686 - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - cpu=i686 - ;; - pentium4-*) - cpu=i786 - ;; - ppc-* | ppcbe-*) - cpu=powerpc - ;; - ppcle-* | powerpclittle-*) - cpu=powerpcle - ;; - ppc64-*) - cpu=powerpc64 - ;; - ppc64le-* | powerpc64little-*) - cpu=powerpc64le - ;; - sb1-*) - cpu=mipsisa64sb1 - ;; - sb1el-*) - cpu=mipsisa64sb1el - ;; - sh5e[lb]-*) - cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'` - ;; - spur-*) - cpu=spur - ;; - strongarm-* | thumb-*) - cpu=arm - ;; - tx39-*) - cpu=mipstx39 - ;; - tx39el-*) - cpu=mipstx39el - ;; - xscale-* | xscalee[bl]-*) - cpu=`echo "$cpu" | sed 's/^xscale/arm/'` - ;; - arm64-* | aarch64le-* | arm64_32-*) - cpu=aarch64 - ;; - - # Recognize the canonical CPU Types that limit and/or modify the - # company names they are paired with. - cr16-*) - basic_os=${basic_os:-elf} - ;; - crisv32-* | etraxfs*-*) - cpu=crisv32 - vendor=axis - ;; - cris-* | etrax*-*) - cpu=cris - vendor=axis - ;; - crx-*) - basic_os=${basic_os:-elf} - ;; - neo-tandem) - cpu=neo - vendor=tandem - ;; - nse-tandem) - cpu=nse - vendor=tandem - ;; - nsr-tandem) - cpu=nsr - vendor=tandem - ;; - nsv-tandem) - cpu=nsv - vendor=tandem - ;; - nsx-tandem) - cpu=nsx - vendor=tandem - ;; - mipsallegrexel-sony) - cpu=mipsallegrexel - vendor=sony - ;; - tile*-*) - basic_os=${basic_os:-linux-gnu} - ;; - - *) - # Recognize the canonical CPU types that are allowed with any - # company name. - case $cpu in - 1750a \ - | 580 \ - | [cjt]90 \ - | a29k \ - | aarch64 \ - | aarch64_be \ - | aarch64c \ - | abacus \ - | alpha \ - | alpha64 \ - | alpha64ev56 \ - | alpha64ev6[78] \ - | alpha64ev[4-8] \ - | alpha64pca5[67] \ - | alphaev56 \ - | alphaev6[78] \ - | alphaev[4-8] \ - | alphapca5[67] \ - | am33_2.0 \ - | amdgcn \ - | arc \ - | arc32 \ - | arc64 \ - | arceb \ - | arm \ - | arm64e \ - | arm64ec \ - | arm[lb]e \ - | arme[lb] \ - | armv* \ - | asmjs \ - | avr \ - | avr32 \ - | ba \ - | be32 \ - | be64 \ - | bfin \ - | bpf \ - | bs2000 \ - | c30 \ - | c4x \ - | c8051 \ - | c[123]* \ - | clipper \ - | craynv \ - | csky \ - | cydra \ - | d10v \ - | d30v \ - | dlx \ - | dsp16xx \ - | e2k \ - | elxsi \ - | epiphany \ - | f30[01] \ - | f700 \ - | fido \ - | fr30 \ - | frv \ - | ft32 \ - | fx80 \ - | h8300 \ - | h8500 \ - | hexagon \ - | hppa \ - | hppa1.[01] \ - | hppa2.0 \ - | hppa2.0[nw] \ - | hppa64 \ - | i*86 \ - | i370 \ - | i860 \ - | i960 \ - | ia16 \ - | ia64 \ - | intelgt \ - | ip2k \ - | iq2000 \ - | javascript \ - | k1om \ - | kvx \ - | le32 \ - | le64 \ - | lm32 \ - | loongarch32 \ - | loongarch64 \ - | m32c \ - | m32r \ - | m32rle \ - | m5200 \ - | m68000 \ - | m680[012346]0 \ - | m6811 \ - | m6812 \ - | m68360 \ - | m683?2 \ - | m68hc11 \ - | m68hc12 \ - | m68hcs12x \ - | m68k \ - | m88110 \ - | m88k \ - | maxq \ - | mb \ - | mcore \ - | mep \ - | metag \ - | microblaze \ - | microblazeel \ - | mips* \ - | mmix \ - | mn10200 \ - | mn10300 \ - | moxie \ - | msp430 \ - | mt \ - | nanomips* \ - | nds32 \ - | nds32be \ - | nds32le \ - | nfp \ - | nios \ - | nios2 \ - | nios2eb \ - | nios2el \ - | none \ - | np1 \ - | ns16k \ - | ns32k \ - | nvptx \ - | open8 \ - | or1k* \ - | or32 \ - | orion \ - | pdp10 \ - | pdp11 \ - | picochip \ - | pj \ - | pjl \ - | pn \ - | power \ - | powerpc \ - | powerpc64 \ - | powerpc64le \ - | powerpcle \ - | powerpcspe \ - | pru \ - | pyramid \ - | riscv \ - | riscv32 \ - | riscv32be \ - | riscv64 \ - | riscv64be \ - | rl78 \ - | romp \ - | rs6000 \ - | rx \ - | s390 \ - | s390x \ - | score \ - | sh \ - | sh64 \ - | sh64le \ - | sh[12345][lb]e \ - | sh[1234] \ - | sh[1234]e[lb] \ - | sh[23]e \ - | sh[23]ele \ - | sh[24]a \ - | sh[24]ae[lb] \ - | sh[lb]e \ - | she[lb] \ - | shl \ - | sparc \ - | sparc64 \ - | sparc64b \ - | sparc64v \ - | sparc86x \ - | sparclet \ - | sparclite \ - | sparcv8 \ - | sparcv9 \ - | sparcv9b \ - | sparcv9v \ - | spu \ - | sv1 \ - | sx* \ - | tahoe \ - | thumbv7* \ - | tic30 \ - | tic4x \ - | tic54x \ - | tic55x \ - | tic6x \ - | tic80 \ - | tron \ - | ubicom32 \ - | v70 \ - | v810 \ - | v850 \ - | v850e \ - | v850e1 \ - | v850e2 \ - | v850e2v3 \ - | v850es \ - | vax \ - | vc4 \ - | visium \ - | w65 \ - | wasm32 \ - | wasm64 \ - | we32k \ - | x86 \ - | x86_64 \ - | xc16x \ - | xgate \ - | xps100 \ - | xstormy16 \ - | xtensa* \ - | ymp \ - | z80 \ - | z8k) - ;; - - *) - echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2 - exit 1 - ;; - esac - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $vendor in - digital*) - vendor=dec - ;; - commodore*) - vendor=cbm - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if test x"$basic_os" != x -then - -# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just -# set os. -obj= -case $basic_os in - gnu/linux*) - kernel=linux - os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` - ;; - os2-emx) - kernel=os2 - os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` - ;; - nto-qnx*) - kernel=nto - os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` - ;; - *-*) - saved_IFS=$IFS - IFS="-" read kernel os <<EOF -$basic_os -EOF - IFS=$saved_IFS - ;; - # Default OS when just kernel was specified - nto*) - kernel=nto - os=`echo "$basic_os" | sed -e 's|nto|qnx|'` - ;; - orange*) - kernel=orange - os=`echo "$basic_os" | sed -e 's|orange|mlibc|'` - ;; - linux*) - kernel=linux - os=`echo "$basic_os" | sed -e 's|linux|gnu|'` - ;; - managarm*) - kernel=managarm - os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'` - ;; - *) - kernel= - os=$basic_os - ;; -esac - -# Now, normalize the OS (knowing we just have one component, it's not a kernel, -# etc.) -case $os in - # First match some system type aliases that might get confused - # with valid system types. - # solaris* is a basic system type, with this one exception. - auroraux) - os=auroraux - ;; - bluegene*) - os=cnk - ;; - solaris1 | solaris1.*) - os=`echo "$os" | sed -e 's|solaris1|sunos4|'` - ;; - solaris) - os=solaris2 - ;; - unixware*) - os=sysv4.2uw - ;; - # The marketing names for NeXT's operating systems were - # NeXTSTEP, NeXTSTEP 2, OpenSTEP 3, OpenSTEP 4. 'openstep' is - # mapped to 'openstep3', but 'openstep1' and 'openstep2' are - # mapped to 'nextstep' and 'nextstep2', consistent with the - # treatment of SunOS/Solaris. - ns | ns1 | nextstep | nextstep1 | openstep1) - os=nextstep - ;; - ns2 | nextstep2 | openstep2) - os=nextstep2 - ;; - ns3 | nextstep3 | openstep | openstep3) - os=openstep3 - ;; - ns4 | nextstep4 | openstep4) - os=openstep4 - ;; - # es1800 is here to avoid being matched by es* (a different OS) - es1800*) - os=ose - ;; - # Some version numbers need modification - chorusos*) - os=chorusos - ;; - isc) - os=isc2.2 - ;; - sco6) - os=sco5v6 - ;; - sco5) - os=sco3.2v5 - ;; - sco4) - os=sco3.2v4 - ;; - sco3.2.[4-9]*) - os=`echo "$os" | sed -e 's/sco3.2./sco3.2v/'` - ;; - sco*v* | scout) - # Don't match below - ;; - sco*) - os=sco3.2v2 - ;; - psos*) - os=psos - ;; - qnx*) - os=qnx - ;; - hiux*) - os=hiuxwe2 - ;; - lynx*178) - os=lynxos178 - ;; - lynx*5) - os=lynxos5 - ;; - lynxos*) - # don't get caught up in next wildcard - ;; - lynx*) - os=lynxos - ;; - mac[0-9]*) - os=`echo "$os" | sed -e 's|mac|macos|'` - ;; - opened*) - os=openedition - ;; - os400*) - os=os400 - ;; - sunos5*) - os=`echo "$os" | sed -e 's|sunos5|solaris2|'` - ;; - sunos6*) - os=`echo "$os" | sed -e 's|sunos6|solaris3|'` - ;; - wince*) - os=wince - ;; - utek*) - os=bsd - vendor=`echo "$vendor" | sed -e 's|^unknown$|tektronix|'` - ;; - dynix*) - os=bsd - ;; - acis*) - os=aos - ;; - atheos*) - os=atheos - ;; - syllable*) - os=syllable - ;; - 386bsd) - os=bsd - ;; - ctix*) - os=sysv - vendor=`echo "$vendor" | sed -e 's|^unknown$|convergent|'` - ;; - uts*) - os=sysv - ;; - nova*) - kernel=rtmk - os=nova - ;; - # Preserve the version number of sinix5. - sinix5.*) - os=`echo "$os" | sed -e 's|sinix|sysv|'` - vendor=`echo "$vendor" | sed -e 's|^unknown$|sni|'` - ;; - sinix*) - os=sysv4 - vendor=`echo "$vendor" | sed -e 's|^unknown$|sni|'` - ;; - tpf*) - os=tpf - ;; - triton*) - os=sysv3 - ;; - oss*) - os=sysv3 - ;; - svr4*) - os=sysv4 - ;; - svr3) - os=sysv3 - ;; - sysvr4) - os=sysv4 - ;; - ose*) - os=ose - ;; - *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) - os=mint - ;; - dicos*) - os=dicos - ;; - pikeos*) - # Until real need of OS specific support for - # particular features comes up, bare metal - # configurations are quite functional. - case $cpu in - arm*) - os=eabi - ;; - *) - os= - obj=elf - ;; - esac - ;; - aout* | coff* | elf* | pe*) - # These are machine code file formats, not OSes - obj=$os - os= - ;; - *) - # No normalization, but not necessarily accepted, that comes below. - ;; -esac - -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -kernel= -obj= -case $cpu-$vendor in - score-*) - os= - obj=elf - ;; - spu-*) - os= - obj=elf - ;; - *-acorn) - os=riscix1.2 - ;; - arm*-rebel) - kernel=linux - os=gnu - ;; - arm*-semi) - os= - obj=aout - ;; - c4x-* | tic4x-*) - os= - obj=coff - ;; - c8051-*) - os= - obj=elf - ;; - clipper-intergraph) - os=clix - ;; - hexagon-*) - os= - obj=elf - ;; - tic54x-*) - os= - obj=coff - ;; - tic55x-*) - os= - obj=coff - ;; - tic6x-*) - os= - obj=coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=tops20 - ;; - pdp11-*) - os=none - ;; - *-dec | vax-*) - os=ultrix4.2 - ;; - m68*-apollo) - os=domain - ;; - i386-sun) - os=sunos4.0.2 - ;; - m68000-sun) - os=sunos3 - ;; - m68*-cisco) - os= - obj=aout - ;; - mep-*) - os= - obj=elf - ;; - # The -sgi and -siemens entries must be before the mips- entry - # or we get the wrong os. - *-sgi) - os=irix - ;; - *-siemens) - os=sysv4 - ;; - mips*-cisco) - os= - obj=elf - ;; - mips*-*|nanomips*-*) - os= - obj=elf - ;; - or32-*) - os= - obj=coff - ;; - # This must be before the sparc-* entry or we get the wrong os. - *-tti) - os=sysv3 - ;; - sparc-* | *-sun) - os=sunos4.1.1 - ;; - pru-*) - os= - obj=elf - ;; - *-be) - os=beos - ;; - *-ibm) - os=aix - ;; - *-knuth) - os=mmixware - ;; - *-wec) - os=proelf - ;; - *-winbond) - os=proelf - ;; - *-oki) - os=proelf - ;; - *-hp) - os=hpux - ;; - *-hitachi) - os=hiuxwe2 - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=sysv - ;; - *-cbm) - os=amigaos - ;; - *-dg) - os=dgux - ;; - *-dolphin) - os=sysv3 - ;; - m68k-ccur) - os=rtu - ;; - m88k-omron*) - os=luna - ;; - *-next) - os=nextstep - ;; - *-sequent) - os=ptx - ;; - *-crds) - os=unos - ;; - *-ns) - os=genix - ;; - i370-*) - os=mvs - ;; - *-gould) - os=sysv - ;; - *-highlevel) - os=bsd - ;; - *-encore) - os=bsd - ;; - *-masscomp) - os=rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=uxpv - ;; - *-rom68k) - os= - obj=coff - ;; - *-*bug) - os= - obj=coff - ;; - *-apple) - os=macos - ;; - *-atari*) - os=mint - ;; - *-wrs) - os=vxworks - ;; - *) - os=none - ;; -esac - -fi - -# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ). - -case $os in - # Sometimes we do "kernel-libc", so those need to count as OSes. - llvm* | musl* | newlib* | relibc* | uclibc*) - ;; - # Likewise for "kernel-abi" - eabi* | gnueabi*) - ;; - # VxWorks passes extra cpu info in the 4th filed. - simlinux | simwindows | spe) - ;; - # See `case $cpu-$os` validation below - ghcjs) - ;; - # Now accept the basic system types. - # Each alternative MUST end in a * to match a version number. - abug \ - | aix* \ - | amdhsa* \ - | amigados* \ - | amigaos* \ - | android* \ - | aof* \ - | aos* \ - | aros* \ - | atheos* \ - | auroraux* \ - | aux* \ - | banan_os* \ - | beos* \ - | bitrig* \ - | bme* \ - | bosx* \ - | bsd* \ - | cegcc* \ - | chorusos* \ - | chorusrdb* \ - | clix* \ - | cloudabi* \ - | cnk* \ - | conix* \ - | cos* \ - | cxux* \ - | cygwin* \ - | darwin* \ - | dgux* \ - | dicos* \ - | dnix* \ - | domain* \ - | dragonfly* \ - | drops* \ - | ebmon* \ - | ecoff* \ - | ekkobsd* \ - | emscripten* \ - | emx* \ - | es* \ - | fiwix* \ - | freebsd* \ - | fuchsia* \ - | genix* \ - | genode* \ - | glidix* \ - | gnu* \ - | go32* \ - | haiku* \ - | hcos* \ - | hiux* \ - | hms* \ - | hpux* \ - | ieee* \ - | interix* \ - | ios* \ - | iris* \ - | irix* \ - | isc* \ - | its* \ - | l4re* \ - | libertybsd* \ - | lites* \ - | lnews* \ - | luna* \ - | lynxos* \ - | mach* \ - | macos* \ - | magic* \ - | mbr* \ - | midipix* \ - | midnightbsd* \ - | mingw32* \ - | mingw64* \ - | minix* \ - | mint* \ - | mirbsd* \ - | mks* \ - | mlibc* \ - | mmixware* \ - | mon960* \ - | morphos* \ - | moss* \ - | moxiebox* \ - | mpeix* \ - | mpw* \ - | msdos* \ - | msys* \ - | mvs* \ - | nacl* \ - | netbsd* \ - | netware* \ - | newsos* \ - | nextstep* \ - | nindy* \ - | nonstopux* \ - | nova* \ - | nsk* \ - | nucleus* \ - | nx6 \ - | nx7 \ - | oabi* \ - | ohos* \ - | onefs* \ - | openbsd* \ - | openedition* \ - | openstep* \ - | os108* \ - | os2* \ - | os400* \ - | os68k* \ - | os9* \ - | ose* \ - | osf* \ - | oskit* \ - | osx* \ - | palmos* \ - | phoenix* \ - | plan9* \ - | powermax* \ - | powerunix* \ - | proelf* \ - | psos* \ - | psp* \ - | ptx* \ - | pw32* \ - | qnx* \ - | rdos* \ - | redox* \ - | rhapsody* \ - | riscix* \ - | riscos* \ - | rtems* \ - | rtmk* \ - | rtu* \ - | scout* \ - | secbsd* \ - | sei* \ - | serenity* \ - | sim* \ - | skyos* \ - | solaris* \ - | solidbsd* \ - | sortix* \ - | storm-chaos* \ - | sunos \ - | sunos[34]* \ - | superux* \ - | syllable* \ - | sym* \ - | sysv* \ - | tenex* \ - | tirtos* \ - | tock* \ - | toppers* \ - | tops10* \ - | tops20* \ - | tpf* \ - | tvos* \ - | twizzler* \ - | uclinux* \ - | udi* \ - | udk* \ - | ultrix* \ - | unicos* \ - | uniplus* \ - | unleashed* \ - | unos* \ - | uwin* \ - | uxpv* \ - | v88r* \ - |*vms* \ - | vos* \ - | vsta* \ - | vxsim* \ - | vxworks* \ - | wasi* \ - | watchos* \ - | wince* \ - | windiss* \ - | windows* \ - | winnt* \ - | xenix* \ - | xray* \ - | zephyr* \ - | zvmoe* ) - ;; - # This one is extra strict with allowed versions - sco3.2v2 | sco3.2v[4-9]* | sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - ;; - # This refers to builds using the UEFI calling convention - # (which depends on the architecture) and PE file format. - # Note that this is both a different calling convention and - # different file format than that of GNU-EFI - # (x86_64-w64-mingw32). - uefi) - ;; - none) - ;; - kernel* | msvc* ) - # Restricted further below - ;; - '') - if test x"$obj" = x - then - echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2 - fi - ;; - *) - echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 - exit 1 - ;; -esac - -case $obj in - aout* | coff* | elf* | pe*) - ;; - '') - # empty is fine - ;; - *) - echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 - exit 1 - ;; -esac - -# Here we handle the constraint that a (synthetic) cpu and os are -# valid only in combination with each other and nowhere else. -case $cpu-$os in - # The "javascript-unknown-ghcjs" triple is used by GHC; we - # accept it here in order to tolerate that, but reject any - # variations. - javascript-ghcjs) - ;; - javascript-* | *-ghcjs) - echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 - exit 1 - ;; -esac - -# As a final step for OS-related things, validate the OS-kernel combination -# (given a valid OS), if there is a kernel. -case $kernel-$os-$obj in - linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ - | linux-mlibc*- | linux-musl*- | linux-newlib*- \ - | linux-relibc*- | linux-uclibc*- | linux-ohos*- ) - ;; - uclinux-uclibc*- | uclinux-gnu*- ) - ;; - orange-mlibc*-) - ;; - managarm-mlibc*- | managarm-kernel*- ) - ;; - windows*-msvc*-) - ;; - -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ - | -uclibc*- ) - # These are just libc implementations, not actual OSes, and thus - # require a kernel. - echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 - exit 1 - ;; - -kernel*- ) - echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 - exit 1 - ;; - *-kernel*- ) - echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 - exit 1 - ;; - *-msvc*- ) - echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 - exit 1 - ;; - kfreebsd*-gnu*- | knetbsd*-gnu*- | netbsd*-gnu*- | kopensolaris*-gnu*-) - ;; - vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) - ;; - nto-qnx*-) - ;; - os2-emx-) - ;; - rtmk-nova-) - ;; - *-eabi*- | *-gnueabi*-) - ;; - ios*-simulator- | tvos*-simulator- | watchos*-simulator- ) - ;; - none--*) - # None (no kernel, i.e. freestanding / bare metal), - # can be paired with an machine code file format - ;; - -*-) - # Blank kernel with real OS is always fine. - ;; - --*) - # Blank kernel and OS with real machine code file format is always fine. - ;; - *-*-*) - echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 - exit 1 - ;; -esac - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -case $vendor in - unknown) - case $cpu-$os in - *-riscix*) - vendor=acorn - ;; - *-sunos* | *-solaris*) - vendor=sun - ;; - *-cnk* | *-aix*) - vendor=ibm - ;; - *-beos*) - vendor=be - ;; - *-hpux*) - vendor=hp - ;; - *-mpeix*) - vendor=hp - ;; - *-hiux*) - vendor=hitachi - ;; - *-unos*) - vendor=crds - ;; - *-dgux*) - vendor=dg - ;; - *-luna*) - vendor=omron - ;; - *-genix*) - vendor=ns - ;; - *-clix*) - vendor=intergraph - ;; - *-mvs* | *-opened*) - vendor=ibm - ;; - *-os400*) - vendor=ibm - ;; - s390-* | s390x-*) - vendor=ibm - ;; - *-ptx*) - vendor=sequent - ;; - *-tpf*) - vendor=ibm - ;; - *-vxsim* | *-vxworks* | *-windiss*) - vendor=wrs - ;; - *-aux*) - vendor=apple - ;; - *-hms*) - vendor=hitachi - ;; - *-mpw* | *-macos*) - vendor=apple - ;; - *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) - vendor=atari - ;; - *-vos*) - vendor=stratus - ;; - esac - ;; -esac - -echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" -exit - -# Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp nil t) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%Y-%02m-%02d" -# time-stamp-end: "'" -# End:
\ No newline at end of file diff --git a/tools/pkg/pkg-lib.sh b/tools/pkg/pkg-lib.sh deleted file mode 100644 index 48db2fd..0000000 --- a/tools/pkg/pkg-lib.sh +++ /dev/null @@ -1,114 +0,0 @@ - -GNU_MIRROR=https://mirror.dogado.de/ -CFLAGS="$CFLAGS -lstdc++" - -cachedownload() { - if [ ! -f "../cached/$1" ]; then - curl -o ../cached/$1 $2 - fi -} - -installgnu() { - cachedownload ../cached/$2-$3.tar.gz "$GNU_MIRROR/gnu/$1/$2-$3.tar.gz" - rm -rf ./* - cp -rf ../cached/$2-$3.tar.gz . - tar -xvf $2-$3.tar.gz -} - -diff_patch() { - patch -p1 < "$1" -} - -patch_config_sub() { - SRC="$1/tools/pkg/config.sub" - find "." -type f -name "config.sub" -exec sudo cp "$SRC" {} \; - find "." -type f -name "config.guess" -exec sudo cp "$1/tools/pkg/config.guess" {} \; -} - -fast_install() { - old0="$(pwd)" - wget "$2" - archive_name="$(basename $2)" - dir_name=$(tar -tf "$archive_name" | head -1 | cut -f1 -d"/") - tar -xf "$archive_name" - cd "$dir_name" - autotools_recursive_regen - if [ -n "$4" ]; then - diff_patch "$4" - fi - ./configure --prefix="/usr" --disable-static --host=x86_64-linux-gnu --enable-shared --disable-malloc0returnsnull --bindir=/usr/bin --libdir=/usr/lib --sbindir=/usr/bin --sysconfdir=/etc --localstatedir=/var --with-sysroot="$1" $3 - make -j$(nproc) - make install DESTDIR="$1" - - old="$(pwd)" - cd "$1/usr/lib" - rm -rf *.la - cd "$old" - - cd "$old0" -} - -fast_install_debug() { - old0="$(pwd)" - wget "$2" - archive_name="$(basename $2)" - dir_name=$(tar -tf "$archive_name" | head -1 | cut -f1 -d"/") - #tar -xvf "$archive_name" - cd "$dir_name" - #autotools_recursive_regen - # if [ -n "$4" ]; then - # diff_patch "$4" - # fi - ./configure --prefix="/usr" --host=x86_64-orange-mlibc --disable-static --enable-shared --disable-malloc0returnsnull $3 - make -j$(nproc) - sudo make install DESTDIR="$1" - - old="$(pwd)" - cd "$1/usr/lib" - rm -rf *.la - cd "$old" - - cd "$old0" -} - - -checked_subst() { - tmpfile="$2".checked_subst - sed -z -E -e "$1" "$2" >"$tmpfile" - if cmp -s "$2" "$tmpfile"; then - rm -f "$2".checked_subst - if [ "$3" = no_die ]; then - return 1 - else - die "*** substitution '$1' failed for file '$2'" - fi - fi - - #diff --color=auto -ur "$2" "$tmpfile" || true - - touch -r "$2" "$2".checked_subst - chmod --reference="$2" "$2".checked_subst - mv -f "$2".checked_subst "$2" -} - -base_dir="$(realpath ../../../../)" - -autotools_recursive_regen() { - : -} - -# - -generate_shared() { - echo Generating shared from $2 to $1 - x86_64-orange-mlibc-gcc -shared -o "$1" -Wl,--whole-archive "$2" -Wl,--no-whole-archive -fPIC - rm -f "$2" -} - -kill_libtool_demons() { - echo Killing libtool demons - old="$(pwd)" - cd "$1/usr/lib" - rm -rf *.la - cd "$old" -} diff --git a/tools/pkg/readme b/tools/pkg/readme deleted file mode 100644 index eee1b56..0000000 --- a/tools/pkg/readme +++ /dev/null @@ -1 +0,0 @@ -in future...
\ No newline at end of file diff --git a/tools/pkg/toolchain.cmake b/tools/pkg/toolchain.cmake deleted file mode 100644 index e108e33..0000000 --- a/tools/pkg/toolchain.cmake +++ /dev/null @@ -1,12 +0,0 @@ - -set(CMAKE_SYSTEM_NAME Orange) -set(CMAKE_SYSTEM_PROCESSOR x86_64) - -set(CMAKE_C_COMPILER x86_64-linux-gnu-gcc) -set(CMAKE_CXX_COMPILER x86_64-linux-gnu-g++) -set(CMAKE_LINKER x86_64-linux-gnu-ld) - -set(CMAKE_POSITION_INDEPENDENT_CODE ON) - -set(CMAKE_CXX_EXTENSIONS ON) -set(CMAKE_C_EXTENSIONS ON)
\ No newline at end of file diff --git a/tools/pkg/x86_64-orange-cpp.crossfile b/tools/pkg/x86_64-orange-cpp.crossfile deleted file mode 100644 index a333b18..0000000 --- a/tools/pkg/x86_64-orange-cpp.crossfile +++ /dev/null @@ -1,13 +0,0 @@ -[binaries] -c = 'x86_64-linux-gnu-gcc' -cpp = 'x86_64-linux-gnu-g++' -ar = 'x86_64-linux-gnu-ar' -nm = 'x86_64-linux-gnu-nm' -ld = 'x86_64-linux-gnu-ld' -pkg-config = 'x86_64-linux-gnu-pkg-config' - -[host_machine] -system = 'orange' -cpu_family = 'x86_64' -cpu = 'x86_64' -endian = 'little'
\ No newline at end of file diff --git a/tools/pkg/x86_64-orange.crossfile b/tools/pkg/x86_64-orange.crossfile deleted file mode 100644 index a333b18..0000000 --- a/tools/pkg/x86_64-orange.crossfile +++ /dev/null @@ -1,13 +0,0 @@ -[binaries] -c = 'x86_64-linux-gnu-gcc' -cpp = 'x86_64-linux-gnu-g++' -ar = 'x86_64-linux-gnu-ar' -nm = 'x86_64-linux-gnu-nm' -ld = 'x86_64-linux-gnu-ld' -pkg-config = 'x86_64-linux-gnu-pkg-config' - -[host_machine] -system = 'orange' -cpu_family = 'x86_64' -cpu = 'x86_64' -endian = 'little'
\ No newline at end of file diff --git a/tools/test.c b/tools/test.c deleted file mode 100644 index 6e6af36..0000000 --- a/tools/test.c +++ /dev/null @@ -1,5 +0,0 @@ -#include <X11/keysymdef.h> - -int main() { - return 0; -} diff --git a/tools/toolchain-build.sh b/tools/toolchain-build.sh deleted file mode 100644 index a65b716..0000000 --- a/tools/toolchain-build.sh +++ /dev/null @@ -1,111 +0,0 @@ - -. pkg/pkg-lib.sh - -export CFLAGS="-fPIC" -export CXXFLAGS="-fPIC" -export CPPFLAGS="-fPIC" - -GNU_MIRROR=https://mirror.dogado.de/ -CURRENT_DIR="$(realpath .)" - - rm -rf "$HOME/opt/cross/orange" - - rm -rf pack - - echo Downloading binutils and gcc - - mkdir -p pack - - mkdir -p $1/initrd/usr/include - mkdir -p $1/initrd/usr/lib - - cd pack - - wget -nc $GNU_MIRROR/gnu/gcc/gcc-15.1.0/gcc-15.1.0.tar.gz - wget -nc $GNU_MIRROR/gnu/binutils/binutils-2.38.tar.gz - - echo Unpacking binutils and gcc - - tar -xvf gcc-15.1.0.tar.gz - tar -xvf binutils-2.38.tar.gz - - echo Patching binutils and gcc - - echo Downloading prerequisites - - echo Donwloading and installing automake and autoconf - - wget -nc $GNU_MIRROR/gnu/automake/automake-1.15.1.tar.gz - wget -nc $GNU_MIRROR/gnu/autoconf/autoconf-2.69.tar.gz - - tar -xvf automake-1.15.1.tar.gz - tar -xvf autoconf-2.69.tar.gz - - cd automake-1.15.1 - ./configure --prefix="$HOME/opt/cross/orange" - make - make install - cd .. - - cd autoconf-2.69 - ./configure --prefix="$HOME/opt/cross/orange" -make - make install - cd .. - - export PATH="$HOME/opt/cross/orange/bin:$PATH" - - cd gcc-15.1.0 - cp -rf "$1/tools/pkg/config.sub" "$1/tools/pkg/config.guess" . - cd .. - - cd binutils-2.38 - cp -rf "$1/tools/pkg/config.sub" "$1/tools/pkg/config.guess" . - cd .. - - echo Building binutils and gcc - - mkdir -p binutils-build - cd binutils-build - mkdir -p $1/initrd - ../binutils-2.38/configure --target=x86_64-linux-gnu --prefix="$HOME/opt/cross/orange" --with-sysroot="$(realpath $1)/initrd" --enable-shared - make -j$(nproc) - make install -j$(nproc) - - export CFLAGS="-fPIC" - export CXXFLAGS="-fPIC" - - cd .. - -rm -rf gcc-build -mkdir -p gcc-build -cd gcc-build - -export CPP=/bin/cpp -export CXX=/bin/g++ - -echo hi - -cp -rf "/usr/include/sys/sdt.h" "/usr/include/sys/sdt-config.h" "$1/initrd/usr/include/sys" # copy it if available - -../gcc-15.1.0/configure --without-dtrace --disable-systemtap --target=x86_64-linux-gnu --prefix="$HOME/opt/cross/orange" --with-sysroot="$(realpath $1)/initrd" --enable-languages=c,c++,go --disable-nls --with-pic --enable-linker-build-id --enable-threads=posix --enable-default-pie --enable-default-ssp --disable-multilib --enable-initfini-array --enable-shared --enable-host-shared --with-mpc --with-mpfr --with-gmp --with-build-config=bootstrap-lto --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace --enable-link-serialization=1 --enable-linker-build-id --enable-lto --disable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-werror - -echo no - -make all-gcc -j$(nproc) -make all-target-libgcc -j$(nproc) -make install-gcc -j$(nproc) -make install-target-libgcc -j$(nproc) - -make all-target-libstdc++-v3 -j$(nproc) -make install-target-libstdc++-v3 - -T="$(pwd)" -cd "$1/initrd/usr/lib" -ln -sf ld.so ld64.so.1 -cp -rf "$HOME"/opt/cross/orange/x86_64-linux-gnu/lib/libs*.so* . -cp -rf "$HOME"/opt/cross/orange/lib64/libg*.so* . -cp -rf "$HOME"/opt/cross/orange/lib64/libs*.so* . -cd "$T" - -echo Done |
