Merge branch 'master' of git://localhost/acess2
authorJohn Hodge <[email protected]>
Tue, 4 Dec 2012 01:08:34 +0000 (09:08 +0800)
committerJohn Hodge <[email protected]>
Tue, 4 Dec 2012 01:08:34 +0000 (09:08 +0800)
284 files changed:
AcessNative/Makefile
AcessNative/acesskernel_src/Makefile
AcessNative/acesskernel_src/helpers.c
AcessNative/acesskernel_src/include/arch.h
AcessNative/acesskernel_src/include/mouse_int.h [new file with mode: 0644]
AcessNative/acesskernel_src/include/threads_glue.h [new file with mode: 0644]
AcessNative/acesskernel_src/include/threads_int.h
AcessNative/acesskernel_src/main.c
AcessNative/acesskernel_src/mouse.c
AcessNative/acesskernel_src/server.c
AcessNative/acesskernel_src/syscalls.c
AcessNative/acesskernel_src/threads.c
AcessNative/acesskernel_src/threads_glue.c [new file with mode: 0644]
AcessNative/acesskernel_src/ui.h
AcessNative/acesskernel_src/ui_sdl.c
AcessNative/acesskernel_src/vfs_handle.c
AcessNative/acesskernel_src/video.c
AcessNative/ld-acess_src/Makefile
AcessNative/ld-acess_src/common.h
AcessNative/ld-acess_src/elf.c [changed from symlink to file mode: 0644]
AcessNative/ld-acess_src/elf32.h [changed from symlink to file mode: 0644]
AcessNative/ld-acess_src/elf64.h [changed from symlink to file mode: 0644]
AcessNative/ld-acess_src/elf_load.c
AcessNative/ld-acess_src/exports.c
AcessNative/ld-acess_src/exports.h
AcessNative/ld-acess_src/main.c
AcessNative/ld-acess_src/memory.c
AcessNative/ld-acess_src/request.c
AcessNative/ld-acess_src/syscalls.c
AcessNative/syscalls.h
BuildConf/armv7/Makefile.cfg
BuildConf/host/Makefile.cfg
BuildConf/x86/Makefile.cfg
BuildConf/x86/default.mk
BuildConf/x86_64/Makefile.cfg
Externals/ACPICA/.gitignore [new file with mode: 0644]
Externals/ACPICA/Makefile [new file with mode: 0644]
Externals/ACPICA/Makefile.kinc [new file with mode: 0644]
Externals/ACPICA/acacess.h [new file with mode: 0644]
KernelLand/Kernel/Makefile
KernelLand/Kernel/arch/armv7/Makefile
KernelLand/Kernel/arch/armv7/lib.c
KernelLand/Kernel/arch/armv7/link.ld
KernelLand/Kernel/arch/armv7/mm_virt.c
KernelLand/Kernel/arch/armv7/proc.c
KernelLand/Kernel/arch/armv7/start.S
KernelLand/Kernel/arch/armv7/vpci_realview_pb.c [new file with mode: 0644]
KernelLand/Kernel/arch/armv7/vpci_tegra2.c [new file with mode: 0644]
KernelLand/Kernel/arch/x86/Makefile
KernelLand/Kernel/arch/x86/acpica.c [new file with mode: 0644]
KernelLand/Kernel/arch/x86/include/arch.h
KernelLand/Kernel/arch/x86/irq.c
KernelLand/Kernel/arch/x86/lib.c
KernelLand/Kernel/arch/x86/link.ld
KernelLand/Kernel/arch/x86/main.c
KernelLand/Kernel/arch/x86/mboot.c
KernelLand/Kernel/arch/x86/mm_phys.c
KernelLand/Kernel/arch/x86/proc.c
KernelLand/Kernel/arch/x86/start.asm
KernelLand/Kernel/arch/x86/vpci.c [new file with mode: 0644]
KernelLand/Kernel/arch/x86_64/Makefile
KernelLand/Kernel/arch/x86_64/desctab.asm
KernelLand/Kernel/arch/x86_64/errors.c
KernelLand/Kernel/arch/x86_64/include/mm_virt.h
KernelLand/Kernel/arch/x86_64/lib.c
KernelLand/Kernel/arch/x86_64/main.c
KernelLand/Kernel/arch/x86_64/mm_virt.c
KernelLand/Kernel/arch/x86_64/proc.asm
KernelLand/Kernel/arch/x86_64/proc.c
KernelLand/Kernel/arch/x86_64/vpci.c [new file with mode: 0644]
KernelLand/Kernel/bin/elf.c
KernelLand/Kernel/binary.c
KernelLand/Kernel/debug.c
KernelLand/Kernel/drv/pci.c
KernelLand/Kernel/drv/proc.c
KernelLand/Kernel/drv/vpci.c [new file with mode: 0644]
KernelLand/Kernel/drv/vterm_input.c
KernelLand/Kernel/heap.c
KernelLand/Kernel/include/acess.h
KernelLand/Kernel/include/api_drv_keyboard.h
KernelLand/Kernel/include/errno.h
KernelLand/Kernel/include/events.h
KernelLand/Kernel/include/hal_proc.h
KernelLand/Kernel/include/logdebug.h [new file with mode: 0644]
KernelLand/Kernel/include/rwlock.h
KernelLand/Kernel/include/syscalls.h
KernelLand/Kernel/include/syscalls.inc.asm
KernelLand/Kernel/include/threads.h
KernelLand/Kernel/include/threads_int.h
KernelLand/Kernel/include/timers_int.h [new file with mode: 0644]
KernelLand/Kernel/include/vfs_int.h
KernelLand/Kernel/include/virtual_pci.h [new file with mode: 0644]
KernelLand/Kernel/lib.c
KernelLand/Kernel/libc.c
KernelLand/Kernel/logging.c
KernelLand/Kernel/messages.c
KernelLand/Kernel/modules.c
KernelLand/Kernel/pmemmap.c
KernelLand/Kernel/semaphore.c
KernelLand/Kernel/syscalls.c
KernelLand/Kernel/syscalls.lst
KernelLand/Kernel/system.c
KernelLand/Kernel/threads.c
KernelLand/Kernel/time.c
KernelLand/Kernel/vfs/dir.c
KernelLand/Kernel/vfs/handle.c
KernelLand/Kernel/vfs/main.c
KernelLand/Kernel/vfs/mmap.c
KernelLand/Kernel/vfs/mount.c
KernelLand/Kernel/vfs/nodecache.c
KernelLand/Kernel/vfs/open.c
KernelLand/Modules/Display/BochsGA/bochsvbe.c
KernelLand/Modules/Filesystems/Ext2/dir.c
KernelLand/Modules/Filesystems/Ext2/ext2.c
KernelLand/Modules/Filesystems/Ext2/ext2_common.h
KernelLand/Modules/Filesystems/FAT/common.h
KernelLand/Modules/Filesystems/FAT/dir.c
KernelLand/Modules/Filesystems/FAT/fat.c
KernelLand/Modules/Filesystems/FAT/fatio.c
KernelLand/Modules/Filesystems/FAT/nodecache.c
KernelLand/Modules/Filesystems/InitRD/GenerateInitRD.php
KernelLand/Modules/Filesystems/InitRD/files.lst
KernelLand/Modules/IPStack/adapters.c
KernelLand/Modules/IPStack/udp.c
KernelLand/Modules/Storage/ATA/main.c
KernelLand/Modules/USB/Core/Makefile
KernelLand/Modules/USB/Core/hub.c
KernelLand/Modules/USB/Core/include/usb_host.h
KernelLand/Modules/USB/Core/include/usb_hub.h
KernelLand/Modules/USB/Core/main.c
KernelLand/Modules/USB/Core/portctl.c [new file with mode: 0644]
KernelLand/Modules/USB/Core/usb.c
KernelLand/Modules/USB/Core/usb.h
KernelLand/Modules/USB/Core/usb_devinit.c
KernelLand/Modules/USB/Core/usb_lowlevel.c
KernelLand/Modules/USB/Core/usb_poll.c
KernelLand/Modules/USB/EHCI/ehci.c
KernelLand/Modules/USB/EHCI/ehci.h
KernelLand/Modules/USB/UHCI/uhci.c
Makefile
Makefile.cfg
Notes/VirtualPCI.txt [new file with mode: 0644]
RunQemu
TODO.txt
Tools/DiskTool/src/actions.c
Tools/DiskTool/src/logging.c
Tools/GCCProxy/gccproxy.sh [new file with mode: 0755]
Tools/GCCProxy/getconfig.mk [new file with mode: 0644]
Usermode/Applications/CLIShell_src/main.c
Usermode/Applications/Makefile.cfg
Usermode/Applications/Makefile.tpl
Usermode/Applications/axwin3_src/Interface/main.c
Usermode/Applications/axwin3_src/WM/Makefile
Usermode/Applications/axwin3_src/WM/decorator.c
Usermode/Applications/axwin3_src/WM/include/wm.h
Usermode/Applications/axwin3_src/WM/include/wm_internals.h
Usermode/Applications/axwin3_src/WM/include/wm_renderer.h
Usermode/Applications/axwin3_src/WM/input.c
Usermode/Applications/axwin3_src/WM/ipc.c
Usermode/Applications/axwin3_src/WM/main.c
Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c [new file with mode: 0644]
Usermode/Applications/axwin3_src/WM/renderers/menu.c
Usermode/Applications/axwin3_src/WM/renderers/passthru.c [deleted file]
Usermode/Applications/axwin3_src/WM/renderers/richtext.c [new file with mode: 0644]
Usermode/Applications/axwin3_src/WM/renderers/widget.c
Usermode/Applications/axwin3_src/WM/renderers/widget/subwin.c [new file with mode: 0644]
Usermode/Applications/axwin3_src/WM/utf-8.c
Usermode/Applications/axwin3_src/WM/video.c
Usermode/Applications/axwin3_src/WM/wm.c
Usermode/Applications/axwin3_src/WM/wm_input.c
Usermode/Applications/axwin3_src/WM/wm_render_text.c
Usermode/Applications/axwin3_src/include/framebuffer_messages.h
Usermode/Applications/axwin3_src/include/ipcmessages.h
Usermode/Applications/axwin3_src/include/menu_messages.h
Usermode/Applications/axwin3_src/include/richtext_messages.h [new file with mode: 0644]
Usermode/Applications/axwin3_src/include/widget_messages.h
Usermode/Applications/axwin3_src/libaxwin3.so_src/Makefile
Usermode/Applications/axwin3_src/libaxwin3.so_src/include/internal.h
Usermode/Applications/axwin3_src/libaxwin3.so_src/include/ipc.h
Usermode/Applications/axwin3_src/libaxwin3.so_src/main.c
Usermode/Applications/axwin3_src/libaxwin3.so_src/msg.c
Usermode/Applications/axwin3_src/libaxwin3.so_src/r_menu.c
Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c [new file with mode: 0644]
Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c
Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c
Usermode/Applications/bomb_src/main.c
Usermode/Applications/cat_src/main.c
Usermode/Applications/dhcpclient_src/main.c
Usermode/Applications/gui_ate_src/Makefile [new file with mode: 0644]
Usermode/Applications/gui_ate_src/edit.c [new file with mode: 0644]
Usermode/Applications/gui_ate_src/include/file.h [new file with mode: 0644]
Usermode/Applications/gui_ate_src/include/syntax.h [new file with mode: 0644]
Usermode/Applications/gui_ate_src/main.c [new file with mode: 0644]
Usermode/Applications/gui_shell_src/Makefile [new file with mode: 0644]
Usermode/Applications/gui_shell_src/include/display.h [new file with mode: 0644]
Usermode/Applications/gui_shell_src/include/vt100.h [new file with mode: 0644]
Usermode/Applications/gui_shell_src/main.c [new file with mode: 0644]
Usermode/Applications/gui_shell_src/vt100.c [new file with mode: 0644]
Usermode/Applications/init_src/main.c
Usermode/Applications/ip_src/addr.c
Usermode/Applications/ip_src/routes.c
Usermode/Applications/irc_src/main.c
Usermode/Applications/login_src/main.c
Usermode/Applications/ls_src/main.c
Usermode/Applications/lspci_src/main.c
Usermode/Applications/mount_src/main.c
Usermode/Applications/ping_src/main.c
Usermode/Applications/telnet_src/main.c
Usermode/Applications/telnetd_src/main.c
Usermode/Applications/wget_src/main.c
Usermode/Libraries/Makefile.tpl
Usermode/Libraries/ld-acess.so_src/Makefile
Usermode/Libraries/ld-acess.so_src/_stublib.c
Usermode/Libraries/ld-acess.so_src/arch/armv7.S.h
Usermode/Libraries/ld-acess.so_src/arch/armv7.ld
Usermode/Libraries/ld-acess.so_src/arch/syscalls.s.h
Usermode/Libraries/ld-acess.so_src/common.h
Usermode/Libraries/ld-acess.so_src/elf.c
Usermode/Libraries/ld-acess.so_src/export.c
Usermode/Libraries/ld-acess.so_src/include_exp/acess/fd_set.h [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/include_exp/acess/intdefs.h [deleted file]
Usermode/Libraries/ld-acess.so_src/include_exp/acess/sys.h
Usermode/Libraries/ld-acess.so_src/include_exp/acess/syscall_types.h [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/include_exp/stddef.h [deleted file]
Usermode/Libraries/ld-acess.so_src/include_exp/sys/param.h [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/include_exp/sys/stat.h [deleted file]
Usermode/Libraries/ld-acess.so_src/include_exp/sys/sys.h [deleted file]
Usermode/Libraries/ld-acess.so_src/include_exp/sys/types.h [deleted file]
Usermode/Libraries/ld-acess.so_src/include_exp/unistd.h [deleted file]
Usermode/Libraries/ld-acess.so_src/lib.c
Usermode/Libraries/ld-acess.so_src/loadlib.c
Usermode/Libraries/ld-acess.so_src/main.c
Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/axwin.h
Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/richtext.h [new file with mode: 0644]
Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/widget.h
Usermode/Libraries/libc.so_src/Makefile
Usermode/Libraries/libc.so_src/fileIO.c [deleted file]
Usermode/Libraries/libc.so_src/heap.c
Usermode/Libraries/libc.so_src/include_exp/assert.h [new file with mode: 0644]
Usermode/Libraries/libc.so_src/include_exp/ctype.h
Usermode/Libraries/libc.so_src/include_exp/errno.enum.h [new file with mode: 0644]
Usermode/Libraries/libc.so_src/include_exp/errno.h
Usermode/Libraries/libc.so_src/include_exp/signal.h
Usermode/Libraries/libc.so_src/include_exp/stdio.h
Usermode/Libraries/libc.so_src/include_exp/stdlib.h
Usermode/Libraries/libc.so_src/lib.h
Usermode/Libraries/libc.so_src/perror.c [new file with mode: 0644]
Usermode/Libraries/libc.so_src/rules.mk
Usermode/Libraries/libc.so_src/scanf.c [new file with mode: 0644]
Usermode/Libraries/libc.so_src/signals.c
Usermode/Libraries/libc.so_src/stdio.c [new file with mode: 0644]
Usermode/Libraries/libc.so_src/stdio_int.h
Usermode/Libraries/libc.so_src/stdlib.c
Usermode/Libraries/libc.so_src/string.c
Usermode/Libraries/libc.so_src/strtoi.c [new file with mode: 0644]
Usermode/Libraries/libc.so_src/stub.c
Usermode/Libraries/libnet.so_src/main.c
Usermode/Libraries/libnet.so_src/socket.c
Usermode/Libraries/libposix.so_src/Makefile [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/include_exp/dirent.h [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/include_exp/fcntl.h
Usermode/Libraries/libposix.so_src/include_exp/grp.h [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/include_exp/pwd.h [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/include_exp/sys/resource.h [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/include_exp/sys/select.h [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/include_exp/sys/stat.h [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/include_exp/sys/time.h [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/include_exp/sys/types.h [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/include_exp/sys/wait.h [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/include_exp/syslog.h [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/include_exp/termios.h [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/include_exp/unistd.h [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/main.c [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/unistd.c [new file with mode: 0644]
Usermode/Libraries/libpsocket.so_src/common.h [new file with mode: 0644]
Usermode/Libraries/libpsocket.so_src/include_exp/arpa/inet.h [new file with mode: 0644]
Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h
Usermode/Libraries/libpsocket.so_src/include_exp/netinet/tcp.h [new file with mode: 0644]
Usermode/Libraries/libpsocket.so_src/include_exp/sys/socket.h
Usermode/Libraries/libpsocket.so_src/include_exp/sys/un.h [new file with mode: 0644]
Usermode/Libraries/libpsocket.so_src/main.c
Usermode/Libraries/libpsocket.so_src/socket.c
Usermode/Libraries/libreadline.so_src/main.c
Usermode/Libraries/liburi.so_src/main.c

index c9cd481..7448f4f 100644 (file)
@@ -1,4 +1,6 @@
 
-all:
-       @$(MAKE) -C acesskernel_src
-       @$(MAKE) -C ld-acess_src
+.PHONY: all clean
+
+all clean:
+       @$(MAKE) -C acesskernel_src $@
+       @$(MAKE) -C ld-acess_src $@
index 0d63d5f..b4b7c11 100644 (file)
@@ -13,7 +13,7 @@ endif
 \r
 KERNEL_SRC = ../../KernelLand/Kernel/\r
 \r
-KERNEL_OBJ := logging.o adt.o lib.o drvutil.o debug.o messages.o\r
+KERNEL_OBJ := logging.o adt.o lib.o libc.o debug.o messages.o drvutil_disk.o drvutil_video.o\r
 KERNEL_OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o\r
 KERNEL_OBJ += vfs/nodecache.o vfs/mount.o vfs/memfile.o vfs/select.o\r
 KERNEL_OBJ += vfs/fs/root.o vfs/fs/devfs.o\r
@@ -25,7 +25,7 @@ N_OBJ := main.o
 BUILDINFO_OBJ := obj-$(PLATFORM)/buildinfo.o\r
 BUILDINFO_SRC := $(BUILDINFO_OBJ:%.o=%.c)\r
 \r
-OBJ := helpers.o threads.o server.o syscalls.o time.o\r
+OBJ := helpers.o threads.o threads_glue.o server.o syscalls.o time.o\r
 OBJ += video.o keyboard.o mouse.o nativefs.o vfs_handle.o ui_sdl.o\r
 OBJ := $(addprefix obj-$(PLATFORM)/,$(OBJ))\r
 N_OBJ := $(addprefix obj-$(PLATFORM)/,$(N_OBJ))\r
@@ -34,16 +34,18 @@ K_OBJ := $(addprefix $(KERNEL_SRC)obj-native-$(PLATFORM)/,$(KERNEL_OBJ))
 DEPFILES  = $(filter %.o,$(OBJ) $(N_OBJ) $(K_OBJ))\r
 DEPFILES := $(DEPFILES:%=%.dep)\r
 \r
-CPPFLAGS += -I include/ -I $(KERNEL_SRC)include/\r
-CFLAGS += -Wall -g\r
+KCPPFLAGS = -I include/ -I $(KERNEL_SRC)include/\r
+CFLAGS += -Wall -g -std=gnu99\r
 LDFLAGS += -lSDL -lSDLmain -g -Wl,--defsym,__buildnum=$(BUILD_NUM)\r
 \r
 ifeq ($(PLATFORM),win)\r
        BIN := ../AcessKernel.exe\r
+       LDFLAGS += -lws2_32 -lpthread\r
 endif\r
 ifeq ($(PLATFORM),lin)\r
        BIN := ../AcessKernel\r
-       CFLAGS +=\r
+       CFLAGS += \r
+       LDFLAGS += -lpthread\r
 endif\r
 \r
 .PHONY: all clean\r
@@ -61,26 +63,30 @@ $(BIN): $(OBJ) $(N_OBJ) $(K_OBJ) $(BUILDINFO_OBJ)
 $(OBJ): obj-$(PLATFORM)/%.o: %.c\r
        @mkdir -p $(dir $@)\r
        @echo [CC] -o $@\r
-       @$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)\r
-       @$(CC) -M $(CPPFLAGS) -MT $@ -o [email protected] $<\r
+       @$(CC) -c $< -o $@ $(CFLAGS) $(KCPPFLAGS) $(CPPFLAGS)\r
+       @$(CC) -M $(CPPFLAGS) $(KCPPFLAGS) -MT $@ -o [email protected] $<\r
 \r
 $(K_OBJ): $(KERNEL_SRC)obj-native-$(PLATFORM)/%.o: $(KERNEL_SRC)%.c\r
        @mkdir -p $(dir $@)\r
        @echo [CC] -o $@\r
-       @$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)\r
-       @$(CC) -M $(CPPFLAGS) -MT $@ -o [email protected] $<\r
+       $(CC) -ffreestanding -c $< -o $@ $(CFLAGS) $(KCPPFLAGS) $(CPPFLAGS)\r
+       @$(CC) -ffreestanding -M $(KCPPFLAGS) $(CPPFLAGS) -MT $@ -o [email protected] $<\r
 \r
 \r
 $(N_OBJ): obj-$(PLATFORM)/%.o: %.c\r
        @mkdir -p $(dir $@)\r
        @echo [CC] -o $@\r
-       @$(CC) -c $< -o $@ $(CFLAGS)\r
+       @$(CC) -c $< -o $@ $(CPPFLAGS) $(CFLAGS)\r
        @$(CC) -M -MT $@ -o [email protected] $<\r
 \r
 $(BUILDINFO_SRC): $(filter-out $(BUILDINFO_OBJ), $(OBJ)) Makefile\r
        @echo "" > $@\r
+       $(eval _GITHASH=$(shell (git log -n 1 | head -n 1 | awk '{print $$2}') || echo UNK))\r
+       $(eval _GITCHANGED=$(shell (git status --porcelain | grep -c '^ M ') || echo UNK))\r
        @echo "const char gsKernelVersion[] = \"$(ACESS_VERSION)\";" >> $@\r
-       @echo "const char gsGitHash[] = \""`git log -n 1 | head -n 1 | awk '{print $$2}'`"\";" >> $@\r
+       @echo "const char gsGitHash[] = \"$(_GITHASH)\";" >> $@\r
+       @echo "const char gsBuildInfo[] = \"Acess2 v$(KERNEL_VERSION) $(ARCH)-$(PLATFORM)\\\\r\\\\n\"" >> $@\r
+       @echo "                           \"Build $(shell hostname --fqdn):$(BUILD_NUM) Git $(_GITHASH) - $(_GITCHANGED) modified\";" >> $@\r
        @echo "const int giBuildNumber = $(BUILD_NUM);" >> $@\r
 $(BUILDINFO_OBJ): $(BUILDINFO_SRC)\r
        @echo [CC] -o $@\r
index fb3e48c..3cf273e 100644 (file)
@@ -93,6 +93,10 @@ void Heap_Deallocate(void *Ptr)
        free(Ptr);
 }
 
+void Heap_Dump(void)
+{
+}
+
 tPAddr MM_GetPhysAddr(tVAddr VAddr)
 {
        return VAddr;   // HACK!
@@ -121,3 +125,8 @@ Sint64 now(void)
        return tv.tv_sec * 1000 + tv.tv_usec/1000;
 }
 
+void IPStack_SendDebugText(const char *str)
+{
+       // nop
+}
+
index b63d1bb..1307e0c 100644 (file)
@@ -5,7 +5,6 @@
 
 #include <stdint.h>
 //#include <stdlib.h>
-#include <pthread.h>
 #undef CLONE_VM
 #define        _MODULE_NAME_   "NativeKernel"
 
@@ -29,14 +28,18 @@ typedef intptr_t    tPAddr;
 
 typedef        int     BOOL;
 
+#include <stddef.h>
+#undef NULL
+#undef offsetof
+
 struct sShortSpinlock
 {
-        int    IsValid;
-       pthread_mutex_t Mutex;
+       void    *Mutex;
 };
 
 #define SHORTLOCK(...)
 #define SHORTREL(...)
+#define CPU_HAS_LOCK(...)      0
 
 //#define      NUM_CFG_ENTRIES 10
 
diff --git a/AcessNative/acesskernel_src/include/mouse_int.h b/AcessNative/acesskernel_src/include/mouse_int.h
new file mode 100644 (file)
index 0000000..d18d566
--- /dev/null
@@ -0,0 +1,35 @@
+
+#ifndef _ACESSNATIVE__MOUSE_INT_H_
+#define _ACESSNATIVE__MOUSE_INT_H_
+
+#include <api_drv_joystick.h>
+
+typedef struct sPointer        tPointer;
+
+#define MAX_BUTTONS    5
+#define MAX_AXIES      2
+#define MAX_FILESIZE   (sizeof(tJoystick_FileHeader) + MAX_AXIES*sizeof(tJoystick_Axis) + MAX_BUTTONS)
+
+/**
+ */
+struct sPointer
+{
+       tPointer        *Next;
+
+       // Node
+       tVFS_Node       Node;
+
+       // Data
+       Uint8   FileData[MAX_FILESIZE];
+       tJoystick_FileHeader    *FileHeader;
+       tJoystick_Axis  *Axies;
+       Uint8   *Buttons;
+
+       // Limits for axis positions
+       Uint16  AxisLimits[MAX_AXIES];
+};
+
+extern void    Mouse_HandleEvent(Uint32 ButtonState, int *AxisDeltas, int *AxisValues);
+
+#endif
+
diff --git a/AcessNative/acesskernel_src/include/threads_glue.h b/AcessNative/acesskernel_src/include/threads_glue.h
new file mode 100644 (file)
index 0000000..61346bd
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ */
+#ifndef _ACESSNATIVE__THREADS_GLUE_H_
+#define _ACESSNATIVE__THREADS_GLUE_H_
+
+
+extern void    Threads_Glue_Yield(void);
+extern void    Threads_Glue_AcquireMutex(void **Lock);
+extern void    Threads_Glue_ReleaseMutex(void **Lock);
+extern void    Threads_Glue_SemInit(void **Ptr, int Val);
+extern int     Threads_Glue_SemWait(void *Ptr, int Max);
+extern int     Threads_Glue_SemSignal( void *Ptr, int AmmountToAdd );
+
+#endif
+
index f070a50..1294a5f 100644 (file)
@@ -72,7 +72,7 @@ enum {
        THREAD_STAT_DEAD,       // Awaiting burial (free)
        THREAD_STAT_BURIED      // If it's still on the list here, something's wrong
 };
-extern tThread *Threads_GetThread(Uint TID);
+extern struct sThread  *Threads_GetThread(Uint TID);
 
 #endif
 
index fbb457c..eb0883d 100644 (file)
@@ -13,6 +13,9 @@
 #endif
 #include <unistd.h>
 #include <string.h>
+#include "../../KernelLand/Kernel/include/logdebug.h"
+
+#define VALGRIND_CLIENT        0
 
 // === IMPORTS ===
 extern int     UI_Initialise(int Width, int Height);
@@ -23,9 +26,11 @@ extern int   NativeKeyboard_Install(char **Arguments);
 extern int     NativeFS_Install(char **Arguments);
 extern void    Debug_SetKTerminal(char *Path);
 extern int     VT_Install(char **Arguments);
+extern int     Mouse_Install(char **Arguments);
 extern int     VFS_Mount(const char *Device, const char *MountPoint, const char *Filesystem, const char *Options);
 extern int     VFS_MkDir(const char *Path);
 extern int     SyscallServer(void);
+extern int     Server_Shutdown(void);
 extern const char      gsKernelVersion[];
 extern const char      gsGitHash[];
 extern int     giBuildNumber;
@@ -34,6 +39,19 @@ extern int   giBuildNumber;
 const char     *gsAcessDir = "../Usermode/Output/x86_64";
 
 // === CODE ===
+#ifndef __WIN32__
+#define P_NOWAIT       0
+int spawnv(int flags, const char *execuable, char * const argv[])
+{
+       int pid = fork();
+       if( pid != 0 )  return pid;
+
+       execv(execuable, argv);
+       perror("spawnv - execve");
+       for(;;);
+}
+#endif
+
 int main(int argc, char *argv[])
 {
        char    **rootapp = NULL;
@@ -63,7 +81,9 @@ int main(int argc, char *argv[])
        UI_Initialise(800, 480);
        
        // - Ignore SIGUSR1 (used to wake threads)
+       #ifdef SIGUSR1
        signal(SIGUSR1, SIG_IGN);
+       #endif
                
        // Initialise VFS
        VFS_Init();
@@ -75,6 +95,7 @@ int main(int argc, char *argv[])
                Log_Error("Init", "Unable to load NativeKeyboard");
        }
        NativeFS_Install(NULL);
+       Mouse_Install(NULL);
        // - Start VTerm
        {
                char    *args[] = {
@@ -97,28 +118,24 @@ int main(int argc, char *argv[])
        if( rootapp )
        {
                 int    pid;
-               char    *args[7+rootapp_argc+1];
-               
-               args[0] = "ld-acess";
-               args[1] = "--open";     args[2] = "/Devices/VTerm/0";
-               args[3] = "--open";     args[4] = "/Devices/VTerm/0";
-               args[5] = "--open";     args[6] = "/Devices/VTerm/0";
+                int    argcount = 0;
+               const char      *args[7+rootapp_argc+1+1];
+
+               #if VALGRIND_CLIENT
+               args[argcount++] = "valgrind";
+               #endif
+               args[argcount++] = "./ld-acess";
+               args[argcount++] = "--open";    args[argcount++] = "/Devices/VTerm/0";
+               args[argcount++] = "--open";    args[argcount++] = "/Devices/VTerm/0";
+               args[argcount++] = "--open";    args[argcount++] = "/Devices/VTerm/0";
                for( i = 0; i < rootapp_argc; i ++ )
-                       args[7+i] = rootapp[i];
-               args[7+rootapp_argc] = NULL;
-               
-               pid = fork();
+                       args[argcount+i] = rootapp[i];
+               args[argcount+rootapp_argc] = NULL;
+               pid = spawnv(P_NOWAIT, "./ld-acess", args);
                if(pid < 0) {
                        perror("Starting root application [fork(2)]");
                        return 1;
                }
-               if(pid == 0)
-               {
-                       #ifdef __LINUX__
-                       prctl(PR_SET_PDEATHSIG, SIGHUP);        // LINUX ONLY!
-                       #endif
-                       execv("./ld-acess", args);
-               }
                printf("Root application running as PID %i\n", pid);
        }
 
@@ -130,6 +147,7 @@ int main(int argc, char *argv[])
 void AcessNative_Exit(void)
 {
        // TODO: Close client applications too
+       Server_Shutdown();
        exit(0);
 }
 
index e69de29..0ff9e8a 100644 (file)
@@ -0,0 +1,170 @@
+/*
+ * Acess2 Kernel - Mouse Mulitplexing Driver
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Mouse mulitplexing
+ */
+#define DEBUG  0
+#define VERSION        VER2(0,1)
+#include <acess.h>
+#include <modules.h>
+#include <fs_devfs.h>
+#include "include/mouse_int.h"
+
+// === PROTOTYPES ===
+ int   Mouse_Install(char **Arguments);
+ int   Mouse_Cleanup(void);
+// - "User" side
+ int   Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
+tVFS_Node      *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name);
+ int   Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data);
+size_t Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Data);
+// - Device Side
+void   Mouse_HandleEvent(Uint32 ButtonState, int *AxisDeltas, int *AxisValues);
+
+// === GLOBALS ===
+tVFS_NodeType  gMouse_RootNodeType = {
+       .ReadDir = Mouse_Root_ReadDir,
+       .FindDir = Mouse_Root_FindDir
+};
+tVFS_NodeType  gMouse_DevNodeType = {
+       .IOCtl = Mouse_Dev_IOCtl,
+       .Read = Mouse_Dev_Read
+};
+tDevFS_Driver  gMouse_DevInfo = {
+       NULL, "Mouse",
+       { .Flags = VFS_FFLAG_DIRECTORY, .Type = &gMouse_RootNodeType, .Size = 1 }
+};
+tPointer       gMouse_Pointer;
+
+// === CODE ===
+/**
+ * \brief Initialise the keyboard driver
+ */
+int Mouse_Install(char **Arguments)
+{
+       /// - Register with DevFS
+       DevFS_AddDevice( &gMouse_DevInfo );
+
+       gMouse_Pointer.Node.Type = &gMouse_DevNodeType;
+       gMouse_Pointer.Node.ImplPtr = &gMouse_Pointer;
+       gMouse_Pointer.FileHeader = (void*)gMouse_Pointer.FileData;
+       gMouse_Pointer.Axies = (void*)( gMouse_Pointer.FileHeader + 1 );
+       gMouse_Pointer.Buttons = (void*)( gMouse_Pointer.Axies + MAX_AXIES );
+       gMouse_Pointer.FileHeader->NAxies = MAX_AXIES;
+       gMouse_Pointer.FileHeader->NButtons = MAX_BUTTONS;
+
+       return 0;
+}
+
+/**
+ * \brief Pre-unload cleanup function
+ */
+int Mouse_Cleanup(void)
+{
+       return 0;
+}
+
+// --- VFS Interface ---
+int Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
+{
+       if( Pos != 0 )
+               return -EINVAL;
+       strcpy(Dest, "system");
+       return 0;
+}
+
+tVFS_Node *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name)
+{
+       if( strcmp(Name, "system") != 0 )       return NULL;
+       return &gMouse_Pointer.Node;
+}
+
+static const char *csaIOCTL_NAMES[] = {DRV_IOCTLNAMES, DRV_JOY_IOCTLNAMES, NULL};
+/**
+ * \brief IOCtl handler for the mouse
+ */
+int Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data)
+{
+       tJoystick_NumValue      *numval = Data;
+       tPointer        *ptr = Node->ImplPtr;
+       switch(ID)
+       {
+       BASE_IOCTLS(DRV_TYPE_MOUSE, "Mouse", VERSION, csaIOCTL_NAMES);
+
+       case JOY_IOCTL_GETSETAXISLIMIT:
+               if( !numval || !CheckMem(numval, sizeof(*numval)) )
+                       return -1;
+               LOG("GetSetAxisLimit %i = %i", numval->Num, numval->Value);
+               if(numval->Num < 0 || numval->Num >= ptr->FileHeader->NAxies)
+                       return 0;
+               if(numval->Value != -1)
+                       ptr->AxisLimits[numval->Num] = numval->Value;
+               return ptr->AxisLimits[numval->Num];
+
+       case JOY_IOCTL_GETSETAXISPOSITION:
+               if( !numval || !CheckMem(numval, sizeof(*numval)) )
+                       return -1;
+               if(numval->Num < 0 || numval->Num >= ptr->FileHeader->NAxies)
+                       return 0;
+               if(numval->Value != -1)
+                       ptr->Axies[numval->Num].CursorPos = numval->Value;
+               return ptr->Axies[numval->Num].CursorPos;
+       }
+       return -1;
+}
+
+/**
+ * \brief Read from a device
+ */
+size_t Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Data)
+{
+       tPointer *ptr = Node->ImplPtr;
+        int    n_buttons = ptr->FileHeader->NButtons;
+        int    n_axies = ptr->FileHeader->NAxies;
+
+       ENTER("pNode iLength pData", Node, Length, Data);
+
+       // TODO: Locking (Acquire)
+
+       Length = MIN(
+               Length, 
+               sizeof(tJoystick_FileHeader) + n_axies*sizeof(tJoystick_Axis) + n_buttons
+               );
+
+       // Mark as checked
+       VFS_MarkAvaliable( Node, 0 );
+
+       memcpy( Data, ptr->FileData, Length );
+
+       // TODO: Locking (Release)
+
+       LEAVE('i', Length);
+       return Length;
+}
+
+// --- Device Interface ---
+/*
+ * Handle a mouse event (movement or button press/release)
+ * - See Input/Mouse/include/mouse.h
+ */
+void Mouse_HandleEvent(Uint32 ButtonState, int *AxisDeltas, int *AxisValues)
+{
+       tPointer *ptr = &gMouse_Pointer;
+       
+       ENTER("pHandle xButtonState pAxisDeltas", Handle, ButtonState, AxisDeltas);
+
+       // Update cursor position
+       for( int i = 0; i < 2; i ++ )
+       {
+               ptr->Axies[i].CursorPos = AxisValues[i];
+               ptr->Axies[i].CurValue = AxisDeltas ? AxisDeltas[i] : 0;
+       }
+       for( int i = 0; i < 5; i ++ )
+               ptr->Buttons[i] = ButtonState & (1 << i) ? 255 : 0;
+
+       VFS_MarkAvaliable( &ptr->Node, 1 );
+       LEAVE('-');
+}
+
index 78f7fa1..45806e2 100644 (file)
@@ -9,17 +9,24 @@
 #include <string.h>
 #include <SDL/SDL.h>
 #ifdef __WIN32__
+# define _WIN32_WINNT 0x0501
 # include <windows.h>
-# include <winsock.h>
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# define close(fd)     closesocket(fd)
+typedef int    socklen_t;
 #else
 # include <unistd.h>
 # include <sys/socket.h>
 # include <netinet/in.h>
+# include <netdb.h>    // getaddrinfo
 #endif
+#define DONT_INCLUDE_SYSCALL_NAMES
 #include "../syscalls.h"
-//#include <debug.h>
+#include <logdebug.h>  // acess but std
+#include <errno.h>
 
-#define        USE_TCP 0
+#define        USE_TCP 1
 #define MAX_CLIENTS    16
 
 // === TYPES ===
@@ -27,6 +34,7 @@ typedef struct {
         int    ClientID;
        SDL_Thread      *WorkerThread;
        #if USE_TCP
+        int    Socket;
        #else
        tRequestHeader  *CurrentRequest;
        struct sockaddr_in      ClientAddr;
@@ -39,9 +47,8 @@ typedef struct {
 extern tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength);
 extern int     Threads_CreateRootProcess(void);
 extern void    Threads_SetThread(int TID);
-// HACK: Should have these in a header
-extern void    Log_Debug(const char *Subsys, const char *Message, ...);
-extern void    Log_Notice(const char *Subsys, const char *Message, ...);
+extern void    *Threads_GetThread(int TID);
+extern void    Threads_PostEvent(void *Thread, uint32_t Event);
 
 // === PROTOTYPES ===
 tClient        *Server_GetClient(int ClientID);
@@ -102,12 +109,20 @@ tClient *Server_GetClient(int ClientID)
        
        // Allocate a thread for the process
        ret->ClientID = ClientID;
+       #if USE_TCP
+       ret->Socket = 0;
+       #else
        ret->CurrentRequest = NULL;
+       #endif
                
        if( !ret->WorkerThread ) {
+               #if USE_TCP
+               #else
                ret->WaitFlag = SDL_CreateCond();
                ret->Mutex = SDL_CreateMutex();
                SDL_mutexP( ret->Mutex );
+               #endif
+               Log_Debug("Server", "Creating worker for %p", ret);
                ret->WorkerThread = SDL_CreateThread( Server_WorkerThread, ret );
        }
        
@@ -117,19 +132,142 @@ tClient *Server_GetClient(int ClientID)
 int Server_WorkerThread(void *ClientPtr)
 {
        tClient *Client = ClientPtr;
+
+       Log_Debug("Server", "Worker %p", ClientPtr);    
+
+       #if USE_TCP
+       while( *((volatile typeof(Client->Socket)*)&Client->Socket) == 0 )
+               ;
+       Threads_SetThread( Client->ClientID );
+       
+       while( Client->ClientID != -1 )
+       {
+               fd_set  fds;
+                int    nfd = Client->Socket+1;
+               FD_ZERO(&fds);
+               FD_SET(Client->Socket, &fds);
+               
+               int rv = select(nfd, &fds, NULL, NULL, NULL);   // TODO: Timeouts?
+               if(rv < 0) {
+                       perror("select");
+                       continue ;
+               }
+//             Log_Debug("Server", "%p: rv=%i", Client, rv);           
+
+               if( FD_ISSET(Client->Socket, &fds) )
+               {
+                       const int       ciMaxParamCount = 6;
+                       char    lbuf[sizeof(tRequestHeader) + ciMaxParamCount*sizeof(tRequestValue)];
+                       tRequestHeader  *hdr = (void*)lbuf;
+                       size_t  len = recv(Client->Socket, (void*)hdr, sizeof(*hdr), 0);
+//                     Log_Debug("Server", "%i bytes of header", len);
+                       if( len == 0 ) {
+                               Log_Notice("Server", "Zero RX on %i (worker %p)", Client->Socket, Client);
+                               break;
+                       }
+                       if( len == -1 ) {
+                               perror("recv header");
+//                             Log_Warning("Server", "recv() error - %s", strerror(errno));
+                               break;
+                       }
+                       if( len != sizeof(*hdr) ) {
+                               // Oops?
+                               Log_Warning("Server", "FD%i bad sized (%i != exp %i)",
+                                       Client->Socket, len, sizeof(*hdr));
+                               continue ;
+                       }
+
+                       if( hdr->NParams > ciMaxParamCount ) {
+                               // Oops.
+                               Log_Warning("Server", "FD%i too many params (%i > max %i)",
+                                       Client->Socket, hdr->NParams, ciMaxParamCount);
+                               break ;
+                       }
+
+                       if( hdr->NParams > 0 )
+                       {
+                               len = recv(Client->Socket, (void*)hdr->Params, hdr->NParams*sizeof(tRequestValue), 0);
+//                             Log_Debug("Server", "%i bytes of params", len);
+                               if( len != hdr->NParams*sizeof(tRequestValue) ) {
+                                       // Oops.
+                                       perror("recv params");
+                                       Log_Warning("Sever", "Recieving params failed");
+                                       break ;
+                               }
+                       }
+                       else
+                       {
+//                             Log_Debug("Server", "No params?");
+                       }
+
+                       // Get buffer size
+                       size_t  hdrsize = sizeof(tRequestHeader) + hdr->NParams*sizeof(tRequestValue);
+                       size_t  bufsize = hdrsize;
+                        int    i;
+                       for( i = 0; i < hdr->NParams; i ++ )
+                       {
+                               if( hdr->Params[i].Flags & ARG_FLAG_ZEROED )
+                                       ;
+                               else {
+                                       bufsize += hdr->Params[i].Length;
+                               }
+                       }
+
+                       // Allocate full buffer
+                       hdr = malloc(bufsize);
+                       memcpy(hdr, lbuf, hdrsize);
+                       if( bufsize > hdrsize )
+                       {
+                               size_t  rem = bufsize - hdrsize;
+                               char    *ptr = (void*)( hdr->Params + hdr->NParams );
+                               while( rem )
+                               {
+                                       len = recv(Client->Socket, ptr, rem, 0);
+//                                     Log_Debug("Server", "%i bytes of data", len);
+                                       if( len == -1 ) {
+                                               // Oops?
+                                               perror("recv data");
+                                               Log_Warning("Sever", "Recieving data failed");
+                                               break ;
+                                       }
+                                       rem -= len;
+                                       ptr += len;
+                               }
+                               if( rem ) {
+                                       break;
+                               }
+                       }
+//                     else
+//                             Log_Debug("Server", "no data");
+
+                        int    retlen;
+                       tRequestHeader  *retHeader;
+                       retHeader = SyscallRecieve(hdr, &retlen);
+                       if( !retHeader ) {
+                               // Some sort of error
+                               Log_Warning("Server", "SyscallRecieve failed?");
+                               continue ;
+                       }
+                       
+                       send(Client->Socket, (void*)retHeader, retlen, 0); 
+
+                       // Clean up
+                       free(hdr);
+               }
+       }
+       #else
        tRequestHeader  *retHeader;
        tRequestHeader  errorHeader;
         int    retSize = 0;
         int    sentSize;
         int    cur_client_id = 0;
-       
-       #if USE_TCP
-       #else
-       for( ;; )
+       while( Client->ClientID != -1 )
        {
                // Wait for something to do
-               while( Client->CurrentRequest == NULL )
+               if( Client->CurrentRequest == NULL )
                        SDL_CondWait(Client->WaitFlag, Client->Mutex);
+               if( Client->CurrentRequest == NULL )
+                       continue ;
                
 //             Log_Debug("AcessSrv", "Worker got message %p", Client->CurrentRequest);
                
@@ -187,6 +325,8 @@ int Server_WorkerThread(void *ClientPtr)
                        free( retHeader );
        }
        #endif
+       Log_Notice("Server", "Terminated Worker %p", ClientPtr);        
+       return 0;
 }
 
 int SyscallServer(void)
@@ -247,24 +387,94 @@ int SyscallServer(void)
        return 0;
 }
 
+int Server_Shutdown(void)
+{
+       close(gSocket);
+       for( int i = 0; i < MAX_CLIENTS; i ++ )
+       {
+               if( gaServer_Clients[i].ClientID == 0 )
+                       continue ;
+               Threads_PostEvent( Threads_GetThread(gaServer_Clients[i].ClientID), 0 );
+               gaServer_Clients[i].ClientID = -1;
+               #if USE_TCP
+               close(gaServer_Clients[i].Socket);
+               #else
+               SDL_CondSignal(gaServer_Clients[i].WaitFlag);
+               #endif
+       }
+       return 0;
+}
+
 int Server_ListenThread(void *Unused)
 {      
        // Wait for something to do :)
        for( ;; )
        {
                #if USE_TCP
-               struct sockaddr_in      client;
-               uint    clientSize = sizeof(client);
-                int    clientSock = accept(gSocket, (struct sockaddr*)&client, &clientSize);
+               struct sockaddr_in      clientaddr;
+               socklen_t       clientSize = sizeof(clientaddr);
+                int    clientSock = accept(gSocket, (struct sockaddr*)&clientaddr, &clientSize);
                if( clientSock < 0 ) {
                        perror("SyscallServer - accept");
                        break ;
                }
+
+               char    addrstr[4*8+8+1];
+               getnameinfo((struct sockaddr*)&clientaddr, sizeof(clientaddr),
+                       addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
+               Log_Debug("Server", "Client connection %s:%i", addrstr, ntohs(clientaddr.sin_port));
                
-               Log("Client connection %x:%i\n",
-                       ntohl(client.sin_addr), ntohs(client.sin_port)
-                       );
+               // Perform auth
+               size_t  len;
+               tRequestAuthHdr authhdr;
+               len = recv(clientSock, (void*)&authhdr, sizeof(authhdr), 0);
+               if( len != sizeof(authhdr) ) {
+                       // Some form of error?
+                       Log_Warning("Server", "Client auth block bad size (%i != exp %i)",
+                               len, sizeof(authhdr));
+                       close(clientSock);
+                       continue ;
+               }
+               
+               Log_Debug("Server", "Client assumed PID %i", authhdr.pid);
+
+               tClient *client;
+               if( authhdr.pid == 0 ) {
+                       // Allocate PID and client structure/thread
+                       client = Server_GetClient(0);
+                       client->Socket = clientSock;
+                       authhdr.pid = client->ClientID;
+               }
+               else {
+                       // Get client structure and make sure it's unused
+                       // - Auth token / verifcation?
+                       client = Server_GetClient(authhdr.pid);
+                       if( !client ) {
+                               Log_Warning("Server", "Can't allocate a client struct for %s:%i",
+                                       addrstr, clientaddr.sin_port);
+                               close(clientSock);
+                               continue ;
+                       }
+                       if( client->Socket != 0 ) {
+                               Log_Warning("Server", "Client (%i)%p owned by FD%i but %s:%i tried to use it",
+                                       authhdr.pid, client, addrstr, clientaddr.sin_port);
+                               close(clientSock);
+                               continue;
+                       }
+                       else {
+                               client->Socket = clientSock;
+                       }
+               }
+               Log_Debug("Server", "Client given PID %i - info %p", authhdr.pid, client);
                
+               len = send(clientSock, (void*)&authhdr, sizeof(authhdr), 0);
+               if( len != sizeof(authhdr) ) {
+                       // Ok, this is an error
+                       perror("Sending auth reply");
+               }
+
+               // All done, client thread should be watching now               
+
                #else
                char    data[BUFSIZ];
                tRequestHeader  *req = (void*)data;
index 9b9fda4..d14a1d9 100644 (file)
@@ -8,10 +8,14 @@
 #include <acess.h>
 #include <threads.h>
 #include <events.h>
+#if DEBUG == 0
+# define DONT_INCLUDE_SYSCALL_NAMES
+#endif
 #include "../syscalls.h"
 
 // === IMPORTS ===
 extern int     Threads_Fork(void);     // AcessNative only function
+extern int     Threads_Spawn(int nFD, int FDs[], const void *info);
 
 // === TYPES ===
 typedef int    (*tSyscallHandler)(Uint *Errno, const char *Format, void *Args, int *Sizes);
@@ -137,7 +141,7 @@ SYSCALL2(Syscall_ReadDir, "id", int, char *,
                return -1;
        return VFS_ReadDir(a0, a1);
 );
-SYSCALL6(Syscall_select, "iddddi", int, fd_set *, fd_set *, fd_set *, time_t *, unsigned int,
+SYSCALL6(Syscall_select, "iddddi", int, fd_set *, fd_set *, fd_set *, tTime *, unsigned int,
        return VFS_Select(a0, a1, a2, a3, a4, a5, 0);
 );
 SYSCALL3(Syscall_OpenChild, "isi", int, const char *, int,
@@ -190,6 +194,13 @@ SYSCALL1(Syscall_AN_Fork, "d", int *,
        return *a0;
 );
 
+SYSCALL3(Syscall_AN_Spawn, "ddd", int *, int *, void *,
+       if(Sizes[0] < sizeof(int))
+               return -1;
+       *a0 = Threads_Spawn(Sizes[1] / sizeof(int), a1, a2);
+       return *a0;
+);
+
 SYSCALL2(Syscall_SendMessage, "id", int, void *,
        return Proc_SendMessage(a0, Sizes[1], a1);
 );
@@ -203,11 +214,11 @@ SYSCALL2(Syscall_GetMessage, "dd", uint32_t *, void *,
        Uint    tmp;
         int    rv;
        if( a0 ) {
-               rv = Proc_GetMessage(&tmp, a1);
+               rv = Proc_GetMessage(&tmp, Sizes[1], a1);
                *a0 = tmp;
        }
        else
-               rv = Proc_GetMessage(NULL, a1);
+               rv = Proc_GetMessage(NULL, Sizes[1], a1);
        return rv;
 );
 
@@ -244,6 +255,7 @@ const tSyscallHandler       caSyscalls[] = {
 
        Syscall_Sleep,
        Syscall_AN_Fork,
+       Syscall_AN_Spawn,
 
        Syscall_SendMessage,
        Syscall_GetMessage,
@@ -384,11 +396,12 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
        }
        
        // Allocate the return
-       ret = malloc(sizeof(tRequestHeader) + retValueCount * sizeof(tRequestValue)
-               + retDataLen);
+       size_t  msglen = sizeof(tRequestHeader) + retValueCount * sizeof(tRequestValue) + retDataLen;
+       ret = malloc(msglen);
        ret->ClientID = Request->ClientID;
        ret->CallID = Request->CallID;
        ret->NParams = retValueCount;
+       ret->MessageLength = msglen;
        inData = (char*)&ret->Params[ ret->NParams ];
        
        // Static Uint64 return value
@@ -398,7 +411,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
        *(Uint64*)inData = retVal;
        inData += sizeof(Uint64);
        
-       Log_Debug("Syscalls", "Return 0x%llx", retVal);
+       //Log_Debug("Syscalls", "Return 0x%llx", retVal);
        
        retValueCount = 1;
        for( i = 0; i < Request->NParams; i ++ )
index c390a03..661d584 100644 (file)
@@ -5,43 +5,26 @@
  * threads.c
  * - Thread and process handling
  */
-#define _SIGNAL_H_     // Stop the acess signal.h being used
-#define _HEAP_H_       // Stop heap.h being imported (collides with stdlib heap)
-#define _VFS_EXT_H     // Stop vfs_ext.h being imported (collides with fd_set)
 
-#define off_t  _acess_off_t
 #include <arch.h>
-#undef NULL    // Remove acess definition
 #include <acess.h>
 #include <mutex.h>
-#include <semaphore.h>
+#include "../../KernelLand/Kernel/include/semaphore.h"
+typedef signed long long int   time_t;
+#include "../../Usermode/Libraries/ld-acess.so_src/include_exp/acess/syscall_types.h"
+#include <rwlock.h>
 #include <events.h>
 #include <threads_int.h>
-
-#undef CLONE_VM        // Such a hack
-#undef off_t   
-
-// - Native headers
-#include <unistd.h>
-#include <sys/types.h>
-#include <stdint.h>
-#include "/usr/include/signal.h"
-#include <SDL/SDL.h>
+#include <limits.h>
+#include "include/threads_glue.h"
 
 #define THREAD_EVENT_WAKEUP    0x80000000
 
 // === IMPORTS ===
-void   VFS_CloneHandleList(int PID);
+extern void    VFS_CloneHandleList(int PID);
+extern void    VFS_CloneHandlesFromList(int PID, int nFD, int FDs[]);
 
 // === STRUCTURES ===
-#if 0
-typedef struct sState
-{
-       void    *CurState;
-       Uint    SP, BP, IP;
-}      tState;
-#endif
-
 // === PROTOTYPES ===
  int   Threads_Wake(tThread *Thread);
 
@@ -118,7 +101,7 @@ tThread *Threads_CloneTCB(tThread *TemplateThread)
        ret->TID = giThreads_NextThreadID ++;
        
        ret->ThreadName = strdup(TemplateThread->ThreadName);
-       ret->EventSem = SDL_CreateSemaphore(0);
+       Threads_Glue_SemInit( &ret->EventSem, 0 );
        
        ret->WaitingThreads = NULL;
        ret->WaitingThreadsEnd = NULL;
@@ -219,7 +202,7 @@ tTID Threads_WaitTID(int TID, int *Status)
 void Threads_Sleep(void)
 {
        // TODO: Add to a sleeping queue
-       pause();
+       //pause();
 }
 
 void Threads_Yield(void)
@@ -240,7 +223,7 @@ void Threads_Exit(int TID, int Status)
        {
                // Wait for the thread to be waited upon
                while( gpCurrentThread->WaitingThreads == NULL )
-                       SDL_Delay(10);
+                       Threads_Glue_Yield();
        }
        #endif
        
@@ -251,7 +234,7 @@ void Threads_Exit(int TID, int Status)
                Threads_Wake(toWake);
                
                while(gpCurrentThread->WaitingThreads == toWake)
-                       SDL_Delay(10);
+                       Threads_Glue_Yield();
        }
 }
 
@@ -284,29 +267,46 @@ int Threads_Fork(void)
 {
        tThread *thread = Threads_CloneTCB(gpCurrentThread);
        thread->PID = thread->TID;
+
        // Duplicate the VFS handles (and nodes) from vfs_handle.c
-       
        VFS_CloneHandleList(thread->PID);
        
        return thread->PID;
 }
 
+int Threads_Spawn(int nFD, int FDs[], struct s_sys_spawninfo *info)
+{
+       tThread *thread = Threads_CloneTCB(gpCurrentThread);
+       thread->PID = thread->TID;
+       if( info )
+       {
+               // TODO: PGID?
+               //if( info->flags & SPAWNFLAG_NEWPGID )
+               //      thread->PGID = thread->PID;
+               if( info->gid && thread->UID == 0 )
+                       thread->GID = info->gid;
+               if( info->uid && thread->UID == 0 )     // last because ->UID is used above
+                       thread->UID = info->uid;
+       }
+       
+       VFS_CloneHandlesFromList(thread->PID, nFD, FDs);
+
+       Log_Debug("Threads", "_spawn: %i", thread->PID);
+       return thread->PID;
+}
+
 // --------------------------------------------------------------------
 // Mutexes 
 // --------------------------------------------------------------------
 int Mutex_Acquire(tMutex *Mutex)
 {
-       if(!Mutex->Protector.IsValid) {
-               pthread_mutex_init( &Mutex->Protector.Mutex, NULL );
-               Mutex->Protector.IsValid = 1;
-       }
-       pthread_mutex_lock( &Mutex->Protector.Mutex );
+       Threads_Glue_AcquireMutex(&Mutex->Protector.Mutex);
        return 0;
 }
 
 void Mutex_Release(tMutex *Mutex)
 {
-       pthread_mutex_unlock( &Mutex->Protector.Mutex );
+       Threads_Glue_ReleaseMutex(&Mutex->Protector.Mutex);
 }
 
 // --------------------------------------------------------------------
@@ -316,21 +316,17 @@ void Semaphore_Init(tSemaphore *Sem, int InitValue, int MaxValue, const char *Mo
 {
        memset(Sem, 0, sizeof(tSemaphore));
        // HACK: Use `Sem->Protector` as space for the semaphore pointer
-       *(void**)(&Sem->Protector) = SDL_CreateSemaphore(InitValue);
+       Threads_Glue_SemInit( &Sem->Protector.Mutex, InitValue );
 }
 
 int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
 {
-       SDL_SemWait( *(void**)(&Sem->Protector) );
-       return 1;
+       return Threads_Glue_SemWait( Sem->Protector.Mutex, MaxToTake );
 }
 
 int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
 {
-        int    i;
-       for( i = 0; i < AmmountToAdd; i ++ )
-               SDL_SemPost( *(void**)(&Sem->Protector) );
-       return AmmountToAdd;
+       return Threads_Glue_SemSignal( Sem->Protector.Mutex, AmmountToAdd );
 }
 
 // --------------------------------------------------------------------
@@ -340,27 +336,33 @@ Uint32 Threads_WaitEvents(Uint32 Mask)
 {
        Uint32  rv;
 
-       Log_Debug("Threads", "Mask = %x, ->Events = %x", Mask, gpCurrentThread->Events);        
+       //Log_Debug("Threads", "Mask = %x, ->Events = %x", Mask, gpCurrentThread->Events);      
 
        gpCurrentThread->WaitMask = Mask;
        if( !(gpCurrentThread->Events & Mask) )
        {
-               SDL_SemWait( gpCurrentThread->EventSem );
+               if( Threads_Glue_SemWait(gpCurrentThread->EventSem, INT_MAX) == -1 ) {
+                       Log_Warning("Threads", "Wait on eventsem of %p, %p failed",
+                               gpCurrentThread, gpCurrentThread->EventSem);
+               }
+               //Log_Debug("Threads", "Woken from nap (%i here)", SDL_SemValue(gpCurrentThread->EventSem));
        }
        rv = gpCurrentThread->Events & Mask;
        gpCurrentThread->Events &= ~Mask;
        gpCurrentThread->WaitMask = -1;
-       
+
+       //Log_Debug("Threads", "- rv = %x", rv);
+
        return rv;
 }
 
 void Threads_PostEvent(tThread *Thread, Uint32 Events)
 {
        Thread->Events |= Events;
-       Log_Debug("Threads", "Trigger event %x (->Events = %p)", Events, Thread->Events);
-       
-       if( Thread->WaitMask & Events ) {
-               SDL_SemPost( Thread->EventSem );
+//     Log_Debug("Threads", "Trigger event %x (->Events = %p) on %p", Events, Thread->Events, Thread);
+
+       if( Events == 0 || Thread->WaitMask & Events ) {
+               Threads_Glue_SemSignal( Thread->EventSem, 1 );
 //             Log_Debug("Threads", "Waking %p(%i %s)", Thread, Thread->TID, Thread->ThreadName);
        }
 }
diff --git a/AcessNative/acesskernel_src/threads_glue.c b/AcessNative/acesskernel_src/threads_glue.c
new file mode 100644 (file)
index 0000000..ba407b8
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Acess2 Native Kernel
+ * - Acess kernel emulation on another OS using SDL and UDP
+ *
+ * threads.c
+ * - Thread and process handling
+ */
+#include "include/threads_glue.h"
+
+#define _ACESS_H
+typedef void   **tShortSpinlock;
+#include <rwlock.h>
+
+// - Native headers
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdint.h>
+//#include "/usr/include/signal.h"
+#include <SDL/SDL.h>
+#include <pthread.h>
+#include <assert.h>
+
+#include <logdebug.h>  // Kernel land, but uses standards
+
+// === CODE ===
+void Threads_Glue_Yield(void)
+{
+       SDL_Delay(10);
+}
+
+void Threads_Glue_AcquireMutex(void **Lock)
+{
+       if(!*Lock) {
+               *Lock = malloc( sizeof(pthread_mutex_t) );
+               pthread_mutex_init( *Lock, NULL );
+       }
+       pthread_mutex_lock( *Lock );
+}
+
+void Threads_Glue_ReleaseMutex(void **Lock)
+{
+       pthread_mutex_unlock( *Lock );
+}
+
+void Threads_Glue_SemInit(void **Ptr, int Val)
+{
+       *Ptr = SDL_CreateSemaphore(Val);
+       if( !*Ptr ) {
+               Log_Warning("Threads", "Semaphore creation failed - %s", SDL_GetError());
+       }
+}
+
+int Threads_Glue_SemWait(void *Ptr, int Max)
+{
+        int    have = 0;
+       assert(Ptr);
+       do {
+               if( SDL_SemWait( Ptr ) == -1 ) {
+                       return -1;
+               }
+               have ++;
+       } while( SDL_SemValue(Ptr) && have < Max );
+       return have;
+}
+
+int Threads_Glue_SemSignal( void *Ptr, int AmmountToAdd )
+{
+        int    i;
+       for( i = 0; i < AmmountToAdd; i ++ )
+               SDL_SemPost( Ptr );
+       return AmmountToAdd;
+}
+
+// --------------------------------------------------------------------
+// Event handling
+// --------------------------------------------------------------------
+int RWLock_AcquireRead(tRWLock *Lock)
+{
+       if( !Lock->ReaderWaiting ) {
+               Lock->ReaderWaiting = malloc(sizeof(pthread_rwlock_t));
+               pthread_rwlock_init( (void*)Lock->ReaderWaiting, 0 );
+       }
+       pthread_rwlock_rdlock( (void*)Lock->ReaderWaiting );
+       return 0;
+}
+int RWLock_AcquireWrite(tRWLock *Lock)
+{
+       if( !Lock->ReaderWaiting ) {
+               Lock->ReaderWaiting = malloc(sizeof(pthread_rwlock_t));
+               pthread_rwlock_init( (void*)Lock->ReaderWaiting, 0 );
+       }
+       pthread_rwlock_wrlock( (void*)Lock->ReaderWaiting );
+       return 0;
+}
+void RWLock_Release(tRWLock *Lock)
+{
+       pthread_rwlock_unlock( (void*)Lock->ReaderWaiting );
+}
+
index 80241da..3c43cc5 100644 (file)
@@ -20,5 +20,6 @@ extern void   UI_Redraw(void);
 
 typedef void (*tUI_KeybardCallback)(Uint32 Key);
 extern tUI_KeybardCallback     gUI_KeyboardCallback;
+extern void    Mouse_HandleEvent(Uint32 ButtonState, int *AxisDeltas, int *AxisValues);
 
 #endif
index 520ac00..7e97cbe 100644 (file)
@@ -57,7 +57,7 @@ int UI_Initialise(int MaxWidth, int MaxHeight)
        return 0;
 }
 
-Uint32 UI_GetAcessKeyFromSDL(SDLKey Sym, Uint16 Unicode)
+Uint32 UI_GetAcessKeyFromSDL(SDLKey Sym)
 {
        Uint8   *keystate = SDL_GetKeyState(NULL);
         int    shiftState = 0;
@@ -70,48 +70,61 @@ Uint32 UI_GetAcessKeyFromSDL(SDLKey Sym, Uint16 Unicode)
        if( gUI_Keymap[shiftState][Sym] )
                return gUI_Keymap[shiftState][Sym];
 
-       // Enter key on acess returns \n, but SDL returns \r
-       if( Sym == SDLK_RETURN )
-               Unicode = '\n';
-       
-       // How nice of you, a unicode value
-       if( Unicode )
-       {
-               ret = Unicode;
-       }
-       // Ok, we need to do work :(
-       else
+       switch(Sym)
        {
-               switch(Sym)
-               {
-               case SDLK_UP:   ret = KEY_UP;   break;
-               case SDLK_DOWN: ret = KEY_DOWN; break;
-               case SDLK_LEFT: ret = KEY_LEFT; break;
-               case SDLK_RIGHT:ret = KEY_RIGHT;break;
-               case SDLK_CAPSLOCK:     ret = KEY_CAPSLOCK;     break;
-               case SDLK_F1:   ret = KEY_F1;   break;
-               case SDLK_F2:   ret = KEY_F2;   break;
-               case SDLK_F3:   ret = KEY_F3;   break;
-               case SDLK_F4:   ret = KEY_F4;   break;
-               case SDLK_F5:   ret = KEY_F5;   break;
-               case SDLK_F6:   ret = KEY_F6;   break;
-               case SDLK_F7:   ret = KEY_F7;   break;
-               case SDLK_F8:   ret = KEY_F8;   break;
-               case SDLK_F9:   ret = KEY_F9;   break;
-               case SDLK_F10:  ret = KEY_F10;  break;
-               case SDLK_F11:  ret = KEY_F11;  break;
-               case SDLK_F12:  ret = KEY_F12;  break;
-               case SDLK_RETURN:       ret = '\n';     break;
-               default:
-                       printf("Unhandled key code %i\n", Sym);
-                       break;
-               }
+       case SDLK_a ... SDLK_z:
+               ret = Sym - SDLK_a + KEYSYM_a;
+               break;
+       case SDLK_0 ... SDLK_9:
+               ret = Sym - SDLK_0 + KEYSYM_0;
+               break;
+       case SDLK_CAPSLOCK:     ret = KEYSYM_CAPS;      break;
+       case SDLK_TAB:  ret = KEYSYM_TAB;       break;
+       case SDLK_UP:   ret = KEYSYM_UPARROW;   break;
+       case SDLK_DOWN: ret = KEYSYM_DOWNARROW; break;
+       case SDLK_LEFT: ret = KEYSYM_LEFTARROW; break;
+       case SDLK_RIGHT:ret = KEYSYM_RIGHTARROW;break;
+       case SDLK_F1:   ret = KEYSYM_F1;        break;
+       case SDLK_F2:   ret = KEYSYM_F2;        break;
+       case SDLK_F3:   ret = KEYSYM_F3;        break;
+       case SDLK_F4:   ret = KEYSYM_F4;        break;
+       case SDLK_F5:   ret = KEYSYM_F5;        break;
+       case SDLK_F6:   ret = KEYSYM_F6;        break;
+       case SDLK_F7:   ret = KEYSYM_F7;        break;
+       case SDLK_F8:   ret = KEYSYM_F8;        break;
+       case SDLK_F9:   ret = KEYSYM_F9;        break;
+       case SDLK_F10:  ret = KEYSYM_F10;       break;
+       case SDLK_F11:  ret = KEYSYM_F11;       break;
+       case SDLK_F12:  ret = KEYSYM_F12;       break;
+       case SDLK_RETURN:       ret = KEYSYM_RETURN;    break;
+       case SDLK_LALT:         ret = KEYSYM_LEFTALT;   break;
+       case SDLK_LCTRL:        ret = KEYSYM_LEFTCTRL;  break;
+       case SDLK_LSHIFT:       ret = KEYSYM_LEFTSHIFT; break;
+       case SDLK_LSUPER:       ret = KEYSYM_LEFTGUI;   break;
+       case SDLK_RALT:         ret = KEYSYM_RIGHTALT;  break;
+       case SDLK_RCTRL:        ret = KEYSYM_RIGHTCTRL; break;
+       case SDLK_RSHIFT:       ret = KEYSYM_RIGHTSHIFT;        break;
+       case SDLK_RSUPER:       ret = KEYSYM_RIGHTGUI;  break;
+       default:
+               printf("Unhandled key code %i\n", Sym);
+               break;
        }
        
        gUI_Keymap[shiftState][Sym] = ret;
        return ret;
 }
 
+Uint32 UI_GetButtonBits(Uint8 sdlstate)
+{
+       Uint32  rv = 0;
+       rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_LEFT)    ? (1 << 0) : 0;
+       rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_RIGHT)   ? (1 << 1) : 0;
+       rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_MIDDLE)  ? (1 << 2) : 0;
+       rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_X1)      ? (1 << 3) : 0;
+       rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_X2)      ? (1 << 4) : 0;
+       return rv;
+}
+
 void UI_MainLoop(void)
 {
        SDL_Event       event;
@@ -128,29 +141,41 @@ void UI_MainLoop(void)
                                return ;
                                
                        case SDL_KEYDOWN:
-                               acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym,
-                                       event.key.keysym.unicode);
-                               
+                               acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym);
+                               // Enter key on acess returns \n, but SDL returns \r
+                               if(event.key.keysym.sym == SDLK_RETURN)
+                                       event.key.keysym.unicode = '\n';                                
+
                                if( gUI_KeyboardCallback ) {
-                                       gUI_KeyboardCallback(KEY_ACTION_RAWSYM|event.key.keysym.sym);
-                                       gUI_KeyboardCallback(KEY_ACTION_PRESS|acess_sym);
+                                       gUI_KeyboardCallback(KEY_ACTION_RAWSYM|acess_sym);
+                                       gUI_KeyboardCallback(KEY_ACTION_PRESS|event.key.keysym.unicode);
                                }
                                break;
                        
                        case SDL_KEYUP:
-                               acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym,
-                                       event.key.keysym.unicode);
+                               acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym);
                                
                                if( gUI_KeyboardCallback ) {
-                                       gUI_KeyboardCallback(KEY_ACTION_RAWSYM|event.key.keysym.sym);
-                                       gUI_KeyboardCallback(KEY_ACTION_RELEASE|acess_sym);
+                                       gUI_KeyboardCallback(KEY_ACTION_RAWSYM|acess_sym);
+                                       gUI_KeyboardCallback(KEY_ACTION_RELEASE|0);
                                }
                                break;
 
                        case SDL_USEREVENT:
                                SDL_UpdateRect(gScreen, 0, 0, giUI_Width, giUI_Height);
                                SDL_Flip(gScreen);
-                               break;          
+                               break;
+                       
+                       case SDL_MOUSEMOTION: {
+                               int abs[] = {event.motion.x, event.motion.y};
+                               int delta[] = {event.motion.xrel, event.motion.yrel};
+                               Mouse_HandleEvent(UI_GetButtonBits(SDL_GetMouseState(NULL, NULL)), delta, abs);
+                               break; }
+                       case SDL_MOUSEBUTTONUP:
+                       case SDL_MOUSEBUTTONDOWN: {
+                               int abs[] = {event.button.x, event.button.y};
+                               Mouse_HandleEvent(UI_GetButtonBits(SDL_GetMouseState(NULL, NULL)), NULL, abs);
+                               break; }
        
                        default:
                                break;
index cfe0489..724e76f 100644 (file)
@@ -38,8 +38,8 @@ tUserHandles *VFS_int_GetUserHandles(int PID, int bCreate)
        tUserHandles    *ent, *prev = NULL;
        for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) {
                if( ent->PID == PID ) {
-                       if( bCreate )
-                               Log_Warning("VFS", "Process %i already has a handle list", PID);
+                       //if( bCreate )
+                       //      Log_Warning("VFS", "Process %i already has a handle list", PID);
                        return ent;
                }
                if( ent->PID > PID )    break;
@@ -88,6 +88,40 @@ void VFS_CloneHandleList(int PID)
        }
 }
 
+void VFS_CloneHandlesFromList(int PID, int nFD, int FDs[])
+{
+       tUserHandles    *ent;
+       tUserHandles    *cur;
+        int    i, maxhandles;
+       
+       cur = VFS_int_GetUserHandles(Threads_GetPID(), 0);
+       if(!cur)        return ;        // Don't need to do anything if the current list is empty
+       
+       ent = VFS_int_GetUserHandles(PID, 1);
+       
+       maxhandles = *Threads_GetMaxFD();
+       if( nFD > maxhandles )
+               nFD = maxhandles;
+       for( i = 0; i < nFD; i ++ )
+       {
+               if( FDs[i] >= maxhandles ) {
+                       ent->Handles[i].Node = NULL;
+                       continue ;
+               }
+               memcpy(&ent->Handles[i], &cur->Handles[ FDs[i] ], sizeof(tVFS_Handle));
+       }
+       for( ; i < maxhandles; i ++ )
+               cur->Handles[i].Node = NULL;
+       
+       for( i = 0; i < maxhandles; i ++ )
+       {
+               if(!cur->Handles[i].Node)       continue;
+               
+               if(ent->Handles[i].Node->Type->Reference)
+                       ent->Handles[i].Node->Type->Reference(ent->Handles[i].Node);
+       }
+}
+
 /**
  * \fn tVFS_Handle *VFS_GetHandle(int FD)
  * \brief Gets a pointer to the handle information structure
index 5408b56..da18f48 100644 (file)
@@ -166,10 +166,12 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Bu
                
                LOG("buffer = %p", Buffer);
                
+               Offset /= 4;
                startX = Offset % giUI_Width;
                startY = Offset / giUI_Width;
-               
-               if( Length + startX < giUI_Width )
+               Length /= 4;
+
+               if( startX + Length < giUI_Width )
                {
                        // Single line
                        UI_BlitBitmap(
@@ -177,6 +179,15 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Bu
                                Length, 1,
                                Buffer);
                }
+               else if( startX == 0 )
+               {
+                       int     lines = Length / giUI_Width;
+                       int     rem = Length % giUI_Width;
+                       UI_BlitBitmap(0, startY, giUI_Width, lines, Buffer);
+                       if( rem ) {
+                               UI_BlitBitmap(0, startY + lines, rem, 1, (Uint32*)Buffer + lines*giUI_Width);
+                       }
+               }
                else
                {
                        // First scanline (partial or full)
index af7f8c8..bbaef1d 100644 (file)
@@ -11,10 +11,11 @@ OBJ := $(addprefix obj-$(PLATFORM)/,$(OBJ))
 
 ifeq ($(PLATFORM),win)
        BIN := ../ld-acess.exe
+       LDFLAGS += -lws2_32
 endif
 ifeq ($(PLATFORM),lin)
        BIN := ../ld-acess
-       LINKADDR := 0x200000
+       LINKADDR := 0x70000000
 #      LD += -m elf_i386
 endif
 
@@ -35,7 +36,8 @@ clean:
        $(RM) $(BIN) $(OBJ) $(DEPFILES) obj-$(PLATFORM)/link.ld
 
 $(BIN): obj-$(PLATFORM)/link.ld $(OBJ)
-       $(CC) $(LDFLAGS) -o $@ $(OBJ)
+       $(CC) -o $@ $(OBJ) $(LDFLAGS)
+       objdump -S $@ > [email protected]
 
 obj-$(PLATFORM)/%.o: %.c
        @mkdir -p $(dir $@)
@@ -44,10 +46,16 @@ obj-$(PLATFORM)/%.o: %.c
        @$(CC) -M $(CPPFLAGS) -MT $@ -o [email protected] $<
 
 # Modify the default makefile to put the executable at 1MB instead
-obj-lin/link.ld:
+obj-lin/link.ld: Makefile
        @mkdir -p $(dir $@)
        @echo "Making Linker Script ($@)"
-       $(LD) --verbose | awk '{ if( substr($$0,0,5) == "====="){ bPrint = !bPrint; } else { if(bPrint){ print $$0;} } }' | sed 's/\b0x[048][0-9]*\b/$(LINKADDR)/g' | sed 's/CONSTANT (MAXPAGESIZE)/0x1000/g' > $@
+       $(LD) -g --verbose | awk '{ if( substr($$1,0,5) == "====="){ bPrint = !bPrint; } else { if(bPrint){ print $$0;} } }' | sed 's/\b0x[048][0-9]*\b/$(LINKADDR)/g' | sed 's/CONSTANT (MAXPAGESIZE)/0x1000/g' > $@
+
+# Modify the default makefile to put the executable at 1MB instead
+obj-win/link.ld: Makefile
+       @mkdir -p $(dir $@)
+       @echo "Making Linker Script ($@)"
+       $(LD) -g --verbose | awk '{ if( substr($$1,0,5) == "====="){ bPrint = !bPrint; } else { if(bPrint){ print $$0;} } }' | sed 's/\b0x[048][0-9]*\b/$(LINKADDR)/g' | sed 's/CONSTANT (MAXPAGESIZE)/0x1000/g' > $@
 
 -include $(DEPFILES)
 
index 0d1dee8..63db861 100644 (file)
@@ -14,12 +14,13 @@ extern void *Binary_Load(const char *Path, uintptr_t *EntryPoint);
 extern void    Binary_SetReadyToUse(void *Base);
 
 // HACKS - So this can share the usermode elf.c
-static inline void *GetSymbol(const char*sym, size_t*sz)
+static inline int GetSymbol(const char *sym, void **val, size_t *sz)
 {
        uintptr_t rv;
        if( !Binary_GetSymbol(sym, &rv, sz) )
-               return NULL;
-       return (void*)rv;
+               return 0;
+       *val = (void*)rv;
+       return 1;
 }
 static inline void *LoadLibrary(const char *Name, const char *SearchPath, char **envp)
 {
@@ -30,6 +31,11 @@ static inline void AddLoaded(const char *Path, void *Base)
        Binary_SetReadyToUse(Base);
 }
 
+static inline int SysSetMemFlags(uintptr_t Addr, unsigned int flags, unsigned int mask)
+{
+       return 0;
+}
+
 extern int     AllocateMemory(uintptr_t VirtAddr, size_t ByteCount);
 extern uintptr_t       FindFreeRange(size_t ByteCount, int MaxBits);
 
deleted file mode 120000 (symlink)
index f7aa1a5b6ff39e25d1cf81b521e2518828dbe87f..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../../Usermode/Libraries/ld-acess.so_src/elf.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..3e05f24a5d7b914d7d578cc85699a0abe2c39b4a
--- /dev/null
@@ -0,0 +1,4 @@
+#include "common.h"
+#define _COMMON_H
+// stops real ld-acess.so common.h being included
+#include "../../Usermode/Libraries/ld-acess.so_src/elf.c"
deleted file mode 120000 (symlink)
index a693e8d6ccfe71a918027962550f4f685c52c45a..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../../Usermode/Libraries/ld-acess.so_src/elf32.h
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..dfecd7142298a3eb464973518ba26c4658f0b807
--- /dev/null
@@ -0,0 +1 @@
+#include "../../Usermode/Libraries/ld-acess.so_src/elf32.h"
deleted file mode 120000 (symlink)
index 272e8de0f9d33e57471767607e85e45ed9f6b526..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../../Usermode/Libraries/ld-acess.so_src/elf64.h
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..6edb566a42e95eaddd3bc324be572db6481f58e9
--- /dev/null
@@ -0,0 +1 @@
+#include "../../Usermode/Libraries/ld-acess.so_src/elf64.h"
index 909c24a..d661622 100644 (file)
@@ -8,6 +8,7 @@
 #include <stdio.h>\r
 #include <string.h>\r
 #include <unistd.h>\r
+#include <inttypes.h>  // PRIx64\r
 #include "common.h"\r
 #include "elf32.h"\r
 #include "elf64.h"\r
@@ -288,8 +289,8 @@ void *Elf64Load(int FD, Elf64_Ehdr *hdr)
                addr = phtab[i].p_vaddr + baseDiff;\r
 \r
                if( AllocateMemory( addr, phtab[i].p_memsz ) ) {\r
-                       fprintf(stderr, "Elf_Load: Unable to map memory at %llx (0x%llx bytes)\n",\r
-                               (long long)addr, (long long)phtab[i].p_memsz);\r
+                       fprintf(stderr, "Elf_Load: Unable to map memory at %"PRIx64" (0x%"PRIx64" bytes)\n",\r
+                               (uint64_t)addr, (uint64_t)phtab[i].p_memsz);\r
                        free( phtab );\r
                        return NULL;\r
                }\r
index fc336c8..07662a5 100644 (file)
 #include <stdarg.h>
 #include <stddef.h>
 
-#define DEBUG(v...)    Debug(v)
+#define DEBUG(v...)    do{}while(0)//Debug(v)
 #define PAGE_SIZE      4096
 
 typedef struct sFILE   FILE;
 
-extern FILE    *stderr;
 extern void    exit(int) __attribute__ ((noreturn));
 extern int     printf(const char *, ...);
 extern int     fprintf(FILE *,const char *, ...);
@@ -29,12 +28,17 @@ extern int  giSyscall_ClientID;     // Needed for execve
 extern void    _InitSyscalls(void);
 extern void    _CloseSyscalls(void);
 
+extern void    Warning(const char *Format, ...);
 extern void    Debug(const char *Format, ...);
 extern int     AllocateMemory(uintptr_t VirtAddr, size_t ByteCount);
 
 // === CONSTANTS ===
 #define NATIVE_FILE_MASK       0x40000000
 
+// === GLOBALS ===
+int    acess__errno;
+char   *gsExecutablePath = "./ld-acess";
+
 // === CODE ===
 // --- VFS Calls
 int acess_chdir(const char *Path)
@@ -92,6 +96,7 @@ int acess_seek(int FD, int64_t Ofs, int Dir) {
 uint64_t acess_tell(int FD) {
        if(FD & NATIVE_FILE_MASK)
                return native_tell( FD & (NATIVE_FILE_MASK-1) );
+       DEBUG("tell(0x%x)", FD);
        return _Syscall(SYS_TELL, ">i", FD);
 }
 
@@ -115,8 +120,8 @@ int acess_finfo(int fd, t_sysFInfo *info, int maxacls) {
                );
 }
 
-int acess_readdir(int fd, char *dest) {
-       DEBUG("readdir(%i, %p)", fd, dest);
+int acess_SysReadDir(int fd, char *dest) {
+       DEBUG("SysReadDir(%i, %p)", fd, dest);
        return _Syscall(SYS_READDIR, ">i <d", fd, 256, dest);
 }
 
@@ -139,14 +144,17 @@ int acess_select(int nfds, fd_set *read, fd_set *write, fd_set *error, time_t *t
 
 
 int acess__SysOpenChild(int fd, char *name, int flags) {
+       DEBUG("_SysOpenChild(0x%x, '%s', 0x%x)", fd, name, flags);
        return _Syscall(SYS_OPENCHILD, ">i >s >i", fd, name, flags);
 }
 
 int acess__SysGetACL(int fd, t_sysACL *dest) {
+       DEBUG("%s(0x%x, %p)", __func__, fd, dest);
        return _Syscall(SYS_GETACL, ">i <d", fd, sizeof(t_sysACL), dest);
 }
 
 int acess__SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
+       DEBUG("%s('%s', '%s', '%s', '%s')", __func__, Device, Directory, Type, Options);
        return _Syscall(SYS_MOUNT, ">s >s >s >s", Device, Directory, Type, Options);
 }
 
@@ -169,10 +177,14 @@ uint64_t acess__SysAllocate(uint vaddr)
 // --- Process Management ---
 int acess_clone(int flags, void *stack)
 {
+       #ifdef __WIN32__
+       Warning("Win32 does not support anything like fork(2), cannot emulate");
+       exit(-1);
+       #else
        extern int fork(void);
        if(flags & CLONE_VM) {
                 int    ret, newID, kernel_tid=0;
-               printf("USERSIDE fork()\n");
+               Debug("USERSIDE fork()");
                
                newID = _Syscall(SYS_AN_FORK, "<d", sizeof(int), &kernel_tid);
                ret = fork();
@@ -183,8 +195,8 @@ int acess_clone(int flags, void *stack)
                if(ret == 0)
                {
                        _CloseSyscalls();
-                       _InitSyscalls();
                        giSyscall_ClientID = newID;
+                       _InitSyscalls();
                        return 0;
                }
                
@@ -193,12 +205,13 @@ int acess_clone(int flags, void *stack)
        }
        else
        {
-               fprintf(stderr, "ERROR: Threads currently unsupported\n");
+               Warning("ERROR: Threads currently unsupported\n");
                exit(-1);
        }
+       #endif
 }
 
-int acess_execve(char *path, char **argv, char **envp)
+int acess_execve(char *path, char **argv, const char **envp)
 {
         int    i, argc;
        
@@ -208,7 +221,7 @@ int acess_execve(char *path, char **argv, char **envp)
        for( argc = 0; argv[argc]; argc ++ ) ;
        DEBUG(" acess_execve: argc = %i", argc);
 
-       char    *new_argv[7+argc+1];
+       const char      *new_argv[7+argc+1];
        char    client_id_str[11];
        char    socket_fd_str[11];
        sprintf(client_id_str, "%i", giSyscall_ClientID);
@@ -241,13 +254,49 @@ int acess_execve(char *path, char **argv, char **envp)
        return native_execve("./ld-acess", new_argv, envp);
 }
 
+int acess__SysSpawn(const char *binary, const char **argv, const char **envp, int nfd, int fds[], struct s_sys_spawninfo *info)
+{
+        int    argc = 0;
+       while( argv[argc++] );
+
+       Debug("_SysSpawn('%s', %p (%i), %p, %i, %p, %p)",
+               binary, argv, argc, envp, nfd, fds, info);
+
+        int    kernel_tid;
+        int    newID;
+       newID = _Syscall(SYS_AN_SPAWN, "<d >d >d", sizeof(int), &kernel_tid,
+               nfd*sizeof(int), fds,
+               info ? sizeof(*info) : 0, info);
+
+       const char      *new_argv[5+argc+1];
+        int    new_argc = 0, i;
+       char    client_id_str[11];
+       sprintf(client_id_str, "%i", newID);
+       new_argv[new_argc++] = gsExecutablePath;       // TODO: Get path to ld-acess executable
+       new_argv[new_argc++] = "--key";
+       new_argv[new_argc++] = client_id_str;
+       new_argv[new_argc++] = "--binary";
+       new_argv[new_argc++] = binary;
+       for( i = 0; argv[i]; i ++)
+               new_argv[new_argc++] = argv[i];
+       new_argv[new_argc++] = NULL;
+       
+       // TODO: Debug output?
+       
+       native_spawn(gsExecutablePath, new_argv, envp);
+
+       return kernel_tid;
+}
+
 void acess_sleep(void)
 {
+       DEBUG("%s()", __func__);
        _Syscall(SYS_SLEEP, "");
 }
 
 int acess_waittid(int TID, int *ExitStatus)
 {
+       DEBUG("%s(%i, %p)", __func__, TID, ExitStatus);
        return _Syscall(SYS_WAITTID, ">i <d", TID, sizeof(int), &ExitStatus);
 }
 
@@ -260,23 +309,22 @@ int acess_getgid(void) { return _Syscall(SYS_GETGID, ""); }
 
 int acess_SysSendMessage(int DestTID, int Length, void *Data)
 {
+       DEBUG("%s(%i, 0x%x, %p)", __func__, DestTID, Length, Data);
        return _Syscall(SYS_SENDMSG, ">i >d", DestTID, Length, Data);
 }
 
-int acess_SysGetMessage(int *SourceTID, void *Data)
+int acess_SysGetMessage(int *SourceTID, int BufLen, void *Data)
 {
-//     static __thread int lastlen = 1024;
-       int lastlen;
-
-       lastlen = _Syscall(SYS_GETMSG, "<d <d",
+       DEBUG("%s(%p, %p)", __func__, SourceTID, Data);
+       return _Syscall(SYS_GETMSG, "<d <d",
                SourceTID ? sizeof(uint32_t) : 0, SourceTID,
-               Data ? 1024 : 0, Data
+               BufLen, Data
                );
-       return lastlen;
 }
 
 int acess__SysWaitEvent(int Mask)
 {
+       DEBUG("%s(%x)", __func__, Mask);
        return _Syscall(SYS_WAITEVENT, ">i", Mask);
 }
 
@@ -303,7 +351,7 @@ void acess__exit(int Status)
 
 
 // === Symbol List ===
-#define DEFSYM(name)   {#name, acess_##name}
+#define DEFSYM(name)   {#name, &acess_##name}
 const tSym     caBuiltinSymbols[] = {
        DEFSYM(_exit),
        
@@ -317,7 +365,7 @@ const tSym  caBuiltinSymbols[] = {
        DEFSYM(tell),
        DEFSYM(ioctl),
        DEFSYM(finfo),
-       DEFSYM(readdir),
+       DEFSYM(SysReadDir),
        DEFSYM(select),
        DEFSYM(_SysOpenChild),
        DEFSYM(_SysGetACL),
@@ -326,12 +374,15 @@ const tSym        caBuiltinSymbols[] = {
        
        DEFSYM(clone),
        DEFSYM(execve),
+       DEFSYM(_SysSpawn),
        DEFSYM(sleep),
        
        DEFSYM(waittid),
+       DEFSYM(gettid),
        DEFSYM(setuid),
        DEFSYM(setgid),
-       DEFSYM(gettid),
+       DEFSYM(getuid),
+       DEFSYM(getgid),
 
        DEFSYM(SysSendMessage),
        DEFSYM(SysGetMessage),
@@ -339,7 +390,9 @@ const tSym  caBuiltinSymbols[] = {
        DEFSYM(_SysAllocate),
        DEFSYM(_SysDebug),
        DEFSYM(_SysSetFaultHandler),
-       DEFSYM(_SysWaitEvent)
+       DEFSYM(_SysWaitEvent),
+       
+       DEFSYM(_errno)
 };
 
 const int      ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]);
index feb5bfd..dc319ac 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef _EXPORTS_H_
 #define _EXPORTS_H_
 
+#include <stddef.h>
+
 // Syscall request (used by acess_*)
 extern uint64_t        _Syscall(int SyscallID, const char *ArgTypes, ...);
 
@@ -18,7 +20,8 @@ extern size_t native_write(int FD, const void *Src, size_t Bytes);
 extern int     native_seek(int FD, int64_t Offset, int Dir);
 extern uint64_t        native_tell(int FD);
 
-extern int     native_execve(const char *filename, char *const argv[], char *const envp[]);
+extern int     native_execve(const char *filename, const char *const argv[], const char *const envp[]);
+extern int     native_spawn(const char *filename, const char *const argv[], const char *const envp[]);
 
 // Syscalls used by the linker
 extern int     acess_open(const char *Path, int Flags);
index 0c9b743..e4acbf0 100644 (file)
@@ -137,7 +137,8 @@ void Notice(const char *Format, ...)
 void Debug(const char *Format, ...)
 {
        va_list args;
-       printf("[DEBUG  %i] ", giSyscall_ClientID);
+       printf("[DEBUG ");
+       printf("%2i] ", giSyscall_ClientID);
        va_start(args, Format);
        vprintf(Format, args);
        va_end(args);
index 2e9612c..3f0091d 100644 (file)
@@ -21,9 +21,9 @@ int AllocateMemory(uintptr_t VirtAddr, size_t ByteCount)
        size_t  size = (VirtAddr & 0xFFF) + ByteCount;
        void    *tmp;
        #if __WIN32__
-       tmp = VirtualAlloc(base, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+       tmp = VirtualAlloc((void*)base, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        if( tmp == NULL ) {
-               printf("ERROR: Unable to allocate memory (%i)\n", GetLastError());
+               printf("ERROR: Unable to allocate memory (0x%x)\n", (int)GetLastError());
                return -1;
        }
        #else
@@ -41,9 +41,6 @@ int AllocateMemory(uintptr_t VirtAddr, size_t ByteCount)
 
 uintptr_t FindFreeRange(size_t ByteCount, int MaxBits)
 {
-       #if __WIN32__
-       # error "Windows FindFreeRange() unimplemented"
-       #else
        uintptr_t       base, ofs, size;
        uintptr_t       end = -1;
        static const int        PAGE_SIZE = 0x1000;
@@ -59,15 +56,21 @@ uintptr_t FindFreeRange(size_t ByteCount, int MaxBits)
        for( base = end - size + 1; base > 0; base -= PAGE_SIZE )
        {
                for( ofs = 0; ofs < size; ofs += PAGE_SIZE ) {
+                       #if __WIN32__
+                       MEMORY_BASIC_INFORMATION        info;
+                       VirtualQuery( (void*)(base + ofs), &info, sizeof(info) );
+                       if( info.State != MEM_FREE )
+                               break;
+                       #else
                        if( msync( (void*)(base+ofs), 1, 0) == 0 )
                                break;
                        if( errno != ENOMEM )
                                perror("FindFreeRange, msync");
+                       #endif
                }
                if( ofs >= size ) {
                        return base;
                }
        }
        return 0;
-       #endif
 }
index 2117591..5bcf8cd 100644 (file)
@@ -13,6 +13,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <inttypes.h>
 #ifdef __WIN32__
 # include <windows.h>
 # include <winsock.h>
@@ -24,7 +25,7 @@
 #include "request.h"
 #include "../syscalls.h"
 
-#define USE_TCP        0
+#define USE_TCP        1
 
 // === PROTOTYPES ===
 void   SendData(void *Data, int Length);
@@ -91,7 +92,6 @@ int _InitSyscalls(void)
        if( connect(gSocket, (struct sockaddr *)&gSyscall_ServerAddr, sizeof(struct sockaddr_in)) < 0 )
        {
                fprintf(stderr, "[ERROR -] Cannot connect to server (localhost:%i)\n", SERVER_PORT);
-               fprintf(stderr, "[ERROR -] ", giSyscall_ClientID);
                perror("_InitSyscalls");
                #if __WIN32__
                closesocket(gSocket);
@@ -118,7 +118,20 @@ int _InitSyscalls(void)
        }
        #endif
        
-       #if !USE_TCP
+       #if USE_TCP
+       {
+               tRequestAuthHdr auth;
+               auth.pid = giSyscall_ClientID;
+               auth.key = 0;
+               SendData(&auth, sizeof(auth));
+               int len = ReadData(&auth, sizeof(auth), 5);
+               if( len == 0 ) { 
+                       fprintf(stderr, "Timeout waiting for auth response\n");
+                       exit(-1);
+               }
+               giSyscall_ClientID = auth.pid;
+       }
+       #else
        // Ask server for a client ID
        if( !giSyscall_ClientID )
        {
@@ -177,6 +190,7 @@ int SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize)
                printf("\n");
        }
        #endif
+       #if DEBUG
        {
                 int    i;
                char    *data = (char*)&Request->Params[Request->NParams];
@@ -190,7 +204,7 @@ int SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize)
                                data += sizeof(uint32_t);
                                break;
                        case ARG_TYPE_INT64:
-                               DEBUG_S(" 0x%016llx", *(uint64_t*)data);
+                               DEBUG_S(" 0x%016"PRIx64"", *(uint64_t*)data);
                                data += sizeof(uint64_t);
                                break;
                        case ARG_TYPE_STRING:
@@ -206,6 +220,7 @@ int SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize)
                }
                DEBUG_S("\n");
        }
+       #endif
        
        // Send it off
        SendData(Request, RequestSize);
@@ -213,7 +228,23 @@ int SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize)
        if( Request->CallID == SYS_EXIT )       return 0;
 
        // Wait for a response (no timeout)
-       return ReadData(Request, ResponseSize, 0);
+       ReadData(Request, sizeof(*Request), 0);
+       // TODO: Sanity
+       size_t  recvbytes = sizeof(*Request), expbytes = Request->MessageLength;
+       char    *ptr = (void*)Request->Params;
+       while( recvbytes < expbytes )
+       {
+               size_t  len = ReadData(ptr, expbytes - recvbytes, 1000);
+               if( len == -1 ) {
+                       return -1;
+               }
+               recvbytes += len;
+               ptr += len;
+       }
+       if( recvbytes > expbytes ) {
+               // TODO: Warning
+       }
+       return recvbytes;
 }
 
 void SendData(void *Data, int Length)
@@ -221,7 +252,7 @@ void SendData(void *Data, int Length)
         int    len;
        
        #if USE_TCP
-       len = send(Data, Length, 0);
+       len = send(gSocket, Data, Length, 0);
        #else
        len = sendto(gSocket, Data, Length, 0,
                (struct sockaddr*)&gSyscall_ServerAddr, sizeof(gSyscall_ServerAddr));
@@ -262,7 +293,7 @@ int ReadData(void *Dest, int MaxLength, int Timeout)
        
        if( !ret ) {
                printf("[ERROR %i] Timeout reading from socket\n", giSyscall_ClientID);
-               return 0;       // Timeout
+               return -2;      // Timeout
        }
        
        #if USE_TCP
@@ -276,6 +307,11 @@ int ReadData(void *Dest, int MaxLength, int Timeout)
                perror("ReadData");
                exit(-1);
        }
+       if( ret == 0 ) {
+               fprintf(stderr, "[ERROR %i] Connection closed.\n", giSyscall_ClientID);
+               close(gSocket);
+               exit(0);
+       }
        
        DEBUG_S("%i bytes read from socket\n", ret);
        
index 3c691aa..26f6c44 100644 (file)
@@ -9,9 +9,14 @@
 #include <string.h>
 #include <stddef.h>
 #include <unistd.h>
+#include <spawn.h>     // posix_spawn
 #include "request.h"
 
+#if SYSCALL_TRACE
 #define DEBUG(str, x...)       Debug(str, x)
+#else
+#define DEBUG(...)     do{}while(0)
+#endif
 
 #define        MAX_FPS 16
 
@@ -108,7 +113,7 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
                break;
        // Data (special handling)
        case 'd':
-               len = va_arg(*Args, int);
+               len = va_arg(*Args, size_t);
                str = va_arg(*Args, char*);
                
                // Save the pointer for later
@@ -116,7 +121,7 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
                
                // Create parameter block
                Dest->Type = ARG_TYPE_DATA;
-               Dest->Length = len;
+               Dest->Length = str ? len : 0;
                Dest->Flags = 0;
                if( direction & 2 )
                        Dest->Flags |= ARG_FLAG_RETURN;
@@ -124,7 +129,7 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
                // Has data?
                if( direction & 1 )
                {
-                       if( DataDest )
+                       if( DataDest && str )
                                memcpy(DataDest, str, len);
                }
                else
@@ -206,6 +211,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        req->ClientID = 0;      //< Filled later
        req->CallID = SyscallID;
        req->NParams = paramCount;
+       req->MessageLength = dataLength;
        dataPtr = &req->Params[paramCount];
        
        // Fill `output` and `input`
@@ -253,6 +259,11 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        }
        
        // Write changes to buffers
+       if( req->NParams - 1 != retCount ) {
+               fprintf(stderr, "syscalls.c: Return count inbalance (%i - 1 != exp %i) [Call %i]\n",
+                       req->NParams, retCount, SyscallID);
+               exit(127);
+       }
        retCount = 0;
        for( i = 1; i < req->NParams; i ++ )
        {
@@ -270,7 +281,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        free( req );
        free( retPtrs );
        
-       DEBUG(": %llx", retValue);
+       DEBUG(": %i 0x%llx", SyscallID, retValue);
        
        return retValue;
 }
@@ -318,10 +329,19 @@ uint64_t native_tell(int FD)
        return ftell( gaSyscall_LocalFPs[FD] );
 }
 
-int native_execve(const char *filename, char *const argv[], char *const envp[])
+int native_execve(const char *filename, const char *const argv[], const char *const envp[])
 {
        int ret;
-       ret = execve(filename, argv, envp);
+       ret = execve(filename, (void*)argv, (void*)envp);
        perror("native_execve");
        return ret;
 }
+
+int native_spawn(const char *filename, const char *const argv[], const char *const envp[])
+{
+       int rv;
+       
+       rv = posix_spawn(NULL, filename, NULL, NULL, (void*)argv, (void*)envp);
+       
+       return rv;
+}
index d1a0bdc..21a9cb5 100644 (file)
  * uint8_t     paramData[SUM(params[].Lengh)];
  */
 
+typedef struct {
+       uint32_t        pid;
+       uint32_t        key;
+} tRequestAuthHdr;
+
 typedef struct sRequestValue {
        /// \see eArgumentTypes
        uint16_t        Type;
        uint16_t        Flags;
-       uint16_t        Length;
+       uint32_t        Length;
 }      tRequestValue;
 
 typedef struct sRequestHeader {
        uint16_t        ClientID;
        uint16_t        CallID; //!< \see eSyscalls
+       uint32_t        MessageLength;
        uint16_t        NParams;
        
        tRequestValue   Params[];
@@ -61,6 +67,7 @@ enum eSyscalls {
        // IPC
        SYS_SLEEP,
        SYS_AN_FORK,
+       SYS_AN_SPAWN,
        SYS_SENDMSG,
        SYS_GETMSG,
        SYS_SELECT,
index 167e022..340fa0d 100644 (file)
@@ -1,8 +1,8 @@
 
 ARM_CPUNAME = gerneric-armv7
-CC = arm-elf-gcc -mcpu=$(ARM_CPUNAME)
-AS = arm-elf-gcc -mcpu=$(ARM_CPUNAME) -c
-LD = arm-elf-ld
+CC = arm-eabi-gcc -mcpu=$(ARM_CPUNAME)
+AS = arm-eabi-gcc -mcpu=$(ARM_CPUNAME) -c
+LD = arm-eabi-ld
 OBJDUMP = arm-elf-objdump
 DISASM = $(OBJDUMP) -d -S
 ARCHDIR = armv7
index 057e96e..d3241b1 100644 (file)
@@ -6,6 +6,10 @@
 SAVED_CC_ := $(CC)
 SAVED_LD_ := $(LD)
 
+ifeq ($(HOST_ARCH),)
+$(error Please set HOST_ARCH to the architecture to compile, e.g. x86)
+endif
+
 include $(ACESSDIR)/BuildConf/$(HOST_ARCH)/Makefile.cfg
 
 OBJDUMP := objdump -S
index 7b3d8a9..65777d1 100644 (file)
@@ -3,9 +3,13 @@
 #
 
 CC = i586-elf-gcc
+#CC = clang -m32
 LD = i586-elf-ld
+#CC = gcc
+#LD = ld
 AS = nasm
-OBJDUMP = i586-elf-objdump
+#OBJDUMP = i586-elf-objdump
+OBJDUMP = objdump
 RM = @rm -f
 STRIP = strip
 
index 5d153f5..ff8de6e 100644 (file)
@@ -10,7 +10,8 @@ MODULES += Display/BochsGA
 MODULES += Input/PS2KbMouse
 MODULES += x86/ISADMA x86/VGAText
 
-MODULES += USB/Core USB/UHCI USB/EHCI
+MODULES += USB/Core USB/UHCI
+#MODULES += USB/EHCI
 #USB/OHCI
 MODULES += USB/HID USB/MSC
 #MODULES += Interfaces/UDI
index ebca2d9..cc252bc 100644 (file)
@@ -6,8 +6,8 @@ CC := $(PREFIX)-gcc
 LD := $(PREFIX)-ld
 DISASM = $(PREFIX)-objdump -d -M x86-64 -S
 
-KERNEL_CFLAGS := -mcmodel=kernel -nostdlib -mno-red-zone -Wall
-DYNMOD_CFLAGS := -mcmodel=small -fPIC -mno-red-zone
+KERNEL_CFLAGS := -mcmodel=kernel -nostdlib -mno-red-zone -Wall -mno-sse
+DYNMOD_CFLAGS := -mcmodel=small -fPIC -mno-red-zone -mno-sse
 
 ARCHDIR = x86_64
 
diff --git a/Externals/ACPICA/.gitignore b/Externals/ACPICA/.gitignore
new file mode 100644 (file)
index 0000000..63b3b30
--- /dev/null
@@ -0,0 +1,2 @@
+acpica-unix-*
+include
diff --git a/Externals/ACPICA/Makefile b/Externals/ACPICA/Makefile
new file mode 100644 (file)
index 0000000..97d3414
--- /dev/null
@@ -0,0 +1,80 @@
+
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../Makefile.cfg
+
+BIN := ../bin-$(ARCH)/libacpica.a
+
+_VERS := $(patsubst acpica-unix-%.tar.gz,%,$(wildcard acpica-unix-*.tar.gz))
+_VERS := $(sort $(_VERS))
+_LATEST := $(lastword $(_VERS))
+
+ifeq ($(ACPICAVER),)
+ ifeq ($(_LATEST),)
+  $(warning Unable to find an archive matching acpica-unix-%.tar.gz)
+  $(warning Go to https://www.acpica.org/downloads/ to get it)
+  $(error No ACPICA archive found)
+ endif
+ ifneq ($(_LATEST),$(_VERS))
+  $(warning Multiple archvies found, picked $(_LATEST))
+ endif
+ ACPICAVER := $(_LATEST)
+endif
+
+ACPICAROOT := acpica-unix-$(ACPICAVER)/
+ACPICA_ARCHIVE := acpica-unix-$(ACPICAVER).tar.gz
+COMPDIR := $(ACPICAROOT)source/components/
+KERNELDIR := ../../KernelLand/Kernel/
+
+CPPFLAGS       += -I $(KERNELDIR)include -I$(KERNELDIR)arch/$(ARCHDIR)/include -D_MODULE_NAME_=\"ACPICA\"
+CPPFLAGS        += -I $(ACPICAROOT)source/include -D _ACESS -D __KERNEL__
+CPPFLAGS       += -D ARCH=$(ARCH) -D ARCHDIR=$(ARCHDIR) -D PLATFORM=\"$(PLATFORM)\" -D ARCHDIR_IS_$(ARCHDIR)=1 -D PLATFORM_is_$(PLATFORM)=1
+CPPFLAGS       += -D KERNEL_VERSION=$(KERNEL_VERSION) -ffreestanding
+CFLAGS         += -Wall -fno-stack-protector -Wstrict-prototypes -std=gnu99 -g
+
+SRCS := $(wildcard $(COMPDIR)*/*.c)
+OBJS := $(SRCS:$(COMPDIR)%.c=obj-$(ARCH)/%.o)
+
+ACENV_H := $(ACPICAROOT)source/include/platform/acenv.h
+ACACESS_H := $(ACPICAROOT)source/include/platform/acacess.h
+
+.PHONY: all clean
+
+ifeq ($(words $(SRCS)),0)
+extract: $(ACPICAROOT)
+       @echo Re-run make to compile
+endif
+
+all: $(BIN) include
+
+clean:
+       $(RM) -r obj-$(ARCH)/ include
+
+purge: clean
+       $(RM) -r $(ACPICAROOT)
+
+$(BIN): $(OBJS)
+       @mkdir -p $(dir $@)
+       @echo [AR] $@
+       @ar rcu $@ $(OBJS)
+
+include:
+       ln -s $(ACPICAROOT)source/include
+
+$(ACPICAROOT): $(ACPICA_ARCHIVE)
+       tar -xf $(ACPICA_ARCHIVE)
+
+$(ACACESS_H): acacess.h
+       cp $< $@
+
+$(ACENV_H): $(ACPICA_ARCHIVE) Makefile
+       tar -x -O -f $(ACPICA_ARCHIVE) $(ACENV_H) | sed 's/aclinux/acacess/' | sed 's/_LINUX/_ACESS/' > $@
+
+obj-$(ARCH)/%.o: $(COMPDIR)%.c $(ACENV_H) $(ACACESS_H)
+       @mkdir -p $(dir $@)
+       @echo [CC] -o $@
+       @$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< 
+       @$(CC) -M -MP -MT $@ $(CPPFLAGS) $< -o [email protected]
+
+-include $(OBJS:%=%.dep)
+
diff --git a/Externals/ACPICA/Makefile.kinc b/Externals/ACPICA/Makefile.kinc
new file mode 100644 (file)
index 0000000..6410f51
--- /dev/null
@@ -0,0 +1,8 @@
+CPPFLAGS += -I $(ACESSDIR)/Externals/ACPICA/include -D_ACESS -D__KERNEL__
+EXTERN_OBJS += $(ACESSDIR)/Externals/bin-$(ARCH)/libacpica.a
+
+$(ACESSDIR)/Externals/bin-$(ARCH)/libacpica.a:
+       @make -C $(ACESSDIR)/Externals/ACPICA
+       @make -C $(ACESSDIR)/Externals/ACPICA
+
+
diff --git a/Externals/ACPICA/acacess.h b/Externals/ACPICA/acacess.h
new file mode 100644 (file)
index 0000000..fdbf335
--- /dev/null
@@ -0,0 +1,128 @@
+/******************************************************************************
+ *
+ * Name: aclinux.h - OS specific defines, etc. for Linux
+ *
+ *****************************************************************************/
+
+#ifndef _ACPICA__ACACESS_H_
+#define _ACPICA__ACACESS_H_
+
+#define ACPI_USE_SYSTEM_CLIBRARY
+#define ACPI_USE_DO_WHILE_0
+#define ACPI_MUTEX_TYPE             ACPI_OSL_MUTEX
+
+//#define ACPI_DEBUG_OUTPUT    1
+
+#ifdef __KERNEL__
+
+#include <acess.h>
+
+/* Host-dependent types and defines for in-kernel ACPICA */
+
+#define ACPI_MACHINE_WIDTH          BITS
+
+typedef struct sACPICache      tACPICache;
+
+#define ACPI_CACHE_T   tACPICache
+#define ACPI_SPINLOCK               tShortSpinlock*
+#define ACPI_CPU_FLAGS              unsigned long
+
+#define COMPILER_DEPENDENT_UINT64      Uint64
+#define COMPILER_DEPENDENT_INT64       Sint64
+
+#define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) do { \
+       Uint64  rem; \
+       Sint64  num = ((Sint64)n_hi<<32)|n_lo; \
+        int    sgn = 1; \
+       if(num < 0) {num = -num; sgn = -sgn; } \
+       if(d32 < 0) {d32 = -d32; sgn = -sgn; } \
+       q32 = sgn * DivMod64U( num, d32, &rem ); \
+       r32 = rem; \
+       }while(0)
+#define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) do { \
+       n_lo >>= 1; \
+       if(n_hi & 1)    n_lo |= (1 << 31); \
+       n_hi >>= 1; \
+       }while(0)
+
+#else /* !__KERNEL__ */
+
+#error "Kernel only"
+
+#endif /* __KERNEL__ */
+
+/* Linux uses GCC */
+
+#include "acgcc.h"
+
+
+#if 0
+#ifdef __KERNEL__
+#define ACPI_SYSTEM_XFACE
+#include <actypes.h>
+/*
+ * Overrides for in-kernel ACPICA
+ */
+static inline acpi_thread_id acpi_os_get_thread_id(void)
+{
+    return (ACPI_THREAD_ID) (unsigned long) current;
+}
+
+/*
+ * The irqs_disabled() check is for resume from RAM.
+ * Interrupts are off during resume, just like they are for boot.
+ * However, boot has  (system_state != SYSTEM_RUNNING)
+ * to quiet __might_sleep() in kmalloc() and resume does not.
+ */
+static inline void *acpi_os_allocate(acpi_size size)
+{
+    return malloc(size);
+}
+
+static inline void *acpi_os_allocate_zeroed(acpi_size size)
+{
+    return calloc(size, 1);
+}
+
+static inline void *acpi_os_acquire_object(acpi_cache_t * cache)
+{
+//    return kmem_cache_zalloc(cache,
+//        irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
+}
+
+#define ACPI_ALLOCATE(a)        acpi_os_allocate(a)
+#define ACPI_ALLOCATE_ZEROED(a) acpi_os_allocate_zeroed(a)
+#define ACPI_FREE(a)            free(a)
+
+#ifndef CONFIG_PREEMPT
+/*
+ * Used within ACPICA to show where it is safe to preempt execution
+ * when CONFIG_PREEMPT=n
+ */
+#define ACPI_PREEMPTION_POINT() \
+    do { \
+        Threads_Yield(); \
+    } while (0)
+#endif
+
+/*
+ * When lockdep is enabled, the spin_lock_init() macro stringifies it's
+ * argument and uses that as a name for the lock in debugging.
+ * By executing spin_lock_init() in a macro the key changes from "lock" for
+ * all locks to the name of the argument of acpi_os_create_lock(), which
+ * prevents lockdep from reporting false positives for ACPICA locks.
+ */
+#define AcpiOsCreateLock(__handle)                             \
+({                                                             \
+       tShortlock *lock = ACPI_ALLOCATE_ZEROED(sizeof(*lock)); \
+                                                               \
+       if (lock) {                                             \
+               *(__handle) = lock;                             \
+       }                                                       \
+       lock ? AE_OK : AE_NO_MEMORY;                            \
+})
+
+#endif /* __KERNEL__ */
+#endif
+
+#endif /* __ACLINUX_H__ */
index 66eb9cd..d39e5a3 100644 (file)
@@ -29,6 +29,7 @@ CFLAGS        += -Wall -fno-stack-protector -Wstrict-prototypes -std=gnu99 -g
 CFLAGS         += -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wuninitialized
 CFLAGS          += -O3
 LDFLAGS                += -T arch/$(ARCHDIR)/link.ld -g
+LIBGCC_PATH     := $(shell $(CC) -print-libgcc-file-name)
 
 ifeq ($(PLATFORM),default)
        OBJDIR := obj-$(ARCH)/
@@ -56,7 +57,7 @@ OBJ += heap.o logging.o debug.o lib.o libc.o adt.o time.o
 OBJ += drvutil_video.o drvutil_disk.o
 OBJ += messages.o modules.o syscalls.o system.o
 OBJ += threads.o mutex.o semaphore.o workqueue.o events.o rwlock.o
-OBJ += drv/zero-one.o drv/proc.o drv/fifo.o drv/iocache.o drv/pci.o
+OBJ += drv/zero-one.o drv/proc.o drv/fifo.o drv/iocache.o drv/pci.o drv/vpci.o
 OBJ += drv/vterm.o drv/vterm_font.o drv/vterm_vt100.o drv/vterm_output.o drv/vterm_input.o drv/vterm_termbuf.o
 OBJ += binary.o bin/elf.o bin/pe.o
 OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/dir.o vfs/io.o vfs/mount.o
@@ -84,6 +85,10 @@ clean:
        @$(RM) $(BIN) ../Acess2.$(ARCH).gz $(BIN).dsm ../Map.$(ARCH).txt LineCounts.$(ARCH).txt
        @$(RM) -r $(OBJDIR) $(OBJ) $(DEPFILES) $(BUILDINFO_SRC)
 
+# Lower to avoid taking default target from 'all'
+-include $(addprefix ../../Externals/,$(addsuffix /Makefile.kinc, $(EXTERNS)))
+
+
 # Creates a stripped and compressed copy of the kernel
 # and installs it to the target
 install: $(BIN) 
@@ -98,14 +103,14 @@ apidoc:
 # - Disassembles it
 # - Increments the build count
 # - Does whatever architecture defined rules
-$(BIN): $(OBJ) $(MODS) arch/$(ARCHDIR)/link.ld Makefile ../../BuildConf/$(ARCH)/Makefile.cfg ../../BuildConf/$(ARCH)/$(PLATFORM).mk
+$(BIN): $(EXTERN_OBJS) $(OBJ) $(MODS) arch/$(ARCHDIR)/link.ld Makefile ../../BuildConf/$(ARCH)/Makefile.cfg ../../BuildConf/$(ARCH)/$(PLATFORM).mk
        @echo --- LD -o $(BIN)
-       @$(LD) $(LDFLAGS) -o $(BIN) $(OBJ) $(MODS) $(LIBGCC_PATH) --defsym __buildnum=$$(( $(BUILD_NUM) + 1 )) -Map ../Map.$(ARCH).txt
+       @$(LD) $(LDFLAGS) -o $(BIN) $(OBJ) $(MODS) $(EXTERN_OBJS) $(LIBGCC_PATH) --defsym __buildnum=$$(( $(BUILD_NUM) + 1 )) -Map ../Map.$(ARCH).txt
        @$(DISASM) -S $(BIN) > $(BIN).dsm
        @echo BUILD_NUM = $$(( $(BUILD_NUM) + 1 )) > Makefile.BuildNum.$(ARCH)
        $(POSTBUILD)
        @cp $(BIN) $(BIN)_
-       @-$(STRIP) $(BIN)_
+       @$(STRIP) $(BIN)_ || true
        @gzip -c $(BIN)_ > $(GZBIN)
        @$(RM) $(BIN)_
 
index fad1b55..5429fe6 100644 (file)
@@ -12,6 +12,7 @@ LDFLAGS += `$(CC) --print-libgcc-file-name`
 
 A_OBJ  = start.ao main.o lib.o lib.ao time.o pci.o debug.o
 A_OBJ += mm_phys.o mm_virt.o proc.o proc.ao
+A_OBJ += vpci_$(PLATFORM).o
 
 #main.c: Makefile.BuildNum.$(ARCH)
 
index 5a6928e..f33f339 100644 (file)
@@ -14,12 +14,15 @@ extern Uint32       __divmod32_asm(Uint32 Num, Uint32 Den, Uint32 *Rem);
 // === PROTOTYPES ===
 Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem);
 Uint32 __divmod32(Uint32 Num, Uint32 Den, Uint32 *Rem);
+#if 0
 Uint64 __udivdi3(Uint64 Num, Uint64 Den);
 Uint64 __umoddi3(Uint64 Num, Uint64 Den);
 Uint32 __udivsi3(Uint32 Num, Uint32 Den);
 Uint32 __umodsi3(Uint32 Num, Uint32 Den);
 Sint32 __divsi3(Sint32 Num, Sint32 Den);
 Sint32 __modsi3(Sint32 Num, Sint32 Den);
+#endif
+void   abort(void);
 
 // === CODE ===
 void *memcpy(void *_dest, const void *_src, size_t _length)
@@ -100,7 +103,7 @@ void *memset(void *_dest, int _value, size_t _length)
        val32 |= val32 << 16;
        
        // Force alignment
-       while( (tVAddr)dst8 & 3 ) *dst8 ++ = _value;
+       while( (tVAddr)dst8 & 3 ) *dst8 ++ = _value, _length --;
        dst = (void *)dst8;
 
        // DWORD copies
@@ -160,6 +163,7 @@ Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
        return ret;
 }
 
+#if 0
 // Unsigned Divide 64-bit Integer
 Uint64 __udivdi3(Uint64 Num, Uint64 Den)
 {
@@ -215,3 +219,9 @@ Sint32 __modsi3(Sint32 Num, Sint32 Den)
        DivMod32S(Num, Den, &rem);
        return rem;
 }
+#endif
+
+void abort(void)
+{
+       for(;;);
+}
index d10dcc4..fbd3582 100644 (file)
@@ -27,9 +27,33 @@ SECTIONS
                *(.usertext)
        }
        . += gUsertextPhysStart + _kernel_base - _usertext_vbase;
-       
+
+       /DISCARD/           : { *(.ARM.extab.init .ARM.exidx.init)      }
+       .ARM.extab          : AT( ADDR(.ARM.extab) - _kernel_base)
+       {
+               *(.ARM.extab* .gnu.linkonce.armextab.*)
+       }
+       PROVIDE_HIDDEN ( __exidx_start = . );
+       .ARM.exidx          : AT( ADDR(.ARM.exidx) - _kernel_base)
+       {
+               *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+       }
+       PROVIDE_HIDDEN ( __exidx_end = . );
+       .eh_frame_hdr       : AT( ADDR(.eh_frame_hdr) - _kernel_base) {
+               *(.eh_frame_hdr)
+       }
+       .eh_frame           : AT( ADDR(.eh_frame) - _kernel_base) ONLY_IF_RO
+       {
+               KEEP (*(.eh_frame))
+       }
+       .gcc_except_table   : AT( ADDR(.gcc_except_table) - _kernel_base) ONLY_IF_RO
+       {
+               *(.gcc_except_table .gcc_except_table.*)
+       }
+
        /* 0x4000 (4 pages) alignment needed for root table */
-       .data ALIGN(0x4000) : AT( ADDR(.data) - _kernel_base )
+       . = ALIGN(0x4000);
+       .data : AT( ADDR(.data) - _kernel_base )
        {
                *(.padata)
                *(.data*)
@@ -42,7 +66,7 @@ SECTIONS
                *(KMODULES)
                gKernelModulesEnd = .;
        }
-       .bss : AT( ADDR(.bss) - _kernel_base )
+       .bss ALIGN(0x1000) : AT( ADDR(.bss) - _kernel_base )
        {
                bss_start = .;
                *(.bss*)
index 4583b7b..146caea 100644 (file)
@@ -10,6 +10,7 @@
 #include <hal_proc.h>
 
 #define TRACE_MAPS     0
+#define TRACE_COW      1
 
 #define AP_KRW_ONLY    1       // Kernel page
 #define AP_KRO_ONLY    5       // Kernel RO page
 #define AP_RO_USER     2       // User RO Page
 #define PADDR_MASK_LVL1        0xFFFFFC00
 
+const char * const caAPValueNames[] = {
+       "AP_NOACCESS", "AP_KRW_ONLY",
+       "AP_RO_USER", "AP_RW_BOTH",
+       "AP_???_4", "AP_KRO_ONLY",
+       "AP_???_6", "AP_RO_BOTH"
+};
+
 // === IMPORTS ===
 extern Uint32  kernel_table0[];
 
@@ -53,7 +61,7 @@ tPAddr        MM_Clone(void);
 tVAddr MM_NewKStack(int bGlobal);
 void   MM_int_DumpTableEnt(tVAddr Start, size_t Len, tMM_PageInfo *Info);
 //void MM_DumpTables(tVAddr Start, tVAddr End);
-void   MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch);
+void   MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch, Uint32 UserLR);
 
 // === GLOBALS ===
 tPAddr giMM_ZeroPage;
@@ -320,12 +328,12 @@ int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
 }
 
 // --- Exports ---
-tPAddr MM_GetPhysAddr(tVAddr VAddr)
+tPAddr MM_GetPhysAddr(const void *Ptr)
 {
        tMM_PageInfo    pi;
-       if( MM_int_GetPageInfo(VAddr, &pi) )
+       if( MM_int_GetPageInfo((tVAddr)Ptr, &pi) )
                return 0;
-       return pi.PhysAddr | (VAddr & ((1 << pi.Size)-1));
+       return pi.PhysAddr | ((tVAddr)Ptr & ((1 << pi.Size)-1));
 }
 
 Uint MM_GetFlags(tVAddr VAddr)
@@ -902,7 +910,7 @@ tVAddr MM_NewUserStack(void)
        tVAddr  addr, ofs;
 
        addr = USER_STACK_TOP - USER_STACK_SIZE;
-       if( MM_GetPhysAddr(addr + PAGE_SIZE) ) {
+       if( MM_GetPhysAddr( (void*)(addr + PAGE_SIZE) ) ) {
                Log_Error("MMVirt", "Unable to create initial user stack, addr %p taken",
                        addr + PAGE_SIZE
                        );
@@ -938,18 +946,20 @@ void MM_int_DumpTableEnt(tVAddr Start, size_t Len, tMM_PageInfo *Info)
 {
        if( giMM_ZeroPage && Info->PhysAddr == giMM_ZeroPage )
        {
-               Debug("%p => %8s - 0x%7x %i %x %s",
+               Debug("%p => %8s - 0x%7x D%i %x %s %s",
                        Start, "ZERO", Len,
                        Info->Domain, Info->AP,
-                       Info->bGlobal ? "G" : "nG"
+                       Info->bExecutable ? " X" : "nX",
+                       Info->bGlobal ? " G" : "nG"
                        );
        }
        else
        {
-               Debug("%p => %8x - 0x%7x %i %x %s",
+               Debug("%p => %8x - 0x%7x D%i %x %s %s",
                        Start, Info->PhysAddr-Len, Len,
                        Info->Domain, Info->AP,
-                       Info->bGlobal ? "G" : "nG"
+                       Info->bExecutable ? " X" : "nX",
+                       Info->bGlobal ? " G" : "nG"
                        );
        }
 }
@@ -996,7 +1006,7 @@ void MM_DumpTables(tVAddr Start, tVAddr End)
 }
 
 // NOTE: Runs in abort context, not much difference, just a smaller stack
-void MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch)
+void MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch, Uint32 UserLR)
 {
         int    rv;
        tMM_PageInfo    pi;
@@ -1070,6 +1080,33 @@ void MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch)
        Log_Error("MMVirt", "Code at %p accessed %p (DFSR = 0x%x)%s", PC, Addr, DFSR,
                (bPrefetch ? " - Prefetch" : "")
                );
+       Log_Error("MMVirt", "- User LR = 0x%x", UserLR);
+       const char * const dfsr_errors[] = {
+               /* 00000 */ "-", "Alignment Fault",
+               /* 00010 */ "Debug event", "Access Flag (Section)",
+               /* 00100 */ "Instr Cache Maint", "Translation (Section)",
+               /* 00110 */ "Access Flag (Page)", "Translation (Page)",
+               /* 01000 */ "Sync. External abort", "Domain (Section)",
+               /* 01010 */ "-", "Domain (Page)",
+               /* 01100 */ "Table Walk sync ext (lvl 1)", "Permission (Section)",
+               /* 01110 */ "Table Walk sync ext (lvl 2)", "Permission (Page)",
+               // 0b10000
+               /* 10000 */ "-", "-",
+               /* 10010 */ "-", "-",
+               /* 10100 */ "IMPL (Lockdown)", "-",
+               /* 10110 */ "Async. Extern. Abort", "-",
+               /* 11000 */ "Mem. access async pairity error", "Mem. access async pairity error",
+               /* 11010 */ "IMPL (Coprocessor abort)", "-",
+               /* 11100 */ "Table Walk Sync parity (lvl 1)", "-",
+               /* 11110 */ "Table Walk Sync parity (lvl 2)", "-"
+               };
+        int    errcode = (DFSR & 0xF) | (((DFSR >> 10) & 1) << 4);
+       Log_Error("MMVirt", "- Errcode 0b%05b", errcode);
+       Log_Error("MMVirt", "- Dom %i %s %s",
+               (DFSR >> 4) & 0xF, (DFSR & 0x800 ? "Write": "Read"),
+               dfsr_errors[errcode]
+               );
+       Log_Error("MMVirt", "- AP=%i(%s) %s", pi.AP, caAPValueNames[pi.AP], pi.bExecutable ? " Executable":"");
        if( Addr < 0x80000000 )
                MM_DumpTables(0, 0x80000000);
        else
index cd998f2..fa1e02c 100644 (file)
@@ -130,13 +130,13 @@ tTID Proc_Clone(Uint Flags)
        return new->TID;
 }
 
-int Proc_SpawnWorker( void (*Fnc)(void*), void *Ptr )
+tThread *Proc_SpawnWorker( void (*Fnc)(void*), void *Ptr )
 {
        tThread *new;
        Uint32  sp;
 
        new = Threads_CloneThreadZero();
-       if(!new)        return -1;
+       if(!new)        return NULL;
        if(new->ThreadName)     free(new->ThreadName);
        new->ThreadName = NULL;
 
@@ -144,7 +144,7 @@ int Proc_SpawnWorker( void (*Fnc)(void*), void *Ptr )
        if(!new->KernelStack) {
                // TODO: Delete thread
                Log_Error("Proc", "Unable to allocate kernel stack");
-               return -1;
+               return NULL;
        }       
 
        sp = new->KernelStack;
@@ -158,7 +158,7 @@ int Proc_SpawnWorker( void (*Fnc)(void*), void *Ptr )
 
        Threads_AddActive(new);
 
-       return new->TID;
+       return new;
 }
 
 tTID Proc_NewKThread( void (*Fnc)(void*), void *Ptr )
index 113c8a4..71534f5 100644 (file)
@@ -194,12 +194,21 @@ DataAbort:
 @      cpsid ifa, #19
        PUSH_GPRS
 
+       @ Get the user's LR value (and push to stack)
+       cps #31 @ Go to system mode
+       mov r1, lr
+       cps #19 @ Go to supervisor
+       mov r0, lr
+       cps #23 @ back to exception
+       push {r0,r1}
+       
        mov r3, #0      @ not a prefetch abort
        mrc p15, 0, r2, c5, c0, 0       @ Read DFSR (Data Fault Status Register) to R2
        mrc p15, 0, r1, c6, c0, 0       @ Read DFAR (Data Fault Address Register) into R1
        mov r0, lr      @ PC
        ldr r4, =MM_PageFault
        blx r4
+       add sp, #8      @ Undo push of the user/system LR
 
        POP_GPRS
        rfeia sp!       @ Pop state (actually RFEFD)
@@ -211,17 +220,24 @@ PrefetchAbort:
 @      cpsid ifa, #19
        PUSH_GPRS
 
-       ldr r0, =csAbort_Tag
-       ldr r1, =csPrefetchAbort_Fmt
-#      mov r2, lr
-       mrc p15, 0, r2, c6, c0, 2       @ Read IFAR (Instruction Fault Address Register) into R3
-       mrc p15, 0, r3, c5, c0, 1       @ Read IFSR (Instruction Fault Status Register) into R3
-       ldr r5, =Log_Error
-       blx r5
 
-.loop:
-       wfi
-       b .loop
+       @ Get the user's LR value (and push to stack)
+       cps #31 @ Go to system mode
+       mov r0, lr
+       cps #23 @ back to supervisor
+       push {r0}
+       
+       mrc p15, 0, r2, c5, c0, 1       @ Read IFSR (Instruction Fault Status Register) into R3
+       mrc p15, 0, r1, c6, c0, 2       @ Read IFAR (Instruction Fault Address Register) into R3
+       mov r0, r1
+       mov r3, #1      @ IS a prefetch abort
+       ldr r4, =MM_PageFault
+       blx r4
+       add sp, #4      @ Undo push of the user LR
+
+       POP_GPRS
+       rfeia sp!       @ Pop state (actually RFEFD)
+
 .globl Undef_Handler
 Undef_Handler:
        wfi
@@ -238,7 +254,7 @@ csIRQ_Fmt:
 csDataAbort_Fmt:
        .asciz "Data Abort - %p accessed %p, DFSR=%x Unk:%x Unk:%x"
 csPrefetchAbort_Fmt:
-       .asciz "Prefetch Abort at %p, IFSR=%x"
+       .asciz "Prefetch Abort at %p, IFSR=%x, UserLR:0x%x"
 csSyscallPrintRetAddr:
        .asciz "Syscall ret to %p"
 
diff --git a/KernelLand/Kernel/arch/armv7/vpci_realview_pb.c b/KernelLand/Kernel/arch/armv7/vpci_realview_pb.c
new file mode 100644 (file)
index 0000000..8c8afdb
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Acess2 Kernel ARMv7 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * vpci_realview_pb.c
+ * - Realview PB VPCI Definitions
+ */
+#include <virtual_pci.h>
+
+// === PROTOTYPES ===
+
+// === GLOBALS ===
+tVPCI_Device   gaVPCI_Devices[] = {
+};
+int giVPCI_DeviceCount = sizeof(gaVPCI_Devices)/sizeof(gaVPCI_Devices[0]);
+
diff --git a/KernelLand/Kernel/arch/armv7/vpci_tegra2.c b/KernelLand/Kernel/arch/armv7/vpci_tegra2.c
new file mode 100644 (file)
index 0000000..d44e9d5
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Acess2 Kernel ARMv7 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * vpci_tegra2.c
+ * - Tegra2 VPCI Definitions
+ */
+#include <virtual_pci.h>
+
+// === PROTOTYPES ===
+
+// === GLOBALS ===
+tVPCI_Device   gaVPCI_Devices[] = {
+       {
+       .Vendor=0x0ACE,.Device=0x1100,
+       .Class = 0x0C032000,    // Serial, USB, ECHI
+       .BARs = {0xC5000000,0,0,0,0,0},
+       .IRQ = 0*32+20,
+       },
+       {
+       .Vendor=0x0ACE,.Device=0x1100,
+       .Class = 0x0C032000,    // Serial, USB, ECHI
+       .BARs = {0xC5004000,0,0,0,0,0},
+       .IRQ = 0*32+21,
+       },
+       {
+       .Vendor=0x0ACE,.Device=0x1100,
+       .Class = 0x0C032000,    // Serial, USB, ECHI
+       .BARs = {0xC5008000,0,0,0,0,0},
+       .IRQ = 4*32+1,
+       }
+};
+int giVPCI_DeviceCount = sizeof(gaVPCI_Devices)/sizeof(gaVPCI_Devices[0]);
+
index c3223d0..9e5a883 100644 (file)
@@ -5,7 +5,7 @@
 
 AS_SUFFIX = asm
 
-CPPFLAGS       =
+CPPFLAGS       = 
 CFLAGS         =
 ASFLAGS                = -f elf
 
@@ -23,4 +23,8 @@ CPPFLAGS += -DUSE_MP=$(USE_MP)
 A_OBJ  = start.ao main.o mboot.o lib.o desctab.ao errors.o irq.o
 A_OBJ += mm_phys.o mm_virt.o
 A_OBJ += proc.o proc.ao time.o vm8086.o
-A_OBJ += kpanic.o pci.o
+A_OBJ += kpanic.o pci.o vpci.o
+#A_OBJ += acpica.o
+
+#EXTERNS += ACPICA
+
diff --git a/KernelLand/Kernel/arch/x86/acpica.c b/KernelLand/Kernel/arch/x86/acpica.c
new file mode 100644 (file)
index 0000000..f310fc5
--- /dev/null
@@ -0,0 +1,610 @@
+/*
+ * Acess2 Kernel (x86 Core)
+ * - By John Hodge (thePowersGang)
+ *
+ * acpica.c
+ * - ACPICA Interface
+ */
+#define DEBUG  1
+#define _AcpiModuleName "Shim"
+#define _COMPONENT     "Acess"
+#include <acpi.h>
+#include <timers.h>
+#include <mutex.h>
+#include <semaphore.h>
+
+#define ONEMEG (1024*1024)
+
+// === GLOBALS ===
+// - RSDP Address from uEFI
+tPAddr gACPI_RSDPOverride = 0;
+
+// === PROTOTYPES ===
+int    ACPICA_Initialise(void);
+void   ACPI_int_InterruptProxy(int IRQ, void *data);
+
+
+// === CODE ===
+int ACPICA_Initialise(void)
+{
+       ACPI_STATUS     rv;
+
+       #ifdef ACPI_DEBUG_OUTPUT
+       AcpiDbgLevel = ACPI_DB_ALL;
+       #endif
+
+       rv = AcpiInitializeSubsystem();
+       if( ACPI_FAILURE(rv) )
+       {
+               Log_Error("ACPI", "AcpiInitializeSubsystem: %i", rv);
+               return -1;
+       }
+       
+       rv = AcpiInitializeTables(NULL, 16, FALSE);
+       if( ACPI_FAILURE(rv) )
+       {
+               Log_Error("ACPI", "AcpiInitializeTables: %i", rv);
+               AcpiTerminate();
+               return -1;
+       }
+
+       // AcpiInitializeTables?
+       rv = AcpiLoadTables();
+       if( ACPI_FAILURE(rv) )
+       {
+               Log_Error("ACPI", "AcpiLoadTables: %i", rv);
+               AcpiTerminate();
+               return -1;
+       }
+       
+       rv = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION);
+       if( ACPI_FAILURE(rv) )
+       {
+               Log_Error("ACPI", "AcpiEnableSubsystem: %i", rv);
+               AcpiTerminate();
+               return -1;
+       }
+
+       return 0;
+}
+
+// ---------------
+// --- Exports ---
+// ---------------
+ACPI_STATUS AcpiOsInitialize(void)
+{
+       return AE_OK;
+}
+
+ACPI_STATUS AcpiOsTerminate(void)
+{
+       return AE_OK;
+}
+
+ACPI_PHYSICAL_ADDRESS AcpiOsGetRootPointer(void)
+{
+       ACPI_SIZE       val;
+       ACPI_STATUS     rv;
+
+       if( gACPI_RSDPOverride )
+               return gACPI_RSDPOverride;      
+
+       rv = AcpiFindRootPointer(&val);
+       if( ACPI_FAILURE(rv) )
+               return 0;
+
+       LOG("val=%x", val);
+       
+       return val;
+       // (Or use EFI)
+}
+
+ACPI_STATUS AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES *PredefinedObject, ACPI_STRING *NewValue)
+{
+       *NewValue = NULL;
+       return AE_OK;
+}
+
+ACPI_STATUS AcpiOsTableOverride(ACPI_TABLE_HEADER *ExisitingTable, ACPI_TABLE_HEADER **NewTable)
+{
+       *NewTable = NULL;
+       return AE_OK;
+}
+
+ACPI_STATUS AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER *ExisitingTable, ACPI_PHYSICAL_ADDRESS *NewAddress, UINT32 *NewTableLength)
+{
+       *NewAddress = 0;
+       return AE_OK;
+}
+
+// -- Memory Management ---
+struct sACPICache
+{
+       Uint16  nObj;
+       Uint16  ObjectSize;
+       char    *Name;
+       void    *First;
+       char    ObjectStates[];
+};
+
+ACPI_STATUS AcpiOsCreateCache(char *CacheName, UINT16 ObjectSize, UINT16 MaxDepth, ACPI_CACHE_T **ReturnCache)
+{
+       tACPICache      *ret;
+        int    namelen = (CacheName ? strlen(CacheName) : 0) + 1;
+       LOG("CacheName=%s, ObjSize=%x, MaxDepth=%x", CacheName, ObjectSize, MaxDepth);
+
+       ret = malloc(sizeof(*ret) + MaxDepth*sizeof(char) + namelen + MaxDepth*ObjectSize);
+       if( !ret )      return AE_NO_MEMORY;
+
+       ret->nObj = MaxDepth;
+       ret->ObjectSize = ObjectSize;
+       ret->Name = (char*)(ret->ObjectStates + MaxDepth);
+       ret->First = ret->Name + namelen;
+       if( CacheName )
+               strcpy(ret->Name, CacheName);
+       else
+               ret->Name[0] = 0;
+       memset(ret->ObjectStates, 0, sizeof(char)*MaxDepth);
+
+       LOG("Allocated cache '%s' (%i x 0x%x)", CacheName, MaxDepth, ObjectSize);
+       
+       *ReturnCache = ret;
+       
+       return AE_OK;
+}
+
+ACPI_STATUS AcpiOsDeleteCache(ACPI_CACHE_T *Cache)
+{
+       if( Cache == NULL )
+               return AE_BAD_PARAMETER;
+
+       free(Cache);
+       return AE_OK;
+}
+
+ACPI_STATUS AcpiOsPurgeCache(ACPI_CACHE_T *Cache)
+{
+       if( Cache == NULL )
+               return AE_BAD_PARAMETER;
+
+       memset(Cache->ObjectStates, 0, sizeof(char)*Cache->nObj);
+
+       return AE_OK;
+}
+
+void *AcpiOsAcquireObject(ACPI_CACHE_T *Cache)
+{
+       LOG("(Cache=%p)", Cache);
+       for(int i = 0; i < Cache->nObj; i ++ )
+       {
+               if( !Cache->ObjectStates[i] ) {
+                       Cache->ObjectStates[i] = 1;
+                       return (char*)Cache->First + i*Cache->ObjectSize;
+               }
+       }
+       // TODO
+       return NULL;
+}
+
+ACPI_STATUS AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object)
+{
+       if( Cache == NULL || Object == NULL )
+               return AE_BAD_PARAMETER;
+
+       tVAddr delta = (tVAddr)Object - (tVAddr)Cache->First;
+       delta /= Cache->ObjectSize;
+       
+       if( delta > Cache->nObj )
+               return AE_BAD_PARAMETER;
+       
+       Cache->ObjectStates[delta] = 0;
+
+       return AE_OK;
+}
+
+void *AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS PhysicalAddress, ACPI_SIZE Length)
+{
+       if( PhysicalAddress < ONEMEG )
+               return (void*)(KERNEL_BASE | PhysicalAddress);
+       
+       Uint    ofs = PhysicalAddress & (PAGE_SIZE-1);
+       int npages = (ofs + Length + (PAGE_SIZE-1)) / PAGE_SIZE;
+       void *rv = ((char*)MM_MapHWPages(PhysicalAddress, npages)) + ofs;
+       LOG("Map (%P+%i pg) to %p", PhysicalAddress, npages, rv);
+       return rv;
+}
+
+void AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Length)
+{
+       if( (tVAddr)LogicalAddress - KERNEL_BASE < ONEMEG )
+               return ;
+
+       LOG("%p", LogicalAddress);
+
+       Uint    ofs = (tVAddr)LogicalAddress & (PAGE_SIZE-1);
+       int npages = (ofs + Length + (PAGE_SIZE-1)) / PAGE_SIZE;
+       // TODO: Validate `Length` is the same as was passed to AcpiOsMapMemory
+       MM_UnmapHWPages( (tVAddr)LogicalAddress, npages);
+}
+
+ACPI_STATUS AcpiOsGetPhysicalAddress(void *LogicalAddress, ACPI_PHYSICAL_ADDRESS *PhysicalAddress)
+{
+       if( LogicalAddress == NULL || PhysicalAddress == NULL )
+               return AE_BAD_PARAMETER;
+       
+       tPAddr  rv = MM_GetPhysAddr(LogicalAddress);
+       if( rv == 0 )
+               return AE_ERROR;
+       *PhysicalAddress = rv;
+       return AE_OK;
+}
+
+void *AcpiOsAllocate(ACPI_SIZE Size)
+{
+       return malloc(Size);
+}
+
+void AcpiOsFree(void *Memory)
+{
+       return free(Memory);
+}
+
+BOOLEAN AcpiOsReadable(void *Memory, ACPI_SIZE Length)
+{
+       return CheckMem(Memory, Length);
+}
+
+BOOLEAN AcpiOsWritable(void *Memory, ACPI_SIZE Length)
+{
+       // TODO: Actually check if it's writable
+       return CheckMem(Memory, Length);
+}
+
+
+// --- Threads ---
+ACPI_THREAD_ID AcpiOsGetThreadId(void)
+{
+       return Threads_GetTID() + 1;
+}
+
+ACPI_STATUS AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function, void *Context)
+{
+       // TODO: Need to store currently executing functions
+       if( Function == NULL )
+               return AE_BAD_PARAMETER;
+       Proc_SpawnWorker(Function, Context);
+       return AE_OK;
+}
+
+void AcpiOsSleep(UINT64 Milliseconds)
+{
+       Time_Delay(Milliseconds);
+}
+
+void AcpiOsStall(UINT32 Microseconds)
+{
+       // TODO: need a microsleep function
+       Microseconds += (1000-1);
+       Microseconds /= 1000;
+       Time_Delay(Microseconds);
+}
+
+void AcpiOsWaitEventsComplete(void)
+{
+       // TODO: 
+}
+
+// --- Mutexes etc ---
+ACPI_STATUS AcpiOsCreateMutex(ACPI_MUTEX *OutHandle)
+{
+       LOG("()");
+       if( !OutHandle )
+               return AE_BAD_PARAMETER;
+       tMutex  *ret = calloc( sizeof(tMutex), 1 );
+       if( !ret )
+               return AE_NO_MEMORY;
+       ret->Name = "AcpiOsCreateMutex";
+       *OutHandle = ret;
+       
+       return AE_OK;
+}
+
+void AcpiOsDeleteMutex(ACPI_MUTEX Handle)
+{
+       Mutex_Acquire(Handle);
+       free(Handle);
+}
+
+ACPI_STATUS AcpiOsAcquireMutex(ACPI_MUTEX Handle, UINT16 Timeout)
+{
+       if( Handle == NULL )
+               return AE_BAD_PARAMETER;
+
+       Mutex_Acquire(Handle);  
+
+       return AE_OK;
+}
+
+void AcpiOsReleaseMutex(ACPI_MUTEX Handle)
+{
+       Mutex_Release(Handle);
+}
+
+ACPI_STATUS AcpiOsCreateSemaphore(UINT32 MaxUnits, UINT32 InitialUnits, ACPI_SEMAPHORE *OutHandle)
+{
+       LOG("(MaxUnits=%i,InitialUnits=%i)", MaxUnits, InitialUnits);
+       if( !OutHandle )
+               return AE_BAD_PARAMETER;
+       tSemaphore      *ret = calloc( sizeof(tSemaphore), 1 );
+       if( !ret )
+               return AE_NO_MEMORY;
+       
+       Semaphore_Init(ret, InitialUnits, MaxUnits, "AcpiOsCreateSemaphore", "");
+       *OutHandle = ret;
+       return AE_OK;
+}
+
+ACPI_STATUS AcpiOsDeleteSemaphore(ACPI_SEMAPHORE Handle)
+{
+       if( !Handle )
+               return AE_BAD_PARAMETER;
+
+       free(Handle);   
+
+       return AE_OK;
+}
+
+ACPI_STATUS AcpiOsWaitSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units, UINT16 Timeout)
+{
+       if( !Handle )
+               return AE_BAD_PARAMETER;
+
+       // Special case
+       if( Timeout == 0 )
+       {
+               // NOTE: Possible race condition
+               if( Semaphore_GetValue(Handle) >= Units ) {
+                       Semaphore_Wait(Handle, Units);
+                       return AE_OK;
+               }
+               return AE_TIME;
+       }
+
+       tTime   start = now();
+       UINT32  rem = Units;
+       while(rem && now() - start < Timeout)
+       {
+               rem -= Semaphore_Wait(Handle, rem);
+       }
+
+       if( rem ) {
+               Semaphore_Signal(Handle, Units - rem);
+               return AE_TIME;
+       }
+
+       return AE_OK;
+}
+
+ACPI_STATUS AcpiOsSignalSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units)
+{
+       if( !Handle )
+               return AE_BAD_PARAMETER;
+
+       // TODO: Support AE_LIMIT detection early (to avoid blocks)
+
+       // NOTE: Blocks
+       int rv = Semaphore_Signal(Handle, Units);
+       if( rv != Units )
+               return AE_LIMIT;
+       
+       return AE_OK;
+}
+
+ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK *OutHandle)
+{
+       LOG("()");
+       if( !OutHandle )
+               return AE_BAD_PARAMETER;
+       tShortSpinlock  *lock = calloc(sizeof(tShortSpinlock), 1);
+       if( !lock )
+               return AE_NO_MEMORY;
+       
+       *OutHandle = lock;
+       return AE_OK;
+}
+
+void AcpiOsDeleteLock(ACPI_SPINLOCK Handle)
+{
+       free(Handle);
+}
+
+ACPI_CPU_FLAGS AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
+{
+       SHORTLOCK(Handle);
+       return 0;
+}
+
+void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
+{
+       SHORTREL(Handle);
+}
+
+// --- Interrupt handling ---
+#define N_INT_LEVELS   16
+ACPI_OSD_HANDLER       gaACPI_InterruptHandlers[N_INT_LEVELS];
+void   *gaACPI_InterruptData[N_INT_LEVELS];
+ int   gaACPI_InterruptHandles[N_INT_LEVELS];
+
+void ACPI_int_InterruptProxy(int IRQ, void *data)
+{
+       if( !gaACPI_InterruptHandlers[IRQ] )
+               return ;
+       gaACPI_InterruptHandlers[IRQ](gaACPI_InterruptData[IRQ]);
+}
+
+ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLER Handler, void *Context)
+{
+       if( InterruptLevel >= N_INT_LEVELS || Handler == NULL )
+               return AE_BAD_PARAMETER;
+       if( gaACPI_InterruptHandlers[InterruptLevel] )
+               return AE_ALREADY_EXISTS;
+
+       gaACPI_InterruptHandlers[InterruptLevel] = Handler;
+       gaACPI_InterruptData[InterruptLevel] = Context;
+
+       gaACPI_InterruptHandles[InterruptLevel] = IRQ_AddHandler(InterruptLevel, ACPI_int_InterruptProxy, NULL);
+       return AE_OK;
+}
+
+ACPI_STATUS AcpiOsRemoveInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLER Handler)
+{
+       if( InterruptLevel >= N_INT_LEVELS || Handler == NULL )
+               return AE_BAD_PARAMETER;
+       if( gaACPI_InterruptHandlers[InterruptLevel] != Handler )
+               return AE_NOT_EXIST;
+       gaACPI_InterruptHandlers[InterruptLevel] = NULL;
+       IRQ_RemHandler(gaACPI_InterruptHandles[InterruptLevel]);
+       return AE_OK;
+}
+
+// --- Memory Access ---
+ACPI_STATUS AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 *Value, UINT32 Width)
+{
+       void *ptr;
+       if( Address < ONEMEG ) {
+               ptr = (void*)(KERNEL_BASE | Address);
+       }
+       else {
+               ptr = (char*)MM_MapTemp(Address) + (Address & 0xFFF);
+       }
+
+       switch(Width)
+       {
+       case 8:         *Value = *(Uint8 *)ptr; break;
+       case 16:        *Value = *(Uint16*)ptr; break;
+       case 32:        *Value = *(Uint32*)ptr; break;
+       case 64:        *Value = *(Uint64*)ptr; break;
+       }
+
+       if( Address >= ONEMEG ) {
+               MM_FreeTemp(ptr);
+       }
+
+       return AE_OK;
+}
+
+ACPI_STATUS AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT32 Width)
+{
+       void *ptr;
+       if( Address < ONEMEG ) {
+               ptr = (void*)(KERNEL_BASE | Address);
+       }
+       else {
+               ptr = (char*)MM_MapTemp(Address) + (Address & 0xFFF);
+       }
+
+       switch(Width)
+       {
+       case 8:         *(Uint8 *)ptr = Value;  break;
+       case 16:        *(Uint16*)ptr = Value;  break;
+       case 32:        *(Uint32*)ptr = Value;  break;
+       case 64:        *(Uint64*)ptr = Value;  break;
+       default:
+               return AE_BAD_PARAMETER;
+       }
+
+       if( Address >= 1024*1024 ) {
+               MM_FreeTemp(ptr);
+       }
+       
+       return AE_OK;
+}
+
+// --- Port Input / Output ---
+ACPI_STATUS AcpiOsReadPort(ACPI_IO_ADDRESS Address, UINT32 *Value, UINT32 Width)
+{
+       switch(Width)
+       {
+       case 8:         *Value = inb(Address);  break;
+       case 16:        *Value = inw(Address);  break;
+       case 32:        *Value = ind(Address);  break;
+       default:
+               return AE_BAD_PARAMETER;
+       }
+       return AE_OK;
+}
+
+ACPI_STATUS AcpiOsWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width)
+{
+       switch(Width)
+       {
+       case 8:         outb(Address, Value);   break;
+       case 16:        outw(Address, Value);   break;
+       case 32:        outd(Address, Value);   break;
+       default:
+               return AE_BAD_PARAMETER;
+       }
+       return AE_OK;
+}
+
+// --- PCI Configuration Space Access ---
+ACPI_STATUS AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 *Value, UINT32 Width)
+{
+       UNIMPLEMENTED();
+       return AE_NOT_IMPLEMENTED;
+}
+
+ACPI_STATUS AcpiOsWritePciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 Value, UINT32 Width)
+{
+       UNIMPLEMENTED();
+       return AE_NOT_IMPLEMENTED;
+}
+
+// --- Formatted Output ---
+void AcpiOsPrintf(const char *Format, ...)
+{
+       va_list args;
+       va_start(args, Format);
+
+       LogFV(Format, args);
+
+       va_end(args);
+}
+
+void AcpiOsVprintf(const char *Format, va_list Args)
+{
+       LogFV(Format, Args);
+}
+
+void AcpiOsRedirectOutput(void *Destination)
+{
+       // TODO: Do I even need to impliment this?
+}
+
+// --- Miscellaneous ---
+UINT64 AcpiOsGetTimer(void)
+{
+       return now() * 10 * 1000;
+}
+
+ACPI_STATUS AcpiOsSignal(UINT32 Function, void *Info)
+{
+       switch(Function)
+       {
+       case ACPI_SIGNAL_FATAL: {
+               ACPI_SIGNAL_FATAL_INFO  *finfo = Info;
+               Log_Error("ACPI AML", "Fatal %x %x %x", finfo->Type, finfo->Code, finfo->Argument);
+               break; }
+       case ACPI_SIGNAL_BREAKPOINT: {
+               Log_Notice("ACPI AML", "Breakpoint %s", Info);
+               break; };
+       }
+       return AE_OK;
+}
+
+ACPI_STATUS AcpiOsGetLine(char *Buffer, UINT32 BufferLength, UINT32 *BytesRead)
+{
+       UNIMPLEMENTED();
+       return AE_NOT_IMPLEMENTED;
+}
+
index 8a98705..6586845 100644 (file)
@@ -45,6 +45,7 @@ struct sShortSpinlock {
        #if LOCK_DISABLE_INTS
         int    IF;     //!< Interrupt state on call to SHORTLOCK
        #endif
+       void    *LockedBy;
 };
 
 // === MACROS ===
@@ -77,7 +78,6 @@ typedef signed char           Sint8;
 typedef signed short   Sint16;
 typedef signed long            Sint32;
 typedef signed long long       Sint64;
-typedef Uint   size_t;
 typedef char   BOOL;
 
 typedef Uint32 tPAddr;
index 0a19510..7250deb 100644 (file)
@@ -66,10 +66,17 @@ int IRQ_AddHandler( int Num, void (*Callback)(int, void*), void *Ptr )
                        Log_Log("IRQ", "Added IRQ%i Cb#%i %p", Num, i, Callback);
                        gIRQ_Handlers[Num][i] = Callback;
                        gaIRQ_DataPointers[Num][i] = Ptr;
-                       return 1;
+                       return Num * MAX_CALLBACKS_PER_IRQ + i;
                }
        }
 
        Log_Warning("IRQ", "No free callbacks on IRQ%i", Num);
-       return 0;
+       return -1;
+}
+
+void IRQ_RemHandler(int Handle)
+{
+        int    Num = Handle / MAX_CALLBACKS_PER_IRQ;
+        int    id = Handle % MAX_CALLBACKS_PER_IRQ;
+       gIRQ_Handlers[Num][id] = NULL;
 }
index 6b3d722..b732f75 100644 (file)
@@ -85,6 +85,12 @@ void SHORTLOCK(struct sShortSpinlock *Lock)
        __ASM__ ("pushf;\n\tpop %0" : "=r"(IF));
        IF &= 0x200;    // AND out all but the interrupt flag
        
+       if( CPU_HAS_LOCK(Lock) )
+       {
+               Panic("Double lock of %p, %p req, %p has", Lock, __builtin_return_address(0), Lock->LockedBy);
+               for(;;);
+       }
+
        #if TRACE_LOCKS
        if( TRACE_LOCK_COND )
        {
@@ -98,6 +104,7 @@ void SHORTLOCK(struct sShortSpinlock *Lock)
        // Wait for another CPU to release
        __AtomicTestSetLoop( (Uint*)&Lock->Lock, cpu );
        Lock->IF = IF;
+       Lock->LockedBy = __builtin_return_address(0);
        
        #if TRACE_LOCKS
        if( TRACE_LOCK_COND )
index a09b29a..533b05d 100644 (file)
@@ -3,8 +3,7 @@
  * Linker Script
  */
 
-lowStart = start - 0xC0000000;
-ENTRY(lowStart)
+ENTRY(start)
 OUTPUT_FORMAT(elf32-i386)
 
 SECTIONS {
@@ -12,6 +11,7 @@ SECTIONS {
        __load_addr = .;
        .multiboot : AT(ADDR(.multiboot)) {
                *(.multiboot)
+               *(.inittext)
        }
        
        . += 0xC0000000;
index af9007d..8f36f47 100644 (file)
@@ -24,6 +24,7 @@ extern void   MM_PreinitVirtual(void);
 extern void    MM_Install(int NPMemRanges, tPMemMapEnt *PMemRanges);
 extern void    MM_InstallVirtual(void);
 extern int     Time_Setup(void);
+//extern int   ACPICA_Initialise(void);
 
 // === PROTOTYPES ===
  int   kmain(Uint MbMagic, void *MbInfoPtr);
@@ -54,7 +55,7 @@ int kmain(Uint MbMagic, void *MbInfoPtr)
                gsBootCmdLine = (char*)(mbInfo->CommandLine + KERNEL_BASE);
 
                // Adjust Multiboot structure address
-               mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE );
+               mbInfo = (void*)( (tVAddr)MbInfoPtr + KERNEL_BASE );
 
                nPMemMapEnts = Multiboot_LoadMemoryMap(mbInfo, KERNEL_BASE, pmemmap, MAX_PMEMMAP_ENTS,
                        KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_BASE);
@@ -79,13 +80,14 @@ int kmain(Uint MbMagic, void *MbInfoPtr)
        
        MM_InstallVirtual();    // Clean up virtual address space
        Heap_Install();         // Create initial heap
+       Time_Setup();   // Initialise timing
        
        // Start Multitasking
        Threads_Init();
-       
-       // Start Timers
-       Time_Setup();
-       
+
+       // Poke ACPICA
+//     ACPICA_Initialise();    
+
        Log_Log("Arch", "Starting VFS...");
        // Load Virtual Filesystem
        VFS_Init();
index 5fe4068..7403f38 100644 (file)
@@ -5,7 +5,7 @@
  * mboot.c
  * - Multiboot Support
  */
-#define DEBUG  0
+#define DEBUG  1
 #include <acess.h>
 #include <mboot.h>
 
@@ -19,51 +19,90 @@ int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *
        ENTER("pMBInfo pMapOffset pMap iMapSize PKStart PKEnd",
                MBInfo, MapOffset, Map, MapSize, KStart, KEnd);
 
-       // Build up memory map
-       nPMemMapEnts = 0;
-       while( ent < last && nPMemMapEnts < MapSize )
+       // Check that the memory map is present
+       if( MBInfo->Flags & (1 << 6) )
        {
-               tPMemMapEnt     *nent = &Map[nPMemMapEnts];
-               nent->Start = ent->Base;
-               nent->Length = ent->Length;
-               switch(ent->Type)
+               // Build up memory map
+               nPMemMapEnts = 0;
+               while( ent < last && nPMemMapEnts < MapSize )
                {
-               case 1:
-                       nent->Type = PMEMTYPE_FREE;
-                       break;
-               default:
-                       nent->Type = PMEMTYPE_RESERVED;
-                       break;
+                       tPMemMapEnt     *nent = &Map[nPMemMapEnts];
+                       if( !MM_GetPhysAddr(ent) )
+                               Log_KernelPanic("MBoot", "MBoot Map entry %i addres bad (%p)",
+                                       nPMemMapEnts, ent);
+                       LOG("%llx+%llx", ent->Base, ent->Length);
+       
+                       nent->Start = ent->Base;
+                       nent->Length = ent->Length;
+                       switch(ent->Type)
+                       {
+                       case 1:
+                               nent->Type = PMEMTYPE_FREE;
+                               break;
+                       default:
+                               nent->Type = PMEMTYPE_RESERVED;
+                               break;
+                       }
+                       nent->NUMADomain = 0;
+                       
+                       nPMemMapEnts ++;
+                       ent = (void*)( (tVAddr)ent + ent->Size + 4 );
                }
-               nent->NUMADomain = 0;
-               
-               nPMemMapEnts ++;
-               ent = (void*)( (tVAddr)ent + ent->Size + 4 );
+       }
+       else if( MBInfo->Flags & (1 << 0) )
+       {
+               Log_Warning("MBoot", "No memory map passed, using mem_lower and mem_upper");
+               nPMemMapEnts = 2;
+               Map[0].Start = 0;
+               Map[0].Length = MBInfo->LowMem * 1024;
+               Map[0].Type = PMEMTYPE_FREE;
+               Map[0].NUMADomain = 0;
+
+               Map[1].Start = 0x100000;
+               Map[1].Length = MBInfo->HighMem * 1024;
+               Map[1].Type = PMEMTYPE_FREE;
+               Map[1].NUMADomain = 0;
+       }
+       else
+       {
+               Log_KernelPanic("MBoot", "Multiboot didn't pass memory information");
        }
 
        // Ensure it's valid
+       LOG("Validating");
        nPMemMapEnts = PMemMap_ValidateMap(Map, nPMemMapEnts, MapSize);
        // TODO: Error handling
 
        // Replace kernel with PMEMTYPE_USED
+       LOG("Marking kernel");
        nPMemMapEnts = PMemMap_MarkRangeUsed(
                Map, nPMemMapEnts, MapSize,
                KStart, KEnd - KStart
                );
 
-       // Replace modules with PMEMTYPE_USED
-       nPMemMapEnts = PMemMap_MarkRangeUsed(Map, nPMemMapEnts, MapSize,
-               MBInfo->Modules, MBInfo->ModuleCount*sizeof(tMBoot_Module)
-               );
-       tMBoot_Module *mods = (void*)( (tVAddr)MBInfo->Modules + MapOffset);
-       for( int i = 0; i < MBInfo->ModuleCount; i ++ )
+       LOG("Dumping");
+       PMemMap_DumpBlocks(Map, nPMemMapEnts);
+
+       // Check if boot modules were passed
+       if( MBInfo->Flags & (1 << 3) )
        {
-               nPMemMapEnts = PMemMap_MarkRangeUsed(
-                       Map, nPMemMapEnts, MapSize,
-                       mods->Start, mods->End - mods->Start
+               // Replace modules with PMEMTYPE_USED
+               nPMemMapEnts = PMemMap_MarkRangeUsed(Map, nPMemMapEnts, MapSize,
+                       MBInfo->Modules, MBInfo->ModuleCount*sizeof(tMBoot_Module)
                        );
+               LOG("MBInfo->Modules = %x", MBInfo->Modules);
+               tMBoot_Module *mods = (void*)( (tVAddr)MBInfo->Modules + MapOffset);
+               for( int i = 0; i < MBInfo->ModuleCount; i ++ )
+               {
+                       LOG("&mods[%i] = %p", i, &mods[i]);
+                       LOG("mods[i] = {0x%x -> 0x%x}", mods[i].Start, mods[i].End);
+                       nPMemMapEnts = PMemMap_MarkRangeUsed(
+                               Map, nPMemMapEnts, MapSize,
+                               mods[i].Start, mods[i].End - mods[i].Start
+                               );
+               }
        }
-       
+               
        // Debug - Output map
        PMemMap_DumpBlocks(Map, nPMemMapEnts);
 
@@ -73,6 +112,12 @@ int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *
 
 tBootModule *Multiboot_LoadModules(tMBoot_Info *MBInfo, tVAddr MapOffset, int *ModuleCount)
 {
+       if( !(MBInfo->Flags & (1 << 3)) ) {
+               *ModuleCount = 0;
+               Log_Log("Arch", "No multiboot module information passed");
+               return NULL;
+       }
+
        tMBoot_Module   *mods = (void*)( MBInfo->Modules + MapOffset );
        *ModuleCount = MBInfo->ModuleCount;
        tBootModule *ret = malloc( MBInfo->ModuleCount * sizeof(*ret) );
index f785ba4..2b2a764 100644 (file)
@@ -101,6 +101,7 @@ void MM_Install(int NPMemRanges, tPMemMapEnt *PMemRanges)
        
        gaPageReferences = (void*)MM_REFCOUNT_BASE;
 
+       Log_Debug("PMem", "maxAddr = %P", maxAddr);
        Log_Log("PMem", "Physical memory set up (%lli pages of ~%lli MiB used)",
                giPhysAlloc, (giTotalMemorySize*PAGE_SIZE)/(1024*1024)
                );
@@ -240,6 +241,8 @@ tPAddr MM_AllocPhys(void)
        Mutex_Release( &glPhysAlloc );
        
        LEAVE('X', ret);
+       if( ret == 0x17FFE000 )
+               LogF("TRIP!\n");
        #if TRACE_ALLOCS
        if( now() > 4000 ) {
        Log_Debug("PMem", "MM_AllocPhys: RETURN %P (%i free)", ret, giPageCount-giPhysAlloc);
index de0d5c3..d3aea16 100644 (file)
@@ -404,21 +404,42 @@ void MP_StartAP(int CPU)
        *(Uint16*)(KERNEL_BASE|0x469) = 0xFFFF;
        outb(0x70, 0x0F);       outb(0x71, 0x0A);       // Set warm reset flag
        MP_SendIPI(gaCPUs[CPU].APICID, 0, 5);   // Init IPI
-       
-       // Delay
-       inb(0x80); inb(0x80); inb(0x80); inb(0x80);
-       
+
+       // Take a quick nap (20ms)
+       Time_Delay(20);
+
        // TODO: Use a better address, preferably registered with the MM
        // - MM_AllocDMA mabye?
        // Create a far jump
        *(Uint8*)(KERNEL_BASE|0x11000) = 0xEA;  // Far JMP
-       *(Uint16*)(KERNEL_BASE|0x11001) = (Uint)&APStartup - (KERNEL_BASE|0xFFFF0);     // IP
+       *(Uint16*)(KERNEL_BASE|0x11001) = (Uint16)&APStartup + 0x10;    // IP
        *(Uint16*)(KERNEL_BASE|0x11003) = 0xFFFF;       // CS
+       
+       giNumInitingCPUs ++;
+       
        // Send a Startup-IPI to make the CPU execute at 0x11000 (which we
        // just filled)
        MP_SendIPI(gaCPUs[CPU].APICID, 0x11, 6);        // StartupIPI
        
-       giNumInitingCPUs ++;
+       tTime   timeout = now() + 2;
+       while( giNumInitingCPUs && now() > timeout )
+               HALT();
+       
+       if( giNumInitingCPUs == 0 )
+               return ;
+       
+       // First S-IPI failed, send again
+       MP_SendIPI(gaCPUs[CPU].APICID, 0x11, 6);
+       timeout = now() + 2;
+       while( giNumInitingCPUs && now() > timeout )
+               HALT();
+       if( giNumInitingCPUs == 0 )
+               return ;
+
+       Log_Notice("Proc", "CPU %i (APIC %x) didn't come up", CPU, gaCPUs[CPU].APICID); 
+
+       // Oh dammit.
+       giNumInitingCPUs = 0;
 }
 
 void MP_SendIPIVector(int CPU, Uint8 Vector)
@@ -439,11 +460,9 @@ void MP_SendIPI(Uint8 APICID, int Vector, int DeliveryMode)
        
        // Hi
        val = (Uint)APICID << 24;
-//     Log("%p = 0x%08x", &gpMP_LocalAPIC->ICR[1], val);
        gpMP_LocalAPIC->ICR[1].Val = val;
        // Low (and send)
        val = ((DeliveryMode & 7) << 8) | (Vector & 0xFF);
-//     Log("%p = 0x%08x", &gpMP_LocalAPIC->ICR[0], val);
        gpMP_LocalAPIC->ICR[0].Val = val;
 }
 #endif
@@ -468,15 +487,17 @@ void Proc_IdleThread(void *Ptr)
 void Proc_Start(void)
 {
        #if USE_MP
-        int    i;
-       #endif
+       // BSP still should run the current task
+       gaCPUs[giProc_BootProcessorID].Current = &gThreadZero;
+       
+       __asm__ __volatile__ ("sti");
        
-       #if USE_MP
        // Start APs
-       for( i = 0; i < giNumCPUs; i ++ )
+       for( int i = 0; i < giNumCPUs; i ++ )
        {
-               if(i)   gaCPUs[i].Current = NULL;
-               
+               if(i != giProc_BootProcessorID)
+                       gaCPUs[i].Current = NULL;
+
                // Create Idle Task
                Proc_NewKThread(Proc_IdleThread, &gaCPUs[i]);
                
@@ -485,14 +506,6 @@ void Proc_Start(void)
                        MP_StartAP( i );
                }
        }
-       
-       // BSP still should run the current task
-       gaCPUs[0].Current = &gThreadZero;
-       
-       // Start interrupts and wait for APs to come up
-       Log_Debug("Proc", "Waiting for APs to come up");
-       __asm__ __volatile__ ("sti");
-       while( giNumInitingCPUs )       __asm__ __volatile__ ("hlt");
        #else
        // Create Idle Task
        Proc_NewKThread(Proc_IdleThread, &gaCPUs[0]);
@@ -663,7 +676,7 @@ tPID Proc_Clone(Uint Flags)
  * \fn int Proc_SpawnWorker(void)
  * \brief Spawns a new worker thread
  */
-int Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
+tThread *Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
 {
        tThread *new;
        Uint    stack_contents[4];
@@ -672,7 +685,7 @@ int Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
        new = Threads_CloneThreadZero();
        if(!new) {
                Warning("Proc_SpawnWorker - Out of heap space!\n");
-               return -1;
+               return NULL;
        }
 
        // Create the stack contents
@@ -694,7 +707,7 @@ int Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
        new->Status = THREAD_STAT_PREINIT;
        Threads_AddActive( new );
        
-       return new->TID;
+       return new;
 }
 
 /**
index 1d4a35d..7602b9b 100644 (file)
@@ -55,7 +55,7 @@ mboot:
 ;      dd      8
 ;mboot2_end:
        
-[section .text]
+[section .inittext]
 [extern kmain]
 [extern Desctab_Install]
 [global start]
@@ -137,13 +137,13 @@ APStartup:
        ; Load initial GDT
        mov ax, 0xFFFF
        mov ds, ax
-       lgdt [DWORD ds:lGDTPtr-KERNEL_BASE-0xFFFF0]
+       lgdt [DWORD ds:lGDTPtr-0xFFFF0]
        ; Enable PMode in CR0
        mov eax, cr0
        or al, 1
        mov cr0, eax
        ; Jump into PMode
-       jmp 08h:DWORD .ProtectedMode-KERNEL_BASE
+       jmp 08h:DWORD .ProtectedMode
 [bits 32]
 .ProtectedMode:
        ; Load segment registers
@@ -218,6 +218,10 @@ APStartup:
        jmp .hlt
 %endif
 
+;
+;
+;
+[section .text]
 [global GetEIP]
 GetEIP:
        mov eax, [esp]
diff --git a/KernelLand/Kernel/arch/x86/vpci.c b/KernelLand/Kernel/arch/x86/vpci.c
new file mode 100644 (file)
index 0000000..0319e6e
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Acess2 Kernel x86 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * vpci.c
+ * - Virtual PCI Bus
+ */
+#include <virtual_pci.h>
+
+// === GLOBALS ===
+ int   giVPCI_DeviceCount = 0;
+tVPCI_Device   gaVPCI_Devices[0];
+
index 4c030a5..17adec9 100644 (file)
@@ -26,7 +26,7 @@ endif
 A_OBJ := start32.ao start64.ao desctab.ao proc.ao
 A_OBJ += main.o lib.o proc.o mm_virt.o mm_phys.o
 A_OBJ += kernelpanic.o errors.o time.o pci.o
-A_OBJ += vm8086.o
+A_OBJ += vm8086.o vpci.o
 A_OBJ += ../x86/mboot.o
 # rme.o
 
index 6e8aa63..e833173 100644 (file)
@@ -5,6 +5,7 @@
 [BITS 64]
 
 [extern Log]
+[extern Log_Debug]
 [extern gGDTPtr]
 [extern gGDT]
 
@@ -167,11 +168,11 @@ IRQ_AddHandler:
        push rax
        push rdx
        sub rsp, 8
-       mov rcx, rdi    ; IRQ Number
-       mov rdx, rsi    ; Callback
-       mov rsi, rax    ; Pointer
-       mov rdi, csIRQ_Assigned
-       call Log
+       mov rcx, rsi    ; IRQ Number
+       mov rdx, rdi    ; Callback
+       mov rsi, csIRQ_Assigned
+       mov rdi, csIRQ_Tag
+       call Log_Debug
        add rsp, 8
        pop rdx
        pop rax
@@ -189,9 +190,11 @@ IRQ_AddHandler:
        
 [section .rodata]
 csIRQ_Assigned:
-       db      "IRQ %p := %p (IRQ %i)",0
+       db      "IRQ %i .= %p",0
 csIRQ_Fired:
        db      "IRQ %i fired",0
+csIRQ_Tag:
+       db      "IRQ",0
 [section .text]
 
 %macro ISR_NOERRNO     1
@@ -273,17 +276,23 @@ DEFIRQ    i
 %assign i i+1
 %endrep
 
+[extern Proc_int_SetIRQIP]
+
 [global IrqCommon]
 IrqCommon:
        PUSH_GPR
        push gs
        push fs
-
+       
+       mov rdi, [rsp+(16+2+2)*8]       ; 2SReg + GPRs + Int/Errcode = RIP
+       call Proc_int_SetIRQIP
+       push rax
+       
 ;      mov rdi, csIRQ_Fired
 ;      mov rsi, [rsp+(16+2)*8]
 ;      call Log
        
-       mov ebx, [rsp+(16+2)*8] ; Get interrupt number (16 GPRS + 2 SRs)
+       mov ebx, [rsp+(1+2+16)*8]       ; Get interrupt number (16 GPRS + 2 SRs)
        shl ebx, 2      ; *4
        mov rax, gaIRQ_Handlers
        lea rbx, [rax+rbx*8]
@@ -297,7 +306,7 @@ IrqCommon:
        test rax, rax   ; Check if it exists
        jz .skip.%[i]
        ; Set RDI to IRQ number
-       mov rdi, [rsp+(16+2+1)*8]       ; Get IRQ number
+       mov rdi, [rsp+(16+2+1+1)*8]     ; Get IRQ number
        mov rsi, [rbx-gaIRQ_Handlers+gaIRQ_DataPtrs]
        call rax        ; Call
 .skip.%[i]:
@@ -308,12 +317,15 @@ IrqCommon:
        
        ; ACK
        mov al, 0x20
-       mov rdi, [rsp+(16+2)*8] ; Get IRQ number
+       mov rdi, [rsp+(16+2+1)*8]       ; Get IRQ number
        cmp rdi, 8
        jb .skipAckSecondary
        out 0xA0, al
 .skipAckSecondary:
        out 0x20, al
+
+       pop rdi
+       call Proc_int_SetIRQIP
        
        pop fs
        pop gs
@@ -395,7 +407,10 @@ SyscallStub:
        mov [rsp+0x28], r10     ; Arg4
        mov [rsp+0x30], r8      ; Arg5
        mov [rsp+0x38], r9      ; Arg6
-       
+
+       mov rdi, rcx    
+       call Proc_int_SetIRQIP
+
        mov rdi, rsp
        sub rsp, 8
        call SyscallHandler
index e7812c3..fda3113 100644 (file)
@@ -13,6 +13,7 @@
 extern int     MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs);
 extern void    Error_Backtrace(Uint IP, Uint BP);
 extern void    Proc_EnableSSE(void);
+extern void    Threads_Dump(void);
 extern void    Proc_RestoreSSE(Uint32 Data);
 
 // === PROTOTYPES ===
@@ -98,6 +99,9 @@ void Error_Handler(tRegs *Regs)
                        *(Uint8*)(Regs->RIP+2), *(Uint8*)(Regs->RIP+3)
                        );
                break;
+       case 2: // NMI
+               Threads_Dump();
+               break;
        }
        
        __asm__ __volatile__ ("cli");
index 6cf25f0..120afb3 100644 (file)
@@ -84,7 +84,7 @@
 // === FUNCTIONS ===
 void   MM_FinishVirtualInit(void);
 tVAddr MM_NewKStack(void);
-tVAddr MM_Clone(void);
+tVAddr MM_Clone(int bCopyUser);
 tVAddr MM_NewWorkerStack(void *StackData, size_t StackSize);
 
 #endif
index 5b9609a..385b677 100644 (file)
@@ -373,3 +373,6 @@ Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
        return ret;
 }
 
+EXPORT(memcpy);
+EXPORT(memset);
+
index 0348de6..a855a47 100644 (file)
@@ -14,6 +14,7 @@
 // === CONSTANTS ===
 #define KERNEL_LOAD    0x100000
 #define MAX_PMEMMAP_ENTS       16
+#define MAX_ARGSTR_POS (0x200000-0x2000)
 
 // === IMPORTS ===
 extern void    Desctab_Init(void);
@@ -28,6 +29,8 @@ void  kmain(Uint MbMagic, void *MbInfoPtr);
 
 // === GLOBALS ==
 char   *gsBootCmdLine = NULL;
+tBootModule    *gaArch_BootModules;
+ int   giArch_NumBootModules = 0;
 
 // === CODE ===
 void kmain(Uint MbMagic, void *MbInfoPtr)
@@ -50,6 +53,7 @@ void kmain(Uint MbMagic, void *MbInfoPtr)
                // Adjust Multiboot structure address
                mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE );
                gsBootCmdLine = (char*)( (Uint)mbInfo->CommandLine + KERNEL_BASE);
+               // TODO: ref above?
                nPMemMapEnts = Multiboot_LoadMemoryMap(mbInfo, KERNEL_BASE, pmemmap, MAX_PMEMMAP_ENTS,
                        KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_BASE
                        );
@@ -63,6 +67,13 @@ void kmain(Uint MbMagic, void *MbInfoPtr)
        MM_InitPhys( nPMemMapEnts, pmemmap );   // Set up physical memory manager
        Log("gsBootCmdLine = '%s'", gsBootCmdLine);
        
+       switch(MbMagic)
+       {
+       case MULTIBOOT_MAGIC:
+               MM_RefPhys( mbInfo->CommandLine );
+               break;
+       }
+
        *(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'D';
        Heap_Install();
        
@@ -76,6 +87,8 @@ void kmain(Uint MbMagic, void *MbInfoPtr)
        Log_Log("Arch", "Starting VFS...");
        VFS_Init();
        
+       gaArch_BootModules = Multiboot_LoadModules(mbInfo, KERNEL_BASE, &giArch_NumBootModules);
+       
        *(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'Z';
        
        // Pass on to Independent Loader
@@ -89,7 +102,32 @@ void kmain(Uint MbMagic, void *MbInfoPtr)
 
 void Arch_LoadBootModules(void)
 {
-       
+        int    i, j, numPages;
+       Log("gsBootCmdLine = '%s'", gsBootCmdLine);
+       for( i = 0; i < giArch_NumBootModules; i ++ )
+       {
+               Log_Log("Arch", "Loading '%s'", gaArch_BootModules[i].ArgString);
+               
+               if( !Module_LoadMem( gaArch_BootModules[i].Base,
+                       gaArch_BootModules[i].Size, gaArch_BootModules[i].ArgString
+                       ) )
+               {
+                       Log_Warning("Arch", "Unable to load module");
+               }
+               
+               // Unmap and free
+               numPages = (gaArch_BootModules[i].Size + ((Uint)gaArch_BootModules[i].Base&0xFFF) + 0xFFF) >> 12;
+               MM_UnmapHWPages( (tVAddr)gaArch_BootModules[i].Base, numPages );
+               
+               for( j = 0; j < numPages; j++ )
+                       MM_DerefPhys( gaArch_BootModules[i].PBase + (j << 12) );
+               
+               if( (tVAddr) gaArch_BootModules[i].ArgString < KERNEL_BASE )
+                       MM_UnmapHWPages( (tVAddr)gaArch_BootModules[i].ArgString, 2 );
+       }
+       Log_Log("Arch", "Boot modules loaded");
+       if( gaArch_BootModules )
+               free( gaArch_BootModules );
 }
 
 void StartupPrint(const char *String)
index 14117f4..de7ae52 100644 (file)
@@ -340,8 +340,8 @@ void MM_DumpTables(tVAddr Start, tVAddr End)
                                expected |= expected_pml4 & PF_NX;
                                expected |= expected_pdp  & PF_NX;
                                expected |= expected_pd   & PF_NX;
-                               Log("expected (pml4 = %x, pdp = %x, pd = %x)",
-                                       expected_pml4, expected_pdp, expected_pd);
+//                             Log("expected (pml4 = %x, pdp = %x, pd = %x)",
+//                                     expected_pml4, expected_pdp, expected_pd);
                                // Dump
                                MM_int_DumpTablesEnt( rangeStart, curPos - rangeStart, expected );
                                expected = CHANGEABLE_BITS;
@@ -722,43 +722,73 @@ int MM_IsValidBuffer(tVAddr Addr, size_t Size)
 
        Size += Addr & (PAGE_SIZE-1);
        Addr &= ~(PAGE_SIZE-1);
-       Addr &= ((1UL << 48)-1);        // Clap to address space
+       // NC addr
+       if( ((Addr >> 47) & 1) != ((Addr>>48) == 0xFFFF))
+               return 0;
+       Addr &= ((1UL << 48)-1);        // Clamp to address space
 
        pml4 = Addr >> 39;
        pdp = Addr >> 30;
        dir = Addr >> 21;
        tab = Addr >> 12;
 
-       if( !(PAGEMAPLVL4(pml4) & 1) )  return 0;
-       if( !(PAGEDIRPTR(pdp) & 1) )    return 0;
-       if( !(PAGEDIR(dir) & 1) )       return 0;
-       if( !(PAGETABLE(tab) & 1) )     return 0;
+       if( !(PAGEMAPLVL4(pml4) & 1) ) {
+               Log_Debug("MMVirt", "PML4E %i NP", pml4);
+               return 0;
+       }
+       if( !(PAGEDIRPTR(pdp) & 1) ) {
+               Log_Debug("MMVirt", "PDPE %i NP", pdp);
+               return 0;
+       }
+       if( !(PAGEDIR(dir) & 1) ) {
+               Log_Debug("MMVirt", "PDE %i NP", dir);
+               return 0;
+       }
+       if( !(PAGETABLE(tab) & 1) ) {
+               Log_Debug("MMVirt", "PTE %i NP", tab);
+               return 0;
+       }
        
        bIsUser = !!(PAGETABLE(tab) & PF_USER);
 
        while( Size >= PAGE_SIZE )
        {
+               tab ++;
+               Size -= PAGE_SIZE;
+               
                if( (tab & 511) == 0 )
                {
                        dir ++;
-                       if( ((dir >> 9) & 511) == 0 )
+                       if( (dir & 511) == 0 )
                        {
                                pdp ++;
-                               if( ((pdp >> 18) & 511) == 0 )
+                               if( (pdp & 511) == 0 )
                                {
                                        pml4 ++;
-                                       if( !(PAGEMAPLVL4(pml4) & 1) )  return 0;
+                                       if( !(PAGEMAPLVL4(pml4) & 1) ) {
+                                               Log_Debug("MMVirt", "IsValidBuffer - PML4E %x NP, Size=%x", pml4, Size);
+                                               return 0;
+                                       }
                                }
-                               if( !(PAGEDIRPTR(pdp) & 1) )    return 0;
+                               if( !(PAGEDIRPTR(pdp) & 1) ) {
+                                       Log_Debug("MMVirt", "IsValidBuffer - PDPE %x NP", pdp);
+                                       return 0;
+                               }
+                       }
+                       if( !(PAGEDIR(dir) & 1) ) {
+                               Log_Debug("MMVirt", "IsValidBuffer - PDE %x NP", dir);
+                               return 0;
                        }
-                       if( !(PAGEDIR(dir) & 1) )       return 0;
                }
                
-               if( !(PAGETABLE(tab) & 1) )   return 0;
-               if( bIsUser && !(PAGETABLE(tab) & PF_USER) )    return 0;
-
-               tab ++;
-               Size -= PAGE_SIZE;
+               if( !(PAGETABLE(tab) & 1) ) {
+                       Log_Debug("MMVirt", "IsValidBuffer - PTE %x NP", tab);
+                       return 0;
+               }
+               if( bIsUser && !(PAGETABLE(tab) & PF_USER) ) {
+                       Log_Debug("MMVirt", "IsValidBuffer - PTE %x Not user", tab);
+                       return 0;
+               }
        }
        return 1;
 }
@@ -849,6 +879,7 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
        
        // Allocated successfully, now map
        ret = MM_MapHWPages(phys, Pages);
+       *PhysAddr = phys;
        // MapHWPages references the pages, so deref them back down to 1
        for(;Pages--;phys+=0x1000)
                MM_DerefPhys(phys);
@@ -857,7 +888,6 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
                return 0;
        }
        
-       *PhysAddr = phys;
        return ret;
 }
 
@@ -894,7 +924,7 @@ void MM_FreeTemp(void *Ptr)
 
 
 // --- Address Space Clone --
-tPAddr MM_Clone(void)
+tPAddr MM_Clone(int bNoUserCopy)
 {
        tPAddr  ret;
         int    i;
@@ -910,7 +940,7 @@ tPAddr MM_Clone(void)
        INVLPG_ALL();
        
        // #3 Set Copy-On-Write to all user pages
-       if( Threads_GetPID() != 0 )
+       if( Threads_GetPID() != 0 && !bNoUserCopy )
        {
                for( i = 0; i < 256; i ++)
                {
@@ -1070,8 +1100,6 @@ tVAddr MM_NewWorkerStack(void *StackData, size_t StackSize)
                tmp_addr = MM_MapTemp(phys);
                dest = (char*)tmp_addr + (0x1000 - StackSize);
                memcpy( dest, StackData, StackSize );
-               Log_Debug("MM", "MM_NewWorkerStack: %p->%p %i bytes (i=%i)", StackData, dest, StackSize, i);
-               Log_Debug("MM", "MM_NewWorkerStack: ret = %p", ret);
                MM_FreeTemp(tmp_addr);
        }
 
index f540b3b..f3b3a28 100644 (file)
@@ -21,7 +21,7 @@ NewTaskHeader:
        mov rdi, [rsp+0x10]
        mov rax, [rsp+0x8]
        add rsp, 0x10   ; Reclaim stack space (thread/fcn)
-       xchg bx, bx
+       ;xchg bx, bx
        call rax
        
        ; Quit thread with RAX as the return code
@@ -39,6 +39,8 @@ Proc_CloneInt:
        PUSH_GPR
        ; Save RSP
        mov [rdi], rsp
+       ; Call MM_Clone (with bNoUserCopy flag)
+       mov rdi, rdx
        call MM_Clone
        ; Save CR3
        mov rsi, [rsp+0x30]     ; Saved version of RSI
index 18cfd02..46e2b21 100644 (file)
@@ -37,7 +37,7 @@ extern void   APStartup(void);        // 16-bit AP startup code
 
 extern Uint    GetRIP(void);   // start.asm
 extern Uint    SaveState(Uint *RSP, Uint *Regs);
-extern Uint    Proc_CloneInt(Uint *RSP, Uint *CR3);
+extern Uint    Proc_CloneInt(Uint *RSP, Uint *CR3, int bCopyUserVM);
 extern void    NewTaskHeader(void);    // Actually takes cdecl args
 extern void    Proc_InitialiseSSE(void);
 extern void    Proc_SaveSSE(Uint DestPtr);
@@ -75,6 +75,7 @@ void  Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP) NO
 //void Proc_DumpThreadCPUState(tThread *Thread);
 //void Proc_Reschedule(void);
 void   Proc_Scheduler(int CPU, Uint RSP, Uint RIP);
+Uint   Proc_int_SetIRQIP(Uint RIP);
 
 // === GLOBALS ===
 //!\brief Used by desctab.asm in SyscallStub
@@ -507,7 +508,7 @@ tTID Proc_Clone(Uint Flags)
        if(!newThread)  return -1;
        
        // Save core machine state
-       rip = Proc_CloneInt(&newThread->SavedState.RSP, &newThread->Process->MemState.CR3);
+       rip = Proc_CloneInt(&newThread->SavedState.RSP, &newThread->Process->MemState.CR3, !!(Flags & CLONE_NOUSER));
        if(rip == 0)    return 0;       // Child
        newThread->KernelStack = cur->KernelStack;
        newThread->SavedState.RIP = rip;
@@ -534,7 +535,7 @@ tTID Proc_Clone(Uint Flags)
  * \fn int Proc_SpawnWorker(void)
  * \brief Spawns a new worker thread
  */
-int Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
+tThread *Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
 {
        tThread *new, *cur;
        Uint    stack_contents[3];
@@ -545,7 +546,7 @@ int Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
        new = Threads_CloneThreadZero();
        if(!new) {
                Warning("Proc_SpawnWorker - Out of heap space!\n");
-               return -1;
+               return NULL;
        }
 
        // Create the stack contents
@@ -567,7 +568,7 @@ int Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
        new->Status = THREAD_STAT_PREINIT;
        Threads_AddActive( new );
        
-       return new->TID;
+       return new;
 }
 
 /**
@@ -725,7 +726,14 @@ void Proc_CallFaultHandler(tThread *Thread)
 
 void Proc_DumpThreadCPUState(tThread *Thread)
 {
-       Log("  At %04x:%016llx", Thread->SavedState.UserCS, Thread->SavedState.UserRIP);
+       if( Thread->CurCPU == GetCPUNum() ) {
+               // TODO: Backtrace to IRQ
+               Log("  IRQ %016llx", Thread->SavedState.UserRIP);
+       }
+       else {
+               Log("  At %016llx, SP=%016llx", Thread->SavedState.RIP, Thread->SavedState.RSP);
+               Log("  User %04x:%016llx", Thread->SavedState.UserCS, Thread->SavedState.UserRIP);
+       }
 }
 
 void Proc_Reschedule(void)
@@ -758,7 +766,7 @@ void Proc_Reschedule(void)
 
        // Update CPU state
        gaCPUs[cpu].Current = nextthread;
-       gTSSs[cpu].RSP0 = nextthread->KernelStack-4;
+       gTSSs[cpu].RSP0 = nextthread->KernelStack-sizeof(void*);
        __asm__ __volatile__ ("mov %0, %%db0" : : "r" (nextthread));
 
        if( curthread )
@@ -825,5 +833,14 @@ void Proc_Scheduler(int CPU, Uint RSP, Uint RIP)
 #endif
 }
 
+Uint Proc_int_SetIRQIP(Uint RIP)
+{
+        int    cpu = GetCPUNum();
+       tThread *thread = gaCPUs[cpu].Current;
+       Uint    rv = thread->SavedState.UserRIP;
+       thread->SavedState.UserRIP = RIP;
+       return rv;
+}
+
 // === EXPORTS ===
 EXPORT(Proc_SpawnWorker);
diff --git a/KernelLand/Kernel/arch/x86_64/vpci.c b/KernelLand/Kernel/arch/x86_64/vpci.c
new file mode 100644 (file)
index 0000000..0319e6e
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Acess2 Kernel x86 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * vpci.c
+ * - Virtual PCI Bus
+ */
+#include <virtual_pci.h>
+
+// === GLOBALS ===
+ int   giVPCI_DeviceCount = 0;
+tVPCI_Device   gaVPCI_Devices[0];
+
index b0d96ca..f4c73e2 100644 (file)
@@ -1,19 +1,37 @@
 /*\r
- * Acess v0.1\r
- * ELF Executable Loader Code\r
+ * Acess2 Kernel\r
+ * - By John Hodge (thePowersGang)\r
+ *\r
+ * elf.c\r
+ * - ELF Executable Loader Code\r
  */\r
 #define DEBUG  0\r
 #include <acess.h>\r
 #include <binary.h>\r
 \r
+// ---- Import linking code from userland\r
 #define _COMMON_H\r
 #define SysDebug(v...) LOG(v)\r
-#define DISABLE_ELF64\r
-void   *GetSymbol(const char *Name, size_t *Size);\r
-void   *GetSymbol(const char *Name, size_t *Size) { Uint val; Binary_GetSymbol(Name, &val); if(Size)*Size=0; return (void*)val; };\r
+#if BITS <= 32\r
+# define DISABLE_ELF64\r
+#endif\r
+static int     GetSymbol(const char *Name, void **Value, size_t *Size);\r
+static int     GetSymbol(const char *Name, void **Value, size_t *Size) {\r
+       Uint val;\r
+       if(!Binary_GetSymbol(Name, &val)) {\r
+               Log_Notice("ELF", "Lookup of '%s' failed", Name);\r
+               return 0;\r
+       }\r
+       if(Size)\r
+               *Size=0;\r
+       *Value = (void*)val;\r
+       return 1;\r
+}\r
 #define AddLoaded(a,b) do{}while(0)\r
 #define LoadLibrary(a,b,c)     (Log_Debug("ELF", "Module requested lib '%s'",a),0)\r
+#define _SysSetMemFlags(ad,f,m)        do{}while(0)\r
 #include "../../../Usermode/Libraries/ld-acess.so_src/elf.c"\r
+// ---- / ----\r
 \r
 #define DEBUG_WARN     1\r
 \r
@@ -291,7 +309,7 @@ tBinary *Elf_Load32(int FD, Elf32_Ehdr *Header)
 \r
 int Elf_Relocate(void *Base)\r
 {\r
-       return  ElfRelocate(Base, (char**){NULL}, "") != NULL;\r
+       return ElfRelocate(Base, (char**){NULL}, "") != NULL;\r
 }\r
 int Elf_GetSymbol(void *Base, const char *Name, Uint *ret)\r
 {\r
index de94c6f..208ab95 100644 (file)
@@ -194,9 +194,10 @@ int Proc_SysSpawn(const char *Binary, const char **ArgV, const char **EnvP, int
                Proc_Execve(Binary, ArgV, EnvP, size);
                for(;;);
        }
-       if( ret < 0 )
+       if( ret == -1 )
        {
                VFS_FreeSavedHandles(nFD, handles);
+               free(cachebuf);
        }
        
        return ret;
@@ -822,9 +823,12 @@ Uint Binary_GetSymbolEx(const char *Name, Uint *Value)
        tKernelBin      *pKBin;
         int    numKSyms = ((Uint)&gKernelSymbolsEnd-(Uint)&gKernelSymbols)/sizeof(tKernelSymbol);
        
+       LOG("numKSyms = %i", numKSyms);
+
        // Scan Kernel
        for( i = 0; i < numKSyms; i++ )
        {
+               LOG("KSym %s = %p", gKernelSymbols[i].Name, gKernelSymbols[i].Value);
                if(strcmp(Name, gKernelSymbols[i].Name) == 0) {
                        *Value = gKernelSymbols[i].Value;
                        return 1;
index dab20ad..6132bd9 100644 (file)
@@ -162,27 +162,47 @@ void Debug(const char *Fmt, ...)
        SHORTREL(&glDebug_Lock);
        #endif
 }
-/**
- * \fn void Log(const char *Msg, ...)
- */
-void Log(const char *Fmt, ...)
+
+
+void LogFV(const char *Fmt, va_list args)
 {
-       va_list args;
+       #if LOCK_DEBUG_OUTPUT
+       SHORTLOCK(&glDebug_Lock);
+       #endif
+
+       Debug_Fmt(1, Fmt, args);
        
+       #if LOCK_DEBUG_OUTPUT
+       SHORTREL(&glDebug_Lock);
+       #endif
+}
+
+void LogV(const char *Fmt, va_list args)
+{
        #if LOCK_DEBUG_OUTPUT
        SHORTLOCK(&glDebug_Lock);
        #endif
 
        Debug_Puts(1, "Log: ");
-       va_start(args, Fmt);
        Debug_Fmt(1, Fmt, args);
-       va_end(args);
        Debug_Puts(1, "\r\n");
        
        #if LOCK_DEBUG_OUTPUT
        SHORTREL(&glDebug_Lock);
        #endif
 }
+
+/**
+ * \fn void Log(const char *Msg, ...)
+ */
+void Log(const char *Fmt, ...)
+{
+       va_list args;
+       va_start(args, Fmt);
+       LogV(Fmt, args);
+       va_end(args);
+}
+
 void Warning(const char *Fmt, ...)
 {
        va_list args;
@@ -221,6 +241,7 @@ void Panic(const char *Fmt, ...)
        Debug_Putchar('\n');
 
        Threads_Dump();
+       Heap_Dump();
 
        for(;;) ;
 }
@@ -384,7 +405,7 @@ void Debug_Leave(const char *FuncName, char RetType, ...)
        #endif
 }
 
-void Debug_HexDump(const char *Header, const void *Data, Uint Length)
+void Debug_HexDump(const char *Header, const void *Data, size_t Length)
 {
        const Uint8     *cdat = Data;
        Uint    pos = 0;
index 702c9cc..2e1ce15 100644 (file)
@@ -1,6 +1,9 @@
 /*\r
- * AcessOS/AcessBasic v0.1\r
- * PCI Bus Driver\r
+ * Acess2 Kernel\r
+ * - By John Hodge (thePowersGang)\r
+ * \r
+ * drv/pci.c\r
+ * - PCI Enumeration and Arbitration\r
  */\r
 #define DEBUG  0\r
 #include <acess.h>\r
@@ -9,9 +12,11 @@
 #include <fs_devfs.h>\r
 #include <drv_pci.h>\r
 #include <drv_pci_int.h>\r
+#include <virtual_pci.h>\r
 \r
 #define USE_PORT_BITMAP        0\r
 #define        LIST_DEVICES    1\r
+#define PCI_MAX_BUSSES 8\r
 \r
 // === STRUCTURES ===\r
 typedef struct sPCIDevice\r
@@ -42,6 +47,7 @@ size_t        PCI_int_ReadDevice(tVFS_Node *node, off_t Offset, size_t Length, void *bu
 // === GLOBALS ===\r
 MODULE_DEFINE(0, 0x0100, PCI, PCI_Install, NULL, NULL);\r
  int   giPCI_BusCount = 1;\r
+Uint8  gaPCI_BusNumbers[PCI_MAX_BUSSES];\r
  int   giPCI_InodeHandle = -1;\r
  int   giPCI_DeviceCount = 0;\r
 tPCIDevice     *gPCI_Devices = NULL;\r
@@ -95,12 +101,18 @@ int PCI_Install(char **Arguments)
        #endif  \r
 \r
        // Scan Bus (Bus 0, Don't fill gPCI_Devices)\r
+       giPCI_DeviceCount = 0;\r
+       giPCI_BusCount = 1;\r
+       gaPCI_BusNumbers[0] = 0;\r
        for( bus = 0; bus < giPCI_BusCount; bus ++ )\r
        {\r
-               ret = PCI_ScanBus(bus, 0);\r
+               ret = PCI_ScanBus(gaPCI_BusNumbers[bus], 0);\r
                if(ret != MODULE_ERR_OK)        return ret;\r
        }\r
-               \r
+       // TODO: PCIe\r
+       // - Add VPCI Devices\r
+       giPCI_DeviceCount += giVPCI_DeviceCount;\r
+       \r
        if(giPCI_DeviceCount == 0) {\r
                Log_Notice("PCI", "No devices were found");\r
                return MODULE_ERR_NOTNEEDED;\r
@@ -123,7 +135,33 @@ int PCI_Install(char **Arguments)
        // Rescan, filling the PCI device array\r
        for( bus = 0; bus < giPCI_BusCount; bus ++ )\r
        {\r
-               PCI_ScanBus(bus, 1);\r
+               PCI_ScanBus(gaPCI_BusNumbers[bus], 1);\r
+       }\r
+       // Insert VPCI Devices\r
+       for( int i = 0; i < giVPCI_DeviceCount; i ++ )\r
+       {\r
+               tPCIDevice      *devinfo = &gPCI_Devices[giPCI_DeviceCount];\r
+               \r
+               devinfo->bus = -1;\r
+               devinfo->slot = i;\r
+               devinfo->fcn = 0;\r
+               devinfo->vendor = gaVPCI_Devices[i].Vendor;\r
+               devinfo->device = gaVPCI_Devices[i].Device;\r
+               devinfo->revision = gaVPCI_Devices[i].Class & 0xFF;\r
+               devinfo->class = gaVPCI_Devices[i].Class >> 8;\r
+               snprintf(devinfo->Name, sizeof(devinfo->Name), "%02x.%02x:%x", 0xFF, i, 0);\r
+\r
+               for(int j = 0; j < 256/4; j ++ )\r
+                       devinfo->ConfigCache[i] = VPCI_Read(&gaVPCI_Devices[i], j*4, 4);\r
+\r
+               memset(&devinfo->Node, 0, sizeof(devinfo->Node));\r
+               devinfo->Node.Inode = giPCI_DeviceCount;\r
+               devinfo->Node.Size = 256;\r
+               devinfo->Node.NumACLs = 1;\r
+               devinfo->Node.ACLs = &gVFS_ACL_EveryoneRO;\r
+               devinfo->Node.Type = &gPCI_DevNodeType;\r
+\r
+               giPCI_DeviceCount ++;\r
        }\r
        \r
        // Complete Driver Structure\r
@@ -158,26 +196,12 @@ int PCI_ScanBus(int BusID, int bFill)
                        if(!PCI_int_EnumDevice(BusID, dev, fcn, &devInfo))\r
                                continue;\r
                        \r
-                       if(devInfo.class == PCI_OC_PCIBRIDGE)\r
-                       {\r
-                               #if LIST_DEVICES\r
-                               if( !bFill )\r
-                                       Log_Log("PCI", "Bridge @ %i,%i:%i (0x%x:0x%x)",\r
-                                               BusID, dev, fcn, devInfo.vendor, devInfo.device);\r
-                               #endif\r
-                               //TODO: Handle PCI-PCI Bridges\r
-                               //PCI_ScanBus(devInfo.???, bFill);\r
-                               giPCI_BusCount ++;\r
-                       }\r
-                       else\r
-                       {\r
-                               #if LIST_DEVICES\r
-                               if( !bFill )\r
-                                       Log_Log("PCI", "Device %i,%i:%i %06x => 0x%04x:0x%04x Rev %i",\r
-                                               BusID, dev, fcn, devInfo.class,\r
-                                               devInfo.vendor, devInfo.device, devInfo.revision);\r
-                               #endif\r
-                       }\r
+                       #if LIST_DEVICES\r
+                       if( !bFill )\r
+                               Log_Log("PCI", "Device %i,%i:%i %06x => 0x%04x:0x%04x Rev %i",\r
+                                       BusID, dev, fcn, devInfo.class,\r
+                                       devInfo.vendor, devInfo.device, devInfo.revision);\r
+                       #endif\r
                        \r
                        if( bFill ) {\r
                                devInfo.Node.Inode = giPCI_DeviceCount;\r
@@ -185,7 +209,28 @@ int PCI_ScanBus(int BusID, int bFill)
                        }\r
                        giPCI_DeviceCount ++;\r
                        \r
-                       // If bit 23 of (soemthing) is set, there are sub-functions\r
+                       switch(devInfo.ConfigCache[3] & 0x007F0000)\r
+                       {\r
+                       case 0x00:      // Normal device\r
+                               break;\r
+                       case 0x01:      // PCI-PCI Bridge\r
+                               {\r
+                               // TODO: Add to list of busses?\r
+                               Uint8   sec = (devInfo.ConfigCache[6] & 0x0000FF00) >> 8;\r
+                               #if LIST_DEVICES\r
+                               if( !bFill ) {\r
+                                       Uint8   pri = (devInfo.ConfigCache[6] & 0x000000FF) >> 0;\r
+                                       Log_Log("PCI", "- PCI-PCI Bridge %02x=>%02x", pri, sec);\r
+                               }\r
+                               #endif\r
+                               gaPCI_BusNumbers[giPCI_BusCount++] = sec;\r
+                               }\r
+                               break;\r
+                       case 0x02:      // PCI-CardBus Bridge\r
+                               break;\r
+                       }\r
+\r
+                       // If bit 8 of the Header Type register is set, there are sub-functions\r
                        if(fcn == 0 && !(devInfo.ConfigCache[3] & 0x00800000) )\r
                                break;\r
                }\r
@@ -212,35 +257,16 @@ int PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
  */\r
 tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename)\r
 {\r
-        int    bus,slot,fcn;\r
         int    i;\r
-       // Validate Filename (Pointer and length)\r
-       if(!filename || strlen(filename) != 7)\r
-               return NULL;\r
-       // Check for spacers\r
-       if(filename[2] != '.' || filename[5] != ':')\r
-               return NULL;\r
-       \r
-       // Get Information\r
-       if(filename[0] < '0' || filename[0] > '9')      return NULL;\r
-       bus = (filename[0] - '0')*10;\r
-       if(filename[1] < '0' || filename[1] > '9')      return NULL;\r
-       bus += filename[1] - '0';\r
-       if(filename[3] < '0' || filename[3] > '9')      return NULL;\r
-       slot = (filename[3] - '0')*10;\r
-       if(filename[4] < '0' || filename[4] > '9')      return NULL;\r
-       slot += filename[4] - '0';\r
-       if(filename[6] < '0' || filename[6] > '9')      return NULL;\r
-       fcn = filename[6] - '0';\r
        \r
        // Find Match\r
        for(i=0;i<giPCI_DeviceCount;i++)\r
        {\r
-               if(gPCI_Devices[i].bus != bus)          continue;\r
-               if(gPCI_Devices[i].slot != slot)        continue;\r
-               if(gPCI_Devices[i].fcn != fcn)  continue;\r
-               \r
-               return &gPCI_Devices[i].Node;\r
+               int cmp = strcmp(gPCI_Devices[i].Name, filename);\r
+               if( cmp > 0 )   // Sorted list\r
+                       break;\r
+               if( cmp == 0 )\r
+                       return &gPCI_Devices[i].Node;\r
        }\r
        \r
        // Error Return\r
@@ -372,6 +398,11 @@ Uint32 PCI_ConfigRead(tPCIDev ID, int Offset, int Size)
        if( Offset & (Size - 1) )       return 0;\r
 \r
        dev = &gPCI_Devices[ID];\r
+       // Detect VPCI devices\r
+       if( dev->bus == -1 ) {\r
+               return VPCI_Read(&gaVPCI_Devices[dev->slot], Offset, Size);\r
+       }\r
+\r
        addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, Offset);\r
 \r
        dword = PCI_CfgReadDWord(addr);\r
@@ -391,10 +422,18 @@ void PCI_ConfigWrite(tPCIDev ID, int Offset, int Size, Uint32 Value)
        tPCIDevice      *dev;\r
        Uint32  dword, addr;\r
         int    shift;\r
+\r
        if( ID < 0 || ID >= giPCI_DeviceCount ) return ;\r
        if( Offset < 0 || Offset > 256 )        return ;\r
-       \r
+\r
        dev = &gPCI_Devices[ID];\r
+\r
+       // Detect VPCI devices\r
+       if( dev->bus == -1 ) {\r
+               VPCI_Write(&gaVPCI_Devices[dev->slot], Offset, Size, Value);\r
+               return ;\r
+       }\r
+\r
        addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, Offset);\r
 \r
        if(Size != 4)\r
@@ -456,16 +495,18 @@ int PCI_int_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info)
        vendor_dev = PCI_CfgReadDWord( addr );\r
        if((vendor_dev & 0xFFFF) == 0xFFFF)     // Invalid Device\r
                return 0;\r
+       \r
+       info->bus = bus;\r
+       info->slot = slot;\r
+       info->fcn = fcn;\r
 \r
+       // Read configuration\r
        info->ConfigCache[0] = vendor_dev;\r
        for( i = 1, addr += 4; i < 256/4; i ++, addr += 4 )\r
        {\r
                info->ConfigCache[i] = PCI_CfgReadDWord(addr);\r
        }       \r
 \r
-       info->bus = bus;\r
-       info->slot = slot;\r
-       info->fcn = fcn;\r
        info->vendor = vendor_dev & 0xFFFF;\r
        info->device = vendor_dev >> 16;\r
        tmp = info->ConfigCache[2];\r
@@ -479,14 +520,7 @@ int PCI_int_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info)
 //     #endif\r
        \r
        // Make node name\r
-       info->Name[0] = '0' + bus/10;\r
-       info->Name[1] = '0' + bus%10;\r
-       info->Name[2] = '.';\r
-       info->Name[3] = '0' + slot/10;\r
-       info->Name[4] = '0' + slot%10;\r
-       info->Name[5] = ':';\r
-       info->Name[6] = '0' + fcn;\r
-       info->Name[7] = '\0';\r
+       snprintf(info->Name, 8, "%02x.%02x:%x", bus, slot, fcn);\r
        \r
        // Create VFS Node\r
        memset( &info->Node, 0, sizeof(tVFS_Node) );\r
index 1e0c6bd..9c7d909 100644 (file)
@@ -276,14 +276,15 @@ int SysFS_RemoveFile(int ID)
        tSysFS_Ent      *ent, *parent, *prev;
        
        prev = NULL;
-       for( ent = gSysFS_FileList; ent; prev = ent, ent = ent->Next )
+       for( ent = gSysFS_FileList; ent; prev = ent, ent = ent->ListNext )
        {
                // It's a reverse sorted list
-               if(ent->Node.Inode < (Uint64)ID)        return 0;
-               if(ent->Node.Inode == (Uint64)ID)       break;
+               if(ent->Node.Inode <= (Uint64)ID)       break;
+       }
+       if( !ent || ent->Node.Inode != (Uint64)ID) {
+               Log_Notice("SysFS", "ID %i not present", ID);
+               return 0;
        }
-       
-       if(!ent)        return 0;
        
        // Set up for next part
        file = ent;
@@ -297,26 +298,37 @@ int SysFS_RemoveFile(int ID)
        file->Node.Size = 0;
        file->Node.ImplPtr = NULL;
        
-       // Search parent directory
-       for( ent = parent->Node.ImplPtr; ent; prev = ent, ent = ent->Next )
+       // Clean out of parent directory
+       while(parent)
        {
-               if( ent == file )       break;
-       }
-       if(!ent) {
-               Log_Warning("SysFS", "Bookkeeping Error: File in list, but not in directory");
-               return 0;
+               for( ent = parent->Node.ImplPtr; ent; prev = ent, ent = ent->Next )
+               {
+                       if( ent == file )       break;
+               }
+               if(!ent) {
+                       Log_Warning("SysFS", "Bookkeeping Error: File in list, but not in directory");
+                       return 0;
+               }
+               
+               // Remove from parent directory
+               if(prev)
+                       prev->Next = ent->Next;
+               else
+                       parent->Node.ImplPtr = ent->Next;
+
+               // Free if not in use
+               if(file->Node.ReferenceCount == 0) {
+                       free(file);
+               }
+
+               if( parent->Node.ImplPtr )
+                       break;
+
+               // Remove parent from the tree
+               file = parent;
+               parent = parent->Parent;
        }
        
-       // Remove from parent directory
-       if(prev)
-               prev->Next = ent->Next;
-       else
-               parent->Node.ImplPtr = ent->Next;
-       
-       // Free if not in use
-       if(file->Node.ReferenceCount == 0)
-               free(file);
-       
        return 1;
 }
 
diff --git a/KernelLand/Kernel/drv/vpci.c b/KernelLand/Kernel/drv/vpci.c
new file mode 100644 (file)
index 0000000..4fccdb8
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * drv/vpci.c
+ * - Virtual PCI Bus
+ */
+#include <virtual_pci.h>
+
+// === CODE ===
+Uint32 VPCI_Read(tVPCI_Device *Dev, Uint8 Offset, Uint8 Size)
+{
+       Uint32  tmp_dword = 0;
+
+       if( Size > 4 || Size == 3 || Size == 0 )
+               return 0;
+       if( Offset & (Size - 1) )
+               return 0;
+       
+       switch( Offset >> 2 )
+       {
+       case 0: // Vendor[0:15], Device[16:31]
+               tmp_dword = (Dev->Vendor) | (Dev->Device << 16);
+               break;
+       case 2: // Class Code
+               tmp_dword = Dev->Class;
+               break;
+       // 1: Command[0:15], Status[16:31]
+       // 3: Cache Line Size, Latency Timer, Header Type, BIST
+       // 4-9: BARs
+       // 10: Unused (Cardbus CIS Pointer)
+       // 11: Subsystem Vendor ID, Subsystem ID
+       // 12: Expansion ROM Address
+       // 13: Capabilities[0:8], Reserved[9:31]
+       // 14: Reserved
+       // 15: Interrupt Line, Interrupt Pin, Min Grant, Max Latency
+       default:
+               tmp_dword = Dev->Read(Dev->Ptr, Offset >> 2);
+               break;
+       }
+
+       tmp_dword >>= 8*(Offset & 3);
+       switch(Size)
+       {
+       case 4: break;
+       case 2: tmp_dword &= 0xFFFF;    break;
+       case 1: tmp_dword &= 0xFF;
+       }
+
+       return tmp_dword;
+}
+
+void VPCI_Write(tVPCI_Device *Dev, Uint8 Offset, Uint8 Size, Uint32 Data)
+{
+       Uint32  tmp_dword;
+       if( Size > 4 || Size == 3 || Size == 0 )
+               return ;
+       if( Offset & (Size - 1) )
+               return ;
+       
+       switch(Offset >> 2)
+       {
+       case 0: // Vendor / Device IDs
+       case 2: // Class Code
+               // READ ONLY
+               return ;
+       }
+
+       tmp_dword = Dev->Read(Dev->Ptr, Offset>>2);
+       switch(Size)
+       {
+       case 4: tmp_dword = 0;  break;
+       case 2:
+               tmp_dword &= ~(0xFFFF << ((Offset&2)*16));
+               Data |= 0xFFFF;
+               break;
+       case 1:
+               tmp_dword &= ~(0xFF << ((Offset&3)*8));
+               Data |= 0xFF;
+               break;
+       }
+       tmp_dword |= Data << ((Offset&3)*8);
+       Dev->Write(Dev->Ptr, Offset>>2, tmp_dword);
+}
index 31b050f..b44564e 100644 (file)
@@ -133,9 +133,6 @@ void VT_KBCallBack(Uint32 Codepoint)
        
                Codepoint &= KEY_CODEPOINT_MASK;
 
-               // Ignore Modifer Keys
-               if(Codepoint > KEY_MODIFIERS)   return;
-               
                // Get UTF-8/ANSI Encoding
                if( Codepoint == 0 )
                {
index af2bde4..be8eeaf 100644 (file)
@@ -512,7 +512,12 @@ void Heap_Dump(void)
 {
        tHeapHead       *head, *badHead;
        tHeapFoot       *foot = NULL;
+       static int      in_heap_dump;
        
+       if( in_heap_dump )      return;
+
+       in_heap_dump = 1;
+
        head = gHeapStart;
        while( (Uint)head < (Uint)gHeapEnd )
        {               
@@ -560,12 +565,16 @@ void Heap_Dump(void)
        }
        
        // If the heap is valid, ok!
-       if( (tVAddr)head == (tVAddr)gHeapEnd )
+       if( (tVAddr)head == (tVAddr)gHeapEnd ) {
+               in_heap_dump = 0;
                return ;
+       }
        
        // Check for a bad return
-       if( (tVAddr)head >= (tVAddr)gHeapEnd )
+       if( (tVAddr)head >= (tVAddr)gHeapEnd ) {
+               in_heap_dump = 0;
                return ;
+       }
 
        #if !VERBOSE_DUMP
        Log_Log("Heap", "%p (%P): 0x%08lx %i %4C",
index 1d062a5..24148e1 100644 (file)
@@ -9,18 +9,19 @@
  * \brief Acess2 Kernel API Core
  */
 
-//! NULL Pointer
-#define NULL   ((void*)0)
+#include <stddef.h>
+#include <arch.h>
+
 //! Pack a structure
 #define PACKED __attribute__((packed))
 //! Mark a function as not returning
 #define NORETURN       __attribute__((noreturn))
+//! Mark a function that its return value should be used
+#define WARN_UNUSED_RET        __attribute__((warn_unused_result))
 //! Mark a function (or variable) as deprecated
 #define DEPRECATED     __attribute__((deprecated))
 //! Mark a parameter as unused
 #define UNUSED(x)      UNUSED_##x __attribute__((unused))
-//! Get the offset of a member in a structure
-#define offsetof(st, m) ((Uint)((char *)&((st *)(0))->m - (char *)0 ))
 
 /**
  * \name Boolean constants
@@ -32,7 +33,6 @@
  * \}
  */
 
-#include <arch.h>
 #include <stdarg.h>
 #include "errno.h"
 
@@ -142,60 +142,7 @@ extern void        IRQ_RemHandler(int Handle);
  * \}
  */
 
-// --- Logging ---
-/**
- * \name Logging to kernel ring buffer
- * \{
- */
-extern void    Log_KernelPanic(const char *Ident, const char *Message, ...);
-extern void    Log_Panic(const char *Ident, const char *Message, ...);
-extern void    Log_Error(const char *Ident, const char *Message, ...);
-extern void    Log_Warning(const char *Ident, const char *Message, ...);
-extern void    Log_Notice(const char *Ident, const char *Message, ...);
-extern void    Log_Log(const char *Ident, const char *Message, ...);
-extern void    Log_Debug(const char *Ident, const char *Message, ...);
-/**
- * \}
- */
-
-// --- Debug ---
-/**
- * \name Debugging and Errors
- * \{
- */
-extern void    Debug_KernelPanic(void);        //!< Initiate a kernel panic
-extern void    Panic(const char *Msg, ...);    //!< Print a panic message (initiates a kernel panic)
-extern void    Warning(const char *Msg, ...);  //!< Print a warning message
-extern void    LogF(const char *Fmt, ...);     //!< Print a log message without a trailing newline
-extern void    Log(const char *Fmt, ...);      //!< Print a log message
-extern void    Debug(const char *Fmt, ...);    //!< Print a debug message (doesn't go to KTerm)
-extern void    LogV(const char *Fmt, va_list Args);    //!< va_list Log message
-extern void    Debug_Enter(const char *FuncName, const char *ArgTypes, ...);
-extern void    Debug_Log(const char *FuncName, const char *Fmt, ...);
-extern void    Debug_Leave(const char *FuncName, char RetType, ...);
-extern void    Debug_HexDump(const char *Header, const void *Data, Uint Length);
-#define UNIMPLEMENTED()        Warning("'%s' unimplemented", __func__)
-#if DEBUG
-# define ENTER(_types...)      Debug_Enter((char*)__func__, _types)
-# define LOG(_fmt...)  Debug_Log((char*)__func__, _fmt)
-# define LEAVE(_t...)  Debug_Leave((char*)__func__, _t)
-# define LEAVE_RET(_t,_v...)   do{LEAVE(_t,_v);return _v;}while(0)
-# define LEAVE_RET0()  do{LEAVE('-');return;}while(0)
-#else
-# define ENTER(...)
-# define LOG(...)
-# define LEAVE(...)
-# define LEAVE_RET(_t,_v...)   return (_v)
-# define LEAVE_RET0()  return
-#endif
-#if SANITY
-# define ASSERT(expr) do{if(!(expr))Panic("%s:%i - %s: Assertion '"#expr"' failed",__FILE__,__LINE__,(char*)__func__);}while(0)
-#else
-# define ASSERT(expr)
-#endif
-/**
- * \}
- */
+#include "logdebug.h"
 
 // --- IO ---
 #if NO_IO_BUS
@@ -507,7 +454,7 @@ extern Sint64       now(void);
  * \name Threads and Processes
  * \{
  */
-extern int     Proc_SpawnWorker(void (*Fcn)(void*), void *Data);
+extern struct sThread  *Proc_SpawnWorker(void (*Fcn)(void*), void *Data);
 extern int     Proc_Spawn(const char *Path);
 extern int     Proc_SysSpawn(const char *Binary, const char **ArgV, const char **EnvP, int nFD, int *FDs);
 extern int     Proc_Execve(const char *File, const char **ArgV, const char **EnvP, int DataSize);
index f027e0e..964be49 100644 (file)
@@ -87,56 +87,6 @@ typedef void (*tKeybardCallback)(Uint32 Key);
  * \}\r
  */\r
 \r
-/**\r
- * \brief Symbolic key codes\r
- * \r
- * These key codes represent non-pritable characters and are placed above\r
- * the Unicode character space.\r
- * If the using driver recieves a key code with the 31st bit set, it means\r
- * that that key has been released.\r
- */\r
-enum eTplKeyboard_KeyCodes {\r
-       KEY_ESC = 0x1B, //!< Escape Character\r
-       \r
-       KEY_NP_MASK = 0x20000000,       //! Mask for non-printable characters\r
-       \r
-       /**\r
-        * \name Special Keys\r
-        * \brief These keys are usually used on their own\r
-        * \{\r
-        */\r
-       KEY_CAPSLOCK,\r
-       KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT,\r
-       KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, \r
-       KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12,\r
-       KEY_NUMLOCK, KEY_SCROLLLOCK,\r
-       KEY_HOME, KEY_END, KEY_INS, KEY_DEL,\r
-       KEY_PAUSE, KEY_BREAK,\r
-       KEY_PGUP, KEY_PGDOWN,\r
-       KEY_KPENTER, KEY_KPSLASH, KEY_KPMINUS, KEY_KPPLUS, KEY_KPSTAR,\r
-       KEY_KPHOME, KEY_KPUP, KEY_KPPGUP, KEY_KPLEFT, KEY_KP5, KEY_KPRIGHT,\r
-       KEY_KPEND, KEY_KPDOWN, KEY_KPPGDN, KEY_KPINS, KEY_KPDEL,\r
-       KEY_LWIN, KEY_RWIN,\r
-       KEY_MENU,\r
-       /**\r
-        * \}\r
-        */\r
-       \r
-       // Modifiers\r
-       /**\r
-        * \name Modifiers\r
-        * \brief These keye usually alter the character stream sent to the user\r
-        * \{\r
-        */\r
-       KEY_MODIFIERS = 0x30000000,\r
-       KEY_LCTRL, KEY_RCTRL,\r
-       KEY_LALT, KEY_RALT,\r
-       KEY_LSHIFT, KEY_RSHIFT,\r
-       /**\r
-        * \}\r
-        */\r
-};\r
-\r
 #include "keysyms.h"\r
 \r
 #endif\r
index a327cc0..f6ec953 100644 (file)
@@ -5,28 +5,6 @@
 #ifndef _ERRNO_H
 #define _ERRNO_H
 
-enum eErrorNums
-{
-       EOK,
-       
-       ENOSYS, // Invalid Instruction
-       EINVAL, // Invalid Paramater
-       ENOMEM, // No free memory
-       EACCES, // Not permitted
-       EBUSY,  // Resource is busy
-       ENOTFOUND,      // Item not found
-       EREADONLY,      // Read only
-       ENOTIMPL,       // Not implemented
-       ENOENT, // No entry?
-       EEXIST, // Already exists
-       ENFILE, // Too many open files
-       ENOTDIR,        // Not a directory
-       EIO,    // IO Error
-       
-       EALREADY,       // Operation was a NOP
-       EINTERNAL,      // Internal Error
-       
-       NUM_ERRS
-};
+#include "../../../Usermode/Libraries/libc.so_src/include_exp/errno.enum.h"
 
 #endif
index 5770940..dc9d654 100644 (file)
 
 #include <threads.h>
 
+/**
+ * \name Event Values
+ * \{
+ */
+//! Fired when a VFS wait is ready [used in select(2)]
 #define THREAD_EVENT_VFS       0x00000001
+//! Fired when an IPC Message arrives
 #define THREAD_EVENT_IPCMSG    0x00000002
+//! Fired when a signal (e.g. SIGINT) is asserted
 #define THREAD_EVENT_SIGNAL    0x00000004
+//! Timer event fire
 #define THREAD_EVENT_TIMER     0x00000008
+//! General purpose event for short waits
+//! e.g. waiting for an IRQ in a Read() call
 #define THREAD_EVENT_SHORTWAIT 0x00000010
 
+#define THREAD_EVENT_USER1     0x10000000
+#define THREAD_EVENT_USER2     0x20000000
+#define THREAD_EVENT_USER3     0x40000000
+#define THREAD_EVENT_USER4     0x80000000
+/**
+ * \}
+ */
+
 // === FUNCTIONS ===
 extern void    Threads_PostEvent(tThread *Thread, Uint32 EventMask);
 extern void    Threads_ClearEvent(Uint32 EventMask);
index bb9dd4f..5c03bda 100644 (file)
@@ -13,6 +13,7 @@
  * \brief Achitecture defined thread/process management functions
  */
 
+#include <threads.h>
 #include <threads_int.h>
 
 /**
diff --git a/KernelLand/Kernel/include/logdebug.h b/KernelLand/Kernel/include/logdebug.h
new file mode 100644 (file)
index 0000000..80cb1c9
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * logdebug.h
+ * - Logging / Debug printing functions
+ */
+#ifndef _KERNEL__LOGDEBUG_H_
+#define _KERNEL__LOGDEBUG_H_
+
+#include <stdarg.h>
+
+// --- Logging ---
+/**
+ * \name Logging to kernel ring buffer
+ * \{
+ */
+extern void    Log_KernelPanic(const char *Ident, const char *Message, ...);
+extern void    Log_Panic(const char *Ident, const char *Message, ...);
+extern void    Log_Error(const char *Ident, const char *Message, ...);
+extern void    Log_Warning(const char *Ident, const char *Message, ...);
+extern void    Log_Notice(const char *Ident, const char *Message, ...);
+extern void    Log_Log(const char *Ident, const char *Message, ...);
+extern void    Log_Debug(const char *Ident, const char *Message, ...);
+/**
+ * \}
+ */
+
+// --- Debug ---
+/**
+ * \name Debugging and Errors
+ * \{
+ */
+extern void    Debug_KernelPanic(void);        //!< Initiate a kernel panic
+extern void    Panic(const char *Msg, ...);    //!< Print a panic message (initiates a kernel panic)
+extern void    Warning(const char *Msg, ...);  //!< Print a warning message
+extern void    LogF(const char *Fmt, ...);     //!< Print a log message without a trailing newline
+extern void    Log(const char *Fmt, ...);      //!< Print a log message
+extern void    Debug(const char *Fmt, ...);    //!< Print a debug message (doesn't go to KTerm)
+extern void    LogV(const char *Fmt, va_list Args);    //!< va_list Log message
+extern void    Debug_Enter(const char *FuncName, const char *ArgTypes, ...);
+extern void    Debug_Log(const char *FuncName, const char *Fmt, ...);
+extern void    Debug_Leave(const char *FuncName, char RetType, ...);
+extern void    Debug_HexDump(const char *Header, const void *Data, size_t Length);
+#define UNIMPLEMENTED()        Warning("'%s' unimplemented", __func__)
+#if DEBUG
+# define ENTER(_types...)      Debug_Enter((char*)__func__, _types)
+# define LOG(_fmt...)  Debug_Log((char*)__func__, _fmt)
+# define LEAVE(_t...)  Debug_Leave((char*)__func__, _t)
+# define LEAVE_RET(_t,_v...)   do{LEAVE(_t,_v);return _v;}while(0)
+# define LEAVE_RET0()  do{LEAVE('-');return;}while(0)
+#else
+# define ENTER(...)
+# define LOG(...)
+# define LEAVE(...)
+# define LEAVE_RET(_t,_v...)   return (_v)
+# define LEAVE_RET0()  return
+#endif
+#if !DISABLE_ASSERTS
+# define ASSERT(expr) do{if(!(expr))Panic("%s:%i - %s: Assertion '"#expr"' failed",__FILE__,__LINE__,(char*)__func__);}while(0)
+#else
+# define ASSERT(expr)
+#endif
+/**
+ * \}
+ */
+
+#endif
+
index a6f46b5..e0d4207 100644 (file)
@@ -37,7 +37,7 @@ struct sRWLock
  */
 extern int     RWLock_AcquireRead(tRWLock *Lock);
 
-extern int     RWLock_AcquireWrite(tRWLock *LOck);
+extern int     RWLock_AcquireWrite(tRWLock *Lock);
 
 /**
  * \brief Release a held mutex
index 5ce2814..4164e64 100644 (file)
 #define SYS_SETGID     42      // Set current Group ID
 #define SYS_OPEN       64      // Open a file
 #define SYS_REOPEN     65      // Close a file and reuse its handle
-#define SYS_CLOSE      66      // Close a file
-#define SYS_READ       67      // Read from an open file
-#define SYS_WRITE      68      // Write to an open file
-#define SYS_IOCTL      69      // Perform an IOCtl Call
-#define SYS_SEEK       70      // Seek to a new position in the file
-#define SYS_READDIR    71      // Read from an open directory
-#define SYS_OPENCHILD  72      // Open a child entry in a directory
-#define SYS_GETACL     73      // Get an ACL Value
-#define SYS_SETACL     74      // Set an ACL Value
-#define SYS_FINFO      75      // Get file information
-#define SYS_MKDIR      76      // Create a new directory
-#define SYS_LINK       77      // Create a new link to a file
-#define SYS_SYMLINK    78      // Create a symbolic link
-#define SYS_UNLINK     79      // Delete a file
-#define SYS_TELL       80      // Return the current file position
-#define SYS_CHDIR      81      // Change current directory
-#define SYS_GETCWD     82      // Get current directory
-#define SYS_MOUNT      83      // Mount a filesystem
-#define SYS_SELECT     84      // Wait for file handles
+#define SYS_OPENCHILD  66      // Open a child entry in a directory
+#define SYS_OPENPIPE   67      // Open a FIFO pipe pair
+#define SYS_CLOSE      68      // Close a file
+#define SYS_COPYFD     69      // Create a copy of a file handle
+#define SYS_FDCTL      70      // Modify properties of a file descriptor
+#define SYS_READ       71      // Read from an open file
+#define SYS_WRITE      72      // Write to an open file
+#define SYS_IOCTL      73      // Perform an IOCtl Call
+#define SYS_SEEK       74      // Seek to a new position in the file
+#define SYS_READDIR    75      // Read from an open directory
+#define SYS_GETACL     76      // Get an ACL Value
+#define SYS_SETACL     77      // Set an ACL Value
+#define SYS_FINFO      78      // Get file information
+#define SYS_MKDIR      79      // Create a new directory
+#define SYS_LINK       80      // Create a new link to a file
+#define SYS_SYMLINK    81      // Create a symbolic link
+#define SYS_UNLINK     82      // Delete a file
+#define SYS_TELL       83      // Return the current file position
+#define SYS_CHDIR      84      // Change current directory
+#define SYS_GETCWD     85      // Get current directory
+#define SYS_MOUNT      86      // Mount a filesystem
+#define SYS_SELECT     87      // Wait for file handles
 
-#define NUM_SYSCALLS   85
+#define NUM_SYSCALLS   88
 #define SYS_DEBUG      0x100
 
 #ifndef __ASSEMBLER__
@@ -133,13 +136,16 @@ static const char *cSYSCALL_NAMES[] = {
        "",
        "SYS_OPEN",
        "SYS_REOPEN",
+       "SYS_OPENCHILD",
+       "SYS_OPENPIPE",
        "SYS_CLOSE",
+       "SYS_COPYFD",
+       "SYS_FDCTL",
        "SYS_READ",
        "SYS_WRITE",
        "SYS_IOCTL",
        "SYS_SEEK",
        "SYS_READDIR",
-       "SYS_OPENCHILD",
        "SYS_GETACL",
        "SYS_SETACL",
        "SYS_FINFO",
index 149fe37..55f8fee 100644 (file)
 %define SYS_SETGID     42       ;Set current Group ID
 %define SYS_OPEN       64       ;Open a file
 %define SYS_REOPEN     65       ;Close a file and reuse its handle
-%define SYS_CLOSE      66       ;Close a file
-%define SYS_READ       67       ;Read from an open file
-%define SYS_WRITE      68       ;Write to an open file
-%define SYS_IOCTL      69       ;Perform an IOCtl Call
-%define SYS_SEEK       70       ;Seek to a new position in the file
-%define SYS_READDIR    71       ;Read from an open directory
-%define SYS_OPENCHILD  72       ;Open a child entry in a directory
-%define SYS_GETACL     73       ;Get an ACL Value
-%define SYS_SETACL     74       ;Set an ACL Value
-%define SYS_FINFO      75       ;Get file information
-%define SYS_MKDIR      76       ;Create a new directory
-%define SYS_LINK       77       ;Create a new link to a file
-%define SYS_SYMLINK    78       ;Create a symbolic link
-%define SYS_UNLINK     79       ;Delete a file
-%define SYS_TELL       80       ;Return the current file position
-%define SYS_CHDIR      81       ;Change current directory
-%define SYS_GETCWD     82       ;Get current directory
-%define SYS_MOUNT      83       ;Mount a filesystem
-%define SYS_SELECT     84       ;Wait for file handles
+%define SYS_OPENCHILD  66       ;Open a child entry in a directory
+%define SYS_OPENPIPE   67       ;Open a FIFO pipe pair
+%define SYS_CLOSE      68       ;Close a file
+%define SYS_COPYFD     69       ;Create a copy of a file handle
+%define SYS_FDCTL      70       ;Modify properties of a file descriptor
+%define SYS_READ       71       ;Read from an open file
+%define SYS_WRITE      72       ;Write to an open file
+%define SYS_IOCTL      73       ;Perform an IOCtl Call
+%define SYS_SEEK       74       ;Seek to a new position in the file
+%define SYS_READDIR    75       ;Read from an open directory
+%define SYS_GETACL     76       ;Get an ACL Value
+%define SYS_SETACL     77       ;Set an ACL Value
+%define SYS_FINFO      78       ;Get file information
+%define SYS_MKDIR      79       ;Create a new directory
+%define SYS_LINK       80       ;Create a new link to a file
+%define SYS_SYMLINK    81       ;Create a symbolic link
+%define SYS_UNLINK     82       ;Delete a file
+%define SYS_TELL       83       ;Return the current file position
+%define SYS_CHDIR      84       ;Change current directory
+%define SYS_GETCWD     85       ;Get current directory
+%define SYS_MOUNT      86       ;Mount a filesystem
+%define SYS_SELECT     87       ;Wait for file handles
index 0362cdb..6382cf0 100644 (file)
@@ -37,6 +37,6 @@ extern char   **Threads_GetCWD(void);
 extern char    **Threads_GetChroot(void);
 
 extern int     Proc_SendMessage(Uint Dest, int Length, void *Data);
-extern int     Proc_GetMessage(Uint *Source, void *Buffer);
+extern int     Proc_GetMessage(Uint *Source, Uint BufSize, void *Buffer);
 
 #endif
index 2f15a72..578fdcf 100644 (file)
@@ -1,5 +1,9 @@
 /*
- * Internal Threading header
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * include/threads_int.h
+ * - Internal Threading header
  * - Only for use by stuff that needs access to the thread type.
  */
 #ifndef _THREADS_INT_H_
@@ -7,6 +11,7 @@
 
 #include <threads.h>
 #include <proc.h>
+#include <timers_int.h>
 
 typedef struct sProcess        tProcess;
 
@@ -92,10 +97,12 @@ struct sThread
        
        // --- event.c
        Uint32  EventState;
+       // --- timer.c
+       tTimer  ThreadTimer;
 };
 
 
-enum {
+enum eThreadStatus {
        THREAD_STAT_NULL,       // Invalid process
        THREAD_STAT_ACTIVE,     // Running and schedulable process
        THREAD_STAT_SLEEPING,   // Message Sleep
diff --git a/KernelLand/Kernel/include/timers_int.h b/KernelLand/Kernel/include/timers_int.h
new file mode 100644 (file)
index 0000000..85a52ec
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * include/timers_int.h
+ * - Timer internal header
+ * - Only for use by code that needs access to timer internals
+ */
+#ifndef _KERNEL__TIMERS_INT_H_
+#define _KERNEL__TIMERS_INT_H_
+
+#include <timers.h>
+
+// === TYPEDEFS ===
+struct sTimer {
+       tTimer  *Next;
+       Sint64  FiresAfter;
+       void    (*Callback)(void*);
+       void    *Argument;
+//     tMutex  Lock;
+       BOOL    bActive;
+};
+
+#endif
+
index 1f67f4b..232c55e 100644 (file)
@@ -51,6 +51,7 @@ extern tVFS_Mount     *gVFS_Mounts;
 extern tVFS_Driver     *gVFS_Drivers;
 
 // === PROTOTYPES ===
+extern void    VFS_Deinit(void);
 // --- open.c ---
 extern char    *VFS_GetAbsPath(const char *Path);
 extern tVFS_Node       *VFS_ParsePath(const char *Path, char **TruePath, tVFS_Mount **MountPoint);
diff --git a/KernelLand/Kernel/include/virtual_pci.h b/KernelLand/Kernel/include/virtual_pci.h
new file mode 100644 (file)
index 0000000..c6408cd
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ * 
+ * virtual_pci.h
+ * - Virtual PCI bus definitions
+ */
+#ifndef _VIRTUAL_PCI_H_
+#define _VIRTUAL_PCI_H_
+#include <acess.h>
+
+typedef struct sVPCI_Device    tVPCI_Device;
+
+struct sVPCI_Device
+{
+       void    *Ptr;
+
+       // Vendor/Device is defined at runtime as 0x0ACE:0x[ARCH][ARCH][IDX][IDX]
+       Uint16  Vendor;
+       Uint16  Device;
+       // Class code (Class, Subclass, Programming Interface, Revision)
+       Uint32  Class;
+       
+       Uint32  BARs[6];
+       Uint8   IRQ;
+       
+       /**
+        * \param Ptr   Value in sVPCI_Device.Ptr
+        * \param Data  Data to write to the specified address
+        */
+       void    (*Write)(void *Ptr, Uint8 DWord, Uint32 Data);
+       Uint32  (*Read)(void *Ptr, Uint8 DWord);
+};
+
+extern int     giVPCI_DeviceCount;
+extern tVPCI_Device    gaVPCI_Devices[];
+
+extern Uint32  VPCI_Read(tVPCI_Device *Dev, Uint8 Offset, Uint8 Size);
+extern void    VPCI_Write(tVPCI_Device *Dev, Uint8 Offset, Uint8 Size, Uint32 Data);
+#endif
+
index 36b877c..d0c6de6 100644 (file)
@@ -180,7 +180,7 @@ int ReadUTF8(const Uint8 *str, Uint32 *Val)
        }
        
        // Four Byte
-       if( (*str & 0xF1) == 0xF0 ) {
+       if( (*str & 0xF8) == 0xF0 ) {
                outval = (*str & 0x07) << 18;   // Upper 3 Bits
                str ++;
                if( (*str & 0xC0) != 0x80)      return 2;       // Validity check
@@ -287,23 +287,23 @@ Sint64 timestamp(int sec, int min, int hrs, int day, int month, int year)
        return stamp * 1000;
 }
 
+static Sint64 DivMod64(Sint64 N, Sint64 D, Sint64 *R);
+       
+static Sint64 DivMod64(Sint64 N, Sint64 D, Sint64 *R)
+{
+       int sign = (N < 0) != (D < 0);
+       if(N < 0)       N = -N;
+       if(D < 0)       D = -D;
+       if(sign)
+               return -DivMod64U(N, D, (Uint64*)R);
+       else
+               return DivMod64U(N, D, (Uint64*)R);
+}
+
 void format_date(tTime TS, int *year, int *month, int *day, int *hrs, int *mins, int *sec, int *ms)
 {
         int    is_leap = 0, i;
 
-       auto Sint64 DivMod64(Sint64 N, Sint64 D, Sint64 *R);
-       
-       Sint64 DivMod64(Sint64 N, Sint64 D, Sint64 *R)
-       {
-               int sign = (N < 0) != (D < 0);
-               if(N < 0)       N = -N;
-               if(D < 0)       D = -D;
-               if(sign)
-                       return -DivMod64U(N, D, (Uint64*)R);
-               else
-                       return DivMod64U(N, D, (Uint64*)R);
-       }
-
        // Get time
        // TODO: Leap-seconds?
        {
index ef94426..58c2e1a 100644 (file)
 #define        RANDOM_SPRUCE   0xf12b039
 
 // === PROTOTYPES ===
+unsigned long long     strtoull(const char *str, char **end, int base);
+unsigned long  strtoul(const char *str, char **end, int base);
+signed long long       strtoll(const char *str, char **end, int base);
+signed long    strtol(const char *str, char **end, int base);
 #if 0
  int   atoi(const char *string);
  int   ParseInt(const char *string, int *Val);
@@ -67,15 +71,10 @@ EXPORT(CheckString);
 EXPORT(CheckMem);
 
 // === CODE ===
-/**
- * \brief Convert a string into an integer
- */
-int atoi(const char *string)
-{
-       int ret = 0;
-       ParseInt(string, &ret);
-       return ret;
-}
+// - Import userland stroi.c file
+#define _LIB_H_
+#include "../../Usermode/Libraries/libc.so_src/strtoi.c"
+
 int ParseInt(const char *string, int *Val)
 {
         int    ret = 0;
@@ -184,7 +183,14 @@ void itoa(char *buf, Uint64 num, int base, int minLength, char pad)
 /**
  * \brief Append a character the the vsnprintf output
  */
-#define PUTCH(c)       _putch(c)
+#define PUTCH(ch)      do { \
+               if(pos < __maxlen) { \
+                       if(__s) __s[pos] = ch; \
+               } else { \
+                       (void)ch;\
+               } \
+               pos ++; \
+       } while(0)
 #define GETVAL()       do {\
        if(isLongLong)  val = va_arg(args, Uint64);\
        else    val = va_arg(args, unsigned int);\
@@ -203,17 +209,6 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
        size_t  pos = 0;
        // Flags
         int    bPadLeft = 0;
-       
-       auto void _putch(char ch);
-
-       void _putch(char ch)
-       {
-               if(pos < __maxlen)
-               {
-                       if(__s) __s[pos] = ch;
-               }
-               pos ++;
-       }
 
        while((c = *__format++) != 0)
        {
@@ -230,8 +225,14 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                if(c == 'p') {
                        Uint    ptr = va_arg(args, Uint);
                        PUTCH('*');     PUTCH('0');     PUTCH('x');
-                       for( len = BITS/4; len --; )
-                               PUTCH( cUCDIGITS[ (ptr>>(len*4))&15 ] );
+                       for( len = BITS/4; len -- && ((ptr>>(len*4))&15) == 0; )
+                               ;
+                       len ++;
+                       if( len == 0 )
+                               PUTCH( '0' );
+                       else
+                               while( len -- )
+                                       PUTCH( cUCDIGITS[ (ptr>>(len*4))&15 ] );
                        continue ;
                }
                
@@ -361,7 +362,7 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                        if(!p)          p = "(null)";
                        len = strlen(p);
                        if( !bPadLeft ) while(len++ < minSize)  PUTCH(pad);
-                       while(*p && precision--)        PUTCH(*p++);
+                       while(*p && precision--) { PUTCH(*p); p++;} 
                        if( bPadLeft )  while(len++ < minSize)  PUTCH(pad);
                        break;
                
@@ -369,7 +370,10 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                        p = va_arg(args, char*);
                        if( !CheckMem(p, minSize) )     continue;       // No #PFs please
                        if(!p)  goto printString;
-                       while(minSize--)        PUTCH(*p++);
+                       while(minSize--) {
+                               PUTCH(*p);
+                               p ++;
+                       }
                        break;
                
                // Single Character
@@ -742,7 +746,8 @@ void *memmove(void *__dest, const void *__src, size_t len)
        
 }
 
-// NOTE: Strictly not libc, but lib.c is used by userland code too
+// NOTE: Strictly not libc, but lib.c is used by userland code too and hence these two
+// can't be in it.
 /**
  * \name Memory Validation
  * \{
index 9617b83..aab25a1 100644 (file)
@@ -91,12 +91,10 @@ void Log_AddEvent(const char *Ident, int Level, const char *Format, va_list Args
        va_list args_tmp;
        
        if( Level >= NUM_LOG_LEVELS )   return;
-       
+
        va_copy(args_tmp, Args);
        len = vsnprintf(NULL, 256, Format, args_tmp);
        
-       //Log("len = %i", len);
-       
        #if USE_RING_BUFFER || !CACHE_MESSAGES
        {
        char    buf[sizeof(tLogEntry)+len+1];
@@ -161,9 +159,11 @@ void Log_Int_PrintMessage(tLogEntry *Entry)
        if( CPU_HAS_LOCK(&glLogOutput) )
                return ;        // TODO: Error?
        SHORTLOCK( &glLogOutput );
-       LogF("%s%014lli%s [%-8s] %i - %s",
+       LogF("%s%014lli",
                csaLevelColours[Entry->Level],
-               Entry->Time,
+               Entry->Time
+               );
+       LogF("%s [%-8s] %i - %s",
                csaLevelCodes[Entry->Level],
                Entry->Ident,
                Threads_GetTID(),
index 09c8c14..8237423 100644 (file)
@@ -78,10 +78,11 @@ int Proc_SendMessage(Uint Dest, int Length, void *Data)
  * \fn int Proc_GetMessage(Uint *Source, void *Buffer)
  * \brief Gets a message
  * \param Source       Where to put the source TID
+ * \param BufSize      Size of \a Buffer, only this many bytes will be copied
  * \param Buffer       Buffer to place the message data (set to NULL to just get message length)
  * \return Message length
  */
-int Proc_GetMessage(Uint *Source, void *Buffer)
+int Proc_GetMessage(Uint *Source, Uint BufSize, void *Buffer)
 {
         int    ret;
        void    *tmp;
@@ -113,7 +114,7 @@ int Proc_GetMessage(Uint *Source, void *Buffer)
        // Get message
        if(Buffer != GETMSG_IGNORE)
        {
-               if( !CheckMem( Buffer, cur->Messages->Length ) )
+               if( !CheckMem( Buffer, BufSize ) )
                {
                        LOG("Invalid buffer");
                        errno = -EINVAL;
@@ -121,18 +122,28 @@ int Proc_GetMessage(Uint *Source, void *Buffer)
                        LEAVE('i', -1);
                        return -1;
                }
+               if( BufSize < cur->Messages->Length )
+                       Log_Notice("Threads", "Buffer of 0x%x passed, but 0x%x long message, truncated",
+                               BufSize, cur->Messages->Length);
+               else if( BufSize < cur->Messages->Length )
+                       BufSize = cur->Messages->Length;
+               else
+                       ;       // equal
                LOG("Copied to buffer");
-               memcpy(Buffer, cur->Messages->Data, cur->Messages->Length);
+               memcpy(Buffer, cur->Messages->Data, BufSize);
        }
        ret = cur->Messages->Length;
        
        // Remove from list
        tmp = cur->Messages;
        cur->Messages = cur->Messages->Next;
+       // - Removed last message? Clear the end-of-list pointer
        if(cur->Messages == NULL)       cur->LastMessage = NULL;
+       //  > Otherwise, re-mark the IPCMSG event flag
+       else    cur->EventState |= THREAD_EVENT_IPCMSG;
        
        SHORTREL( &cur->IsLocked );
-       
+
        free(tmp);      // Free outside of lock
 
        LEAVE('i', ret);
index 544e866..c5e7f1b 100644 (file)
@@ -366,7 +366,7 @@ int Module_LoadFile(const char *Path, const char *ArgString)
        // TODO: I need a way of relocating the dependencies before everything else, so
        // they can be resolved before any other link errors
        if( !Binary_Relocate(base) ) {
-               Log_Warning("Relocation of module %s failed", Path);
+               Log_Warning("Module", "Relocation of module %s failed", Path);
                Binary_Unload(base);
                return 0;
        }
@@ -389,7 +389,7 @@ int Module_LoadFile(const char *Path, const char *ArgString)
        }
 
        if( !Module_int_ResolveDeps(info) ) {
-               Log_Warning("Dependencies not met for '%s'", Path);
+               Log_Warning("Module", "Dependencies not met for '%s'", Path);
                Binary_Unload(base);
                return 0;
        }
index 21ced24..bf341ff 100644 (file)
@@ -14,9 +14,10 @@ void PMemMap_DumpBlocks(tPMemMapEnt *map, int NEnts)
 {
        for( int i = 0; i < NEnts; i ++ )
        {
-               Log_Debug("PMemMap", "%i: %i 0x%02x %08llx+%llx",
+               Log_Debug("PMemMap", "%i: %i 0x%02x %08llx+%llx (end %llx)",
                        i, map[i].Type, map[i].NUMADomain,
-                       map[i].Start, map[i].Length
+                       map[i].Start, map[i].Length,
+                       map[i].Start + map[i].Length
                        );
        }
 }
index e43547a..2c9fc94 100644 (file)
@@ -127,10 +127,8 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
                toWake->RetStatus = given;
                
                // Wake the sleeper
-               SHORTLOCK( &glThreadListLock );
                if( toWake->Status != THREAD_STAT_ACTIVE )
                        Threads_AddActive(toWake);
-               SHORTREL( &glThreadListLock );
        }
        SHORTREL( &Sem->Protector );
        
index d629ae4..1f2f798 100644 (file)
 #include <threads.h>
 #include <events.h>
 
+#if 1
+# define MERR(f,v...) Log_Debug("Syscalls", "0x%x "f, callNum ,## v)
+#else
+# define MERR(v...) do{}while(0)
+#endif
+
 #define CHECK_NUM_NULLOK(v,size)       \
-       if((v)&&!Syscall_Valid((size),(v))){ret=-1;err=-EINVAL;break;}
+       if((v)&&!Syscall_Valid((size),(v))){MERR("CHECK_NUM_NULLOK: %p(%x) FAIL",v,size);ret=-1;err=-EINVAL;break;}
 #define CHECK_STR_NULLOK(v)    \
-       if((v)&&!Syscall_ValidString((v))){ret=-1;err=-EINVAL;break;}
+       if((v)&&!Syscall_ValidString((v))){MERR("CHECK_STR_NULLOK: %p FAIL",v);ret=-1;err=-EINVAL;break;}
 #define CHECK_NUM_NONULL(v,size)       \
-       if(!(v)||!Syscall_Valid((size),(v))){ret=-1;err=-EINVAL;break;}
+       if(!(v)||!Syscall_Valid((size),(v))){MERR("CHECK_NUM_NONULL: %p(%x) FAIL",v,size);ret=-1;err=-EINVAL;break;}
 #define CHECK_STR_NONULL(v)    \
-       if(!(v)||!Syscall_ValidString((v))){ret=-1;err=-EINVAL;break;}
+       if(!(v)||!Syscall_ValidString((v))){MERR("CHECK_STR_NONULL: %p FAIL",v);ret=-1;err=-EINVAL;break;}
 #define CHECK_STR_ARRAY(arr)   do {\
         int    i;\
        char    **tmp = (char**)arr; \
@@ -38,6 +44,7 @@ extern Uint   Binary_Load(const char *file, Uint *entryPoint);
 void   SyscallHandler(tSyscallRegs *Regs);
  int   Syscall_ValidString(const char *Addr);
  int   Syscall_Valid(int Size, const void *Addr);
+ int   Syscall_MM_SetFlags(const void *Addr, Uint Flags, Uint Mask);
 
 // === CODE ===
 // TODO: Do sanity checking on arguments, ATM the user can really fuck with the kernel
@@ -114,6 +121,11 @@ void SyscallHandler(tSyscallRegs *Regs)
        // -- Unmap an address
        case SYS_UNMAP:         MM_Deallocate(Regs->Arg1);      break;
        
+       // -- Change the protection on an address
+       case SYS_SETFLAGS:
+               ret = Syscall_MM_SetFlags((void*)Regs->Arg1, Regs->Arg2, Regs->Arg3);
+               break;
+
        // -- Get Thread/Process IDs
        case SYS_GETTID:        ret = Threads_GetTID(); break;
        case SYS_GETPID:        ret = Threads_GetPID(); break;
@@ -135,13 +147,10 @@ void SyscallHandler(tSyscallRegs *Regs)
        // -- Check for messages
        case SYS_GETMSG:
                CHECK_NUM_NULLOK( (Uint*)Regs->Arg1, sizeof(Uint) );
-               // NOTE: Can't do range checking as we don't know the size
-               // - Should be done by Proc_GetMessage
-               if( Regs->Arg2 && Regs->Arg2 != -1 && !MM_IsUser(Regs->Arg2) ) {
-                       err = -EINVAL;  ret = -1;       break;
-               }
+               if( Regs->Arg3 != -1 )
+                       CHECK_NUM_NULLOK((void*)Regs->Arg3, Regs->Arg2);
                // *Source, *Data
-               ret = Proc_GetMessage((Uint*)Regs->Arg1, (void*)Regs->Arg2);
+               ret = Proc_GetMessage((Uint*)Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3);
                break;
        
        // -- Get the current timestamp
@@ -163,7 +172,7 @@ void SyscallHandler(tSyscallRegs *Regs)
                CHECK_STR_NONULL((const char*)Regs->Arg1);
                CHECK_STR_ARRAY((const char**)Regs->Arg2);
                CHECK_STR_ARRAY((const char**)Regs->Arg3);
-               CHECK_NUM_NONULL((void*)Regs->Arg5, Regs->Arg4*sizeof(int));
+               CHECK_NUM_NULLOK((void*)Regs->Arg5, Regs->Arg4*sizeof(int));
                ret = Proc_SysSpawn(
                        (const char*)Regs->Arg1, (const char**)Regs->Arg2, (const char**)Regs->Arg3,
                        Regs->Arg4, (int*)Regs->Arg5
@@ -262,6 +271,7 @@ void SyscallHandler(tSyscallRegs *Regs)
        case SYS_IOCTL:
                // All sanity checking should be done by the driver
                if( Regs->Arg3 && !MM_IsUser(Regs->Arg3) ) {
+                       MERR("IOCtl Invalid arg %p", Regs->Arg3);
                        err = -EINVAL;  ret = -1;       break;
                }
                ret = VFS_IOCtl( Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3 );
@@ -275,21 +285,35 @@ void SyscallHandler(tSyscallRegs *Regs)
                        ret = -1;
                        break;
                }
-               // Sanity check the paths
-               if(!Syscall_ValidString((char*)Regs->Arg1)
-               || !Syscall_ValidString((char*)Regs->Arg2)
-               || !Syscall_ValidString((char*)Regs->Arg3)
-               || !Syscall_ValidString((char*)Regs->Arg4) ) {
-                       err = -EINVAL;
-                       ret = -1;
-                       break;
+               
+               if( !Regs->Arg1 )
+               {
+                       if( !Syscall_ValidString((char*)Regs->Arg2) ) {
+                               err = -EINVAL;
+                               ret = -1;
+                               break;
+                       }
+                       
+                       ret = VFS_Unmount((char*)Regs->Arg2);
+               }
+               else
+               {
+                       // Sanity check the paths
+                       if(!Syscall_ValidString((char*)Regs->Arg1)
+                       || !Syscall_ValidString((char*)Regs->Arg2)
+                       || (Regs->Arg3 && !Syscall_ValidString((char*)Regs->Arg3))
+                       || !Syscall_ValidString((char*)Regs->Arg4) ) {
+                               err = -EINVAL;
+                               ret = -1;
+                               break;
+                       }
+                       ret = VFS_Mount(
+                               (char*)Regs->Arg1,      // Device
+                               (char*)Regs->Arg2,      // Mount point
+                               (char*)Regs->Arg3,      // Filesystem
+                               (char*)Regs->Arg4       // Options
+                               );
                }
-               ret = VFS_Mount(
-                       (char*)Regs->Arg1,      // Device
-                       (char*)Regs->Arg2,      // Mount point
-                       (char*)Regs->Arg3,      // Filesystem
-                       (char*)Regs->Arg4       // Options
-                       );
                break;
                
        // Wait on a set of handles
@@ -383,7 +407,31 @@ int Syscall_ValidString(const char *Addr)
  */
 int Syscall_Valid(int Size, const void *Addr)
 {
-       if(!MM_IsUser( (tVAddr)Addr ))  return 0;
+       if(!MM_IsUser( (tVAddr)Addr )) {
+               Log_Debug("Syscalls", "Syscall_Valid - %p not user", Addr);
+               return 0;
+       }
        
        return CheckMem( Addr, Size );
 }
+
+int Syscall_MM_SetFlags(const void *Addr, Uint Flags, Uint Mask)
+{
+       tPAddr  paddr = MM_GetPhysAddr(Addr);
+       Flags &= MM_PFLAG_RO|MM_PFLAG_EXEC;
+       Mask &= MM_PFLAG_RO|MM_PFLAG_EXEC;
+
+       //Log_Debug("Syscalls", "SYS_SETFLAGS: %p %x %x", Addr, Flags, Mask);   
+
+       // Enable write?
+       if( (Mask & MM_PFLAG_RO) && !(Flags & MM_PFLAG_RO) ) {
+               void    *node;
+               // HACK - Assume that RO mmap'd files are immutable
+               if( MM_GetPageNode(paddr, &node) == 0 && node ) {
+                       Flags |= MM_PFLAG_COW;
+                       Mask |= MM_PFLAG_COW;
+               }
+       }
+       MM_SetFlags((tVAddr)Addr, Flags, Mask);
+       return 0;
+}
index 283caf9..b139217 100644 (file)
@@ -43,13 +43,16 @@ SYS_SETGID  Set current Group ID
 64
 SYS_OPEN       Open a file
 SYS_REOPEN     Close a file and reuse its handle
+SYS_OPENCHILD  Open a child entry in a directory
+SYS_OPENPIPE   Open a FIFO pipe pair
 SYS_CLOSE      Close a file
+SYS_COPYFD     Create a copy of a file handle
+SYS_FDCTL      Modify properties of a file descriptor
 SYS_READ       Read from an open file
 SYS_WRITE      Write to an open file
 SYS_IOCTL      Perform an IOCtl Call
 SYS_SEEK       Seek to a new position in the file
 SYS_READDIR    Read from an open directory
-SYS_OPENCHILD  Open a child entry in a directory
 SYS_GETACL     Get an ACL Value
 SYS_SETACL     Set an ACL Value
 SYS_FINFO      Get file information
index aa1cad8..9224db5 100644 (file)
@@ -4,7 +4,7 @@
  * system.c
  * - Architecture Independent System Init
  */
-#define DEBUG  0
+#define DEBUG  1
 #include <acess.h>
 #include <hal_proc.h>
 
index 17cccca..92a7a57 100644 (file)
@@ -765,11 +765,11 @@ int Threads_Wake(tThread *Thread)
                return -EALREADY;
        
        case THREAD_STAT_SLEEPING:
-               SHORTLOCK( &glThreadListLock );
                // Remove from sleeping queue
+               SHORTLOCK( &glThreadListLock );
                Threads_int_DelFromQueue(&gSleepingThreads, Thread);
-               
                SHORTREL( &glThreadListLock );
+               
                Threads_AddActive( Thread );
                
                #if DEBUG_TRACE_STATE
@@ -835,7 +835,7 @@ int Threads_Wake(tThread *Thread)
                return -ENOTIMPL;
        
        default:
-               Warning("Threads_Wake - Unknown process status (%i)\n", Thread->Status);
+               Log_Warning("Threads", "Threads_Wake - Unknown process status (%i)", Thread->Status);
                return -EINTERNAL;
        }
 }
@@ -1079,7 +1079,7 @@ void Threads_int_DumpThread(tThread *thread)
        default:        break;
        }
        Log("  Priority %i, Quantum %i", thread->Priority, thread->Quantum);
-       Log("  KStack 0x%x", thread->KernelStack);
+       Log("  KStack %p", thread->KernelStack);
        if( thread->bInstrTrace )
                Log("  Tracing Enabled");
        Proc_DumpThreadCPUState(thread);
index d8c2924..449afcd 100644 (file)
@@ -8,19 +8,11 @@
 #define DEBUG  0
 #include <acess.h>
 #include <timers.h>
+#include <timers_int.h>
 #include <events.h>
 #include <hal_proc.h>  // Proc_GetCurThread
 #include <workqueue.h>
-
-// === TYPEDEFS ===
-struct sTimer {
-       tTimer  *Next;
-       Sint64  FiresAfter;
-       void    (*Callback)(void*);
-       void    *Argument;
-//     tMutex  Lock;
-       BOOL    bActive;
-};
+#include <threads_int.h>       // Used to get thread timer
 
 // === PROTOTYPES ===
 void   Timer_CallbackThread(void *Unused);
@@ -240,11 +232,10 @@ void Time_FreeTimer(tTimer *Timer)
  */
 void Time_Delay(int Delay)
 {
-       tTimer  *t;
-       t = Time_AllocateTimer(NULL, NULL);
+       tTimer  *t = &Proc_GetCurThread()->ThreadTimer;
+       Time_InitTimer(t, NULL, NULL);
        Time_ScheduleTimer(t, Delay);
        Threads_WaitEvents(THREAD_EVENT_TIMER);
-       Time_FreeTimer(t);
 }
 
 // === EXPORTS ===
index fab9d56..cd45121 100644 (file)
@@ -2,6 +2,7 @@
  * Acess2 VFS
  * - Directory Management Functions
  */
+#define SANITY 1
 #define DEBUG  0
 #include <acess.h>
 #include <vfs.h>
@@ -68,26 +69,22 @@ int VFS_MkNod(const char *Path, Uint Flags)
        LOG("parent = %p", parent);
        
        if(!parent) {
-               LEAVE('i', -1);
-               return -1;      // Error Check
+               errno = ENOENT;
+               goto _error;
        }
 
        // Permissions Check
        if( !VFS_CheckACL(parent, VFS_PERM_EXECUTE|VFS_PERM_WRITE) ) {
-               _CloseNode(parent);
-               mountpt->OpenHandleCount --;
-               free(absPath);
-               LEAVE('i', -1);
-               return -1;
+               errno = EACCES;
+               goto _error;
        }
        
        LOG("parent = %p", parent);
        
        if(!parent->Type || !parent->Type->MkNod) {
                Log_Warning("VFS", "VFS_MkNod - Directory has no MkNod method");
-               mountpt->OpenHandleCount --;
-               LEAVE('i', -1);
-               return -1;
+               errno = ENOTDIR;
+               goto _error;
        }
        
        // Create node
@@ -98,12 +95,21 @@ int VFS_MkNod(const char *Path, Uint Flags)
        free(absPath);
        
        // Free Parent
+       ASSERT(mountpt->OpenHandleCount>0);
        mountpt->OpenHandleCount --;
        _CloseNode(parent);
 
        // Return whatever the driver said      
        LEAVE('i', ret==NULL);
        return ret==NULL;
+
+_error:
+       _CloseNode(parent);
+       ASSERT(mountpt->OpenHandleCount>0);
+       mountpt->OpenHandleCount --;
+       free(absPath);
+       LEAVE('i', -1);
+       return -1;
 }
 
 /**
@@ -123,6 +129,7 @@ int VFS_Symlink(const char *Name, const char *Link)
        realLink = VFS_GetAbsPath( Link );
        if(!realLink) {
                Log_Warning("VFS", "Path '%s' is badly formed", Link);
+               errno = EINVAL;
                LEAVE('i', -1);
                return -1;
        }
@@ -133,12 +140,19 @@ int VFS_Symlink(const char *Name, const char *Link)
        if( VFS_MkNod(Name, VFS_FFLAG_SYMLINK) != 0 ) {
                Log_Warning("VFS", "Unable to create link node '%s'", Name);
                free(realLink);
+               // errno is set by VFS_MkNod
                LEAVE('i', -2);
                return -2;      // Make link node
        }
        
        // Write link address
        fp = VFS_Open(Name, VFS_OPENFLAG_WRITE|VFS_OPENFLAG_NOLINK);
+       if( fp == -1 ) {
+               Log_Warning("VFS", "Unable to open newly created symlink '%s'", Name);
+               free(realLink);
+               LEAVE('i', -3);
+               return -3;
+       }
        VFS_Write(fp, strlen(realLink), realLink);
        VFS_Close(fp);
        
index 8cae804..88877ab 100644 (file)
@@ -2,6 +2,7 @@
  * Acess2 VFS
  * - AllocHandle, GetHandle
  */
+#define SANITY 1
 #define DEBUG  0
 #include <acess.h>
 #include <mm_virt.h>
@@ -25,6 +26,19 @@ tVFS_Handle  *gaUserHandles = (void*)MM_PPD_HANDLES;
 tVFS_Handle    *gaKernelHandles = (void*)MM_KERNEL_VFS;
 
 // === CODE ===
+inline void _ReferenceNode(tVFS_Node *Node)
+{
+       if( !MM_GetPhysAddr(Node->Type) ) {
+               Log_Error("VFS", "Node %p's type is invalid (%p bad pointer) - %P corrupted",
+                       Node, Node->Type, MM_GetPhysAddr(&Node->Type));
+               return ;
+       }
+       if( Node->Type && Node->Type->Reference )
+               Node->Type->Reference( Node );
+       else
+               Node->ReferenceCount ++;
+}
+
 /**
  * \fn tVFS_Handle *VFS_GetHandle(int FD)
  * \brief Gets a pointer to the handle information structure
@@ -130,8 +144,8 @@ void VFS_ReferenceUserHandles(void)
                h = &gaUserHandles[i];
                if( !h->Node )
                        continue ;
-               if( h->Node->Type && h->Node->Type->Reference )
-                       h->Node->Type->Reference( h->Node );
+               _ReferenceNode(h->Node);
+               h->Mount->OpenHandleCount ++;
        }
 }
 
@@ -150,8 +164,7 @@ void VFS_CloseAllUserHandles(void)
                h = &gaUserHandles[i];
                if( !h->Node )
                        continue ;
-               if( h->Node->Type && h->Node->Type->Close )
-                       h->Node->Type->Close( h->Node );
+               _CloseNode(h->Node);
        }
 }
 
@@ -196,8 +209,7 @@ void *VFS_SaveHandles(int NumFDs, int *FDs)
                // Reference node
                if( !h->Node )
                        continue ;
-               if( h->Node->Type && h->Node->Type->Reference )
-                       h->Node->Type->Reference( h->Node );
+               _ReferenceNode(h->Node);
                h->Mount->OpenHandleCount ++;
        }       
 
@@ -243,8 +255,7 @@ void VFS_RestoreHandles(int NumFDs, void *Handles)
        
                if( !h->Node )
                        continue ;
-               if( h->Node->Type && h->Node->Type->Reference )
-                       h->Node->Type->Reference( h->Node );
+               _ReferenceNode(h->Node);
                h->Mount->OpenHandleCount ++;
        }
 }
@@ -265,8 +276,10 @@ void VFS_FreeSavedHandles(int NumFDs, void *Handles)
        
                if( !h->Node )
                        continue ;
-               if( h->Node->Type && h->Node->Type->Close )
-                       h->Node->Type->Close( h->Node );
+               _CloseNode(h->Node);
+               
+               ASSERT(h->Mount->OpenHandleCount > 0);
+               LOG("dec. mntpt '%s' to %i", h->Mount->MountPoint, h->Mount->OpenHandleCount-1);
                h->Mount->OpenHandleCount --;
        }
        free( Handles );
index 38f7c80..0261eca 100644 (file)
@@ -65,6 +65,14 @@ int VFS_Init(void)
        return 0;
 }
 
+void VFS_Deinit(void)
+{
+       SysFS_RemoveFile(giVFS_MountFileID);
+       free(gsVFS_MountFile);
+       SysFS_RemoveFile(giVFS_DriverFileID);
+       free(gsVFS_DriverFile);
+}
+
 /**
  * \fn char *VFS_GetTruePath(const char *Path)
  * \brief Gets the true path (non-symlink) of a file
@@ -164,3 +172,9 @@ void VFS_UpdateDriverFile(void)
        if(gsVFS_DriverFile)    free(gsVFS_DriverFile);
        gsVFS_DriverFile = buf;
 }
+
+void VFS_CleanupNode(tVFS_Node *Node)
+{
+       
+}
+
index c5015e6..8930177 100644 (file)
@@ -57,6 +57,7 @@ void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD,
                                        PAGE_SIZE - (mapping_base & (PAGE_SIZE-1))
                                        );
                                memset( (void*)(mapping_base + ofs), 0, PAGE_SIZE - (mapping_base & (PAGE_SIZE-1)));
+                               LOG("dune");
                        }
                        else {
                                LOG("New empty page");
index 1832ac1..1823857 100644 (file)
@@ -1,6 +1,7 @@
 /* 
  * Acess Micro - VFS Server version 1
  */
+#define SANITY 1
 #define DEBUG  0
 #include <acess.h>
 #include <vfs.h>
@@ -104,6 +105,7 @@ int VFS_Mount(const char *Device, const char *MountPoint, const char *Filesystem
        // Create mount information
        mnt = malloc( sizeof(tVFS_Mount)+deviceLen+1+mountLen+1+argLen+1 );
        if(!mnt) {
+               ASSERT(parent_mnt->OpenHandleCount > 0);
                parent_mnt->OpenHandleCount --;
                return -2;
        }
@@ -148,6 +150,7 @@ int VFS_Mount(const char *Device, const char *MountPoint, const char *Filesystem
        mnt->RootNode = fs->InitDevice(Device, (const char **)args);
        if(!mnt->RootNode) {
                free(mnt);
+               ASSERT(parent_mnt->OpenHandleCount>0);
                parent_mnt->OpenHandleCount --;
                return -2;
        }
@@ -204,7 +207,8 @@ void VFS_int_Unmount(tVFS_Mount *Mount)
                        break;
                }
                if(mpmnt) {
-                       mpmnt->OpenHandleCount -= 1;
+                       ASSERT(mpmnt->OpenHandleCount>0);
+                       mpmnt->OpenHandleCount --;
                }
                else {
                        Log_Notice("VFS", "Mountpoint '%s' has no parent", Mount->MountPoint);
@@ -227,6 +231,8 @@ int VFS_Unmount(const char *Mountpoint)
                        if( mount->OpenHandleCount ) {
                                LOG("Mountpoint busy");
                                RWLock_Release(&glVFS_MountList);
+                               Log_Log("VFS", "Unmount of '%s' deferred, still busy (%i open handles)",
+                                       Mountpoint, mount->OpenHandleCount);
                                return EBUSY;
                        }
                        if(prev)
@@ -258,12 +264,18 @@ int VFS_UnmountAll(void)
        // If we've unmounted the final filesystem, all good
        if( gVFS_Mounts == NULL) {
                RWLock_Release( &glVFS_MountList );
+               
+               // Final unmount means VFS completely deinited
+               VFS_Deinit();
                return -1;
        }
 
        for( mount = gVFS_Mounts; mount; prev = mount, mount = next )
        {
                next = mount->Next;
+               
+               ASSERT(mount->OpenHandleCount >= 0);            
+
                // Can't unmount stuff with open handles
                if( mount->OpenHandleCount > 0 ) {
                        LOG("%p (%s) has open handles (%i of them)",
index 0d23894..b2cc57f 100644 (file)
@@ -85,7 +85,7 @@ tVFS_Node *Inode_GetCache(int Handle, Uint64 Inode)
 tVFS_Node *Inode_CacheNode(int Handle, tVFS_Node *Node)
 {
        tInodeCache     *cache;
-       tCachedInode    *newEnt, *ent, *prev;
+       tCachedInode    *newEnt, *ent, *prev = NULL;
        
        cache = Inode_int_GetFSCache(Handle);
        if(!cache)      return NULL;
@@ -95,7 +95,6 @@ tVFS_Node *Inode_CacheNode(int Handle, tVFS_Node *Node)
        
        // Search Cache
        ent = cache->FirstNode;
-       prev = (tCachedInode*) &cache->FirstNode;
        for( ; ent; prev = ent, ent = ent->Next )
        {
                if(ent->Node.Inode < Node->Inode)       continue;
@@ -110,7 +109,10 @@ tVFS_Node *Inode_CacheNode(int Handle, tVFS_Node *Node)
        newEnt = malloc(sizeof(tCachedInode));
        newEnt->Next = ent;
        memcpy(&newEnt->Node, Node, sizeof(tVFS_Node));
-       prev->Next = newEnt;
+       if( prev )
+               prev->Next = newEnt;
+       else
+               cache->FirstNode = newEnt;
        newEnt->Node.ReferenceCount = 1;
 
        LOG("Cached %llx as %p", Node->Inode, &newEnt->Node);
index 5ea67c1..e83ace8 100644 (file)
@@ -2,6 +2,7 @@
  * Acess2 VFS
  * - Open, Close and ChDir
  */
+#define SANITY 1
 #define DEBUG  0
 #include <acess.h>
 #include "vfs.h"
@@ -21,9 +22,22 @@ extern int   VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode);
 extern tVFS_Node       *VFS_MemFile_Create(const char *Path);
 
 // === PROTOTYPES ===
+void   _ReferenceMount(tVFS_Mount *Mount, const char *DebugTag);
+void   _DereferenceMount(tVFS_Mount *Mount, const char *DebugTag);
  int   VFS_int_CreateHandle( tVFS_Node *Node, tVFS_Mount *Mount, int Mode );
 
 // === CODE ===
+void _ReferenceMount(tVFS_Mount *Mount, const char *DebugTag)
+{
+//     Log_Debug("VFS", "%s: inc. mntpt '%s' to %i", DebugTag, Mount->MountPoint, Mount->OpenHandleCount+1);
+       Mount->OpenHandleCount ++;
+}
+void _DereferenceMount(tVFS_Mount *Mount, const char *DebugTag)
+{
+//     Log_Debug("VFS", "%s: dec. mntpt '%s' to %i", DebugTag, Mount->MountPoint, Mount->OpenHandleCount-1);
+       ASSERT(Mount->OpenHandleCount > 0);
+       Mount->OpenHandleCount --;
+}
 /**
  * \fn char *VFS_GetAbsPath(const char *Path)
  * \brief Create an absolute path from a relative one
@@ -201,7 +215,7 @@ restart_parse:
                        *TruePath = malloc( gVFS_RootMount->MountPointLen+1 );
                        strcpy(*TruePath, gVFS_RootMount->MountPoint);
                }
-               gVFS_RootMount->OpenHandleCount ++;
+               _ReferenceMount(gVFS_RootMount, "ParsePath - Fast Tree Root");
                if(MountPoint)  *MountPoint = gVFS_RootMount;
                LEAVE('p', gVFS_RootMount->RootNode);
                return gVFS_RootMount->RootNode;
@@ -239,13 +253,19 @@ restart_parse:
                                *MountPoint = mnt;
                        RWLock_Release( &glVFS_MountList );
                        LOG("Mount %p root", mnt);
+                       _ReferenceMount(mnt, "ParsePath - Mount Root");
                        LEAVE('p', mnt->RootNode);
                        return mnt->RootNode;
                }
                #endif
                longestMount = mnt;
        }
-       longestMount->OpenHandleCount ++;       // Increment assuimg it worked
+       if(!longestMount) {
+               Log_Panic("VFS", "VFS_ParsePath - No mount for '%s'", Path);
+               return NULL;
+       }
+       
+       _ReferenceMount(longestMount, "ParsePath");
        RWLock_Release( &glVFS_MountList );
        
        // Save to shorter variable
@@ -347,7 +367,7 @@ restart_parse:
 
                        // EVIL: Goto :)
                        LOG("Symlink -> '%s', restart", Path);
-                       mnt->OpenHandleCount --;        // Not in this mountpoint
+                       _DereferenceMount(mnt, "ParsePath - sym");
                        goto restart_parse;
                }
                
@@ -430,7 +450,7 @@ _error:
                *TruePath = NULL;
        }
        // Open failed, so decrement the open handle count
-       mnt->OpenHandleCount --;
+       _DereferenceMount(mnt, "ParsePath - error");
        
        LEAVE('n');
        return NULL;
@@ -459,6 +479,13 @@ int VFS_int_CreateHandle( tVFS_Node *Node, tVFS_Mount *Mount, int Mode )
                errno = EACCES;
                LEAVE_RET('i', -1);
        }
+
+       if( MM_GetPhysAddr(Node->Type) == 0 ) {
+               Log_Error("VFS", "Node %p from mount '%s' (%s) has a bad type (%p)",
+                       Node, Mount->MountPoint, Mount->Filesystem->Name, Node->Type);
+               errno = EINTERNAL;
+               LEAVE_RET('i', -1);
+       }
        
        i = VFS_AllocHandle( !!(Mode & VFS_OPENFLAG_USER), Node, Mode );
        if( i < 0 ) {
@@ -521,28 +548,44 @@ int VFS_OpenEx(const char *Path, Uint Flags, Uint Mode)
                        LEAVE_RET('i', -1);
                }
 
-               // TODO: Check ACLs on the parent
+               // Check ACLs on the parent
                if( !VFS_CheckACL(pnode, VFS_PERM_EXECUTE|VFS_PERM_WRITE) ) {
-                       _CloseNode(pnode);
-                       pmnt->OpenHandleCount --;
-                       free(absPath);
-                       LEAVE('i', -1);
-                       return -1;
+                       errno = EACCES;
+                       goto _pnode_err;
                }
 
                // Check that there's a MkNod method
                if( !pnode->Type || !pnode->Type->MkNod ) {
                        Log_Warning("VFS", "VFS_Open - Directory has no MkNod method");
                        errno = EINVAL;
-                       LEAVE_RET('i', -1);
+                       goto _pnode_err;
                }
                
                node = pnode->Type->MkNod(pnode, file, new_flags);
+               if( !node ) {
+                       LOG("Cannot create node '%s' in '%s'", file, absPath);
+                       errno = ENOENT;
+                       goto _pnode_err;
+               }
+               // Set mountpoint (and increment open handle count)
+               mnt = pmnt;
+               _ReferenceMount(mnt, "Open - create");
                // Fall through on error check
                
                _CloseNode(pnode);
-               pmnt->OpenHandleCount --;
+               _DereferenceMount(pmnt, "Open - create");
+               goto _pnode_ok;
+
+       _pnode_err:
+               if( pnode ) {
+                       _CloseNode(pnode);
+                       _DereferenceMount(pmnt, "Open - create,fail");
+                       free(absPath);
+               }
+               LEAVE('i', -1);
+               return -1;
        }
+       _pnode_ok:
        
        // Free generated path
        free(absPath);
@@ -552,7 +595,7 @@ int VFS_OpenEx(const char *Path, Uint Flags, Uint Mode)
        {
                LOG("Cannot find node");
                errno = ENOENT;
-               LEAVE_RET('i', -1);
+               goto _error;
        }
        
        // Check for symlinks
@@ -561,26 +604,35 @@ int VFS_OpenEx(const char *Path, Uint Flags, Uint Mode)
                char    tmppath[node->Size+1];
                if( node->Size > MAX_PATH_LEN ) {
                        Log_Warning("VFS", "VFS_Open - Symlink is too long (%i)", node->Size);
-                       LEAVE_RET('i', -1);
+                       goto _error;
                }
                if( !node->Type || !node->Type->Read ) {
                        Log_Warning("VFS", "VFS_Open - No read method on symlink");
-                       LEAVE_RET('i', -1);
+                       goto _error;
                }
                // Read symlink's path
                node->Type->Read( node, 0, node->Size, tmppath );
                tmppath[ node->Size ] = '\0';
                _CloseNode( node );
+               _DereferenceMount(mnt, "Open - symlink");
                // Open the target
                node = VFS_ParsePath(tmppath, NULL, &mnt);
                if(!node) {
                        LOG("Cannot find symlink target node (%s)", tmppath);
                        errno = ENOENT;
-                       LEAVE_RET('i', -1);
+                       goto _error;
                }
        }
 
-       LEAVE_RET('x', VFS_int_CreateHandle(node, mnt, Flags));
+        int    ret = VFS_int_CreateHandle(node, mnt, Flags);
+       LEAVE_RET('x', ret);
+_error:
+       if( node )
+       {
+               _DereferenceMount(mnt, "Open - error");
+               _CloseNode(node);
+       }
+       LEAVE_RET('i', -1);
 }
 
 
@@ -624,7 +676,7 @@ int VFS_OpenChild(int FD, const char *Name, Uint Mode)
        }
 
        // Increment open handle count, no problems with the mount going away as `h` is already open on it
-       h->Mount->OpenHandleCount ++;
+       _ReferenceMount(h->Mount, "OpenChild");
 
        LEAVE_RET('x', VFS_int_CreateHandle(node, h->Mount, Mode));
 }
@@ -676,7 +728,12 @@ void VFS_Close(int FD)
                Log_Warning("VFS", "Invalid file handle passed to VFS_Close, 0x%x", FD);
                return;
        }
-       
+
+       if( h->Node == NULL ) {
+               Log_Warning("VFS", "Non-open handle passed to VFS_Close, 0x%x", FD);
+               return ;
+       }       
+
        #if VALIDATE_VFS_FUNCTIPONS
        if(h->Node->Close && !MM_GetPhysAddr(h->Node->Close)) {
                Log_Warning("VFS", "Node %p's ->Close method is invalid (%p)",
@@ -685,10 +742,12 @@ void VFS_Close(int FD)
        }
        #endif
        
+       LOG("Handle %x", FD);
        _CloseNode(h->Node);
 
-       if( h->Mount )
-               h->Mount->OpenHandleCount --;   
+       if( h->Mount ) {
+               _DereferenceMount(h->Mount, "Close");
+       }
 
        h->Node = NULL;
 }
index 70f0c91..5988ee7 100644 (file)
@@ -47,8 +47,6 @@ enum {
        VBE_DISPI_INDEX_Y_OFFSET\r
 };\r
 \r
-extern void MM_DumpTables(tVAddr Start, tVAddr End);\r
-\r
 // === PROTOTYPES ===\r
 // Driver\r
  int   BGA_Install(char **Arguments);\r
@@ -221,6 +219,10 @@ int BGA_IOCtl(tVFS_Node *Node, int ID, void *Data)
                                gBGA_CursorPos.x, gBGA_CursorPos.y\r
                                );\r
                break;\r
+\r
+       case VIDEO_IOCTL_SETCURSORBITMAP:\r
+               DrvUtil_Video_SetCursor( &gBGA_DrvUtil_BufInfo, Data );\r
+               return 0;\r
        \r
        default:\r
                LEAVE('i', -2);\r
index de0b30a..33df847 100644 (file)
@@ -5,7 +5,7 @@
  * dir.c
  * - Directory Handling
  */
-#define DEBUG  1
+#define DEBUG  0
 #define VERBOSE        0
 #include "ext2_common.h"
 
@@ -18,8 +18,6 @@ tVFS_Node     *Ext2_FindDir(tVFS_Node *Node, const char *FileName);
 tVFS_Node      *Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
  int   Ext2_Unlink(tVFS_Node *Node, const char *OldName);
  int   Ext2_Link(tVFS_Node *Parent, const char *Name, tVFS_Node *Node);
-// --- Helpers ---
-tVFS_Node      *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeId);
 
 // === GLOBALS ===
 tVFS_NodeType  gExt2_DirType = {
@@ -234,7 +232,6 @@ int Ext2_Unlink(tVFS_Node *Node, const char *OldName)
  */
 int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child)
 {      
-       #if 1
        tExt2_Disk      *disk = Node->ImplPtr;
        tExt2_Inode     inode;
        tExt2_DirEnt    *dirent;
@@ -401,83 +398,5 @@ int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child)
        Mutex_Release(&Node->Lock);
        LEAVE('i', 0);
        return 0;
-       #else
-       Log_Warning("Ext2", "TODO: Impliment Ext2_Link");
-       return 1;
-       #endif
-}
-
-// ---- INTERNAL FUNCTIONS ----
-/**
- * \fn vfs_node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)
- * \brief Create a new VFS Node
- */
-tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)
-{
-       tExt2_Inode     inode;
-       tVFS_Node       retNode;
-       tVFS_Node       *tmpNode;
-       
-       if( !Ext2_int_ReadInode(Disk, InodeID, &inode) )
-               return NULL;
-       
-       if( (tmpNode = Inode_GetCache(Disk->CacheID, InodeID)) )
-               return tmpNode;
-
-       memset(&retNode, 0, sizeof(retNode));   
-       
-       // Set identifiers
-       retNode.Inode = InodeID;
-       retNode.ImplPtr = Disk;
-       retNode.ImplInt = inode.i_links_count;
-       
-       // Set file length
-       retNode.Size = inode.i_size;
-       
-       // Set Access Permissions
-       retNode.UID = inode.i_uid;
-       retNode.GID = inode.i_gid;
-       retNode.NumACLs = 3;
-       retNode.ACLs = VFS_UnixToAcessACL(inode.i_mode & 0777, inode.i_uid, inode.i_gid);
-       
-       //  Set Function Pointers
-       retNode.Type = &gExt2_FileType;
-       
-       switch(inode.i_mode & EXT2_S_IFMT)
-       {
-       // Symbolic Link
-       case EXT2_S_IFLNK:
-               retNode.Flags = VFS_FFLAG_SYMLINK;
-               break;
-       // Regular File
-       case EXT2_S_IFREG:
-               retNode.Flags = 0;
-               retNode.Size |= (Uint64)inode.i_dir_acl << 32;
-               break;
-       // Directory
-       case EXT2_S_IFDIR:
-               retNode.Type = &gExt2_DirType;
-               retNode.Flags = VFS_FFLAG_DIRECTORY;
-               retNode.Data = calloc( sizeof(Uint16), DivUp(retNode.Size, Disk->BlockSize) );
-               break;
-       // Unknown, Write protect it to be safe 
-       default:
-               retNode.Flags = VFS_FFLAG_READONLY;
-               break;
-       }
-       
-       // Set Timestamps
-       retNode.ATime = inode.i_atime * 1000;
-       retNode.MTime = inode.i_mtime * 1000;
-       retNode.CTime = inode.i_ctime * 1000;
-       
-       // Save in node cache and return saved node
-       return Inode_CacheNode(Disk->CacheID, &retNode);
-}
-
-int Ext2_int_WritebackNode(tExt2_Disk *Disk, tVFS_Node *Node)
-{
-       Log_Warning("Ext2","TODO: Impliment Ext2_int_WritebackNode");
-       return 0;
 }
 
index adf9163..4d13f1e 100644 (file)
@@ -13,9 +13,6 @@
 #define MIN_BLOCKS_PER_GROUP   2\r
 #define MAX_BLOCK_LOG_SIZE     10      // 1024 << 10 = 1MiB\r
 \r
-// === IMPORTS ===\r
-extern tVFS_NodeType   gExt2_DirType;\r
-\r
 // === PROTOTYPES ===\r
  int   Ext2_Install(char **Arguments);\r
  int   Ext2_Cleanup(void);\r
@@ -236,7 +233,8 @@ void Ext2_CloseFile(tVFS_Node *Node)
        if( Node->Flags & VFS_FFLAG_DIRTY )\r
        {\r
                // Commit changes\r
-               Log_Warning("Ext2", "TODO: Commit node changes");\r
+               Ext2_int_WritebackNode(disk, Node);\r
+               Node->Flags &= ~VFS_FFLAG_DIRTY;\r
        }\r
 \r
        int was_not_referenced = (Node->ImplInt == 0);\r
@@ -247,7 +245,7 @@ void Ext2_CloseFile(tVFS_Node *Node)
                {\r
                        LOG("Removng inode");\r
                        // Remove inode\r
-                       Log_Warning("Ext2", "TODO: Remove inode when not referenced");\r
+                       Log_Warning("Ext2", "TODO: Remove inode when not referenced (%x)", (Uint32)Node->Inode);\r
                }\r
                if( acls != &gVFS_ACL_EveryoneRW ) {\r
                        free(acls);\r
@@ -325,6 +323,118 @@ int Ext2_int_WriteInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode)
        return 1;\r
 }\r
 \r
+/**\r
+ * \fn vfs_node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)\r
+ * \brief Create a new VFS Node\r
+ */\r
+tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)\r
+{\r
+       tExt2_Inode     inode;\r
+       tVFS_Node       retNode;\r
+       tVFS_Node       *tmpNode;\r
+       \r
+       if( !Ext2_int_ReadInode(Disk, InodeID, &inode) )\r
+               return NULL;\r
+       \r
+       if( (tmpNode = Inode_GetCache(Disk->CacheID, InodeID)) )\r
+               return tmpNode;\r
+\r
+       memset(&retNode, 0, sizeof(retNode));   \r
+       \r
+       // Set identifiers\r
+       retNode.Inode = InodeID;\r
+       retNode.ImplPtr = Disk;\r
+       retNode.ImplInt = inode.i_links_count;\r
+       if( inode.i_links_count == 0 ) {\r
+               Log_Notice("Ext2", "Inode %p:%x is not referenced, bug?", Disk, InodeID);\r
+       }\r
+       \r
+       // Set file length\r
+       retNode.Size = inode.i_size;\r
+       \r
+       // Set Access Permissions\r
+       retNode.UID = inode.i_uid;\r
+       retNode.GID = inode.i_gid;\r
+       retNode.NumACLs = 3;\r
+       retNode.ACLs = VFS_UnixToAcessACL(inode.i_mode & 0777, inode.i_uid, inode.i_gid);\r
+       \r
+       //  Set Function Pointers\r
+       retNode.Type = &gExt2_FileType;\r
+       \r
+       switch(inode.i_mode & EXT2_S_IFMT)\r
+       {\r
+       // Symbolic Link\r
+       case EXT2_S_IFLNK:\r
+               retNode.Flags = VFS_FFLAG_SYMLINK;\r
+               break;\r
+       // Regular File\r
+       case EXT2_S_IFREG:\r
+               retNode.Flags = 0;\r
+               retNode.Size |= (Uint64)inode.i_dir_acl << 32;\r
+               break;\r
+       // Directory\r
+       case EXT2_S_IFDIR:\r
+               retNode.Type = &gExt2_DirType;\r
+               retNode.Flags = VFS_FFLAG_DIRECTORY;\r
+               retNode.Data = calloc( sizeof(Uint16), DivUp(retNode.Size, Disk->BlockSize) );\r
+               break;\r
+       // Unknown, Write protect it to be safe \r
+       default:\r
+               retNode.Flags = VFS_FFLAG_READONLY;\r
+               break;\r
+       }\r
+       \r
+       // Set Timestamps\r
+       retNode.ATime = inode.i_atime * 1000;\r
+       retNode.MTime = inode.i_mtime * 1000;\r
+       retNode.CTime = inode.i_ctime * 1000;\r
+       \r
+       // Save in node cache and return saved node\r
+       return Inode_CacheNode(Disk->CacheID, &retNode);\r
+}\r
+\r
+int Ext2_int_WritebackNode(tExt2_Disk *Disk, tVFS_Node *Node)\r
+{\r
+       tExt2_Inode     inode;\r
+\r
+       if( Disk != Node->ImplPtr ) {\r
+               Log_Error("Ext2", "Ext2_int_WritebackNode - Disk != Node->ImplPtr");\r
+               return -1;\r
+       }\r
+       \r
+       if( Node->Flags & VFS_FFLAG_SYMLINK ) {\r
+               inode.i_mode = EXT2_S_IFLNK;\r
+       }\r
+       else if( Node->Flags & VFS_FFLAG_DIRECTORY ) {\r
+               inode.i_mode = EXT2_S_IFDIR;\r
+       }\r
+       else if( Node->Flags & VFS_FFLAG_READONLY ) {\r
+               Log_Notice("Ext2", "Not writing back readonly inode %p:%x", Disk, Node->Inode);\r
+               return 1;\r
+       }\r
+       else {\r
+               inode.i_mode = EXT2_S_IFREG;\r
+               inode.i_dir_acl = Node->Size >> 32;\r
+       }\r
+\r
+       inode.i_size = Node->Size & 0xFFFFFFFF;\r
+       inode.i_links_count = Node->ImplInt;\r
+\r
+       inode.i_uid = Node->UID;\r
+       inode.i_gid = Node->GID;\r
+\r
+       inode.i_atime = Node->ATime / 1000;\r
+       inode.i_mtime = Node->MTime / 1000;\r
+       inode.i_ctime = Node->CTime / 1000;\r
+\r
+       // TODO: Compact ACLs into unix mode\r
+       Log_Warning("Ext2", "TODO: Support converting Acess ACLs into unix modes");\r
+\r
+       Ext2_int_WriteInode(Disk, Node->Inode, &inode);\r
+\r
+       return 0;\r
+}\r
+\r
 /**\r
  * \fn Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)\r
  * \brief Get the address of a block from an inode's list\r
index 5515429..4c8c45e 100644 (file)
@@ -23,6 +23,10 @@ typedef struct {
        tExt2_Group             Groups[];
 } tExt2_Disk;
 
+// === GLOBALS ===
+extern tVFS_NodeType   gExt2_FileType;
+extern tVFS_NodeType   gExt2_DirType;
+
 // === FUNCTIONS ===
 // --- Common ---
 extern void    Ext2_CloseFile(tVFS_Node *Node);
@@ -37,6 +41,8 @@ extern int    Ext2_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 extern tVFS_Node       *Ext2_FindDir(tVFS_Node *Node, const char *FileName);
 extern tVFS_Node       *Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
 extern int     Ext2_Link(tVFS_Node *Parent, const char *Name, tVFS_Node *Node);
+extern tVFS_Node       *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeId);
+extern int     Ext2_int_WritebackNode(tExt2_Disk *Disk, tVFS_Node *Node);
 // --- Read ---
 extern size_t  Ext2_Read(tVFS_Node *node, off_t offset, size_t length, void *buffer);
 // --- Write ---
index 9402830..3983b93 100644 (file)
@@ -97,6 +97,7 @@ extern int    FAT_int_DerefNode(tVFS_Node *Node);
 extern void    FAT_int_ClearNodeCache(tFAT_VolInfo *Disk);
 
 // --- FAT Access ---
+#define GETFATVALUE_EOC        0xFFFFFFFF
 extern Uint32  FAT_int_GetFatValue(tFAT_VolInfo *Disk, Uint32 Cluster);
 #if SUPPORT_WRITE
 extern Uint32  FAT_int_AllocateCluster(tFAT_VolInfo *Disk, Uint32 Previous);
index b74b31f..c7268d7 100644 (file)
@@ -278,7 +278,10 @@ int FAT_int_GetEntryByCluster(tVFS_Node *DirNode, Uint32 Cluster, fat_filetable
        fat_filetable   fileinfo[ents_per_sector];
         int    i, sector;
 
-       Mutex_Acquire(&DirNode->Lock);
+       if( Mutex_Acquire(&DirNode->Lock) ) {
+               return -EINTR;
+       }
+       
        sector = 0;
        for( i = 0; ; i ++ )
        {
@@ -318,7 +321,7 @@ int FAT_int_GetEntryByCluster(tVFS_Node *DirNode, Uint32 Cluster, fat_filetable
        }
        
        Mutex_Release(&DirNode->Lock);
-       return -1;
+       return -ENOENT;
 }
 
 /* 
@@ -445,7 +448,9 @@ Uint16 *FAT_int_GetLFN(tVFS_Node *Node, int ID)
        tFAT_LFNCache   *cache;
         int    i, firstFree;
        
-       Mutex_Acquire( &Node->Lock );
+       if( Mutex_Acquire( &Node->Lock ) ) {
+               return NULL;
+       }
        
        // TODO: Thread Safety (Lock things)
        cache = Node->Data;
@@ -659,6 +664,7 @@ tVFS_Node *FAT_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode)
        if( ret ) {
                if( (ret->Inode >> 32) != 0 ) {
                        LOG("Node in cache, quick return");
+                       LEAVE('p', ret);
                        return ret;
                }
                else {
@@ -812,7 +818,9 @@ int FAT_Link(tVFS_Node *DirNode, const char *NewName, tVFS_Node *NewNode)
        const int eps = 512 / sizeof(fat_filetable);
        fat_filetable   fileinfo[eps];
        
-       Mutex_Acquire( &DirNode->Lock );
+       if( Mutex_Acquire( &DirNode->Lock ) ) {
+               return EINTR;
+       }
 
        // -- Ensure duplicates aren't created --
        if( FAT_int_GetEntryByName(DirNode, NewName, &ft) >= 0 ) {
@@ -1096,7 +1104,9 @@ int FAT_Unlink(tVFS_Node *Node, const char *OldName)
        tVFS_Node       *child;
        fat_filetable   ft;
        
-       Mutex_Acquire(&Node->Lock);
+       if( Mutex_Acquire(&Node->Lock) ) {
+               return EINTR;
+       }
 
        int id = FAT_int_GetEntryByName(Node, OldName, &ft);
        if(id == -1) {
index f7ebafe..be0a51c 100644 (file)
@@ -98,7 +98,11 @@ int FAT_Detect(int FD)
 \r
        if(bs.bps == 0 || bs.spc == 0)\r
                return 0;\r
-       \r
+\r
+       Log_Debug("FAT", "_Detect: Media type = %02x", bs.mediaDesc);\r
+       if( bs.mediaDesc < 0xF0 )\r
+               return 0;\r
+\r
        return 1;\r
 }\r
 /**\r
@@ -334,7 +338,7 @@ int FAT_int_GetAddress(tVFS_Node *Node, Uint64 Offset, Uint64 *Addr, Uint32 *Clu
                        if(Cluster)     *Cluster = cluster;\r
                        cluster = FAT_int_GetFatValue(disk, cluster);\r
                        // Check for end of cluster chain\r
-                       if(cluster == 0xFFFFFFFF) {     LEAVE('i', 1);  return 1;}\r
+                       if(cluster == GETFATVALUE_EOC) { LEAVE('i', 1); return 1; }\r
                }\r
                if(Cluster)     *Cluster = cluster;\r
        }\r
@@ -417,7 +421,7 @@ size_t FAT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
        for(i = preSkip; i--; )\r
        {\r
                cluster = FAT_int_GetFatValue(disk, cluster);\r
-               if(cluster == -1) {\r
+               if(cluster == GETFATVALUE_EOC) {\r
                        Log_Warning("FAT", "Offset is past end of cluster chain mark");\r
                        LEAVE('i', 0);\r
                        return 0;\r
@@ -443,7 +447,7 @@ size_t FAT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
                LOG("pos = %i, Reading the rest of the clusters");\r
                // Get next cluster in the chain\r
                cluster = FAT_int_GetFatValue(disk, cluster);\r
-               if(cluster == -1) {\r
+               if(cluster == GETFATVALUE_EOC) {\r
                        Log_Warning("FAT", "Read past End of Cluster Chain (Align)");\r
                        LEAVE('X', pos);\r
                        return pos;\r
@@ -461,7 +465,7 @@ size_t FAT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
        // Read the rest of the cluster data\r
        for( ; count; count -- )\r
        {\r
-               if(cluster == -1) {\r
+               if(cluster == GETFATVALUE_EOC) {\r
                        Log_Warning("FAT", "Read past End of Cluster Chain (Bulk)");\r
                        LEAVE('X', pos);\r
                        return pos;\r
@@ -519,7 +523,7 @@ size_t FAT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffe
        while( Offset > disk->BytesPerCluster )\r
        {\r
                cluster = FAT_int_GetFatValue( disk, cluster );\r
-               if(cluster == -1) {\r
+               if(cluster == GETFATVALUE_EOC) {\r
                        Log_Warning("FAT", "EOC Unexpectedly Reached");\r
                        LEAVE('i', 0);\r
                        return 0;\r
@@ -565,7 +569,7 @@ size_t FAT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffe
                \r
                // Get next cluster (allocating if needed)\r
                tmpCluster = FAT_int_GetFatValue(disk, cluster);\r
-               if(tmpCluster == -1) {\r
+               if(tmpCluster == GETFATVALUE_EOC) {\r
                        tmpCluster = FAT_int_AllocateCluster(disk, cluster);\r
                        if( tmpCluster == 0 )\r
                                goto ret_incomplete;\r
@@ -581,7 +585,7 @@ size_t FAT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffe
                \r
                // Get next cluster (allocating if needed)\r
                tmpCluster = FAT_int_GetFatValue(disk, cluster);\r
-               if(tmpCluster == -1) {\r
+               if(tmpCluster == GETFATVALUE_EOC) {\r
                        bNewCluster = 1;\r
                        tmpCluster = FAT_int_AllocateCluster(disk, cluster);\r
                        if( tmpCluster == 0 )\r
index 340ccf8..7bf62ef 100644 (file)
@@ -20,14 +20,15 @@ Uint32 FAT_int_GetFatValue(tFAT_VolInfo *Disk, Uint32 cluster)
        Uint32  val = 0;
        Uint32  ofs;
        ENTER("pDisk xCluster", Disk, cluster);
+       
        Mutex_Acquire( &Disk->lFAT );
        #if CACHE_FAT
        if( Disk->ClusterCount <= giFAT_MaxCachedClusters )
        {
                val = Disk->FATCache[cluster];
-               if(Disk->type == FAT12 && val == EOC_FAT12)     val = -1;
-               if(Disk->type == FAT16 && val == EOC_FAT16)     val = -1;
-               if(Disk->type == FAT32 && val == EOC_FAT32)     val = -1;
+               if(Disk->type == FAT12 && val == EOC_FAT12)     val = GETFATVALUE_EOC;
+               if(Disk->type == FAT16 && val == EOC_FAT16)     val = GETFATVALUE_EOC;
+               if(Disk->type == FAT32 && val == EOC_FAT32)     val = GETFATVALUE_EOC;
        }
        else
        {
@@ -37,13 +38,13 @@ Uint32 FAT_int_GetFatValue(tFAT_VolInfo *Disk, Uint32 cluster)
                        VFS_ReadAt(Disk->fileHandle, ofs+(cluster/2)*3, 3, &val);
                        LOG("3 bytes at 0x%x are (Uint32)0x%x", ofs+(cluster/2)*3, val);
                        val = (cluster & 1) ? (val>>12) : (val & 0xFFF);
-                       if(val == EOC_FAT12)    val = -1;
+                       if(val == EOC_FAT12)    val = GETFATVALUE_EOC;
                } else if(Disk->type == FAT16) {
                        VFS_ReadAt(Disk->fileHandle, ofs+cluster*2, 2, &val);
-                       if(val == EOC_FAT16)    val = -1;
+                       if(val == EOC_FAT16)    val = GETFATVALUE_EOC;
                } else {
                        VFS_ReadAt(Disk->fileHandle, ofs+cluster*4, 4, &val);
-                       if(val == EOC_FAT32)    val = -1;
+                       if(val == EOC_FAT32)    val = GETFATVALUE_EOC;
                }
        #if CACHE_FAT
        }
index a0b3b31..1ad26e5 100644 (file)
@@ -223,6 +223,7 @@ int FAT_int_DerefNode(tVFS_Node *Node)
                // Already out of the list :)
                if(cnode->Node.Data)
                        free(cnode->Node.Data);
+               VFS_CleanupNode(&cnode->Node);
                free(cnode);
                bFreed = 1;
        }
index 4a6635b..5119442 100644 (file)
@@ -1,4 +1,6 @@
 <?php
+date_default_timezone_set("UTC");
+
 $lGenDate = date("Y-m-d H:i");
 $gOutput = <<<EOF
 /*
index fe2fc4d..ccbbe0c 100644 (file)
@@ -19,12 +19,13 @@ Dir "Libs" {
        File "ld-acess.so" "__BIN__/Libs/ld-acess.so"
        File "libld-acess.so" "__BIN__/Libs/libld-acess.so"
        File "libc.so" "__BIN__/Libs/libc.so"
-       File "libgcc.so" "__BIN__/Libs/libgcc.so"
        File "libreadline.so" "__BIN__/Libs/libreadline.so"
        File "libnet.so" "__BIN__/Libs/libnet.so"
        File "liburi.so" "__BIN__/Libs/liburi.so"
        File "libimage_sif.so" "__BIN__/Libs/libimage_sif.so"
        File "libaxwin3.so" "__BIN__/Libs/libaxwin3.so"
+       File "libposix.so" "__BIN__/Libs/libposix.so"
+       File "libpsocket.so" "__BIN__/Libs/libpsocket.so"
 }
 Dir "Conf" {
        File "BootConf.cfg" "__FS__/Conf/BootConf.cfg"
@@ -34,6 +35,7 @@ Dir "Apps" {
                Dir "3.0" {
                        File "AxWinWM" "__BIN__/Apps/AxWin/3.0/AxWinWM"
                        File "AxWinUI" "__BIN__/Apps/AxWin/3.0/AxWinUI"
+                       File "ate" "__BIN__/Apps/AxWin/3.0/ate"
                        File "AcessLogoSmall.sif" "__SRC__/Usermode/Applications/axwin3_src/AcessLogoSmall.sif"
                }
        }
index 2a02fd2..deb0552 100644 (file)
@@ -85,8 +85,8 @@ void *IPStack_Adapter_Add(const tIPStack_AdapterType *Type, void *Ptr, const voi
        Mutex_Release( &glIP_Adapters );
        
        // Watch the adapter for incoming packets
-       tTID tid = Proc_SpawnWorker(Adapter_int_WatchThread, ret);
-       if(tid < 0) {
+       void *worker = Proc_SpawnWorker(Adapter_int_WatchThread, ret);
+       if(!worker) {
                Log_Warning("IPStack", "Unable to create watcher thread for %p", ret);
        }
        
index 8b0904c..1d80569 100644 (file)
@@ -255,7 +255,11 @@ size_t UDP_Channel_Write(tVFS_Node *Node, off_t Offset, size_t Length, const voi
        const tUDPEndpoint      *ep;
        const void      *data;
         int    ofs;
-       if(chan->LocalPort == 0)        return 0;
+       
+       if(chan->LocalPort == 0) {
+               Log_Notice("UDP", "Write to channel %p with zero local port", chan);
+               return 0;
+       }
        
        ep = Buffer;    
        ofs = 2 + 2 + IPStack_GetAddressSize( ep->AddrType );
index a131a44..050faad 100644 (file)
@@ -122,7 +122,7 @@ int ATA_ScanDisk(int Disk)
 /**
  * \fn Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
  */
-int ATA_ReadRaw(void *Ptr, Uint64 Address, Uint Count, void *Buffer)
+int ATA_ReadRaw(void *Ptr, Uint64 Address, size_t Count, void *Buffer)
 {
         int    Disk = (tVAddr)Ptr;
         int    ret;
@@ -160,7 +160,7 @@ int ATA_ReadRaw(void *Ptr, Uint64 Address, Uint Count, void *Buffer)
 /**
  * \fn Uint ATA_WriteRaw(Uint64 Address, Uint Count, const void *Buffer, Uint Disk)
  */
-int ATA_WriteRaw(void *Ptr, Uint64 Address, Uint Count, const void *Buffer)
+int ATA_WriteRaw(void *Ptr, Uint64 Address, size_t Count, const void *Buffer)
 {
         int    Disk = (tVAddr)Ptr;
         int    ret;
index 33e311b..8dbe04e 100644 (file)
@@ -3,7 +3,7 @@
 
 OBJ  = main.o
 OBJ += usb.o usb_lowlevel.o usb_devinit.o usb_io.o usb_poll.o usb_info.o
-OBJ += hub.o
+OBJ += hub.o portctl.o
 CPPFLAGS = -Iinclude
 NAME = Core
 
index 7bc4dc2..23f3a36 100644 (file)
 // resvd
 #define SET_FEATURE    3
 
-#define PORT_CONNECTION        0
-#define PORT_ENABLE    1
-#define PORT_SUSPEND   2
-#define PORT_OVER_CURRENT      3
-#define PORT_RESET     4
-#define PORT_POWER     8
-#define PORT_LOW_SPEED 9
-#define C_PORT_CONNECTION      16
-#define C_PORT_ENABLE  17
-#define C_PORT_SUSPEND 18
-#define C_PORT_OVER_CURRENT    19
-#define C_PORT_RESET   20
-#define PORT_TEST      21
-#define PORT_INDICATOR 21
-
 struct sHubDescriptor
 {
        Uint8   DescLength;
@@ -56,6 +41,9 @@ void  Hub_Connected(tUSBInterface *Dev, void *Descriptors, size_t Length);
 void   Hub_Disconnected(tUSBInterface *Dev);
 void   Hub_PortStatusChange(tUSBInterface *Dev, int Endpoint, int Length, void *Data);
 void   Hub_int_HandleChange(tUSBInterface *Dev, int Port);
+void   Hub_SetPortFeature(tUSBInterface *Dev, int Port, int Feat);
+void   Hub_ClearPortFeature(tUSBInterface *HubDev, int Port, int Feat);
+int    Hub_GetPortStatus(tUSBInterface *HubDev, int Port, int Flag);
 
 // === GLOBALS ===
 tUSBDriver     gUSBHub_Driver = {
@@ -150,13 +138,8 @@ void Hub_int_HandleChange(tUSBInterface *Dev, int Port)
                        // - Power on port
                        USB_Request(Dev, 0, 0x23, SET_FEATURE, PORT_POWER, Port, 0, NULL);
                        Time_Delay(info->PowerOnDelay);
-                       // - Reset
-                       USB_Request(Dev, 0, 0x23, SET_FEATURE, PORT_RESET, Port, 0, NULL);
-                       Time_Delay(20); // Spec says 10ms after reset, but how long is reset?
-                       // - Enable
-                       USB_Request(Dev, 0, 0x23, SET_FEATURE, PORT_ENABLE, Port, 0, NULL);
-                       // - Poke USB Stack
-                       USB_DeviceConnected(info->HubPtr, Port);
+                       // - Start reset process
+                       USB_PortCtl_BeginReset(info->HubPtr, Port);
                }
                else {
                        // Disconnected
@@ -179,3 +162,20 @@ void Hub_int_HandleChange(tUSBInterface *Dev, int Port)
                USB_Request(Dev, 0, 0x23, CLEAR_FEATURE, C_PORT_RESET, Port, 0, NULL);
        }
 }
+
+void Hub_SetPortFeature(tUSBInterface *Dev, int Port, int Feat)
+{
+       USB_Request(Dev, 0, 0x23, SET_FEATURE, Feat, Port, 0, NULL);
+}
+
+void Hub_ClearPortFeature(tUSBInterface *Dev, int Port, int Feat)
+{
+       USB_Request(Dev, 0, 0x23, CLEAR_FEATURE, Feat, Port, 0, NULL);
+}
+
+int Hub_GetPortStatus(tUSBInterface *Dev, int Port, int Flag)
+{
+       Uint16  status[2];      // Status, Change
+       USB_Request(Dev, 0, 0xA3, GET_STATUS, 0, Port, 4, status);
+       return !!(status[0] & (1 << Flag));
+}
index 8b4f96d..7806e1b 100644 (file)
@@ -50,7 +50,11 @@ struct sUSBHostDef
        tUSBBulkOp      SendBulk;
        void    (*FreeOp)(void *Ptr, void *Handle);
 
+       // Root hub stuff
        void    (*CheckPorts)(void *Ptr);
+       void    (*SetPortFeature)(void *Ptr, int PortNum, int Feat);
+       void    (*ClearPortFeature)(void *Ptr, int PortNum, int Feat);
+        int    (*GetPortStatus)(void *Ptr, int PortNum, int Flag);
 };
 
 extern tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts);
index 6b32d49..b38b101 100644 (file)
@@ -23,5 +23,26 @@ extern void  USB_RemoveHub(tUSBHub *Hub);
 extern void    USB_DeviceConnected(tUSBHub *Hub, int Port);
 extern void    USB_DeviceDisconnected(tUSBHub *Hub, int Port);
 
+#define PORT_CONNECTION        0
+#define PORT_ENABLE    1
+#define PORT_SUSPEND   2
+#define PORT_OVER_CURRENT      3
+#define PORT_RESET     4
+#define PORT_POWER     8
+#define PORT_LOW_SPEED 9
+#define C_PORT_CONNECTION      16
+#define C_PORT_ENABLE  17
+#define C_PORT_SUSPEND 18
+#define C_PORT_OVER_CURRENT    19
+#define C_PORT_RESET   20
+#define PORT_TEST      21
+#define PORT_INDICATOR 21
+
+extern void    Hub_SetPortFeature(tUSBInterface *HubDev, int Port, int Feat);
+extern void    Hub_ClearPortFeature(tUSBInterface *HubDev, int Port, int Feat);
+extern int     Hub_GetPortStatus(tUSBInterface *HubDev, int Port, int Flag);
+
+extern void    USB_PortCtl_BeginReset(tUSBHub *Hub, int Port);
+
 #endif
 
index cdbe2ee..0464550 100644 (file)
@@ -13,6 +13,7 @@
 // === IMPORTS ===
 extern void    USB_PollThread(void *unused);
 extern void    USB_AsyncThread(void *Unused);
+extern void    USB_PortCtl_Init(void);
 
 // === PROTOTYPES ===
  int   USB_Install(char **Arguments);
@@ -43,6 +44,7 @@ tDevFS_Driver gUSB_DrvInfo = {
  */
 int USB_Install(char **Arguments)
 {
+       USB_PortCtl_Init();
        Proc_SpawnWorker(USB_PollThread, NULL);
        Proc_SpawnWorker(USB_AsyncThread, NULL);
        
diff --git a/KernelLand/Modules/USB/Core/portctl.c b/KernelLand/Modules/USB/Core/portctl.c
new file mode 100644 (file)
index 0000000..1f6cf86
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Acess2 USB Stack
+ * - By John Hodge (thePowersGang)
+ *
+ * portctl.c
+ * - Port control code
+ */
+#define DEBUG  1
+#define SANITY 1
+#include <acess.h>
+#include "usb.h"
+#include <workqueue.h>
+#include <timers.h>
+#include <usb_hub.h>
+
+// === PROTOTYPES ===
+void   USB_PortCtl_Init(void);
+void   USB_PortCtl_Worker(void *Unused);
+void   USB_PortCtl_SetPortFeature(tUSBHub *Hub, int Port, int Feat);
+void   USB_PortCtl_ClearPortFeature(tUSBHub *Hub, int Port, int Feat);
+ int   USB_PortCtl_GetPortStatus(tUSBHub *Hub, int Port, int Flag);
+
+// === GLOBALS === 
+tWorkqueue     gUSB_PortCtl_WorkQueue;
+
+// === CODE ===
+void USB_PortCtl_Init(void)
+{
+       Workqueue_Init(&gUSB_PortCtl_WorkQueue, "USB Port Reset Work Queue", offsetof(tUSBHubPort, ListNext));
+       Proc_SpawnWorker(USB_PortCtl_Worker, NULL);
+}
+
+void USB_PortCtl_Worker(void *Unused)
+{
+       Threads_SetName("USB PortCtl Worker");
+       for(;;)
+       {
+               tUSBHubPort *port;
+               tUSBHub *hub;
+              
+               port = Workqueue_GetWork(&gUSB_PortCtl_WorkQueue);
+               if( !port ) {
+                       Log_Warning("USB", "PortCtl Workqueue returned NULL");
+                       break;
+               }
+               hub = (tUSBHub*)(port - port->PortNum) - 1;
+
+               LOG("port = %p, hub = %p", port, hub);
+
+               switch(port->Status)
+               {
+               case 1:
+                       // Assert reset
+                       USB_PortCtl_SetPortFeature(hub, port->PortNum, PORT_RESET);
+                       LOG("Port reset starting");
+                       // Wait 50 ms
+                       Time_Delay(50);
+                       USB_PortCtl_ClearPortFeature(hub, port->PortNum, PORT_RESET);
+                       Time_Delay(10); // May take up to 2ms for reset to clear
+                       // Enable port
+                       LOG("Port enabling");
+                       USB_PortCtl_SetPortFeature(hub, port->PortNum, PORT_ENABLE);
+                       // Begin connect processing
+                       port->Status = 2;
+                       USB_DeviceConnected(hub, port->PortNum);
+                       break;
+               }
+       }
+}
+
+void USB_PortCtl_BeginReset(tUSBHub *Hub, int Port)
+{
+       LOG("Starting %p %i", Hub, Port);
+       // Set status field in hub structure
+       Hub->Ports[Port].Status = 1;
+       Hub->Ports[Port].PortNum = Port;
+       // Add to the work queue
+       Workqueue_AddWork(&gUSB_PortCtl_WorkQueue, &Hub->Ports[Port]);
+}
+
+void USB_PortCtl_SetPortFeature(tUSBHub *Hub, int Port, int Feat)
+{
+       if( Hub->Interface->Driver == NULL ) {
+               // - Host Port
+               tUSBHost        *host = Hub->Interface->Dev->Host;
+               ASSERT(host->HostDef->SetPortFeature);
+               host->HostDef->SetPortFeature(host->Ptr, Port, Feat);
+       }
+       else {
+               // - Hub Port
+               Hub_SetPortFeature(Hub->Interface, Port, Feat);
+       }
+}
+
+void USB_PortCtl_ClearPortFeature(tUSBHub *Hub, int Port, int Feat)
+{
+       if( Hub->Interface->Driver == NULL ) {
+               // - Host Port
+               tUSBHost        *host = Hub->Interface->Dev->Host;
+               ASSERT(host->HostDef->ClearPortFeature);
+               host->HostDef->ClearPortFeature(host->Ptr, Port, Feat);
+       }
+       else {
+               // - Hub Port
+               Hub_ClearPortFeature(Hub->Interface, Port, Feat);
+       }
+}
+
+int USB_PortCtl_GetPortStatus(tUSBHub *Hub, int Port, int Flag)
+{
+       if( Hub->Interface->Driver == NULL ) {
+               // - Host Port
+               tUSBHost        *host = Hub->Interface->Dev->Host;
+               ASSERT(host->HostDef->GetPortStatus);
+               return host->HostDef->GetPortStatus(host->Ptr, Port, Flag);
+       }
+       else {
+               // - Hub Port
+               return Hub_GetPortStatus(Hub->Interface, Port, Flag);
+       }
+       return 0;
+}
+
index 9a0e2bc..c4e1680 100644 (file)
@@ -31,7 +31,7 @@ tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts)
 {
        tUSBHost        *host;
        
-       host = malloc(sizeof(tUSBHost) + nPorts*sizeof(void*));
+       host = malloc(sizeof(tUSBHost) + nPorts*sizeof(tUSBHubPort) + sizeof(tUSBDevice) + sizeof(tUSBInterface));
        if(!host) {
                // Oh, bugger.
                return NULL;
@@ -40,20 +40,23 @@ tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts)
        host->Ptr = ControllerPtr;
        memset(host->AddressBitmap, 0, sizeof(host->AddressBitmap));
 
-       host->RootHubDev.ParentHub = NULL;
-       host->RootHubDev.Host = host;
-       host->RootHubDev.Address = 0;
-       host->RootHubDev.EndpointHandles[0] = HostDef->InitControl(ControllerPtr, 0, 64);
+       host->RootHubDev = (void*)(host->RootHub.Ports + nPorts);
+       host->RootHubDev->ParentHub = NULL;
+       host->RootHubDev->Host = host;
+       host->RootHubDev->Address = 0;
+       ASSERT(HostDef->InitControl);
+       host->RootHubDev->EndpointHandles[0] = HostDef->InitControl(ControllerPtr, 0, 64);
+       host->RootHubDev->nInterfaces = 0;
 
-//     host->RootHubIf.Next = NULL;
-       host->RootHubIf.Dev = &host->RootHubDev;
-       host->RootHubIf.Driver = NULL;
-       host->RootHubIf.Data = NULL;
-       host->RootHubIf.nEndpoints = 0;
+       host->RootHubIf = (void*)(host->RootHubDev + 1);
+       host->RootHubIf->Dev = host->RootHubDev;
+       host->RootHubIf->Driver = NULL;
+       host->RootHubIf->Data = NULL;
+       host->RootHubIf->nEndpoints = 0;
 
-       host->RootHub.Interface = &host->RootHubIf;
+       host->RootHub.Interface = host->RootHubIf;
        host->RootHub.nPorts = nPorts;
-       memset(host->RootHub.Devices, 0, sizeof(void*)*nPorts);
+       memset(host->RootHub.Ports, 0, sizeof(tUSBHubPort)*nPorts);
 
        // Append to list
        Mutex_Acquire( &glUSB_Hosts );
@@ -98,10 +101,10 @@ tUSBHub *USB_RegisterHub(tUSBInterface *Device, int PortCount)
 {
        tUSBHub *ret;
        
-       ret = malloc(sizeof(tUSBHub) + sizeof(ret->Devices[0])*PortCount);
+       ret = malloc(sizeof(tUSBHub) + sizeof(ret->Ports[0])*PortCount);
        ret->Interface = Device;
        ret->nPorts = PortCount;
-       memset(ret->Devices, 0, sizeof(ret->Devices[0])*PortCount);
+       memset(ret->Ports, 0, sizeof(ret->Ports[0])*PortCount);
        return ret;
 }
 
@@ -109,7 +112,7 @@ void USB_RemoveHub(tUSBHub *Hub)
 {
        for( int i = 0; i < Hub->nPorts; i ++ )
        {
-               if( Hub->Devices[i] )
+               if( Hub->Ports[i].Dev )
                {
                        USB_DeviceDisconnected( Hub, i );
                }
index 24cd80a..2de6985 100644 (file)
 #include <usb_host.h>
 #include "usb_proto.h"
 
+typedef struct sUSBHubPort     tUSBHubPort;
 typedef struct sUSBHost        tUSBHost;
 typedef struct sUSBDevice      tUSBDevice;
 typedef struct sUSBEndpoint    tUSBEndpoint;
 
 // === STRUCTURES ===
+struct sUSBHubPort
+{
+       void    *ListNext;
+       char    Status;
+       char    PortNum;
+       tUSBDevice      *Dev;
+};
+
 /**
  * \brief USB Hub data
  */
@@ -26,7 +35,7 @@ struct sUSBHub
        tUSBInterface   *Interface;
        
         int    nPorts;
-       tUSBDevice      *Devices[];
+       struct sUSBHubPort      Ports[];
 };
 
 struct sUSBEndpoint
@@ -92,8 +101,8 @@ struct sUSBHost
        
        Uint8   AddressBitmap[128/8];
        
-       tUSBDevice      RootHubDev;
-       tUSBInterface   RootHubIf;
+       tUSBDevice      *RootHubDev;
+       tUSBInterface   *RootHubIf;
        tUSBHub RootHub;
 };
 
index 6143bdb..c9655cb 100644 (file)
@@ -29,7 +29,7 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
        tUSBDevice      tmpdev;
        tUSBDevice      *dev = &tmpdev;
        if( Port >= Hub->nPorts )       return ;
-       if( Hub->Devices[Port] )        return ;
+       if( Hub->Ports[Port].Dev )      return ;
 
        ENTER("pHub iPort", Hub, Port);
 
@@ -325,7 +325,7 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                free(full_buf);
        }
        
-       Hub->Devices[Port] = dev;
+       Hub->Ports[Port].Dev = dev;
        
        // Done.
        LEAVE('-');
@@ -334,11 +334,11 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
 void USB_DeviceDisconnected(tUSBHub *Hub, int Port)
 {
        tUSBDevice      *dev;
-       if( !Hub->Devices[Port] ) {
+       if( !Hub->Ports[Port].Dev ) {
                Log_Error("USB", "Non-registered device disconnected");
                return;
        }
-       dev = Hub->Devices[Port];
+       dev = Hub->Ports[Port].Dev;
 
        // TODO: Free related resources
        // - Endpoint registrations
@@ -351,8 +351,9 @@ void USB_DeviceDisconnected(tUSBHub *Hub, int Port)
        // - Bus Address
        USB_int_DeallocateAddress(dev->Host, dev->Address);
        // - Inform handler
-       // - Allocate memory
+       // - Release memory
        free(dev);
+       Hub->Ports[Port].Dev = NULL;
 }
 
 void *USB_GetDeviceDataPtr(tUSBInterface *Dev) { return Dev->Data; }
@@ -361,6 +362,7 @@ void USB_SetDeviceDataPtr(tUSBInterface *Dev, void *Ptr) { Dev->Data = Ptr; }
 int USB_int_AllocateAddress(tUSBHost *Host)
 {
         int    i;
+       ASSERT(Host);
        for( i = 1; i < 128; i ++ )
        {
                if(Host->AddressBitmap[i/8] & (1 << (i%8)))
index 57948ce..27bad3e 100644 (file)
@@ -84,7 +84,7 @@ void USB_int_WakeThread(void *Thread, void *Data, size_t Length)
 
 int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address)
 {
-       USB_int_Request(&Host->RootHubDev, 0, 0x00, 5, Address & 0x7F, 0, 0, NULL);
+       USB_int_Request(Host->RootHubDev, 0, 0x00, 5, Address & 0x7F, 0, 0, NULL);
        return 0;
 }
 
index a32e08e..5a93269 100644 (file)
@@ -81,7 +81,8 @@ int USB_PollThread(void *unused)
                // Check hosts
                for( tUSBHost *host = gUSB_Hosts; host; host = host->Next )
                {
-                       host->HostDef->CheckPorts(host->Ptr);
+                       if( host->HostDef->CheckPorts )
+                               host->HostDef->CheckPorts(host->Ptr);
                }
 
                Time_Delay(100);
index 8a316e3..50004c7 100644 (file)
 #include "ehci.h"
 #include <drv_pci.h>
 #include <limits.h>
+#include <events.h>
+#include <timers.h>
 
 // === CONSTANTS ===
 #define EHCI_MAX_CONTROLLERS   4
+#define EHCI_THREADEVENT_IOC   THREAD_EVENT_USER1
+#define EHCI_THREADEVENT_PORTSC        THREAD_EVENT_USER2
 
 // === PROTOTYPES ===
  int   EHCI_Initialise(char **Arguments);
@@ -36,12 +40,17 @@ void        *EHCI_SendControl(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData,
        );
 void   *EHCI_SendBulk(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData, int Dir, void *Data, size_t Length);
 void   EHCI_FreeOp(void *Ptr, void *Handle);
+Uint32 EHCI_int_RootHub_FeatToMask(int Feat);
+void   EHCI_RootHub_SetPortFeature(void *Ptr, int Port, int Feat);
+void   EHCI_RootHub_ClearPortFeature(void *Ptr, int Port, int Feat);
+ int   EHCI_RootHub_GetPortStatus(void *Ptr, int Port, int Flag);
 // --- Internals ---
 tEHCI_qTD      *EHCI_int_AllocateTD(tEHCI_Controller *Cont, int PID, void *Data, size_t Length, tUSBHostCb Cb, void *CbData);
 void   EHCI_int_DeallocateTD(tEHCI_Controller *Cont, tEHCI_qTD *TD);
-void   EHCI_int_AppendTD(tEHCI_QH *QH, tEHCI_qTD *TD);
+void   EHCI_int_AppendTD(tEHCI_Controller *Cont, tEHCI_QH *QH, tEHCI_qTD *TD);
 tEHCI_QH       *EHCI_int_AllocateQH(tEHCI_Controller *Cont, int Endpoint, size_t MaxPacketSize);
 void   EHCI_int_DeallocateQH(tEHCI_Controller *Cont, tEHCI_QH *QH);
+void   EHCI_int_InterruptThread(void *ControllerPtr);
 
 // === GLOBALS ===
 MODULE_DEFINE(0, VERSION, USB_EHCI, EHCI_Initialise, NULL, "USB_Core", NULL);
@@ -49,12 +58,18 @@ tEHCI_Controller    gaEHCI_Controllers[EHCI_MAX_CONTROLLERS];
 tUSBHostDef    gEHCI_HostDef = {
        .InitInterrupt = EHCI_InitInterrupt,
        .InitIsoch     = EHCI_InitIsoch,
+       .InitControl   = EHCI_InitControl,
        .InitBulk      = EHCI_InitBulk,
        .RemEndpoint   = EHCI_RemEndpoint,
        .SendIsoch   = NULL,
        .SendControl = EHCI_SendControl,
        .SendBulk    = EHCI_SendBulk,
-       .FreeOp      = EHCI_FreeOp
+       .FreeOp      = EHCI_FreeOp,
+       
+       .CheckPorts = NULL,     // No need
+       .SetPortFeature   = EHCI_RootHub_SetPortFeature,
+       .ClearPortFeature = EHCI_RootHub_ClearPortFeature,
+       .GetPortStatus    = EHCI_RootHub_GetPortStatus,
        };
 
 // === CODE ===
@@ -71,10 +86,16 @@ int EHCI_Initialise(char **Arguments)
                        // TODO: The same
                }
 
-               if( EHCI_InitController(addr, irq) ) {
+               Log_Log("ECHI", "Controller at PCI %i 0x%x IRQ 0x%x",
+                       id, addr, irq);
+
+               if( EHCI_InitController(addr, irq) )
+               {
                        // TODO: Detect other forms of failure than "out of slots"
                        break ;
                }
+
+               // TODO: Register with the USB stack
        }
        return 0;
 }
@@ -97,22 +118,62 @@ int EHCI_InitController(tPAddr BaseAddress, Uint8 InterruptNum)
                        break;
                }
        }
-
        if(!cont) {
+               Log_Notice("EHCI", "Too many controllers (EHCI_MAX_CONTROLLERS=%i)",
+                       EHCI_MAX_CONTROLLERS);
                return 1;
        }
 
+       // - Nuke a couple of fields so error handling code doesn't derp
+       cont->CapRegs = NULL;
+       cont->PeriodicQueue = NULL;
+       cont->TDPool = NULL;
+
        // -- Build up structure --
        cont->CapRegs = (void*)MM_MapHWPages(BaseAddress, 1);
+       if( !cont->CapRegs ) {
+               Log_Warning("EHCI", "Can't map 1 page at %P into kernel space", BaseAddress);
+               goto _error;
+       }
        // TODO: Error check
+       if( (cont->CapRegs->CapLength & 3) ) {
+               Log_Warning("EHCI", "Controller at %P non-aligned op regs", BaseAddress);
+               goto _error;
+       }
        cont->OpRegs = (void*)( (Uint32*)cont->CapRegs + cont->CapRegs->CapLength / 4 );
        // - Allocate periodic queue
-       cont->PeriodicQueue = (void*)MM_AllocDMA(1, 32, NULL);
+       tPAddr  unused;
+       cont->PeriodicQueue = (void*)MM_AllocDMA(1, 32, &unused);
+       if( !cont->PeriodicQueue ) {
+               Log_Warning("ECHI", "Can't allocate 1 32-bit page for periodic queue");
+               goto _error;
+       }
+       for( int i = 0; i < 1024; i ++ )
+               cont->PeriodicQueue[i] = 1;
        // TODO: Error check
        //  > Populate queue
 
+       // - Allocate TD pool
+       cont->TDPool = (void*)MM_AllocDMA(1, 32, &unused);
+       if( !cont->TDPool ) {
+               Log_Warning("ECHI", "Can't allocate 1 32-bit page for qTD pool");
+               goto _error;
+       }
+       for( int i = 0; i < TD_POOL_SIZE; i ++ ) {
+               cont->TDPool[i].Token = 3 << 8;
+       }
+
+       // Get port count
+       cont->nPorts = cont->CapRegs->HCSParams & 0xF;
+
        // -- Bind IRQ --
        IRQ_AddHandler(InterruptNum, EHCI_InterruptHandler, cont);
+       cont->InterruptThread = Proc_SpawnWorker(EHCI_int_InterruptThread, cont);
+       if( !cont->InterruptThread ) {
+               Log_Warning("EHCI", "Can't spawn interrupt worker thread");
+               goto _error;
+       }
+       LOG("cont->InterruptThread = %p", cont->InterruptThread);
 
        // -- Initialisation procedure (from ehci-r10) --
        // - Reset controller
@@ -126,37 +187,69 @@ int EHCI_InitController(tPAddr BaseAddress, Uint8 InterruptNum)
        cont->OpRegs->USBCmd = (0x40 << 16) | USBCMD_PeriodicEnable | USBCMD_Run;
        // - Route all ports
        cont->OpRegs->ConfigFlag = 1;
-       
+
+       cont->DeadTD = EHCI_int_AllocateTD(cont, 0, NULL, 0, NULL, NULL);
+       cont->DeadTD->Link = 1;
+       cont->DeadTD->Link2 = 1;
+       cont->DeadTD->Token = 0;
+
+       // -- Register with USB Core --
+       cont->RootHub = USB_RegisterHost(&gEHCI_HostDef, cont, cont->nPorts);
+
        return 0;
+_error:
+       cont->PhysBase = 0;
+       if( cont->CapRegs )
+               MM_Deallocate( (tVAddr)cont->CapRegs );
+       if( cont->PeriodicQueue )
+               MM_Deallocate( (tVAddr)cont->PeriodicQueue );
+       if( cont->TDPool )
+               MM_Deallocate( (tVAddr)cont->TDPool );
+       return 2;
 }
 
 void EHCI_InterruptHandler(int IRQ, void *Ptr)
 {
-       tEHCI_Controller *cont = Ptr;
-       Uint32  sts = cont->OpRegs->USBSts;
+       tEHCI_Controller *Cont = Ptr;
+       Uint32  sts = Cont->OpRegs->USBSts;
        
        // Clear interrupts
-       cont->OpRegs->USBSts = sts;     
+       Cont->OpRegs->USBSts = sts;     
+
+       if( sts & 0xFFFF0FC0 ) {
+               LOG("Oops, reserved bits set (%08x), funny hardware?", sts);
+               sts &= ~0xFFFF0FFC0;
+       }
+
+       // Unmask read-only bits
+       sts &= ~(0xF000);
 
        if( sts & USBINTR_IOC ) {
                // IOC
+               Threads_PostEvent(Cont->InterruptThread, EHCI_THREADEVENT_IOC);
                sts &= ~USBINTR_IOC;
        }
 
        if( sts & USBINTR_PortChange ) {
                // Port change, determine what port and poke helper thread
+               LOG("Port status change");
+               Threads_PostEvent(Cont->InterruptThread, EHCI_THREADEVENT_PORTSC);
                sts &= ~USBINTR_PortChange;
        }
        
        if( sts & USBINTR_FrameRollover ) {
                // Frame rollover, used to aid timing (trigger per-second operations)
+               LOG("Frame rollover");
                sts &= ~USBINTR_FrameRollover;
        }
 
        if( sts ) {
                // Unhandled interupt bits
                // TODO: Warn
+               LOG("WARN - Bitmask %x unhandled", sts);
        }
+
+
 }
 
 // --------------------------------------------------------------------
@@ -196,6 +289,8 @@ void *EHCI_InitInterrupt(void *Ptr, int Endpoint, int bOutbound, int Period,
        tEHCI_QH *qh = EHCI_int_AllocateQH(Cont, Endpoint, Length);
        qh->Impl.IntPeriodPow = period_pow;
 
+       Mutex_Acquire(&Cont->PeriodicListLock);
+
        // Choose an interrupt slot to use      
        int minslot = 0, minslot_load = INT_MAX;
        for( int slot = 0; slot < Period; slot ++ )
@@ -210,15 +305,60 @@ void *EHCI_InitInterrupt(void *Ptr, int Endpoint, int bOutbound, int Period,
                }
        }
        // Increase loading on the selected slot
-       for( int i = 0; i < PERIODIC_SIZE; i += Period )
-               Cont->InterruptLoad[i+minslot] += Length;
+       for( int i = minslot; i < PERIODIC_SIZE; i += Period )
+               Cont->InterruptLoad[i] += Length;
        qh->Impl.IntOfs = minslot;
 
        // Allocate TD for the data
        tEHCI_qTD *td = EHCI_int_AllocateTD(Cont, (bOutbound ? PID_OUT : PID_IN), Buf, Length, Cb, CbData);
-       EHCI_int_AppendTD(qh, td);
+       EHCI_int_AppendTD(Cont, qh, td);
 
        // Insert into the periodic list
+       for( int i = 0; i < PERIODIC_SIZE; i += Period )
+       {
+               // Walk list until
+               // - the end is reached
+               // - this QH is found
+               // - A QH with a lower period is encountered
+               tEHCI_QH        *pqh = NULL;
+               tEHCI_QH        *nqh;
+               for( nqh = Cont->PeriodicQueueV[i]; nqh; pqh = nqh, nqh = nqh->Impl.Next )
+               {
+                       if( nqh == qh )
+                               break;
+                       if( nqh->Impl.IntPeriodPow < period_pow )
+                               break;
+               }
+
+               // Somehow, we've already been added to this queue.
+               if( nqh && nqh == qh )
+                       continue ;
+
+               if( qh->Impl.Next && qh->Impl.Next != nqh ) {
+                       Log_Warning("EHCI", "Suspected bookkeeping error on %p - int list %i+%i overlap",
+                               Cont, period_pow, minslot);
+                       break;
+               }
+
+               if( nqh ) {
+                       qh->Impl.Next = nqh;
+                       qh->HLink = MM_GetPhysAddr(nqh) | 2;
+               }
+               else {
+                       qh->Impl.Next = NULL;
+                       qh->HLink = 2|1;        // QH, Terminate
+               }
+
+               if( pqh ) {
+                       pqh->Impl.Next = qh;
+                       pqh->HLink = MM_GetPhysAddr(qh) | 2;
+               }
+               else {
+                       Cont->PeriodicQueueV[i] = qh;
+                       Cont->PeriodicQueue[i] = MM_GetPhysAddr(qh) | 2;
+               }
+       }
+       Mutex_Release(&Cont->PeriodicListLock);
 
        return qh;
 }
@@ -233,16 +373,23 @@ void *EHCI_InitControl(void *Ptr, int Endpoint, size_t MaxPacketSize)
        
        // Allocate a QH
        tEHCI_QH *qh = EHCI_int_AllocateQH(Cont, Endpoint, MaxPacketSize);
+       qh->CurrentTD = MM_GetPhysAddr(Cont->DeadTD);
 
        // Append to async list 
        if( Cont->LastAsyncHead ) {
                Cont->LastAsyncHead->HLink = MM_GetPhysAddr(qh)|2;
                Cont->LastAsyncHead->Impl.Next = qh;
+               LOG("- Placed after %p", Cont->LastAsyncHead);
        }
-       else
+       else {
                Cont->OpRegs->AsyncListAddr = MM_GetPhysAddr(qh)|2;
+       }
+       qh->HLink = Cont->OpRegs->AsyncListAddr;
+       Cont->OpRegs->USBCmd |= USBCMD_AsyncEnable;
        Cont->LastAsyncHead = qh;
 
+       LOG("Created %p for %p Ep 0x%x - %i bytes MPS", qh, Ptr, Endpoint, MaxPacketSize);
+
        return qh;
 }
 void *EHCI_InitBulk(void *Ptr, int Endpoint, size_t MaxPacketSize)
@@ -256,8 +403,16 @@ void EHCI_RemEndpoint(void *Ptr, void *Handle)
        else if( (tVAddr)Handle <= 256*16 )
                return ;        // Isoch
        else {
+               tEHCI_QH        *qh = Ptr;
+
                // Remove QH from list
                // - If it's a polling endpoint, need to remove from all periodic lists
+               if( qh->Impl.IntPeriodPow != 0xFF) {
+                       // Poll
+               }
+               else {
+                       // GP
+               }
                
                // Deallocate QH
                EHCI_int_DeallocateQH(Ptr, Handle);
@@ -284,19 +439,28 @@ void *EHCI_SendControl(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData,
        td_setup = EHCI_int_AllocateTD(Cont, PID_SETUP, (void*)SetupData, SetupLength, NULL, NULL);
        if( isOutbound )
        {
-               td_data = EHCI_int_AllocateTD(Cont, PID_OUT, (void*)OutData, OutLength, NULL, NULL);
+               td_data = OutData ? EHCI_int_AllocateTD(Cont, PID_OUT, (void*)OutData, OutLength, NULL, NULL) : NULL;
                td_status = EHCI_int_AllocateTD(Cont, PID_IN, InData, InLength, Cb, CbData);
        }
        else
        {
-               td_data = EHCI_int_AllocateTD(Cont, PID_IN, InData, InLength, NULL, NULL);
+               td_data = InData ? EHCI_int_AllocateTD(Cont, PID_IN, InData, InLength, NULL, NULL) : NULL;
                td_status = EHCI_int_AllocateTD(Cont, PID_OUT, (void*)OutData, OutLength, Cb, CbData);
+               td_status->Token |= (1 << 15);  // IOC
        }
 
        // Append TDs
-       EHCI_int_AppendTD(Dest, td_setup);
-       EHCI_int_AppendTD(Dest, td_data);
-       EHCI_int_AppendTD(Dest, td_status);
+       if( td_data ) {
+               td_setup->Link = MM_GetPhysAddr(td_data);
+               td_data->Link = MM_GetPhysAddr(td_status) | 1;
+               td_data->Token |= (1 << 8);     // Active
+       }
+       else {
+               td_setup->Link = MM_GetPhysAddr(td_status) | 1;
+       }
+       td_setup->Token |= (1 << 8);    // Active
+       td_status->Token |= (1 << 8);
+       EHCI_int_AppendTD(Cont, Dest, td_setup);
 
        return td_status;
 }
@@ -312,7 +476,7 @@ void *EHCI_SendBulk(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData, int Dir,
        
        // Allocate single TD
        tEHCI_qTD       *td = EHCI_int_AllocateTD(Cont, (Dir ? PID_OUT : PID_IN), Data, Length, Cb, CbData);
-       EHCI_int_AppendTD(Dest, td);    
+       EHCI_int_AppendTD(Cont, Dest, td);      
 
        return td;
 }
@@ -324,28 +488,211 @@ void EHCI_FreeOp(void *Ptr, void *Handle)
        EHCI_int_DeallocateTD(Cont, Handle);
 }
 
+Uint32 EHCI_int_RootHub_FeatToMask(int Feat)
+{
+       switch(Feat)
+       {
+       case PORT_RESET:        return PORTSC_PortReset;
+       case PORT_ENABLE:       return PORTSC_PortEnabled;
+       default:
+               Log_Warning("EHCI", "Unknown root hub port feature %i", Feat);
+               return 0;
+       }
+}
+
+void EHCI_RootHub_SetPortFeature(void *Ptr, int Port, int Feat)
+{
+       tEHCI_Controller        *Cont = Ptr;
+       if(Port >= Cont->nPorts)        return;
+
+       Cont->OpRegs->PortSC[Port] |= EHCI_int_RootHub_FeatToMask(Feat);
+}
+
+void EHCI_RootHub_ClearPortFeature(void *Ptr, int Port, int Feat)
+{
+       tEHCI_Controller        *Cont = Ptr;
+       if(Port >= Cont->nPorts)        return;
+
+       Cont->OpRegs->PortSC[Port] &= ~EHCI_int_RootHub_FeatToMask(Feat);
+}
+
+int EHCI_RootHub_GetPortStatus(void *Ptr, int Port, int Flag)
+{
+       tEHCI_Controller        *Cont = Ptr;
+       if(Port >= Cont->nPorts)        return 0;
+
+       return !!(Cont->OpRegs->PortSC[Port] & EHCI_int_RootHub_FeatToMask(Flag));
+}
+
 // --------------------------------------------------------------------
 // Internals
 // --------------------------------------------------------------------
+tEHCI_qTD *EHCI_int_GetTDFromPhys(tEHCI_Controller *Cont, Uint32 Addr)
+{
+       if( Addr == 0 ) return NULL;
+       LOG("%p + (%x - %x)", Cont->TDPool, Addr, MM_GetPhysAddr(Cont->TDPool));
+       return Cont->TDPool + (Addr - MM_GetPhysAddr(Cont->TDPool))/sizeof(tEHCI_qTD);
+}
+
 tEHCI_qTD *EHCI_int_AllocateTD(tEHCI_Controller *Cont, int PID, void *Data, size_t Length, tUSBHostCb Cb, void *CbData)
 {
+//     Semaphore_Wait(&Cont->TDSemaphore, 1);
+       Mutex_Acquire(&Cont->TDPoolMutex);
+       for( int i = 0; i < TD_POOL_SIZE; i ++ )
+       {
+               if( ((Cont->TDPool[i].Token >> 8) & 3) != 3 )
+                       continue ;
+               Cont->TDPool[i].Token = (PID << 8) | (Length << 16);
+               // NOTE: Assumes that `Length` is <= PAGE_SIZE
+               Cont->TDPool[i].Pages[0] = MM_GetPhysAddr(Data);
+               if( (Cont->TDPool[i].Pages[0] & (PAGE_SIZE-1)) + Length - 1 > PAGE_SIZE )
+                       Cont->TDPool[i].Pages[1] = MM_GetPhysAddr((char*)Data + Length - 1) & ~(PAGE_SIZE-1);
+               Mutex_Release(&Cont->TDPoolMutex);
+               LOG("Allocated %p for PID %i on %p", &Cont->TDPool[i], PID, Cont);
+               return &Cont->TDPool[i];
+       }
+
+       Mutex_Release(&Cont->TDPoolMutex);
        return NULL;
 }
 
 void EHCI_int_DeallocateTD(tEHCI_Controller *Cont, tEHCI_qTD *TD)
 {
+       UNIMPLEMENTED();
 }
 
-void EHCI_int_AppendTD(tEHCI_QH *QH, tEHCI_qTD *TD)
+void EHCI_int_AppendTD(tEHCI_Controller *Cont, tEHCI_QH *QH, tEHCI_qTD *TD)
 {
+       tEHCI_qTD       *ptd = NULL;
+       Uint32  link = QH->CurrentTD;
+
+       // TODO: Need locking and validation here
+       while( link && !(link & 1) )
+       {
+               ptd = EHCI_int_GetTDFromPhys(Cont, link);
+               link = ptd->Link;
+       }
+       // TODO: Figure out how to follow this properly
+       if( !ptd ) {
+               QH->CurrentTD = MM_GetPhysAddr(TD);
+               LOG("Appended %p to beginning of %p", TD, QH);
+       }
+       else {
+               ptd->Link = MM_GetPhysAddr(TD);
+               LOG("Appended %p to end of %p", TD, QH);
+       }
 }
 
 tEHCI_QH *EHCI_int_AllocateQH(tEHCI_Controller *Cont, int Endpoint, size_t MaxPacketSize)
 {
+       tEHCI_QH        *ret;
+       Mutex_Acquire(&Cont->QHPoolMutex);
+       for( int i = 0; i < QH_POOL_SIZE; i ++ )
+       {
+               if( !MM_GetPhysAddr( Cont->QHPools[i/QH_POOL_NPERPAGE] ) ) {
+                       tPAddr  tmp;
+                       Cont->QHPools[i/QH_POOL_NPERPAGE] = (void*)MM_AllocDMA(1, 32, &tmp);
+                       memset(Cont->QHPools[i/QH_POOL_NPERPAGE], 0, PAGE_SIZE);
+               }
+
+               ret = &Cont->QHPools[i/QH_POOL_NPERPAGE][i%QH_POOL_NPERPAGE];
+               if( ret->HLink == 0 ) {
+                       ret->HLink = 1;
+                       ret->Overlay.Link = 1;
+                       ret->Endpoint = (Endpoint >> 4) | 0x80 | ((Endpoint & 0xF) << 8)
+                               | (MaxPacketSize << 16);
+                       // TODO: Endpoint speed (13:12) 0:Full, 1:Low, 2:High
+                       // TODO: Control Endpoint Flag (27) 0:*, 1:Full/Low Control
+                       Mutex_Release(&Cont->QHPoolMutex);
+                       return ret;
+               }
+       }
+       Mutex_Release(&Cont->QHPoolMutex);
        return NULL;
 }
 
 void EHCI_int_DeallocateQH(tEHCI_Controller *Cont, tEHCI_QH *QH)
 {
+       // TODO: Ensure it's unused (somehow)
+       QH->HLink = 0;
 }
 
+void EHCI_int_HandlePortConnectChange(tEHCI_Controller *Cont, int Port)
+{
+       // Connect Event
+       if( Cont->OpRegs->PortSC[Port] & PORTSC_CurrentConnectStatus )
+       {
+               // Is the device low-speed?
+               if( (Cont->OpRegs->PortSC[Port] & PORTSC_LineStatus_MASK) == PORTSC_LineStatus_Kstate )
+               {
+                       LOG("Low speed device on %p Port %i, giving to companion", Cont, Port);
+                       Cont->OpRegs->PortSC[Port] |= PORTSC_PortOwner;
+               }
+               // not a low-speed device, EHCI reset
+               else
+               {
+                       LOG("Device connected on %p #%i", Cont, Port);
+                       // Reset procedure.
+                       USB_PortCtl_BeginReset(Cont->RootHub, Port);
+               }
+       }
+       // Disconnect Event
+       else
+       {
+               if( Cont->OpRegs->PortSC[Port] & PORTSC_PortOwner ) {
+                       LOG("Companion port %i disconnected, taking it back", Port);
+                       Cont->OpRegs->PortSC[Port] &= ~PORTSC_PortOwner;
+               }
+               else {
+                       LOG("Port %i disconnected", Port);
+                       USB_DeviceDisconnected(Cont->RootHub, Port);
+               }
+       }
+}
+
+void EHCI_int_InterruptThread(void *ControllerPtr)
+{
+       tEHCI_Controller        *Cont = ControllerPtr;
+       while(Cont->OpRegs)
+       {
+               Uint32  events;
+               
+               LOG("sleeping for events");
+               events = Threads_WaitEvents(EHCI_THREADEVENT_IOC|EHCI_THREADEVENT_PORTSC);
+               if( !events ) {
+                       // TODO: Should this cause a termination?
+               }
+               LOG("events = 0x%x", events);
+
+               if( events & EHCI_THREADEVENT_IOC )
+               {
+                       // IOC, Do whatever it is you do
+               }
+
+               // Port status change interrupt
+               if( events & EHCI_THREADEVENT_PORTSC )
+               {
+                       // Check for port status changes
+                       for(int i = 0; i < Cont->nPorts; i ++ )
+                       {
+                               Uint32  sts = Cont->OpRegs->PortSC[i];
+                               LOG("Port %i: sts = %x", i, sts);
+                               Cont->OpRegs->PortSC[i] = sts;
+                               if( sts & PORTSC_ConnectStatusChange )
+                                       EHCI_int_HandlePortConnectChange(Cont, i);
+
+                               if( sts & PORTSC_PortEnableChange )
+                               {
+                                       // Handle enable/disable
+                               }
+
+                               if( sts & PORTSC_OvercurrentChange )
+                               {
+                                       // Handle over-current change
+                               }
+                       }
+               }
+
+               LOG("Going back to sleep");
+       }
+}
index f76b93b..598c8d4 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef _EHCI_H_
 #define _EHCI_H_
 
+#include <threads.h>
+
 #define PERIODIC_SIZE  1024
 
 typedef struct sEHCI_CapRegs   tEHCI_CapRegs;
@@ -92,7 +94,7 @@ struct sEHCI_OpRegs
         * 15    = Asynchronous Schedule Status
         * 16:31 = Reserved ?(Zero)
         */
-       Uint32  USBSts;
+       volatile Uint32 USBSts;
        /**
         * USB Interrupt Enable Register
         *
@@ -110,7 +112,7 @@ struct sEHCI_OpRegs
         * 
         * Bits 14:3 are used as n index into PeridocListBase
         */
-       Uint32  FrIndex;
+       volatile Uint32 FrIndex;
        /**
         * Control Data Structure Segment Register
         *
@@ -159,7 +161,7 @@ struct sEHCI_OpRegs
         * 22    = Wake on Over-current Enable
         * 23:31 = Reserved (ZERO)
         */
-       Uint32  PortSC[15];
+       volatile Uint32 PortSC[15];
 };
 
 #define USBCMD_Run     0x0001
@@ -174,6 +176,28 @@ struct sEHCI_OpRegs
 #define USBINTR_HostSystemError        0x0010
 #define USBINTR_AsyncAdvance   0x0020
 
+#define PORTSC_CurrentConnectStatus    0x0001
+#define PORTSC_ConnectStatusChange     0x0002
+#define PORTSC_PortEnabled     0x0004
+#define PORTSC_PortEnableChange        0x0008
+#define PORTSC_OvercurrentActive       0x0010
+#define PORTSC_OvercurrentChange       0x0020
+#define PORTSC_ForcePortResume 0x0040
+#define PORTSC_Suspend         0x0080
+#define PORTSC_PortReset       0x0100
+#define PORTSC_Reserved1       0x0200
+#define PORTSC_LineStatus_MASK 0x0C00
+#define PORTSC_LineStatus_SE0          0x0000
+#define PORTSC_LineStatus_Jstate       0x0400
+#define PORTSC_LineStatus_Kstate       0x0800
+#define PORTSC_LineStatus_Undef        0x0C00
+#define PORTSC_PortPower       0x1000
+#define PORTSC_PortOwner       0x2000
+#define PORTSC_PortIndicator_MASK      0xC000
+#define PORTSC_PortIndicator_Off       0x0000
+#define PORTSC_PortIndicator_Amber     0x4000
+#define PORTSC_PortIndicator_Green     0x800
+
 // Isochronous (High-Speed) Transfer Descriptor
 struct sEHCI_iTD
 {
@@ -226,33 +250,53 @@ struct sEHCI_QH
        Uint32  Endpoint;
        Uint32  EndpointExt;
        Uint32  CurrentTD;
-       tEHCI_qTD       Overlay;
+       struct {
+               Uint32  Link;
+               Uint32  Link2;
+               Uint32  Token;
+               Uint32  Pages[5];
+       }       Overlay;
        struct {
                Uint8   IntOfs;
                Uint8   IntPeriodPow;
                tEHCI_QH        *Next;
        } Impl;
 } __attribute__((aligned(32)));
-// sizeof = 48 (64)
+// sizeof = 48 (round up to 64)
 
 #define PID_OUT        0
 #define PID_IN         1
 #define PID_SETUP      2
 
+#define TD_POOL_SIZE   (PAGE_SIZE/sizeof(tEHCI_qTD))
+// - 256 addresses * 16 endpoints
+#define QH_POOL_SIZE   (256*16)
+#define QH_POOL_PAGES  (QH_POOL_SIZE*sizeof(tEHCI_QH)/PAGE_SIZE)
+#define QH_POOL_NPERPAGE       (PAGE_SIZE/sizeof(tEHCI_QH))
+
 struct sEHCI_Controller
 {
+       tUSBHub *RootHub;
+       tThread *InterruptThread;
+        int    nPorts;
+
        tPAddr  PhysBase;
        tEHCI_CapRegs   *CapRegs;
        tEHCI_OpRegs    *OpRegs;
 
+       tEHCI_qTD       *DeadTD;
+
         int    InterruptLoad[PERIODIC_SIZE];
        tEHCI_QH        *LastAsyncHead;
        
-       Uint32  *PeriodicQueue;
-       tEHCI_QH PeriodicQueueV[PERIODIC_SIZE];
+       tMutex          PeriodicListLock;
+       Uint32          *PeriodicQueue;
+       tEHCI_QH        *PeriodicQueueV[PERIODIC_SIZE];
        
-       tEHCI_QH        *QHPools[(256*16)*sizeof(tEHCI_QH)/PAGE_SIZE];  // [PAGE_SIZE/64]
-       tEHCI_qTD       *TDPool[PAGE_SIZE/sizeof(tEHCI_qTD)];
+       tMutex  QHPoolMutex;
+       tEHCI_QH        *QHPools[QH_POOL_PAGES];        // [PAGE_SIZE/64]
+       tMutex  TDPoolMutex;
+       tEHCI_qTD       *TDPool;        // [TD_POOL_SIZE]
 };
 
 #endif
index 0fe80dc..98a4b09 100644 (file)
@@ -93,7 +93,14 @@ int UHCI_Initialise(char **Arguments)
         int    ret;
        
        ENTER("");
-       
+
+       if( Arguments && *Arguments && strcmp(*Arguments, "0") == 0 )
+       {
+               LOG("Disabled by argument");
+               LEAVE('i', MODULE_ERR_NOTNEEDED);
+               return MODULE_ERR_NOTNEEDED;
+       }
+
        // Initialise with no maximum value
        Semaphore_Init( &gUHCI_InterruptSempahore, 0, 0, "UHCI", "Interrupt Queue");
 
@@ -107,14 +114,15 @@ int UHCI_Initialise(char **Arguments)
                tPAddr  tmp;    
                gaUHCI_TDPool = (void *) MM_AllocDMA(1, 32, &tmp);
                memset(gaUHCI_TDPool, 0, PAGE_SIZE);
+               LOG("gaUHCI_TDPool = %p (%P)", gaUHCI_TDPool, tmp);
        }
 
        // Enumerate PCI Bus, getting a maximum of `MAX_CONTROLLERS` devices
+       // Class:SubClass:Protocol = 0xC (Serial) : 0x3 (USB) : 0x00 (UHCI)
        while( (id = PCI_GetDeviceByClass(0x0C0300, 0xFFFFFF, id)) >= 0 && i < MAX_CONTROLLERS )
        {
                tUHCI_Controller        *cinfo = &gUHCI_Controllers[i];
                Uint32  base_addr;
-               // NOTE: Check "protocol" from PCI?
                
                cinfo->PciId = id;
                base_addr = PCI_GetBAR(id, 4);
@@ -184,6 +192,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host)
                LEAVE('i', -1);
                return -1;
        }
+       LOG("->FrameList = %p (%P)", Host->FrameList, Host->PhysFrameList);
 
        Host->TDQHPage = (void *) MM_AllocDMA(1, 32, &Host->PhysTDQHPage);
        if( !Host->TDQHPage ) {
@@ -192,6 +201,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host)
                LEAVE('i', -1);
                return -1;
        }
+       LOG("->TDQHPage = %p (%P)", Host->TDQHPage, Host->PhysTDQHPage);
 
        // Fill frame list
        // - The numbers 0...31, but bit reversed (16 (0b1000) = 1 (0b00001)
@@ -199,6 +209,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host)
                0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30,
                1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31
                };
+       // Fill all slots (but every 4th will be changed below
        for( int i = 0; i < 1024; i ++ ) {
                Uint32  addr = MM_GetPhysAddr( &Host->TDQHPage->ControlQH );
                Host->FrameList[i] = addr | 2;
@@ -214,7 +225,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host)
                Host->FrameList[768 + i*4] = addr | 2;
        }
 
-       // Build up interrupt binary tree       
+       // Build up interrupt binary tree
        {
                tUHCI_QH        *dest = Host->TDQHPage->InterruptQHs;
                Uint32  destphys = Host->PhysTDQHPage;
@@ -222,7 +233,9 @@ int UHCI_int_InitHost(tUHCI_Controller *Host)
                // Set up next pointer to index to i/2 in the next step
                for( int _count = 64; _count > 1; _count /= 2 )
                {
+                       LOG("count=%i, dest=%p, destphys=%P", _count, dest, destphys);
                        for( int i = 0; i < _count; i ++ ) {
+                               LOG(" %i-%i: %P==%P", _count, i, MM_GetPhysAddr(dest+i), destphys+i*sizeof(tUHCI_QH));
                                dest[i].Next = destphys + (_count + i/2) * sizeof(tUHCI_QH) + 2;
                                dest[i].Child = 1;
                        }
@@ -257,6 +270,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host)
        PCI_ConfigWrite( Host->PciId, 0xC0, 2, 0x2000 );
 
        // Enable processing
+       LOG("Processing enabling");
        _OutWord( Host, USBCMD, 0x0001 );
 
        LEAVE('i', 0);
@@ -301,16 +315,18 @@ void UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_QH *QH, tUHCI_TD *TD)
        TD->Control |= (TD->Token >> 21) & 0x7FF;
 
        // Stop controller
+       tPAddr  tdaddr = MM_GetPhysAddr( TD );
+       ASSERT(tdaddr);
        _OutWord( Cont, USBCMD, 0x0000 );
        
        // Add
        TD->Link = 1;
        if( QH->Child & 1 ) {
-               QH->Child = MM_GetPhysAddr( TD );
+               QH->Child = tdaddr;
        }
        else {
                // Depth first
-               QH->_LastItem->Link = MM_GetPhysAddr( TD ) | 4;
+               QH->_LastItem->Link = tdaddr | 4;
        }
        QH->_LastItem = TD;
 
@@ -574,7 +590,7 @@ void *UHCI_SendControl(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData,
        void *InData, size_t InLength
        )
 {
-       ENTER("pPtr pEndpt ibOutbound", Ptr, Endpt, bOutbound);
+       ENTER("pPtr pEndpt bOutbound", Ptr, Endpt, bOutbound);
        
        tUHCI_Controller        *Cont = Ptr;
        tUHCI_QH        *qh = &Cont->TDQHPage->ControlQH;
@@ -644,7 +660,14 @@ void *UHCI_SendControl(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData,
        
        // Update toggle value
        epi->Tgl = tgl;
-       
+
+       // --- HACK!!!
+//     for( int i = 0; i < 1024; i ++ )
+//     {
+//             LOG("- FrameList[%i] = %x", i, Cont->FrameList[i]);
+//     }
+       // --- /HACK    
+
        LEAVE('p', td); 
        return td;
 }
@@ -658,7 +681,7 @@ void *UHCI_SendBulk(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData, int bOu
         int    dest, tgl;
        size_t  mps;
 
-       ENTER("pPtr pEndpt pCb pCbData bOutbound pData iLength", Ptr, Dest, Cb, CbData, bOutbound, Data, Length);
+       ENTER("pPtr pEndpt pCb pCbData bOutbound pData iLength", Ptr, Endpt, Cb, CbData, bOutbound, Data, Length);
 
        if( Endpt == NULL ) {
                Log_Error("UHCI", "_SendBulk passed a NULL endpoint handle");
@@ -800,7 +823,8 @@ void UHCI_int_CleanQH(tUHCI_Controller *Cont, tUHCI_QH *QH)
                        continue ;
                }
 
-               LOG("Removed %p from QH %p", td, QH);           
+               LOG("Removed %p from QH %p", td, QH);
+               ASSERT(td->Link);
 
                if( !prev )
                        QH->Child = td->Link;
@@ -968,26 +992,38 @@ void UHCI_InterruptHandler(int IRQ, void *Ptr)
        // USB Error Interrupt
        if( status & 2 )
        {
-               
+               Log_Notice("UHCI", "USB Error");
        }
 
        // Resume Detect
        // - Fired if in suspend state and a USB device sends the RESUME signal
        if( status & 4 )
        {
-               
+               Log_Notice("UHCI", "Resume Detect");
        }
 
        // Host System Error
        if( status & 8 )
        {
-               
+               Log_Notice("UHCI", "Host System Error");
        }
 
        // Host Controller Process Error
        if( status & 0x10 )
        {
                Log_Error("UHCI", "Host controller process error on controller %p", Ptr);
+               // Spam Tree
+               //for( int i = 0; i < 1024; i += 4 ) {
+               //      LOG("%4i: %x", i, Host->FrameList[i]);
+               //}
+               
+               tPAddr  phys = Host->TDQHPage->ControlQH.Child;
+               while( !(phys & 1) && MM_GetRefCount(phys & ~15))
+               {
+                       tUHCI_TD *td = UHCI_int_GetTDFromPhys(Host, phys);
+                       LOG("%08P: %08x %08x %08x", phys, td->Control, td->Token, td->BufferPointer);
+                       phys = td->Link;
+               }
        }
 
        _OutWord(Host, USBSTS, status);
index e16a7b2..32f1ffb 100644 (file)
--- a/Makefile
+++ b/Makefile
 
 SUBMAKE = $(MAKE) --no-print-directory
 
-USRLIBS := crt0.o acess.ld ld-acess.so libgcc.so libc.so
+USRLIBS := crt0.o acess.ld ld-acess.so libc.so libposix.so
 USRLIBS += libreadline.so libnet.so liburi.so libpsocket.so
 USRLIBS += libimage_sif.so
 
 USRAPPS := init login CLIShell cat ls mount
 USRAPPS += bomb lspci
 USRAPPS += ip dhcpclient ping telnet irc wget telnetd
-USRAPPS += axwin3
+USRAPPS += axwin3 gui_ate
 
 ALL_DYNMODS = $(addprefix all-,$(DYNMODS))
 ALL_MODULES := $(addprefix all-,$(MODULES))
@@ -37,6 +37,8 @@ AI_USRLIBS := $(addprefix allinstall-,$(USRLIBS))
 AI_USRAPPS := $(addprefix allinstall-,$(USRAPPS))
 
 .PHONY: all clean install \
+       kmode all-kmode clean-kmode \
+       all-user clean-user \
        $(ALL_MODULES) all-Kernel $(ALL_USRLIBS) $(ALL_USRAPPS) \
        $(AI_MODULES) allinstall-Kernel $(AI_USRLIBS) $(AI_USRAPPS) \
        $(CLEAN_MODULES) clean-Kernel $(CLEAN_USRLIBS) $(CLEAN_USRAPPS) \
@@ -44,6 +46,7 @@ AI_USRAPPS := $(addprefix allinstall-,$(USRAPPS))
 
 kmode: $(AI_MODULES) $(AI_DYNMODS) allinstall-Kernel
 all-kmode:     $(ALL_MODULES) $(ALL_DYNMODS) all-Kernel
+clean-kmode:   $(CLEAN_MODULES) $(CLEAN_DYNMODS) clean-Kernel
 
 all-user: $(ALL_USRLIBS) $(ALL_USRAPPS)
 clean-user: $(CLEAN_USRLIBS) $(CLEAN_USRAPPS)
index 7b0ad8c..c030d47 100644 (file)
@@ -2,14 +2,14 @@
 # Acess2 Build Configuration
 #
 
+ACESSDIR := $(dir $(lastword $(MAKEFILE_LIST)))
+ACESSDIR := $(shell cd $(ACESSDIR) && pwd)
+
 # Install destination configuration
-DISTROOT := a:/Acess2
+DISTROOT := -i $(ACESSDIR)/Acess2.img ::/Acess2
 xCP := mcopy -D o
 xMKDIR := mmd -D s
 
-ACESSDIR := $(dir $(lastword $(MAKEFILE_LIST)))
-ACESSDIR := $(shell cd $(ACESSDIR) && pwd)
-
 -include $(ACESSDIR)/Makefile.Version.cfg
 
 # Default build programs
diff --git a/Notes/VirtualPCI.txt b/Notes/VirtualPCI.txt
new file mode 100644 (file)
index 0000000..341af06
--- /dev/null
@@ -0,0 +1,5 @@
+Rationale:
+- Provides a method for ARM SoCs to use existing device drivers (e.g. USB ECHI) with minimal modifcation.
+
+Method possibilities
+# Hook in Kernel/drv/pci.c that enumerates the virtual bus using a fixed format.
diff --git a/RunQemu b/RunQemu
index 74316df..87cae41 100755 (executable)
--- a/RunQemu
+++ b/RunQemu
@@ -26,13 +26,20 @@ while [ $# -ne 0 ]; do
                        _kfile="KernelLand/Acess2.$1-$2.bin"
                fi
                BOOTOPT="-kernel $_kfile"
-               BOOTOPT=$BOOTOPT" -initrd KernelLand/Modules/Filesystems/FS_InitRD.kmd.$1 -append $3"
+               BOOTOPT=$BOOTOPT" -initrd KernelLand/Modules/Filesystems/FS_InitRD.kmd.$1 -append \"$3\""
                shift
                shift
                ;;
        -dbgbin)
                QEMU=/home/tpg/apps/bin/qemu-system-x86_64
                ;;
+       -bin)
+               shift
+               QEMU=$1
+               ;;
+       -dbgscript)
+               QEMU="echo $QEMU"
+               ;;
        -extramem)
                QEMU_PARAMS=$QEMU_PARAMS" -m 768"
                ;;
@@ -52,6 +59,9 @@ while [ $# -ne 0 ]; do
        -notee)
                _NOTEE="yes"
                ;;
+       -nographic)
+               _NOGRAPHIC="yes"
+               ;;
        esac
        shift
 done
@@ -59,6 +69,7 @@ QEMU_PARAMS=$QEMU_PARAMS" -net "$_NETTYPE
 
 if [ "x$_NOUSB" != "xyes" ] ; then
        QEMU_PARAMS=$QEMU_PARAMS" -usb"
+#      QEMU_PARAMS=$QEMU_PARAMS" -device usb-ehci"
        QEMU_PARAMS=$QEMU_PARAMS" -drive id=test_usb_image,file=USB_Test_Image.img,if=none"
        QEMU_PARAMS=$QEMU_PARAMS" -device usb-storage,drive=test_usb_image"
        QEMU_PARAMS=$QEMU_PARAMS" -usbdevice mouse"
@@ -68,8 +79,14 @@ fi
 #      /home/tpg/apps/bin/qemu-system-x86_64 $QEMU_PARAMS -serial stdio -serial file:QemuLog.txt
 #      qemu-system-x86_64 $QEMU_PARAMS -serial stdio | tee QemuLog.txt
 #echo $QEMU $BOOTOPT $QEMU_PARAMS
-if [ "x$_NOTEE" != "xyes" ] ; then
-       $QEMU $BOOTOPT $QEMU_PARAMS -serial stdio | tee QemuLog.txt
-else
+if [ "x$_NOGRAPHIC" = "xyes" ] ; then
+       $QEMU $BOOTOPT $QEMU_PARAMS -nographic
+       exit
+fi
+
+if [ "x$_NOTEE" = "xyes" ] ; then
        $QEMU $BOOTOPT $QEMU_PARAMS -serial stdio
+       exit
 fi
+
+eval $QEMU $BOOTOPT $QEMU_PARAMS -serial stdio | tee QemuLog.txt
index 1a54976..f90ee27 100644 (file)
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,4 +1,6 @@
 TODO:
+
+=== Hardware ===
 - E1000 Driver (stubbed)
  > Find specs
    http://download.intel.com/design/network/manuals/8254x_GBe_SDM.pdf
@@ -15,6 +17,8 @@ TODO:
 - Sound Stack
  > Intel 82801AA AC97 Audio (qemu)
 
+
+=== General Features ===
 - Init Scripts
  > With an argument to init passed from the kernel?
 
@@ -30,6 +34,8 @@ TODO:
 - Signals
  > Add return value to mutexs and semaphores, and add warn_unused_ret
 
+
+=== Kernel Core ===
 - Virtual PCI bus for system configuration
  > Hook in drv_pci.c, with an arch-defined array of devices
  > Allow hooks on PCI config accesses (to emulate power management etc)
@@ -50,6 +56,7 @@ TODO:
 - LVM Usablity
  > /Devices/LVM/by-id/ and /Devices/LVM/by-label
 
+=== Userland ===
 - AxWin3
  > Text editor (with a GP formatted text field?)
  > Maybe a basic web browser using the surface support?
index 074aab9..5cda588 100644 (file)
@@ -141,7 +141,14 @@ int DiskTool_ListDirectory(const char *Directory)
        char    name[256];
        while( VFS_ReadDir(fd, name) )
        {
-               Log("- %s", name);
+               tFInfo  fi;
+               int child = VFS_OpenChild(fd, name, 0);
+               if( child != -1 )
+               {
+                       VFS_FInfo(child, &fi, 0);
+                       VFS_Close(child);
+               }
+               Log("- %02x %6lli %s", fi.flags, fi.size, name);
        }
        
        VFS_Close(fd);
index 07d7a52..0cb3ed3 100644 (file)
@@ -67,7 +67,7 @@ void Debug_HexDump(const char *Prefix, const void *Data, size_t Length)
        fprintf(stderr, "[HexDump ]d %s:", Prefix);
        for( ; ofs < Length; ofs ++ )
        {
-               if( ofs % 16 == 8 )     fprintf(stderr, " ");
+               if( ofs % 8 == 0 )      fprintf(stderr, " ");
                fprintf(stderr, " %02x", data[ofs%16]);
        }
        fprintf(stderr, "\n");
diff --git a/Tools/GCCProxy/gccproxy.sh b/Tools/GCCProxy/gccproxy.sh
new file mode 100755 (executable)
index 0000000..8fb035b
--- /dev/null
@@ -0,0 +1,86 @@
+#!/bin/bash
+
+# Get invocation path (which could be a symlink in $PATH)
+fullpath=`which "$0"`
+if [[ !$? ]]; then
+       fullpath="$0"
+fi
+
+# Resolve symlink
+fullpath=`readlink -f "$fullpath"`
+
+# Get base directory
+BASEDIR=`dirname "$fullpath"`
+
+cfgfile=`mktemp`
+make --no-print-directory -f $BASEDIR/getconfig.mk ARCH=x86 > $cfgfile
+#echo $cfgfile
+#cat $cfgfile
+. $cfgfile
+rm $cfgfile
+
+_miscargs=""
+_compile=0
+
+while [[ $# -gt 0 ]]; do
+       case "$1" in
+       -E)
+               _preproc=1
+               ;;
+       -c)
+               _compile=1
+               ;;
+       -o)
+               shift
+               _outfile="-o $1"
+               ;;
+       -I)
+               shift
+               _cflags=$_cflags" -I$1"
+               ;;
+       -I*|-D*|-O*)
+               _cflags=$_cflags" $1"
+               ;;
+       -Wl,*)
+               arg=$1
+               arg=${arg#-Wl}
+               arg=${arg/,/ }
+               _ldflags=$_ldflags" ${arg}"
+               ;;
+       -l)
+               shift
+               _libs=$_libs" -l$1"
+               ;;
+       -l*|-L*)
+               _libs=$_libs" $1"
+               ;;
+       *)
+               _miscargs=$_miscargs" $1"
+               ;;
+       esac
+       shift
+done
+
+run() {
+#      echo $*
+       $*
+}
+
+if [[ $_preproc -eq 1 ]]; then
+       run $_CC -E $CFLAGS $_cflags $_miscargs $_outfile
+       exit $?
+fi
+if [[ $_compile -eq 1 ]]; then
+       run $_CC $CFLAGS $_cflags $_miscargs -c $_outfile
+       exit $?
+fi
+
+if echo " $_miscargs" | grep '\.c' >/dev/null; then
+       tmpout=`mktemp acess_gccproxy.XXXXXXXXXX.o --tmpdir`
+       run $_CC $CFLAGS $_miscargs -c -o $tmpout
+       run $_LD $LDFLAGS $_ldflags $_libs $tmpout $_outfile
+       rm $tmpout
+else
+       run $_LD $LDFLAGS $_ldflags $_miscargs $_outfile $LIBGCC_PATH
+fi
+
diff --git a/Tools/GCCProxy/getconfig.mk b/Tools/GCCProxy/getconfig.mk
new file mode 100644 (file)
index 0000000..bd0ce0d
--- /dev/null
@@ -0,0 +1,10 @@
+include $(dir $(lastword $(MAKEFILE_LIST)))../../Usermode/Applications/Makefile.cfg
+
+.PHONY: shellvars
+
+shellvars:
+       @echo '_CC="$(CC)"'
+       @echo '_LD="$(LD)"'
+       @echo 'LDFLAGS="$(LDFLAGS)"'
+       @echo 'CFLAGS="$(CFLAGS)"'
+       @echo 'LIBGCC_PATH="$(LIBGCC_PATH)"'
index 24889fa..28007e1 100644 (file)
@@ -165,15 +165,15 @@ void CallCommand(char **Args)
        {\r
                GeneratePath(exefile, gsCurrentDirectory, sTmpBuffer);\r
                // Check file existence\r
-               fd = open(sTmpBuffer, OPENFLAG_EXEC);\r
+               fd = _SysOpen(sTmpBuffer, OPENFLAG_EXEC);\r
                if(fd == -1) {\r
                        printf("Unknown Command: `%s'\n", Args[0]);     // Error Message\r
                        return ;\r
                }\r
                \r
                // Get File info and close file\r
-               finfo( fd, &info, 0 );\r
-               close( fd );\r
+               _SysFInfo( fd, &info, 0 );\r
+               _SysClose( fd );\r
                \r
                // Check if the file is a directory\r
                if(info.flags & FILEFLAG_DIRECTORY) {\r
@@ -189,10 +189,10 @@ void CallCommand(char **Args)
                for( i = 0; i < giNumPathDirs; i++ )\r
                {\r
                        GeneratePath(exefile, gasPathDirs[i], sTmpBuffer);\r
-                       fd = open(sTmpBuffer, OPENFLAG_EXEC);\r
+                       fd = _SysOpen(sTmpBuffer, OPENFLAG_EXEC);\r
                        if(fd == -1)    continue;\r
-                       finfo( fd, &info, 0 );\r
-                       close( fd );\r
+                       _SysFInfo( fd, &info, 0 );\r
+                       _SysClose( fd );\r
                        if(info.flags & FILEFLAG_DIRECTORY)     continue;\r
                        // Woohoo! We found a valid command\r
                        break;\r
@@ -206,19 +206,14 @@ void CallCommand(char **Args)
        }\r
        \r
        // Create new process\r
-       pid = clone(CLONE_VM, 0);\r
-       // Start Task\r
-       if(pid == 0) {\r
-               execve(sTmpBuffer, Args, gasEnvironment);\r
-               printf("Execve returned, ... oops\n");\r
-               exit(-1);\r
-       }\r
+       int fds[] = {0, 1, 2};\r
+       pid = _SysSpawn(sTmpBuffer, (const char **)Args, (const char **)gasEnvironment, 3, fds, NULL);\r
        if(pid <= 0) {\r
                printf("Unable to create process: `%s'\n", sTmpBuffer); // Error Message\r
        }\r
        else {\r
                 int    status;\r
-               waittid(pid, &status);\r
+               _SysWaitTID(pid, &status);\r
        }\r
 }\r
 \r
@@ -256,7 +251,7 @@ void Command_Help(int argc, char **argv)
  */\r
 void Command_Clear(int argc, char **argv)\r
 {\r
-       write(_stdout, "\x1B[2J", 4);   //Clear Screen\r
+       _SysWrite(_stdout, "\x1B[2J", 4);       //Clear Screen\r
 }\r
 \r
 /**\r
@@ -277,13 +272,13 @@ void Command_Cd(int argc, char **argv)
        \r
        GeneratePath(argv[1], gsCurrentDirectory, tmpPath);\r
        \r
-       fp = open(tmpPath, 0);\r
+       fp = _SysOpen(tmpPath, 0);\r
        if(fp == -1) {\r
                printf("Directory does not exist\n");\r
                return;\r
        }\r
-       finfo(fp, &stats, 0);\r
-       close(fp);\r
+       _SysFInfo(fp, &stats, 0);\r
+       _SysClose(fp);\r
        \r
        if( !(stats.flags & FILEFLAG_DIRECTORY) ) {\r
                printf("Not a Directory\n");\r
@@ -295,7 +290,7 @@ void Command_Cd(int argc, char **argv)
        strcpy(gsCurrentDirectory, tmpPath);\r
        \r
        // Register change with kernel\r
-       chdir( gsCurrentDirectory );\r
+       _SysChdir( gsCurrentDirectory );\r
 }\r
 \r
 /**\r
@@ -321,7 +316,7 @@ void Command_Dir(int argc, char **argv)
        dirLen = strlen(tmpPath);\r
        \r
        // Open Directory\r
-       dp = open(tmpPath, OPENFLAG_READ);\r
+       dp = _SysOpen(tmpPath, OPENFLAG_READ);\r
        // Check if file opened\r
        if(dp == -1)\r
        {\r
@@ -329,16 +324,16 @@ void Command_Dir(int argc, char **argv)
                return;\r
        }\r
        // Get File Stats\r
-       if( finfo(dp, &info, 0) == -1 )\r
+       if( _SysFInfo(dp, &info, 0) == -1 )\r
        {\r
-               close(dp);\r
+               _SysClose(dp);\r
                printf("stat Failed, Bad File Descriptor\n");\r
                return;\r
        }\r
        // Check if it's a directory\r
        if(!(info.flags & FILEFLAG_DIRECTORY))\r
        {\r
-               close(dp);\r
+               _SysClose(dp);\r
                printf("Unable to open directory `%s', Not a directory\n", tmpPath);\r
                return;\r
        }\r
@@ -352,7 +347,7 @@ void Command_Dir(int argc, char **argv)
        \r
        fileName = (char*)(tmpPath+dirLen);\r
        // Read Directory Content\r
-       while( (fp = SysReadDir(dp, fileName)) )\r
+       while( (fp = _SysReadDir(dp, fileName)) )\r
        {\r
                if(fp < 0)\r
                {\r
@@ -361,10 +356,10 @@ void Command_Dir(int argc, char **argv)
                        break;\r
                }\r
                // Open File\r
-               fp = open(tmpPath, 0);\r
+               fp = _SysOpen(tmpPath, 0);\r
                if(fp == -1)    continue;\r
                // Get File Stats\r
-               finfo(fp, &info, 0);\r
+               _SysFInfo(fp, &info, 0);\r
                \r
                if(info.flags & FILEFLAG_DIRECTORY)\r
                        printf("d");\r
@@ -391,7 +386,7 @@ void Command_Dir(int argc, char **argv)
                if(acl.perms & 2)       modeStr[7] = 'w';       else    modeStr[7] = '-';\r
                if(acl.perms & 8)       modeStr[8] = 'x';       else    modeStr[8] = '-';\r
                printf(modeStr);\r
-               close(fp);\r
+               _SysClose(fp);\r
                \r
                // Colour Code\r
                if(info.flags & FILEFLAG_DIRECTORY)     // Directory: Green\r
@@ -412,5 +407,5 @@ void Command_Dir(int argc, char **argv)
                printf("\n");\r
        }\r
        // Close Directory\r
-       close(dp);\r
+       _SysClose(dp);\r
 }\r
index 0e89a7c..5314aea 100644 (file)
@@ -8,7 +8,7 @@ ASFLAGS = -felf
 CPPFLAGS = -ffreestanding -I$(ACESSUSERDIR)/include/ -DARCHDIR_is_$(ARCHDIR)
 CPPFLAGS += $(addprefix -I,$(wildcard $(ACESSUSERDIR)Libraries/*/include_exp/))
 CFLAGS   = -fno-stack-protector $(CPPFLAGS)
-LDFLAGS  = -T $(OUTPUTDIR)Libs/acess.ld -rpath-link $(OUTPUTDIR)Libs -L $(OUTPUTDIR)Libs -I /Acess/Libs/ld-acess.so -lld-acess -lc $(OUTPUTDIR)Libs/crtbegin.o $(OUTPUTDIR)Libs/crtend.o
+LDFLAGS  = -T $(OUTPUTDIR)Libs/acess.ld -rpath-link $(OUTPUTDIR)Libs -L $(OUTPUTDIR)Libs -I /Acess/Libs/ld-acess.so -lld-acess -lc $(OUTPUTDIR)Libs/crtbegin.o $(OUTPUTDIR)Libs/crtend.o -lposix
 LIBGCC_PATH = $(shell $(CC) -print-libgcc-file-name)
 
 # Extra-verbose errors!
index c1245ae..5bf963b 100644 (file)
@@ -47,7 +47,7 @@ ifneq ($(_OBJPREFIX),)
        @mkdir -p $(dir $@)
 endif
        @$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
-       @$(CC) -M -MT $@ $(CPPFLAGS) $< -o $(_OBJPREFIX)$*.dep
+       @$(CC) -M -MP -MT $@ $(CPPFLAGS) $< -o $(_OBJPREFIX)$*.dep
 
 $(OUTPUTDIR)Libs/libld-acess.so:
        @make -C $(ACESSDIR)/Usermode/Libraries/ld-acess.so_src/
index fee178a..e8b5834 100644 (file)
@@ -20,6 +20,8 @@ void  create_sidebar(void);
 void   create_mainmenu(void);
 void   create_run_dialog(void);
 void   mainmenu_run_dialog(void *unused);
+void   mainmenu_app_terminal(void *unused);
+void   mainmenu_app_textedit(void *unused);
 
 // === GLOBALS ===
 tHWND  gSidebar;
@@ -29,6 +31,7 @@ tHWND gRunDialog;
 tAxWin3_Widget *gRunInput;
  int   giScreenWidth;
  int   giScreenHeight;
+char   **gEnvion;
 
 // === CODE ===
 int systembutton_fire(tAxWin3_Widget *Widget)
@@ -38,8 +41,9 @@ int systembutton_fire(tAxWin3_Widget *Widget)
        return 0;
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *argv[], char **envp)
 {
+       gEnvion = envp;
        // Connect to AxWin3 Server
        AxWin3_Connect(NULL);
 
@@ -51,8 +55,8 @@ int main(int argc, char *argv[])
        create_run_dialog();
        
        AxWin3_RegisterAction(gSidebar, "Interface>Run", (tAxWin3_HotkeyCallback)mainmenu_run_dialog);
-//     AxWin3_RegisterAction(gSidebar, "Interface>Terminal", mainmenu_app_terminal);
-//     AxWin3_RegisterAction(gSidebar, "Interface>TextEdit", mainmenu_app_textedit);
+       AxWin3_RegisterAction(gSidebar, "Interface>Terminal", (tAxWin3_HotkeyCallback)mainmenu_app_terminal);
+       AxWin3_RegisterAction(gSidebar, "Interface>TextEdit", (tAxWin3_HotkeyCallback)mainmenu_app_textedit);
 
        // Idle loop
        AxWin3_MainLoop();
@@ -107,7 +111,9 @@ void create_sidebar(void)
 
 void mainmenu_app_textedit(void *unused)
 {
-       _SysDebug("TODO: Launch text editor");
+       const char      *args[] = {"ate",NULL};
+//     _SysDebug("TODO: Launch text editor");
+       _SysSpawn("/Acess/Apps/AxWin/3.0/ate", args, (const char **)gEnvion, 0, NULL, NULL);
 }
 
 void mainmenu_app_terminal(void *unused)
index fae6cbe..1d67450 100644 (file)
@@ -10,9 +10,10 @@ BIN := AxWinWM
 OBJ := main.o input.o video.o ipc.o image.o utf-8.o
 OBJ += wm.o wm_input.o wm_render.o wm_render_text.o wm_hotkeys.o
 OBJ += decorator.o
-OBJ += renderers/passthru.o
+OBJ += renderers/framebuffer.o
 OBJ += renderers/background.o
 OBJ += renderers/menu.o
+OBJ += renderers/richtext.o
 # TODO: Move to a lower makefile
 OBJ += renderers/widget.o
 OBJ += renderers/widget/button.o
@@ -20,6 +21,7 @@ OBJ += renderers/widget/image.o
 OBJ += renderers/widget/disptext.o
 OBJ += renderers/widget/textinput.o
 OBJ += renderers/widget/spacer.o
+OBJ += renderers/widget/subwin.o
 
 LDFLAGS += -limage_sif -luri -lnet
 
index 14c0414..6600408 100644 (file)
@@ -133,18 +133,31 @@ void Decorator_Redraw(tWindow *Window)
 
 int Decorator_HandleMessage(tWindow *Window, int Message, int Length, const void *Data)
 {
+       static tWindow  *btn1_down;
        switch(Message)
        {
        case WNDMSG_MOUSEMOVE: {
                const struct sWndMsg_MouseMove  *msg = Data;
+
+               if( btn1_down == Window ) {
+                       WM_MoveWindow(Window, Window->X + msg->dX, Window->Y + msg->dY);
+                       return 0;
+               }
+
                if(msg->Y >= 0) return 1;       // Pass
-               
+
                // TODO: Handle
                return 0; }
        case WNDMSG_MOUSEBTN: {
                const struct sWndMsg_MouseButton        *msg = Data;
+               if( msg->Button == 0 && !msg->bPressed )
+                       btn1_down = 0;          
+
                if(msg->Y >= 0) return 1;       // Pass
-               
+       
+               if( msg->Button == 0 && msg->bPressed )
+                       btn1_down = Window;
+
                // TODO: Handle
                return 0; }
        default:        // Anything unhandled is passed on
index 7807c90..e060e24 100644 (file)
@@ -24,6 +24,8 @@
 #define WINFLAG_NODECORATE     0x00000002
 //! Window takes up all of screen
 #define WINFLAG_MAXIMIZED      0x00000004
+//! Window is contained within the parent
+#define WINFLAG_RELATIVE       0x00000008
 //! Window contents are valid
 #define WINFLAG_CLEAN          0x00000040
 //! All child windows are un-changed
@@ -45,12 +47,14 @@ typedef struct sIPC_Client  tIPC_Client;
 // === FUNCTIONS ===
 // --- Management
 extern tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int Flags, const char *Renderer);
+extern tWindow *WM_GetWindowByID(tWindow *Requester, uint32_t ID);
 extern void    WM_Invalidate(tWindow *Window);
 extern void    WM_SetWindowTitle(tWindow *Window, const char *Title);
 extern void    WM_FocusWindow(tWindow *Destination);
 extern void    WM_RaiseWindow(tWindow *Window);
 extern void    WM_ShowWindow(tWindow *Window, int bShow);
 extern void    WM_DecorateWindow(tWindow *Window, int bDecorate);
+extern void    WM_SetRelative(tWindow *Window, int bRelativeToParent);
 extern int     WM_ResizeWindow(tWindow *Window, int W, int H);
 extern int     WM_MoveWindow(tWindow *Window, int X, int Y);
 extern int     WM_SendMessage(tWindow *Source, tWindow *Dest, int MessageID, int Length, const void *Data);
index 9ab29f8..45769e8 100644 (file)
@@ -41,8 +41,9 @@ struct sWindow
 
        // Position and dimensions
         int    X, Y;
-        int    RealW, RealH;
         int    W, H;
+        int    RealX, RealY;
+        int    RealW, RealH;
 
        void    *RenderBuffer;  //!< Cached copy of the rendered window
 };
index 5882549..89aceb9 100644 (file)
@@ -52,9 +52,17 @@ struct sWMRenderer
         * \return Boolean failure (0: Handled, 1: Unhandled)
         */
         int    (*HandleMessage)(tWindow *Window, int MessageID, int Length, const void *Data);
+       
+        int    nIPCHandlers;
+       
+       /**
+        * \brief IPC Message handler
+        */
+        int    (*IPCHandlers[])(tWindow *Window, size_t Length, const void *Data);
 };
 
 extern void    WM_RegisterRenderer(tWMRenderer *Renderer);
 extern tWindow *WM_CreateWindowStruct(size_t ExtraBytes);
+extern int     WM_SendIPCReply(tWindow *Window, int Message, size_t Length, const void *Data);
 
 #endif
index 352bdee..29ef004 100644 (file)
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <acess/sys.h>
 #include <wm_input.h>
+#include <stddef.h>
 
 // TODO: Move out to a common header
 typedef struct
@@ -36,21 +37,21 @@ int Input_Init(void)
        tNumValue       num_value;
 
        // Open mouse for RW
-       giMouseFD = open(gsMouseDevice, 3);
+       giMouseFD = _SysOpen(gsMouseDevice, 3);
 
        // Set mouse limits
        // TODO: Update these if the screen resolution changes
        num_value.Num = 0;      num_value.Value = giScreenWidth;
-       ioctl(giMouseFD, JOY_IOCTL_GETSETAXISLIMIT, &num_value);
+       _SysIOCtl(giMouseFD, JOY_IOCTL_GETSETAXISLIMIT, &num_value);
        num_value.Value = giScreenWidth/2;
        giInput_MouseX = giScreenWidth/2;
-       ioctl(giMouseFD, JOY_IOCTL_GETSETAXISPOSITION, &num_value);
+       _SysIOCtl(giMouseFD, JOY_IOCTL_GETSETAXISPOSITION, &num_value);
 
        num_value.Num = 1;      num_value.Value = giScreenHeight;
-       ioctl(giMouseFD, JOY_IOCTL_GETSETAXISLIMIT, &num_value);
+       _SysIOCtl(giMouseFD, JOY_IOCTL_GETSETAXISLIMIT, &num_value);
        num_value.Value = giScreenHeight/2;
        giInput_MouseY = giScreenHeight/2;
-       ioctl(giMouseFD, JOY_IOCTL_GETSETAXISPOSITION, &num_value);
+       _SysIOCtl(giMouseFD, JOY_IOCTL_GETSETAXISPOSITION, &num_value);
 
        return 0;
 }
@@ -71,7 +72,7 @@ void Input_HandleSelect(fd_set *set)
                static uint32_t scancode;
                #define KEY_CODEPOINT_MASK      0x3FFFFFFF
                
-               size_t readlen = read(giTerminalFD_Input, &codepoint, sizeof(codepoint));
+               size_t readlen = _SysRead(giTerminalFD_Input, &codepoint, sizeof(codepoint));
                if( readlen != sizeof(codepoint) )
                {
                        // oops, error
@@ -118,8 +119,8 @@ void Input_HandleSelect(fd_set *set)
 
                mouseinfo = (void*)data;
 
-               seek(giMouseFD, 0, SEEK_SET);
-               i = read(giMouseFD, data, sizeof(data));
+               _SysSeek(giMouseFD, 0, SEEK_SET);
+               i = _SysRead(giMouseFD, data, sizeof(data));
                i -= sizeof(*mouseinfo);
                if( i < 0 ) {
                        _SysDebug("Mouse data undersized (no header)");
index cbed7fd..5b600ee 100644 (file)
@@ -13,7 +13,8 @@
 #include <stdio.h>
 #include <wm.h>
 #include <wm_internals.h>
-#include <wm_hotkeys.h>
+#include <wm_hotkeys.h>        // Hotkey registration
+#include <wm_renderer.h>       // Renderer IPC messages
 
 #define AXWIN_PORT     4101
 
@@ -75,11 +76,11 @@ void IPC_Init(void)
 {
         int    tmp;
        // TODO: Check this
-       giNetworkFileHandle = open("/Devices/ip/loop/udp", OPENFLAG_READ);
+       giNetworkFileHandle = _SysOpen("/Devices/ip/loop/udp", OPENFLAG_READ);
        if( giNetworkFileHandle != -1 )
        {
                tmp = AXWIN_PORT;
-               ioctl(giNetworkFileHandle, 4, &tmp);    // TODO: Don't hard-code IOCtl number
+               _SysIOCtl(giNetworkFileHandle, 4, &tmp);        // TODO: Don't hard-code IOCtl number
        }
 }
 
@@ -102,7 +103,7 @@ void IPC_HandleSelect(fd_set *set)
                         int    readlen, identlen;
                        char    *msg;
        
-                       readlen = read(giNetworkFileHandle, staticBuf, sizeof(staticBuf));
+                       readlen = _SysRead(giNetworkFileHandle, staticBuf, sizeof(staticBuf));
                        
                        identlen = 4 + Net_GetAddressSize( ((uint16_t*)staticBuf)[1] );
                        msg = staticBuf + identlen;
@@ -112,12 +113,12 @@ void IPC_HandleSelect(fd_set *set)
                }
        }
 
-       while(SysGetMessage(NULL, NULL))
+       size_t  len;
+       int     tid;
+       while( (len = _SysGetMessage(&tid, 0, NULL)) )
        {
-               pid_t   tid;
-                int    len = SysGetMessage(&tid, NULL);
                char    data[len];
-               SysGetMessage(NULL, data);
+               _SysGetMessage(NULL, len, data);
 
                IPC_Handle(&gIPC_Type_SysMessage, &tid, len, (void*)data);
 //             _SysDebug("IPC_HandleSelect: Message handled");
@@ -144,7 +145,7 @@ void IPC_Type_Datagram_Send(const void *Ident, size_t Length, const void *Data)
        memcpy(tmpbuf, Ident, identlen);        // Header
        memcpy(tmpbuf + identlen, Data, Length);        // Data
        // TODO: Handle fragmented packets
-       write(giNetworkFileHandle, tmpbuf, sizeof(tmpbuf));
+       _SysWrite(giNetworkFileHandle, tmpbuf, sizeof(tmpbuf));
 }
 
 int IPC_Type_Sys_GetSize(const void *Ident)
@@ -159,7 +160,7 @@ int IPC_Type_Sys_Compare(const void *Ident1, const void *Ident2)
 
 void IPC_Type_Sys_Send(const void *Ident, size_t Length, const void *Data)
 {
-       SysSendMessage( *(const tid_t*)Ident, Length, Data );
+       _SysSendMessage( *(const tid_t*)Ident, Length, Data );
 }
 
 // --- Client -> Window Mappings
@@ -244,7 +245,6 @@ tWindow *IPC_int_GetWindow(tIPC_Client *Client, uint32_t WindowID)
                return NULL;
 
        if( WindowID >= Client->nWindows ) {
-//             _SysDebug("Window %i out of range for %p (%i)", WindowID, Client, Client->nWindows);
                return NULL;
        }
 
@@ -540,8 +540,8 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW
        tIPC_Client     *client;
         int    rv = 0;
        
-       _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)",
-               IPCType, Ident, MsgLen, Msg);
+//     _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)",
+//             IPCType, Ident, MsgLen, Msg);
        
        if( MsgLen < sizeof(tAxWin_IPCMessage) )
                return ;
@@ -549,25 +549,53 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW
                return ;
        
        client = IPC_int_GetClient(IPCType, Ident);
-
-       if( Msg->ID >= giIPC_NumMessageHandlers ) {
-               fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
-               _SysDebug("WARNING: Unknown message %i (%p)", Msg->ID, IPCType);
-               return ;
+       if( !client ) {
+               // Oops?
        }
        
-       if( !gIPC_MessageHandlers[ Msg->ID ] ) {
-               fprintf(stderr, "WARNING: Message %i does not have a handler\n", Msg->ID);
-               _SysDebug("WARNING: Message %i does not have a handler", Msg->ID);
-               return ;
+       if( Msg->Flags & IPCMSG_FLAG_RENDERER )
+       {
+               tWindow *win = IPC_int_GetWindow(client, Msg->Window);
+               if( !win ) {
+                       _SysDebug("WARNING: NULL window in message %i", Msg->ID);
+                       return ;
+               }
+               tWMRenderer     *renderer = win->Renderer;
+               if( Msg->ID >= renderer->nIPCHandlers ) {
+                       _SysDebug("WARNING: Message %i out of range in %s", Msg->ID, renderer->Name);
+                       return ;
+               }
+               if( !renderer->IPCHandlers[Msg->ID] ) {
+                       _SysDebug("WARNING: Message %i has no handler in %s", Msg->ID, renderer->Name);
+                       return ;
+               }
+               _SysDebug("IPC_Handle: Call %s-%i", renderer->Name, Msg->ID);
+               rv = renderer->IPCHandlers[Msg->ID](win, Msg->Size, Msg->Data);
+               if( rv )
+                       _SysDebug("IPC_Handle: rv != 0 (%i)", rv);
+       }
+       else
+       {
+               if( Msg->ID >= giIPC_NumMessageHandlers ) {
+                       fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
+                       _SysDebug("WARNING: Unknown message %i (%p)", Msg->ID, IPCType);
+                       return ;
+               }
+               
+               if( !gIPC_MessageHandlers[ Msg->ID ] ) {
+                       fprintf(stderr, "WARNING: Message %i does not have a handler\n", Msg->ID);
+                       _SysDebug("WARNING: Message %i does not have a handler", Msg->ID);
+                       return ;
+               }
+       
+               _SysDebug("IPC_Handle: Call WM-%i", Msg->ID);
+               rv = gIPC_MessageHandlers[Msg->ID](client, Msg);
+               if( rv )
+                       _SysDebug("IPC_Handle: rv != 0 (%i)", rv);
        }
-
-       _SysDebug("IPC_Handle: Msg->ID = %i", Msg->ID);
-       rv = gIPC_MessageHandlers[Msg->ID](client, Msg);
-       _SysDebug("IPC_Handle: rv = %i", rv);
 }
 
-// --- Server->Client replies
+// Dispatch a message to the client
 void IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int MsgID, int Len, void *Data)
 {
        tAxWin_IPCMessage       *hdr;
@@ -590,3 +618,20 @@ void IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int MsgI
        Client->IPCType->SendMessage(Client->Ident, sizeof(buf), buf);
 }
 
+// --- Server->Client replies
+void IPC_SendReply(tIPC_Client *Client, uint32_t WinID, int MsgID, size_t Len, const void *Data)
+{
+       tAxWin_IPCMessage       *hdr;
+       char    buf[sizeof(*hdr)+Len];
+       
+       hdr = (void*)buf;
+       
+       hdr->ID = MsgID;
+       hdr->Flags = IPCMSG_FLAG_RENDERER;
+       hdr->Size = Len;
+       hdr->Window = WinID;
+       
+       memcpy(hdr->Data, Data, Len);
+       Client->IPCType->SendMessage(Client->Ident, sizeof(buf), buf);
+}
+
index 0996f90..7d2d391 100644 (file)
@@ -18,6 +18,7 @@ extern int    Renderer_Menu_Init(void);
 extern int     Renderer_Widget_Init(void);
 extern int     Renderer_Background_Init(void);
 extern int     Renderer_Framebuffer_Init(void);
+extern int     Renderer_RichText_Init(void);
 extern void    WM_Update(void);
 extern void    WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName);
 
@@ -45,8 +46,6 @@ const char    *gsInstallRoot = __INSTALL_ROOT;
  */
 int main(int argc, char *argv[])
 {
-        int    server_tid = gettid();
-       
        ParseCommandline(argc, argv);
        
        if( gsTerminalDevice == NULL ) {
@@ -64,6 +63,7 @@ int main(int argc, char *argv[])
        Renderer_Widget_Init();
        Renderer_Background_Init();
        Renderer_Framebuffer_Init();
+       Renderer_RichText_Init();
        WM_Initialise();
 
        // TODO: Config
@@ -72,16 +72,20 @@ int main(int argc, char *argv[])
        WM_Hotkey_Register(2, keys, "Interface>Run");
        
        // Spawn interface root
-       if( clone(CLONE_VM, 0) == 0 )
        {
+               int     server_tid = gettid();
+               _SysDebug("server_tid = %i", server_tid);
                static char csInterfaceApp[] = __INSTALL_ROOT"/AxWinUI";
                char    server_info[] = "AXWIN3_SERVER=00000";
-               char    *envp[] = {server_info, NULL};
-               char    *argv[] = {csInterfaceApp, NULL};
+               const char      *envp[] = {server_info, NULL};
+               const char      *argv[] = {csInterfaceApp, NULL};
                _SysDebug("server_tid = %i, &server_tid = %p", server_tid, &server_tid);
                sprintf(server_info, "AXWIN3_SERVER=%i", server_tid);
-               execve(csInterfaceApp, argv, envp);
-               exit(1);
+               // TODO: Does the client need FDs?
+                int    rv = _SysSpawn(csInterfaceApp, argv, envp, 0, NULL, NULL);
+               if( rv ) {
+                       _SysDebug("_SysSpawn chucked a sad, rv=%i, errno=%i", rv, _errno);
+               }
        }
 
        // Main Loop
diff --git a/Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c b/Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c
new file mode 100644 (file)
index 0000000..fc838cb
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Acess2 Window Manager v3
+ * - By John Hodge (thePowersGang)
+ *
+ * renderer_passthru.c
+ * - Passthrough window render (framebuffer essentially)
+ */
+#include <common.h>
+#include <wm_renderer.h>
+#include <string.h>
+#include <framebuffer_messages.h>
+#include <wm_messages.h>
+
+// === TYPES ===
+typedef struct
+{
+       short   W, H;
+       void    *Data;
+       char    _data[];
+} tFBBuffer;
+typedef struct
+{
+       tFBBuffer       BackBuffer;
+        int    MaxBufferCount;
+       tFBBuffer       *Buffers[];
+} tFBWin;
+
+// === PROTOTYPES ===
+tWindow        *Renderer_Framebuffer_Create(int Flags);
+void   Renderer_Framebuffer_Redraw(tWindow *Window);
+ int   _Handle_Commit(tWindow *Target, size_t Len, const void *Data);
+ int   _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data);
+ int   Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
+
+// === GLOBALS ===
+tWMRenderer    gRenderer_Framebuffer = {
+       .Name = "FrameBuffer",
+       .CreateWindow = Renderer_Framebuffer_Create,
+       .Redraw = Renderer_Framebuffer_Redraw,
+       .HandleMessage = Renderer_Framebuffer_HandleMessage,
+       .nIPCHandlers = N_IPC_FB,
+       .IPCHandlers = {
+               [IPC_FB_COMMIT] = _Handle_Commit,
+               [IPC_FB_NEWBUF] = _Handle_CreateBuf,
+       }
+};
+
+// === CODE ===
+int Renderer_Framebuffer_Init(void)
+{
+       WM_RegisterRenderer(&gRenderer_Framebuffer);
+       return 0;
+}
+
+tWindow        *Renderer_Framebuffer_Create(int Flags)
+{
+       tWindow *ret;
+       tFBWin  *info;
+       const int       max_buffers = 10;       // TODO: Have this be configurable
+       
+       ret = WM_CreateWindowStruct( sizeof(*info) + max_buffers*sizeof(tFBBuffer*) );
+       info = ret->RendererInfo;
+       
+       info->BackBuffer.W = 0;
+       info->BackBuffer.H = 0;
+       info->BackBuffer.Data = NULL;
+       info->MaxBufferCount = max_buffers;
+       memset( info->Buffers, 0, sizeof(tFBBuffer*) * max_buffers );
+       
+       return ret;
+}
+
+void Renderer_Framebuffer_Redraw(tWindow *Window)
+{
+       
+}
+
+// --- ---
+tFBBuffer *_GetBuffer(tWindow *Win, uint16_t ID)
+{
+       tFBWin  *info = Win->RendererInfo;
+       if( ID == 0xFFFF )
+               return &info->BackBuffer;
+       else if( ID >= info->MaxBufferCount )
+               return NULL;
+       else
+               return info->Buffers[ ID ];
+}
+
+void _Blit(
+       tFBBuffer *Dest, uint16_t DX, uint16_t DY,
+       const tFBBuffer *Src, uint16_t SX, uint16_t SY,
+       uint16_t W, uint16_t H
+       )
+{
+       uint32_t        *dest_data = Dest->Data;
+       const uint32_t  *src_data = Src->Data;
+       // First, some sanity
+       if( DX > Dest->W )      return ;
+       if( DY > Dest->H )      return ;
+       if( SX > Src->W )       return ;
+       if( SY > Src->H )       return ;
+       
+       if( DX + W > Dest->W )  W = Dest->W - DX;
+       if( SX + W > Src->W )   W = Src->W - SX;
+       if( DY + H > Dest->H )  H = Dest->H - DY;
+       if( SY + H > Src->H )   H = Src->H - SY;
+       
+       dest_data += (DY * Dest->W) + DX;
+       src_data  += (SY * Src->W ) + SX;
+       for( int i = 0; i < H; i ++ )
+       {
+               memcpy( dest_data, src_data, W * 4 );
+               dest_data += Dest->W;
+               src_data += Src->W;
+       }
+}
+
+void _Fill(tFBBuffer *Buf, uint16_t X, uint16_t Y, uint16_t W, uint16_t H, uint32_t Colour)
+{
+       uint32_t        *data = Buf->Data;
+       
+       if( X > Buf->W )        return ;
+       if( Y > Buf->H )        return ;
+       if( X + W > Buf->W )    W = Buf->W - X;
+       if( Y + H > Buf->H )    H = Buf->H - Y;
+       
+       data += (Y * Buf->W) + X;
+       for( int i = 0; i < H; i ++ )
+       {
+               for( int j = 0; j < W; j ++ )
+                       *data++ = Colour;
+               data += Buf->W - W;
+       }
+}
+
+// --- ---
+int _Handle_Commit(tWindow *Target, size_t Len, const void *Data)
+{
+       // Do a window invalidate
+       return 0;
+}
+
+int _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data)
+{
+       const tFBIPC_NewBuf     *msg = Data;
+       tFBBuffer       *buf;
+       tFBWin  *info = Target->RendererInfo;
+       
+       if( Len < sizeof(*msg) )        return -1;
+       
+       if( msg->Buffer == -1 || msg->Buffer >= info->MaxBufferCount ) {
+               // Can't reallocate -1
+               return 1;
+       }
+       
+       if( info->Buffers[msg->Buffer] ) {
+               free(info->Buffers[msg->Buffer]);
+               info->Buffers[msg->Buffer] = NULL;
+       }
+       
+       buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4);
+       buf->W = msg->W;
+       buf->H = msg->H;
+       buf->Data = buf->_data;
+       
+       info->Buffers[msg->Buffer] = buf;
+       
+       return 0;
+}
+
+int _Handle_Upload(tWindow *Target, size_t Len, const void *Data)
+{
+       const tFBIPC_Transfer   *msg = Data;
+       tFBBuffer       *dest, src;
+       
+       if( Len < sizeof(*msg) )        return -1;
+       if( Len < sizeof(*msg) + msg->W * msg->H * 4 )  return -1;
+       
+       dest = _GetBuffer(Target, msg->Buffer);
+
+       src.W = msg->W; 
+       src.H = msg->H; 
+       src.Data = (void*)msg->ImageData;
+
+       _Blit( dest, msg->X, msg->Y,  &src, 0, 0,  msg->W, msg->H );
+       return 0;
+}
+
+int _Handle_Download(tWindow *Target, size_t Len, const void *Data)
+{
+       const tFBIPC_Transfer   *msg = Data;
+       tFBBuffer       dest, *src;
+       
+       if( Len < sizeof(*msg) )        return -1;
+       
+       src = _GetBuffer(Target, msg->Buffer);
+
+       tFBIPC_Transfer *ret;
+        int    retlen = sizeof(*ret) + msg->W*msg->H*4;
+       ret = malloc( retlen );
+
+       dest.W = ret->W = msg->W;
+       dest.H = ret->H = msg->H;
+       dest.Data = ret->ImageData;
+       
+       _Blit( &dest, 0, 0,  src, msg->X, msg->Y,  msg->W, msg->H );
+
+       WM_SendIPCReply(Target, IPC_FB_DOWNLOAD, retlen, ret);
+
+       free(ret);
+
+       return 0;
+}
+
+int _Handle_LocalBlit(tWindow *Target, size_t Len, const void *Data)
+{
+       const tFBIPC_Blit       *msg = Data;
+       tFBBuffer       *dest, *src;
+       
+       if( Len < sizeof(*msg) )        return -1;
+       
+       src = _GetBuffer(Target, msg->Source);
+       dest = _GetBuffer(Target, msg->Dest);
+
+       _Blit( dest, msg->DstX, msg->DstY,  src, msg->SrcX, msg->SrcY,  msg->W, msg->H );
+       return 0;
+}
+
+int _Handle_FillRect(tWindow *Target, size_t Len, const void *Data)
+{
+       const tFBIPC_Fill       *msg = Data;
+       tFBBuffer       *dest;
+       
+       if( Len < sizeof(*msg) )        return -1;
+       
+       dest = _GetBuffer(Target, msg->Buffer);
+       
+       _Fill( dest, msg->X, msg->Y, msg->W, msg->H, msg->Colour );
+       return 0;
+}
+
+int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
+{
+       switch(Msg)
+       {
+       case WNDMSG_RESIZE:
+               // Resize the framebuffer
+               return 1;       // Pass on
+       
+       // Messages that get passed on
+       case WNDMSG_MOUSEBTN:
+               return 1;
+       }
+       return 1;
+}
+
+
index a183de0..9d2ecea 100644 (file)
@@ -47,6 +47,8 @@ typedef struct sMenuWindowInfo
 void   Renderer_Menu_Init(void);
 tWindow        *Renderer_Menu_Create(int Argument);
 void   Renderer_Menu_Redraw(tWindow *Window);
+ int   Renderer_Menu_HandleIPC_AddItem(tWindow *Window, size_t Length, const void *Data);
+ int   Renderer_Menu_HandleIPC_SetFlags(tWindow *Window, size_t Length, const void *Data);
  int   Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, const void *Data);
 
 // === CONSTANTS ===
@@ -70,7 +72,12 @@ tWMRenderer  gRenderer_Menu = {
        .Name = "Menu",
        .CreateWindow = Renderer_Menu_Create,
        .Redraw = Renderer_Menu_Redraw,
-       .HandleMessage = Renderer_Menu_HandleMessage
+       .HandleMessage = Renderer_Menu_HandleMessage,
+       .nIPCHandlers = 2,
+       .IPCHandlers = {
+               Renderer_Menu_HandleIPC_AddItem,
+//             Renderer_Menu_HandleIPC_SetFlags
+       }
 };
 tFont  *gMenu_Font = NULL;     // System monospace
 
@@ -196,8 +203,9 @@ void Renderer_Menu_Redraw(tWindow *Window)
        }
 }
 
-int Renderer_Menu_int_AddItem(tWindow *Window, int Length, const tMenuMsg_AddItem *Msg)
+int Renderer_Menu_HandleIPC_AddItem(tWindow *Window, size_t Length, const void *Data)
 {
+       const tMenuIPC_AddItem  *Msg = Data;
        tMenuWindowInfo *info = Window->RendererInfo;
        tMenuItem       *item;
        
@@ -418,11 +426,6 @@ int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, const void
 
                return 0; }
 
-       // Manipulation messages
-       case MSG_MENU_ADDITEM:
-//             _SysDebug("MSG_MENU_ADDITEM");
-               return Renderer_Menu_int_AddItem(Window, Length, Data);
-       
        // Only message to pass to client
        case MSG_MENU_SELECT:
                return 1;
diff --git a/Usermode/Applications/axwin3_src/WM/renderers/passthru.c b/Usermode/Applications/axwin3_src/WM/renderers/passthru.c
deleted file mode 100644 (file)
index c8d61cf..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Acess2 Window Manager v3
- * - By John Hodge (thePowersGang)
- *
- * renderer_passthru.c
- * - Passthrough window render (framebuffer essentially)
- */
-#include <common.h>
-#include <wm_renderer.h>
-#include <string.h>
-#include <framebuffer_messages.h>
-#include <wm_messages.h>
-
-// === TYPES ===
-typedef struct
-{
-       short   W, H;
-       void    *Data;
-       char    _data[];
-} tFBBuffer;
-typedef struct
-{
-       tFBBuffer       BackBuffer;
-        int    MaxBufferCount;
-       tFBBuffer       *Buffers[];
-} tFBWin;
-
-// === PROTOTYPES ===
-tWindow        *Renderer_Framebuffer_Create(int Flags);
-void   Renderer_Framebuffer_Redraw(tWindow *Window);
- int   Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
-
-// === GLOBALS ===
-tWMRenderer    gRenderer_Framebuffer = {
-       .Name = "FrameBuffer",
-       .CreateWindow = Renderer_Framebuffer_Create,
-       .Redraw = Renderer_Framebuffer_Redraw,
-       .HandleMessage = Renderer_Framebuffer_HandleMessage
-};
-
-// === CODE ===
-int Renderer_Framebuffer_Init(void)
-{
-       WM_RegisterRenderer(&gRenderer_Framebuffer);
-       return 0;
-}
-
-tWindow        *Renderer_Framebuffer_Create(int Flags)
-{
-       tWindow *ret;
-       tFBWin  *info;
-       const int       max_buffers = 10;       // TODO: Have this be configurable
-       
-       ret = WM_CreateWindowStruct( sizeof(*info) + max_buffers*sizeof(tFBBuffer*) );
-       info = ret->RendererInfo;
-       
-       info->BackBuffer.W = 0;
-       info->BackBuffer.H = 0;
-       info->BackBuffer.Data = NULL;
-       info->MaxBufferCount = max_buffers;
-       memset( info->Buffers, 0, sizeof(tFBBuffer*) * max_buffers );
-       
-       return ret;
-}
-
-void Renderer_Framebuffer_Redraw(tWindow *Window)
-{
-       
-}
-
-// --- ---
-tFBBuffer *_GetBuffer(tWindow *Win, uint16_t ID)
-{
-       tFBWin  *info = Win->RendererInfo;
-       if( ID == 0xFFFF )
-               return &info->BackBuffer;
-       else if( ID >= info->MaxBufferCount )
-               return NULL;
-       else
-               return info->Buffers[ ID ];
-}
-
-void _Blit(
-       tFBBuffer *Dest, uint16_t DX, uint16_t DY,
-       const tFBBuffer *Src, uint16_t SX, uint16_t SY,
-       uint16_t W, uint16_t H
-       )
-{
-       uint32_t        *dest_data = Dest->Data;
-       const uint32_t  *src_data = Src->Data;
-       // First, some sanity
-       if( DX > Dest->W )      return ;
-       if( DY > Dest->H )      return ;
-       if( SX > Src->W )       return ;
-       if( SY > Src->H )       return ;
-       
-       if( DX + W > Dest->W )  W = Dest->W - DX;
-       if( SX + W > Src->W )   W = Src->W - SX;
-       if( DY + H > Dest->H )  H = Dest->H - DY;
-       if( SY + H > Src->H )   H = Src->H - SY;
-       
-       dest_data += (DY * Dest->W) + DX;
-       src_data  += (SY * Src->W ) + SX;
-       for( int i = 0; i < H; i ++ )
-       {
-               memcpy( dest_data, src_data, W * 4 );
-               dest_data += Dest->W;
-               src_data += Src->W;
-       }
-}
-
-void _Fill(tFBBuffer *Buf, uint16_t X, uint16_t Y, uint16_t W, uint16_t H, uint32_t Colour)
-{
-       uint32_t        *data = Buf->Data;
-       
-       if( X > Buf->W )        return ;
-       if( Y > Buf->H )        return ;
-       if( X + W > Buf->W )    W = Buf->W - X;
-       if( Y + H > Buf->H )    H = Buf->H - Y;
-       
-       data += (Y * Buf->W) + X;
-       for( int i = 0; i < H; i ++ )
-       {
-               for( int j = 0; j < W; j ++ )
-                       *data++ = Colour;
-               data += Buf->W - W;
-       }
-}
-
-// --- ---
-void _Handle_Commit(tWindow *Target, size_t Len, const void *Data)
-{
-       // Do a window invalidate
-}
-
-void _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data)
-{
-       const tFBMsg_NewBuf     *msg = Data;
-       tFBBuffer       *buf;
-       tFBWin  *info = Target->RendererInfo;
-       
-       if( Len < sizeof(*msg) )        return ;
-       
-       if( msg->Buffer == -1 || msg->Buffer >= info->MaxBufferCount ) {
-               // Can't reallocate -1
-               return ;
-       }
-       
-       if( info->Buffers[msg->Buffer] ) {
-               free(info->Buffers[msg->Buffer]);
-               info->Buffers[msg->Buffer] = NULL;
-       }
-       
-       buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4);
-       buf->W = msg->W;
-       buf->H = msg->H;
-       buf->Data = buf->_data;
-       
-       info->Buffers[msg->Buffer] = buf;
-}
-
-void _Handle_Upload(tWindow *Target, size_t Len, const void *Data)
-{
-       const tFBMsg_Transfer   *msg = Data;
-       tFBBuffer       *dest, src;
-       
-       if( Len < sizeof(*msg) )        return ;
-       if( Len < sizeof(*msg) + msg->W * msg->H * 4 )  return ;
-       
-       dest = _GetBuffer(Target, msg->Buffer);
-
-       src.W = msg->W; 
-       src.H = msg->H; 
-       src.Data = (void*)msg->ImageData;
-
-       _Blit( dest, msg->X, msg->Y,  &src, 0, 0,  msg->W, msg->H );
-}
-
-void _Handle_Download(tWindow *Target, size_t Len, const void *Data)
-{
-       #if 0
-       const tFBMsg_Transfer   *msg = Data;
-       tFBBuffer       dest, *src;
-       
-       if( Len < sizeof(*msg) )        return ;
-       if( Len < sizeof(*msg) + msg->W * msg->H * 4 )  return ;
-       
-       src = _GetBuffer(Target, msg->Buffer);
-
-       dest.W = msg->W;        
-       dest.H = msg->H;        
-       dest.Data = msg->ImageData;
-       
-       _Blit( &dest, 0, 0,  src, msg->X, msg->Y,  msg->W, msg->H );
-       #endif
-}
-
-void _Handle_LocalBlit(tWindow *Target, size_t Len, const void *Data)
-{
-       const tFBMsg_Blit       *msg = Data;
-       tFBBuffer       *dest, *src;
-       
-       if( Len < sizeof(*msg) )        return ;
-       
-       src = _GetBuffer(Target, msg->Source);
-       dest = _GetBuffer(Target, msg->Dest);
-
-       _Blit( dest, msg->DstX, msg->DstY,  src, msg->SrcX, msg->SrcY,  msg->W, msg->H );
-}
-
-void _Handle_FillRect(tWindow *Target, size_t Len, const void *Data)
-{
-       const tFBMsg_Fill       *msg = Data;
-       tFBBuffer       *dest;
-       
-       if( Len < sizeof(*msg) )        return ;
-       
-       dest = _GetBuffer(Target, msg->Buffer);
-       
-       _Fill( dest, msg->X, msg->Y, msg->W, msg->H, msg->Colour );
-}
-
-int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
-{
-       switch(Msg)
-       {
-       case WNDMSG_RESIZE:
-               // Resize the framebuffer
-               return 1;       // Pass on
-       
-       // Messages that get passed on
-       case WNDMSG_MOUSEBTN:
-               return 1;
-       
-       // --- Local messages ---
-       // - Drawing completed, do an update
-       case MSG_FB_COMMIT:
-               _Handle_Commit(Target, Len, Data);
-               return 0;
-       // - New Buffer (create a new server-side buffer)
-       case MSG_FB_NEWBUF:
-               _Handle_CreateBuf(Target, Len, Data);
-               return 0;
-       // - Upload (Transfer data from client to server)
-       case MSG_FB_UPLOAD:
-               _Handle_Upload(Target, Len, Data);
-               return 0;
-       // - Download (Transfer image data from server to client)
-       case MSG_FB_DOWNLOAD:
-               _Handle_Download(Target, Len, Data);
-               return 0;
-       // - Local Blit (Transfer from server to server)
-       case MSG_FB_BLIT:
-               _Handle_LocalBlit(Target, Len, Data);
-               return 0;
-       // - Fill a rectangle
-       case MSG_FB_FILL:
-               _Handle_FillRect(Target, Len, Data);
-               return 0;
-       }
-       return 1;
-}
-
-
diff --git a/Usermode/Applications/axwin3_src/WM/renderers/richtext.c b/Usermode/Applications/axwin3_src/WM/renderers/richtext.c
new file mode 100644 (file)
index 0000000..28be1ae
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+ * Acess2 Window Manager v3
+ * - By John Hodge (thePowersGang)
+ *
+ * render/richtext.c
+ * - Formatted Line Editor
+ */
+#include <common.h>
+#include <wm_renderer.h>
+#include <wm_messages.h>
+#include <richtext_messages.h>
+#include <stdio.h>     // sscanf
+#include <string.h>    // memcpy
+
+#define LINES_PER_BLOCK        30
+
+// === TYPES ===
+typedef struct sRichText_Line
+{
+       struct sRichText_Line   *Next;
+       struct sRichText_Line   *Prev;
+        int    Num;
+       // TODO: Pre-rendered cache?
+       short   ByteLength;
+       short   Space;
+       char    Data[];
+} tRichText_Line;
+typedef struct sRichText_Window
+{
+        int    DispLines, DispCols;
+        int    FirstVisRow, FirstVisCol;
+        int    nLines, nCols;
+        int    CursorRow, CursorCol;
+       tRichText_Line  *FirstLine;
+       tRichText_Line  *FirstVisLine;
+       tColour DefaultFG;
+       tColour DefaultBG;
+       tFont   *Font;
+       
+       short   LineHeight;
+} tRichText_Window;
+
+// === PROTOTYPES ===
+ int   Renderer_RichText_Init(void);
+tWindow        *Renderer_RichText_Create(int Flags);
+void   Renderer_RichText_Redraw(tWindow *Window);
+ int   Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void *Data);
+ int   Renderer_RichText_HandleIPC_WriteLine(tWindow *Window, size_t Len, const void *Data);
+ int   Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
+
+// === GLOBALS ===
+tWMRenderer    gRenderer_RichText = {
+       .Name = "RichText",
+       .CreateWindow   = Renderer_RichText_Create,
+       .Redraw         = Renderer_RichText_Redraw,
+       .HandleMessage  = Renderer_RichText_HandleMessage,
+       .nIPCHandlers = N_IPC_RICHTEXT,
+       .IPCHandlers = {
+               [IPC_RICHTEXT_SETATTR] = Renderer_RichText_HandleIPC_SetAttr,
+               [IPC_RICHTEXT_WRITELINE] = Renderer_RichText_HandleIPC_WriteLine
+       }
+};
+
+// === CODE ===
+int Renderer_RichText_Init(void)
+{
+       WM_RegisterRenderer(&gRenderer_RichText);       
+       return 0;
+}
+
+tWindow *Renderer_RichText_Create(int Flags)
+{
+       tRichText_Window        *info;
+       tWindow *ret = WM_CreateWindowStruct( sizeof(*info) );
+       if(!ret)        return NULL;
+       info = ret->RendererInfo;
+       
+       // Initialise font (get an idea of dimensions)
+       int h;
+       WM_Render_GetTextDims(NULL, "yY!", 3, NULL, &h);
+       info->LineHeight = h;
+       
+       return ret;
+}
+
+static inline int Renderer_RichText_RenderText_Act(tWindow *Window, tRichText_Window *info, int X, int Row, const char *Text, int Bytes, tColour FG, tColour BG, int Flags)
+{
+        int    rwidth;
+       // TODO: Fill only what is needed? What about the rest of the line?
+       WM_Render_DrawRect(Window, X, Row*info->LineHeight,
+               Window->W - X, info->LineHeight,
+               BG
+               );
+       // TODO: Bold, Italic, Underline
+       rwidth = WM_Render_DrawText(Window,
+               X, Row*info->LineHeight,
+               Window->W - X, info->LineHeight,
+               info->Font, FG,
+               Text, Bytes
+               );
+       return rwidth;
+}
+
+void Renderer_RichText_RenderText(tWindow *Window, int Line, const char *Text)
+{
+       tRichText_Window        *info = Window->RendererInfo;
+       tColour fg = info->DefaultFG;
+       tColour bg = info->DefaultBG;
+        int    flagset = 0;
+        int    bRender = 0;
+        int    curx = 0;
+       const char      *oldtext = Text;
+       
+       for( int i = 0; curx < Window->W; i ++ )
+       {
+               char    ch, flags;
+                int    len;
+
+               if( i == info->FirstVisCol )
+                       bRender = 1;
+
+               ch = *Text++;
+               if( ch == 0 )   break;
+
+               // Not an escape - move along
+               if( ch > 4 )
+                       continue ;              
+
+               if( bRender ) {
+                       // Render previous characters
+                       curx += Renderer_RichText_RenderText_Act(Window, info, curx, Line,
+                               oldtext, Text - oldtext - 1, fg, bg, flagset);
+                       if( curx >= Window->W )
+                               break;
+               }
+               oldtext = Text;
+               switch(ch)
+               {
+               case 1: // FG Select (\1 RRGGBB)
+                       if( sscanf(Text, "%6x%n", &fg, &len) != 1 || len != 6 ) {
+                               // Bad client
+                               _SysDebug("foreground scanf failed - len=%i", len);
+                               len = 0;
+                       }
+                       Text += len;
+                       oldtext = Text;
+                       _SysDebug("FG update to %x", fg);
+                       break ;
+               case 2: // BG Select (\2 RRGGBB)
+                       if( sscanf(Text, "%6x%n", &bg, &len) != 1 || len != 6 ) {
+                               // Bad client
+                               _SysDebug("background scanf failed - len=%i", len);
+                               len = 0;
+                       }
+                       Text += len;
+                       oldtext = Text;
+                       _SysDebug("BG update to %x", bg);
+                       break ;
+               case 3: // Flagset (0,it,uline,bold)
+                       if( sscanf(Text, "%1hhx%n", &flags, &len) != 1 || len != 1 ) {
+                               // Bad client
+                               _SysDebug("Flagset scanf failed - len=%i", len);
+                       }
+                       flagset = flags & 7;
+                       Text += len;
+                       oldtext = Text;
+                       break ;
+               case 4: // Escape (do nothing)
+                       Text ++;
+                       // NOTE: No update to oldtext
+                       break;
+               default: // Error.
+                       break;
+               }
+       }
+       curx += Renderer_RichText_RenderText_Act(Window, info, curx,
+               Line, oldtext, Text - oldtext + 1, fg, bg, flagset);
+       WM_Render_DrawRect(Window, curx, Line * info->LineHeight,
+               Window->W - curx, info->LineHeight, info->DefaultBG);
+}
+
+void Renderer_RichText_Redraw(tWindow *Window)
+{
+       tRichText_Window        *info = Window->RendererInfo;
+        int    i;
+       tRichText_Line  *line = info->FirstVisLine;
+       
+       if( !line ) {
+               line = info->FirstLine;
+               while(line && line->Num < info->FirstVisRow )
+                       line = line->Next;
+               info->FirstVisLine = line;
+       }
+       while( line && line->Prev && line->Prev->Num > info->FirstVisRow )
+               line = line->Prev;
+
+       for( i = 0; i < info->DispLines && line; i ++ )
+       {
+               if( i >= info->nLines - info->FirstVisRow )
+                       break;
+               // TODO: Dirty rectangles?
+               WM_Render_FillRect(Window,
+                       0, i*info->LineHeight,
+                       Window->W, info->LineHeight,
+                       info->DefaultBG
+                       );
+               if( line->Num > info->FirstVisRow + i )
+                       continue ;
+               // TODO: Horizontal scrolling?
+               // TODO: Formatting
+               
+               // Formatted text out
+               Renderer_RichText_RenderText(Window, i, line->Data);
+               _SysDebug("RichText: %p - Render %i '%.*s'", Window,
+                       line->Num, line->ByteLength, line->Data);
+
+               line = line->Next;
+       }
+       // Clear out i -- info->DispLines
+       _SysDebug("RichText: %p - Clear %i px lines with %06x starting at %i",
+               Window, (info->DispLines-i)*info->LineHeight, info->DefaultBG, i*info->LineHeight);
+       WM_Render_FillRect(Window,
+               0, i*info->LineHeight,
+               Window->W, (info->DispLines-i)*info->LineHeight,
+               info->DefaultBG
+               );
+}
+
+int Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void *Data)
+{
+       tRichText_Window        *info = Window->RendererInfo;
+       const struct sRichTextIPC_SetAttr *msg = Data;
+       if(Len < sizeof(*msg))  return -1;
+
+       _SysDebug("RichText Attr %i set to %x", msg->Attr, msg->Value);
+       switch(msg->Attr)
+       {
+       case _ATTR_DEFBG:
+               info->DefaultBG = msg->Value;
+               break;
+       case _ATTR_DEFFG:
+               info->DefaultFG = msg->Value;
+               break;
+       case _ATTR_SCROLL:
+               // TODO: Set scroll flag
+               break;
+       case _ATTR_LINECOUNT:
+               info->nLines = msg->Value;
+               break;
+       }
+       
+       return 0;
+}
+
+int Renderer_RichText_HandleIPC_WriteLine(tWindow *Window, size_t Len, const void *Data)
+{
+       tRichText_Window        *info = Window->RendererInfo;
+       const struct sRichTextIPC_WriteLine     *msg = Data;
+       if( Len < sizeof(*msg) )        return -1;
+       if( msg->Line >= info->nLines ) return 1;       // Bad count
+
+       tRichText_Line  *line = info->FirstLine;
+       tRichText_Line  *prev = NULL;
+       while(line && line->Num < msg->Line)
+               prev = line, line = line->Next;
+       if( !line || line->Num > msg->Line )
+       {
+               // New line!
+               // Round up to 32
+                int    space = ((Len - sizeof(*msg)) + 32-1) & ~(32-1);
+               tRichText_Line  *new = malloc(sizeof(*line) + space);
+               // TODO: Bookkeeping on how much memory each window uses
+               new->Next = line;
+               new->Prev = prev;
+               new->Num = msg->Line;
+               new->Space = space;
+               if(new->Prev)   new->Prev->Next = new;
+               else    info->FirstLine = new;
+               if(new->Next)   new->Next->Prev = new;
+               line = new;
+       }
+       else if( line->Space < Len - sizeof(*msg) )
+       {
+               // Need to allocate more space
+                int    space = ((Len - sizeof(*msg)) + 32-1) & ~(32-1);
+               tRichText_Line *new = realloc(line, space);
+               // TODO: Bookkeeping on how much memory each window uses
+               new->Space = space;
+
+               if(new->Prev)   new->Prev->Next = new;
+               else    info->FirstLine = new;
+               if(new->Next)   new->Next->Prev = new;
+               line = new;
+       }
+       else
+       {
+               // It fits :)
+       }
+       line->ByteLength = Len - sizeof(*msg);
+       memcpy(line->Data, msg->LineData, Len - sizeof(*msg));
+       
+       return  0;
+}
+
+int Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
+{
+       tRichText_Window        *info = Target->RendererInfo;
+       switch(Msg)
+       {
+       case WNDMSG_RESIZE: {
+               const struct sWndMsg_Resize *msg = Data;
+               if(Len < sizeof(*msg))  return -1;
+               info->DispLines = msg->H / info->LineHeight;
+               return 1; }
+       }
+       return 0;
+}
index 46b3198..49f1f64 100644 (file)
@@ -26,10 +26,15 @@ void        Widget_UpdateDimensions(tElement *Element);
 void   Widget_UpdatePosition(tElement *Element);
 // --- Messages
 tElement       *Widget_GetElementById(tWidgetWin *Info, uint32_t ID);
-void   Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg);
-void   Widget_SetFlags(tWidgetWin *Info, int Len, const tWidgetMsg_SetFlags *Msg);
-void   Widget_SetSize(tWidgetWin *Info, int Len, const tWidgetMsg_SetSize *Msg);
-void   Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg);
+ int   Widget_IPC_Create(tWindow *Win, size_t Len, const void *Data);
+ int   Widget_IPC_NewWidgetSubwin(tWindow *Win, size_t Len, const void *Data);
+// int Widget_IPC_Delete(tWindow *Win, size_t Len, const void *Data);
+ int   Widget_IPC_SetFocus(tWindow *Win, size_t Len, const void *Data);
+ int   Widget_IPC_SetFlags(tWindow *Win, size_t Len, const void *Data);
+ int   Widget_IPC_SetSize(tWindow *Win, size_t Len, const void *Data);
+ int   Widget_IPC_SetText(tWindow *Win, size_t Len, const void *Data);
+ int   Widget_IPC_GetText(tWindow *Win, size_t Len, const void *Data);
+// int Widget_IPC_SetColour(tWindow *Win, size_t Len, const void *Data);
  int   Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
 
 // === GLOBALS ===
@@ -37,7 +42,17 @@ tWMRenderer  gRenderer_Widget = {
        .Name = "Widget",
        .CreateWindow = Renderer_Widget_Create,
        .Redraw = Renderer_Widget_Redraw,
-       .HandleMessage = Renderer_Widget_HandleMessage
+       .HandleMessage = Renderer_Widget_HandleMessage,
+       .nIPCHandlers = N_IPC_WIDGET,
+       .IPCHandlers = {
+               [IPC_WIDGET_CREATE] = Widget_IPC_Create,
+               [IPC_WIDGET_CREATESUBWIN] = Widget_IPC_NewWidgetSubwin,
+               [IPC_WIDGET_SETFOCUS] = Widget_IPC_SetFocus,
+               [IPC_WIDGET_SETFLAGS] = Widget_IPC_SetFlags,
+               [IPC_WIDGET_SETSIZE] = Widget_IPC_SetSize,
+               [IPC_WIDGET_SETTEXT] = Widget_IPC_SetText,
+               [IPC_WIDGET_GETTEXT] = Widget_IPC_GetText,
+       }
 };
        
 // --- Element callbacks
@@ -87,7 +102,7 @@ tWindow      *Renderer_Widget_Create(int Flags)
        tWidgetWin      *info;
         int    eletable_size = DEFAULT_ELETABLE_SIZE;
 
-       _SysDebug("Renderer_Widget_Create: (Flags = 0x%x)", Flags);
+       //_SysDebug("Renderer_Widget_Create: (Flags = 0x%x)", Flags);
 
        // TODO: Use `Flags` as default element count?
        // - Actaully, it's taken by the root ele flags
@@ -214,14 +229,14 @@ void Widget_UpdateDimensions(tElement *Element)
        else
                fullCross = Element->CachedH - Element->PaddingT - Element->PaddingB;
 
-       _SysDebug("%i (p=%i) - WxH=%ix%i",
-               Element->ID, (Element->Parent ? Element->Parent->ID : -1),
-               Element->CachedW, Element->CachedH
-               );
-       _SysDebug("  %s dynWith = %i, fullCross = %i",
-               (Element->Flags & ELEFLAG_VERTICAL ? "Vert" : "Horiz"),
-               dynWith, fullCross
-               );
+       //_SysDebug("%i (p=%i) - WxH=%ix%i",
+       //      Element->ID, (Element->Parent ? Element->Parent->ID : -1),
+       //      Element->CachedW, Element->CachedH
+       //      );
+       //_SysDebug("  %s dynWith = %i, fullCross = %i",
+       //      (Element->Flags & ELEFLAG_VERTICAL ? "Vert" : "Horiz"),
+       //      dynWith, fullCross
+       //      );
        
        // Pass 2 - Set sizes and recurse
        for( child = Element->FirstChild; child; child = child->NextSibling )
@@ -423,61 +438,33 @@ tElement *Widget_GetElementById(tWidgetWin *Info, uint32_t ID)
        return ele;
 }
 
-// --- Message Handlers ---
-void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg)
+tElement *Widget_int_Create(tWidgetWin *Info, tElement *Parent, int ID, int Type, int Flags)
 {
-       const int       max_debugname_len = Len - sizeof(tWidgetMsg_Create);
-       tElement        *parent, *new;
-
-       // Sanity check
-       if( Len < sizeof(*Msg) )
-               return ;
-       if( strnlen(Msg->DebugName, max_debugname_len) == max_debugname_len )
-               return ;
-       
-       _SysDebug("Widget_NewWidget (%i %i Type %i Flags 0x%x)",
-               Msg->Parent, Msg->NewID, Msg->Type, Msg->Flags);
-       
-       if(Msg->Type >= ciWM_NumWidgetTypes)
-       {
-               _SysDebug("Widget_NewWidget - Bad widget type %i", Msg->Type);
-               return ;
-       }
-
-       // Create
-       parent = Widget_GetElementById(Info, Msg->Parent);
-       if(!parent)
-       {
-               _SysDebug("Widget_NewWidget - Bad parent ID %i", Msg->Parent);
-               return ;
-       }
-
-       // Check if the ID is already in use
-       if( Widget_GetElementById(Info, Msg->NewID) )
-               return ;
+       if( Widget_GetElementById(Info, ID) )
+               return NULL;
 
        // Create new element
-       new = calloc(sizeof(tElement), 1);
-       new->Window = parent->Window;
-       new->ID = Msg->NewID;
-       new->Type = Msg->Type;
-       new->Parent = parent;
-       new->Flags = Msg->Flags;
+       tElement *new = calloc(sizeof(tElement), 1);
+       new->Window = Parent->Window;
+       new->ID = ID;
+       new->Type = Type;
+       new->Parent = Parent;
+       new->Flags = Flags;
        new->PaddingT = 2;
        new->PaddingB = 2;
        new->PaddingL = 2;
        new->PaddingR = 2;
        new->CachedX = -1;
        
-       if( gaWM_WidgetTypes[new->Type]->Init )
-               gaWM_WidgetTypes[new->Type]->Init(new);
+       if( gaWM_WidgetTypes[Type]->Init )
+               gaWM_WidgetTypes[Type]->Init(new);
        
        // Add to parent's list
-       if(parent->LastChild)
-               parent->LastChild->NextSibling = new;
+       if(Parent->LastChild)
+               Parent->LastChild->NextSibling = new;
        else
-               parent->FirstChild = new;
-       parent->LastChild = new;
+               Parent->FirstChild = new;
+       Parent->LastChild = new;
 
        // Add to info
        {
@@ -488,8 +475,8 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg
                else
                        Info->ElementTable[new->ID % Info->TableSize] = new;
        }
-
-       Widget_UpdateMinDims(parent);
+       
+       return new;
 }
 
 void Widget_SetFocus(tWidgetWin *Info, tElement *Ele)
@@ -499,47 +486,130 @@ void Widget_SetFocus(tWidgetWin *Info, tElement *Ele)
        Info->FocusedElement = Ele;
 }
 
-void Widget_SetFlags(tWidgetWin *Info, int Len, const tWidgetMsg_SetFlags *Msg)
+
+// --- Message Handlers ---
+int Widget_IPC_Create(tWindow *Win, size_t Len, const void *Data)
+{
+       tWidgetWin      *Info = Win->RendererInfo;
+       const tWidgetIPC_Create *Msg = Data;
+       const int       max_debugname_len = Len - sizeof(*Msg);
+       tElement        *parent;
+
+       // Sanity check
+       if( Len < sizeof(*Msg) )
+               return -1;
+       if( strnlen(Msg->DebugName, max_debugname_len) == max_debugname_len )
+               return -1;
+       
+       _SysDebug("Widget_NewWidget (%i %i Type %i Flags 0x%x)",
+               Msg->Parent, Msg->NewID, Msg->Type, Msg->Flags);
+       
+       if(Msg->Type >= ciWM_NumWidgetTypes)
+       {
+               _SysDebug("Widget_NewWidget - Bad widget type %i", Msg->Type);
+               return 1;
+       }
+
+       // Create
+       parent = Widget_GetElementById(Info, Msg->Parent);
+       if(!parent)
+       {
+               _SysDebug("Widget_NewWidget - Bad parent ID %i", Msg->Parent);
+               return 1;
+       }
+
+       Widget_int_Create(Info, parent, Msg->NewID, Msg->Type, Msg->Flags);
+
+       Widget_UpdateMinDims(parent);
+       return 0;
+}
+
+int Widget_IPC_NewWidgetSubwin(tWindow *Win, size_t Len, const void *Data)
+{
+       tWidgetWin      *Info = Win->RendererInfo;
+       const tWidgetIPC_CreateSubWin   *Msg = Data;
+       const int       max_debugname_len = Len - sizeof(*Msg);
+       tElement        *parent, *new;
+
+       // Sanity check
+       if( Len < sizeof(*Msg) )
+               return -1;
+       if( strnlen(Msg->DebugName, max_debugname_len) == max_debugname_len )
+               return -1;
+       
+       parent = Widget_GetElementById(Info, Msg->Parent);
+       if(!parent)     return 1;
+       if( Widget_GetElementById(Info, Msg->NewID) )   return 1;
+       
+       new = Widget_int_Create(Info, parent, Msg->NewID, Msg->Type, Msg->Flags);
+       new->Data = WM_GetWindowByID(parent->Window, Msg->WindowHandle);
+       Widget_UpdateMinDims(parent);
+       return 0;
+}
+
+// TODO: Widget_IPC_Delete
+
+int Widget_IPC_SetFocus(tWindow *Win, size_t Len, const void *Data)
+{
+       tWidgetWin      *info = Win->RendererInfo;
+       tElement        *ele;
+       const tWidgetIPC_SetFocus       *msg = Data;
+       if(Len < sizeof(*msg))  return -1;
+       
+       ele = Widget_GetElementById(info, msg->WidgetID);
+       Widget_SetFocus(info, ele);
+       return 0;
+}
+
+int Widget_IPC_SetFlags(tWindow *Win, size_t Len, const void *Data)
 {
+       tWidgetWin *Info = Win->RendererInfo;
+       const tWidgetIPC_SetFlags       *Msg = Data;
        tElement        *ele;
        
        if( Len < sizeof(*Msg) )
-               return ;
+               return -1;
 
        _SysDebug("Widget_SetFlags: (%i 0x%x 0x%x)", Msg->WidgetID, Msg->Value, Msg->Mask);
        
        ele = Widget_GetElementById(Info, Msg->WidgetID);
-       if(!ele)        return;
+       if(!ele)        return 1;
 
        ele->Flags &= ~Msg->Mask;
        ele->Flags |= Msg->Value & Msg->Mask;
+       
+       return 0;
 }
 
-void Widget_SetSize(tWidgetWin *Info, int Len, const tWidgetMsg_SetSize *Msg)
+int Widget_IPC_SetSize(tWindow *Win, size_t Len, const void *Data)
 {
+       tWidgetWin      *Info = Win->RendererInfo;
+       const tWidgetIPC_SetSize        *Msg = Data;
        tElement        *ele;
        
        if( Len < sizeof(*Msg) )
-               return ;
+               return -1;
        
        ele = Widget_GetElementById(Info, Msg->WidgetID);
-       if(!ele)        return ;
+       if(!ele)        return 1;
        
        ele->FixedWith = Msg->Value;
+       return 0;
 }
 
-void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg)
+int Widget_IPC_SetText(tWindow *Win, size_t Len, const void *Data)
 {
+       tWidgetWin      *Info = Win->RendererInfo;
+       const tWidgetIPC_SetText        *Msg = Data;
        tElement        *ele;
        
        if( Len < sizeof(*Msg) + 1 )
-               return ;
+               return -1;
        if( Msg->Text[Len - sizeof(*Msg) - 1] != '\0' )
-               return ;
+               return -1;
 
        ele = Widget_GetElementById(Info, Msg->WidgetID);
-       if(!ele)        return ;
-
+       if(!ele)        return 1;
 
        if( gaWM_WidgetTypes[ele->Type]->UpdateText )
        {
@@ -550,22 +620,23 @@ void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg)
 //             if(ele->Text)   free(ele->Text);
 //             ele->Text = strdup(Msg->Text);
 //     }
+       return 0;
 }
 
-int Widget_GetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg)
+int Widget_IPC_GetText(tWindow *Win, size_t Len, const void *Data)
 {
+       tWidgetWin      *Info = Win->RendererInfo;
+       const tWidgetIPC_SetText        *Msg = Data;
        if( Len < sizeof(*Msg) )
-               return 0;
-       if( Len > sizeof(*Msg) )
-               return 1;       // Pass to user
+               return -1;
        
        const char      *text = NULL;
        tElement *ele = Widget_GetElementById(Info, Msg->WidgetID);
        if(ele)
                text = ele->Text;
        
-       char    buf[sizeof(tWidgetMsg_SetText) + strlen(text?text:"") + 1];
-       tWidgetMsg_SetText      *omsg = (void*)buf;
+       char    buf[sizeof(tWidgetIPC_SetText) + strlen(text?text:"") + 1];
+       tWidgetIPC_SetText      *omsg = (void*)buf;
        
        if( text ) {
                omsg->WidgetID = Msg->WidgetID;
@@ -576,7 +647,7 @@ int Widget_GetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg)
                omsg->Text[0] = 0;
        }
        
-       WM_SendMessage(Info->RootElement.Window, Info->RootElement.Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf);
+       WM_SendIPCReply(Win, IPC_WIDGET_GETTEXT, sizeof(buf), buf);
        return 0;
 }
 
@@ -685,43 +756,6 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void
                }
                return 0; }
 
-       // New Widget
-       case MSG_WIDGET_CREATE:
-               Widget_NewWidget(info, Len, Data);
-               return 0;
-
-       // Delete a widget
-       case MSG_WIDGET_DELETE:
-               _SysDebug("TODO: Implement MSG_WIDGET_DELETE");
-               return 0;
-
-       // Set focused widget
-       case MSG_WIDGET_SETFOCUS: {
-               tElement        *ele;
-               const tWidgetMsg_SetFocus       *msg = Data;
-               if(Len < sizeof(*msg))  return -1;
-               
-               ele = Widget_GetElementById(info, msg->WidgetID);
-               Widget_SetFocus(info, ele);
-               return 0; }
-
-       // Set Flags
-       case MSG_WIDGET_SETFLAGS:
-               Widget_SetFlags(info, Len, Data);
-               return 0;
-       
-       // Set length
-       case MSG_WIDGET_SETSIZE:
-               Widget_SetSize(info, Len, Data);
-               return 0;
-       
-       // Set text
-       case MSG_WIDGET_SETTEXT:
-               Widget_SetText(info, Len, Data);
-               return 0;
-       case MSG_WIDGET_GETTEXT:
-               return Widget_GetText(info, Len, Data);
-       
        // 
        default:
                return 1;       // Unhandled, pass to user
@@ -732,6 +766,7 @@ void Widget_Fire(tElement *Element)
 {
        tWidgetMsg_Fire msg;
        msg.WidgetID = Element->ID;
+       _SysDebug("Widget_Fire: Fire on %p %i", Element->Window, Element->ID);
        WM_SendMessage(Element->Window, Element->Window, MSG_WIDGET_FIRE, sizeof(msg), &msg);
 }
 
diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/subwin.c b/Usermode/Applications/axwin3_src/WM/renderers/widget/subwin.c
new file mode 100644 (file)
index 0000000..fcf196d
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Acess2 Window Manager v3
+ * - By John Hodge (thePowersGang)
+ * 
+ * renderer/widget/subwin.c
+ * - Embedded Window Widget Type
+ */
+#include <common.h>
+#include "./common.h"
+#include "./colours.h"
+
+void Widget_SubWin_Render(tWindow *Window, tElement *Element)
+{
+       // Ensure that child window is positioned relative to this window
+       WM_SetRelative(Element->Data, 1);
+       // Note: Doesn't actually render, but does poke the child window
+       WM_MoveWindow(Element->Data, Element->CachedX, Element->CachedY);
+       WM_ResizeWindow(Element->Data, Element->CachedW, Element->CachedH);
+}
+
+DEFWIDGETTYPE(ELETYPE_SUBWIN,
+       WIDGETTYPE_FLAG_NOCHILDREN,
+       .Render = Widget_SubWin_Render
+       )
index 5c08828..93e0318 100644 (file)
@@ -52,7 +52,7 @@ int ReadUTF8(const char *Input, uint32_t *Val)
        }
        
        // Four Byte
-       if( (*str & 0xF1) == 0xF0 ) {
+       if( (*str & 0xF8) == 0xF0 ) {
                *Val = (*str & 0x07) << 18;     // Upper 3 Bits
                str ++;
                if( (*str & 0xC0) != 0x80)      return -1;      // Validity check
index 3adb17d..60f2155 100644 (file)
@@ -38,7 +38,7 @@ void Video_Setup(void)
        
        // Open terminal
        #if 0
-       giTerminalFD = open(gsTerminalDevice, OPENFLAG_READ|OPENFLAG_WRITE);
+       giTerminalFD = _SysOpen(gsTerminalDevice, OPENFLAG_READ|OPENFLAG_WRITE);
        if( giTerminalFD == -1 )
        {
                fprintf(stderr, "ERROR: Unable to open '%s' (%i)\n", gsTerminalDevice, _errno);
@@ -48,8 +48,8 @@ void Video_Setup(void)
        giTerminalFD = 1;
        giTerminalFD_Input = 0;
        // Check that the console is a VT
-       // - ioctl(..., 0, NULL) returns the type, which should be 2
-       if( ioctl(1, 0, NULL) != 2 )
+       // - _SysIOCtl(..., 0, NULL) returns the type, which should be 2
+       if( _SysIOCtl(1, 0, NULL) != 2 )
        {
                fprintf(stderr, "stdout is not an Acess VT, can't start");
                _SysDebug("stdout is not an Acess VT, can't start");
@@ -59,22 +59,22 @@ void Video_Setup(void)
        
        // Set mode to video
        tmpInt = TERM_MODE_FB;
-       ioctl( giTerminalFD, TERM_IOCTL_MODETYPE, &tmpInt );
+       _SysIOCtl( giTerminalFD, TERM_IOCTL_MODETYPE, &tmpInt );
        
        // Get dimensions
-       giScreenWidth = ioctl( giTerminalFD, TERM_IOCTL_WIDTH, NULL );
-       giScreenHeight = ioctl( giTerminalFD, TERM_IOCTL_HEIGHT, NULL );
+       giScreenWidth = _SysIOCtl( giTerminalFD, TERM_IOCTL_WIDTH, NULL );
+       giScreenHeight = _SysIOCtl( giTerminalFD, TERM_IOCTL_HEIGHT, NULL );
 
        giVideo_LastDirtyLine = giScreenHeight;
        
        // Force VT to be shown
-       ioctl( giTerminalFD, TERM_IOCTL_FORCESHOW, NULL );
+       _SysIOCtl( giTerminalFD, TERM_IOCTL_FORCESHOW, NULL );
        
        // Create local framebuffer (back buffer)
        gpScreenBuffer = malloc( giScreenWidth*giScreenHeight*4 );
 
        // Set cursor position and bitmap
-       ioctl(giTerminalFD, TERM_IOCTL_SETCURSORBITMAP, &cCursorBitmap);
+       _SysIOCtl(giTerminalFD, TERM_IOCTL_SETCURSORBITMAP, &cCursorBitmap);
        Video_SetCursorPos( giScreenWidth/2, giScreenHeight/2 );
 }
 
@@ -87,9 +87,9 @@ void Video_Update(void)
 
        _SysDebug("Video_Update - Updating lines %i to %i (0x%x+0x%x px)",
                giVideo_FirstDirtyLine, giVideo_LastDirtyLine, ofs, size);
-       seek(giTerminalFD, ofs*4, 1);
-       _SysDebug("Video_Update - Sending");
-       write(giTerminalFD, gpScreenBuffer+ofs, size*4);
+       _SysSeek(giTerminalFD, ofs*4, 1);
+       _SysDebug("Video_Update - Sending FD %i %p 0x%x", giTerminalFD, gpScreenBuffer+ofs, size*4);
+       _SysWrite(giTerminalFD, gpScreenBuffer+ofs, size*4);
        _SysDebug("Video_Update - Done");
        giVideo_FirstDirtyLine = 0;
        giVideo_LastDirtyLine = 0;
@@ -103,7 +103,7 @@ void Video_SetCursorPos(short X, short Y)
        } pos;
        pos.x = giVideo_CursorX = X;
        pos.y = giVideo_CursorY = Y;
-       ioctl(giTerminalFD, TERM_IOCTL_GETSETCURSOR, &pos);
+       _SysIOCtl(giTerminalFD, TERM_IOCTL_GETSETCURSOR, &pos);
 }
 
 void Video_FillRect(int X, int Y, int W, int H, uint32_t Colour)
@@ -132,35 +132,50 @@ void Video_FillRect(int X, int Y, int W, int H, uint32_t Colour)
 void Video_Blit(uint32_t *Source, short DstX, short DstY, short W, short H)
 {
        uint32_t        *buf;
+       short   drawW = W;
 
        if( DstX >= giScreenWidth)      return ;
        if( DstY >= giScreenHeight)     return ;
-       // TODO: Handle -ve X/Y by clipping
-       if( DstX < 0 || DstY < 0 )      return ;
-       // TODO: Handle out of bounds by clipping too
-       if( DstX + W > giScreenWidth )  return;
+       // Drawing oob to left/top, clip
+       if( DstX < 0 ) {
+               Source += -DstX;
+               drawW -= -DstX;
+               DstX = 0;
+       }
+       if( DstY < 0 ) {
+               Source += (-DstY)*W;
+               H -= -DstY;
+               DstY = 0;
+       }
+       if( drawW < 0 ) return ;
+       // Drawing oob to the right, clip
+       if( DstX + drawW > giScreenWidth ) {
+               //int oldw = drawW;
+               drawW = giScreenWidth - DstX;
+       }
        if( DstY + H > giScreenHeight )
-               H = giScreenWidth - DstY;
+               H = giScreenHeight - DstY;
 
        if( W <= 0 || H <= 0 )  return;
 
-       if( DstX < giVideo_FirstDirtyLine )
+       if( DstY < giVideo_FirstDirtyLine )
                giVideo_FirstDirtyLine = DstY;
        if( DstY + H > giVideo_LastDirtyLine )
                giVideo_LastDirtyLine = DstY + H;
        
        buf = gpScreenBuffer + DstY*giScreenWidth + DstX;
-       if(W != giScreenWidth)
+       if(drawW != giScreenWidth || W != giScreenWidth)
        {
                while( H -- )
                {
-                       memcpy(buf, Source, W*4);
+                       memcpy(buf, Source, drawW*4);
                        Source += W;
                        buf += giScreenWidth;
                }
        }
        else
        {
+               // Only valid if copying full scanlines on both ends
                memcpy(buf, Source, giScreenWidth*H*4);
        }
 }
index 2478151..f9592db 100644 (file)
@@ -15,6 +15,8 @@
 
 // === IMPORTS ===
 extern void    IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int Msg, int Len, const void *Data);
+extern void    IPC_SendReply(tIPC_Client *Client, uint32_t WinID, int MsgID, size_t Len, const void *Data);
+extern tWindow *IPC_int_GetWindow(tIPC_Client *Client, uint32_t ID);
 
 // === GLOBALS ===
 tWMRenderer    *gpWM_Renderers;
@@ -92,6 +94,11 @@ tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int
        return ret;
 }
 
+tWindow *WM_GetWindowByID(tWindow *Requester, uint32_t ID)
+{
+       return IPC_int_GetWindow(Requester->Client, ID);
+}
+
 tWindow *WM_CreateWindowStruct(size_t ExtraSize)
 {
        tWindow *ret;
@@ -133,7 +140,34 @@ void WM_RaiseWindow(tWindow *Window)
        Window->PrevSibling = parent->LastChild;
        Window->NextSibling = NULL;
        parent->LastChild = Window;
+       
+       _SysDebug("Raised %p", Window);
+}
+
+/*
+void WM_RaiseWindow(tWindow *Window)
+{
+       // Move to the last render position (move to top)
+       while(Window && Window->Parent)
+       {
+               if( Window->NextSibling )
+               {
+                       // remove
+                       if( Window->PrevSibling )
+                               Window->PrevSibling->NextSibling = Window->NextSibling;
+                       Window->NextSibling->PrevSibling = Window->PrevSibling;
+                       // Mutate self
+                       Window->PrevSibling = Window->Parent->LastChild;
+                       Window->NextSibling = NULL;
+                       // re-add
+                       Window->PrevSibling->NextSibling = Window;
+                       Window->Parent->LastChild = Window;
+               }
+               _SysDebug("WM_RaiseWindow: Raised %p", Window);
+               Window = Window->Parent;
+       }
 }
+*/
 
 void WM_FocusWindow(tWindow *Destination)
 {
@@ -144,19 +178,21 @@ void WM_FocusWindow(tWindow *Destination)
        if( Destination && !(Destination->Flags & WINFLAG_SHOW) )
                return ;
        
-       _msg.Val = 0;
-       WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_FOCUS, sizeof(_msg), &_msg);
-       _msg.Val = 1;
-       WM_SendMessage(NULL, Destination, WNDMSG_FOCUS, sizeof(_msg), &_msg);
-       
+       if( gpWM_FocusedWindow )
+       {
+               _msg.Val = 0;
+               WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_FOCUS, sizeof(_msg), &_msg);
+       }
+       if( Destination )
+       {
+               _msg.Val = 1;
+               WM_SendMessage(NULL, Destination, WNDMSG_FOCUS, sizeof(_msg), &_msg);
+       }
+               
        WM_Invalidate(gpWM_FocusedWindow);
        WM_Invalidate(Destination);
-       gpWM_FocusedWindow = Destination;
 
-
-       // Get the owner of the focused window  
-//     while(Destination && Destination->Owner)        Destination = Destination->Owner;
-//     gpWM_HilightedWindow = Destination;
+       gpWM_FocusedWindow = Destination;
 }
 
 
@@ -172,8 +208,10 @@ void WM_ShowWindow(tWindow *Window, int bShow)
        WM_SendMessage(NULL, Window, WNDMSG_SHOW, sizeof(_msg), &_msg);
 
        // Update the flag
-       if(bShow)
+       if(bShow) {
                Window->Flags |= WINFLAG_SHOW;
+               _SysDebug("Window %p shown", Window);
+       }
        else
        {
                Window->Flags &= ~WINFLAG_SHOW;
@@ -186,6 +224,7 @@ void WM_ShowWindow(tWindow *Window, int bShow)
                        free(Window->RenderBuffer);
                        Window->RenderBuffer = NULL;
                }
+               _SysDebug("Window %p hidden", Window);
        }
        
        WM_Invalidate(Window);
@@ -210,17 +249,52 @@ void WM_DecorateWindow(tWindow *Window, int bDecorate)
        WM_Invalidate(Window);
 }
 
+void WM_SetRelative(tWindow *Window, int bRelativeToParent)
+{
+//     _SysDebug("WM_SetRelative: (%p{Parent=%p},%i)", Window, Window->Parent, bRelativeToParent);
+       // No meaning if no parent
+       if( !Window->Parent )
+               return ;
+
+       // Check that the flag is changing
+       if( !!bRelativeToParent == !!(Window->Flags & WINFLAG_RELATIVE) )
+               return ;
+
+       if( bRelativeToParent ) {
+               // Set
+               Window->Flags |= WINFLAG_RELATIVE;
+               WM_MoveWindow(Window, Window->X, Window->Y);
+       }
+       else {
+               // Clear
+               Window->Flags &= ~WINFLAG_RELATIVE;
+               WM_MoveWindow(Window, Window->X - Window->Parent->X, Window->Y - Window->Parent->Y);
+       }
+}
+
 int WM_MoveWindow(tWindow *Window, int X, int Y)
 {
+//     _SysDebug("Move %p to (%i,%i)", Window, X, Y);
        // Clip coordinates
        if(X + Window->W < 0)   X = -Window->W + 1;
        if(Y + Window->H < 0)   Y = -Window->H + 1;
        if(X >= giScreenWidth)  X = giScreenWidth - 1;
        if(Y >= giScreenHeight) Y = giScreenHeight - 1;
        
+       // If relative to the parent, extra checks
+       if( (Window->Flags & WINFLAG_RELATIVE) && Window->Parent )
+       {
+               if( X > Window->Parent->W )     return 1;
+               if( Y > Window->Parent->H )     return 1;
+       }
+       // TODO: Re-sanitise
+
+       _SysDebug("WM_MoveWindow: (%i,%i)", X, Y);
        Window->X = X;  Window->Y = Y;
 
-       WM_Invalidate(Window);
+       // Mark up the tree that a child window has changed     
+       while( (Window = Window->Parent) )
+               Window->Flags &= ~WINFLAG_CHILDCLEAN;
 
        return 0;
 }
@@ -231,6 +305,10 @@ int WM_ResizeWindow(tWindow *Window, int W, int H)
        if(Window->X + W < 0)   Window->X = -W + 1;
        if(Window->Y + H < 0)   Window->Y = -H + 1;
 
+       if( Window->W == W && Window->H == H )
+               return 0;
+
+       _SysDebug("WM_Resizeindow: %ix%i", W, H);
        Window->W = W;  Window->H = H;
 
        if(Window->RenderBuffer) {
@@ -251,12 +329,20 @@ int WM_ResizeWindow(tWindow *Window, int W, int H)
 
 int WM_SendMessage(tWindow *Source, tWindow *Dest, int Message, int Length, const void *Data)
 {
-       if(Dest == NULL)        return -2;
-       if(Length > 0 && Data == NULL)  return -1;
+//     _SysDebug("WM_SendMessage: (%p, %p, %i, %i, %p)", Source, Dest, Message, Length, Data);
+       if(Dest == NULL) {
+               _SysDebug("WM_SendMessage: NULL destination from %p", __builtin_return_address(0));
+               return -2;
+       }
+       if(Length > 0 && Data == NULL) {
+               _SysDebug("WM_SendMessage: non-zero length and NULL data");
+               return -1;
+       }
 
        if( Decorator_HandleMessage(Dest, Message, Length, Data) != 1 )
        {
                // TODO: Catch errors from ->HandleMessage
+//             _SysDebug("WM_SendMessage: Decorator grabbed message?");
                return 0;
        }
        
@@ -264,11 +350,13 @@ int WM_SendMessage(tWindow *Source, tWindow *Dest, int Message, int Length, cons
        if( Dest->Renderer->HandleMessage(Dest, Message, Length, Data) != 1 )
        {
                // TODO: Catch errors from ->HandleMessage
+//             _SysDebug("WM_SendMessage: Renderer grabbed message?");
                return 0;
        }
 
        // TODO: Implement message masking
 
+       // Dispatch to client
        if(Dest->Client)
        {
                uint32_t        src_id;
@@ -283,16 +371,23 @@ int WM_SendMessage(tWindow *Source, tWindow *Dest, int Message, int Length, cons
                        src_id = Source->ID;
                }
                
+//             _SysDebug("WM_SendMessage: IPC Dispatch");
                IPC_SendWMMessage(Dest->Client, src_id, Dest->ID, Message, Length, Data);
        }       
 
        return 1;
 }
 
+int WM_SendIPCReply(tWindow *Window, int Message, size_t Length, const void *Data)
+{
+       IPC_SendReply(Window->Client, Window->ID, Message, Length, Data);
+       return 0;
+}
+
 void WM_Invalidate(tWindow *Window)
 {
        if(!Window)     return ;
-       _SysDebug("Invalidating %p", Window);
+//     _SysDebug("Invalidating %p", Window);
        // Don't invalidate twice (speedup)
 //     if( !(Window->Flags & WINFLAG_CLEAN) )  return;
 
@@ -313,13 +408,24 @@ void WM_int_UpdateWindow(tWindow *Window)
        if( !(Window->Flags & WINFLAG_SHOW) )
                return ;
        
+       if( (Window->Flags & WINFLAG_RELATIVE) && Window->Parent )
+       {
+               Window->RealX = Window->Parent->RealX + Window->Parent->BorderL + Window->X;
+               Window->RealY = Window->Parent->RealY + Window->Parent->BorderT + Window->Y;
+       }
+       else
+       {
+               Window->RealX = Window->X;
+               Window->RealY = Window->Y;
+       }
+       
        // Render
        if( !(Window->Flags & WINFLAG_CLEAN) )
        {
                // Calculate RealW/RealH
                if( !(Window->Flags & WINFLAG_NODECORATE) )
                {
-                       _SysDebug("Applying decorations to %p", Window);
+                       //_SysDebug("Applying decorations to %p", Window);
                        Decorator_UpdateBorderSize(Window);
                        Window->RealW = Window->BorderL + Window->W + Window->BorderR;
                        Window->RealH = Window->BorderT + Window->H + Window->BorderB;
@@ -334,7 +440,7 @@ void WM_int_UpdateWindow(tWindow *Window)
                        Window->RealW = Window->W;
                        Window->RealH = Window->H;
                }
-               
+
                Window->Renderer->Redraw(Window);
                Window->Flags |= WINFLAG_CLEAN;
        }
@@ -361,19 +467,31 @@ void WM_int_BlitWindow(tWindow *Window)
        // Ignore hidden windows
        if( !(Window->Flags & WINFLAG_SHOW) )
                return ;
+       
+       // Duplicated position update to handle window moving
+       if( (Window->Flags & WINFLAG_RELATIVE) && Window->Parent )
+       {
+               Window->RealX = Window->Parent->RealX + Window->Parent->BorderL + Window->X;
+               Window->RealY = Window->Parent->RealY + Window->Parent->BorderT + Window->Y;
+       }
+       else
+       {
+               Window->RealX = Window->X;
+               Window->RealY = Window->Y;
+       }
 
-//     _SysDebug("Blit %p to (%i,%i) %ix%i", Window, Window->X, Window->Y, Window->RealW, Window->RealH);
-       Video_Blit(Window->RenderBuffer, Window->X, Window->Y, Window->RealW, Window->RealH);
+//     _SysDebug("Blit %p (%p) to (%i,%i) %ix%i", Window, Window->RenderBuffer,
+//             Window->RealX, Window->RealY, Window->RealW, Window->RealH);
+       Video_Blit(Window->RenderBuffer, Window->RealX, Window->RealY, Window->RealW, Window->RealH);
        
        if( Window == gpWM_FocusedWindow && Window->CursorW )
        {
                Video_FillRect(
-                       Window->X + Window->BorderL + Window->CursorX,
-                       Window->Y + Window->BorderT + Window->CursorY,
+                       Window->RealX + Window->BorderL + Window->CursorX,
+                       Window->RealY + Window->BorderT + Window->CursorY,
                        Window->CursorW, Window->CursorH,
                        0x000000
                        );
-                       
        }
 
        for( child = Window->FirstChild; child; child = child->NextSibling )
index 5f6ef85..858862b 100644 (file)
@@ -34,8 +34,8 @@ tWindow *WM_int_GetWindowAtPos(int X, int Y)
                for(win = ret->FirstChild; win; win = win->NextSibling)
                {
                        if( !(win->Flags & WINFLAG_SHOW) )      continue ;
-                       if( X < win->X || X >= win->X + win->RealW )    continue;
-                       if( Y < win->Y || Y >= win->Y + win->RealH )    continue;
+                       if( X < win->RealX || X >= win->RealX + win->RealW )    continue;
+                       if( Y < win->RealY || Y >= win->RealY + win->RealH )    continue;
                        next_win = win; // Overwrite as we want the final rendered window
                }
        }
@@ -49,8 +49,8 @@ void WM_Input_MouseMoved(int OldX, int OldY, int NewX, int NewY)
        struct sWndMsg_MouseMove        msg;
        
        win = WM_int_GetWindowAtPos(OldX, OldY);
-       msg.X = NewX - win->X - win->BorderL;
-       msg.Y = NewY - win->Y - win->BorderT;
+       msg.X = NewX - win->RealX - win->BorderL;
+       msg.Y = NewY - win->RealY - win->BorderT;
        msg.dX = NewX - OldX;
        msg.dY = NewY - OldY;
        WM_SendMessage(NULL, win, WNDMSG_MOUSEMOVE, sizeof(msg), &msg);
@@ -64,8 +64,8 @@ void WM_Input_MouseMoved(int OldX, int OldY, int NewX, int NewY)
        // TODO: Send mouseup to match mousedown if the cursor moves out of a window?
 
        win = newWin;
-       msg.X = NewX - win->X - win->BorderL;
-       msg.Y = NewY - win->Y - win->BorderT;
+       msg.X = NewX - win->RealX - win->BorderL;
+       msg.Y = NewY - win->RealY - win->BorderT;
        msg.dX = NewX - OldX;
        msg.dY = NewY - OldY;
        WM_SendMessage(NULL, win, WNDMSG_MOUSEMOVE, sizeof(msg), &msg);
@@ -75,8 +75,8 @@ void WM_Input_int_SendBtnMsg(tWindow *Win, int X, int Y, int Index, int Pressed)
 {
        struct sWndMsg_MouseButton      msg;    
 
-       msg.X = X - Win->X - Win->BorderL;
-       msg.Y = Y - Win->Y - Win->BorderT;
+       msg.X = X - Win->RealX - Win->BorderL;
+       msg.Y = Y - Win->RealY - Win->BorderT;
        msg.Button = Index;
        msg.bPressed = !!Pressed;
        
@@ -94,7 +94,12 @@ void WM_Input_MouseButton(int X, int Y, int ButtonIndex, int Pressed)
        {
 //             _SysDebug("Gave focus to %p", win);
                WM_FocusWindow(win);
-               WM_RaiseWindow(win);
+               tWindow *tmpwin = win;
+               while( tmpwin )
+               {
+                       WM_RaiseWindow(tmpwin);
+                       tmpwin = tmpwin->Parent;
+               }
        }
 
        // Make sure that even if the mouse has moved out of the original window,
index 8168c5c..6ad72be 100644 (file)
@@ -9,6 +9,7 @@
 #include <wm_internals.h>
 #include <stdlib.h>
 #include <utf8.h>
+#include <limits.h>    // INT_MAX
 
 // === TYPES ===
 typedef struct sGlyph  tGlyph;
index 034999b..7b2a049 100644 (file)
@@ -8,21 +8,22 @@
 #ifndef _AXWIN3__FRAMEBUFFER_MESSAGES_H_
 #define _AXWIN3__FRAMEBUFFER_MESSAGES_H_
 
-enum
+enum eFrameBuffer_IPCCalls
 {
-       MSG_FB_COMMIT = 0x1000,
-       MSG_FB_NEWBUF,
-       MSG_FB_UPLOAD,
-       MSG_FB_DOWNLOAD,
-       MSG_FB_BLIT,
-       MSG_FB_FILL
+       IPC_FB_COMMIT,
+       IPC_FB_NEWBUF,
+       IPC_FB_UPLOAD,
+       IPC_FB_DOWNLOAD,        // Replies with requested data
+       IPC_FB_BLIT,
+       IPC_FB_FILL,
+       N_IPC_FB
 };
 
 typedef struct
 {
        uint16_t        Buffer;
        uint16_t        W, H;
-} tFBMsg_NewBuf;
+} tFBIPC_NewBuf;
 
 typedef struct
 {
@@ -30,7 +31,7 @@ typedef struct
        uint16_t        W, H;
        uint16_t        X, Y;
        uint32_t        ImageData[];
-} tFBMsg_Transfer;
+} tFBIPC_Transfer;
 
 typedef struct
 {
@@ -39,7 +40,7 @@ typedef struct
        uint16_t        SrcX, SrcY;
        uint16_t        DstX, DstY;
        uint16_t        W, H;
-} tFBMsg_Blit;
+} tFBIPC_Blit;
 
 typedef struct
 {
@@ -47,7 +48,7 @@ typedef struct
        uint16_t        X, Y;
        uint16_t        W, H;
        uint32_t        Colour;
-} tFBMsg_Fill;
+} tFBIPC_Fill;
 
 #endif
 
index 6e61ba8..50a9955 100644 (file)
@@ -28,6 +28,8 @@ typedef struct sIPCMsg_RetDisplayDims tIPCMsg_RetDisplayDims;
  */
 //! Request a return value
 #define IPCMSG_FLAG_RETURN     0x01
+//! IPC Message for renderer
+#define IPCMSG_FLAG_RENDERER   0x80
 /**
  * \}
  */
index 04dcd2d..12d7ba5 100644 (file)
 
 #include "ipcmessages.h"
 
-enum eMenuMessages
+// Client->Server IPC methods
+enum eMenuIPCCalls
 {
-       MSG_MENU_ADDITEM = 0x1000,
-       MSG_MENU_SETFLAGS,
-       
-       MSG_MENU_SELECT
+       IPC_MENU_ADDITEM,
+       IPC_MENU_SETFLAGS
 };
 
 typedef struct
@@ -24,14 +23,20 @@ typedef struct
        uint16_t        Flags;
        uint32_t        SubMenuID;
        char    Label[];
-} tMenuMsg_AddItem;
+} tMenuIPC_AddItem;
 
 typedef struct
 {
        uint16_t        ID;
        uint16_t        Value;
        uint16_t        Mask;
-} tMenuMsg_SetFlags;
+} tMenuIPC_SetFlags;
+
+// Server->Client messages
+enum eMenuMessages
+{
+       MSG_MENU_SELECT = 0x1000
+};
 
 typedef struct
 {
diff --git a/Usermode/Applications/axwin3_src/include/richtext_messages.h b/Usermode/Applications/axwin3_src/include/richtext_messages.h
new file mode 100644 (file)
index 0000000..7f53eb2
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Acess2 Window Manager v3
+ * - By John Hodge (thePowersGang)
+ *
+ * richtext_messages.h
+ * - Formatted Text Field
+ */
+#ifndef _RICHTEXT_MESSAGES_H_
+#define _RICHTEXT_MESSAGES_H_
+
+enum eRichText_Attrs {
+       _ATTR_DEFBG,
+       _ATTR_DEFFG,
+       _ATTR_SCROLL,
+       _ATTR_LINECOUNT,
+       _ATTR_COLCOUNT,
+       _ATTR_CURSOR,
+       _ATTR_CURSORBLINK,
+       _ATTR_CURSORPOS,
+};
+
+enum eRichText_IPCCalls
+{
+       IPC_RICHTEXT_SETATTR,
+       IPC_RICHTEXT_SETFONT,
+       IPC_RICHTEXT_DELLINE,
+       IPC_RICHTEXT_ADDLINE,
+       IPC_RICHTEXT_WRITELINE, // Set line contents
+       IPC_RICHTEXT_READLINE,  // Request line contents
+       N_IPC_RICHTEXT
+};
+
+struct sRichTextIPC_SetAttr
+{
+       uint32_t        Attr;
+       uint32_t        Value;
+};
+
+struct sRichTextIPC_SetFont
+{
+       uint16_t        Size;
+       char    Name[];
+};
+
+struct sRichTextIPC_AddDelLine
+{
+       uint32_t        Line;
+};
+
+struct sRichTextIPC_ReadLine
+{
+       uint32_t        Line;
+};
+
+struct sRichTextIPC_WriteLine
+{
+       uint32_t        Line;
+       char    LineData[];
+};
+
+enum
+{
+       // Events
+       MSG_RICHTEXT_KEYPRESS = 0x1000,
+       MSG_RICHTEXT_MOUSEBTN,
+
+       // Sent by server to get a line that is not cached (expects IPC WRITELINE)
+       MSG_RICHTEXT_REQLINE,
+       // Response to IPC READLINE
+       MSG_RICHTEXT_LINEDATA,
+};
+
+struct sRichTextMsg_ReqLine
+{
+       uint32_t        Line;
+};
+
+struct sRichTextMsg_LineData
+{
+       uint32_t        Line;
+       char    LineData[];
+};
+
+#endif
+
index 0a4b250..6064d6f 100644 (file)
@@ -8,27 +8,31 @@
 #ifndef _WIDGET_MESSAGES_H_
 #define _WIDGET_MESSAGES_H_
 
-enum
+enum eWidgetIPCCalls
 {
        // Control (Client->Server) messages
-       MSG_WIDGET_CREATE = 0x1000,
-       MSG_WIDGET_DELETE,
-       MSG_WIDGET_SETFOCUS,
-       MSG_WIDGET_SETFLAGS,
-       MSG_WIDGET_SETSIZE,
-       MSG_WIDGET_SETTEXT,
-       MSG_WIDGET_SETCOLOUR,
+       IPC_WIDGET_CREATE,
+       IPC_WIDGET_CREATESUBWIN,
+       IPC_WIDGET_DELETE,
+       IPC_WIDGET_SETFOCUS,
+       IPC_WIDGET_SETFLAGS,
+       IPC_WIDGET_SETSIZE,
+       IPC_WIDGET_SETTEXT,
+       IPC_WIDGET_SETCOLOUR,
        
-
-       // Request (Client->Server->Client) messages
-       MSG_WIDGET_GETTEXT,
-
-       // Event (Server->Client) messages
-       MSG_WIDGET_FIRE,
-       MSG_WIDGET_KEYPRESS,
-       MSG_WIDGET_MOUSEBTN,
+       IPC_WIDGET_GETTEXT,
+       
+       N_IPC_WIDGET
 };
 
+typedef struct
+{
+       uint32_t        Parent;
+       uint32_t        NewID;
+       uint32_t        Type;
+       uint32_t        Flags;
+       char    DebugName[];
+} tWidgetIPC_Create;
 
 typedef struct
 {
@@ -36,44 +40,55 @@ typedef struct
        uint32_t        NewID;
        uint32_t        Type;
        uint32_t        Flags;
+       uint32_t        WindowHandle;
        char    DebugName[];
-} tWidgetMsg_Create;
+} tWidgetIPC_CreateSubWin;
 
 typedef struct
 {
        uint32_t        WidgetID;
-} tWidgetMsg_Delete;
+} tWidgetIPC_Delete;
 
 typedef struct
 {
        uint32_t        WidgetID;
-} tWidgetMsg_SetFocus;
+} tWidgetIPC_SetFocus;
 
 typedef struct
 {
        uint32_t        WidgetID;
        uint32_t        Value;
        uint32_t        Mask;
-} tWidgetMsg_SetFlags;
+} tWidgetIPC_SetFlags;
 
 typedef struct
 {
        uint32_t        WidgetID;
        uint32_t        Value;
-} tWidgetMsg_SetSize;
+} tWidgetIPC_SetSize;
 
 typedef struct
 {
        uint32_t        WidgetID;
        char    Text[];
-} tWidgetMsg_SetText;
+} tWidgetIPC_SetText;
 
 typedef struct
 {
        uint32_t        WidgetID;
        uint32_t        Index;
        uint32_t        Colour;
-} tWidgetMsg_SetColour;
+} tWidgetIPC_SetColour;
+
+enum eWidgetMessages
+{
+       // Event (Server->Client) messages
+       MSG_WIDGET_FIRE = 0x1000,
+       MSG_WIDGET_KEYPRESS,
+       MSG_WIDGET_MOUSEBTN,
+};
+
+
 
 typedef struct
 {
index 3d37b5b..f425cc7 100644 (file)
@@ -8,6 +8,7 @@ CFLAGS   += -Wall
 LDFLAGS  += -lc -soname libaxwin3.so
 
 OBJ = main.o msg.o wm.o r_widget.o r_menu.o
+OBJ += r_richtext.o
 BIN = libaxwin3.so
 
 include ../../../Libraries/Makefile.tpl
index 913cf35..19ee8fd 100644 (file)
@@ -22,6 +22,8 @@ struct sAxWin3_Window
 
 extern void    *AxWin3_int_GetDataPtr(tHWND Window);
 extern uint32_t        AxWin3_int_GetWindowID(tHWND Window);
+extern void    AxWin3_SendIPC(tHWND Window, int Message, size_t Length, const void *Data);
+extern void    *AxWin3_WaitIPCMessage(tHWND Window, int Message, size_t *Length);
 
 #endif
 
index 82f76c6..6457c97 100644 (file)
@@ -14,7 +14,7 @@ extern const char     *gsAxWin3_int_ServerDesc;
 
 extern tAxWin_IPCMessage       *AxWin3_int_AllocateIPCMessage(tHWND Window, int Message, int Flags, int ExtraBytes);
 extern void    AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg);
-extern tAxWin_IPCMessage       *AxWin3_int_GetIPCMessage(void);
+extern tAxWin_IPCMessage       *AxWin3_int_GetIPCMessage(int nFD, fd_set *FDs);
 extern tAxWin_IPCMessage       *AxWin3_int_WaitIPCMessage(int WantedID);
 extern void    AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg);
 
index d8f6a61..453d4ba 100644 (file)
@@ -25,15 +25,21 @@ void AxWin3_MainLoop(void)
 
        while(!bExit)
        {
-               msg = AxWin3_int_GetIPCMessage();
+               msg = AxWin3_int_GetIPCMessage(0, NULL);
                if(!msg)        continue;       
 
-               _SysDebug("oh look, a message (Type=%i, Window=%i, Len=%i)",
+               _SysDebug("AxWin3_MainLoop - Message (Type=%i, Window=%i, Len=%i)",
                        msg->ID, msg->Window, msg->Size);
 
                AxWin3_int_HandleMessage( msg );
-               
-               free(msg);
        }
 }
 
+void AxWin3_MessageSelect(int nFD, fd_set *FDs)
+{
+       tAxWin_IPCMessage *msg;
+       msg = AxWin3_int_GetIPCMessage(nFD, FDs);
+       if( msg )
+               AxWin3_int_HandleMessage( msg );
+}
+
index 2b50167..a9a79a3 100644 (file)
@@ -33,9 +33,8 @@ tAxWin3_MessageCallback       gAxWin3_MessageCallback;
 // === CODE ===
 void AxWin3_Connect(const char *ServerDesc)
 {
-       _SysDebug("ServerDesc = %s", ServerDesc);
-       if( !ServerDesc )
-       {
+       _SysDebug("ServerDesc (argument) = %s", ServerDesc);
+       if( !ServerDesc ) {
                ServerDesc = gsAxWin3_int_ServerDesc;
        }
        _SysDebug("ServerDesc = %s", ServerDesc);
@@ -50,6 +49,10 @@ void AxWin3_Connect(const char *ServerDesc)
        case '6': case '7': case '8': case '9': case '0':
                giConnectionType = CONNTYPE_SENDMESSAGE;
                giConnectionNum = atoi(ServerDesc);
+               if( giConnectionNum == 0 ) {
+                       _SysDebug("Invalid server PID");
+                       exit(-1);
+               }
                break;
        case 'u':
                while(*ServerDesc && *ServerDesc != ':')        ServerDesc ++;
@@ -97,75 +100,61 @@ void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg)
        switch(giConnectionType)
        {
        case CONNTYPE_SENDMESSAGE:
-               SysSendMessage(giConnectionNum, size, Msg);
+               _SysSendMessage(giConnectionNum, size, Msg);
                break;
        case CONNTYPE_UDP: {
                // Create UDP header
                char    tmpbuf[giAxWin3_int_UDPHeaderLen + size];
                memcpy(tmpbuf, gaAxWin3_int_UDPHeader, giAxWin3_int_UDPHeaderLen);
                memcpy(tmpbuf + giAxWin3_int_UDPHeaderLen, Msg, size);
-               write(giConnectionNum, tmpbuf, sizeof(tmpbuf));
+               _SysWrite(giConnectionNum, tmpbuf, sizeof(tmpbuf));
                }
                break;
        case CONNTYPE_TCP:
-               write(giConnectionNum, Msg, size);
+               _SysWrite(giConnectionNum, Msg, size);
                break;
        default:
                break;
        }
 }
 
-tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(void)
+tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(int nFD, fd_set *fds)
 {
         int    len;
        tAxWin_IPCMessage       *ret = NULL;
-       switch(giConnectionType)
+        int    tid;
+
+       _SysSelect(nFD, fds, NULL, NULL, NULL, THREAD_EVENT_IPCMSG);
+       
+       // Clear out IPC messages
+       while( (len = _SysGetMessage(&tid, 0, NULL)) )
        {
-       case CONNTYPE_SENDMESSAGE:
-               for( ;; )
+               if( giConnectionType != CONNTYPE_SENDMESSAGE || tid != giConnectionNum )
                {
-                       pid_t   tid;
+                       _SysDebug("%i byte message from %i", len, tid);
+                       // If not, pass the buck (or ignore)
+                       if( gAxWin3_MessageCallback )
+                               gAxWin3_MessageCallback(tid, len);
+                       else
+                               _SysGetMessage(NULL, 0, GETMSG_IGNORE);
+                       continue ;
+               }
                
-                       // Wait for a message to arrive 
-                       while( !(len = SysGetMessage(&tid, NULL)) )
-                       {
-                               _SysWaitEvent(THREAD_EVENT_IPCMSG);
-                       }
-                       
-                       // Check if the message came from the server
-                       if(tid != giConnectionNum)
-                       {
-                               _SysDebug("%i byte message from %i", len, tid);
-                               // If not, pass the buck (or ignore)
-                               if( gAxWin3_MessageCallback )
-                                       gAxWin3_MessageCallback(tid, len);
-                               else
-                                       SysGetMessage(NULL, GETMSG_IGNORE);
-                               continue ;
-                       }
-                       
-                       // If it's from the server, allocate a buffer and return it
-                       ret = malloc(len);
-                       if(ret == NULL) {
-                               _SysDebug("malloc() failed, ignoring message");
-                               SysGetMessage(NULL, GETMSG_IGNORE);
-                               return NULL;
-                       }
-                       SysGetMessage(NULL, ret);
-                       break;
+               // Using CONNTYPE_SENDMESSAGE and server message has arrived
+               ret = malloc(len);
+               if(ret == NULL) {
+                       _SysDebug("malloc() failed, ignoring message");
+                       _SysGetMessage(NULL, 0, GETMSG_IGNORE);
+                       return NULL;
                }
-               break;
-       default:
-               // TODO: Implement
-               _SysDebug("TODO: Implement AxWin3_int_GetIPCMessage for TCP/UDP");
+               _SysGetMessage(NULL, len, ret);
                break;
        }
 
-       // No message?
-       if( ret == NULL )
-               return NULL;
-
-       // TODO: Sanity checks, so a stupid server can't crash us
+       if( giConnectionType == CONNTYPE_TCP || giConnectionType == CONNTYPE_UDP )
+       {
+               // Check fds
+       }
 
        return ret;
 }
@@ -175,10 +164,9 @@ tAxWin_IPCMessage *AxWin3_int_WaitIPCMessage(int WantedID)
        tAxWin_IPCMessage       *msg;
        for(;;)
        {
-               msg = AxWin3_int_GetIPCMessage();
+               msg = AxWin3_int_GetIPCMessage(0, NULL);
                if(msg->ID == WantedID) return msg;
                AxWin3_int_HandleMessage( msg );
-               free(msg);
        }
 }
 
index 1a6bfdf..65525b9 100644 (file)
@@ -43,9 +43,9 @@ int AxWin3_Menu_int_Callback(tHWND Window, int Message, int Length, void *Data)
                if(msg->ID >= info->nItems)     return -1;
                item = &info->Items[msg->ID];
                if(item->Callback)      item->Callback(item->CbPtr);
-               return 0; }
+               return 1; }
        }
-       return 1;
+       return 0;
 }
 
 tHWND AxWin3_Menu_Create(tHWND Parent)
@@ -96,7 +96,7 @@ tAxWin3_MenuItem *AxWin3_Menu_AddItem(
        ret->SubMenu = SubMenu; 
 
        {
-               tMenuMsg_AddItem        *req;
+               tMenuIPC_AddItem        *req;
                 int    data_size;
                if(!Label)      Label = "";
                data_size = sizeof(*req)+strlen(Label)+1;
@@ -105,7 +105,7 @@ tAxWin3_MenuItem *AxWin3_Menu_AddItem(
                req->Flags = Flags;
                req->SubMenuID = AxWin3_int_GetWindowID(SubMenu);
                strcpy(req->Label, Label);
-               AxWin3_SendMessage(Menu, Menu, MSG_MENU_ADDITEM, data_size, req);
+               AxWin3_SendIPC(Menu, IPC_MENU_ADDITEM, data_size, req);
                free(req);
        }
        
diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c
new file mode 100644 (file)
index 0000000..fd1cf39
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * AxWin3 Interface Library
+ * - By John Hodge (thePowersGang)
+ *
+ * r_richtext.c
+ * - Formatted Text window type
+ */
+#include <axwin3/axwin.h>
+#include <axwin3/richtext.h>
+#include "include/internal.h"
+#include <richtext_messages.h>
+#include <string.h>
+//#include <alloca.h>
+
+// === TYPES ===
+typedef struct sRichText_Window
+{
+       tAxWin3_RichText_KeyHandler     KeyCallback;
+       tAxWin3_RichText_MouseHandler   MouseCallback;
+       tAxWin3_RichText_LineHandler    LineHandler;
+} tRichText_Window;
+
+// === CODE ===
+int AxWin3_RichText_MessageHandler(tHWND Window, int MessageID, int Size, void *Data)
+{
+       return 0;
+}
+
+static void _SendAttrib(tHWND Window, int Attr, uint32_t Value)
+{
+       struct sRichTextIPC_SetAttr     msg;
+       msg.Attr = Attr;
+       msg.Value = Value;
+       AxWin3_SendIPC(Window, IPC_RICHTEXT_SETATTR, sizeof(msg), &msg);
+}
+
+tHWND AxWin3_RichText_CreateWindow(tHWND Parent, int Flags)
+{
+       tHWND ret = AxWin3_CreateWindow(Parent, "RichText", Flags, sizeof(tRichText_Window), AxWin3_RichText_MessageHandler);
+//     tRichText_Window *info = AxWin3_int_GetDataPtr(ret);
+       return ret;
+}
+
+void AxWin3_RichText_SetKeyHandler(tHWND Window, tAxWin3_RichText_KeyHandler Handler)
+{
+       tRichText_Window        *info = AxWin3_int_GetDataPtr(Window);
+       info->KeyCallback = Handler;
+}
+
+void AxWin3_RichText_SetMouseHandler(tHWND Window, tAxWin3_RichText_MouseHandler Handler)
+{
+       tRichText_Window        *info = AxWin3_int_GetDataPtr(Window);
+       info->MouseCallback = Handler;
+}
+
+void AxWin3_RichText_EnableScroll(tHWND Window, int bEnable)
+{
+       _SendAttrib(Window, _ATTR_SCROLL, bEnable);
+}
+void AxWin3_RichText_SetLineCount(tHWND Window, int Lines)
+{
+       _SendAttrib(Window, _ATTR_LINECOUNT, Lines);
+}
+void AxWin3_RichText_SetColCount(tHWND Window, int Cols)
+{
+       _SendAttrib(Window, _ATTR_COLCOUNT, Cols);
+}
+void AxWin3_RichText_SetBackground(tHWND Window, uint32_t ARGB_Colour)
+{
+       _SendAttrib(Window, _ATTR_DEFBG, ARGB_Colour);
+}
+void AxWin3_RichText_SetDefaultColour(tHWND Window, uint32_t ARGB_Colour)
+{
+       _SendAttrib(Window, _ATTR_DEFFG, ARGB_Colour);
+}
+void AxWin3_RichText_SetFont(tHWND Window, const char *FontName, int PointSize)
+{
+       // TODO: Send message
+}
+void AxWin3_RichText_SetCursorType(tHWND Window, int Type)
+{
+       _SendAttrib(Window, _ATTR_CURSOR, Type);
+}
+void AxWin3_RichText_SetCursorBlink(tHWND Window, int bBlink)
+{
+       _SendAttrib(Window, _ATTR_CURSORBLINK, bBlink);
+}
+void AxWin3_RichText_SetCursorPos(tHWND Window, int Row, int Column)
+{
+       if(Row < 0 || Row > 0xFFFFF || Column > 0xFFF || Column < 0)
+               return ;
+       _SendAttrib(Window, _ATTR_CURSORPOS, ((Row & 0xFFFFF) << 12) | (Column & 0xFFF));
+}
+
+void AxWin3_RichText_SendLine(tHWND Window, int Line, const char *Text)
+{
+       // TODO: Local sanity check on `Line`?
+       struct sRichTextIPC_WriteLine   *msg;
+       size_t  len = sizeof(*msg) + strlen(Text) + 1;
+       char    buffer[len];
+               msg = (void*)buffer;
+       msg->Line = Line;
+       strcpy(msg->LineData, Text);
+       AxWin3_SendIPC(Window, IPC_RICHTEXT_WRITELINE, len, msg);
+}
+
index 450e4b4..62e4277 100644 (file)
@@ -46,6 +46,33 @@ tAxWin3_Widget *AxWin3_Widget_int_GetElementByID(tHWND Window, uint32_t ID)
        return info->Elements[ID];
 }
 
+uint32_t AxWin3_Widget_int_AllocateID(tWidgetWindowInfo *Info)
+{
+       uint32_t        newID;
+       // BUG BUG BUG - Double Allocations! (citation needed)
+       // TODO: Atomicity
+       for( newID = Info->FirstFreeID; newID < Info->nElements; newID ++ )
+       {
+               if( Info->Elements[newID] == NULL )
+                       break;
+       }
+       if( newID == Info->nElements )
+       {
+               const int size_step = 4;
+               Info->nElements += 4;
+               Info->Elements = realloc(Info->Elements, sizeof(*Info->Elements)*Info->nElements);
+               newID = Info->nElements - 4;
+               memset( &Info->Elements[newID+1], 0, (size_step-1)*sizeof(Info->Elements));
+               _SysDebug("Widget: Expanded to %i and allocated %i", Info->nElements, newID);
+       }
+       else
+               _SysDebug("Widget: Allocated %i", newID);
+       Info->Elements[newID] = (void*)-1;
+       
+       return newID;
+       
+}
+
 int AxWin3_Widget_MessageHandler(tHWND Window, int MessageID, int Size, void *Data)
 {
        tAxWin3_Widget  *widget;
@@ -58,7 +85,7 @@ int AxWin3_Widget_MessageHandler(tHWND Window, int MessageID, int Size, void *Da
                widget = AxWin3_Widget_int_GetElementByID(Window, msg->WidgetID);
                if(widget->Fire)        widget->Fire(widget);
                
-               return 0; }
+               return 1; }
        default:
                return 0;
        }
@@ -108,26 +135,7 @@ tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Fl
 
        info = AxWin3_int_GetDataPtr(Parent->Window);
        
-       // Assign ID
-       // BUG BUG BUG - Double Allocations!
-       // TODO: Atomicity
-       for( newID = info->FirstFreeID; newID < info->nElements; newID ++ )
-       {
-               if( info->Elements[newID] == NULL )
-                       break;
-       }
-       if( newID == info->nElements )
-       {
-               const int size_step = 4;
-               info->nElements += 4;
-               info->Elements = realloc(info->Elements, sizeof(*info->Elements)*info->nElements);
-               newID = info->nElements - 4;
-               memset( &info->Elements[newID+1], 0, (size_step-1)*sizeof(info->Elements));
-               _SysDebug("Expanded to %i and allocated %i", info->nElements, newID);
-       }
-       else
-               _SysDebug("Allocated %i", newID);
-       info->Elements[newID] = (void*)-1;
+       newID = AxWin3_Widget_int_AllocateID(info);
        
        // Create new widget structure
        ret = calloc(sizeof(tAxWin3_Widget), 1);
@@ -138,26 +146,53 @@ tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Fl
 
        // Send create widget message
        {
-               char    tmp[sizeof(tWidgetMsg_Create)+1];
-               tWidgetMsg_Create       *msg = (void*)tmp;
+               char    tmp[sizeof(tWidgetIPC_Create)+1];
+               tWidgetIPC_Create       *msg = (void*)tmp;
                msg->Parent = Parent->ID;
                msg->NewID = newID;
                msg->Type = Type;
                msg->Flags = Flags;
                msg->DebugName[0] = '\0';
-               AxWin3_SendMessage(ret->Window, ret->Window, MSG_WIDGET_CREATE, sizeof(tmp), tmp);
+               AxWin3_SendIPC(ret->Window, IPC_WIDGET_CREATE, sizeof(tmp), tmp);
+       }
+
+       return ret;
+}
+
+tAxWin3_Widget *AxWin3_Widget_AddWidget_SubWindow(tAxWin3_Widget *Parent, tHWND Window, int Flags, const char *DbgName)
+{
+       tWidgetWindowInfo       *info = AxWin3_int_GetDataPtr(Parent->Window);
+       int newID = AxWin3_Widget_int_AllocateID(info);
+       
+       tAxWin3_Widget  *ret = calloc(sizeof(tAxWin3_Widget), 1);
+       ret->Window = Parent->Window;
+       ret->ID = newID;
+       info->Elements[newID] = ret;
+
+       // Send message
+       {
+               char    tmp[sizeof(tWidgetIPC_CreateSubWin)+1];
+               tWidgetIPC_CreateSubWin *msg = (void*)tmp;
+               msg->Parent = Parent->ID;
+               msg->NewID = newID;
+               msg->Type = ELETYPE_SUBWIN;
+               msg->Flags = Flags;     // TODO: Flags
+               msg->WindowHandle = AxWin3_int_GetWindowID(Window);
+               msg->DebugName[0] = '\0';
+               AxWin3_SendIPC(ret->Window, IPC_WIDGET_CREATESUBWIN, sizeof(tmp), tmp);
        }
 
        return ret;
 }
 
+
 void AxWin3_Widget_DelWidget(tAxWin3_Widget *Widget)
 {
-       tWidgetMsg_Delete       msg;
+       tWidgetIPC_Delete       msg;
        tWidgetWindowInfo       *info = AxWin3_int_GetDataPtr(Widget->Window);
        
        msg.WidgetID = Widget->ID;
-       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_DELETE, sizeof(msg), &msg);
+       AxWin3_SendIPC(Widget->Window, IPC_WIDGET_DELETE, sizeof(msg), &msg);
        
        info->Elements[Widget->ID] = NULL;
        if(Widget->ID < info->FirstFreeID)
@@ -199,45 +234,45 @@ void AxWin3_Widget_SetMouseButtonHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_
 // --- Manipulation
 void AxWin3_Widget_SetFlags(tAxWin3_Widget *Widget, int FlagSet, int FlagMask)
 {
-       tWidgetMsg_SetFlags     msg;
+       tWidgetIPC_SetFlags     msg;
        msg.WidgetID = Widget->ID;
        msg.Value = FlagSet;
        msg.Mask = FlagMask;
        
-       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETFLAGS, sizeof(msg), &msg);
+       AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETFLAGS, sizeof(msg), &msg);
 }
 
 void AxWin3_Widget_SetSize(tAxWin3_Widget *Widget, int Size)
 {
-       tWidgetMsg_SetSize      msg;
+       tWidgetIPC_SetSize      msg;
        
        msg.WidgetID = Widget->ID;
        msg.Value = Size;
-       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETSIZE, sizeof(msg), &msg);
+       AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETSIZE, sizeof(msg), &msg);
 }
 
 void AxWin3_Widget_SetText(tAxWin3_Widget *Widget, const char *Text)
 {
-       char    buf[sizeof(tWidgetMsg_SetText) + strlen(Text) + 1];
-       tWidgetMsg_SetText      *msg = (void*)buf;
+       char    buf[sizeof(tWidgetIPC_SetText) + strlen(Text) + 1];
+       tWidgetIPC_SetText      *msg = (void*)buf;
        
        msg->WidgetID = Widget->ID;
        strcpy(msg->Text, Text);
        
-       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETTEXT, sizeof(buf), buf);
+       AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETTEXT, sizeof(buf), buf);
 }
 
 char *AxWin3_Widget_GetText(tAxWin3_Widget *Widget)
 {
-       char    buf[sizeof(tWidgetMsg_SetText)];
-       tWidgetMsg_SetText      *msg = (void*)buf;
+       char    buf[sizeof(tWidgetIPC_SetText)];
+       tWidgetIPC_SetText      *msg = (void*)buf;
        size_t  retmsg_size;
        
        msg->WidgetID = Widget->ID;
 
-       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf);
+       AxWin3_SendIPC(Widget->Window, IPC_WIDGET_GETTEXT, sizeof(buf), buf);
 
-       msg = AxWin3_WaitMessage(Widget->Window, MSG_WIDGET_GETTEXT, &retmsg_size);
+       msg = AxWin3_WaitIPCMessage(Widget->Window, IPC_WIDGET_GETTEXT, &retmsg_size);
        if( retmsg_size < sizeof(*msg) ) {
                free(msg);
                return NULL;
@@ -250,10 +285,10 @@ char *AxWin3_Widget_GetText(tAxWin3_Widget *Widget)
 
 void AxWin3_Widget_SetColour(tAxWin3_Widget *Widget, int Index, tAxWin3_Colour Colour)
 {
-       tWidgetMsg_SetColour    msg;
+       tWidgetIPC_SetColour    msg;
        
        msg.WidgetID = Widget->ID;
        msg.Index = Index;
        msg.Colour = Colour;
-       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETCOLOUR, sizeof(msg), &msg);
+       AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETCOLOUR, sizeof(msg), &msg);
 }
index 4a6d8d3..53208f2 100644 (file)
@@ -127,7 +127,7 @@ int AxWin3_GetDisplayDims(int Display, int *X, int *Y, int *Width, int *Height)
        ret = (void*)msg->Data;
        
        if(X)   *X = ret->X;
-       if(X)   *X = ret->Y;
+       if(Y)   *Y = ret->Y;
        if(Width)       *Width = ret->W;
        if(Height)      *Height = ret->H;
        
@@ -161,6 +161,8 @@ tHWND AxWin3_CreateWindow(
        AxWin3_int_SendIPCMessage(msg);
        free(msg);
 
+       _SysDebug("AxWin3_CreateWindow: %i :: '%s'", newWinID, Renderer);
+
        // TODO: Detect and handle possible errors
 
        // Return success
@@ -217,7 +219,7 @@ void AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg)
                                        gAxWin3_Hotkeys[mi->ID]();
                                }break;
                        default:
-                               _SysDebug("--- Unhandled SENDMSG %i", info->ID);
+                               _SysDebug("--- Unhandled SENDMSG 0x%x win %i", info->ID, Msg->Window);
                                break;
                        }
                }
@@ -226,6 +228,8 @@ void AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg)
                _SysDebug("Unknow message ID %i", Msg->ID);
                break;
        }
+       
+       free(Msg);
 }
 
 void AxWin3_SetWindowTitle(tHWND Window, const char *Title)
@@ -283,6 +287,36 @@ void *AxWin3_WaitMessage(tHWND Window, int MessageID, size_t *Length)
        }
 }
 
+void AxWin3_SendIPC(tHWND Window, int Message, size_t Length, const void *Data)
+{
+       tAxWin_IPCMessage       *msg;
+       
+       msg = AxWin3_int_AllocateIPCMessage(Window, Message, IPCMSG_FLAG_RENDERER, Length);
+       memcpy(msg->Data, Data, Length);
+       AxWin3_int_SendIPCMessage(msg);
+       free(msg);
+}
+
+void *AxWin3_WaitIPCMessage(tHWND Window, int MessageID, size_t *Length)
+{
+       tAxWin_IPCMessage       *msg;
+       for( ;; )
+       {
+               msg = AxWin3_int_WaitIPCMessage(MessageID);
+               if( !(msg->Flags & IPCMSG_FLAG_RENDERER) || msg->Window != AxWin3_int_GetWindowID(Window) ) {
+                       AxWin3_int_HandleMessage(msg);
+                       continue ;
+               }
+
+               *Length = msg->Size;
+               void    *ret = malloc(msg->Size);
+               memcpy(ret, msg->Data, msg->Size);
+               free(msg);
+       
+               return ret;
+       }
+}
+
 void AxWin3_FocusWindow(tHWND Window)
 {
        tAxWin_IPCMessage       *msg;
index af5d094..b5cac3c 100644 (file)
@@ -43,7 +43,7 @@ int main(int argc, char *argv[])
 
        if( gbForkBomb )
        {
-               for(;;) clone(CLONE_VM, 0);
+               for(;;) _SysClone(CLONE_VM, 0);
        }
        else {
                for(;;)
@@ -56,12 +56,12 @@ int main(int argc, char *argv[])
                                printf("Outta heap space!\n");
                                return 0;
                        }
-                       tid = clone(0, stack+stackSize-stackOffset);
+                       tid = _SysClone(0, stack+stackSize-stackOffset);
                        //_SysDebug("tid = %i", tid);
                        if( tid == 0 )
                        {
                                // Sleep forever (TODO: Fix up the stack so it can nuke)
-                               for(;;) sleep();
+                               for(;;) _SysWaitEvent(THREAD_EVENT_SIGNAL);
                        }
                        if( tid < 0 ) {
                                printf("Clone failed\n");
index 443a5de..3fae4c6 100644 (file)
@@ -1,7 +1,6 @@
 /*
  * Acess2 CAT command
  */
-#include <acess/sys.h>
 #include <stdlib.h>
 #include <stdio.h>
 
@@ -13,7 +12,6 @@
  */
 int main(int argc, char *argv[])
 {
-        int    fd;
         int    num;
        char    buf[BUF_SIZE];
 
@@ -22,19 +20,19 @@ int main(int argc, char *argv[])
                return -1;
        }
 
-       fd = open(argv[1], OPENFLAG_READ);
-       if(fd == -1) {
+       FILE *fp = fopen(argv[1], "r");
+       if(!fp) {
                printf("Unable to open '%s' for reading\n", argv[1]);
                return -1;
        }
 
        do {
-               num = read(fd, buf, BUF_SIZE);
+               num = fread(buf, BUF_SIZE, 1, fp);
                if(num < 0)     break;
-               write(1, buf, num);
+               fwrite(buf, num, 1, stdout);
        } while(num == BUF_SIZE);
 
-       close(fd);
+       fclose(fp);
        printf("\n");
 
        return 0;
index 8831cd6..b9b2814 100644 (file)
@@ -2,12 +2,12 @@
  * 
  * http://www.ietf.org/rfc/rfc2131.txt
  */
-#include <unistd.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <net.h>
+#include <acess/sys.h>
 
 #define FILENAME_MAX   255
 // --- Translation functions ---
@@ -33,7 +33,7 @@ enum eStates
        STATE_PREINIT,
        STATE_DISCOVER_SENT,
        STATE_REQUEST_SENT,
-       STATE_COMPLETE
+       STATE_COMPLETE,
 };
 
 // === STRUCTURES ===
@@ -71,6 +71,7 @@ typedef struct sInterface
        char    HWAddr[6];
        
        int64_t Timeout;
+        int    nTimeouts;
 } tInterface;
 
 // === PROTOTYPES ===
@@ -79,8 +80,8 @@ void  Scan_Dir(tInterface **IfaceList, const char *Directory);
 int    Start_Interface(tInterface *Iface);
 void   Send_DHCPDISCOVER(tInterface *Iface);
 void   Send_DHCPREQUEST(tInterface *Iface, void *OfferBuffer, int TypeOffset);
-int    Handle_Packet(tInterface *Iface);
-void   Handle_Timeout(tInterface *Iface);
+ int   Handle_Packet(tInterface *Iface);
+ int   Handle_Timeout(tInterface *Iface);
 void   Update_State(tInterface *Iface, int newState);
 void   SetAddress(tInterface *Iface, void *Addr, void *Mask, void *Router);
 
@@ -144,19 +145,24 @@ int main(int argc, char *argv[])
                        if( FD_ISSET(i->SocketFD, &fds) )
                        {
                                if( Handle_Packet( i ) )
-                               {
-                                       close(i->SocketFD);
-                                       close(i->IfaceFD);
-                                       p->Next = i->Next;
-                                       free(i);
-                                       i = p;
-                               }
+                                       goto _remove;
                        }
                        
                        if( _SysTimestamp() > i->Timeout )
                        {
-                               Handle_Timeout(i);
+                               if( Handle_Timeout(i) )
+                               {
+                                       fprintf(stderr, "%s timed out\n", i->Adapter);
+                                       goto _remove;
+                               }
                        }
+                       continue ;
+               _remove:
+                       _SysClose(i->SocketFD);
+                       _SysClose(i->IfaceFD);
+                       p->Next = i->Next;
+                       free(i);
+                       i = p;
                }
        }
        return 0;
@@ -164,14 +170,15 @@ int main(int argc, char *argv[])
 
 void Scan_Dir(tInterface **IfaceList, const char *Directory)
 {
-       int dp = open(Directory, OPENFLAG_READ);
+       int dp = _SysOpen(Directory, OPENFLAG_READ);
        char filename[FILENAME_MAX];
 
        if( dp == -1 ) {
                fprintf(stderr, "Unable to open directory '%s'\n", Directory);
+               return ;
        }
 
-       while( SysReadDir(dp, filename) )
+       while( _SysReadDir(dp, filename) )
        {
                if( filename[0] == '.' )        continue ;              
                if( strcmp(filename, "lo") == 0 )       continue ;
@@ -182,7 +189,7 @@ void Scan_Dir(tInterface **IfaceList, const char *Directory)
                new->Next = *IfaceList;
                *IfaceList = new;
        }
-       close(dp);
+       _SysClose(dp);
 }
 
 // RETURN: Client FD
@@ -198,52 +205,52 @@ int Start_Interface(tInterface *Iface)
        {
                char    path[] = "/Devices/ip/adapters/ethXXXX";
                sprintf(path, "/Devices/ip/adapters/%s", Iface->Adapter);
-               fd = open(path, 0);
+               fd = _SysOpen(path, 0);
                if(fd == -1) {
                        _SysDebug("Unable to open adapter %s", path);
                        return -1;
                }
-               ioctl(fd, 4, Iface->HWAddr);
+               _SysIOCtl(fd, 4, Iface->HWAddr);
                // TODO: Check if ioctl() failed
-               close(fd);
+               _SysClose(fd);
        }
        
        // Initialise an interface, with a dummy IP address (zero)
-       fd = open("/Devices/ip", 0);
+       fd = _SysOpen("/Devices/ip", 0);
        if( fd == -1 ) {
                fprintf(stderr, "ERROR: Unable to open '/Devices/ip'\n"); 
                return -1;
        }
-       Iface->Num = ioctl(fd, 4, (void*)Iface->Adapter);       // Create interface
+       Iface->Num = _SysIOCtl(fd, 4, (void*)Iface->Adapter);   // Create interface
        if( Iface->Num == -1 ) {
                fprintf(stderr, "ERROR: Unable to create new interface\n");
                return -1;
        }
-       close(fd);
+       _SysClose(fd);
        
        // Open new interface
        snprintf(path, sizeof(path), "/Devices/ip/%i", Iface->Num);
-       Iface->IfaceFD = fd = open(path, 0);
+       Iface->IfaceFD = fd = _SysOpen(path, 0);
        if( fd == -1 ) {
                fprintf(stderr, "ERROR: Unable to open '%s'\n", path); 
                return -1;
        }
-       tmp = 4; ioctl(fd, 4, &tmp);    // Set to IPv4
-       ioctl(fd, 6, addr);     // Set address to 0.0.0.0
-       tmp = 0; ioctl(fd, 7, &tmp);    // Set subnet mask to 0
+       tmp = 4; _SysIOCtl(fd, 4, &tmp);        // Set to IPv4
+       _SysIOCtl(fd, 6, addr); // Set address to 0.0.0.0
+       tmp = 0; _SysIOCtl(fd, 7, &tmp);        // Set subnet mask to 0
 
        // Open UDP Client
        snprintf(path, sizeof(path), "/Devices/ip/%i/udp", Iface->Num);
-       Iface->SocketFD = fd = open(path, O_RDWR);
+       Iface->SocketFD = fd = _SysOpen(path, OPENFLAG_READ|OPENFLAG_WRITE);
        if( fd == -1 ) {
                fprintf(stderr, "ERROR: Unable to open '%s'\n", path); 
                return -1;
        }
-       tmp = 68; ioctl(fd, 4, &tmp);   // Local port
-       tmp = 67; ioctl(fd, 5, &tmp);   // Remote port
-       tmp = 0;        ioctl(fd, 7, &tmp);     // Remote addr mask bits - we don't care where the reply comes from
+       tmp = 68; _SysIOCtl(fd, 4, &tmp);       // Local port
+       tmp = 67; _SysIOCtl(fd, 5, &tmp);       // Remote port
+       tmp = 0;        _SysIOCtl(fd, 7, &tmp); // Remote addr mask bits - we don't care where the reply comes from
        addr[0] = addr[1] = addr[2] = addr[3] = 255;    // 255.255.255.255
-       ioctl(fd, 8, addr);     // Remote address
+       _SysIOCtl(fd, 8, addr); // Remote address
        
        return 0;
 }
@@ -292,7 +299,10 @@ void Send_DHCPDISCOVER(tInterface *Iface)
        data[2] = 4;    data[3] = 0;    // AddrType
        data[4] = 255;  data[5] = 255;  data[6] = 255;  data[7] = 255;
 
-       write(Iface->SocketFD, data, sizeof(data));
+       i = _SysWrite(Iface->SocketFD, data, sizeof(data));
+       if( i != sizeof(data) ) {
+               _SysDebug("_SysWrite failed (%i != %i)", i, sizeof(data));
+       }
        Update_State(Iface, STATE_DISCOVER_SENT);
 }
 
@@ -338,7 +348,7 @@ void Send_DHCPREQUEST(tInterface *Iface, void *OfferPacket, int TypeOffset)
        ((uint8_t*)OfferPacket)[6] = 255;
        ((uint8_t*)OfferPacket)[7] = 255;
        
-       write(Iface->SocketFD, OfferPacket, 8 + sizeof(*msg) + i);
+       _SysWrite(Iface->SocketFD, OfferPacket, 8 + sizeof(*msg) + i);
        Update_State(Iface, STATE_REQUEST_SENT);
 }
 
@@ -353,7 +363,7 @@ int Handle_Packet(tInterface *Iface)
        void    *subnet_mask = NULL;
        
        _SysDebug("Doing read on %i", Iface->SocketFD);
-       len = read(Iface->SocketFD, data, sizeof(data));
+       len = _SysRead(Iface->SocketFD, data, sizeof(data));
        _SysDebug("len = %i", len);
 
        _SysDebug("*msg = {");
@@ -437,8 +447,10 @@ int Handle_Packet(tInterface *Iface)
        return 0;
 }
 
-void Handle_Timeout(tInterface *Iface)
+int Handle_Timeout(tInterface *Iface)
 {
+       if( Iface->nTimeouts == 3 )
+               return 1;
        switch(Iface->State)
        {
        case STATE_DISCOVER_SENT:
@@ -448,6 +460,7 @@ void Handle_Timeout(tInterface *Iface)
                _SysDebug("Timeout with state = %i", Iface->State);
                break;
        }
+       return 0;
 }
 
 void Update_State(tInterface *Iface, int newState)
@@ -456,11 +469,13 @@ void Update_State(tInterface *Iface, int newState)
        {
                Iface->Timeout = _SysTimestamp() + 500;
                Iface->State = newState;
+               Iface->nTimeouts = 0;
        }
        else
        {
                // TODO: Exponential backoff
                Iface->Timeout = _SysTimestamp() + 3000;
+               Iface->nTimeouts ++;
                _SysDebug("State %i repeated, timeout is 3000ms now", newState);
        }
 }
@@ -510,8 +525,8 @@ void SetAddress(tInterface *Iface, void *Addr, void *Mask, void *Router)
                        );
        }
 
-       ioctl(Iface->IfaceFD, 6, Addr);
-       ioctl(Iface->IfaceFD, 7, &mask_bits);
+       _SysIOCtl(Iface->IfaceFD, 6, Addr);
+       _SysIOCtl(Iface->IfaceFD, 7, &mask_bits);
 
        if( Router );
        {
@@ -520,16 +535,16 @@ void SetAddress(tInterface *Iface, void *Addr, void *Mask, void *Router)
                
                // Set default route
                 int    fd;
-               fd = open("/Devices/ip/routes/4:00000000:0:0", OPENFLAG_CREATE);
+               fd = _SysOpen("/Devices/ip/routes/4:00000000:0:0", OPENFLAG_CREATE);
                if(fd == -1) {
                        fprintf(stderr, "ERROR: Unable to open default route\n");
                }
                else {
                        char ifname[snprintf(NULL,0,"%i",Iface->Num)+1];
                        sprintf(ifname, "%i", Iface->Num);
-                       ioctl(fd, ioctl(fd, 3, "set_nexthop"), Router);
-                       ioctl(fd, ioctl(fd, 3, "set_interface"), ifname);
-                       close(fd);
+                       _SysIOCtl(fd, _SysIOCtl(fd, 3, "set_nexthop"), Router);
+                       _SysIOCtl(fd, _SysIOCtl(fd, 3, "set_interface"), ifname);
+                       _SysClose(fd);
                }
        }
 }
diff --git a/Usermode/Applications/gui_ate_src/Makefile b/Usermode/Applications/gui_ate_src/Makefile
new file mode 100644 (file)
index 0000000..569e141
--- /dev/null
@@ -0,0 +1,11 @@
+# Project: [GUI] Acess Text Editor (ATE)
+
+-include ../Makefile.cfg
+
+LDFLAGS += -laxwin3
+
+OBJ = main.o
+BIN = ate
+DIR := Apps/AxWin/3.0
+
+-include ../Makefile.tpl
diff --git a/Usermode/Applications/gui_ate_src/edit.c b/Usermode/Applications/gui_ate_src/edit.c
new file mode 100644 (file)
index 0000000..8e1f01e
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Acess Text Editor (ATE)
+ * - By John Hodge (thePowersGang)
+ *
+ * edit.c
+ * - File Loading / Manipulation
+ */
+#include <stdio.h>
+#include "include/file.h"
+#include "include/syntax.h"
+
+// === CODE ===
+tFile *File_New(void)
+{
+       tFile *ret = malloc(sizeof(tFile) + 1);
+       ret->Handle = NULL;
+       ret->nLines = 0;
+       ret->Lines = NULL;
+       ret->NameOfs = 0;
+       ret->Path[0] = 0;
+       return ret;
+}
+
+tFile *File_Load(const char *Path)
+{
+       return NULL;
+}
+
+int File_Save(tFile *File)
+{
+       
+       //file->bIsDirty = 0;
+       return -1;
+}
+
+int File_Close(tFile *File, int bDiscard)
+{
+       //if( file->bIsDirty && !bDiscard )
+       //      return 1;
+       if( file->Handle )
+               fclose(File->Handle);
+       
+       return 0;
+}
+
diff --git a/Usermode/Applications/gui_ate_src/include/file.h b/Usermode/Applications/gui_ate_src/include/file.h
new file mode 100644 (file)
index 0000000..5eb15b0
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Acess Text Editor (ATE)
+ * - By John Hodge (thePowersGang)
+ *
+ * include/file.h
+ * - In-memory file structures
+ */
+#ifndef _ATE__FILE_H_
+#define _ATE__FILE_H_
+#include <stdio.h>
+
+typedef struct sFileLine
+{
+        int    Num;
+
+       // State data for hilighting
+        int    HilightState;
+       char    *Rendered;
+
+        int    Space;
+        int    Length;
+       char    Data[];
+} tFileLine;
+
+typedef struct sFile
+{
+       FILE    *Handle;
+        int    nLines;
+       tFileLine       **Lines;        // TODO: Handle very large files?
+        int    NameOfs;
+       const char      Path[];
+} tFile;
+
+#endif
+
diff --git a/Usermode/Applications/gui_ate_src/include/syntax.h b/Usermode/Applications/gui_ate_src/include/syntax.h
new file mode 100644 (file)
index 0000000..99b35ce
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Acess Text Editor (ATE)
+ * - By John Hodge (thePowersGang)
+ *
+ * include/syntax.h
+ * - Syntax Hilighting / Rendering structures
+ */
+#ifndef _ATE__SYNTAX_H_
+#define _ATE__SYNTAX_H_
+
+#endif
+
diff --git a/Usermode/Applications/gui_ate_src/main.c b/Usermode/Applications/gui_ate_src/main.c
new file mode 100644 (file)
index 0000000..032a968
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Acess Text Editor (ATE)
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Core
+ */
+#include <axwin3/axwin.h>
+#include <axwin3/widget.h>
+#include <axwin3/menu.h>
+#include <axwin3/richtext.h>
+#include <stdio.h>
+#include "strings.h"
+
+// === PROTOTYPES ===
+ int   main(int argc, char *argv[]);
+ int   TextArea_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated);
+ int   TextArea_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col);
+void   add_toolbar_button(tAxWin3_Widget *Toolbar, const char *Ident, tAxWin3_Widget_FireCb Callback);
+ int   Toolbar_New(tAxWin3_Widget *Widget);
+ int   Toolbar_Open(tAxWin3_Widget *Widget);
+ int   Toolbar_Save(tAxWin3_Widget *Widget);
+
+// === GLOBALS ===
+tHWND  gMainWindow;
+tAxWin3_Widget *gMainWindow_Root;
+tHWND  gMainWindow_MenuBar;
+tAxWin3_Widget *gMainWindow_Toolbar;
+tHWND  gMainWindow_TextArea;
+
+// === CODE ===
+int main(int argc, char *argv[])
+{
+       AxWin3_Connect(NULL);
+       
+       // --- Build up window
+       gMainWindow = AxWin3_Widget_CreateWindow(NULL, 700, 400, ELEFLAG_VERTICAL);
+       AxWin3_SetWindowTitle(gMainWindow, "Acess Text Editor");        // TODO: Update title with other info
+       gMainWindow_Root = AxWin3_Widget_GetRoot(gMainWindow);
+
+       //gMainWindow_MenuBar = AxWin3_Menu_Create(gMainWindow);
+       //AxWin3_Widget_AddWidget_SubWindow(gMainWindow_Root, gMainWindow_MenuBar);
+       // TODO: Populate menu  
+
+       // Create toolbar
+       gMainWindow_Toolbar = AxWin3_Widget_AddWidget(gMainWindow_Root, ELETYPE_TOOLBAR, ELEFLAG_NOSTRETCH, "Toolbar");
+       add_toolbar_button(gMainWindow_Toolbar, "BtnNew", Toolbar_New);
+       add_toolbar_button(gMainWindow_Toolbar, "BtnOpen", Toolbar_Open);
+       add_toolbar_button(gMainWindow_Toolbar, "BtnSave", Toolbar_Save);
+       AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, 0, "");
+       add_toolbar_button(gMainWindow_Toolbar, "BtnUndo", NULL);
+       add_toolbar_button(gMainWindow_Toolbar, "BtnRedo", NULL);
+       AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, 0, "");
+       add_toolbar_button(gMainWindow_Toolbar, "BtnCut", NULL);
+       add_toolbar_button(gMainWindow_Toolbar, "BtnCopy", NULL);
+       add_toolbar_button(gMainWindow_Toolbar, "BtnPaste", NULL);
+       AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, 0, "");
+       add_toolbar_button(gMainWindow_Toolbar, "BtnSearch", NULL);
+       add_toolbar_button(gMainWindow_Toolbar, "BtnReplace", NULL);
+
+       // TODO: Tab control?   
+
+       gMainWindow_TextArea = AxWin3_RichText_CreateWindow(gMainWindow, 0);
+       AxWin3_Widget_AddWidget_SubWindow(gMainWindow_Root, gMainWindow_TextArea, 0, "TextArea");
+       AxWin3_RichText_SetKeyHandler   (gMainWindow_TextArea, TextArea_KeyHandler);
+       AxWin3_RichText_SetMouseHandler (gMainWindow_TextArea, TextArea_MouseHandler);
+       AxWin3_RichText_SetBackground   (gMainWindow_TextArea, 0xFFFFFF);
+       AxWin3_RichText_SetDefaultColour(gMainWindow_TextArea, 0x000000);
+       AxWin3_RichText_SetFont         (gMainWindow_TextArea, "#monospace", 10);
+       AxWin3_RichText_SetCursorPos    (gMainWindow_TextArea, 0, 0);
+       AxWin3_RichText_SetCursorType   (gMainWindow_TextArea, AXWIN3_RICHTEXT_CURSOR_VLINE);
+       AxWin3_RichText_SetCursorBlink  (gMainWindow_TextArea, 1);
+
+       // <testing>
+       AxWin3_RichText_SetLineCount(gMainWindow_TextArea, 3);
+       AxWin3_RichText_SendLine(gMainWindow_TextArea, 0, "First line!");
+       AxWin3_RichText_SendLine(gMainWindow_TextArea, 2, "Third line! \x01""ff0000A red");
+       // </testing>
+
+       AxWin3_ShowWindow(gMainWindow_TextArea, 1);
+       // TODO: Status Bar?
+
+       AxWin3_MoveWindow(gMainWindow, 50, 50);
+       AxWin3_ShowWindow(gMainWindow, 1);
+       AxWin3_FocusWindow(gMainWindow);
+       
+       // Main loop
+       AxWin3_MainLoop();
+
+       return 0;
+}
+
+int TextArea_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated)
+{
+       return 0;
+}
+
+int TextArea_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col)
+{
+       return 0;
+}
+
+void add_toolbar_button(tAxWin3_Widget *Toolbar, const char *Ident, tAxWin3_Widget_FireCb Callback)
+{
+       tAxWin3_Widget *btn = AxWin3_Widget_AddWidget(Toolbar, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH, Ident);
+       tAxWin3_Widget *txt = AxWin3_Widget_AddWidget(btn, ELETYPE_TEXT, 0, Ident);
+       // TODO: Get image / text using `Ident` as a lookup key
+       AxWin3_Widget_SetText(txt, Ident);
+       AxWin3_Widget_SetFireHandler(btn, Callback);
+}
+
+int Toolbar_New(tAxWin3_Widget *Widget)
+{
+       return 0;
+}
+int Toolbar_Open(tAxWin3_Widget *Widget)
+{
+       return 0;
+}
+int Toolbar_Save(tAxWin3_Widget *Widget)
+{
+       return 0;
+}
+
diff --git a/Usermode/Applications/gui_shell_src/Makefile b/Usermode/Applications/gui_shell_src/Makefile
new file mode 100644 (file)
index 0000000..7ccfff4
--- /dev/null
@@ -0,0 +1,11 @@
+# Project: [GUI] Terminal
+
+-include ../Makefile.cfg
+
+LDFLAGS += -laxwin3
+
+OBJ = main.o
+BIN = terminal
+DIR := Apps/AxWin/3.0
+
+-include ../Makefile.tpl
diff --git a/Usermode/Applications/gui_shell_src/include/display.h b/Usermode/Applications/gui_shell_src/include/display.h
new file mode 100644 (file)
index 0000000..80bc69c
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Acess GUI Terminal
+ * - By John Hodge (thePowersGang)
+ *
+ * display.h
+ * - RichText Termianl Translation
+ */
+#ifndef _DISPLAY_H_
+#define _DISPLAY_H_
+
+extern void    Display_AddText(int Length, const char *UTF8Text);
+extern void    Display_Newline(int bCarriageReturn);
+extern void    Display_SetCursor(int Row, int Col);
+extern void    Display_MoveCursor(int RelRow, int RelCol);
+extern void    Display_ClearLine(int Dir);     // 0: All, 1: Forward, -1: Reverse
+extern void    Display_ClearLines(int Dir);    // 0: All, 1: Forward, -1: Reverse
+extern void    Display_SetForeground(uint32_t RGB);
+extern void    Display_SetBackground(uint32_t RGB);
+
+#endif
+
diff --git a/Usermode/Applications/gui_shell_src/include/vt100.h b/Usermode/Applications/gui_shell_src/include/vt100.h
new file mode 100644 (file)
index 0000000..13f830e
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Acess GUI Terminal
+ * - By John Hodge (thePowersGang)
+ *
+ * vt100.h
+ * - VT100/xterm emulation
+ */
+#ifndef _VT100_H_
+#define _VT100_H_
+
+/**
+ * Returns either a positive or negative byte count.
+ * Positive means that many bytes were used as part of the escape sequence
+ * and should not be sent to the display.
+ * Negative means that there were that many bytes before the next escape
+ * sequence (and hence those should be displayed).
+ */
+extern int     Term_HandleVT100(int Len, const char *Buf);
+
+
+#endif
+
diff --git a/Usermode/Applications/gui_shell_src/main.c b/Usermode/Applications/gui_shell_src/main.c
new file mode 100644 (file)
index 0000000..c7aac85
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Acess GUI Terminal
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Core
+ */
+#include <axwin3/axwin.h>
+#include <axwin3/menu.h>
+#include <axwin3/richtext.h>
+#include <stdio.h>
+#include "include/display.h"
+#include "include/vt100.h"
+
+// === PROTOTYPES ===
+ int   main(int argc, char *argv[], const char **envp);
+ int   Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated);
+ int   Term_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col);
+
+// === GLOBALS ===
+tHWND  gMainWindow;
+tHWND  gMenuWindow;
+ int   giChildStdin;
+ int   giChildStdout;
+
+// === CODE ===
+int main(int argc, char *argv[], const char **envp)
+{
+       AxWin3_Connect(NULL);
+       
+       // --- Build up window
+       gMainWindow = AxWin3_RichText_CreateWindow(NULL, 0);
+       AxWin3_SetWindowTitle(gMainWindow, "Terminal"); // TODO: Update title with other info
+
+       gMenuWindow = AxWin3_Menu_Create(gMainWindow);
+       AxWin3_Menu_AddItem(gMenuWindow, "Copy\tWin+C", NULL, NULL, 0, NULL);
+       AxWin3_Menu_AddItem(gMenuWindow, "Paste\tWin+V", NULL, NULL, 0, NULL);
+       // TODO: Populate menu  
+
+
+       // TODO: Tabs?
+       
+       AxWin3_RichText_SetKeyHandler   (gMainWindow, Term_KeyHandler);
+       AxWin3_RichText_SetMouseHandler (gMainWindow, Term_MouseHandler);
+       AxWin3_RichText_SetDefaultColour(gMainWindow, 0xFFFFFF);
+       AxWin3_RichText_SetBackground   (gMainWindow, 0x000000);
+       AxWin3_RichText_SetFont         (gMainWindow, "#monospace", 10);
+       AxWin3_RichText_SetCursorPos    (gMainWindow, 0, 0);
+       AxWin3_RichText_SetCursorType   (gMainWindow, AXWIN3_RICHTEXT_CURSOR_INV);
+       AxWin3_RichText_SetCursorBlink  (gMainWindow, 1);
+
+       // <testing>
+       AxWin3_RichText_SetLineCount(gMainWindow, 3);
+       AxWin3_RichText_SendLine(gMainWindow, 0, "First line!");
+       AxWin3_RichText_SendLine(gMainWindow, 2, "Third line! \x01""ff0000A red");
+       // </testing>
+
+       AxWin3_ResizeWindow(gMainWindow, 600, 400);
+       AxWin3_MoveWindow(gMainWindow, 50, 50);
+       AxWin3_ShowWindow(gMainWindow, 1);
+       AxWin3_FocusWindow(gMainWindow);
+
+       // Spawn shell
+       giChildStdout = open("/Devices/FIFO/anon", O_RDWR);
+       giChildStdin = open("/Devices/FIFO/anon", O_RDWR);
+
+       {
+                int    fds[] = {giChildStdin, giChildStdout, giChildStdout};
+               const char      *argv[] = {"CLIShell", NULL};
+               _SysSpawn("/Acess/Bin/CLIShell", argv, envp, 3, fds, NULL);
+       }
+
+       // Main loop
+       for( ;; )
+       {
+               fd_set  fds;
+               
+               FD_ZERO(&fds);
+               FD_SET(giChildStdout, &fds);
+               AxWin3_MessageSelect(giChildStdout + 1, &fds);
+               
+               if( FD_ISSET(giChildStdout, &fds) )
+               {
+                       // Read and update screen
+                       char    buf[32];
+                       int len = read(giChildStdout, buf, sizeof(buf));
+                       if( len <= 0 )  break;
+                       
+                       Term_HandleOutput(len, buf);
+               }
+       }
+
+       return 0;
+}
+
+int Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated)
+{
+       static int      ctrl_state = 0;
+
+       // Handle modifiers
+       #define _bitset(var,bit,set) do{if(set)var|=1<<(bit);else var&=1<<(bit);}while(0)
+       switch(KeySym)
+       {
+       case KEY_LCTRL:
+               _bitset(ctrl_state, 0, bPress);
+               return 0;
+       case KEY_RCTRL:
+               _bitset(ctrl_state, 0, bPress);
+               return 0;
+       }
+       #undef _bitset
+
+       // Handle shortcuts
+       // - Ctrl-A -- Ctrl-Z
+       if( ctrl_state && KeySym >= KEY_a && KeySym <= KEY_z )
+       {
+               Translated = KeySym - KEY_a + 1;
+       }
+
+       if( Translated )
+       {
+               // Encode and send
+               
+               return 0;
+       }
+       
+       // No translation, look for escape sequences to send
+       switch(KeySym)
+       {
+       case KEY_LEFTARROW:
+       //      str = "\x1b[D";
+               break;
+       }
+       return 0;
+}
+
+int Term_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col)
+{
+       return 0;
+}
+
+void Term_HandleOutput(int Len, const char *Buf)
+{
+       // TODO: Handle graphical / accelerated modes
+
+        int    ofs = 0;
+        int    esc_len = 0;
+
+       while( ofs < Len )
+       {
+               esc_len = Term_HandleVT100(Len - ofs, Buf + ofs);
+               if( esc_len < 0 ) {
+                       Display_AddText(-esc_len, Buf + ofs);
+                       esc_len = -esc_len;
+               }
+               Len -= esc_len;
+               ofs += esc_len;
+       }
+}
+
diff --git a/Usermode/Applications/gui_shell_src/vt100.c b/Usermode/Applications/gui_shell_src/vt100.c
new file mode 100644 (file)
index 0000000..51c8016
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Acess GUI Terminal
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Core
+ */
+#include <string.h>
+#include "include/vt100.h"
+#include "include/display.h"
+
+int Term_HandleVT100(int Len, const char *Buf)
+{
+       const int       max_length = 16;
+       static char     inc_buf[max_length]
+       static int      inc_len = 0;
+
+       if( inc_len > 0 || *Buf == '\x1b' )
+       {
+               memcpy(inc_buf + inc_len, Buf, min(max_length - inc_len, Len));
+               // Handle VT100 (like) escape sequence
+               
+               inc_len = 0;
+               return 1;
+       }
+
+       switch( *Buf )
+       {
+       case '\b':
+               // TODO: Backspace
+               return 1;
+       case '\t':
+               // TODO: tab
+               return 1;
+       case '\n':
+               Display_Newline(1);
+               return 1;
+       case '\r':
+               // TODO: Carriage return
+               return ;
+       }
+
+        int    ret = 0;
+       while( ret < Len )
+       {
+               if( *Buf == '\n' )
+                       break;
+               if( *Buf == '\x1b' )
+                       break;
+               ret ++;
+               Buf ++;
+       }
+       return -ret;
+}
index c18e5f8..51b9194 100644 (file)
@@ -32,21 +32,22 @@ int main(int argc, char *argv[])
        // - Start virtual terminals
        for( i = 0; i < NUM_TERMS; i++ )
        {               
-               tid = clone(CLONE_VM, 0);
+               tid = _SysClone(CLONE_VM, 0);
                if(tid == 0)
                {
                        termpath[sizeof(DEFAULT_TERMINAL)-2] = '0' + i;
                        
-                       open(termpath, OPENFLAG_READ);  // Stdin
-                       open(termpath, OPENFLAG_WRITE); // Stdout
-                       open(termpath, OPENFLAG_WRITE); // Stderr
-                       execve(DEFAULT_SHELL, child_argv, NULL);
-                       for(;;) sleep();
+                       _SysOpen(termpath, OPENFLAG_READ);      // Stdin
+                       _SysOpen(termpath, OPENFLAG_WRITE);     // Stdout
+                       _SysOpen(termpath, OPENFLAG_WRITE);     // Stderr
+                       _SysExecVE(DEFAULT_SHELL, child_argv, NULL);
+                       for(;;) ;
                }
        }
        
        // TODO: Implement message watching
-       for(;;) sleep();
+       for(;;)
+               _SysWaitEvent(THREAD_EVENT_IPCMSG);
        
        return 42;
 }
index cf5d5dc..2046bb0 100644 (file)
@@ -61,9 +61,9 @@ int AddInterface(const char *Device)
 {
         int    dp, ret;
        
-       dp = open(IPSTACK_ROOT, OPENFLAG_READ);
-       ret = ioctl(dp, 4, (void*)Device);
-       close(dp);
+       dp = _SysOpen(IPSTACK_ROOT, OPENFLAG_READ);
+       ret = _SysIOCtl(dp, 4, (void*)Device);
+       _SysClose(dp);
        
        if( ret < 0 ) {
                fprintf(stderr, "Unable to add '%s' as a network interface\n", Device);
@@ -94,26 +94,26 @@ int SetAddress(int IFNum, const char *Address)
        
        // Open file
        sprintf(path, IPSTACK_ROOT"/%i", IFNum);
-       fd = open(path, OPENFLAG_READ);
+       fd = _SysOpen(path, OPENFLAG_READ);
        if( fd == -1 ) {
                fprintf(stderr, "Unable to open '%s'\n", path);
                return -1;
        }
        
        tmp = type;
-       tmp = ioctl(fd, ioctl(fd, 3, "getset_type"), &tmp);
+       tmp = _SysIOCtl(fd, _SysIOCtl(fd, 3, "getset_type"), &tmp);
        if( tmp != type ) {
                fprintf(stderr, "Error in setting address type (got %i, expected %i)\n", tmp, type);
-               close(fd);
+               _SysClose(fd);
                return -1;
        }
        // Set Address
-       ioctl(fd, ioctl(fd, 3, "set_address"), addr);
+       _SysIOCtl(fd, _SysIOCtl(fd, 3, "set_address"), addr);
        
        // Set Subnet
-       ioctl(fd, ioctl(fd, 3, "getset_subnet"), &subnet);
+       _SysIOCtl(fd, _SysIOCtl(fd, 3, "getset_subnet"), &subnet);
        
-       close(fd);
+       _SysClose(fd);
        
        // Dump!
        //DumpInterface( path+sizeof(IPSTACK_ROOT)+1 );
@@ -129,15 +129,15 @@ void DumpInterfaces(void)
         int    dp;
        char    filename[FILENAME_MAX+1];
        
-       dp = open(IPSTACK_ROOT, OPENFLAG_READ);
+       dp = _SysOpen(IPSTACK_ROOT, OPENFLAG_READ);
        
-       while( SysReadDir(dp, filename) )
+       while( _SysReadDir(dp, filename) )
        {
                if(filename[0] == '.')  continue;
                DumpInterface(filename);
        }
        
-       close(dp);
+       _SysClose(dp);
 }
 
 /**
@@ -151,13 +151,13 @@ void DumpInterface(const char *Name)
        
        strcat(path, Name);
        
-       fd = open(path, OPENFLAG_READ);
+       fd = _SysOpen(path, OPENFLAG_READ);
        if(fd == -1) {
                fprintf(stderr, "Bad interface name '%s' (%s does not exist)\t", Name, path);
                return ;
        }
        
-       type = ioctl(fd, 4, NULL);
+       type = _SysIOCtl(fd, 4, NULL);
        
        // Ignore -1 values
        if( type == -1 ) {
@@ -166,10 +166,10 @@ void DumpInterface(const char *Name)
        
        printf("%s:\t", Name);
        {
-                int    call_num = ioctl(fd, 3, "get_device");
-                int    len = ioctl(fd, call_num, NULL);
+                int    call_num = _SysIOCtl(fd, 3, "get_device");
+                int    len = _SysIOCtl(fd, call_num, NULL);
                char    *buf = malloc(len+1);
-               ioctl(fd, call_num, buf);
+               _SysIOCtl(fd, call_num, buf);
                printf("'%s'\n", buf);
                free(buf);
        }
@@ -185,8 +185,8 @@ void DumpInterface(const char *Name)
                uint8_t ip[4];
                 int    subnet;
                printf("IPv4\t");
-               ioctl(fd, 5, ip);       // Get IP Address
-               subnet = ioctl(fd, 7, NULL);    // Get Subnet Bits
+               _SysIOCtl(fd, 5, ip);   // Get IP Address
+               subnet = _SysIOCtl(fd, 7, NULL);        // Get Subnet Bits
                printf("%i.%i.%i.%i/%i\n", ip[0], ip[1], ip[2], ip[3], subnet);
                }
                break;
@@ -195,8 +195,8 @@ void DumpInterface(const char *Name)
                uint16_t        ip[8];
                 int    subnet;
                printf("IPv6\t");
-               ioctl(fd, 5, ip);       // Get IP Address
-               subnet = ioctl(fd, 7, NULL);    // Get Subnet Bits
+               _SysIOCtl(fd, 5, ip);   // Get IP Address
+               subnet = _SysIOCtl(fd, 7, NULL);        // Get Subnet Bits
                printf("%x:%x:%x:%x:%x:%x:%x:%x/%i\n",
                        ntohs(ip[0]), ntohs(ip[1]), ntohs(ip[2]), ntohs(ip[3]),
                        ntohs(ip[4]), ntohs(ip[5]), ntohs(ip[6]), ntohs(ip[7]),
@@ -208,6 +208,6 @@ void DumpInterface(const char *Name)
                break;
        }
                        
-       close(fd);
+       _SysClose(fd);
 }
 
index f074bff..a5f682c 100644 (file)
@@ -12,7 +12,7 @@
 // === PROTOTYPES ===
  int   Routes_main(int argc, char *argv[]);
 void   DumpRoutes(void);
-void   DumpRoute(const char *Name);
+void   DumpRoute(int PFD, const char *Name);
 void   AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, int Metric, void *NextHop);
 
 // === CODE ===
@@ -50,15 +50,15 @@ int Routes_main(int argc, char *argv[])
                }
                
                // Destination IP
-               addrType = ParseIPAddress(argv[3], dest, &subnetBits);
+               addrType = ParseIPAddress(argv[2], dest, &subnetBits);
                if( subnetBits == -1 ) {
                        subnetBits = Net_GetAddressSize(addrType)*8;
                }
                // Interface Name / Next Hop
-               if( (nextHopType = ParseIPAddress(argv[4], nextHop, &nextHopBits)) == 0 )
+               if( (nextHopType = ParseIPAddress(argv[3], nextHop, &nextHopBits)) == 0 )
                {
                        // Interface name
-                       ifaceName = argv[4];
+                       ifaceName = argv[3];
                }
                else
                {
@@ -78,8 +78,8 @@ int Routes_main(int argc, char *argv[])
                // Metric
                if( argc - 3 >= 3 )
                {
-                       metric = atoi(argv[5]);
-                       if( metric == 0 && argv[5][0] != '0' ) {
+                       metric = atoi(argv[4]);
+                       if( metric == 0 && argv[4][0] != '0' ) {
                                fprintf(stderr, "ERROR: Metric should be a number\n");
                                return -1;
                        }
@@ -114,33 +114,30 @@ void DumpRoutes(void)
         int    dp;
        char    filename[FILENAME_MAX+1];
        
-       dp = open(IPSTACK_ROOT"/routes", OPENFLAG_READ);
+       dp = _SysOpen(IPSTACK_ROOT"/routes", OPENFLAG_READ);
        
        printf("Type\tNetwork \tGateway \tMetric\tIFace\n");
        
-       while( SysReadDir(dp, filename) )
+       while( _SysReadDir(dp, filename) )
        {
                if(filename[0] == '.')  continue;
-               DumpRoute(filename);
+               DumpRoute(dp, filename);
        }
        
-       close(dp);
+       _SysClose(dp);
 }
 
 /**
  * \brief Dump a route
  */
-void DumpRoute(const char *Name)
+void DumpRoute(int PFD, const char *Name)
 {
         int    fd;
         int    type;
-       char    path[sizeof(IPSTACK_ROOT)+8+FILENAME_MAX+1] = IPSTACK_ROOT"/routes/";
        
-       strcat(path, Name);
-       
-       fd = open(path, OPENFLAG_READ);
+       fd = _SysOpenChild(PFD, Name, OPENFLAG_READ);
        if(fd == -1) {
-               printf("%s:\tUnable to open ('%s')\n", Name, path);
+               printf("%s:\tUnable to open\n", Name);
                return ;
        }
        
@@ -161,7 +158,7 @@ void DumpRoute(const char *Name)
        subnet = atoi(Name+ofs);
        ofs ++;
        metric = atoi(Name+ofs);
-       ioctl(fd, ioctl(fd, 3, "get_nexthop"), gw);     // Get Gateway/NextHop
+       _SysIOCtl(fd, _SysIOCtl(fd, 3, "get_nexthop"), gw);     // Get Gateway/NextHop
        
        // Get the address type
        switch(type)
@@ -185,17 +182,17 @@ void DumpRoute(const char *Name)
        
        // Interface
        {
-                int    call_num = ioctl(fd, 3, "get_interface");
-                int    len = ioctl(fd, call_num, NULL);
+                int    call_num = _SysIOCtl(fd, 3, "get_interface");
+                int    len = _SysIOCtl(fd, call_num, NULL);
                char    *buf = malloc(len+1);
-               ioctl(fd, call_num, buf);
+               _SysIOCtl(fd, call_num, buf);
                printf("'%s'\t", buf);
                free(buf);
        }
        
        printf("\n");
                        
-       close(fd);
+       _SysClose(fd);
 }
 
 void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, int Metric, void *NextHop)
@@ -227,20 +224,20 @@ void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits,
                // Open interface
                strcpy(ifacePath, IPSTACK_ROOT"/");
                strcat(ifacePath, Interface);
-               fd = open(ifacePath, 0);
+               fd = _SysOpen(ifacePath, 0);
                if( fd == -1 ) {
                        fprintf(stderr, "Error: Interface '%s' does not exist\n", Interface);
                        return ;
                }
                // Get and check type
-               num = ioctl(fd, ioctl(fd, 3, "getset_type"), NULL);
+               num = _SysIOCtl(fd, _SysIOCtl(fd, 3, "getset_type"), NULL);
                if( num != AddressType ) {
                        fprintf(stderr, "Error: Passed type does not match interface type (%i != %i)\n",
                                AddressType, num);
                        return ;
                }
                
-               close(fd);
+               _SysClose(fd);
        }
        
        // Create route
@@ -256,23 +253,23 @@ void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits,
                sprintf(path+ofs, ":%i:%i", MaskBits, Metric);
        }
 
-       fd = open(path, 0);
+       fd = _SysOpen(path, 0);
        if( fd != -1 ) {
-               close(fd);
+               _SysClose(fd);
                fprintf(stderr, "Unable to create route '%s', already exists\n", path);
                return ;
        }
-       fd = open(path, OPENFLAG_CREATE, 0);
+       fd = _SysOpen(path, OPENFLAG_CREATE, 0);
        if( fd == -1 ) {
                fprintf(stderr, "Unable to create '%s'\n", path);
                return ;
        }
        
        if( NextHop )
-               ioctl(fd, ioctl(fd, 3, "set_nexthop"), NextHop);
-       ioctl(fd, ioctl(fd, 3, "set_interface"), (void*)Interface);
+               _SysIOCtl(fd, _SysIOCtl(fd, 3, "set_nexthop"), NextHop);
+       _SysIOCtl(fd, _SysIOCtl(fd, 3, "set_interface"), (void*)Interface);
        
-       close(fd);
+       _SysClose(fd);
        
        // Check if the interface name was allocated by us
        if( ifaceToFree )
index 901e8ac..9e5a075 100644 (file)
@@ -102,8 +102,8 @@ int main(int argc, const char *argv[], const char *envp[])
        \r
        atexit(ExitHandler);\r
        \r
-       giTerminal_Width = ioctl(1, 5, NULL);   // getset_width\r
-       giTerminal_Height = ioctl(1, 6, NULL);  // getset_height\r
+       giTerminal_Width = _SysIOCtl(1, 5, NULL);       // getset_width\r
+       giTerminal_Height = _SysIOCtl(1, 6, NULL);      // getset_height\r
        \r
        printf("\x1B[?1047h");\r
        printf("\x1B[%i;%ir", 0, giTerminal_Height-1);\r
@@ -194,7 +194,7 @@ int main(int argc, const char *argv[], const char *envp[])
        {\r
                tServer *srv;\r
                for( srv = gpServers; srv; srv = srv->Next )\r
-                       close(srv->FD);\r
+                       _SysClose(srv->FD);\r
        }\r
        return 0;\r
 }\r
@@ -659,11 +659,11 @@ int ProcessIncoming(tServer *Server)
        // ioctl#8 on a TCP client gets the number of bytes in the recieve buffer\r
        // - Used to avoid blocking\r
        #if NON_BLOCK_READ\r
-       while( (len = ioctl(Server->FD, 8, NULL)) > 0 )\r
+       while( (len = _SysIOCtl(Server->FD, 8, NULL)) > 0 )\r
        {\r
        #endif\r
                // Read data\r
-               len = read(Server->FD, &Server->InBuf[Server->ReadPos], BUFSIZ - Server->ReadPos);\r
+               len = _SysRead(Server->FD, &Server->InBuf[Server->ReadPos], BUFSIZ - Server->ReadPos);\r
                if( len == -1 ) {\r
                        return -1;\r
                }\r
@@ -717,7 +717,7 @@ int writef(int FD, const char *Format, ...)
                vsnprintf(buf, len+1, Format, args);\r
                va_end(args);\r
                \r
-               return write(FD, buf, len);\r
+               return _SysWrite(FD, buf, len);\r
        }\r
 }\r
 \r
@@ -747,12 +747,12 @@ int OpenTCP(const char *AddressString, short PortNumber)
        \r
        // Set remote port and address\r
 //     printf("Setting port and remote address\n");\r
-       ioctl(fd, 5, &PortNumber);\r
-       ioctl(fd, 6, addrBuffer);\r
+       _SysIOCtl(fd, 5, &PortNumber);\r
+       _SysIOCtl(fd, 6, addrBuffer);\r
        \r
        // Connect\r
 //     printf("Initiating connection\n");\r
-       if( ioctl(fd, 7, NULL) == 0 ) {\r
+       if( _SysIOCtl(fd, 7, NULL) == 0 ) {\r
                // Shouldn't happen :(\r
                fprintf(stderr, "Unable to start connection\n");\r
                return -1;\r
@@ -797,7 +797,7 @@ int SetCursorPos(int Row, int Col)
                Row = Col / giTerminal_Width;\r
                Col = Col % giTerminal_Width;\r
        }\r
-       rv = ioctl(1, 9, NULL); // Ugh, constants\r
+       rv = _SysIOCtl(1, 9, NULL);     // Ugh, constants\r
        printf("\x1B[%i;%iH", Col, Row);\r
        return rv;\r
 }\r
index e859bfe..59b4a78 100644 (file)
@@ -38,36 +38,24 @@ int main(int argc, char *argv[])
                                break;
                }
                printf("\n");
-               
-               // Create child process
-               pid = clone(CLONE_VM, 0);
+
+               uinfo = GetUserInfo(uid);
+               struct s_sys_spawninfo  spawninfo;
+               spawninfo.flags = 0;
+               spawninfo.gid = uinfo->GID;
+               spawninfo.uid = uinfo->UID;
+               const char      *child_argv[2] = {"-", 0};
+               const char      **child_envp = NULL;
+                int    fds[] = {0, 1, 2};
+               pid = _SysSpawn(uinfo->Shell, child_argv, child_envp, 3, fds, &spawninfo);
                // Error check
                if(pid == -1) {
                        fprintf(stderr, "Unable to fork the login process!\n");
                        return -1;
                }
                
-               // Spawn shell in a child process
-               if(pid == 0)
-               {
-                       char    *child_argv[2] = {NULL, 0};
-                       char    **child_envp = NULL;
-                       
-                       // Get user information
-                       uinfo = GetUserInfo(uid);
-                       
-                       child_argv[0] = uinfo->Shell;
-                       // Set Environment
-                       setgid(uinfo->GID);
-                       //setuid(uid);
-                       setuid(uinfo->UID);
-                       
-                       execve(uinfo->Shell, child_argv, child_envp);
-                       exit(-1);
-               }
-               
                // Wait for child to terminate
-               waittid(pid, &status);
+               _SysWaitTID(pid, &status);
        }
        
        return 0;
index 2394af6..973013b 100644 (file)
@@ -51,17 +51,17 @@ int main(int argc, char *argv[])
        ParseArguments(argc, argv);
 
        // Open Directory
-       fd = open(gsDirectory, OPENFLAG_READ|OPENFLAG_EXEC);
+       fd = _SysOpen(gsDirectory, OPENFLAG_READ|OPENFLAG_EXEC);
        if(fd == -1) {
                printf("Unable to open '%s' for reading\n", gsDirectory);
                return EXIT_FAILURE;
        }
 
        // Check that it is a directory
-       finfo(fd, &info, 0);
+       _SysFInfo(fd, &info, 0);
        if( !(info.flags & FILEFLAG_DIRECTORY) ) {
                fprintf(stderr, "'%s' is not a directory\n", gsDirectory);
-               close(fd);
+               _SysClose(fd);
                return EXIT_FAILURE;
        }
 
@@ -75,11 +75,11 @@ int main(int argc, char *argv[])
        }
 
        // Traverse Directory
-       while( (tmp = SysReadDir(fd, buf)) > 0 )
+       while( (tmp = _SysReadDir(fd, buf)) > 0 )
        {
                // Error check
                if(tmp < 0) {
-                       close(fd);
+                       _SysClose(fd);
                        return EXIT_FAILURE;
                }
                
@@ -89,7 +89,7 @@ int main(int argc, char *argv[])
                        space += 16;
                        gFileList = realloc(gFileList, space*sizeof(char*));
                        if(gFileList == NULL) {
-                               close(fd);
+                               _SysClose(fd);
                                return EXIT_FAILURE;
                        }
                }
@@ -105,7 +105,7 @@ int main(int argc, char *argv[])
                DisplayFile( gFileList[i] );
        }
 
-       close(fd);
+       _SysClose(fd);
        printf("\n");
 
        return EXIT_SUCCESS;
@@ -218,13 +218,13 @@ void DisplayFile(char *Filename)
        strcpy(&path[dirLen+1], Filename);
        
        // Get file type
-       fd = open(path, 0);
+       fd = _SysOpen(path, 0);
        if(fd == -1) {
                fprintf(stderr, "Unable to open '%s'\n", path);
        }
        else {
                // Get Info
-               finfo(fd, &info, 0);
+               _SysFInfo(fd, &info, 0);
                // Get Type
                if(info.flags & FILEFLAG_DIRECTORY) {
                        type = FTYPE_DIR;
@@ -262,7 +262,7 @@ void DisplayFile(char *Filename)
                if(acl.perms & 8)       perms |= 0001;  // X
                
                // Close file
-               close(fd);
+               _SysClose(fd);
        }
        free(path);     // We're finished with it
        
index c24fde9..44dc61a 100644 (file)
@@ -6,7 +6,6 @@
  */
 #include <stdlib.h>
 #include <stdio.h>
-#include <unistd.h>
 #include <acess/sys.h>
 
 #define PCI_BASE       "/Devices/pci"
@@ -17,17 +16,19 @@ void        show_device(int PFD, const char *File, int bVerbose);
 // === CODE ===
 int main(int argc, char *argv[])
 {
-       int fd = open(PCI_BASE, OPENFLAG_READ);
+       int fd = _SysOpen(PCI_BASE, OPENFLAG_READ);
 
        char name[256]; 
 
-       while( SysReadDir(fd, name) )
+       while( _SysReadDir(fd, name) )
        {
                if(name[0] == '.')      continue ;
                
                show_device(fd, name, 0);
        }
 
+       _SysClose(fd);
+
        return 0;
 }
 
@@ -48,10 +49,10 @@ void show_device(int PFD, const char *File, int bVerbose)
                printf("%s - ERR (open failure)\n", File);
                return ;
        }
-       rv = read(fd, &pciinfo, sizeof(pciinfo));
+       rv = _SysRead(fd, &pciinfo, sizeof(pciinfo));
        if( rv != sizeof(pciinfo) ) {
                printf("%s - ERR (read %i < %i)\n", File, rv, sizeof(pciinfo));
-               close(fd);
+               _SysClose(fd);
                return ;
        }
        uint32_t        class_if = pciinfo.revclass >> 8;
@@ -67,6 +68,6 @@ void show_device(int PFD, const char *File, int bVerbose)
                printf("\n");
        }
 
-       close(fd);
+       _SysClose(fd);
 }
 
index a272214..1a1fc7b 100644 (file)
@@ -22,10 +22,12 @@ int main(int argc, char *argv[])
         int    fd;
         int    i;
        char    *arg;
+       
        char    *sType = NULL;
        char    *sDevice = NULL;
        char    *sDir = NULL;
        char    *sOptions = NULL;
+        int    bUnmount = 0;
 
        // List mounted filesystems
        // - This is cheating, isn't it?
@@ -56,7 +58,10 @@ int main(int argc, char *argv[])
                        {
                        // -t <driver> :: Filesystem driver to use
                        case 't':       sType = argv[++i];      break;
+                       // -o option_list :: Options to pass the driver
                        case 'o':       sOptions = argv[++i];   break;
+                       // -u :: Unmount
+                       case 'u':       bUnmount = 1;   break;
                        case '-':
                                //TODO: Long Arguments
                        default:
@@ -82,6 +87,22 @@ int main(int argc, char *argv[])
                return EXIT_FAILURE;
        }
 
+       if( bUnmount )
+       {
+               // TODO: Check for a match in the fstab
+               
+               if( sDir ) {
+                       fprintf(stderr, "`mount -u` takes one argument\n");
+               }
+               
+               sDir = sDevice;
+               if( _SysMount(NULL, sDir, NULL, NULL) ) // Unmount (Dev=NULL means unmount)
+               {
+                       fprintf(stderr, "Unmount failed\n");
+               }
+               return EXIT_SUCCESS;
+       }
+
        // Check if we even got a device/mountpoint
        if(sDevice == NULL) {
                ShowUsage(argv[0]);
@@ -121,28 +142,32 @@ int main(int argc, char *argv[])
        }
        
        // Check Device
-       fd = open(sDevice, OPENFLAG_READ);
+       fd = _SysOpen(sDevice, OPENFLAG_READ);
        if(fd == -1) {
                printf("Device '%s' cannot be opened for reading\n", sDevice);
                return EXIT_FAILURE;
        }
-       close(fd);
+       _SysClose(fd);
        
        // Check Mount Point
-       fd = open(sDir, OPENFLAG_EXEC);
+       fd = _SysOpen(sDir, OPENFLAG_EXEC);
        if(fd == -1) {
                printf("Directory '%s' does not exist\n", sDir);
                return EXIT_FAILURE;
        }
-       close(fd);
+       _SysClose(fd);
 
        // Replace sOptions with an empty string if it is still NULL
        if(sOptions == NULL)    sOptions = "";
 
        // Let's Mount!
        if( _SysMount(sDevice, sDir, sType, sOptions) ) {
+//             perror("_SysMount");
                if( !sType )
                        fprintf(stderr, "Filesystem autodetection failed, please pass a type\n");
+               else {
+                       fprintf(stderr, "Mount %s:'%s'=>'%s' failed\n", sType, sDevice, sDir);
+               }
        }
 
        return 0;
index 7686e5c..7c10e57 100644 (file)
@@ -88,7 +88,7 @@ int main(int argc, char *argv[])
                free(iface);    // TODO: Handle when this is not heap
                iface = _iface;
                printf("iface = '%s'\n", iface);
-               fd = open(iface, OPENFLAG_EXEC);
+               fd = _SysOpen(iface, OPENFLAG_EXEC);
                if(fd == -1) {
                        fprintf(stderr, "ERROR: Unable to open interface '%s'\n", iface);
                        return 1;
@@ -106,7 +106,7 @@ int main(int argc, char *argv[])
                }
        }
        
-       call = ioctl(fd, 3, "ping");
+       call = _SysIOCtl(fd, 3, "ping");
        if(call == 0) {
                fprintf(stderr, "ERROR: '%s' does not have a 'ping' call\n", iface);
                return 1;
@@ -114,11 +114,11 @@ int main(int argc, char *argv[])
        
        for( i = 0; i < giNumberOfPings; i ++ )
        {
-               ping = ioctl(fd, call, addr);
+               ping = _SysIOCtl(fd, call, addr);
                printf("ping = %i\n", ping);
        }
                
-       close(fd);
+       _SysClose(fd);
        
        return 0;
 }
index 3fdbf00..708935d 100644 (file)
@@ -62,8 +62,8 @@ int main(int argc, char *argv[], char *envp[])
                        // Read from server, and write to stdout\r
                        do\r
                        {\r
-                               len = read(server_fd, buffer, BUFSIZ);\r
-                               write(1, buffer, len);\r
+                               len = _SysRead(server_fd, buffer, BUFSIZ);\r
+                               _SysWrite(1, buffer, len);\r
                        } while( len == BUFSIZ );\r
                }\r
                \r
@@ -76,17 +76,17 @@ int main(int argc, char *argv[], char *envp[])
                                char    *line = Readline_NonBlock(readline_info);\r
                                if( line )\r
                                {\r
-                                       write(server_fd, line, strlen(line));\r
-                                       write(server_fd, "\n", 1);\r
+                                       _SysWrite(server_fd, line, strlen(line));\r
+                                       _SysWrite(server_fd, "\n", 1);\r
                                }\r
                        }\r
                        else\r
                        {\r
                                do\r
                                {\r
-                                       len = read(0, buffer, BUFSIZ);\r
-                                       write(server_fd, buffer, len);\r
-                                       write(1, buffer, len);\r
+                                       len = _SysRead(0, buffer, BUFSIZ);\r
+                                       _SysWrite(server_fd, buffer, len);\r
+                                       _SysWrite(1, buffer, len);\r
                                } while( len == BUFSIZ );\r
                        }\r
                }\r
@@ -99,7 +99,7 @@ int main(int argc, char *argv[], char *envp[])
                }\r
        }\r
        \r
-       close(server_fd);\r
+       _SysClose(server_fd);\r
        return 0;\r
 }\r
 \r
@@ -127,11 +127,11 @@ int OpenTCP(const char *AddressString, short PortNumber)
        }\r
        \r
        // Set remote port and address\r
-       ioctl(fd, 5, &PortNumber);\r
-       ioctl(fd, 6, addrBuffer);\r
+       _SysIOCtl(fd, 5, &PortNumber);\r
+       _SysIOCtl(fd, 6, addrBuffer);\r
        \r
        // Connect\r
-       if( ioctl(fd, 7, NULL) == 0 ) {\r
+       if( _SysIOCtl(fd, 7, NULL) == 0 ) {\r
                fprintf(stderr, "Unable to start connection\n");\r
                return -1;\r
        }\r
index 8a66ad7..a4f5e0d 100644 (file)
@@ -1,9 +1,14 @@
 /*
+ * Acess2 Telnet Server (TCP server test case)
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - All
  */
 #include <stddef.h>
 #include <net.h>
-#include <unistd.h>
 #include <stdio.h>
+#include <acess/sys.h>
 
 // === TYPES ===
 typedef struct sClient
@@ -41,7 +46,7 @@ int main(int argc, char *argv[])
                 int    addrtype = Net_ParseAddress("10.0.2.10", data);
                 int    port = 23;
                giServerFD = Net_OpenSocket(addrtype, data, "tcps");
-               ioctl(giServerFD, 4, &port);    // Set port and start listening
+               _SysIOCtl(giServerFD, 4, &port);        // Set port and start listening
        }
 
        // Event loop
@@ -77,7 +82,7 @@ void EventLoop(void)
                }
                
                // Select!
-               select( maxfd+1, &fds, NULL, NULL, NULL );
+               _SysSelect( maxfd+1, &fds, NULL, NULL, NULL, 0 );
                
                // Check events
                if( FD_ISSET(giServerFD, &fds) )
@@ -108,7 +113,7 @@ void Server_NewClient(int FD)
        if( giNumClients == giConfig_MaxClients )
        {
                // Open, reject
-               close( _SysOpenChild(FD, "", O_RDWR) );
+               _SysClose( _SysOpenChild(FD, "", OPENFLAG_READ) );
                return ;
        }
        
@@ -121,18 +126,18 @@ void Server_NewClient(int FD)
                }
        }
        // Accept the connection
-       clt->Socket = _SysOpenChild(FD, "", O_RDWR);
+       clt->Socket = _SysOpenChild(FD, "", OPENFLAG_READ|OPENFLAG_WRITE);
        giNumClients ++;
        
        // Create stdin/stdout
-       clt->stdin = open("/Devices/fifo/anon", O_RDWR);
-       clt->stdout = open("/Devices/fifo/anon", O_RDWR);
+       clt->stdin = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
+       clt->stdout = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
        
        // TODO: Arguments and envp
        {
                int fds[3] = {clt->stdin, clt->stdout, clt->stdout};
                const char      *argv[] = {NULL};
-               _SysSpawn("/Acess/SBin/login", argv, argv, 3, fds);
+               _SysSpawn("/Acess/SBin/login", argv, argv, 3, fds, NULL);
        }
 }
 
@@ -141,9 +146,9 @@ void HandleServerBoundData(tClient *Client)
        char    buf[BUFSIZ];
         int    len;
        
-       len = read(Client->Socket, buf, BUFSIZ);
+       len = _SysRead(Client->Socket, buf, BUFSIZ);
        if( len <= 0 )  return ;
-       write(Client->stdin, buf, len);
+       _SysWrite(Client->stdin, buf, len);
 }
 
 void HandleClientBoundData(tClient *Client)
@@ -151,8 +156,8 @@ void HandleClientBoundData(tClient *Client)
        char    buf[BUFSIZ];
         int    len;
        
-       len = read(Client->stdout, buf, BUFSIZ);
+       len = _SysRead(Client->stdout, buf, BUFSIZ);
        if( len <= 0 )  return ;
-       write(Client->Socket, buf, len);
+       _SysWrite(Client->Socket, buf, len);
 }
 
index 3410840..9b5391f 100644 (file)
@@ -11,6 +11,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <netdb.h>
+#include <acess/sys.h> // _SysDebug
 
 enum eProcols
 {
@@ -164,7 +165,7 @@ int main(int argc, char *argv[])
                        if( state == 2 )
                        {
                                _SysDebug("RXing %i bytes to '%s'", bytes_wanted, outfile);
-                                int    outfd = open(outfile, O_WR|O_CREAT, 0666);
+                                int    outfd = open(outfile, O_WRONLY|O_CREAT, 0666);
                                if( outfd == -1 ) {
                                        fprintf(stderr, "Unable to open '%s' for writing\n", outfile);
                                }
index e252210..7160075 100644 (file)
@@ -38,13 +38,13 @@ $(_BIN): $(OBJ) $(_LIBS)
        @mkdir -p $(dir $(_BIN))
        @echo [LD] -o $(BIN) $(OBJ)
        @$(LD) $(LDFLAGS) -o $(_BIN) $(OBJ) $(shell $(CC) -print-libgcc-file-name)
-       @$(DISASM) -S $(_BIN) > $(_OBJPREFIX)$(BIN).dsm
+       @$(DISASM) -D -S $(_BIN) > $(_OBJPREFIX)$(BIN).dsm
 
 $(_OBJPREFIX)%.o: %.c
        @echo [CC] -o $@
        @mkdir -p $(dir $@)
        @$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
-       @$(CC) -M -MT $@ $(CPPFLAGS) $< -o [email protected]
+       @$(CC) -M -MP -MT $@ $(CPPFLAGS) $< -o [email protected]
 
 $(_OBJPREFIX)%.ao: %.$(ASSUFFIX)
        @echo [AS] -o $@
index d451b2c..c77ff05 100644 (file)
@@ -12,7 +12,7 @@ EXTRACLEAN := $(_OBJPREFIX)_stublib.o
 INCFILES := sys/sys.h
 
 CFLAGS   = -g -Wall -fno-builtin -fno-leading-underscore -fno-stack-protector -fPIC
-CFLAGS  += $(CPPFLAGS)
+CFLAGS  += $(CPPFLAGS) -Werror
 LDFLAGS  = -g -T arch/$(ARCHDIR).ld -Map map.txt --export-dynamic
 
 include ../Makefile.tpl
index 1136226..69a392d 100644 (file)
@@ -11,6 +11,7 @@ int _errno;
 #define SYSCALL5(name,num)     void name(void){}
 #define SYSCALL6(name,num)     void name(void){}
 
+#define NO_SYSCALL_STRS
 #include "arch/syscalls.s.h"
 
 // libgcc functions
index 9132c02..2c85b14 100644 (file)
@@ -39,29 +39,29 @@ __clear_cache:
        svc #0x1001
        mov pc, lr
 
-@ DEST
-@ SRC
-@_memcpy:
-@      push rbp
-@      mov rbp, rsp
-@      
-@      ; RDI - First Param
-@      ; RSI - Second Param
-@      mov rcx, rdx    ; RDX - Third
-@      rep movsb
-@      
-@      pop rbp
-@      ret
-@
+
+@ >r0: PC
+@ >r1: Pointer to item count
+@ <r0: Address
+@ STUBBED
+__gnu_Unwind_Find_exidx:
+       mov r0, #0
+       str r0, [r1]
+       mov pc, lr
+
+.section .data
 .globl _errno
 _errno:        .long   0       @ Placed in .text, to allow use of relative addressing
+.section .text
 
 .macro syscall0 _name, _num    
 .globl \_name
 \_name:
        push {lr}
        svc #\_num
-       str r2, _errno
+       @mrc p15, 0, r3, c13, c0, 2
+       ldr r3, =_errno
+       str r2, [r3]
        pop {pc}
 .endm
 
@@ -71,7 +71,8 @@ _errno:       .long   0       @ Placed in .text, to allow use of relative addressing
        push {r4, lr}
        ldr r4, [sp,#8]
        svc #\_num
-       str r2, _errno
+       ldr r3, =_errno
+       str r2, [r3]
        pop {r4, pc}
 .endm
 
@@ -82,7 +83,8 @@ _errno:       .long   0       @ Placed in .text, to allow use of relative addressing
        ldr r4, [sp,#12]
        ldr r5, [sp,#16]
        svc #\_num
-       str r2, _errno
+       ldr r3, =_errno
+       str r2, [r3]
        pop {r4,r5,pc}
 .endm
 
@@ -107,7 +109,8 @@ _clone:
        push {r4}
        mov r4, r1
        svc #SYS_CLONE
-       str r2, _errno
+       ldr r3, =_errno
+       str r2, [r3]
        tst r4, r4
        beq _clone_ret
        @ If in child, set SP
index c138784..fdbfb02 100644 (file)
@@ -44,11 +44,13 @@ SECTIONS {
                *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
        }
 
+       __exidx_start = .;
        .text : AT(ADDR(.text)) {
                code = .;
                *(.text)
                *(.rodata*)
        }
+       __exidx_end = .;
 
        .data ALIGN (0x1000) : AT(ADDR(.data)) {
                data = .;
index aef2247..78d34bf 100644 (file)
@@ -3,12 +3,12 @@
 // --- Process Control ---
 SYSCALL1(_exit, SYS_EXIT)
 
-SYSCALL2(clone, SYS_CLONE)
-SYSCALL2(kill, SYS_KILL)
-SYSCALL0(yield, SYS_YIELD)
-SYSCALL0(sleep, SYS_SLEEP)
+SYSCALL2(_SysClone, SYS_CLONE)
+SYSCALL2(_SysKill, SYS_KILL)
+//SYSCALL0(yield, SYS_YIELD)
+//SYSCALL0(sleep, SYS_SLEEP)
 SYSCALL1(_SysWaitEvent, SYS_WAITEVENT)
-SYSCALL2(waittid, SYS_WAITTID)
+SYSCALL2(_SysWaitTID, SYS_WAITTID)
 
 SYSCALL0(gettid, SYS_GETTID)
 SYSCALL0(getpid, SYS_GETPID)
@@ -18,39 +18,41 @@ SYSCALL0(getgid, SYS_GETGID)
 SYSCALL1(setuid, SYS_SETUID)
 SYSCALL1(setgid, SYS_SETGID)
 
-SYSCALL1(SysSetName, SYS_SETNAME)
-SYSCALL2(SysGetName, SYS_GETNAME)
+SYSCALL1(_SysSetName, SYS_SETNAME)
+SYSCALL2(_SysGetName, SYS_GETNAME)
 SYSCALL0(_SysTimestamp, SYS_GETTIME)
 
-SYSCALL1(SysSetPri, SYS_SETPRI)
+SYSCALL1(_SysSetPri, SYS_SETPRI)
 
-SYSCALL3(SysSendMessage, SYS_SENDMSG)
-SYSCALL3(SysGetMessage, SYS_GETMSG)
+SYSCALL3(_SysSendMessage, SYS_SENDMSG)
+SYSCALL3(_SysGetMessage, SYS_GETMSG)
 
 SYSCALL5(_SysSpawn, SYS_SPAWN)
-SYSCALL3(execve, SYS_EXECVE)
-SYSCALL2(SysLoadBin, SYS_LOADBIN)
-SYSCALL1(SysUnloadBin, SYS_UNLOADBIN)
+SYSCALL3(_SysExecVE, SYS_EXECVE)
+SYSCALL2(_SysLoadBin, SYS_LOADBIN)
+SYSCALL1(_SysUnloadBin, SYS_UNLOADBIN)
 
 SYSCALL1(_SysSetFaultHandler, SYS_SETFAULTHANDLER)
 
 SYSCALL6(_SysDebug, 0x100)
 SYSCALL1(_SysGetPhys, SYS_GETPHYS)     // uint64_t _SysGetPhys(uint addr)
 SYSCALL1(_SysAllocate, SYS_ALLOCATE)   // uint64_t _SysAllocate(uint addr)
+SYSCALL3(_SysSetMemFlags, SYS_SETFLAGS)        // uint32_t SysSetMemFlags(uint addr, uint flags, uint mask)
 // VFS System calls
-SYSCALL2(open, SYS_OPEN)       // char*, int
-SYSCALL3(reopen, SYS_REOPEN)   // int, char*, int
-SYSCALL1(close, SYS_CLOSE)     // int
-SYSCALL3(read, SYS_READ)       // int, uint, void*
-SYSCALL3(write, SYS_WRITE)     // int, uint, void*
-SYSCALL4(seek, SYS_SEEK)       // int, uint64_t, int
-SYSCALL1(tell, SYS_TELL)       // int
-SYSCALL3(finfo, SYS_FINFO)     // int, void*, int
-SYSCALL2(SysReadDir, SYS_READDIR)      // int, char*
+SYSCALL2(_SysOpen, SYS_OPEN)   // char*, int
+SYSCALL3(_SysOpenChild, SYS_OPENCHILD) // int, char*, int
+SYSCALL3(_SysReopen, SYS_REOPEN)       // int, char*, int
+SYSCALL1(_SysClose, SYS_CLOSE) // int
+SYSCALL3(_SysRead, SYS_READ)   // int, uint, void*
+SYSCALL3(_SysWrite, SYS_WRITE) // int, uint, void*
+SYSCALL4(_SysSeek, SYS_SEEK)   // int, uint64_t, int
+SYSCALL1(_SysTell, SYS_TELL)   // int
+SYSCALL3(_SysFInfo, SYS_FINFO) // int, void*, int
+SYSCALL2(_SysReadDir, SYS_READDIR)     // int, char*
 SYSCALL2(_SysGetACL,SYS_GETACL)        // int, void*
-SYSCALL1(chdir, SYS_CHDIR)     // char*
-SYSCALL3(ioctl, SYS_IOCTL)     // int, int, void*
+SYSCALL1(_SysChdir, SYS_CHDIR) // char*
+SYSCALL3(_SysIOCtl, SYS_IOCTL) // int, int, void*
 SYSCALL4(_SysMount, SYS_MOUNT) // char*, char*, char*, char*
 SYSCALL6(_SysSelect, SYS_SELECT)       // int, fd_set*, fd_set*, fd_set*, tTime*, uint32_t
+SYSCALL1(_SysUnlink, SYS_UNLINK)       // const char*
 
-SYSCALL3(_SysOpenChild, SYS_OPENCHILD)
index 6f67811..125d1e5 100644 (file)
@@ -10,6 +10,7 @@
 #include <stddef.h>
 #include <stdarg.h>
 #include <stdint.h>
+#include <acess/sys.h>
 
 typedef        uintptr_t       Uint;
 typedef uint8_t        Uint8;
@@ -39,7 +40,7 @@ extern void   *DoRelocate(void *Base, char **envp, const char *Filename);
 // === Library/Symbol Manipulation ==
 extern void    *LoadLibrary(const char *Filename, const char *SearchDir, char **envp);
 extern void    AddLoaded(const char *File, void *base);
-extern void    *GetSymbol(const char *name, size_t *size);
+extern int     GetSymbol(const char *Name, void **Value, size_t *size);
 extern int     GetSymbolFromBase(void *base, const char *name, void **ret, size_t *size);
 
 // === Library Functions ===
@@ -51,14 +52,6 @@ extern int   file_exists(const char *filename);
 extern void    *memcpy(void *dest, const void *src, size_t len);
 
 // === System Calls ===
-extern void    _exit(int retval);
-extern void    SysDebug(const char *fmt, ...); //!< Now implemented in main.c
-extern void    SysDebugV(const char *fmt, ...);
-extern void    *SysLoadBin(const char *path, void **entry);
-extern int     SysUnloadBin(void *Base);
-extern void    SysSetFaultHandler(int (*Hanlder)(int));
-extern int     open(const char *filename, int flags, ...);
-extern int     close(int fd);
 
 // === ELF Loader ===
 extern void    *ElfRelocate(void *Base, char **envp, const char *Filename);
index 92237ea..13347a6 100644 (file)
@@ -9,6 +9,10 @@
 # define DEBUG 0
 #endif
 
+#ifndef PAGE_SIZE
+# define PAGE_SIZE     4096
+#endif
+
 #include "common.h"
 #include <stdint.h>
 #include "elf32.h"
@@ -35,8 +39,9 @@ void  *ElfRelocate(void *Base, char **envp, const char *Filename);
  int   ElfGetSymbol(void *Base, const char *Name, void **Ret, size_t *Size);
 void   *Elf32Relocate(void *Base, char **envp, const char *Filename);
  int   Elf32GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size);
-void   elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff);
-void   elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff);
+ int   elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff);
+ int   elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff);
+ int   elf_doRelocate_unk(uint32_t , uint32_t *, Elf32_Addr , int , int , const char *, intptr_t);
 #ifdef SUPPORT_ELF64
 void   *Elf64Relocate(void *Base, char **envp, const char *Filename);
  int   Elf64GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size);
@@ -87,26 +92,28 @@ int ElfGetSymbol(void *Base, const char *Name, void **ret, size_t *Size)
        }
 }
 
-void elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff)
+int elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type,
+               int bRela, const char *Sym, intptr_t iBaseDiff)
 {
-       intptr_t        val;
+       void    *symval;
        switch( type )
        {
        // Standard 32 Bit Relocation (S+A)
        case R_386_32:
-               val = (intptr_t) GetSymbol(Sym, NULL);
-               DEBUGS(" elf_doRelocate: R_386_32 *0x%x += 0x%x('%s')",
-                               ptr, val, Sym);
-               *ptr = val + addend;
+               if( !GetSymbol(Sym, &symval, NULL) )
+                       return 1;
+               DEBUGS(" elf_doRelocate: R_386_32 *0x%x += %p('%s')",
+                               ptr, symval, Sym);
+               *ptr = (intptr_t)symval + addend;
                break;
                
        // 32 Bit Relocation wrt. Offset (S+A-P)
        case R_386_PC32:
                DEBUGS(" elf_doRelocate: '%s'", Sym);
-               val = (intptr_t) GetSymbol(Sym, NULL);
-               DEBUGS(" elf_doRelocate: R_386_PC32 *0x%x = 0x%x + 0x%x - 0x%x",
-                       ptr, *ptr, val, (intptr_t)ptr );
-               *ptr = val + addend - (intptr_t)ptr;
+               if( !GetSymbol(Sym, &symval, NULL) )    return 1;
+               DEBUGS(" elf_doRelocate: R_386_PC32 *0x%x = 0x%x + 0x%p - 0x%x",
+                       ptr, *ptr, symval, (intptr_t)ptr );
+               *ptr = (intptr_t)symval + addend - (intptr_t)ptr;
                //*ptr = val + addend - ((Uint)ptr - iBaseDiff);
                break;
 
@@ -114,9 +121,9 @@ void elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int t
        case R_386_GLOB_DAT:
        case R_386_JMP_SLOT:
                DEBUGS(" elf_doRelocate: '%s'", Sym);
-               val = (intptr_t) GetSymbol( Sym, NULL );
-               DEBUGS(" elf_doRelocate: %s *0x%x = 0x%x", csaR_NAMES[type], ptr, val);
-               *ptr = val;
+               if( !GetSymbol(Sym, &symval, NULL) )    return 1;
+               DEBUGS(" elf_doRelocate: %s *0x%x = %p", csaR_NAMES[type], ptr, symval);
+               *ptr = (intptr_t)symval;
                break;
 
        // Base Address (B+A)
@@ -127,18 +134,19 @@ void elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int t
 
        case R_386_COPY: {
                size_t  size;
-               void    *src = GetSymbol(Sym, &size);
-               DEBUGS(" elf_doRelocate_386: R_386_COPY (%p, %p, %i)", ptr, src, size);
-               memcpy(ptr, src, size);
+               if( !GetSymbol(Sym, &symval, &size) )   return 1;
+               DEBUGS(" elf_doRelocate_386: R_386_COPY (%p, %p, %i)", ptr, symval, size);
+               memcpy(ptr, symval, size);
                break; }
 
        default:
                SysDebug("elf_doRelocate_386: Unknown relocation %i", type);
-               break;
+               return 2;
        }
+       return 0;
 }
 
-void elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff)
+int elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff)
 {
        uint32_t        val;
        switch(type)
@@ -146,32 +154,35 @@ void elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int t
        // (S + A) | T
        case R_ARM_ABS32:
                DEBUGS(" elf_doRelocate_arm: R_ARM_ABS32 %p (%s + %x)", ptr, Sym, addend);
-               val = (intptr_t)GetSymbol(Sym, NULL);
+               if( !GetSymbol(Sym, (void**)&val, NULL) )       return 1;
                *ptr = val + addend;
                break;
        case R_ARM_GLOB_DAT:
                DEBUGS(" elf_doRelocate_arm: R_ARM_GLOB_DAT %p (%s + %x)", ptr, Sym, addend);
-               val = (intptr_t)GetSymbol(Sym, NULL);
+               if( !GetSymbol(Sym, (void**)&val, NULL) )       return 1;
                *ptr = val + addend;
                break;
        case R_ARM_JUMP_SLOT:
                if(!bRela)      addend = 0;
                DEBUGS(" elf_doRelocate_arm: R_ARM_JUMP_SLOT %p (%s + %x)", ptr, Sym, addend);
-               val = (intptr_t)GetSymbol(Sym, NULL);
+               if( !GetSymbol(Sym, (void**)&val, NULL) )       return 1;
                *ptr = val + addend;
                break;
        // Copy
        case R_ARM_COPY: {
                size_t  size;
-               void    *src = GetSymbol(Sym, &size);
+               void    *src;
+               if( !GetSymbol(Sym, &src, &size) )      return 1;
                DEBUGS(" elf_doRelocate_arm: R_ARM_COPY (%p, %p, %i)", ptr, src, size);
                memcpy(ptr, src, size);
                break; }
        // Delta between link and runtime locations + A
        case R_ARM_RELATIVE:
+               DEBUGS(" elf_doRelocate_arm: R_ARM_RELATIVE %p (0x%x + 0x%x)", ptr, iBaseDiff, addend);
                if(Sym[0] != '\0') {
                        // TODO: Get delta for a symbol
                        SysDebug("elf_doRelocate_arm: TODO - Implment R_ARM_RELATIVE for symbols");
+                       return 2;
                }
                else {
                        *ptr = iBaseDiff + addend;
@@ -179,8 +190,14 @@ void elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int t
                break;
        default:
                SysDebug("elf_doRelocate_arm: Unknown Relocation, %i", type);
-               break;
+               return 2;
        }
+       return 0;
+}
+
+int elf_doRelocate_unk(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff)
+{
+       return 1;
 }
 
 void *Elf32Relocate(void *Base, char **envp, const char *Filename)
@@ -202,8 +219,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
        Elf32_Dyn       *dynamicTab = NULL;     // Dynamic Table Pointer
        char    *dynstrtab = NULL;      // .dynamic String Table
        Elf32_Sym       *dynsymtab;
-       void    (*do_relocate)(uint32_t t_info, uint32_t *ptr, Elf32_Addr addend, int Type, int bRela, const char *Sym, intptr_t iBaseDiff);
-       auto void _doRelocate(uint32_t r_info, uint32_t *ptr, int bRela, Elf32_Addr addend);
+       int     (*do_relocate)(uint32_t t_info, uint32_t *ptr, Elf32_Addr addend, int Type, int bRela, const char *Sym, intptr_t iBaseDiff);
        
        DEBUGS("ElfRelocate: (Base=0x%x)", Base);
        
@@ -236,7 +252,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
        
        // Adjust "Real" Base
        iBaseDiff = (intptr_t)Base - iRealBase;
-       
+
 //     hdr->entrypoint += iBaseDiff;   // Adjust Entrypoint
        
        // Check if a PT_DYNAMIC segement was found
@@ -244,11 +260,24 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
                SysDebug(" elf_relocate: No PT_DYNAMIC segment in image %p, returning", Base);
                return (void *)(intptr_t)(hdr->entrypoint + iBaseDiff);
        }
-       
+
+       // Allow writing to read-only segments, just in case they need to be relocated
+       // - Will be reversed at the end of the function
+       for( i = 0; i < iSegmentCount; i ++ )
+       {
+               if(phtab[i].Type == PT_LOAD && !(phtab[i].Flags & PF_W) ) {
+                       uintptr_t       addr = phtab[i].VAddr + iBaseDiff;
+                       uintptr_t       end = addr + phtab[i].MemSize;
+                       for( ; addr < end; addr += PAGE_SIZE )
+                               _SysSetMemFlags(addr, 0, 1);    // Unset RO
+               }
+       }
+
        // Adjust Dynamic Table
        dynamicTab = (void *)( (intptr_t)dynamicTab + iBaseDiff );
        
        // === Get Symbol table and String Table ===
+       dynsymtab = NULL;
        for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)
        {
                switch(dynamicTab[j].d_tag)
@@ -340,13 +369,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
        
        DEBUGS(" elf_relocate: Beginning Relocation");
 
-       void _doRelocate(uint32_t r_info, uint32_t *ptr, int bRela, Elf32_Addr addend)
-       {
-                int    type = ELF32_R_TYPE(r_info);
-                int    sym = ELF32_R_SYM(r_info);
-               const char      *symname = dynstrtab + dynsymtab[sym].nameOfs;
-               do_relocate(r_info, ptr, addend, type, bRela, symname, iBaseDiff);
-       }
+        int    fail = 0;
 
        switch(hdr->machine)
        {
@@ -358,11 +381,17 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
                break;
        default:
                SysDebug("Elf32Relocate: Unknown machine type %i", hdr->machine);
+               do_relocate = elf_doRelocate_unk;
+               fail = 1;
                break;
        }
        
        DEBUGS("do_relocate = %p (%p or %p)", do_relocate, &elf_doRelocate_386, &elf_doRelocate_arm);
 
+       #define _doRelocate(r_info, ptr, bRela, addend) \
+               do_relocate(r_info, ptr, addend, ELF32_R_TYPE(r_info), bRela, \
+                       dynstrtab + dynsymtab[ELF32_R_SYM(r_info)].nameOfs, iBaseDiff);
+
        // Parse Relocation Entries
        if(rel && relSz)
        {
@@ -373,7 +402,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
                {
                        //DEBUGS("  Rel %i: 0x%x+0x%x", i, iBaseDiff, rel[i].r_offset);
                        ptr = (void*)(iBaseDiff + rel[i].r_offset);
-                       _doRelocate(rel[i].r_info, ptr, 0, *ptr);
+                       fail |= _doRelocate(rel[i].r_info, ptr, 0, *ptr);
                }
        }
        // Parse Relocation Entries
@@ -385,7 +414,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
                for( i = 0; i < j; i++ )
                {
                        ptr = (void*)(iBaseDiff + rela[i].r_offset);
-                       _doRelocate(rel[i].r_info, ptr, 1, rela[i].r_addend);
+                       fail |= _doRelocate(rel[i].r_info, ptr, 1, rela[i].r_addend);
                }
        }
        
@@ -402,7 +431,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
                        for(i=0;i<j;i++)
                        {
                                ptr = (void*)(iBaseDiff + pltRel[i].r_offset);
-                               _doRelocate(pltRel[i].r_info, ptr, 0, *ptr);
+                               fail |= _doRelocate(pltRel[i].r_info, ptr, 0, *ptr);
                        }
                }
                else
@@ -413,11 +442,30 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
                        for(i=0;i<j;i++)
                        {
                                ptr = (void*)(iRealBase + pltRela[i].r_offset);
-                               _doRelocate(pltRela[i].r_info, ptr, 1, pltRela[i].r_addend);
+                               fail |= _doRelocate(pltRela[i].r_info, ptr, 1, pltRela[i].r_addend);
                        }
                }
        }
-       
+
+       // Re-set readonly
+       for( i = 0; i < iSegmentCount; i ++ )
+       {
+               // If load and not writable
+               if(phtab[i].Type == PT_LOAD && !(phtab[i].Flags & PF_W) ) {
+                       uintptr_t       addr = phtab[i].VAddr + iBaseDiff;
+                       uintptr_t       end = addr + phtab[i].MemSize;
+                       for( ; addr < end; addr += PAGE_SIZE )
+                               _SysSetMemFlags(addr, 1, 1);    // Unset RO
+               }
+       }
+
+       if( fail ) {
+               DEBUGS("ElfRelocate: Failure");
+               return NULL;
+       }       
+
+       #undef _doRelocate
+
        DEBUGS("ElfRelocate: RETURN 0x%x to %p", hdr->entrypoint + iBaseDiff, __builtin_return_address(0));
        return (void*)(intptr_t)( hdr->entrypoint + iBaseDiff );
 }
@@ -528,7 +576,7 @@ void *Elf64Relocate(void *Base, char **envp, const char *Filename)
         int    i;
        Elf64_Ehdr      *hdr = Base;
        Elf64_Phdr      *phtab;
-       Elf64_Dyn       *dyntab;
+       Elf64_Dyn       *dyntab = NULL;
        Elf64_Addr      compiledBase = -1, baseDiff;
        Elf64_Sym       *symtab = NULL;
        char    *strtab = NULL;
@@ -554,7 +602,7 @@ void *Elf64Relocate(void *Base, char **envp, const char *Filename)
        DEBUGS("Elf64Relocate:  e_phnum = %i", hdr->e_phnum);
 
        // Scan for the dynamic table (and find the compiled base)
-       phtab = Base + hdr->e_phoff;
+       phtab = (void*)((uintptr_t)Base + (uintptr_t)hdr->e_phoff);
        for( i = 0; i < hdr->e_phnum; i ++ )
        {
                if(phtab[i].p_type == PT_DYNAMIC)
@@ -663,45 +711,54 @@ void *Elf64Relocate(void *Base, char **envp, const char *Filename)
        }
 
        // Relocation function
-       void _Elf64DoReloc(Elf64_Xword r_info, void *ptr, Elf64_Sxword addend)
+       auto int _Elf64DoReloc(Elf64_Xword r_info, void *ptr, Elf64_Sxword addend);
+       int _Elf64DoReloc(Elf64_Xword r_info, void *ptr, Elf64_Sxword addend)
        {
                 int    sym = ELF64_R_SYM(r_info);
                 int    type = ELF64_R_TYPE(r_info);
                const char      *symname = strtab + symtab[sym].st_name;
+               void    *symval;
+               //DEBUGS("_Elf64DoReloc: %s", symname);
                switch( type )
                {
                case R_X86_64_NONE:
                        break;
                case R_X86_64_64:
-                       *(uint64_t*)ptr = (uintptr_t)GetSymbol(symname, NULL) + addend;
+                       if( !GetSymbol(symname, &symval, NULL)  )       return 1;
+                       *(uint64_t*)ptr = (uintptr_t)symval + addend;
                        break;
                case R_X86_64_COPY: {
                        size_t  size;
-                       void    *sym = GetSymbol(symname, &size);
-                       memcpy(ptr, sym, size);
+                       if( !GetSymbol(symname, &symval, &size)  )      return 1;
+                       memcpy(ptr, symval, size);
                        } break;
                case R_X86_64_GLOB_DAT:
-                       *(uint64_t*)ptr = (uintptr_t)GetSymbol(symname, NULL);
+                       if( !GetSymbol(symname, &symval, NULL)  )       return 1;
+                       *(uint64_t*)ptr = (uintptr_t)symval;
                        break;
                case R_X86_64_JUMP_SLOT:
-                       *(uint64_t*)ptr = (uintptr_t)GetSymbol(symname, NULL);
+                       if( !GetSymbol(symname, &symval, NULL)  )       return 1;
+                       *(uint64_t*)ptr = (uintptr_t)symval;
                        break;
                case R_X86_64_RELATIVE:
                        *(uint64_t*)ptr = (uintptr_t)Base + addend;
                        break;
                default:
                        SysDebug("ld-acess - _Elf64DoReloc: Unknown relocation type %i", type);
-                       break;
+                       return 2;
                }
+               //DEBUGS("_Elf64DoReloc: - Good");
+               return 0;
        }
 
+       int fail = 0;
        if( rel )
        {
                DEBUGS("rel_count = %i", rel_count);
                for( i = 0; i < rel_count; i ++ )
                {
                        uint64_t *ptr = (void *)(uintptr_t)( rel[i].r_offset + baseDiff );
-                       _Elf64DoReloc( rel[i].r_info, ptr, *ptr);
+                       fail |= _Elf64DoReloc( rel[i].r_info, ptr, *ptr);
                }
        }
 
@@ -711,7 +768,7 @@ void *Elf64Relocate(void *Base, char **envp, const char *Filename)
                for( i = 0; i < rela_count; i ++ )
                {
                        uint64_t *ptr = (void *)(uintptr_t)( rela[i].r_offset + baseDiff );
-                       _Elf64DoReloc( rela[i].r_info, ptr, rela[i].r_addend );
+                       fail |= _Elf64DoReloc( rela[i].r_info, ptr, rela[i].r_addend );
                }
        }
 
@@ -724,7 +781,7 @@ void *Elf64Relocate(void *Base, char **envp, const char *Filename)
                        for( i = 0; i < count; i ++ )
                        {
                                uint64_t *ptr = (void *)(uintptr_t)( plt[i].r_offset + baseDiff );
-                               _Elf64DoReloc( plt[i].r_info, ptr, *ptr);
+                               fail |= _Elf64DoReloc( plt[i].r_info, ptr, *ptr);
                        }
                }
                else {
@@ -734,11 +791,16 @@ void *Elf64Relocate(void *Base, char **envp, const char *Filename)
                        for( i = 0; i < count; i ++ )
                        {
                                uint64_t *ptr = (void *)(uintptr_t)( plt[i].r_offset + baseDiff );
-                               _Elf64DoReloc( plt[i].r_info, ptr, plt[i].r_addend);
+                               fail |= _Elf64DoReloc( plt[i].r_info, ptr, plt[i].r_addend);
                        }
                }
        }
 
+       if( fail ) {
+               DEBUGS("Elf64Relocate: Failure");
+               return NULL;
+       }
+
        {
        void *ret = (void *)(uintptr_t)(hdr->e_entry + baseDiff);
        DEBUGS("Elf64Relocate: Relocations done, return %p", ret);
@@ -771,7 +833,7 @@ int Elf64GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size)
                 int    j;
                
                // Locate the tables
-               phtab = (void*)( (intptr_t)Base + hdr->e_phoff );
+               phtab = (void*)( (intptr_t)Base + (uintptr_t)hdr->e_phoff );
                for( i = 0; i < hdr->e_phnum; i ++ )
                {
                        if(phtab[i].p_type == PT_LOAD && iBaseDiff > phtab[i].p_vaddr)
index 1cec11e..586078a 100644 (file)
@@ -11,7 +11,6 @@ extern int32_t        __modsi3(int32_t Num, int32_t Den);
 extern uint32_t        __udivsi3(uint32_t Num, uint32_t Den);
 extern uint32_t        __umodsi3(uint32_t Num, uint32_t Den);
 
-
 #define _STR(x)        #x
 #define STR(x) _STR(x)
 #define EXP(sym)       {&sym, STR(sym)}
@@ -35,6 +34,13 @@ const struct {
        #define __ASSEMBLER__
        #include "arch/syscalls.s.h"
        #undef __ASSEMBLER__
+       
+       #ifdef ARCHDIR_is_armv7
+       {0, "__gnu_Unwind_Find_exidx"},
+       {0, "__cxa_call_unexpected"},
+       {0, "__cxa_type_match"},
+       {0, "__cxa_begin_cleanup"},
+       #endif
 #if 0
        EXP(__umoddi3),
        EXP(__udivdi3),
diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/fd_set.h b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/fd_set.h
new file mode 100644 (file)
index 0000000..0793901
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Acess2 Dynamic Linker
+ * - By John Hodge (thePowersGang)
+ *
+ * acess/fd_set.h
+ * - fd_set structure used by select()
+ */
+#ifndef _ACESS__FD_SET_H_
+#define _ACESS__FD_SET_H_
+
+#define FD_SETSIZE     128
+
+typedef unsigned short fd_set_ent_t;
+
+/**
+ * \brief fd_set for select()
+ */
+typedef struct
+{
+       fd_set_ent_t    flags[FD_SETSIZE/16];
+}      fd_set;
+
+
+extern void    FD_ZERO(fd_set *fdsetp);
+extern void    FD_CLR(int fd, fd_set *fdsetp);
+extern void    FD_SET(int fd, fd_set *fdsetp);
+extern int     FD_ISSET(int fd, fd_set *fdsetp);
+
+#endif
diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/intdefs.h b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/intdefs.h
deleted file mode 100644 (file)
index 36086d0..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- */
-#ifndef _ACESS_INTDEFS_H_
-#define _ACESS_INTDEFS_H_
-
-#define INT_MIN        -0x80000000
-#define INT_MAX        0x7FFFFFFF
-
-typedef unsigned char  __uint8_t;
-typedef unsigned short __uint16_t;
-typedef unsigned int   __uint32_t;
-typedef unsigned long long     __uint64_t;
-
-typedef signed char            __int8_t;
-typedef signed short   __int16_t;
-typedef signed int             __int32_t;
-typedef signed long long       __int64_t;
-
-#if defined(ARCHDIR_is_x86)
-typedef __int32_t      __intptr_t;
-typedef __uint32_t     __uintptr_t;
-#elif defined(ARCHDIR_is_x86_64)
-typedef __int64_t      __intptr_t;
-typedef __uint64_t     __uintptr_t;
-#elif defined(ARCHDIR_is_armv7) | defined(ARCHDIR_is_armv6)
-typedef __int32_t      __intptr_t;
-typedef __uint32_t     __uintptr_t;
-#else
-# error "Unknown pointer size"
-#endif
-
-//typedef uint64_t     off_t;
-
-#endif
-
index 25a91be..c798702 100644 (file)
@@ -5,7 +5,8 @@
 #define _ACESS_SYS_H_
 
 #include <stdint.h>
-#include "../sys/types.h"
+#include <stddef.h>    // size_t
+#include "syscall_types.h"
 
 // === CONSTANTS ===
 #ifndef NULL
@@ -19,6 +20,9 @@
 #define OPENFLAG_EXEC  0x01
 #define OPENFLAG_READ  0x02
 #define OPENFLAG_WRITE 0x04
+#define OPENFLAG_RDWR  (OPENFLAG_READ|OPENFLAG_WRITE)
+#define OPENFLAG_TRUNCATE      0x10
+#define OPENFLAG_APPEND        0x20
 #define        OPENFLAG_NOLINK 0x40
 #define        OPENFLAG_CREATE 0x80
 #ifndef SEEK_CUR
@@ -39,21 +43,19 @@ extern int  _errno;
 extern void    _SysDebug(const char *format, ...);
 // --- Proc ---
 extern void    _exit(int status)       __attribute__((noreturn));
-extern void    sleep(void);
-extern void    yield(void);
-extern int     kill(int pid, int sig);
-//extern void  wait(int miliseconds);
+extern int     _SysKill(int pid, int sig);
 extern int     _SysWaitEvent(int EventMask);
-extern int     waittid(int id, int *status);
-extern int     clone(int flags, void *stack);
-extern int     execve(char *path, char **argv, char **envp);
-extern int     _SysSpawn(const char *Path, const char **argv, const char **envp, int nFDs, int *FDs);
+extern int     _SysWaitTID(int id, int *status);
+extern int     _SysClone(int flags, void *stack);
+extern int     _SysExecVE(const char *path, char **argv, char **envp);
+extern int     _SysSpawn(const char *Path, const char **argv, const char **envp, int nFDs, int *FDs, struct s_sys_spawninfo *info);
 extern int     gettid(void);
 extern int     getpid(void);
 extern int     _SysSetFaultHandler(int (*Handler)(int));
-extern void    SysSetName(const char *Name);
-extern int     SysGetName(char *NameDest);
-extern int     SysSetPri(int Priority);
+extern void    _SysSetName(const char *Name);
+extern int     _SysGetName(char *NameDest);
+extern int     _SysSetPri(int Priority);
+// --- Timekeeping ---
 extern int64_t _SysTimestamp(void);
 
 // --- Permissions ---
@@ -63,29 +65,39 @@ extern void setuid(int id);
 extern void    setgid(int id);
 
 // --- VFS ---
-extern int     chdir(const char *dir);
-extern int     open(const char *path, int flags, ...);
-extern int     reopen(int fd, const char *path, int flags);
-extern int     close(int fd);
-extern uint    read(int fd, void *buffer, uint length);
-extern uint    write(int fd, const void *buffer, uint length);
-extern int     seek(int fd, int64_t offset, int whence);
-extern uint64_t        tell(int fd);
-extern int     ioctl(int fd, int id, void *data);
-extern int     finfo(int fd, t_sysFInfo *info, int maxacls);
-extern int     SysReadDir(int fd, char *dest);
+extern int     _SysChdir(const char *dir);
+extern int     _SysChroot(const char *dir);
+
+extern int     _SysOpen(const char *path, int flags, ...);
 extern int     _SysOpenChild(int fd, const char *name, int flags);
+extern int     _SysOpenPipe(int *read, int *write, int flags);
+extern int     _SysReopen(int fd, const char *path, int flags);
+extern int     _SysCopyFD(int srcfd, int dstfd);
+extern size_t  _SysRead(int fd, void *buffer, size_t length);
+extern int     _SysClose(int fd);
+extern int     _SysFDCtl(int fd, int option, ...);
+extern size_t  _SysWrite(int fd, const void *buffer, size_t length);
+extern int     _SysSeek(int fd, int64_t offset, int whence);
+extern uint64_t        _SysTell(int fd);
+extern int     _SysIOCtl(int fd, int id, void *data);
+extern int     _SysFInfo(int fd, t_sysFInfo *info, int maxacls);
+extern int     _SysReadDir(int fd, char *dest);
 extern int     _SysGetACL(int fd, t_sysACL *dest);
 extern int     _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options);
 extern int     _SysSelect(int nfds, fd_set *read, fd_set *write, fd_set *err, int64_t *timeout, unsigned int extraevents);
 #define select(nfs, rdfds, wrfds, erfds, timeout)      _SysSelect(nfs, rdfds, wrfds, erfds, timeout, 0)
+extern int     _SysUnlink(const char *pathname);
 
 // --- IPC ---
-extern int     SysSendMessage(pid_t dest, uint length, const void *Data);
-extern int     SysGetMessage(pid_t *src, void *Data);
+extern int     _SysSendMessage(int dest, size_t length, const void *Data);
+extern int     _SysGetMessage(int *src, size_t buflen, void *Data);
 
 // --- MEMORY ---
-uint64_t       _SysGetPhys(uint vaddr);
-uint64_t       _SysAllocate(uint vaddr);
+extern uint64_t        _SysGetPhys(uintptr_t vaddr);
+extern uint64_t        _SysAllocate(uintptr_t vaddr);
+extern uint32_t        _SysSetMemFlags(uintptr_t vaddr, uint32_t flags, uint32_t mask);
+extern void    *_SysLoadBin(const char *path, void **entry);
+extern int     _SysUnloadBin(void *base);
+extern void    SysSetFaultHandler(int (*Hanlder)(int));
 
 #endif
diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/syscall_types.h b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/syscall_types.h
new file mode 100644 (file)
index 0000000..c1f25c6
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Acess2 Dynamic Linker
+ * - By John Hodge (thePowersGang)
+ *
+ * acess/syscall_types.h
+ * - Structures used for syscalls
+ */
+#ifndef _ACESS__SYSCALL_TYPES_H_
+#define _ACESS__SYSCALL_TYPES_H_
+
+#include "fd_set.h"
+
+struct s_sysACL {
+       unsigned long   object; /*!< Group or user (bit 31 determines) */
+       unsigned long   perms;  /*!< Inverted by bit 31 */
+};
+struct s_sysFInfo {
+       unsigned int    mount;
+       unsigned long long      inode;
+       unsigned int    uid;
+       unsigned int    gid;
+       unsigned int    flags;
+       unsigned long long      size;
+       int64_t atime;
+       int64_t mtime;
+       int64_t ctime;
+        int    numacls;
+       struct s_sysACL acls[];
+} __attribute__((packed));
+typedef struct s_sysFInfo      t_sysFInfo;
+typedef struct s_sysACL        t_sysACL;
+
+struct s_sys_spawninfo
+{
+       unsigned int    flags;
+       unsigned int    uid;
+       unsigned int    gid;
+};
+
+#endif
+
diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/stddef.h b/Usermode/Libraries/ld-acess.so_src/include_exp/stddef.h
deleted file mode 100644 (file)
index 1995839..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _STDDEF_H_
-#define _STDDEF_H_
-
-#include "acess/intdefs.h"
-
-#ifndef NULL
-# define NULL  ((void*)0)
-#endif
-
-typedef __intptr_t     size_t;
-
-#endif
diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/sys/param.h b/Usermode/Libraries/ld-acess.so_src/include_exp/sys/param.h
new file mode 100644 (file)
index 0000000..b9b50e2
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Acess2 Dynamic Linker
+ * - By John Hodge (thePowersGang)
+ *
+ * sys/param.h
+ * - System Parameters (?)
+ */
+#ifndef _SYS__PARAM_H_
+#define _SYS__PARAM_H_
+
+#endif
+
diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/sys/stat.h b/Usermode/Libraries/ld-acess.so_src/include_exp/sys/stat.h
deleted file mode 100644 (file)
index 1813365..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Acess2 C Library
- * - By John Hodge (thePowersGang)
- */
-#ifndef _SYS_STAT_H_
-#define _SYS_STAT_H_
-
-#include "../acess/intdefs.h"  /* Evil */
-#include "../stddef.h"
-
-;
-typedef void   *dev_t; /* TODO: How to identify a device with Acess */
-typedef __uint64_t     ino_t;
-typedef unsigned int   blksize_t;
-typedef __uint64_t     blkcnt_t;
-typedef unsigned int   nlink_t;
-typedef __uint32_t     mode_t;
-
-typedef __uint32_t     uid_t;
-typedef __uint32_t     gid_t;
-
-#define        S_IFMT          0170000 /* type of file */
-#define                S_IFDIR 0040000 /* directory */
-#define                S_IFCHR 0020000 /* character special */
-#define                S_IFBLK 0060000 /* block special */
-#define                S_IFREG 0100000 /* regular */
-#define                S_IFLNK 0120000 /* symbolic link */
-#define                S_IFSOCK        0140000 /* socket */
-#define                S_IFIFO 0010000 /* fifo */
-
-
-struct stat
-{
-       dev_t     st_dev;     /* ID of device containing file */
-       ino_t     st_ino;     /* inode number */
-       mode_t    st_mode;    /* protection */
-       nlink_t   st_nlink;   /* number of hard links */
-       uid_t     st_uid;     /* user ID of owner */
-       gid_t     st_gid;     /* group ID of owner */
-       dev_t     st_rdev;    /* device ID (if special file) */
-       off_t     st_size;    /* total size, in bytes */
-       blksize_t st_blksize; /* blocksize for file system I/O */
-       blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
-       time_t    st_atime;   /* time of last access */
-       time_t    st_mtime;   /* time of last modification */
-       time_t    st_ctime;   /* time of last status change */
-};
-
-extern int stat(const char *path, struct stat *buf);
-extern int fstat(int fd, struct stat *buf);
-
-#endif
diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/sys/sys.h b/Usermode/Libraries/ld-acess.so_src/include_exp/sys/sys.h
deleted file mode 100644 (file)
index 08bf31e..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*\r
- Syscall Definitions\r
-*/\r
-#ifndef _SYS_SYS_H_\r
-#define _SYS_SYS_H_\r
-\r
-#include <acess/sys.h>\r
-\r
-#include <sys/types.h>\r
-\r
-#define O_RDONLY       OPENFLAG_READ\r
-#define O_WRONLY       OPENFLAG_WRITE\r
-#define O_CREAT        (OPENFLAG_CREATE|OPENFLAG_WRITE)\r
-#define O_TRUNC        OPENFLAG_WRITE\r
-#define O_APPEND       OPENFLAG_WRITE\r
-\r
-\r
-#if 0\r
-#define        OPEN_FLAG_READ  1\r
-#define        OPEN_FLAG_WRITE 2\r
-#define        OPEN_FLAG_EXEC  4\r
-\r
-enum {\r
-       K_WAITPID_DIE = 0\r
-};\r
-\r
-// === System Calls ===\r
-extern void    _exit(int ret);\r
-extern int     brk(int bssend);\r
-extern int     execve(char *file, char *args[], char *envp[]);\r
-extern int     fork();\r
-extern int     yield();\r
-extern int     sleep();\r
-\r
-extern int     open(char *file, int flags);\r
-extern int     close(int fp);\r
-extern int     read(int fp, int len, void *buf);\r
-extern int     write(int fp, int len, void *buf);\r
-extern int     tell(int fp);\r
-extern void    seek(int fp, int64_t dist, int flag);\r
-extern int     fstat(int fp, t_fstat *st);\r
-extern int     ioctl(int fp, int call, void *arg);\r
-extern int     readdir(int fp, char *file);\r
-\r
-extern int     select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errfds, time_t *timeout);\r
-\r
-extern int     kdebug(char *fmt, ...);\r
-extern int     waitpid(int pid, int action);\r
-extern int     gettid();       // Get Thread ID\r
-extern int     getpid();       // Get Process ID\r
-extern int     sendmsg(int dest, unsigned int *Data);\r
-extern int     pollmsg(int *src, unsigned int *Data);\r
-extern int     getmsg(int *src, unsigned int *Data);\r
-#endif\r
-\r
-#endif\r
diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/sys/types.h b/Usermode/Libraries/ld-acess.so_src/include_exp/sys/types.h
deleted file mode 100644 (file)
index 4e38de3..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- */
-#ifndef _SYS_TYPES_H
-#define _SYS_TYPES_H
-
-#include "../acess/intdefs.h"
-
-typedef struct stat    t_fstat;
-
-#define FD_SETSIZE     128
-
-
-#define CLONE_VM       0x10
-
-typedef unsigned long  pid_t;
-typedef unsigned long  tid_t;
-typedef signed long long int   time_t;
-typedef long long int  off_t;
-
-typedef unsigned int   uint;
-
-typedef unsigned short fd_set_ent_t;
-
-/**
- * \brief fd_set for select()
- */
-typedef struct
-{
-       fd_set_ent_t    flags[FD_SETSIZE/16];
-}      fd_set;
-
-struct s_sysACL {
-       unsigned long   object; /*!< Group or user (bit 31 determines) */
-       unsigned long   perms;  /*!< Inverted by bit 31 */
-};
-struct s_sysFInfo {
-       unsigned int    mount;
-       unsigned long long      inode;
-       unsigned int    uid;
-       unsigned int    gid;
-       unsigned int    flags;
-       unsigned long long      size;
-       time_t  atime;
-       time_t  mtime;
-       time_t  ctime;
-        int    numacls;
-       struct s_sysACL acls[];
-} __attribute__((packed));
-typedef struct s_sysFInfo      t_sysFInfo;
-typedef struct s_sysACL        t_sysACL;
-
-extern void    FD_ZERO(fd_set *fdsetp);
-extern void    FD_CLR(int fd, fd_set *fdsetp);
-extern void    FD_SET(int fd, fd_set *fdsetp);
-extern int     FD_ISSET(int fd, fd_set *fdsetp);
-
-typedef __uint8_t      u_int8_t;
-typedef __uint16_t     u_int16_t;
-typedef __uint32_t     u_int32_t;
-
-#include "../sys/stat.h"
-
-#endif
diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/unistd.h b/Usermode/Libraries/ld-acess.so_src/include_exp/unistd.h
deleted file mode 100644 (file)
index 3dc523a..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _UNISTD_H_
-#define _UNISTD_H_
-
-#define        O_RDWR  (OPENFLAG_READ|OPENFLAG_WRITE)
-#define O_WR   (OPENFLAG_WRITE)
-#define O_RD   (OPENFLAG_READ)
-#define O_CREAT        (OPENFLAG_CREATE)
-
-#include "acess/sys.h"
-
-
-#endif
-
index 0672102..9b8f86a 100644 (file)
@@ -73,10 +73,9 @@ void *memcpy(void *dest, const void *src, size_t len)
 int file_exists(const char *filename)
 {
         int    fd;
-       //fd = open(filename, OPENFLAG_READ);
-       fd = open(filename, 0);
+       fd = _SysOpen(filename, 0);
        if(fd == -1)    return 0;
-       close(fd);
+       _SysClose(fd);
        return 1;
 }
 
index 3f8e674..dcacd8a 100644 (file)
@@ -4,6 +4,7 @@
 */
 #include "common.h"
 #include <stdint.h>
+#include <acess/sys.h>
 
 #define DEBUG  0
 
@@ -15,7 +16,6 @@
 
 // === PROTOTYPES ===
 void   *IsFileLoaded(const char *file);
- int   GetSymbolFromBase(void *base, const char *name, void **ret, size_t *size);
 
 // === IMPORTS ===
 extern const struct {
@@ -78,7 +78,7 @@ void *LoadLibrary(const char *SoName, const char *SearchDir, char **envp)
 
        DEBUGS(" LoadLibrary: SysLoadBin()");   
        // Load Library
-       base = SysLoadBin(filename, (void**)&fEntry);
+       base = _SysLoadBin(filename, (void**)&fEntry);
        if(!base) {
                DEBUGS("LoadLibrary: RETURN 0");
                return 0;
@@ -88,6 +88,9 @@ void *LoadLibrary(const char *SoName, const char *SearchDir, char **envp)
        
        // Load Symbols
        fEntry = DoRelocate( base, envp, filename );
+       if( !fEntry ) {
+               return 0;
+       }
        
        // Call Entrypoint
        DEBUGS(" LoadLibrary: '%s' Entry %p", SoName, fEntry);
@@ -170,7 +173,7 @@ void Unload(void *Base)
        if(id == MAX_LOADED_LIBRARIES)  return;
        
        // Unload Binary
-       SysUnloadBin( Base );
+       _SysUnloadBin( Base );
        // Save String Pointer
        str = gLoadedLibraries[id].Name;
        
@@ -198,26 +201,31 @@ void Unload(void *Base)
  \fn Uint GetSymbol(const char *name)
  \brief Gets a symbol value from a loaded library
 */
-void *GetSymbol(const char *name, size_t *Size)
+int GetSymbol(const char *name, void **Value, size_t *Size)
 {
         int    i;
-       void    *ret;
        
        //SysDebug("ciNumLocalExports = %i", ciNumLocalExports);
        for(i=0;i<ciNumLocalExports;i++)
        {
-               if( strcmp(caLocalExports[i].Name, name) == 0 )
-                       return caLocalExports[i].Value;
+               if( strcmp(caLocalExports[i].Name, name) == 0 ) {
+                       *Value = caLocalExports[i].Value;
+                       if(Size)
+                               *Size = 0;
+                       return 1;
+               }
        }
        
        // Entry 0 is ld-acess, ignore it
        for(i = 1; i < MAX_LOADED_LIBRARIES; i ++)
        {
-               if(gLoadedLibraries[i].Base == 0)       break;
+               if(gLoadedLibraries[i].Base == 0)
+                       break;
                
                //SysDebug(" GetSymbol: Trying 0x%x, '%s'",
                //      gLoadedLibraries[i].Base, gLoadedLibraries[i].Name);
-               if(GetSymbolFromBase(gLoadedLibraries[i].Base, name, &ret, Size))       return ret;
+               if(GetSymbolFromBase(gLoadedLibraries[i].Base, name, Value, Size))
+                       return 1;
        }
        SysDebug("GetSymbol: === Symbol '%s' not found ===", name);
        return 0;
index 49b2f86..985f9c8 100644 (file)
@@ -101,3 +101,8 @@ int CallUser(void *entry, void *sp)
        #endif\r
        for(;;);\r
 }\r
+\r
+void abort(void)\r
+{\r
+       _exit(-4);\r
+}\r
index 8d91173..04abfaf 100644 (file)
@@ -9,6 +9,7 @@
 #define _AXWIN3_AXWIN_H_
 
 #include <stddef.h>    // size_t
+#include <unistd.h>
 
 // === CONSTANTS ===
 
@@ -25,6 +26,7 @@ typedef int   (*tAxWin3_WindowMessageHandler)(tHWND Window, int Message, int Lengt
 extern void    AxWin3_Connect(const char *ServerDesc);
 extern tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback);
 extern void    AxWin3_MainLoop(void);
+extern void    AxWin3_MessageSelect(int nFD, fd_set *FDs);
 
 // --- Non-Window based functions
 extern int     AxWin3_GetDisplayCount(void);
diff --git a/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/richtext.h b/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/richtext.h
new file mode 100644 (file)
index 0000000..661c02b
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Acess2 GUI Version 3 (AxWin3)
+ * - By John Hodge (thePowersGang)
+ *
+ * richtext.h
+ * - Rich Text line editor
+ */
+#ifndef _AXWIN3_RICHTEXT_H_
+#define _AXWIN3_RICHTEXT_H_
+
+#include <stdint.h>
+
+typedef        int     (*tAxWin3_RichText_KeyHandler)(tHWND Window, int bPress, uint32_t Sym, uint32_t Unicode);
+typedef int    (*tAxWin3_RichText_MouseHandler)(tHWND Window, int bPress, int Button, int Row, int Col);
+typedef int    (*tAxWin3_RichText_LineHandler)(tHWND Window, int Row);
+
+#define AXWIN3_RICHTEXT_NOSCROLL       0x0001  // Disables server-side scrolling
+#define AXWIN3_RICHTEXT_READONLY       0x0002  // Disables automatic insertion of translated characters
+enum eAxWin3_RichText_CursorType {
+       AXWIN3_RICHTEXT_CURSOR_NONE,
+       AXWIN3_RICHTEXT_CURSOR_VLINE,   // Vertical line
+       AXWIN3_RICHTEXT_CURSOR_ULINE,   // Underline
+       AXWIN3_RICHTEXT_CURSOR_INV,     // Inverted
+};
+
+extern tHWND   AxWin3_RichText_CreateWindow(tHWND Parent, int Flags);
+extern void    AxWin3_RichText_SetKeyHandler(tHWND Window, tAxWin3_RichText_KeyHandler Handler);
+extern void    AxWin3_RichText_SetMouseHandler(tHWND Window, tAxWin3_RichText_MouseHandler Handler);
+/**
+ * \brief Sets the function called when the server requests an update on a line's contents
+ */
+extern void    AxWin3_RichText_SetLineHandler(tHWND Window, tAxWin3_RichText_LineHandler Handler);
+extern void    AxWin3_RichText_EnableScroll(tHWND Window, int bEnable);
+extern void    AxWin3_RichText_SetLineCount(tHWND Window, int Lines);
+extern void    AxWin3_RichText_SetColCount(tHWND Window, int Cols);
+extern void    AxWin3_RichText_SetBackground(tHWND Window, uint32_t ARGB_Colour);
+extern void    AxWin3_RichText_SetDefaultColour(tHWND Window, uint32_t ARGB_Colour);
+extern void    AxWin3_RichText_SetFont(tHWND Window, const char *FontName, int PointSize);
+extern void    AxWin3_RichText_SetCursorType(tHWND Window, int Type);
+extern void    AxWin3_RichText_SetCursorBlink(tHWND Window, int bBlink);
+extern void    AxWin3_RichText_SetCursorPos(tHWND Window, int Row, int Column);
+extern void    AxWin3_RichText_SendLine(tHWND Window, int Line, const char *Text);
+
+#endif
+
index 9eca0b0..58386eb 100644 (file)
@@ -26,6 +26,7 @@ extern tAxWin3_Widget *AxWin3_Widget_GetRoot(tHWND Window);
 
 // --- Element Creation
 extern tAxWin3_Widget  *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Flags, const char *DebugName);
+extern tAxWin3_Widget  *AxWin3_Widget_AddWidget_SubWindow(tAxWin3_Widget *Parent, tHWND Window, int Flags, const char *DebugName);
 extern void    AxWin3_Widget_DelWidget(tAxWin3_Widget *Widget);
 
 // --- Callbacks
index 61d127f..b890d48 100644 (file)
@@ -4,13 +4,14 @@
 -include ../Makefile.cfg\r
 \r
 CPPFLAGS += \r
-CFLAGS   += \r
+CFLAGS   += -Werror -Wextra\r
 ASFLAGS  +=\r
-LDFLAGS  += -soname libc.so -Map map.txt -lgcc\r
+LDFLAGS  += -soname libc.so -Map map.txt\r
 \r
 INCFILES := stdio.h stdlib.h\r
 \r
-OBJ  = stub.o heap.o stdlib.o env.o fileIO.o string.o select.o rand.o\r
+OBJ  = stub.o heap.o stdlib.o env.o stdio.o string.o select.o rand.o\r
+OBJ += perror.o scanf.o signals.o strtoi.o\r
 OBJ += arch/$(ARCHDIR).ao\r
 # signals.o\r
 DEPFILES := $(OBJ:%.o=%.d)\r
diff --git a/Usermode/Libraries/libc.so_src/fileIO.c b/Usermode/Libraries/libc.so_src/fileIO.c
deleted file mode 100644 (file)
index 776a2de..0000000
+++ /dev/null
@@ -1,590 +0,0 @@
-/*\r
- * AcessOS Basic C Library\r
- * stdio.c\r
- */\r
-#include "config.h"\r
-#include <acess/sys.h>\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include "lib.h"\r
-#include "stdio_int.h"\r
-\r
-#define WRITE_STR(_fd, _str)   write(_fd, _str, sizeof(_str))\r
-\r
-#define DEBUG_BUILD    0\r
-\r
-// === CONSTANTS ===\r
-#define        _stdin  0\r
-#define        _stdout 1\r
-\r
-// === PROTOTYPES ===\r
-EXPORT void    itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned);\r
-struct sFILE   *get_file_struct();\r
-\r
-// === GLOBALS ===\r
-struct sFILE   _iob[STDIO_MAX_STREAMS];        // IO Buffer\r
-struct sFILE   *stdin; // Standard Input\r
-struct sFILE   *stdout;        // Standard Output\r
-struct sFILE   *stderr;        // Standard Error\r
-///\note Initialised in SoMain\r
-\r
-// === CODE ===\r
-/**\r
- * \fn FILE *freopen(char *file, char *mode, FILE *fp)\r
- */\r
-EXPORT FILE *freopen(const char *file, const char *mode, FILE *fp)\r
-{\r
-        int    openFlags = 0;\r
-        int    i;\r
-       \r
-       // Sanity Check Arguments\r
-       if(!fp || !file || !mode)       return NULL;\r
-       \r
-       if(fp->Flags) {\r
-               fflush(fp);\r
-       } else\r
-               fp->FD = -1;\r
-       \r
-       // Get main mode\r
-       switch(mode[0])\r
-       {\r
-       case 'r':       fp->Flags = FILE_FLAG_MODE_READ;        break;\r
-       case 'w':       fp->Flags = FILE_FLAG_MODE_WRITE;       break;\r
-       case 'a':       fp->Flags = FILE_FLAG_MODE_APPEND;      break;\r
-       case 'x':       fp->Flags = FILE_FLAG_MODE_EXEC;        break;\r
-       default:\r
-               return NULL;\r
-       }\r
-       // Get Modifiers\r
-       for(i=1;mode[i];i++)\r
-       {\r
-               switch(mode[i])\r
-               {\r
-               case '+':       fp->Flags |= FILE_FLAG_M_EXT;\r
-               }\r
-       }\r
-       \r
-       // Get Open Flags\r
-       switch(mode[0])\r
-       {\r
-       // Read\r
-       case 'r':       openFlags = OPENFLAG_READ;\r
-               if(fp->Flags & FILE_FLAG_M_EXT)\r
-                       openFlags |= OPENFLAG_WRITE;\r
-               break;\r
-       // Write\r
-       case 'w':       openFlags = OPENFLAG_WRITE;\r
-               if(fp->Flags & FILE_FLAG_M_EXT)\r
-                       openFlags |= OPENFLAG_READ;\r
-               break;\r
-       // Execute\r
-       case 'x':       openFlags = OPENFLAG_EXEC;\r
-               break;\r
-       }\r
-\r
-       //Open File\r
-       if(fp->FD != -1)\r
-               fp->FD = reopen(fp->FD, file, openFlags);\r
-       else\r
-               fp->FD = open(file, openFlags);\r
-       if(fp->FD == -1) {\r
-               fp->Flags = 0;\r
-               return NULL;\r
-       }\r
-       \r
-       if(mode[0] == 'a') {\r
-               seek(fp->FD, 0, SEEK_END);      //SEEK_END\r
-       }\r
-       \r
-       return fp;\r
-}\r
-/**\r
- \fn FILE *fopen(const char *file, const char *mode)\r
- \brief Opens a file and returns the pointer\r
- \param file   String - Filename to open\r
- \param mode   Mode to open in\r
-*/\r
-EXPORT FILE *fopen(const char *file, const char *mode)\r
-{\r
-       FILE    *retFile;\r
-       \r
-       // Sanity Check Arguments\r
-       if(!file || !mode)      return NULL;\r
-       \r
-       // Create Return Structure\r
-       retFile = get_file_struct();\r
-       \r
-       return freopen(file, mode, retFile);\r
-}\r
-\r
-EXPORT int fclose(FILE *fp)\r
-{\r
-       close(fp->FD);\r
-       fp->Flags = 0;\r
-       fp->FD = -1;\r
-       return 0;\r
-}\r
-\r
-EXPORT void fflush(FILE *fp)\r
-{\r
-       ///\todo Implement\r
-}\r
-\r
-EXPORT off_t ftell(FILE *fp)\r
-{\r
-       if(!fp || !fp->FD)      return -1;\r
-       \r
-       return tell(fp->FD);\r
-}\r
-\r
-EXPORT int fseek(FILE *fp, long int amt, int whence)\r
-{\r
-       if(!fp || !fp->FD)      return -1;\r
-       \r
-       return seek(fp->FD, amt, whence);\r
-}\r
-\r
-\r
-/**\r
- * \fn EXPORT int vfprintf(FILE *fp, const char *format, va_list args)\r
- * \brief Print to a file from a variable argument list\r
- */\r
-EXPORT int vfprintf(FILE *fp, const char *format, va_list args)\r
-{\r
-       va_list tmpList;\r
-        int    size;\r
-\r
-       if(!fp || !format)      return -1;\r
-\r
-       va_copy(tmpList, args);\r
-       \r
-       size = vsnprintf(NULL, 0, (char*)format, tmpList);\r
-       char    buf[size+1];\r
-       vsnprintf(buf, size+1, (char*)format, args);\r
-       \r
-       // Write to stream\r
-       write(fp->FD, buf, size);\r
-       \r
-       // Free buffer\r
-       free(buf);\r
-       \r
-       // Return written byte count\r
-       return size;\r
-}\r
-\r
-/**\r
- * \fn int fprintf(FILE *fp, const char *format, ...)\r
- * \brief Print a formatted string to a stream\r
- */\r
-EXPORT int fprintf(FILE *fp, const char *format, ...)\r
-{\r
-       va_list args;\r
-        int    ret;\r
-       \r
-       // Get Size\r
-       va_start(args, format);\r
-       ret = vfprintf(fp, (char*)format, args);\r
-       va_end(args);\r
-       \r
-       return ret;\r
-}\r
-\r
-/**\r
- * \fn EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\r
- * \brief Write to a stream\r
- */\r
-EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\r
-{\r
-        int    ret;\r
-       if(!fp || !fp->FD)      return -1;\r
-       \r
-       ret = write(fp->FD, ptr, size*num);\r
-       \r
-       return ret;\r
-}\r
-\r
-/**\r
- * \fn EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp)\r
- * \brief Read from a stream\r
- */\r
-EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp)\r
-{\r
-        int    ret;\r
-       if(!fp || !fp->FD)      return -1;\r
-\r
-       // TODO: Fit the spec better with the return value      \r
-       ret = read(fp->FD, ptr, size*num);\r
-       \r
-       return ret;\r
-}\r
-\r
-/**\r
- * \fn EXPORT int fputc(int c, FILE *fp)\r
- * \brief Write a single character to the stream\r
- */\r
-EXPORT int fputc(int c, FILE *fp)\r
-{\r
-       if(!fp || !fp->FD)      return -1;\r
-       return write(fp->FD, &c, 1);\r
-}\r
-\r
-EXPORT int putchar(int c)\r
-{\r
-       c &= 0xFF;\r
-       return write(_stdout, &c, 1);\r
-}\r
-\r
-/**\r
- * \fn EXPORT int fgetc(FILE *fp)\r
- * \brief Read a character from the stream\r
- */\r
-EXPORT int fgetc(FILE *fp)\r
-{\r
-       char    ret = 0;\r
-       if(!fp) return -1;\r
-       if(read(fp->FD, &ret, 1) == -1) return -1;\r
-       return ret;\r
-}\r
-\r
-EXPORT int getchar(void)\r
-{\r
-       char    ret = 0;\r
-       if(read(_stdin, &ret, 1) != 1)  return -1;\r
-       return ret;\r
-}\r
-\r
-// --- INTERNAL ---\r
-/**\r
- * \fn FILE *get_file_struct()\r
- * \brief Returns a file descriptor structure\r
- */\r
-FILE *get_file_struct()\r
-{\r
-        int    i;\r
-       for(i=0;i<STDIO_MAX_STREAMS;i++)\r
-       {\r
-               if(_iob[i].Flags == 0)  return &_iob[i];\r
-       }\r
-       return NULL;\r
-}\r
-\r
-EXPORT int puts(const char *str)\r
-{\r
-        int    len;\r
-       \r
-       if(!str)        return 0;\r
-       len = strlen(str);\r
-       \r
-       len = write(_stdout, str, len);\r
-       write(_stdout, "\n", 1);\r
-       return len;\r
-}\r
-\r
-EXPORT int vsprintf(char * __s, const char *__format, va_list __args)\r
-{\r
-       return vsnprintf(__s, 0x7FFFFFFF, __format, __args);\r
-}\r
-\r
-//sprintfv\r
-/**\r
- * \fn EXPORT void vsnprintf(char *buf, const char *format, va_list args)\r
- * \brief Prints a formatted string to a buffer\r
- * \param buf  Pointer - Destination Buffer\r
- * \param format       String - Format String\r
- * \param args VarArgs List - Arguments\r
- */\r
-EXPORT int vsnprintf(char *buf, size_t __maxlen, const char *format, va_list args)\r
-{\r
-       char    tmp[65];\r
-        int    c, minSize, precision, len;\r
-        int    pos = 0;\r
-       char    *p;\r
-       char    pad;\r
-       uint64_t        arg;\r
-        int    bLongLong, bPadLeft;\r
-\r
-       void _addchar(char ch)\r
-       {\r
-               if(buf && pos < __maxlen)       buf[pos] = ch;\r
-               pos ++;\r
-       }\r
-\r
-       tmp[32] = '\0';\r
-       \r
-       while((c = *format++) != 0)\r
-       {\r
-               // Non-control character\r
-               if (c != '%') {\r
-                       _addchar(c);\r
-                       continue;\r
-               }\r
-               \r
-               // Control Character\r
-               c = *format++;\r
-               if(c == '%') {  // Literal %\r
-                       _addchar('%');\r
-                       continue;\r
-               }\r
-               \r
-               bPadLeft = 0;\r
-               bLongLong = 0;\r
-               minSize = 0;\r
-               precision = -1;\r
-               pad = ' ';\r
-               \r
-               // Padding Character\r
-               if(c == '0') {\r
-                       pad = '0';\r
-                       c = *format++;\r
-               }\r
-               // Padding length\r
-               if( c == '*' ) {\r
-                       // Variable length\r
-                       minSize = va_arg(args, size_t);\r
-                       c = *format++;\r
-               }\r
-               else {\r
-                       if('1' <= c && c <= '9')\r
-                       {\r
-                               minSize = 0;\r
-                               while('0' <= c && c <= '9')\r
-                               {\r
-                                       minSize *= 10;\r
-                                       minSize += c - '0';\r
-                                       c = *format++;\r
-                               }\r
-                       }\r
-               }\r
-\r
-               // Precision\r
-               if(c == '.') {\r
-                       c = *format++;\r
-                       if(c == '*') {\r
-                               precision = va_arg(args, size_t);\r
-                               c = *format++;\r
-                       }\r
-                       else if('1' <= c && c <= '9')\r
-                       {\r
-                               precision = 0;\r
-                               while('0' <= c && c <= '9')\r
-                               {\r
-                                       precision *= 10;\r
-                                       precision += c - '0';\r
-                                       c = *format++;\r
-                               }\r
-                       }\r
-               }\r
-       \r
-               // Check for long long\r
-               bLongLong = 0;\r
-               if(c == 'l')\r
-               {\r
-                       c = *format++;\r
-                       if(c == 'l') {\r
-                               bLongLong = 1;\r
-                       }\r
-               }\r
-               \r
-               // Just help things along later\r
-               p = tmp;\r
-               \r
-               // Get Type\r
-               switch( c )\r
-               {\r
-               // Signed Integer\r
-               case 'd':       case 'i':\r
-                       // Get Argument\r
-                       if(bLongLong)   arg = va_arg(args, int64_t);\r
-                       else                    arg = va_arg(args, int32_t);\r
-                       itoa(tmp, arg, 10, minSize, pad, 1);\r
-                       precision = -1;\r
-                       goto sprintf_puts;\r
-               \r
-               // Unsigned Integer\r
-               case 'u':\r
-                       // Get Argument\r
-                       if(bLongLong)   arg = va_arg(args, uint64_t);\r
-                       else                    arg = va_arg(args, uint32_t);\r
-                       itoa(tmp, arg, 10, minSize, pad, 0);\r
-                       precision = -1;\r
-                       goto sprintf_puts;\r
-               \r
-               // Pointer\r
-               case 'p':\r
-                       _addchar('*');\r
-                       _addchar('0');\r
-                       _addchar('x');\r
-                       arg = va_arg(args, intptr_t);\r
-                       itoa(tmp, arg, 16, minSize, pad, 0);\r
-                       precision = -1;\r
-                       goto sprintf_puts;\r
-               // Unsigned Hexadecimal\r
-               case 'x':\r
-                       if(bLongLong)   arg = va_arg(args, uint64_t);\r
-                       else                    arg = va_arg(args, uint32_t);\r
-                       itoa(tmp, arg, 16, minSize, pad, 0);\r
-                       precision = -1;\r
-                       goto sprintf_puts;\r
-               \r
-               // Unsigned Octal\r
-               case 'o':\r
-                       if(bLongLong)   arg = va_arg(args, uint64_t);\r
-                       else                    arg = va_arg(args, uint32_t);\r
-                       itoa(tmp, arg, 8, minSize, pad, 0);\r
-                       precision = -1;\r
-                       goto sprintf_puts;\r
-               \r
-               // Unsigned binary\r
-               case 'b':\r
-                       if(bLongLong)   arg = va_arg(args, uint64_t);\r
-                       else                    arg = va_arg(args, uint32_t);\r
-                       itoa(tmp, arg, 2, minSize, pad, 0);\r
-                       precision = -1;\r
-                       goto sprintf_puts;\r
-\r
-               // String\r
-               case 's':\r
-                       p = va_arg(args, char*);\r
-               sprintf_puts:\r
-                       if(!p)  p = "(null)";\r
-                       //_SysDebug("vsnprintf: p = '%s'", p);\r
-                       if(precision >= 0)\r
-                               len = strnlen(p, precision);\r
-                       else\r
-                               len = strlen(p);\r
-                       if(bPadLeft)    while(minSize > len++)  _addchar(pad);\r
-                       while( *p ) {\r
-                               if(precision >= 0 && precision -- == 0)\r
-                                       break;\r
-                               _addchar(*p++);\r
-                       }\r
-                       if(!bPadLeft)   while(minSize > len++)  _addchar(pad);\r
-                       break;\r
-\r
-               // Unknown, just treat it as a character\r
-               default:\r
-                       arg = va_arg(args, uint32_t);\r
-                       _addchar(arg);\r
-                       break;\r
-               }\r
-       }\r
-       _addchar('\0');\r
-       pos --;\r
-       \r
-       //_SysDebug("vsnprintf: buf = '%s'", buf);\r
-       \r
-       return pos;\r
-}\r
-\r
-const char cUCDIGITS[] = "0123456789ABCDEF";\r
-/**\r
- * \fn static void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned)\r
- * \brief Convert an integer into a character string\r
- * \param buf  Destination Buffer\r
- * \param num  Number to convert\r
- * \param base Base-n number output\r
- * \param minLength    Minimum length of output\r
- * \param pad  Padding used to ensure minLength\r
- * \param bSigned      Signed number output?\r
- */\r
-EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned)\r
-{\r
-       char    tmpBuf[64];\r
-        int    pos=0, i;\r
-\r
-       if(!buf)        return;\r
-       if(base > 16 || base < 2) {\r
-               buf[0] = 0;\r
-               return;\r
-       }\r
-       \r
-       if(bSigned && (int64_t)num < 0)\r
-       {\r
-               num = -num;\r
-               bSigned = 1;\r
-       } else\r
-               bSigned = 0;\r
-       \r
-       // Encode into reversed string\r
-       while(num > base-1) {\r
-               tmpBuf[pos++] = cUCDIGITS[ num % base ];\r
-               num = (uint64_t) num / (uint64_t)base;          // Shift {number} right 1 digit\r
-       }\r
-\r
-       tmpBuf[pos++] = cUCDIGITS[ num % base ];                // Last digit of {number}\r
-       if(bSigned)     tmpBuf[pos++] = '-';    // Append sign symbol if needed\r
-       \r
-       i = 0;\r
-       minLength -= pos;\r
-       while(minLength-- > 0)  buf[i++] = pad;\r
-       while(pos-- > 0)                buf[i++] = tmpBuf[pos]; // Reverse the order of characters\r
-       buf[i] = 0;\r
-}\r
-\r
-/**\r
- * \fn EXPORT int printf(const char *format, ...)\r
- * \brief Print a string to stdout\r
- */\r
-EXPORT int printf(const char *format, ...)\r
-{\r
-       #if 1\r
-        int    size;\r
-       va_list args;\r
-       \r
-       // Get final size\r
-       va_start(args, format);\r
-       size = vsnprintf(NULL, 0, (char*)format, args);\r
-       va_end(args);\r
-       char buf[size+1];\r
-       // Fill Buffer\r
-       va_start(args, format);\r
-       vsnprintf(buf, size+1, (char*)format, args);\r
-       va_end(args);\r
-       \r
-       // Send to stdout\r
-       write(_stdout, buf, size+1);\r
-       \r
-       // Free buffer\r
-       free(buf);\r
-       // Return\r
-       return size;\r
-       \r
-       #else\r
-       \r
-        int    ret;\r
-       va_list args;\r
-       va_start(args, format);\r
-       ret = fprintfv(stdout, (char*)format, args);\r
-       va_end(args);\r
-       return ret;\r
-       #endif\r
-}\r
-\r
-/**\r
- * \fn EXPORT int sprintf(const char *buf, char *format, ...)\r
- * \brief Print a formatted string to a buffer\r
- */\r
-EXPORT int sprintf(char *buf, const char *format, ...)\r
-{\r
-        int    ret;\r
-       va_list args;\r
-       va_start(args, format);\r
-       ret = vsprintf((char*)buf, (char*)format, args);\r
-       va_end(args);\r
-       return ret;\r
-}\r
-\r
-/**\r
- * \fn EXPORT int snprintf(const char *buf, size_t maxlen, char *format, ...)\r
- * \brief Print a formatted string to a buffer\r
- */\r
-EXPORT int snprintf(char *buf, size_t maxlen, const char *format, ...)\r
-{\r
-        int    ret;\r
-       va_list args;\r
-       va_start(args, format);\r
-       ret = vsnprintf((char*)buf, maxlen, (char*)format, args);\r
-       va_end(args);\r
-       return ret;\r
-}\r
index d529f65..bdf64de 100644 (file)
@@ -185,7 +185,7 @@ EXPORT void free(void *mem)
        DEBUGS("free(%p) : 0x%x bytes", mem, head->size);\r
        \r
        //Unify Right\r
-       if((intptr_t)head + head->size < (intptr_t)_heap_end)\r
+       if((uintptr_t)head + head->size < (uintptr_t)_heap_end)\r
        {\r
                heap_head       *nextHead = (heap_head*)((intptr_t)head + head->size);\r
                if(nextHead->magic == MAGIC_FREE) {     //Is the next block free\r
@@ -194,7 +194,7 @@ EXPORT void free(void *mem)
                }\r
        }\r
        //Unify Left\r
-       if((intptr_t)head - sizeof(heap_foot) > (intptr_t)_heap_start)\r
+       if((uintptr_t)head - sizeof(heap_foot) > (uintptr_t)_heap_start)\r
        {\r
                heap_head       *prevHead;\r
                heap_foot       *prevFoot = (heap_foot *)((intptr_t)head - sizeof(heap_foot));\r
diff --git a/Usermode/Libraries/libc.so_src/include_exp/assert.h b/Usermode/Libraries/libc.so_src/include_exp/assert.h
new file mode 100644 (file)
index 0000000..07b20b3
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Acess2 C Library
+ * - By John Hodge (thePowersGang)
+ *
+ * assert.h
+ * - assert(expr)
+ */
+#ifndef _LIBC__ASSERT_H_
+#define _LIBC__ASSERT_H_
+
+#ifdef NDEBUG
+# define assert(expr)  do{}while(0)
+#else
+# define assert(expr)  do{if(!(expr)) { fprintf(stderr, "%s:%i: Assertion '%s' failed\n", __FILE__, __LINE__, #expr); exit(-1);}}while(0)
+#endif
+
+#endif
+
index 4c5613b..ddb0a61 100644 (file)
@@ -35,5 +35,11 @@ static inline int isspace(int ch) {
        if(ch == '\n')  return 1;
        return 0;
 }
+// C99
+static inline int isblank(int ch) {
+       if(ch == ' ')   return 1;
+       if(ch == '\t')  return 1;
+       return 0;
+}
 
 #endif
diff --git a/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h b/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h
new file mode 100644 (file)
index 0000000..090b06b
--- /dev/null
@@ -0,0 +1,25 @@
+
+enum {
+       EOK,
+       ENOSYS, // Invalid Instruction
+       EINVAL, // Invalid Paramater
+       ENOMEM, // No free memory
+       EACCES, // Not permitted
+       EBUSY,  // Resource is busy
+       ERANGE, // Value out of range
+       ENOTFOUND,      // Item not found
+       EREADONLY,      // Read only
+       ENOTIMPL,       // Not implemented
+       ENOENT, // No entry?
+       EEXIST, // Already exists
+       ENFILE, // Too many open files
+       ENOTDIR,        // Not a directory
+       EIO,    // IO Error
+       EINTR,  // Operation interrupted (signal)
+       
+       EALREADY,       // Operation was a NOP
+       EINTERNAL,      // Internal Error
+       
+       NUM_ERRNO
+};
+
index ea352f3..cbe8749 100644 (file)
@@ -8,21 +8,6 @@ extern int     _errno;
 
 #define strerror(_x)   "Unimplemented"
 
-enum
-{
-       EOK,
-       EINVAL,
-       ERANGE,
-       ENODEV,
-       EBADF,
-       EINTR,
-       EAGAIN,
-       ENOMEM,
-
-       EADDRNOTAVAIL,
-       EINPROGRESS,
-
-       E_LAST
-};
+#include "errno.enum.h"
 
 #endif
index cc72b00..bf03c7f 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef _SIGNAL_H_
 #define _SIGNAL_H_
 
+typedef void (*sighandler_t)(int);
+
 #define SIG_DFL        ((void*)0)
 #define SIG_ERR        ((void*)-1)
 
@@ -16,5 +18,7 @@
 #define SIGPIPE        1001
 #define SIGCHLD        1002
 
+extern int     raise(int sig);
+
 #endif
 
index be4f20a..d8643eb 100644 (file)
@@ -21,6 +21,7 @@ extern int    vsnprintf(char *buf, size_t __maxlen, const char *format, va_list arg
 extern int     vsprintf(char *buf, const char *format, va_list args);
 extern int     sprintf(char *buf, const char *format, ...);
 extern int     snprintf(char *buf, size_t maxlen, const char *format, ...);
+extern void    perror(const char *s);
 
 extern FILE    *fopen(const char *file, const char *mode);
 extern FILE    *freopen(const char *file, const char *mode, FILE *fp);
@@ -29,6 +30,10 @@ extern int   fclose(FILE *fp);
 extern void    fflush(FILE *fp);
 extern off_t   ftell(FILE *fp);
 extern int     fseek(FILE *fp, long int amt, int whence);
+extern void    clearerr(FILE *stream);
+extern int     feof(FILE *stream);
+extern int     ferror(FILE *stream);
+extern int     fileno(FILE *stream);
 
 extern size_t  fread(void *buf, size_t size, size_t n, FILE *fp);
 extern size_t  fwrite(void *buf, size_t size, size_t n, FILE *fp);
@@ -40,6 +45,14 @@ extern int   putchar(int ch);
 extern int     fprintf(FILE *fp, const char *format, ...);
 extern int     vfprintf(FILE *fp, const char *format, va_list args);
 
+// scanf
+extern int     scanf(const char *format, ...);
+extern int     fscanf(FILE *stream, const char *format, ...);
+extern int     sscanf(const char *str, const char *format, ...);
+extern int     vscanf(const char *format, va_list ap);
+extern int     vsscanf(const char *str, const char *format, va_list ap);
+extern int     vfscanf(FILE *stream, const char *format, va_list ap);
+
 extern FILE    *stdin;
 extern FILE    *stdout;
 extern FILE    *stderr;
index 8acfb8b..7676afe 100644 (file)
 \r
 /* --- StdLib --- */\r
 extern void    _exit(int code) __attribute__((noreturn));      /* NOTE: Also defined in acess/sys.h */\r
+\r
 extern long long       strtoll(const char *ptr, char **end, int base);\r
 extern long    strtol(const char *ptr, char **end, int base);\r
+extern unsigned long long      strtoull(const char *ptr, char **end, int base);\r
+extern unsigned long   strtoul(const char *ptr, char **end, int base);\r
 extern int     atoi(const char *ptr);\r
 extern void    exit(int status) __attribute__((noreturn));\r
+extern void    abort(void);\r
 extern void    atexit(void (*__func)(void));\r
 extern void    qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));\r
 extern int     abs(int j);\r
index 9f773dc..9e91c9f 100644 (file)
@@ -18,6 +18,8 @@
 #define        LOCAL\r
 #endif\r
 \r
+#define UNUSED(type, param)    __attribute__((unused)) type UNUSED__##param\r
+\r
 extern void *memcpy(void *dest, const void *src, size_t n);\r
 \r
 typedef struct sCPUID  tCPUID;\r
diff --git a/Usermode/Libraries/libc.so_src/perror.c b/Usermode/Libraries/libc.so_src/perror.c
new file mode 100644 (file)
index 0000000..0431635
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Acess2 C Library
+ * - By John Hodge (thePowersGang)
+ *
+ * perror.c
+ * - perror() and friends
+ */
+#include <errno.h>
+#include <stdio.h>
+
+void perror(const char *s)
+{
+       fprintf(stderr, "%s: Error (%i)\n", s, errno);
+}
index f689f34..23f3925 100644 (file)
@@ -4,6 +4,7 @@ include $(BASE)header.mk
 
 # Variables
 SRCS := stub.c heap.c stdlib.c env.c fileIO.c string.c select.c
+SRCS += perror.c
 SRCS += arch/$(ARCHDIR).$(ASSUFFIX)
 # signals.c
 BIN  := $(OUTPUTDIR)Libs/libc.so
diff --git a/Usermode/Libraries/libc.so_src/scanf.c b/Usermode/Libraries/libc.so_src/scanf.c
new file mode 100644 (file)
index 0000000..3a561c4
--- /dev/null
@@ -0,0 +1,445 @@
+/*
+ * Acess2 C Library
+ * - By John Hodge (thePowersGang)
+ *
+ * scanf.c
+ * - *scanf family of functions
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+
+extern void    _SysDebug(const char *format, ...);
+
+enum e_vcscanf_types
+{
+       _VCSCANF_NOTYPE,
+       _VCSCANF_INT,
+       _VCSCANF_REAL,
+};
+
+enum e_vcscanf_sizes
+{
+       _VCSCANF_UNDEF,
+       _VCSCANF_CHAR,
+       _VCSCANF_SHORT,
+       _VCSCANF_LONG,
+       _VCSCANF_LONGLONG,
+       _VCSCANF_INTMAX,
+       _VCSCANF_SIZET,
+       _VCSCANF_PTRDIFF,
+       _VCSCANF_LONGDOUBLE
+};
+
+// === CODE ===
+int _vcscanf_int(int (*__getc)(void *), void (*__rewind)(void*), void *h, int base, int maxlen, long long *outval)
+{
+       char    ich;
+        int    sgn = 1;
+       long long int   ret = 0;
+        int    n_read = 0;
+
+       // Initialise output to something sane
+       *outval = 0;
+
+       // First character
+       // - maxlen == 0 means no limit
+       ich = __getc(h);
+       n_read ++;
+       
+       // Sign?
+       if( ich == '-' || ich == '+' ) {
+               sgn = (ich == '-' ? -1 : 1);
+               if( n_read == maxlen )
+                       return n_read;
+               ich = __getc(h);
+               n_read ++;
+       }
+       
+       // Determine base
+       if( base == 0 ) {
+               if( ich != '0' ) {
+                       base = 10;
+               }
+               else {
+                       if( n_read == maxlen )
+                               return n_read;
+                       ich = __getc(h);
+                       n_read ++;
+                       if( ich != 'x' ) {
+                               base = 8;
+                       }
+                       else {
+                               base = 16;
+                               if( n_read == maxlen )
+                                       return n_read;
+                               ich = __getc(h);
+                               n_read ++;
+                       }
+               }
+       }
+       
+       if( ich == 0 ) {
+               // Oops?
+               return n_read;
+       }
+       
+       while( ich )
+       {
+                int    next = -1;
+               
+               // Get the digit value
+               if( base <= 10 ) {
+                       if( '0' <= ich && ich <= '0'+base-1 )
+                               next = ich - '0';
+               }
+               else {
+                       if( '0' <= ich && ich <= '9' )
+                               next = ich - '0';
+                       if( 'A' <= ich && ich <= 'A'+base-10-1 )
+                               next = ich - 'A' + 10;
+                       if( 'a' <= ich && ich <= 'a'+base-10-1 )
+                               next = ich - 'a' + 10;
+               }
+               // if it's not a digit, rewind and break
+               if( next < 0 ) {
+                       __rewind(h);
+                       n_read --;
+                       break;
+               }
+               
+               // Add to the result
+               ret *= base;
+               ret += next;
+               //_SysDebug("- %i/%i read, 0x%x val", n_read, maxlen, ret);
+
+               // Check if we've reached the limit
+               if( n_read == maxlen )
+                       break ;
+
+               // Next character
+               ich = __getc(h);
+               n_read ++;
+       }
+       
+       // Apply sign
+       if( sgn == -1 )
+               ret = -ret;
+
+       *outval = ret;
+       return n_read;
+}
+
+int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char *format, va_list ap)
+{
+       char    fch, ich;
+        int    ret = 0, nch = 0;
+       
+       while( (fch = *format++) )
+       {
+               union {
+                       void    *_void;
+                       char    *_char;
+                       short   *_short;
+                        int    *_int;
+                       long    *_long;
+                       long long       *_longlong;
+               }       ptr;
+               long long       ival;
+               //long double   rval;
+                int    maxlen = 0, offset = -1;
+               enum e_vcscanf_sizes    size = _VCSCANF_UNDEF;
+               enum e_vcscanf_types    valtype;
+
+               const char      *set_start;
+                int    set_len;                
+
+               // Whitespace matches any ammount of whitespace (including none)
+               if( isspace(fch) )
+               {
+                       while( (ich = __getc(h)) && isspace(ich) )
+                               nch ++;
+                       continue ;
+               }
+               
+               // Any non-whitespace and non-% characters must match exactly
+               if( fch != '%' )
+               {
+                       if( __getc(h) != fch )
+                               break;
+                       nch ++;
+                       continue ;
+               }
+               
+               // Format specifier
+               fch = *format++;
+               if(!fch)        break;
+
+               // Catch '%%' early
+               if( fch == '%' ) {
+                       if( __getc(h) != '%' )
+                               break;
+                       nch ++;
+                       continue ;
+               }               
+
+               // %n$ - Direct offset selection, shouldn't be mixed with just %
+               for( ; isdigit(fch); fch = *format++ )
+                       maxlen = maxlen * 10 + (fch - '0');
+               if( fch == '$' ) {
+                       offset = maxlen;
+                       maxlen = 0;
+               }
+               
+               // Supress assignemnt?
+               if( fch == '*' )
+               {
+                       fch = *format++;
+                       ptr._void = NULL;
+                       ret --;
+               }
+               else
+                       ptr._void = va_arg(ap, void*);
+               
+               // Max field length
+               while( isdigit(fch) )
+               {
+                       maxlen = maxlen * 10 + fch - '0';
+                       fch = *format++;
+               }
+               
+               // Length modifier
+               switch( fch )
+               {
+               case 'h':
+                       // 'short'
+                       size = _VCSCANF_SHORT;
+                       fch = *format++;
+                       if( fch == 'h' ) {
+                               // 'char'
+                               size = _VCSCANF_CHAR;
+                               fch = *format++;
+                       }
+                       break;
+               case 'l':
+                       // 'long'
+                       size = _VCSCANF_LONG;
+                       fch = *format++;
+                       if( fch == 'l' ) {
+                               // 'long long'
+                               size = _VCSCANF_LONGLONG;
+                               fch = *format++;
+                       }
+                       break;
+               case 'j':
+                       // '(u)intmax_t'
+                       size = _VCSCANF_INTMAX;
+                       fch = *format++;
+                       break;
+               case 'z':
+                       // 'size_t'
+                       size = _VCSCANF_SIZET;
+                       fch = *format++;
+                       break;
+               case 't':
+                       // 'ptrdiff_t'
+                       size = _VCSCANF_PTRDIFF;
+                       fch = *format++;
+                       break;
+               case 'L':
+                       // 'long double' (a, A, e, E, f, F, g, G)
+                       size = _VCSCANF_LONGDOUBLE;
+                       fch = *format++;
+                       break;
+               }
+               
+               // Format specifiers
+               switch( fch )
+               {
+               // Decimal integer
+               case 'd':
+                       nch += _vcscanf_int(__getc, __rewind, h, 10, maxlen, &ival);
+                       valtype = _VCSCANF_INT;
+                       break;
+               // variable-base integer
+               case 'i':
+                       nch += _vcscanf_int(__getc, __rewind, h, 0, maxlen, &ival);
+                       valtype = _VCSCANF_INT;
+                       break;
+               // Octal integer
+               case 'o':
+                       nch += _vcscanf_int(__getc, __rewind, h, 8, maxlen, &ival);
+                       valtype = _VCSCANF_INT;
+                       break;
+               // Hexadecimal integer
+               case 'x': case 'X':
+                       nch += _vcscanf_int(__getc, __rewind, h, 16, maxlen, &ival);
+                       valtype = _VCSCANF_INT;
+                       break;
+               // strtod format float
+               case 'a': case 'A':
+               case 'e': case 'E':
+               case 'f': case 'F':
+               case 'g': case 'G':
+                       valtype = _VCSCANF_REAL;
+                       break;
+               // `maxlen` or 1 characters
+               case 'c':
+                       if( maxlen == 0 )
+                               maxlen = 1;
+                       while( maxlen -- && (ich = __getc(h)) )
+                       {
+                               if(ptr._char)   *ptr._char++ = ich;
+                               nch ++;
+                       }
+                       valtype = _VCSCANF_NOTYPE;
+                       break;
+               // sequence of non-whitespace characters
+               case 's':
+                       if( maxlen == 0 )
+                               maxlen = -1;
+
+                       ich = 0;
+                       while( maxlen -- && (ich = __getc(h)) && !isblank(ich) )
+                       {
+                               if(ptr._char)   *ptr._char++ = ich;
+                               nch ++;
+                       }
+                       if( maxlen >= 0 && ich )
+                               __rewind(h);
+                       valtype = _VCSCANF_NOTYPE;
+                       break;
+               // match a set of characters
+               case '[':
+                       fch = *format++;
+                       if( fch == '^' ) {
+                               // Invert
+                               fch = *format;
+                       }
+                       set_start = format;
+                       set_len = 0;
+                       // if the first character is ']' it's part of the set
+                       do {
+                               // permissable character
+                               set_len ++;
+                               fch = *format++;
+                       } while( fch && fch != ']' );
+
+                       ich = 0;
+                       while( maxlen -- && (ich = __getc(h)) && memchr(set_start, set_len, ich) )
+                       {
+                               if(ptr._char)   *ptr._char++ = ich;
+                               nch ++;
+                       }
+                       if( maxlen >= 0 && ich )
+                               __rewind(h);
+                       valtype = _VCSCANF_NOTYPE;
+                       break;
+               case 'p': // read back printf("%p")
+                       valtype = _VCSCANF_NOTYPE;
+                       break;
+               case 'n': // number of read characters to this point
+                       if(ptr._int) {
+                               *ptr._int = nch;
+                               ret --; // negates the ret ++ at the end
+                       }
+                       valtype = _VCSCANF_NOTYPE;
+                       break;
+               default:
+                       // Implimentation defined
+                       valtype = _VCSCANF_NOTYPE;
+                       break;
+               }
+               
+               switch(valtype)
+               {
+               case _VCSCANF_NOTYPE:
+                       // Used when assignment is done above
+                       break;
+               case _VCSCANF_INT:
+                       switch(size)
+                       {
+                       case _VCSCANF_UNDEF:    *ptr._int = ival;       break;
+                       case _VCSCANF_CHAR:     *ptr._char = ival;      break;
+                       case _VCSCANF_SHORT:    *ptr._short = ival;     break;
+                       case _VCSCANF_LONG:     *ptr._long = ival;      break;
+                       case _VCSCANF_LONGLONG: *ptr._longlong = ival;  break;
+                       default:        // ???
+                               break;
+                       }
+                       break;
+               case _VCSCANF_REAL:
+                       break;
+               }
+               
+               ret ++;
+       }
+       
+       return ret;
+}
+
+int _vsscanf_getc(void *h)
+{
+       const char      **ibuf = h;
+       return *(*ibuf)++;      // Dereference, read for return, increment
+}
+
+void _vsscanf_rewind(void *h)
+{
+       const char      **ibuf = h;
+       (*ibuf) --;     // NOTE: Breaks if there's a rewind before a getc, but that shouldn't happen
+}
+
+int vscanf(const char *format, va_list ap)
+{
+       return vfscanf(stdin, format, ap);
+}
+
+int vsscanf(const char *str, const char *format, va_list ap)
+{
+       return _vcscanf(_vsscanf_getc, _vsscanf_rewind, &str, format, ap);
+}
+
+int _vfscanf_getc(void *h)
+{
+       return fgetc(h);        // TODO: Handle -1 -> 0
+}
+void _vfscanf_rewind(void *h)
+{
+       fseek(h, -1, SEEK_CUR);
+}
+
+int vfscanf(FILE *stream, const char *format, va_list ap)
+{
+       return _vcscanf(_vfscanf_getc, _vfscanf_rewind, stream, format, ap);
+}
+
+int scanf(const char *format, ...)
+{
+       va_list args;
+        int    rv;
+       va_start(args, format);
+       rv = vfscanf(stdin, format, args);
+       va_end(args);
+       return rv;
+}
+int fscanf(FILE *stream, const char *format, ...)
+{
+       va_list args;
+        int    rv;
+       va_start(args, format);
+       rv = vfscanf(stream, format, args);
+       va_end(args);
+       return rv;
+}
+int sscanf(const char *str, const char *format, ...)
+{
+       va_list args;
+        int    rv;
+       va_start(args, format);
+       rv = vsscanf(str, format, args);
+       va_end(args);
+       return rv;
+}
+
index ddaf544..f8b71d3 100644 (file)
@@ -2,7 +2,7 @@
  * AcessOS Basic C Library
  * signals.c
 */
-#include <syscalls.h>
+//#include <acess/sys.h>
 #include <stdlib.h>
 #include <signal.h>
 #include "lib.h"
@@ -22,3 +22,22 @@ sighandler_t signal(int num, sighandler_t handler)
        sighandlers[num] = handler;
        return prev;
 }
+
+int raise(int signal)
+{
+       if( signal < 0 || signal > NUM_SIGNALS )
+               return 1;
+       switch(signal)
+       {
+       case SIGABRT:
+               abort();
+               break;
+       }
+       return 0;
+}
+
+void abort(void)
+{
+       // raise(SIGABRT);
+       _exit(-1);
+}
diff --git a/Usermode/Libraries/libc.so_src/stdio.c b/Usermode/Libraries/libc.so_src/stdio.c
new file mode 100644 (file)
index 0000000..1dde9ad
--- /dev/null
@@ -0,0 +1,718 @@
+/*\r
+ * AcessOS Basic C Library\r
+ * stdio.c\r
+ */\r
+#include "config.h"\r
+#include <acess/sys.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include "lib.h"\r
+#include "stdio_int.h"\r
+\r
+#define WRITE_STR(_fd, _str)   write(_fd, _str, sizeof(_str))\r
+\r
+#define DEBUG_BUILD    0\r
+\r
+// === CONSTANTS ===\r
+#define        _stdin  0\r
+#define        _stdout 1\r
+\r
+// === PROTOTYPES ===\r
+EXPORT void    itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned);\r
+struct sFILE   *get_file_struct();\r
+\r
+// === GLOBALS ===\r
+struct sFILE   _iob[STDIO_MAX_STREAMS];        // IO Buffer\r
+struct sFILE   *stdin; // Standard Input\r
+struct sFILE   *stdout;        // Standard Output\r
+struct sFILE   *stderr;        // Standard Error\r
+///\note Initialised in SoMain\r
+\r
+// === CODE ===\r
+int _fopen_modetoflags(const char *mode)\r
+{\r
+       int flags = 0;\r
+       \r
+       // Get main mode\r
+       switch(*mode)\r
+       {\r
+       case 'r':       flags = FILE_FLAG_MODE_READ;    break;\r
+       case 'w':       flags = FILE_FLAG_MODE_WRITE;   break;\r
+       case 'a':       flags = FILE_FLAG_MODE_APPEND;  break;\r
+       case 'x':       flags = FILE_FLAG_MODE_EXEC;    break;  // Acess addon\r
+       default:\r
+               return -1;\r
+       }\r
+       mode ++;\r
+\r
+       // Get Modifiers\r
+       for( ; *mode; mode ++ )\r
+       {\r
+               switch(*mode)\r
+               {\r
+               case 'b':       flags |= FILE_FLAG_M_BINARY;    break;\r
+               case '+':       flags |= FILE_FLAG_M_EXT;       break;\r
+               default:\r
+                       return -1;\r
+               }\r
+       }\r
+       \r
+       return flags;\r
+}\r
+\r
+/**\r
+ * \fn FILE *freopen(char *file, char *mode, FILE *fp)\r
+ */\r
+EXPORT FILE *freopen(const char *file, const char *mode, FILE *fp)\r
+{\r
+        int    openFlags = 0;\r
+       \r
+       // Sanity Check Arguments\r
+       if(!fp || !file || !mode)       return NULL;\r
+       \r
+       if(fp->FD != -1) {\r
+               fflush(fp);\r
+       }\r
+\r
+       // Get stdio flags\r
+       fp->Flags = _fopen_modetoflags(mode);\r
+       if(fp->Flags == -1)\r
+               return NULL;\r
+       \r
+       // Get Open Flags\r
+       switch(fp->Flags & FILE_FLAG_MODE_MASK)\r
+       {\r
+       // Read\r
+       case FILE_FLAG_MODE_READ:\r
+               openFlags = OPENFLAG_READ;\r
+               if(fp->Flags & FILE_FLAG_M_EXT)\r
+                       openFlags |= OPENFLAG_WRITE;\r
+               break;\r
+       // Write\r
+       case FILE_FLAG_MODE_WRITE:\r
+               openFlags = OPENFLAG_WRITE;\r
+               if(fp->Flags & FILE_FLAG_M_EXT)\r
+                       openFlags |= OPENFLAG_READ;\r
+               break;\r
+       // Execute\r
+       case FILE_FLAG_MODE_APPEND:\r
+               openFlags = OPENFLAG_APPEND;\r
+               if(fp->Flags & FILE_FLAG_M_EXT)\r
+                       openFlags |= OPENFLAG_READ;\r
+               break;\r
+       // Execute\r
+       case FILE_FLAG_MODE_EXEC:\r
+               openFlags = OPENFLAG_EXEC;\r
+               break;\r
+       }\r
+\r
+       //Open File\r
+       if(fp->FD != -1)\r
+               fp->FD = _SysReopen(fp->FD, file, openFlags);\r
+       else\r
+               fp->FD = _SysOpen(file, openFlags);\r
+       if(fp->FD == -1) {\r
+               fp->Flags = 0;\r
+               return NULL;\r
+       }\r
+       \r
+       if( (fp->Flags & FILE_FLAG_MODE_MASK) == FILE_FLAG_MODE_APPEND ) {\r
+               _SysSeek(fp->FD, 0, SEEK_END);  //SEEK_END\r
+       }\r
+       \r
+       return fp;\r
+}\r
+/**\r
+ \fn FILE *fopen(const char *file, const char *mode)\r
+ \brief Opens a file and returns the pointer\r
+ \param file   String - Filename to open\r
+ \param mode   Mode to open in\r
+*/\r
+EXPORT FILE *fopen(const char *file, const char *mode)\r
+{\r
+       FILE    *retFile;\r
+       \r
+       // Sanity Check Arguments\r
+       if(!file || !mode)      return NULL;\r
+       \r
+       // Create Return Structure\r
+       retFile = get_file_struct();\r
+       \r
+       return freopen(file, mode, retFile);\r
+}\r
+\r
+EXPORT FILE *fmemopen(void *buffer, size_t length, const char *mode)\r
+{\r
+       FILE    *ret;\r
+       \r
+       if( !buffer || !mode )  return NULL;\r
+       \r
+       ret = get_file_struct();\r
+       \r
+       ret->FD = -2;\r
+       ret->Flags = _fopen_modetoflags(mode);\r
+       if(ret->Flags == -1) {\r
+               ret->Flags = 0;\r
+               return NULL;\r
+       }\r
+       \r
+       ret->Buffer = buffer;\r
+       ret->BufferStart = 0;\r
+       ret->BufferSize = length;\r
+       \r
+       return ret;\r
+}\r
+\r
+EXPORT int fclose(FILE *fp)\r
+{\r
+       fflush(fp);\r
+       if( fp->FD != -1 ) {\r
+               _SysClose(fp->FD);\r
+       }\r
+       fp->Flags = 0;\r
+       fp->FD = -1;\r
+       return 0;\r
+}\r
+\r
+EXPORT void fflush(FILE *fp)\r
+{\r
+       if( !fp || fp->FD == -1 )\r
+               return ;\r
+       \r
+       if( !(fp->Flags & FILE_FLAG_DIRTY) )\r
+               return ;\r
+       \r
+       // Nothing to do for memory files\r
+       if( fp->FD == -2 )\r
+               return ;\r
+}\r
+\r
+EXPORT void clearerr(FILE *fp)\r
+{\r
+       if( !fp || fp->FD == -1 )\r
+               return ;\r
+       \r
+       // TODO: Impliment clearerr()\r
+}\r
+\r
+EXPORT int feof(FILE *fp)\r
+{\r
+       if( !fp || fp->FD == -1 )\r
+               return 0;\r
+       return !!(fp->Flags & FILE_FLAG_EOF);\r
+}\r
+\r
+EXPORT int ferror(FILE *fp)\r
+{\r
+       if( !fp || fp->FD == -1 )\r
+               return 0;\r
+       return 0;\r
+}\r
+EXPORT int fileno(FILE *stream)\r
+{\r
+       return stream->FD;\r
+}\r
+\r
+EXPORT off_t ftell(FILE *fp)\r
+{\r
+       if(!fp || fp->FD == -1) return -1;\r
+\r
+       if( fp->FD == -2 )\r
+               return fp->Pos; \r
+       else\r
+               return _SysTell(fp->FD);\r
+}\r
+\r
+EXPORT int fseek(FILE *fp, long int amt, int whence)\r
+{\r
+       if(!fp || fp->FD == -1) return -1;\r
+\r
+       if( fp->FD == -2 ) {\r
+               switch(whence)\r
+               {\r
+               case SEEK_CUR:\r
+                       fp->Pos += amt;\r
+                       break;\r
+               case SEEK_SET:\r
+                       fp->Pos = amt;\r
+                       break;\r
+               case SEEK_END:\r
+                       if( fp->BufferSize < (size_t)amt )\r
+                               fp->Pos = 0;\r
+                       else\r
+                               fp->Pos = fp->BufferSize - amt;\r
+                       break;\r
+               }\r
+               if(fp->Pos > (off_t)fp->BufferSize) {\r
+                       fp->Pos = fp->BufferSize;\r
+                       fp->Flags |= FILE_FLAG_EOF;\r
+               }\r
+               return 0;\r
+       }\r
+       else\r
+               return _SysSeek(fp->FD, amt, whence);\r
+}\r
+\r
+\r
+/**\r
+ * \fn EXPORT int vfprintf(FILE *fp, const char *format, va_list args)\r
+ * \brief Print to a file from a variable argument list\r
+ */\r
+EXPORT int vfprintf(FILE *fp, const char *format, va_list args)\r
+{\r
+       va_list tmpList;\r
+        int    size;\r
+\r
+       if(!fp || !format)      return -1;\r
+\r
+       va_copy(tmpList, args);\r
+       \r
+       size = vsnprintf(NULL, 0, (char*)format, tmpList);\r
+       char    buf[size+1];\r
+       vsnprintf(buf, size+1, (char*)format, args);\r
+       \r
+       // Write to stream\r
+       fwrite(buf, size, 1, fp);\r
+       \r
+       // Return written byte count\r
+       return size;\r
+}\r
+\r
+/**\r
+ * \fn int fprintf(FILE *fp, const char *format, ...)\r
+ * \brief Print a formatted string to a stream\r
+ */\r
+EXPORT int fprintf(FILE *fp, const char *format, ...)\r
+{\r
+       va_list args;\r
+        int    ret;\r
+       \r
+       // Get Size\r
+       va_start(args, format);\r
+       ret = vfprintf(fp, (char*)format, args);\r
+       va_end(args);\r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * \fn EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\r
+ * \brief Write to a stream\r
+ */\r
+EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\r
+{\r
+       size_t  ret;\r
+       \r
+       if(!fp || fp->FD == -1)\r
+               return -1;\r
+\r
+       if( fp->FD == -2 ) {\r
+               size_t  avail = (fp->BufferSize - fp->Pos) / size;\r
+               if( avail == 0 )\r
+                       fp->Flags |= FILE_FLAG_EOF;\r
+               if( num > avail )       num = avail;\r
+               size_t  bytes = num * size;\r
+               memcpy((char*)fp->Buffer + fp->Pos, ptr, bytes);\r
+               fp->Pos += bytes;\r
+               ret = num;\r
+       }\r
+       else {  \r
+               ret = _SysWrite(fp->FD, ptr, size*num);\r
+               ret /= size;\r
+       }\r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * \fn EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp)\r
+ * \brief Read from a stream\r
+ */\r
+EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp)\r
+{\r
+       size_t  ret;\r
+       \r
+       if(!fp || fp->FD == -1)\r
+               return -1;\r
+\r
+       if( fp->FD == -2 ) {\r
+               size_t  avail = (fp->BufferSize - fp->Pos) / size;\r
+               if( avail == 0 )\r
+                       fp->Flags |= FILE_FLAG_EOF;\r
+               if( num > avail )       num = avail;\r
+               size_t  bytes = num * size;\r
+               memcpy(ptr, (char*)fp->Buffer + fp->Pos, bytes);\r
+               fp->Pos += bytes;\r
+               ret = num;\r
+       }\r
+       else {\r
+               ret = _SysRead(fp->FD, ptr, size*num);\r
+               ret /= size;\r
+       }\r
+               \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * \fn EXPORT int fputc(int c, FILE *fp)\r
+ * \brief Write a single character to the stream\r
+ */\r
+EXPORT int fputc(int c, FILE *fp)\r
+{\r
+       return fwrite(&c, 1, 1, fp);\r
+}\r
+\r
+EXPORT int putchar(int c)\r
+{\r
+       c &= 0xFF;\r
+       return _SysWrite(_stdout, &c, 1);\r
+}\r
+\r
+/**\r
+ * \fn EXPORT int fgetc(FILE *fp)\r
+ * \brief Read a character from the stream\r
+ */\r
+EXPORT int fgetc(FILE *fp)\r
+{\r
+       char    ret = 0;\r
+       if( fread(&ret, 1, 1, fp) == (size_t)-1 )\r
+               return -1;\r
+       return ret;\r
+}\r
+\r
+EXPORT int getchar(void)\r
+{\r
+       char    ret = 0;\r
+       if(_SysRead(_stdin, &ret, 1) != 1)      return -1;\r
+       return ret;\r
+}\r
+\r
+// --- INTERNAL ---\r
+/**\r
+ * \fn FILE *get_file_struct()\r
+ * \brief Returns a file descriptor structure\r
+ */\r
+FILE *get_file_struct()\r
+{\r
+        int    i;\r
+       for(i=0;i<STDIO_MAX_STREAMS;i++)\r
+       {\r
+               if(_iob[i].Flags & FILE_FLAG_ALLOC)\r
+                       continue ;\r
+               _iob[i].Flags |= FILE_FLAG_ALLOC;\r
+               _iob[i].FD = -1;\r
+               _iob[i].Pos = 0;\r
+               return &_iob[i];\r
+       }\r
+       return NULL;\r
+}\r
+\r
+EXPORT int puts(const char *str)\r
+{\r
+        int    len;\r
+       \r
+       if(!str)        return 0;\r
+       len = strlen(str);\r
+       \r
+       len = _SysWrite(_stdout, str, len);\r
+       _SysWrite(_stdout, "\n", 1);\r
+       return len;\r
+}\r
+\r
+EXPORT int vsprintf(char * __s, const char *__format, va_list __args)\r
+{\r
+       return vsnprintf(__s, 0x7FFFFFFF, __format, __args);\r
+}\r
+\r
+//sprintfv\r
+/**\r
+ * \fn EXPORT void vsnprintf(char *buf, const char *format, va_list args)\r
+ * \brief Prints a formatted string to a buffer\r
+ * \param buf  Pointer - Destination Buffer\r
+ * \param format       String - Format String\r
+ * \param args VarArgs List - Arguments\r
+ */\r
+EXPORT int vsnprintf(char *buf, size_t __maxlen, const char *format, va_list args)\r
+{\r
+       char    tmp[65];\r
+        int    c, minSize, precision, len;\r
+       size_t  pos = 0;\r
+       char    *p;\r
+       char    pad;\r
+       uint64_t        arg;\r
+        int    bLongLong, bPadLeft;\r
+\r
+       void _addchar(char ch)\r
+       {\r
+               if(buf && pos < __maxlen)       buf[pos] = ch;\r
+               pos ++;\r
+       }\r
+\r
+       tmp[32] = '\0';\r
+       \r
+       while((c = *format++) != 0)\r
+       {\r
+               // Non-control character\r
+               if (c != '%') {\r
+                       _addchar(c);\r
+                       continue;\r
+               }\r
+               \r
+               // Control Character\r
+               c = *format++;\r
+               if(c == '%') {  // Literal %\r
+                       _addchar('%');\r
+                       continue;\r
+               }\r
+               \r
+               bPadLeft = 0;\r
+               bLongLong = 0;\r
+               minSize = 0;\r
+               precision = -1;\r
+               pad = ' ';\r
+               \r
+               // Padding Character\r
+               if(c == '0') {\r
+                       pad = '0';\r
+                       c = *format++;\r
+               }\r
+               // Padding length\r
+               if( c == '*' ) {\r
+                       // Variable length\r
+                       minSize = va_arg(args, size_t);\r
+                       c = *format++;\r
+               }\r
+               else {\r
+                       if('1' <= c && c <= '9')\r
+                       {\r
+                               minSize = 0;\r
+                               while('0' <= c && c <= '9')\r
+                               {\r
+                                       minSize *= 10;\r
+                                       minSize += c - '0';\r
+                                       c = *format++;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // Precision\r
+               if(c == '.') {\r
+                       c = *format++;\r
+                       if(c == '*') {\r
+                               precision = va_arg(args, size_t);\r
+                               c = *format++;\r
+                       }\r
+                       else if('1' <= c && c <= '9')\r
+                       {\r
+                               precision = 0;\r
+                               while('0' <= c && c <= '9')\r
+                               {\r
+                                       precision *= 10;\r
+                                       precision += c - '0';\r
+                                       c = *format++;\r
+                               }\r
+                       }\r
+               }\r
+       \r
+               // Check for long long\r
+               bLongLong = 0;\r
+               if(c == 'l')\r
+               {\r
+                       c = *format++;\r
+                       if(c == 'l') {\r
+                               bLongLong = 1;\r
+                       }\r
+               }\r
+               \r
+               // Just help things along later\r
+               p = tmp;\r
+               \r
+               // Get Type\r
+               switch( c )\r
+               {\r
+               // Signed Integer\r
+               case 'd':       case 'i':\r
+                       // Get Argument\r
+                       if(bLongLong)   arg = va_arg(args, int64_t);\r
+                       else                    arg = va_arg(args, int32_t);\r
+                       itoa(tmp, arg, 10, minSize, pad, 1);\r
+                       precision = -1;\r
+                       goto sprintf_puts;\r
+               \r
+               // Unsigned Integer\r
+               case 'u':\r
+                       // Get Argument\r
+                       if(bLongLong)   arg = va_arg(args, uint64_t);\r
+                       else                    arg = va_arg(args, uint32_t);\r
+                       itoa(tmp, arg, 10, minSize, pad, 0);\r
+                       precision = -1;\r
+                       goto sprintf_puts;\r
+               \r
+               // Pointer\r
+               case 'p':\r
+                       _addchar('*');\r
+                       _addchar('0');\r
+                       _addchar('x');\r
+                       arg = va_arg(args, intptr_t);\r
+                       itoa(tmp, arg, 16, minSize, pad, 0);\r
+                       precision = -1;\r
+                       goto sprintf_puts;\r
+               // Unsigned Hexadecimal\r
+               case 'x':\r
+                       if(bLongLong)   arg = va_arg(args, uint64_t);\r
+                       else                    arg = va_arg(args, uint32_t);\r
+                       itoa(tmp, arg, 16, minSize, pad, 0);\r
+                       precision = -1;\r
+                       goto sprintf_puts;\r
+               \r
+               // Unsigned Octal\r
+               case 'o':\r
+                       if(bLongLong)   arg = va_arg(args, uint64_t);\r
+                       else                    arg = va_arg(args, uint32_t);\r
+                       itoa(tmp, arg, 8, minSize, pad, 0);\r
+                       precision = -1;\r
+                       goto sprintf_puts;\r
+               \r
+               // Unsigned binary\r
+               case 'b':\r
+                       if(bLongLong)   arg = va_arg(args, uint64_t);\r
+                       else                    arg = va_arg(args, uint32_t);\r
+                       itoa(tmp, arg, 2, minSize, pad, 0);\r
+                       precision = -1;\r
+                       goto sprintf_puts;\r
+\r
+               // String\r
+               case 's':\r
+                       p = va_arg(args, char*);\r
+               sprintf_puts:\r
+                       if(!p)  p = "(null)";\r
+                       //_SysDebug("vsnprintf: p = '%s'", p);\r
+                       if(precision >= 0)\r
+                               len = strnlen(p, precision);\r
+                       else\r
+                               len = strlen(p);\r
+                       if(bPadLeft)    while(minSize > len++)  _addchar(pad);\r
+                       while( *p ) {\r
+                               if(precision >= 0 && precision -- == 0)\r
+                                       break;\r
+                               _addchar(*p++);\r
+                       }\r
+                       if(!bPadLeft)   while(minSize > len++)  _addchar(pad);\r
+                       break;\r
+\r
+               // Unknown, just treat it as a character\r
+               default:\r
+                       arg = va_arg(args, uint32_t);\r
+                       _addchar(arg);\r
+                       break;\r
+               }\r
+       }\r
+       _addchar('\0');\r
+       pos --;\r
+       \r
+       //_SysDebug("vsnprintf: buf = '%s'", buf);\r
+       \r
+       return pos;\r
+}\r
+\r
+const char cUCDIGITS[] = "0123456789ABCDEF";\r
+/**\r
+ * \fn static void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned)\r
+ * \brief Convert an integer into a character string\r
+ * \param buf  Destination Buffer\r
+ * \param num  Number to convert\r
+ * \param base Base-n number output\r
+ * \param minLength    Minimum length of output\r
+ * \param pad  Padding used to ensure minLength\r
+ * \param bSigned      Signed number output?\r
+ */\r
+EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned)\r
+{\r
+       char    tmpBuf[64];\r
+        int    pos=0, i;\r
+\r
+       if(!buf)        return;\r
+       if(base > 16 || base < 2) {\r
+               buf[0] = 0;\r
+               return;\r
+       }\r
+       \r
+       if(bSigned && (int64_t)num < 0)\r
+       {\r
+               num = -num;\r
+               bSigned = 1;\r
+       } else\r
+               bSigned = 0;\r
+       \r
+       // Encode into reversed string\r
+       while(num > base-1) {\r
+               tmpBuf[pos++] = cUCDIGITS[ num % base ];\r
+               num = (uint64_t) num / (uint64_t)base;          // Shift {number} right 1 digit\r
+       }\r
+\r
+       tmpBuf[pos++] = cUCDIGITS[ num % base ];                // Last digit of {number}\r
+       if(bSigned)     tmpBuf[pos++] = '-';    // Append sign symbol if needed\r
+       \r
+       i = 0;\r
+       minLength -= pos;\r
+       while(minLength-- > 0)  buf[i++] = pad;\r
+       while(pos-- > 0)                buf[i++] = tmpBuf[pos]; // Reverse the order of characters\r
+       buf[i] = 0;\r
+}\r
+\r
+/**\r
+ * \fn EXPORT int printf(const char *format, ...)\r
+ * \brief Print a string to stdout\r
+ */\r
+EXPORT int printf(const char *format, ...)\r
+{\r
+        int    size;\r
+       va_list args;\r
+       \r
+       // Get final size\r
+       va_start(args, format);\r
+       size = vsnprintf(NULL, 0, (char*)format, args);\r
+       va_end(args);\r
+       char buf[size+1];\r
+       // Fill Buffer\r
+       va_start(args, format);\r
+       vsnprintf(buf, size+1, (char*)format, args);\r
+       va_end(args);\r
+       \r
+       // Send to stdout\r
+       _SysWrite(_stdout, buf, size+1);\r
+       \r
+       // Free buffer\r
+       free(buf);\r
+       // Return\r
+       return size;\r
+}\r
+\r
+/**\r
+ * \fn EXPORT int sprintf(const char *buf, char *format, ...)\r
+ * \brief Print a formatted string to a buffer\r
+ */\r
+EXPORT int sprintf(char *buf, const char *format, ...)\r
+{\r
+        int    ret;\r
+       va_list args;\r
+       va_start(args, format);\r
+       ret = vsprintf((char*)buf, (char*)format, args);\r
+       va_end(args);\r
+       return ret;\r
+}\r
+\r
+/**\r
+ * \fn EXPORT int snprintf(const char *buf, size_t maxlen, char *format, ...)\r
+ * \brief Print a formatted string to a buffer\r
+ */\r
+EXPORT int snprintf(char *buf, size_t maxlen, const char *format, ...)\r
+{\r
+        int    ret;\r
+       va_list args;\r
+       va_start(args, format);\r
+       ret = vsnprintf((char*)buf, maxlen, (char*)format, args);\r
+       va_end(args);\r
+       return ret;\r
+}\r
index 5bfbf98..f87da81 100644 (file)
@@ -4,28 +4,35 @@
  * Configuration Options
  */
 #ifndef _STDIO_INT_H
-# define _STDIO_INT_H
+#define _STDIO_INT_H
+
+#include <sys/types.h>
+#include <stddef.h>
 
 // === CONSTANTS ===
-#define FILE_FLAG_MODE_MASK    0x07
-#define FILE_FLAG_MODE_READ            0x01
-#define FILE_FLAG_MODE_WRITE   0x02
-#define FILE_FLAG_MODE_EXEC            0x03
-#define FILE_FLAG_MODE_APPEND  0x04
-#define FILE_FLAG_M_EXT                0x10
+#define FILE_FLAG_MODE_MASK    0x0007
+#define FILE_FLAG_MODE_READ    0x0001
+#define FILE_FLAG_MODE_WRITE   0x0002
+#define FILE_FLAG_MODE_EXEC    0x0003
+#define FILE_FLAG_MODE_APPEND  0x0004
+#define FILE_FLAG_M_EXT        0x0010
+#define FILE_FLAG_M_BINARY     0x0020
+#define FILE_FLAG_EOF          0x0100
+#define FILE_FLAG_DIRTY        0x0200
+#define FILE_FLAG_ALLOC        0x1000
 
 // === TYPES ===
 struct sFILE {
-        int    FD;
         int    Flags;
+        int    FD;
+       off_t   Pos;    
+
        #if DEBUG_BUILD
-       char    *FileName;
-       #endif
-       #if STDIO_LOCAL_BUFFER
-       char    *Buffer;
-       Uint64  BufferStart;
-        int    BufferSize;
+       char    *FileName;      // heap
        #endif
+       void    *Buffer;
+       off_t   BufferStart;
+       size_t  BufferSize;
 };
 
 #endif
index c91106c..6e81c65 100644 (file)
@@ -5,14 +5,8 @@
 #include <acess/sys.h>\r
 #include <stdlib.h>\r
 #include <stdio.h>\r
-#include <errno.h>\r
-#include <ctype.h>\r
-#include <limits.h>\r
 #include "lib.h"\r
 \r
-#define _stdout        1\r
-#define _stdin 0\r
-\r
 extern void    *_crt0_exit_handler;\r
 \r
 // === PROTOTYPES ===\r
@@ -48,7 +42,7 @@ EXPORT void exit(int status)
  */\r
 EXPORT void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *))\r
 {\r
-        int    i, j, min;\r
+       size_t  i, j, min;\r
        // With 0 items, there's nothing to do and with 1 its already sorted\r
        if(nmemb == 0 || nmemb == 1)    return;\r
        \r
@@ -71,95 +65,6 @@ EXPORT void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void
        }\r
 }\r
 \r
-EXPORT long long strtoll(const char *str, char **end, int base)\r
-{\r
-        int    neg = 0;\r
-       long long       ret = 0;\r
-       \r
-       if( !str || base < 0 || base > 36 || base == 1 ) {\r
-               if(end)\r
-                       *end = (char*)str;\r
-               errno = EINVAL;\r
-               return 0;\r
-       }\r
-\r
-       while( isspace(*str) )\r
-               str++;\r
-       \r
-       // Check for negative (or positive) sign\r
-       if(*str == '-' || *str == '+') {\r
-               neg = (*str == '-');\r
-               str++;\r
-       }\r
-       \r
-       if( base == 0 || base == 16 ) {\r
-               if( *str == '0' && str[1] == 'x' ) {\r
-                       str += 2;\r
-                       base = 16;\r
-               }\r
-       }\r
-       \r
-       if( base == 0 && *str == '0' ) {\r
-               str ++;\r
-               base = 8;\r
-       }\r
-\r
-       if( base == 0 )\r
-               base = 10;\r
-\r
-       while( *str )\r
-       {\r
-                int    next = -1;\r
-               if( base <= 10 ) {\r
-                       if( '0' <= *str && *str <= '0'+base-1 )\r
-                               next = *str - '0';\r
-               }\r
-               else {\r
-                       if( '0' <= *str && *str <= '9' )\r
-                               next = *str - '0';\r
-                       if( 'A' <= *str && *str <= 'A'+base-10-1 )\r
-                               next = *str - 'A';\r
-                       if( 'a' <= *str && *str <= 'a'+base-10-1 )\r
-                               next = *str - 'a';\r
-               }\r
-               if( next < 0 )\r
-                       break;\r
-               ret *= base;\r
-               ret += next;\r
-               str ++;\r
-       }\r
-\r
-       if( neg )\r
-               ret = -ret;     \r
-\r
-       if(end)\r
-               *end = (char*)str;\r
-       return ret;\r
-}\r
-\r
-EXPORT long strtol(const char *str, char **end, int base)\r
-{\r
-       long long tmp = strtoll(str, end, base);\r
-       if( tmp > LONG_MAX || tmp < LONG_MIN ) {\r
-               errno = ERANGE;\r
-               return (tmp > LONG_MAX) ? LONG_MAX : LONG_MIN;\r
-       }\r
-       return tmp;\r
-}\r
-\r
-/**\r
- * \fn EXPORT int atoi(const char *str)\r
- * \brief Convert a string to an integer\r
- */\r
-EXPORT int atoi(const char *str)\r
-{\r
-       long long       tmp = strtoll(str, NULL, 0);\r
-       if( tmp > INT_MAX || tmp < INT_MIN ) {\r
-               errno = ERANGE;\r
-               return (tmp > INT_MAX) ? INT_MAX : INT_MIN;\r
-       }\r
-       return tmp;\r
-}\r
 \r
 int abs(int j) { return j < 0 ? -j : j; }\r
 long int labs(long int j) { return j < 0 ? -j : j; }\r
index 3cadee9..d8d0872 100644 (file)
@@ -273,7 +273,7 @@ EXPORT void *memmove(void *dest, const void *src, size_t count)
        char *sp = (char *)src;
        char *dp = (char *)dest;
        // Check if the areas overlap
-       if( (intptr_t)src < (intptr_t)dest && (intptr_t)dest < (intptr_t)src+count )
+       if( (uintptr_t)src < (uintptr_t)dest && (uintptr_t)dest < (uintptr_t)src+count )
                for(;count--;)
                        dp[count] = sp[count];
        else
diff --git a/Usermode/Libraries/libc.so_src/strtoi.c b/Usermode/Libraries/libc.so_src/strtoi.c
new file mode 100644 (file)
index 0000000..9326fb8
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Acess2 C Library
+ * - By John Hodge (thePowersGang)
+ *
+ * strtoi.c
+ * - strto[u][l]l/atoi implimentation
+ */
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+
+unsigned long long strtoull(const char *str, char **end, int base)
+{
+       long long       ret = 0;
+       
+       if( !str || base < 0 || base > 36 || base == 1 ) {
+               if(end)
+                       *end = (char*)str;
+               errno = EINVAL;
+               return 0;
+       }
+
+       // Trim leading spaces
+       while( isspace(*str) )
+               str++;
+       
+       // Handle base detection for hex
+       if( base == 0 || base == 16 ) {
+               if( *str == '0' && str[1] == 'x' ) {
+                       str += 2;
+                       base = 16;
+               }
+       }
+       
+       // Handle base detection for octal
+       if( base == 0 && *str == '0' ) {
+               str ++;
+               base = 8;
+       }
+
+       // Fall back on decimal when unknown
+       if( base == 0 )
+               base = 10;
+
+       while( *str )
+       {
+                int    next = -1;
+               if( base <= 10 ) {
+                       if( '0' <= *str && *str <= '0'+base-1 )
+                               next = *str - '0';
+               }
+               else {
+                       if( '0' <= *str && *str <= '9' )
+                               next = *str - '0';
+                       if( 'A' <= *str && *str <= 'A'+base-10-1 )
+                               next = *str - 'A';
+                       if( 'a' <= *str && *str <= 'a'+base-10-1 )
+                               next = *str - 'a';
+               }
+               if( next < 0 )
+                       break;
+               ret *= base;
+               ret += next;
+               str ++;
+       }
+
+       if(end)
+               *end = (char*)str;
+       return ret;
+}
+
+unsigned long strtoul(const char *ptr, char **end, int base)
+{
+       unsigned long long tmp = strtoull(ptr, end, base);
+       
+       if( tmp > ULONG_MAX ) {
+               errno = ERANGE;
+               return ULONG_MAX;
+       }
+       
+       return tmp;
+}
+
+long long strtoll(const char *str, char **end, int base)
+{
+        int    neg = 0;
+       unsigned long long      ret;
+
+       if( !str ) {
+               errno = EINVAL;
+               return 0;
+       }
+       
+       while( isspace(*str) )
+               str++;
+       
+       // Check for negative (or positive) sign
+       if(*str == '-' || *str == '+') {
+               neg = (*str == '-');
+               str++;
+       }
+
+       ret = strtoull(str, end, base); 
+
+       if( neg )
+               return -ret;
+       else
+               return ret;
+}
+
+long strtol(const char *str, char **end, int base)
+{
+       long long tmp = strtoll(str, end, base);
+       if( tmp > LONG_MAX || tmp < LONG_MIN ) {
+               errno = ERANGE;
+               return (tmp > LONG_MAX) ? LONG_MAX : LONG_MIN;
+       }
+       return tmp;
+}
+
+/**
+ * \fn int atoi(const char *str)
+ * \brief Convert a string to an integer
+ */
+int atoi(const char *str)
+{
+       long long       tmp = strtoll(str, NULL, 0);
+       if( tmp > INT_MAX || tmp < INT_MIN ) {
+               errno = ERANGE;
+               return (tmp > INT_MAX) ? INT_MAX : INT_MIN;
+       }
+       return tmp;
+}
index 2494fc2..20e796e 100644 (file)
@@ -4,7 +4,7 @@
 #include "stdio_int.h"\r
 #include "lib.h"\r
 #include <stdio.h>\r
-#include <sys/sys.h>\r
+#include <acess/sys.h>\r
 \r
 #define USE_CPUID      0\r
 \r
@@ -44,7 +44,7 @@ tCPUID        gCPU_Features;
  * \param argv Unused - Arguments (NULL for current version of ld-acess)\r
  * \param envp Environment Pointer\r
  */\r
-int SoMain(unsigned int BaseAddress, int argc, char **argv, char **envp)\r
+int SoMain(UNUSED(uintptr_t, BaseAddress), UNUSED(int, argc), UNUSED(char **, argv), char **envp)\r
 {\r
        // Init for env.c\r
        _envp = envp;\r
index 2adaf1b..2b3ff76 100644 (file)
@@ -47,7 +47,7 @@ char *Net_GetInterface(int AddressType, void *Address)
                uint32_t        *type = (void*)buf;
                
                // Open
-               fd = open("/Devices/ip/routes", 0);
+               fd = _SysOpen("/Devices/ip/routes", 0);
                if( !fd ) {
                        fprintf(stderr, "ERROR: Unable to open '/Devices/ip/routes'\n");
                        return NULL;
@@ -56,10 +56,10 @@ char *Net_GetInterface(int AddressType, void *Address)
                // Make structure and ask
                *type = AddressType;
                memcpy(type+1, Address, size);
-               routeNum = ioctl(fd, ioctl(fd, 3, "locate_route"), buf);
+               routeNum = _SysIOCtl(fd, _SysIOCtl(fd, 3, "locate_route"), buf);
                
                // Close
-               close(fd);
+               _SysClose(fd);
        }
        
        // Check answer validity
@@ -71,24 +71,24 @@ char *Net_GetInterface(int AddressType, void *Address)
                sprintf(buf, "/Devices/ip/routes/#%i", routeNum);
                
                // Open route
-               fd = open(buf, 0);
+               fd = _SysOpen(buf, 0);
                if( fd == -1 ) {
                        fprintf(stderr, "Net_GetInterface - ERROR: Unable to open %s\n", buf);
                        return NULL;    // Shouldn't happen :/
                }
                
                // Allocate space for name
-               ret = malloc( ioctl(fd, ioctl(fd, 3, "get_interface"), NULL) + 1 );
+               ret = malloc( _SysIOCtl(fd, _SysIOCtl(fd, 3, "get_interface"), NULL) + 1 );
                if( !ret ) {
                        fprintf(stderr, "malloc() failure - Allocating space for interface name\n");
                        return NULL;
                }
                
                // Get name
-               ioctl(fd, ioctl(fd, 3, "get_interface"), ret);
+               _SysIOCtl(fd, _SysIOCtl(fd, 3, "get_interface"), ret);
                
                // Close and return
-               close(fd);
+               _SysClose(fd);
                
                return ret;
        }
index 0b54079..f5933f2 100644 (file)
@@ -26,14 +26,14 @@ int Net_OpenSocket(int AddrType, void *Addr, const char *Filename)
                char    path[len+1];
                snprintf(path, 100, "/Devices/ip/routes/@%i:%s/%s", AddrType, hexAddr, Filename);
                _SysDebug("%s", path);
-               return open(path, OPENFLAG_READ|OPENFLAG_WRITE);
+               return _SysOpen(path, OPENFLAG_READ|OPENFLAG_WRITE);
        }
        else
        {
                 int    len = snprintf(NULL, 100, "/Devices/ip/routes/@%i:%s", AddrType, hexAddr);
                char    path[len+1];
                snprintf(path, 100, "/Devices/ip/routes/@%i:%s", AddrType, hexAddr);
-               return open(path, OPENFLAG_READ);
+               return _SysOpen(path, OPENFLAG_READ);
        }
 }
 
@@ -42,9 +42,9 @@ int Net_OpenSocket_TCPC(int AddrType, void *Addr, int Port)
        int fd = Net_OpenSocket(AddrType, Addr, "tcpc");
        if( fd == -1 )  return -1;
        
-       ioctl(fd, 5, &Port);    // Remote Port
-        ioctl(fd, 6, Addr);    // Remote address
-       ioctl(fd, 7, NULL);     // connect
+       _SysIOCtl(fd, 5, &Port);        // Remote Port
+        _SysIOCtl(fd, 6, Addr);        // Remote address
+       _SysIOCtl(fd, 7, NULL); // connect
        return fd;
 }
 
diff --git a/Usermode/Libraries/libposix.so_src/Makefile b/Usermode/Libraries/libposix.so_src/Makefile
new file mode 100644 (file)
index 0000000..2f472fc
--- /dev/null
@@ -0,0 +1,16 @@
+# Acess2 POSIX Emulation\r
+# Makefile\r
+\r
+-include ../Makefile.cfg\r
+\r
+CPPFLAGS += \r
+CFLAGS   += -Werror -Wextra\r
+ASFLAGS  +=\r
+LDFLAGS  += -soname libposix.so -Map map.txt\r
+\r
+OBJ  = main.o unistd.o\r
+DEPFILES := $(OBJ:%.o=%.d)\r
+BIN = libposix.so\r
+\r
+include ../Makefile.tpl\r
+\r
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/dirent.h b/Usermode/Libraries/libposix.so_src/include_exp/dirent.h
new file mode 100644 (file)
index 0000000..4f2c0b3
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * dirent.h
+ * - Directory Reading
+ */
+#ifndef _LIBPOSIX__SYS__DIRENT_H_
+#define _LIBPOSIX__SYS__DIRENT_H_
+
+#define NAME_MAX       255
+
+struct dirent
+{
+       ino_t   d_ino;
+       char    d_name[NAME_MAX+1];
+};
+
+typedef struct DIR_s   DIR;
+
+extern int     closedir(DIR *);
+extern DIR     *opendir(const char *);
+extern struct dirent   *readdir(DIR *);
+extern int     readdir_r(DIR *, struct dirent *, struct dirent **);
+extern void    rewinddir(DIR *);
+extern void    seekdir(DIR *, long int);
+extern long int        telldir(DIR *);
+
+#endif
+
index 5fee9a1..ded9ba1 100644 (file)
 // Acess doesn't implement lseek
 #define lseek(_1,_2,_3)        (seek(_1,_2,_3),tell(_1))
 
+enum e_fcntl_cmds
+{
+       F_SETFL
+};
+
+int fcntl(int fd, int cmd, ...) { return -1; }
+
 #endif
 
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/grp.h b/Usermode/Libraries/libposix.so_src/include_exp/grp.h
new file mode 100644 (file)
index 0000000..b3d42bf
--- /dev/null
@@ -0,0 +1,7 @@
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * grp.h
+ * - Group Management
+ */
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/pwd.h b/Usermode/Libraries/libposix.so_src/include_exp/pwd.h
new file mode 100644 (file)
index 0000000..66b157f
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * pwd.h
+ * - Password Structure
+ */
+#ifndef _LIBPOSIX__PWD_H_
+#define _LIBPOSIX__PWD_H_
+
+#include <sys/types.h> // gid_t/uid_t
+
+struct passwd
+{
+       char    *pw_name;
+       uid_t   pw_uid;
+       gid_t   pw_gid;
+       char    *pw_dir;
+       char    *pw_shell;
+};
+
+extern struct passwd   *getpwnam(const char *);
+extern struct passwd   *getpwuid(uid_t);
+extern int     getpwnam_r(const char *, struct passwd *, char *, size_t, struct passwd **);
+extern int     getpwuid_r(uid_t, struct passwd *, char *, size_t, struct passwd **);
+extern void    endpwent(void);
+extern struct passwd   *getpwent(void);
+extern void    setpwent(void);
+
+#endif
+
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/sys/resource.h b/Usermode/Libraries/libposix.so_src/include_exp/sys/resource.h
new file mode 100644 (file)
index 0000000..90308f2
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * sys/resource.h
+ * - (XSI) Resource Operations
+ */
+#ifndef _LIBPOSIX__SYS__RESOURCE_H_
+#define _LIBPOSIX__SYS__RESOURCE_H_
+
+#include <sys/time.h>  // struct timeval
+
+// (get|set)priority(which)
+enum
+{
+       PRIO_PROCESS,
+       PRIO_PGRP,
+       PRIO_USER
+};
+
+typedef unsigned int   rlim_t;
+#define RLIM_INFINITY  -1
+#define RLIM_SAVED_MAX -2
+#define RLIM_SAVED_CUR -3
+
+struct rlimit
+{
+       rlim_t  rlim_cur;
+       rlim_t  rlim_max;
+};
+
+enum
+{
+       RLIMIT_AS,      // Address space size
+       RLIMIT_CORE,    // Max core file size
+       RLIMIT_CPU,     // CPU time limit in s (SIGXCPU when reached)
+       RLIMIT_DATA,
+       // TODO: More?
+};
+
+struct rusage
+{
+       struct timeval  ru_time;
+       struct timeval  ru_stime;
+};
+
+extern int     getpriority(int, id_t);
+extern int     getrlimit(int, struct rlimit *);
+extern int     getrusage(int, struct rusage *);
+extern int     setpriority(int, id_t, int);
+extern int     setrlimit(int, const struct rlimit *);
+
+#endif
+
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/sys/select.h b/Usermode/Libraries/libposix.so_src/include_exp/sys/select.h
new file mode 100644 (file)
index 0000000..c33ccb1
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Acess2 POSIX Emulation Layer
+ * - By John Hodge
+ * 
+ * sys/select.h
+ * - select(2)
+ */
+#ifndef _SYS__SELECT_H_
+#define _SYS__SELECT_H_
+
+#include <acess/fd_set.h>
+
+extern int select(int nfds, fd_set *readfds, fd_set *writefds, struct timeval *timeout);
+// TODO: pselect?
+
+#endif
+
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/sys/stat.h b/Usermode/Libraries/libposix.so_src/include_exp/sys/stat.h
new file mode 100644 (file)
index 0000000..99c526b
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Acess2 C Library
+ * - By John Hodge (thePowersGang)
+ */
+#ifndef _SYS_STAT_H_
+#define _SYS_STAT_H_
+
+//#include "../acess/intdefs.h"        /* Evil */
+//#include "../stddef.h"
+#include <stdint.h>
+#include "sys/types.h" // off_t
+
+typedef void   *dev_t; /* TODO: How to identify a device with Acess */
+typedef uint64_t       ino_t;
+typedef unsigned int   blksize_t;
+typedef uint64_t       blkcnt_t;
+typedef unsigned int   nlink_t;
+typedef uint32_t       mode_t;
+
+typedef uint32_t       uid_t;
+typedef uint32_t       gid_t;
+
+#define        S_IFMT          0170000 /* type of file */
+#define                S_IFDIR 0040000 /* directory */
+#define                S_IFCHR 0020000 /* character special */
+#define                S_IFBLK 0060000 /* block special */
+#define                S_IFREG 0100000 /* regular */
+#define                S_IFLNK 0120000 /* symbolic link */
+#define                S_IFSOCK        0140000 /* socket */
+#define                S_IFIFO 0010000 /* fifo */
+
+
+struct stat
+{
+       dev_t     st_dev;     /* ID of device containing file */
+       ino_t     st_ino;     /* inode number */
+       mode_t    st_mode;    /* protection */
+       nlink_t   st_nlink;   /* number of hard links */
+       uid_t     st_uid;     /* user ID of owner */
+       gid_t     st_gid;     /* group ID of owner */
+       dev_t     st_rdev;    /* device ID (if special file) */
+       off_t     st_size;    /* total size, in bytes */
+       blksize_t st_blksize; /* blocksize for file system I/O */
+       blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
+       time_t    st_atime;   /* time of last access */
+       time_t    st_mtime;   /* time of last modification */
+       time_t    st_ctime;   /* time of last status change */
+};
+
+extern int stat(const char *path, struct stat *buf);
+extern int fstat(int fd, struct stat *buf);
+
+#endif
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/sys/time.h b/Usermode/Libraries/libposix.so_src/include_exp/sys/time.h
new file mode 100644 (file)
index 0000000..5cd2876
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * sys/time.h
+ * - Timing calls
+ */
+#ifndef _LIBPOSIX__SYS__TIME_H_
+#define _LIBPOSIX__SYS__TIME_H_
+
+typedef unsigned long  suseconds_t;
+
+struct timeval
+{
+       time_t  tv_sec;
+       suseconds_t     tv_usec;
+};
+
+struct itimerval
+{
+       struct timeval  it_interval;
+       struct timeval  it_value;
+};
+
+// TODO: This should also define fd_set and select()
+
+extern int     getitimer(int, struct itimerval *);
+extern int     setitimer(int, const struct itimerval *, struct itimerval *);
+extern int     gettimeofday(struct timeval *, void *);
+// select
+extern int     utimes(const char *, const struct timeval [2]);
+
+#endif
+
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/sys/types.h b/Usermode/Libraries/libposix.so_src/include_exp/sys/types.h
new file mode 100644 (file)
index 0000000..db78b5a
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ */
+#ifndef _SYS_TYPES_H
+#define _SYS_TYPES_H
+
+#include <stdint.h>
+
+//typedef signed int   ssize_t;
+//#ifdef  __USE_BSD
+typedef unsigned int   u_int;
+//#endif
+
+typedef struct stat    t_fstat;
+
+
+#define CLONE_VM       0x10
+
+typedef unsigned int   id_t;
+typedef unsigned long  pid_t;
+typedef unsigned long  tid_t;
+typedef signed long long int   time_t;
+typedef long long int  off_t;
+
+typedef unsigned int   uint;
+
+#include "stat.h"
+#include <acess/fd_set.h>
+
+#endif
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/sys/wait.h b/Usermode/Libraries/libposix.so_src/include_exp/sys/wait.h
new file mode 100644 (file)
index 0000000..d37f5e5
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * sys/wait.h
+ * - Waiting
+ */
+#ifndef _LIBPOSIX__SYS__WAIT_H_
+#define _LIBPOSIX__SYS__WAIT_H_
+
+// POSIX, waitpid()
+#define        WNOHANG 0x01
+#define WUNTRACED      0x02
+
+// POSIX, status values
+#define WEXITSTATUS(v) v
+#define WIFCONTINUED(v)        0
+
+// POSIX/XSI, waitid(options)
+#define WEXITED        0x10
+#define WSTOPPED       0x20
+#define WCONTINUED     0x40
+#define WNOWAIT        0x80
+
+// POSIX/XSI, idtype_t
+typedef enum
+{
+       P_ALL,
+       P_PID,
+       P_PGID
+} idtype_t;
+
+// POSIX
+extern pid_t   wait(int *);
+// POSIX/XSI
+//extern int   waitid(idtype_t, id_t, siginfo_t *, int);
+// POSIX
+extern pid_t   waitpid(pid_t, int *, int);
+
+
+#endif
+
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/syslog.h b/Usermode/Libraries/libposix.so_src/include_exp/syslog.h
new file mode 100644 (file)
index 0000000..ae891b7
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * syslog.h
+ * - Centra Loggin
+ */
+#ifndef _LIBPOSIX__SYSLOG_H_
+#define _LIBPOSIX__SYSLOG_H_
+
+// openlog(logopt)
+#define LOG_PID        0x01
+#define LOG_CONS       0x02
+#define LOG_NDELAY     0x04
+#define LOG_ODELAY     0x08
+#define LOG_NOWAIT     0x10
+
+// openlog(facility)
+enum {
+       LOG_KERN,
+       LOG_USER,
+       LOG_MAIL,
+       LOG_NEWS,
+       LOG_UUCP,
+       LOG_DAEMON,
+       LOG_AUTH,
+       LOG_CRON,
+       LOG_LPR,
+       LOG_LOCAL0,
+       LOG_LOCAL1,
+       LOG_LOCAL2,
+       LOG_LOCAL3,
+       LOG_LOCAL4,
+       LOG_LOCAL5,
+       LOG_LOCAL6,
+       LOG_LOCAL7
+};
+
+// setlogmask(maskpri)
+#define LOG_MASK(pri)  pri
+
+// syslog(priority)
+enum {
+       LOG_EMERG,
+       LOG_ALERT,
+       LOG_CRIT,
+       LOG_ERR,
+       LOG_WARNING,
+       LOG_NOTICE,
+       LOG_INFO,
+       LOG_DEBUG
+};
+
+extern void    closelog(void);
+extern void    openlog(const char *, int, int);
+extern int     setlogmask(int);
+extern void    syslog(int, const char *, ...);
+
+#endif
+
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/termios.h b/Usermode/Libraries/libposix.so_src/include_exp/termios.h
new file mode 100644 (file)
index 0000000..e29ff4c
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * termios.h
+ * - Terminal Control
+ */
+#ifndef _LIBPOSIX__TERMIOS_H_
+#define _LIBPOSIX__TERMIOS_H_
+
+typedef unsigned char  cc_t;
+typedef unsigned long  speed_t;
+typedef unsigned short tcflag_t;
+
+enum {
+       VEOF,
+       VEOL,
+       VERASE,
+       VINTR,
+       VKILL,
+       VMIN,
+       VQUIT,
+       VSTART,
+       VSTOP,
+       VSUSP,
+       VTIME,
+       NCCS
+};
+
+struct termios
+{
+       tcflag_t        c_iflag;
+       tcflag_t        c_oflag;
+       tcflag_t        c_cflag;
+       tcflag_t        c_lflag;
+       cc_t    c_cc[NCCS];
+};
+
+#endif
+
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/unistd.h b/Usermode/Libraries/libposix.so_src/include_exp/unistd.h
new file mode 100644 (file)
index 0000000..a2f397c
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Acess2 POSIX Emulation Layer
+ * - By John Hodge
+ * 
+ * unistd.h
+ * - 
+ */
+#ifndef _UNISTD_H_
+#define _UNISTD_H_
+
+#include <stddef.h>
+
+//! \brief flags for open(2)
+#define O_WRONLY       0x01
+#define O_RDONLY       0x02
+#define        O_RDWR          0x03
+#define O_APPEND       0x04
+#define O_CREAT        0x08
+#define O_DIRECTORY    0x10
+#define O_ASYNC        0x20
+#define O_TRUNC        0x40
+#define O_NOFOLLOW     0x80    // don't follow symlinks
+#define        O_EXCL          0x100
+#define O_NOCTTY       0       // unsupported
+#define O_NONBLOCK     0x200
+#define        O_SYNC  0       // not supported
+
+#define STDIN_FILENO   0
+#define STDOUT_FILENO  1
+#define STDERR_FILENO  2
+
+typedef signed long    ssize_t;
+
+#include "sys/stat.h"  // mode_t
+
+extern int     open(const char *path, int flags, ...);
+extern int     creat(const char *path, mode_t mode);
+extern int     close(int fd);
+
+extern ssize_t write(int fd, const void *buf, size_t count);
+extern ssize_t read(int fd, void *buf, size_t count);
+
+extern int     fork(void);
+extern int     execv(const char *b, char *v[]);
+
+#endif
+
diff --git a/Usermode/Libraries/libposix.so_src/main.c b/Usermode/Libraries/libposix.so_src/main.c
new file mode 100644 (file)
index 0000000..72989a5
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Acess2 POSIX Emulation Layer
+ * - By John Hodge
+ * 
+ * main.c
+ * - Stub Main
+ */
+
+// === CODE ===
+int SoMain(void)
+{
+       return 0;
+}
+
diff --git a/Usermode/Libraries/libposix.so_src/unistd.c b/Usermode/Libraries/libposix.so_src/unistd.c
new file mode 100644 (file)
index 0000000..c1d4908
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Acess2 POSIX Emulation Layer
+ * - By John Hodge
+ * 
+ * unistd.c
+ * - POSIX->Acess VFS call translation
+ */
+#include <unistd.h>
+#include <acess/sys.h>
+#include <stdarg.h>
+
+// === CODE ===
+int open(const char *path, int openmode, ...)
+{
+       mode_t  create_mode = 0;
+       int openflags = 0;
+       
+       switch( openmode & O_RDWR )
+       {
+       case 0: // Special
+               break;
+       case O_RDONLY:  openflags |= OPENFLAG_READ;     break;
+       case O_WRONLY:  openflags |= OPENFLAG_WRITE;    break;
+       case O_RDWR:    openflags |= OPENFLAG_READ|OPENFLAG_WRITE;      break;
+       }
+       
+       if( openmode & O_CREAT ) {
+               openflags |= OPENFLAG_CREATE;
+               va_list args;
+               va_start(args, openmode);
+               create_mode = va_arg(args, mode_t);
+               va_end(args);
+       }
+       
+       return _SysOpen(path, openflags, create_mode);
+}
+
+int creat(const char *path, mode_t mode)
+{
+       // TODO: Make native call to do this cheaper
+       int fd = _SysOpen(path, OPENFLAG_CREATE, mode);
+       if( fd == -1 )  return -1;
+       _SysClose(fd);
+       return 0;
+}
+
+int close(int fd)
+{
+       _SysClose(fd);
+       return 0;
+}
+
+ssize_t        write(int fd, const void *buf, size_t count)
+{
+       return _SysWrite(fd, buf, count);
+}
+
+ssize_t        read(int fd, void *buf, size_t count)
+{
+       return _SysRead(fd, buf, count);
+}
+
+int fork(void)
+{
+       return _SysClone(CLONE_VM, 0);
+}
+
+int execv(const char *b, char *v[])
+{
+       return _SysExecVE(b, v, NULL);
+}
diff --git a/Usermode/Libraries/libpsocket.so_src/common.h b/Usermode/Libraries/libpsocket.so_src/common.h
new file mode 100644 (file)
index 0000000..27e88e4
--- /dev/null
@@ -0,0 +1,2 @@
+
+extern char *mkstr(const char *format, ...);
diff --git a/Usermode/Libraries/libpsocket.so_src/include_exp/arpa/inet.h b/Usermode/Libraries/libpsocket.so_src/include_exp/arpa/inet.h
new file mode 100644 (file)
index 0000000..effc288
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Acess2 POSIX Sockets Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * arpa/inet.h
+ * - 
+ */
+#ifndef _LIBPSOCKET__ARPA__INET_H_
+#define _LIBPSOCKET__ARPA__INET_H_
+
+#include <netinet/in.h>
+#include <stdint.h>    // Should be inttypes.h?
+
+extern uint32_t htonl(uint32_t hostlong);
+extern uint16_t htons(uint16_t hostshort);
+extern uint32_t ntohl(uint32_t netlong);
+extern uint16_t ntohs(uint16_t netshort);
+
+extern in_addr_t       inet_addr(const char *cp);
+extern in_addr_t       inet_lnaof(struct in_addr in);
+extern struct in_addr  inet_makeaddr(in_addr_t net, in_addr_t lna);
+extern in_addr_t       inet_netof(struct in_addr in);
+extern in_addr_t       inet_network(const char *cp);
+extern char    *inet_ntoa(struct in_addr in);
+
+#endif
+
index 4bde06d..33e7865 100644 (file)
@@ -3,9 +3,11 @@
 
 #include <stdint.h>
 
+typedef uint32_t       in_addr_t;
+
 struct in_addr
 {
-       unsigned long s_addr;
+       in_addr_t s_addr;
 };
 
 struct sockaddr_in
@@ -15,6 +17,17 @@ struct sockaddr_in
        struct in_addr  sin_addr;
 };
 
+#define INADDR_ANY     0x00000000
+#define INADDR_BROADCAST       0xFFFFFFFF
+
+// getsockopt/setsockopt(level)
+enum {
+       IPPROTO_IP = 1,
+       IPPROTO_ICMP,
+       IPPROTO_TCP,
+       IPPROTO_UDP
+};
+
 struct in6_addr
 {
        unsigned char   s6_addr[16];
diff --git a/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/tcp.h b/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/tcp.h
new file mode 100644 (file)
index 0000000..20cb4d3
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Acess2 POSIX Sockets Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * netinet/tcp.h
+ * - TCP Options
+ */
+#ifndef _NETINET__TCP_H_
+#define _NETINET__TCP_H_
+
+
+/**
+ * \brief Values for \a option_name in setsockopt/getsockopt
+ */
+enum eSockOpts_TCP
+{
+       TCP_NODELAY
+};
+
+#endif
+
index ecf5ce8..dc44ec6 100644 (file)
@@ -1,25 +1,27 @@
 /*
- * Acess2 C Library
+ * Acess2 POSIX Sockets Emulation
+ * - By John Hodge (thePowersGang)
  *
  * sys/sockets.h
  * - POSIX Sockets
- *
- * By John Hodge (thePowersGang)
  */
 #ifndef _SYS_SOCKETS_H_
 #define _SYS_SOCKETS_H_
 
 #include <sys/types.h>
+#include <stddef.h>    // size_t
 
-typedef int    socklen_t;
+typedef uint32_t       socklen_t;
 
 typedef enum
 {
        AF_UNSPEC       = 0,
        AF_PACKET       = 1,
+       AF_LOCAL        = 2,
        AF_INET         = 4,
        AF_INET6        = 6,
 } sa_family_t;
+#define AF_UNIX        AF_LOCAL
 
 struct sockaddr
 {
@@ -27,11 +29,51 @@ struct sockaddr
        char            sa_data[16];
 };
 
+struct msghdr
+{
+       void    *msg_name;
+       socklen_t       msg_namelen;
+       struct iovec    *msg_iov;
+       int     msg_iovlen;
+       void    *msg_control;
+       socklen_t       msg_controllen;
+       int     msg_flags;
+};
+
+struct cmsghdr
+{
+       socklen_t       cmsg_len;
+       int     cmsg_level;
+       int     cmsg_type;
+};
+
+#define SCM_RIGHTS     0x1
+
+#define CMSG_DATA(cmsg)        ((unsigned char*)(cmsg + 1))
+#define CMSG_NXTHDR(mhdr, cmsg)        0
+#define CMSG_FIRSTHDR(mhdr)    0
+
+struct linger
+{
+       int     l_onoff;
+       int     l_linger;
+};
+
+enum eSocketTypes
+{
+       SOCK_STREAM,    //!< Stream (TCP)
+       SOCK_DGRAM,     //!< Datagram (UDP)
+       SOCK_SEQPACKET, //!< 
+       SOCK_RAW,       //!< Raw packet access
+       SOCK_RDM        //!< Reliable non-ordered datagrams
+};
+
 /**
  * \brief Values for \a domain of socket()
  */
 enum eSocketDomains
 {
+       PF_UNSPEC,
        PF_LOCAL,       //!< Machine-local comms
        PF_INET,        //!< IPv4
        PF_INET6,       //!< IPv6
@@ -39,13 +81,18 @@ enum eSocketDomains
 };
 #define PF_UNIX        PF_LOCAL
 
-enum eSocketTypes
+// getsockopt/setsockopt level
+enum
 {
-       SOCK_STREAM,    //!< Stream (TCP)
-       SOCK_DGRAM,     //!< Datagram (UDP)
-       SOCK_SEQPACKET, //!< 
-       SOCK_RAW,       //!< Raw packet access
-       SOCK_RDM        //!< Reliable non-ordered datagrams
+       SOL_SOCKET
+};
+
+
+// SOL_SOCKET getsockopt/setsockopt names
+enum
+{
+       SO_REUSEADDR,
+       SO_LINGER
 };
 
 /**
@@ -79,5 +126,11 @@ extern int  recv(int sockfd, void *buffer, size_t length, int flags);
 extern int     sendto(int sockfd, const void *buffer, size_t length, int flags, const struct sockaddr *clientaddr, socklen_t addrlen);
 extern int     send(int sockfd, void *buffer, size_t length, int flags);
 
+extern int     setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len);
+extern int     getsockopt(int socket, int level, int option_name, void *option_value, socklen_t *option_len);
+
+extern int     getsockname(int socket, struct sockaddr *addr, socklen_t *addrlen);
+extern int     getpeername(int socket, struct sockaddr *addr, socklen_t *addrlen);
+
 #endif
 
diff --git a/Usermode/Libraries/libpsocket.so_src/include_exp/sys/un.h b/Usermode/Libraries/libpsocket.so_src/include_exp/sys/un.h
new file mode 100644 (file)
index 0000000..e932016
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Acess2 POSIX Sockets Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * sys/un.h
+ * - UNIX Domain Sockets
+ */
+#ifndef _LIBPSOCKET__SYS__UN_H_
+#define _LIBPSOCKET__SYS__UN_H_
+
+#define _SUN_PATH_MAX  108
+
+// POSIX Defined
+struct sockaddr_un
+{
+       sa_family_t     sun_family;
+       char    sun_path[_SUN_PATH_MAX];
+};
+
+#endif
+
index 99fbe2a..9c1e5a1 100644 (file)
@@ -8,6 +8,7 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <stdio.h>
+#include "common.h"
 
 int SoMain(void)
 {
index 913f72f..613e82b 100644 (file)
@@ -6,10 +6,11 @@
  * - sys/socket.h calls
  */
 #include <sys/socket.h>
-#include <unistd.h>
+#include <acess/sys.h>
 #include <stdlib.h>    // malloc/free
 #include <string.h>
 #include <netinet/in.h>
+#include "common.h"
 
 #define MAXFD  32
 
@@ -55,7 +56,7 @@ int socket(int domain, int type, int protocol)
        si = _GetInfo(0);
        if( !si )       return -1;
 
-       int fd = open("/Devices/null", O_RDWR);
+       int fd = _SysOpen("/Devices/null", OPENFLAG_RDWR);
        if( fd == -1 )  return -1;
 
        giNumPreinit ++;
@@ -167,7 +168,7 @@ void _CommitServer(int sockfd)
        else
                path = mkstr("/Devices/ip/*%i/%s", si->local->sa_family, file);
 
-       reopen(si->fd, path, O_RDWR);
+       _SysReopen(si->fd, path, OPENFLAG_RDWR);
        // TODO: Error-check
        
        free(path);
@@ -191,10 +192,11 @@ int accept(int sockfd, struct sockaddr *clientaddr, socklen_t addrlen)
         int    child;
 
 
-       child = _SysOpenChild(sockfd, "", O_RDWR);
+       child = _SysOpenChild(sockfd, "", OPENFLAG_RDWR);
        if( child == -1 )       return -1;
        
-       ioctl(child, 8, clientaddr);
+       _SysIOCtl(child, 8, clientaddr);
+
        
        return child;
 }
@@ -203,25 +205,25 @@ int recvfrom(int sockfd, void *buffer, size_t length, int flags, struct sockaddr
 {
        _CommitClient(sockfd);
        // TODO: Determine socket type (TCP/UDP) and use a bounce-buffer for UDP
-       return read(sockfd, buffer, length);
+       return _SysRead(sockfd, buffer, length);
 }
 
 int recv(int sockfd, void *buffer, size_t length, int flags)
 {
        _CommitClient(sockfd);
-       return read(sockfd, buffer, length);
+       return _SysRead(sockfd, buffer, length);
 }
 
 int sendto(int sockfd, const void *buffer, size_t length, int flags, const struct sockaddr *clientaddr, socklen_t addrlen)
 {
        _CommitClient(sockfd);
        // TODO: Determine socket type (TCP/UDP) and use a bounce-buffer for UDP
-       return write(sockfd, buffer, length);
+       return _SysWrite(sockfd, buffer, length);
 }
 
 int send(int sockfd, void *buffer, size_t length, int flags)
 {
        _CommitClient(sockfd);
-       return write(sockfd, buffer, length);
+       return _SysWrite(sockfd, buffer, length);
 }
 
index 719667d..58db03a 100644 (file)
@@ -80,7 +80,7 @@ char *Readline_NonBlock(tReadline *Info)
         int    len, i;
        
        // Read as much as possible (appending to remaining data)
-       len = read(STDIN_FD, Info->ReadBuffer, READ_BUFFER_SIZE - 1 - Info->ReadBufferLen);
+       len = _SysRead(STDIN_FD, Info->ReadBuffer, READ_BUFFER_SIZE - 1 - Info->ReadBufferLen);
        if( len <= 0 )  return NULL;
        Info->ReadBuffer[Info->ReadBufferLen + len] = '\0';
        
@@ -204,21 +204,21 @@ int Readline_int_ParseCharacter(tReadline *Info, char *Input)
                                        
                                        // Move to the beginning of the line
                                        pos = oldLen;
-                                       while(pos--)    write(STDOUT_FD, "\x1B[D", 3);
+                                       while(pos--)    _SysWrite(STDOUT_FD, "\x1B[D", 3);
                                        
                                        // Update state
                                        Info->CurBuffer = Info->History[--Info->HistoryPos];
                                        Info->BufferSize = Info->BufferUsed = strlen(Info->CurBuffer);
                                        
-                                       write(STDOUT_FD, Info->CurBuffer, Info->BufferUsed);
+                                       _SysWrite(STDOUT_FD, Info->CurBuffer, Info->BufferUsed);
                                        Info->BufferWritePos = Info->BufferUsed;
                                        
                                        // Clear old characters (if needed)
                                        if( oldLen > Info->BufferWritePos ) {
                                                pos = oldLen - Info->BufferWritePos;
-                                               while(pos--)    write(STDOUT_FD, " ", 1);
+                                               while(pos--)    _SysWrite(STDOUT_FD, " ", 1);
                                                pos = oldLen - Info->BufferWritePos;
-                                               while(pos--)    write(STDOUT_FD, "\x1B[D", 3);
+                                               while(pos--)    _SysWrite(STDOUT_FD, "\x1B[D", 3);
                                        }
                                }
                                break;
@@ -230,34 +230,34 @@ int Readline_int_ParseCharacter(tReadline *Info, char *Input)
                                        
                                        // Move to the beginning of the line
                                        pos = oldLen;
-                                       while(pos--)    write(STDOUT_FD, "\x1B[D", 3);
+                                       while(pos--)    _SysWrite(STDOUT_FD, "\x1B[D", 3);
                                        
                                        // Update state
                                        Info->CurBuffer = Info->History[Info->HistoryPos++];
                                        Info->BufferSize = Info->BufferUsed = strlen(Info->CurBuffer);
                                        
                                        // Write new line
-                                       write(STDOUT_FD, Info->CurBuffer, Info->BufferUsed);
+                                       _SysWrite(STDOUT_FD, Info->CurBuffer, Info->BufferUsed);
                                        Info->BufferWritePos = Info->BufferUsed;
                                        
                                        // Clear old characters (if needed)
                                        if( oldLen > Info->BufferWritePos ) {
                                                pos = oldLen - Info->BufferWritePos;
-                                               while(pos--)    write(STDOUT_FD, " ", 1);
+                                               while(pos--)    _SysWrite(STDOUT_FD, " ", 1);
                                                pos = oldLen - Info->BufferWritePos;
-                                               while(pos--)    write(STDOUT_FD, "\x1B[D", 3);
+                                               while(pos--)    _SysWrite(STDOUT_FD, "\x1B[D", 3);
                                        }
                                }
                                break;
                        case 'D':       // Left
                                if(Info->BufferWritePos == 0)   break;
                                Info->BufferWritePos --;
-                               write(STDOUT_FD, "\x1B[D", 3);
+                               _SysWrite(STDOUT_FD, "\x1B[D", 3);
                                break;
                        case 'C':       // Right
                                if(Info->BufferWritePos == Info->BufferUsed)    break;
                                Info->BufferWritePos ++;
-                               write(STDOUT_FD, "\x1B[C", 3);
+                               _SysWrite(STDOUT_FD, "\x1B[C", 3);
                                break;
                        }
                        break;
@@ -271,7 +271,7 @@ int Readline_int_ParseCharacter(tReadline *Info, char *Input)
        case '\b':
                if(Info->BufferWritePos <= 0)   break;  // Protect against underflows
                // Write the backsapce
-               write(STDOUT_FD, &ch, 1);
+               _SysWrite(STDOUT_FD, &ch, 1);
                if(Info->BufferWritePos == Info->BufferUsed)    // Simple case: End of string
                {
                        Info->BufferUsed --;
@@ -286,12 +286,12 @@ int Readline_int_ParseCharacter(tReadline *Info, char *Input)
                        buf[3] += (delta/10) % 10;
                        buf[4] += (delta) % 10;
                        // Write everything save for the deleted character
-                       write(STDOUT_FD,
+                       _SysWrite(STDOUT_FD,
                                &Info->CurBuffer[Info->BufferWritePos],
                                Info->BufferUsed - Info->BufferWritePos
                                );
-                       ch = ' ';       write(STDOUT_FD, &ch, 1);       ch = '\b';      // Clear old last character
-                       write(STDOUT_FD, buf, 7);       // Update Cursor
+                       ch = ' ';       _SysWrite(STDOUT_FD, &ch, 1);   ch = '\b';      // Clear old last character
+                       _SysWrite(STDOUT_FD, buf, 7);   // Update Cursor
                        // Alter Buffer
                        memmove(&Info->CurBuffer[Info->BufferWritePos-1],
                                &Info->CurBuffer[Info->BufferWritePos],
@@ -325,12 +325,12 @@ int Readline_int_ParseCharacter(tReadline *Info, char *Input)
                        buf[2] += (delta/100) % 10;
                        buf[3] += (delta/10) % 10;
                        buf[4] += (delta) % 10;
-                       write(STDOUT_FD, &ch, 1);       // Print new character
-                       write(STDOUT_FD,
+                       _SysWrite(STDOUT_FD, &ch, 1);   // Print new character
+                       _SysWrite(STDOUT_FD,
                                &Info->CurBuffer[Info->BufferWritePos],
                                Info->BufferUsed - Info->BufferWritePos
                                );
-                       write(STDOUT_FD, buf, 7);       // Update Cursor
+                       _SysWrite(STDOUT_FD, buf, 7);   // Update Cursor
                        // Move buffer right
                        memmove(
                                &Info->CurBuffer[Info->BufferWritePos+1],
@@ -340,7 +340,7 @@ int Readline_int_ParseCharacter(tReadline *Info, char *Input)
                }
                // Simple append
                else {
-                       write(STDOUT_FD, &ch, 1);
+                       _SysWrite(STDOUT_FD, &ch, 1);
                }
                Info->CurBuffer[ Info->BufferWritePos ++ ] = ch;
                Info->BufferUsed ++;
index bf88b98..e8f8dea 100644 (file)
@@ -32,7 +32,7 @@ void  URI_Close(tURIFile *File);
 size_t URI_file_Read(int Handle, size_t Bytes, void *Buffer);
 size_t URI_file_Write(int Handle, size_t Bytes, void *Buffer);
 void   URI_file_Close(int Handle);
-size_t URI_file_GetSize(int Handle);
+off_t  URI_file_GetSize(int Handle);
 
 // === CONSTANTS ===
 // Builtin URI protocol handlers
@@ -319,7 +319,7 @@ int URI_file_Open(char *Host, int Port, char *Path, int Mode)
 //     printf("URI_file_Open: open('%s', 0x%x)\n", Path, smode);
        {
                 int    ret;
-               ret = open(Path, smode);
+               ret = _SysOpen(Path, smode);
                return ret;
        }
 }
@@ -327,22 +327,22 @@ size_t URI_file_Read(int Handle, size_t Bytes, void *Buffer)
 {
 //     printf("URI_file_Read: (Handle=%i, Buffer=%p, Bytes=%i)\n",
 //             Handle, Buffer, (int)Bytes);
-       return read(Handle, Buffer, Bytes);
+       return _SysRead(Handle, Buffer, Bytes);
 }
 size_t URI_file_Write(int Handle, size_t Bytes, void *Buffer)
 {
-       return write(Handle, Buffer, Bytes);
+       return _SysWrite(Handle, Buffer, Bytes);
 }
 void URI_file_Close(int Handle)
 {
-       close(Handle);
+       _SysClose(Handle);
 }
-size_t URI_file_GetSize(int Handle)
+off_t URI_file_GetSize(int Handle)
 {
-       uint64_t curpos = tell(Handle);
-       size_t ret;
-       seek(Handle, 0, SEEK_END);
-       ret = tell(Handle);
-       seek(Handle, curpos, SEEK_SET);
+       uint64_t curpos = _SysTell(Handle);
+       off_t ret;
+       _SysSeek(Handle, 0, SEEK_END);
+       ret = _SysTell(Handle);
+       _SysSeek(Handle, curpos, SEEK_SET);
        return ret;
 }

UCC git Repository :: git.ucc.asn.au