Merge branch 'master' of git://localhost/acess2
authorJohn Hodge <[email protected]>
Tue, 14 Aug 2012 08:35:14 +0000 (16:35 +0800)
committerJohn Hodge <[email protected]>
Tue, 14 Aug 2012 08:35:14 +0000 (16:35 +0800)
Conflicts:
TODO.txt

153 files changed:
BuildConf/armv6/Makefile.cfg [new file with mode: 0644]
BuildConf/armv6/default.mk [new file with mode: 0644]
BuildConf/armv6/raspberrypi.mk [new file with mode: 0644]
BuildConf/armv7/Makefile.cfg
BuildConf/armv7/tegra2.mk
BuildConf/x86/default.mk
KernelLand/Kernel/Makefile
KernelLand/Kernel/arch/armv6/Makefile [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/debug.c [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/include/arch.h [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/include/assembly.h [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/include/lock.h [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/include/mm_virt.h [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/include/options.h [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/include/proc.h [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/lib.S [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/lib.c [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/link.ld [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/main.c [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/mm_phys.c [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/mm_virt.c [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/pci.c [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/proc.S [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/proc.c [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/start.S [new file with mode: 0644]
KernelLand/Kernel/arch/armv6/time.c [new file with mode: 0644]
KernelLand/Kernel/arch/x86/Makefile
KernelLand/Kernel/arch/x86/main.c
KernelLand/Kernel/arch/x86/mboot.c [new file with mode: 0644]
KernelLand/Kernel/arch/x86/mm_phys.c
KernelLand/Kernel/arch/x86_64/Makefile
KernelLand/Kernel/arch/x86_64/errors.c
KernelLand/Kernel/arch/x86_64/include/archinit.h [new file with mode: 0644]
KernelLand/Kernel/arch/x86_64/link.ld
KernelLand/Kernel/arch/x86_64/main.c
KernelLand/Kernel/arch/x86_64/mm_phys.c
KernelLand/Kernel/arch/x86_64/mm_virt.c
KernelLand/Kernel/arch/x86_64/proc.c
KernelLand/Kernel/arch/x86_64/start32.asm
KernelLand/Kernel/drv/pci.c
KernelLand/Kernel/drvutil_video.c
KernelLand/Kernel/heap.c
KernelLand/Kernel/include/bootmod.h [new file with mode: 0644]
KernelLand/Kernel/include/mboot.h
KernelLand/Kernel/include/tpl_mm_phys_bitmap.h
KernelLand/Kernel/logging.c
KernelLand/Kernel/threads.c
KernelLand/Kernel/vfs/io.c
KernelLand/Kernel/vfs/open.c
KernelLand/Kernel/vfs/select.c
KernelLand/Modules/Display/NVidia/main.c [new file with mode: 0644]
KernelLand/Modules/Display/NVidia/regs.c [new file with mode: 0644]
KernelLand/Modules/Display/NVidia/regs.h [new file with mode: 0644]
KernelLand/Modules/Display/Tegra2Vid/Registers.txt [new file with mode: 0644]
KernelLand/Modules/Display/Tegra2Vid/main.c
KernelLand/Modules/Display/Tegra2Vid/tegra2.h
KernelLand/Modules/Display/VIAVideo/main.c
KernelLand/Modules/Filesystems/InitRD/files.lst
KernelLand/Modules/Filesystems/RAMDisk/ramdisk.c
KernelLand/Modules/IPStack/adapters.c
KernelLand/Modules/Makefile.tpl
KernelLand/Modules/Storage/LVM/volumes.c
KernelLand/Modules/USB/Core/include/usb_core.h
KernelLand/Modules/USB/Core/include/usb_host.h
KernelLand/Modules/USB/Core/usb.c
KernelLand/Modules/USB/Core/usb.h
KernelLand/Modules/USB/Core/usb_devinit.c
KernelLand/Modules/USB/Core/usb_io.c
KernelLand/Modules/USB/Core/usb_lowlevel.c
KernelLand/Modules/USB/Core/usb_lowlevel.h
KernelLand/Modules/USB/Core/usb_poll.c
KernelLand/Modules/USB/EHCI/Makefile [new file with mode: 0644]
KernelLand/Modules/USB/EHCI/ehci.c [new file with mode: 0644]
KernelLand/Modules/USB/EHCI/ehci.h
KernelLand/Modules/USB/HID/main.c
KernelLand/Modules/USB/UHCI/uhci.c
KernelLand/Modules/USB/UHCI/uhci.h
Makefile
Makefile.cfg
Notes/SIF.txt [new file with mode: 0644]
RunQemu
TODO.txt
Tools/DiskTool/src/include/acess.h
Usermode/Applications/CLIShell_src/main.c
Usermode/Applications/Makefile.cfg
Usermode/Applications/Makefile.tpl
Usermode/Applications/axwin2_src/Makefile [deleted file]
Usermode/Applications/axwin2_src/SIF.txt [deleted file]
Usermode/Applications/axwin2_src/Shell_src/Makefile [deleted file]
Usermode/Applications/axwin2_src/Shell_src/main.c [deleted file]
Usermode/Applications/axwin2_src/WM/Makefile [deleted file]
Usermode/Applications/axwin2_src/WM/commandline.c [deleted file]
Usermode/Applications/axwin2_src/WM/common.h [deleted file]
Usermode/Applications/axwin2_src/WM/decorator.c [deleted file]
Usermode/Applications/axwin2_src/WM/font_8x16.h [deleted file]
Usermode/Applications/axwin2_src/WM/helpers.c [deleted file]
Usermode/Applications/axwin2_src/WM/image.c [deleted file]
Usermode/Applications/axwin2_src/WM/image.h [deleted file]
Usermode/Applications/axwin2_src/WM/input.c [deleted file]
Usermode/Applications/axwin2_src/WM/interface.c [deleted file]
Usermode/Applications/axwin2_src/WM/main.c [deleted file]
Usermode/Applications/axwin2_src/WM/messages.c [deleted file]
Usermode/Applications/axwin2_src/WM/render.c [deleted file]
Usermode/Applications/axwin2_src/WM/resources/LogoSmall.sif [deleted file]
Usermode/Applications/axwin2_src/WM/resources/cursor.h [deleted file]
Usermode/Applications/axwin2_src/WM/video.c [deleted file]
Usermode/Applications/axwin2_src/WM/video_text.c [deleted file]
Usermode/Applications/axwin2_src/WM/wm.c [deleted file]
Usermode/Applications/axwin2_src/WM/wm.h [deleted file]
Usermode/Applications/axwin2_src/notes.txt [deleted file]
Usermode/Applications/axwin3_src/Interface/main.c
Usermode/Applications/axwin3_src/Makefile
Usermode/Applications/axwin3_src/WM/include/wm_hotkeys.h
Usermode/Applications/axwin3_src/WM/ipc.c
Usermode/Applications/axwin3_src/WM/main.c
Usermode/Applications/axwin3_src/WM/renderers/widget.c
Usermode/Applications/axwin3_src/WM/wm_hotkeys.c
Usermode/Applications/axwin3_src/WM/wm_input.c
Usermode/Applications/axwin3_src/include/ipcmessages.h
Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c
Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c
Usermode/Applications/dhcpclient_src/main.c
Usermode/Applications/ip_src/addr.c
Usermode/Applications/ip_src/routes.c
Usermode/Applications/ls_src/main.c
Usermode/Applications/lspci_src/Makefile [new file with mode: 0644]
Usermode/Applications/lspci_src/main.c [new file with mode: 0644]
Usermode/Libraries/Makefile.tpl
Usermode/Libraries/acess.ld_src/acess_armv6.ld.h [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/Makefile
Usermode/Libraries/ld-acess.so_src/_stublib.c
Usermode/Libraries/ld-acess.so_src/arch/armv6.S.h [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/arch/armv6.ld [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/arch/syscalls.s.h
Usermode/Libraries/ld-acess.so_src/export.c
Usermode/Libraries/ld-acess.so_src/include_exp/acess/intdefs.h
Usermode/Libraries/ld-acess.so_src/include_exp/acess/sys.h
Usermode/Libraries/ld-acess.so_src/lib.c
Usermode/Libraries/libaxwin2.so_src/Makefile [deleted file]
Usermode/Libraries/libaxwin2.so_src/common.h [deleted file]
Usermode/Libraries/libaxwin2.so_src/include_exp/axwin2/axwin.h [deleted file]
Usermode/Libraries/libaxwin2.so_src/include_exp/axwin2/messages.h [deleted file]
Usermode/Libraries/libaxwin2.so_src/main.c [deleted file]
Usermode/Libraries/libaxwin2.so_src/messages.c [deleted file]
Usermode/Libraries/libaxwin2.so_src/windows.c [deleted file]
Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/axwin.h
Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/keysyms.h [new symlink]
Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/widget.h
Usermode/Libraries/libc.so_src/arch/armv6.S [new file with mode: 0644]
Usermode/Libraries/libc.so_src/heap.c
Usermode/Libraries/libc.so_src/include_exp/stdlib.h
Usermode/Libraries/libc.so_src/stdlib.c
Usermode/Libraries/libc.so_src/string.c

diff --git a/BuildConf/armv6/Makefile.cfg b/BuildConf/armv6/Makefile.cfg
new file mode 100644 (file)
index 0000000..00ed889
--- /dev/null
@@ -0,0 +1,18 @@
+
+ARM_CPUNAME = gerneric-armv6
+CC = arm-armv6-eabi-gcc -mcpu=$(ARM_CPUNAME)
+AS = arm-armv6-eabi-gcc -mcpu=$(ARM_CPUNAME) -c
+LD = arm-armv6-eabi-ld
+OBJDUMP = arm-armv6-eabi-objdump
+DISASM = $(OBJDUMP) -d -S
+ARCHDIR = armv6
+STRIP = arm-elf-strip
+
+ASSUFFIX = S
+
+# Default Configuration
+ifeq ($(PLATFORM),)
+       PLATFORM=raspberrypi
+$(warning Defaulting to "PLATFORM=$(PLATFORM)")
+endif
+
diff --git a/BuildConf/armv6/default.mk b/BuildConf/armv6/default.mk
new file mode 100644 (file)
index 0000000..3b3cc8b
--- /dev/null
@@ -0,0 +1,7 @@
+
+ifeq ($(PLATFORM),default)
+       $(error Please select a platform)
+endif
+
+#MODULES += armv7/GIC
+MODULES += Filesystems/InitRD
diff --git a/BuildConf/armv6/raspberrypi.mk b/BuildConf/armv6/raspberrypi.mk
new file mode 100644 (file)
index 0000000..01f08df
--- /dev/null
@@ -0,0 +1,3 @@
+
+include $(ACESSDIR)/BuildConf/armv6/default.mk
+ARM_CPUNAME = arm1176jzf-s
index 4114eb0..167e022 100644 (file)
@@ -1,7 +1,7 @@
 
 ARM_CPUNAME = gerneric-armv7
 CC = arm-elf-gcc -mcpu=$(ARM_CPUNAME)
-AS = arm-elf-gcc -c
+AS = arm-elf-gcc -mcpu=$(ARM_CPUNAME) -c
 LD = arm-elf-ld
 OBJDUMP = arm-elf-objdump
 DISASM = $(OBJDUMP) -d -S
index 1bac800..24eddf5 100644 (file)
@@ -3,3 +3,4 @@ include $(ACESSDIR)/BuildConf/armv7/default.mk
 
 ARM_CPUNAME = cortex-a9
 MODULES += Display/Tegra2Vid
+MODULES += USB/Core USB/EHCI
index 759953c..5d153f5 100644 (file)
@@ -10,7 +10,7 @@ MODULES += Display/BochsGA
 MODULES += Input/PS2KbMouse
 MODULES += x86/ISADMA x86/VGAText
 
-MODULES += USB/Core USB/UHCI
+MODULES += USB/Core USB/UHCI USB/EHCI
 #USB/OHCI
 MODULES += USB/HID USB/MSC
 #MODULES += Interfaces/UDI
index 40fb4a1..66eb9cd 100644 (file)
@@ -100,12 +100,12 @@ apidoc:
 # - Does whatever architecture defined rules
 $(BIN): $(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) --defsym __buildnum=$$(( $(BUILD_NUM) + 1 )) -Map ../Map.$(ARCH).txt
+       @$(LD) $(LDFLAGS) -o $(BIN) $(OBJ) $(MODS) $(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)_
        @gzip -c $(BIN)_ > $(GZBIN)
        @$(RM) $(BIN)_
 
diff --git a/KernelLand/Kernel/arch/armv6/Makefile b/KernelLand/Kernel/arch/armv6/Makefile
new file mode 100644 (file)
index 0000000..b6768e3
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# Acess2 Kernel
+# arm7 Architecture Makefile
+# arch/arm7/Makefile
+
+CPPFLAGS       =
+CFLAGS         =
+ASFLAGS                =
+
+CPPFLAGS += -DMMU_PRESENT=1
+LDFLAGS += 
+LIBGCC_PATH = $(shell $(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
+
+#main.c: Makefile.BuildNum.$(ARCH)
+
+ifeq ($(PLATFORM),tegra2)
+       POSTBUILD = arm-elf-objcopy $(BIN) -O binary $(BIN)
+endif
diff --git a/KernelLand/Kernel/arch/armv6/debug.c b/KernelLand/Kernel/arch/armv6/debug.c
new file mode 100644 (file)
index 0000000..7b9e55d
--- /dev/null
@@ -0,0 +1,57 @@
+/**
+ * Acess2
+ * - By John Hodge (thePowersGang)
+ *
+ * arch/arm7/debug.c
+ * - ARM7 Debug output
+ * NOTE: Currently designed for the realview-pb-a8 emulated by Qemu
+ */
+#include <acess.h>
+
+// === CONSTANTS ===
+//#define UART0_BASE   0x10009000
+#define UART0_BASE     0xF1000000      // Boot time mapped
+
+// === PROTOTYPES ===
+void   KernelPanic_SetMode(void);
+void   KernelPanic_PutChar(char Ch);
+void   StartupPrint(const char *str);
+
+// === GLOBALS ===
+ int   giDebug_SerialInitialised = 0;
+
+// === CODE ===
+void Debug_PutCharDebug(char ch)
+{
+       if(ch == '\n')
+               Debug_PutCharDebug('\r');
+
+       #if PLATFORM_is_tegra2
+       // Tegra2
+       while( !(*(volatile Uint32*)(UART0_BASE + 0x14) & (1 << 5)) )
+               ;
+       #endif
+       
+//     *(volatile Uint32*)(SERIAL_BASE + SERIAL_REG_DATA) = ch;
+       *(volatile Uint32*)(UART0_BASE) = ch;
+}
+
+void Debug_PutStringDebug(const char *str)
+{
+       for( ; *str; str++ )
+               Debug_PutCharDebug( *str );
+}
+
+void KernelPanic_SetMode(void)
+{
+}
+
+void KernelPanic_PutChar(char ch)
+{
+//     Debug_PutCharDebug(ch);
+}
+
+void StartupPrint(const char *str)
+{
+}
+
diff --git a/KernelLand/Kernel/arch/armv6/include/arch.h b/KernelLand/Kernel/arch/armv6/include/arch.h
new file mode 100644 (file)
index 0000000..837a5e1
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Acess2
+ * ARM7 Architecture Header
+ */
+#ifndef _ARCH_H_
+#define _ARCH_H_
+
+// === CONSTANTS ===
+#define INVLPTR        ((void*)-1)
+#define BITS   32
+#define PAGE_SIZE      0x1000
+#define KERNEL_BASE    0x80000000      // 2GiB
+
+// === TYPES ===
+typedef unsigned int   Uint;
+typedef unsigned char  Uint8;
+typedef unsigned short Uint16;
+typedef unsigned long  Uint32;
+typedef unsigned long long     Uint64;
+typedef signed int     Sint;
+typedef signed char    Sint8;
+typedef signed short   Sint16;
+typedef signed long    Sint32;
+typedef signed long long       Sint64;
+
+typedef int    size_t;
+typedef char   BOOL;
+
+typedef Uint32 tVAddr;
+typedef Uint32 tPAddr;
+
+#include "lock.h"
+
+// --- Debug
+extern void    Debug_PutCharDebug(char Ch);
+extern void    Debug_PutStringDebug(const char *String);
+
+// This should be elsewhere, but CBF
+extern void    MM_SetupPhys(void);
+extern int     MM_InitialiseVirtual(void);
+
+#define NO_IO_BUS      1
+
+#endif
diff --git a/KernelLand/Kernel/arch/armv6/include/assembly.h b/KernelLand/Kernel/arch/armv6/include/assembly.h
new file mode 100644 (file)
index 0000000..0c5c57f
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Acess2 ARMv7
+ * - By John Hodge (thePowersGang)
+ *
+ * arch/arm7/include/assembly.h
+ * - Assembly specific macros
+ */
+#ifndef _ASSEMBLY_H_
+#define _ASSEMBLY_H_
+
+#define PUSH_GPRS \
+       str r0, [sp,#-1*4];\
+       str r1, [sp,#-2*4];\
+       str r2, [sp,#-3*4];\
+       str r3, [sp,#-4*4];\
+       str r4, [sp,#-5*4];\
+       str r5, [sp,#-6*4];\
+       str r6, [sp,#-7*4];\
+       str r7, [sp,#-8*4];\
+       str r8, [sp,#-9*4];\
+       str r9, [sp,#-10*4];\
+       str r10, [sp,#-11*4];\
+       str r11, [sp,#-12*4];\
+       str r12, [sp,#-13*4];\
+       str sp, [sp,#-14*4];\
+       str lr, [sp,#-15*4];\
+       sub sp, #16*4
+
+#define POP_GPRS add sp, #16*4; \
+       ldr r0, [sp,#-1*4]; \
+       ldr r1, [sp,#-2*4]; \
+       ldr r2, [sp,#-3*4]; \
+       ldr r3, [sp,#-4*4]; \
+       ldr r4, [sp,#-5*4]; \
+       ldr r5, [sp,#-6*4]; \
+       ldr r6, [sp,#-7*4]; \
+       ldr r7, [sp,#-8*4]; \
+       ldr r8, [sp,#-9*4]; \
+       ldr r9, [sp,#-10*4]; \
+       ldr r10, [sp,#-11*4]; \
+       ldr r11, [sp,#-12*4]; \
+       ldr r12, [sp,#-13*4]; \
+       ldr lr, [sp,#-15*4];
+
+#endif
+
diff --git a/KernelLand/Kernel/arch/armv6/include/lock.h b/KernelLand/Kernel/arch/armv6/include/lock.h
new file mode 100644 (file)
index 0000000..6688af4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Acess2
+ * ARM7 Architecture
+ *
+ * lock.h - Hardware level spinlocks
+ */
+#ifndef _LOCK_H_
+#define _LOCK_H_
+
+// === CODE ===
+struct sShortSpinlock {
+        int    Lock;
+};
+
+// --- Spinlocks ---
+static inline int IS_LOCKED(struct sShortSpinlock *Lock)
+{
+       return !!Lock->Lock;
+}
+
+static inline int CPU_HAS_LOCK(struct sShortSpinlock *Lock)
+{
+       // TODO: Handle multiple CPUs
+       return !!Lock->Lock;
+}
+
+static inline int SHORTLOCK(struct sShortSpinlock *Lock)
+{
+       #if 0
+       // Coped from linux, yes, but I know what it does now :)
+       Uint    tmp;
+       __asm__ __volatile__ (
+       "1:     ldrex   %0, [%1]\n"     // Exclusive LOAD
+       "       teq     %0, #0\n"       // Check if zero
+       "       strexeq %0, %2, [%1]\n" // Set to one if it is zero (releasing lock on the memory)
+       "       teqeq   %0, #0\n"       // If the lock was avaliable, check if the write succeeded
+       "       bne     1b"     // If the lock was unavaliable, or the write failed, loop
+               : "=&r" (tmp)   // Temp
+               : "r" (&Lock->Lock), "r" (1)
+               : "cc"  // Condition codes clobbered
+               );
+       #elif 1
+       while( *(volatile int*)&Lock->Lock )    ;
+       Lock->Lock = 1;
+       #else
+        int    v = 1;
+       while( v )
+               __asm__ __volatile__ (
+                       "swp %0, %0, [%1]"
+                       : "=r" (v) : "r" (&Lock->Lock)
+                       : "cc"
+                       );
+       #endif
+       return 1;
+}
+
+static inline void SHORTREL(struct sShortSpinlock *Lock)
+{
+       Lock->Lock = 0;
+}
+
+#endif
+
diff --git a/KernelLand/Kernel/arch/armv6/include/mm_virt.h b/KernelLand/Kernel/arch/armv6/include/mm_virt.h
new file mode 100644 (file)
index 0000000..c1f10de
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Acess2
+ * ARM7 Virtual Memory Manager Header
+ */
+#ifndef _MM_VIRT_H_
+#define _MM_VIRT_H_
+
+#include "options.h"
+
+#define USER_STACK_COMM    0x04000     // Pages to allocate up front
+#define USER_STACK_SIZE           0x10000      // Stack space
+#define USER_STACK_TOP 0x78000000
+
+#define MM_USER_MIN    0x00001000
+#define USER_LIB_MAX   0x70000000
+#define MM_PPD_HANDLES 0x7F800000
+#define MM_TABLE1USER  0x7FC00000      // 2 GiB - 4 MiB
+#define MM_TABLE0USER  0x7FE00000      // 2 GiB - 2 MiB
+#define MM_KSTACK_BASE 0x7FE00000
+#define MM_KSTACK_END  0x80000000
+
+// Page Blocks are 12-bits wide (12 address bits used)
+// Hence, the table is 16KiB large (and must be so aligned)
+// and each block addresses 1MiB of data
+
+// First level table is aligned to 16KiB (restriction of TTBR reg)
+// - VMSAv6 uses two TTBR regs, determined by bit 31
+
+//#define KERNEL_BASE  0x80000000      // 2GiB
+
+#define MM_KHEAP_BASE  0x80800000      // 8MiB of kernel code
+#define MM_KHEAP_MAX   0xC0000000      // ~1GiB of kernel heap
+
+#define MM_MODULE_MIN  0xC0000000      // - 0xD0000000
+#define MM_MODULE_MAX  0xCF000000
+
+#define MM_GLOBALSTACKS        0xCF000000      // Global stacks
+#define MM_GLOBALSTACKS_END    0xD0000000
+
+// PMM Data, giving it 256MiB is overkill, but it's unused atm
+#define MM_MAXPHYSPAGE (1024*1024)
+// 2^(32-12) max pages
+// 8.125 bytes per page (for bitmap allocation)
+// = 8.125 MiB
+#define MM_PMM_BASE    0xE0000000
+#define MM_PMM_END     0xF0000000
+
+#define MM_HWMAP_BASE  0xF0000000      // Ent 0xF00
+#define MM_HWMAP_END   0xFE000000
+#define MM_TMPMAP_BASE 0xFE000000
+#define MM_TMPMAP_END  0xFF000000
+
+#define MM_KERNEL_VFS  0xFF000000      // 
+#define MM_TABLE1KERN  0xFF800000      // - 0x???????? 4MiB
+//#define MM_TABLE0KERN        0xFFC00000      // - 0xFFE04000 16KiB
+
+#endif
diff --git a/KernelLand/Kernel/arch/armv6/include/options.h b/KernelLand/Kernel/arch/armv6/include/options.h
new file mode 100644 (file)
index 0000000..4947158
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Acess2 ARMv6 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * options.h
+ * - C/ASM Shared constants
+ */
+#ifndef _ARMV7_OPTIONS_H_
+#define _ARMV7_OPTIONS_H_
+
+#define KERNEL_BASE    0x80000000
+
+#if PLATFORM_is_raspberrypi
+# define UART0_PADDR   0x7E215040      // Realview
+#else
+# error Unknown platform
+#endif
+
+#define MM_KSTACK_SIZE 0x2000  // 2 Pages
+
+#endif
+
diff --git a/KernelLand/Kernel/arch/armv6/include/proc.h b/KernelLand/Kernel/arch/armv6/include/proc.h
new file mode 100644 (file)
index 0000000..d6ef3d5
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Acess2
+ * ARM7 Architecture
+ *
+ * proc.h - Arch-Dependent Process Management
+ */
+#ifndef _PROC_H_
+#define _PROC_H_
+
+#define MAX_CPUS       4
+#define USER_MAX       0x80000000
+
+// === STRUCTURES ===
+typedef struct {
+       Uint32  IP, SP;
+       Uint32  UserIP, UserSP;
+} tTaskState;
+
+typedef struct {
+       Uint32  Base;
+} tMemoryState;
+
+typedef struct {
+       union {
+               Uint32  Num;
+               Uint32  Error;
+       };
+       union {
+               Uint32  Arg1;
+               Uint32  Return;
+       };
+       union {
+               Uint32  Arg2;
+               Uint32  RetHi;
+       };
+       Uint32  Arg3;
+       Uint32  Arg4;
+       Uint32  Arg5;
+       Uint32  Arg6;   // R6
+} tSyscallRegs;
+
+// === MACROS ===
+#define HALT() do{}while(0)
+
+// === PROTOTYPES ===
+
+#endif
+
diff --git a/KernelLand/Kernel/arch/armv6/lib.S b/KernelLand/Kernel/arch/armv6/lib.S
new file mode 100644 (file)
index 0000000..e2f0613
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Acess2 ARM
+ * - By John Hodge (thePowersGang)
+ *
+ * arch/arm7/lib.S
+ * - Assembly editions of library functions
+ */
+#include "include/assembly.h"
+
+.globl __memcpy_byte
+__memcpy_byte:
+1:
+       tst r2, r2      @ Check counter
+       moveq pc, lr    @ Return if zero
+       ldrb r3, [r1],#1        @ Read
+       strb r3, [r0],#1        @ Write
+       sub r2, #1
+       b 1b
+
+@ 
+@ Pre-aligned memcpy (32-bit blocks)
+@ 
+.globl __memcpy_align4
+__memcpy_align4:
+       push {r4}
+       mvn r3, #3      @ Mask for checking length
+       
+       @ 4 byte chunk copies
+1:     tst r2, r3
+       ldrne r4, [r1],#4
+       strne r4, [r0],#4
+       subne r2, #4
+       bne 1b
+
+       @ single byte copies to finish off
+2:     tst r2, #3
+       beq 3f
+       ldrb r4, [r1],#1
+       strb r4, [r0],#1
+       sub r2, #1
+       b 2b
+
+3:     pop {r4}
+       mov pc, lr
+
+@
+@ Division
+@
+.globl __divmod32_asm
+__divmod32_asm:
+       push {r4}
+       mov r4, #0      @ Return value
+       mov r3, #1      @ add value
+
+       @ Scan up for first larger multiple of 2
+1:     cmp r0, r1      @ N < D
+       bmi 2f          @ ^^
+       lsl r1, r1, #1  @ D <<= 1
+       lsls r3, r3, #1 @ add <<= 1
+       beq .err        @ result is zero
+       b 1b
+       
+       @ Go back down
+2:     lsrs r3, r3, #1 @ add >>= 1
+       beq 3f          @ Done (value is zero)
+       lsr r1, r1, #1  @ D >>= 1
+       cmp r0, r1      @ N < D
+       bmi 2b
+       sub r0, r1      @ N -= D
+       add r4, r3      @ ret += add
+       b 2b
+3:
+       tst r2, r2      @ Remainder (if wanted)
+       strne r0,[r2]
+       mov r0, r4      @ Return value
+       pop {r4}
+       mov pc, lr
+.err:
+       mov r0, #0
+       tst r2, r2
+       strne r0, [r2]
+       pop {r4}
+       mov pc, lr
+
diff --git a/KernelLand/Kernel/arch/armv6/lib.c b/KernelLand/Kernel/arch/armv6/lib.c
new file mode 100644 (file)
index 0000000..7894e3a
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Acess2 ARM7 Port
+ *
+ * lib.c - Library Functions
+ */
+#include <acess.h>
+#include "../helpers.h"
+
+// === IMPORTS ===
+extern void    __memcpy_align4(void *_dest, const void *_src, size_t _length);
+extern void    __memcpy_byte(void *_dest, const void *_src, size_t _length);
+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
+
+// === CODE ===
+void *memcpy(void *_dest, const void *_src, size_t _length)
+{
+       Uint8   *dst8 = _dest;
+       const Uint8     *src8 = _src;
+
+       if( ((tVAddr)_dest & 3) == 0 && ((tVAddr)_src & 3) == 0 )
+       {
+               __memcpy_align4(_dest, _src, _length);
+               return _dest;
+       }
+
+       // Handle small copies / Non-aligned
+       if( _length < 4 || ((tVAddr)_dest & 3) != ((tVAddr)_src & 3) )
+       {
+               __memcpy_byte(_dest, _src, _length);
+               return _dest;
+       }
+
+       // Force alignment
+       while( (tVAddr)dst8 & 3 ) *dst8 ++ = *src8++, _length --;
+
+       __memcpy_align4(dst8, src8, _length);
+       
+       return _dest;
+}
+
+int memcmp(const void *_m1, const void *_m2, size_t _length)
+{
+       const Uint32    *m1, *m2;
+       const Uint8     *m1_8 = _m1, *m2_8 = _m2;
+
+       // Handle small copies / Non-aligned
+       if( _length < 4 || ((tVAddr)_m1 & 3) != ((tVAddr)_m1 & 3) )
+       {
+               for( ; _length--; m1_8++,m2_8++ ) {
+                       if(*m1_8 != *m2_8)      return *m1_8 - *m2_8;
+               }
+               return 0;
+       }
+
+       // Force alignment
+       for( ; (tVAddr)m1_8 & 3; m1_8 ++, m2_8 ++) {
+               if(*m1_8 != *m2_8)      return *m1_8 - *m2_8;
+       }
+       m1 = (void *)m1_8;      m2 = (void *)m2_8;
+
+       // DWORD copies
+       for( ; _length > 3; _length -= 4, m1++, m2++)
+               if(*m1 != *m2)  return *m1 - *m2;
+
+       // Trailing bytes
+       m1_8 = (void*)m1;       m2_8 = (void*)m2;
+       for( ; _length; _length --, m1_8++, m2_8++ )
+               if(*m1_8 != *m2_8)      return *m1_8 - *m2_8;
+       
+       return 0;
+}
+
+void *memset(void *_dest, int _value, size_t _length)
+{
+       Uint32  *dst, val32;
+       Uint8   *dst8 = _dest;
+
+       _value = (Uint8)_value;
+
+       // Handle small copies
+       if( _length < 4 )
+       {
+               for( ; _length--; dst8++ )
+                       *dst8 = _value;
+               return _dest;
+       }
+
+       val32 = _value;
+       val32 |= val32 << 8;
+       val32 |= val32 << 16;
+       
+       // Force alignment
+       while( (tVAddr)dst8 & 3 ) *dst8 ++ = _value;
+       dst = (void *)dst8;
+
+       // DWORD copies
+       for( ; _length > 3; _length -= 4)
+               *dst++ = val32;
+
+       // Trailing bytes
+       dst8 = (void*)dst;
+       for( ; _length; _length -- )
+               *dst8 ++ = _value;
+       
+       return _dest;
+}
+
+DEF_DIVMOD(64)
+DEF_DIVMOD(32)
+
+Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
+{
+       Uint64  ret;
+       if(Den == 0)    return 0;       // TODO: #div0
+       if(Num < Den) {
+               if(Rem) *Rem = Num;
+               return 0;
+       }
+       if(Num == 0) {
+               if(Rem) *Rem = 0;
+               return 0;
+       }
+       if(Den == 1) {
+               if(Rem) *Rem = 0;
+               return Num;
+       }
+       if(Den == 2) {
+               if(Rem) *Rem = Num & 1;
+               return Num >> 1;
+       }
+       if(Den == 16) {
+               if(Rem) *Rem = Num & 0xF;
+               return Num >> 4;
+       }
+       if(Den == 32) {
+               if(Rem) *Rem = Num & 0x1F;
+               return Num >> 5;
+       }
+       if(Den == 0x1000) {
+               if(Rem) *Rem = Num & 0xFFF;
+               return Num >> 12;
+       }
+       
+       if( !(Den >> 32) && !(Num >> 32) ) {
+               if(Rem) *Rem = 0;       // Clear high bits
+               return __divmod32_asm(Num, Den, (Uint32*)Rem);
+       }
+
+       ret = __divmod64(Num, Den, Rem);
+       return ret;
+}
+
+#if 0
+// Unsigned Divide 64-bit Integer
+Uint64 __udivdi3(Uint64 Num, Uint64 Den)
+{
+       return DivMod64U(Num, Den, NULL);
+}
+
+// Unsigned Modulus 64-bit Integer
+Uint64 __umoddi3(Uint64 Num, Uint64 Den)
+{
+       Uint64  ret = 0;
+       DivMod64U(Num, Den, &ret);
+       return ret;
+}
+
+Uint32 __udivsi3(Uint32 Num, Uint32 Den)
+{
+       return __divmod32_asm(Num, Den, NULL);
+}
+
+Uint32 __umodsi3(Uint32 Num, Uint32 Den)
+{
+       Uint32  rem;
+       __divmod32_asm(Num, Den, &rem);
+       return rem;
+}
+#endif
+
+static inline Sint32 DivMod32S(Sint32 Num, Sint32 Den, Sint32 *Rem)
+{
+       Sint32  ret = 1;
+       if( Num < 0 ) {
+               ret = -ret;
+               Num = -Num;
+       }
+       if( Den < 0 ) {
+               ret = -ret;
+               Den = -Den;
+       }
+       if(ret < 0)
+               ret = -__divmod32(Num, Den, (Uint32*)Rem);
+       else
+               ret = __divmod32(Num, Den, (Uint32*)Rem);
+       return ret;
+}
+
+#if 0
+Sint32 __divsi3(Sint32 Num, Sint32 Den)
+{
+       return DivMod32S(Num, Den, NULL);
+}
+
+Sint32 __modsi3(Sint32 Num, Sint32 Den)
+{
+       Sint32  rem;
+       DivMod32S(Num, Den, &rem);
+       return rem;
+}
+#endif
+
diff --git a/KernelLand/Kernel/arch/armv6/link.ld b/KernelLand/Kernel/arch/armv6/link.ld
new file mode 100644 (file)
index 0000000..2ad5afe
--- /dev/null
@@ -0,0 +1,59 @@
+ENTRY (_start)
+
+_kernel_base = 0x80000000;
+_usertext_vbase = 0xFFFFE000;
+
+SECTIONS
+{
+       . = 0;
+       .init :
+       {
+               *(.init)
+       }
+       . += _kernel_base;
+       .text : AT( ADDR(.text) - _kernel_base )
+       {
+               *(.text*)
+               *(.rodata*)
+       }
+       __exidx_start = .;
+       .ARM.exidx   : { *(.ARM.exidx*) }
+       __exidx_end = .;
+       .ARM.extab : { *(.ARM.extab*) }
+                       
+
+       /* HACKS: User accesible .text section */
+       . = ALIGN(0x1000);
+       gUsertextPhysStart = . - _kernel_base;
+       . = _usertext_vbase;
+       .usertext : AT( gUsertextPhysStart )
+       {
+               *(.usertext)
+       }
+       . += gUsertextPhysStart + _kernel_base - _usertext_vbase;
+       
+       /* 0x4000 (4 pages) alignment needed for root table */
+       .data ALIGN(0x4000) : AT( ADDR(.data) - _kernel_base )
+       {
+               *(.padata)
+               *(.data*)
+               
+               gKernelSymbols = .;
+               *(KEXPORT)
+               gKernelSymbolsEnd = .;
+               
+               gKernelModules = .;
+               *(KMODULES)
+               gKernelModulesEnd = .;
+       }
+       .bss : AT( ADDR(.bss) - _kernel_base )
+       {
+               bss_start = .;
+               *(.bss*)
+               *(COMMON*)
+               . = ALIGN(0x1000);
+               *(.pabss)
+               bss_end = .;
+       }
+       gKernelEnd = .;
+}
diff --git a/KernelLand/Kernel/arch/armv6/main.c b/KernelLand/Kernel/arch/armv6/main.c
new file mode 100644 (file)
index 0000000..248c17c
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Acess2
+ *
+ * ARM7 Entrypoint
+ * arch/arm7/main.c
+ */
+#define DEBUG  0
+
+#include <acess.h>
+#include <modules.h>
+
+// === IMPORTS ===
+extern void    Interrupts_Setup(void);
+extern void    Arch_LoadBootModules(void);
+extern void    Heap_Install(void);
+extern void    Threads_Init(void);
+extern void    System_Init(const char *Commandline);
+
+// === PROTOTYPES ===
+ int   kmain(void);
+Uint32 ARMv7_int_HandleSyscalls(Uint32 Num, Uint32 *Args);
+
+// === CODE ===
+int kmain(void)
+{
+       LogF("Acess2 ARMv7 v"EXPAND_STR(KERNEL_VERSION)"\n");
+       LogF(" Git Hash %s\n", gsGitHash);
+       LogF(" Build %i\n", BUILD_NUM);
+       
+       MM_SetupPhys();
+
+       LogF("Heap Setup...\n");
+       Heap_Install();
+
+       LogF("Threads Init...\n");
+       Threads_Init();
+       
+       LogF("VFS Init...\n");
+       VFS_Init();
+
+       // Boot modules?
+       Module_EnsureLoaded("armv7_GIC");
+
+       //
+       LogF("Moving to arch-independent init\n");
+       #if PLATFORM_is_tegra2
+       System_Init("Acess2.armv7.bin /Acess=initrd: -VTerm:Video=Tegra2Vid");
+       #else
+       System_Init("Acess2.armv7.bin /Acess=initrd: -VTerm:Video=PL110");
+       #endif
+//     System_Init("Acess2.armv7.bin /Acess=initrd:");
+       //TODO: 
+       LogF("End of kmain(), for(;;) Threads_Sleep();\n");
+       for(;;)
+               Threads_Sleep();
+}
+
+void Arch_LoadBootModules(void)
+{
+}
+
+Uint32 ARMv7_int_HandleSyscalls(Uint32 Num, Uint32 *Args)
+{
+       Uint32  ret = -1, err = 0;
+       Uint32  addr;
+       ENTER("iNum xArgs[0] xArgs[1] xArgs[2] xArgs[3]",
+               Num, Args[0], Args[1], Args[2], Args[3]
+               );
+       switch(Num)
+       {
+       case 1:
+//             Log_Debug("ARMv7", "__clear_cache(%p, %p)", Args[0], Args[1]);
+               // Align
+               Args[0] &= ~0xFFF;
+               Args[1] += 0xFFF;       Args[1] &= ~0xFFF;
+               // Invalidate!
+               for( addr = Args[0]; addr < Args[1]; addr += 0x1000 )
+               {
+                       LOG("addr = %p", addr);
+                       __asm__ __volatile__ (
+                               "mcrlt p15, 0, %0, c7, c5, 1;\n\t"
+                               "mcrlt p15, 0, %0, c7, c6, 1;\n\t"
+                               :
+                               : "r" (addr)
+                               );
+               }
+               ret = 0;
+               break;
+       }
+       Args[0] = ret;  // RetLow
+       Args[1] = 0;    // RetHi
+       Args[2] = err;  // Errno
+       LEAVE('x', ret);
+       return ret;
+}
+
diff --git a/KernelLand/Kernel/arch/armv6/mm_phys.c b/KernelLand/Kernel/arch/armv6/mm_phys.c
new file mode 100644 (file)
index 0000000..5e4a242
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Acess2
+ *
+ * ARM7 Physical Memory Manager
+ * arch/arm7/mm_phys.c
+ */
+#define DEBUG  0
+
+#include <acess.h>
+#include <mm_virt.h>
+
+#define MM_NUM_RANGES  1       // Single range
+#define MM_RANGE_MAX   0
+#define TRACE_ALLOCS   0
+
+#define NUM_STATIC_ALLOC       4
+
+char   gStaticAllocPages[NUM_STATIC_ALLOC][PAGE_SIZE] __attribute__ ((section(".padata")));
+tPAddr gaiStaticAllocPages[NUM_STATIC_ALLOC] = {
+       (tPAddr)(&gStaticAllocPages[0]) - KERNEL_BASE,
+       (tPAddr)(&gStaticAllocPages[1]) - KERNEL_BASE,
+       (tPAddr)(&gStaticAllocPages[2]) - KERNEL_BASE,
+       (tPAddr)(&gStaticAllocPages[3]) - KERNEL_BASE
+};
+extern char    gKernelEnd[];
+
+
+#include <tpl_mm_phys_bitmap.h>
+
+//#define REALVIEW_LOWRAM_SIZE 0x10000000
+#define REALVIEW_LOWRAM_SIZE   (32*1024*1024)
+
+void MM_SetupPhys(void)
+{
+       LogF("MM_SetupPhys: ()\n");
+       MM_Tpl_InitPhys( REALVIEW_LOWRAM_SIZE/0x1000, NULL );
+}
+
+int MM_int_GetMapEntry( void *Data, int Index, tPAddr *Start, tPAddr *Length )
+{
+       switch(Index)
+       {
+       case 0:
+               *Start = ((tVAddr)&gKernelEnd - KERNEL_BASE + 0xFFF) & ~0xFFF;
+               *Length = REALVIEW_LOWRAM_SIZE - *Start;
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+/**
+ * \brief Takes a physical address and returns the ID of its range
+ * \param Addr Physical address of page
+ * \return Range ID from eMMPhys_Ranges
+ */
+int MM_int_GetRangeID( tPAddr Addr )
+{
+       return MM_RANGE_MAX;    // ARM doesn't need ranges
+}
diff --git a/KernelLand/Kernel/arch/armv6/mm_virt.c b/KernelLand/Kernel/arch/armv6/mm_virt.c
new file mode 100644 (file)
index 0000000..2dc1147
--- /dev/null
@@ -0,0 +1,1080 @@
+/*
+ * Acess2
+ * 
+ * ARM7 Virtual Memory Manager
+ * - arch/arm7/mm_virt.c
+ */
+#define DEBUG  0
+#include <acess.h>
+#include <mm_virt.h>
+#include <hal_proc.h>
+
+#define TRACE_MAPS     0
+
+#define AP_KRW_ONLY    1       // Kernel page
+#define AP_KRO_ONLY    5       // Kernel RO page
+#define AP_RW_BOTH     3       // Standard RW
+#define AP_RO_BOTH     7       // COW Page
+#define AP_RO_USER     2       // User RO Page
+#define PADDR_MASK_LVL1        0xFFFFFC00
+
+// === IMPORTS ===
+extern Uint32  kernel_table0[];
+
+// === TYPES ===
+typedef struct
+{
+       tPAddr  PhysAddr;
+       Uint8   Size;
+       Uint8   Domain;
+       BOOL    bExecutable;
+       BOOL    bGlobal;
+       BOOL    bShared;
+        int    AP;
+} tMM_PageInfo;
+
+//#define FRACTAL(table1, addr)        ((table1)[ (0xFF8/4*1024) + ((addr)>>20)])
+#define FRACTAL(table1, addr)  ((table1)[ (0xFF8/4*1024) + ((addr)>>22)])
+#define USRFRACTAL(addr)       (*((Uint32*)(0x7FDFF000) + ((addr)>>22)))
+#define TLBIALL()      __asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0))
+#define TLBIMVA(addr)  __asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 1" : : "r" (((addr)&~0xFFF)|1):"memory")
+#define DCCMVAC(addr)  __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" ((addr)&~0xFFF))
+
+// === PROTOTYPES ===
+void   MM_int_GetTables(tVAddr VAddr, Uint32 **Table0, Uint32 **Table1);
+ int   MM_int_AllocateCoarse(tVAddr VAddr, int Domain);
+ int   MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi);
+ int   MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi);
+tVAddr MM_NewUserStack(void);
+tPAddr MM_AllocateZero(tVAddr VAddr);
+tPAddr MM_AllocateRootTable(void);
+void   MM_int_CloneTable(Uint32 *DestEnt, int Table);
+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);
+
+// === GLOBALS ===
+tPAddr giMM_ZeroPage;
+
+// === CODE ===
+int MM_InitialiseVirtual(void)
+{
+       return 0;
+}
+
+void MM_int_GetTables(tVAddr VAddr, Uint32 **Table0, Uint32 **Table1)
+{
+       if(VAddr & 0x80000000) {
+               *Table0 = (void*)&kernel_table0;        // Level 0
+               *Table1 = (void*)MM_TABLE1KERN; // Level 1
+       }
+       else {
+               *Table0 = (void*)MM_TABLE0USER;
+               *Table1 = (void*)MM_TABLE1USER;
+       }
+}
+
+int MM_int_AllocateCoarse(tVAddr VAddr, int Domain)
+{
+       Uint32  *table0, *table1;
+       Uint32  *desc;
+       tPAddr  paddr;
+       
+       ENTER("xVAddr iDomain", VAddr, Domain);
+
+       MM_int_GetTables(VAddr, &table0, &table1);
+
+       VAddr &= ~(0x400000-1); // 4MiB per "block", 1 Page
+
+       desc = &table0[ VAddr>>20];
+       LOG("desc = %p", desc);
+       
+       // table0: 4 bytes = 1 MiB
+
+       LOG("desc[0] = %x", desc[0]);
+       LOG("desc[1] = %x", desc[1]);
+       LOG("desc[2] = %x", desc[2]);
+       LOG("desc[3] = %x", desc[3]);
+
+       if( (desc[0] & 3) != 0 || (desc[1] & 3) != 0
+        || (desc[2] & 3) != 0 || (desc[3] & 3) != 0 )
+       {
+               // Error?
+               LEAVE('i', 1);
+               return 1;
+       }
+
+       paddr = MM_AllocPhys();
+       if( !paddr )
+       {
+               // Error
+               LEAVE('i', 2);
+               return 2;
+       }
+       
+       *desc = paddr | (Domain << 5) | 1;
+       desc[1] = desc[0] + 0x400;
+       desc[2] = desc[0] + 0x800;
+       desc[3] = desc[0] + 0xC00;
+
+       if( VAddr < 0x80000000 ) {
+               USRFRACTAL(VAddr) = paddr | 0x13;
+       }
+       else {
+               FRACTAL(table1, VAddr) = paddr | 0x13;
+       }
+
+       // TLBIALL 
+       TLBIALL();
+       
+       memset( (void*)&table1[ (VAddr >> 12) & ~(1024-1) ], 0, 0x1000 );
+
+       LEAVE('i', 0);
+       return 0;
+}      
+
+int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
+{
+       Uint32  *table0, *table1;
+       Uint32  *desc;
+
+       ENTER("pVAddr ppi", VAddr, pi);
+
+       MM_int_GetTables(VAddr, &table0, &table1);
+
+       desc = &table0[ VAddr >> 20 ];
+       LOG("desc = %p", desc);
+
+       switch(pi->Size)
+       {
+       case 12:        // Small Page
+       case 16:        // Large Page
+               LOG("Page");
+               if( (*desc & 3) == 0 ) {
+                       MM_int_AllocateCoarse( VAddr, pi->Domain );
+               }
+               desc = &table1[ VAddr >> 12 ];
+               LOG("desc (2) = %p", desc);
+               if( pi->Size == 12 )
+               {
+                       // Small page
+                       // - Error if overwriting a large page
+                       if( (*desc & 3) == 1 )  LEAVE_RET('i', 1);
+                       if( pi->PhysAddr == 0 ) {
+                               *desc = 0;
+                               TLBIMVA( VAddr );
+                               DCCMVAC( (tVAddr) desc );
+//                             #warning "HACK: TLBIALL"
+//                             TLBIALL();                              
+                               LEAVE('i', 0);
+                               return 0;
+                       }
+
+                       *desc = (pi->PhysAddr & 0xFFFFF000) | 2;
+                       if(!pi->bExecutable)    *desc |= 1;     // XN
+                       if(!pi->bGlobal)        *desc |= 1 << 11;       // nG
+                       if( pi->bShared)        *desc |= 1 << 10;       // S
+                       *desc |= (pi->AP & 3) << 4;     // AP
+                       *desc |= ((pi->AP >> 2) & 1) << 9;      // APX
+                       TLBIMVA( VAddr );       
+//                     #warning "HACK: TLBIALL"
+//                     TLBIALL();
+                       DCCMVAC( (tVAddr) desc );
+                       LEAVE('i', 0);
+                       return 0;
+               }
+               else
+               {
+                       // Large page
+                       Log_Warning("MMVirt", "TODO: Implement large pages in MM_int_SetPageInfo");
+               }
+               break;
+       case 20:        // Section or unmapped
+               Log_Warning("MMVirt", "TODO: Implement sections in MM_int_SetPageInfo");
+               break;
+       case 24:        // Supersection
+               // Error if not aligned
+               if( VAddr & 0xFFFFFF ) {
+                       LEAVE('i', 1);
+                       return 1;
+               }
+               if( (*desc & 3) == 0 || ((*desc & 3) == 2 && (*desc & (1 << 18)))  )
+               {
+                       if( pi->PhysAddr == 0 ) {
+                               *desc = 0;
+                       }
+                       else {
+                               // Apply
+                               *desc = pi->PhysAddr & 0xFF000000;
+//                             *desc |= ((pi->PhysAddr >> 32) & 0xF) << 20;
+//                             *desc |= ((pi->PhysAddr >> 36) & 0x7) << 5;
+                               *desc |= 2 | (1 << 18);
+                       }
+                       // TODO: Apply to all entries
+                       Log_Warning("MMVirt", "TODO: Apply changes to all entries of supersections");
+                       LEAVE('i', 0);
+                       return 0;
+               }
+               // TODO: What here?
+               Log_Warning("MMVirt", "TODO: 24-bit not on supersection?");
+               LEAVE('i', 1);
+               return 1;
+       }
+
+       LEAVE('i', 1);
+       return 1;
+}
+
+int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
+{
+       Uint32  *table0, *table1;
+       Uint32  desc;
+
+//     LogF("MM_int_GetPageInfo: VAddr=%p, pi=%p\n", VAddr, pi);
+       
+       MM_int_GetTables(VAddr, &table0, &table1);
+
+       desc = table0[ VAddr >> 20 ];
+
+//     if( VAddr > 0x90000000)
+//             LOG("table0 desc(%p) = %x", &table0[ VAddr >> 20 ], desc);
+       
+       pi->bExecutable = 1;
+       pi->bGlobal = 0;
+       pi->bShared = 0;
+       pi->AP = 0;
+
+       switch( (desc & 3) )
+       {
+       // 0: Unmapped
+       case 0:
+               pi->PhysAddr = 0;
+               pi->Size = 20;
+               pi->Domain = 0;
+               return 1;
+
+       // 1: Coarse page table
+       case 1:
+               // Domain from top level table
+               pi->Domain = (desc >> 5) & 7;
+               // Get next level
+               desc = table1[ VAddr >> 12 ];
+//             LOG("table1 desc(%p) = %x", &table1[ VAddr >> 12 ], desc);
+               switch( desc & 3 )
+               {
+               // 0: Unmapped
+               case 0: 
+                       pi->Size = 12;
+                       return 1;
+               // 1: Large Page (64KiB)
+               case 1:
+                       pi->Size = 16;
+                       pi->PhysAddr = desc & 0xFFFF0000;
+                       pi->AP = ((desc >> 4) & 3) | (((desc >> 9) & 1) << 2);
+                       pi->bExecutable = !(desc & 0x8000);
+                       pi->bShared = (desc >> 10) & 1;
+                       return 0;
+               // 2/3: Small page
+               case 2:
+               case 3:
+                       pi->Size = 12;
+                       pi->PhysAddr = desc & 0xFFFFF000;
+                       pi->bExecutable = !(desc & 1);
+                       pi->bGlobal = !(desc >> 11);
+                       pi->bShared = (desc >> 10) & 1;
+                       pi->AP = ((desc >> 4) & 3) | (((desc >> 9) & 1) << 2);
+                       return 0;
+               }
+               return 1;
+       
+       // 2: Section (or Supersection)
+       case 2:
+               if( desc & (1 << 18) ) {
+                       // Supersection
+                       pi->PhysAddr = desc & 0xFF000000;
+                       pi->PhysAddr |= (Uint64)((desc >> 20) & 0xF) << 32;
+                       pi->PhysAddr |= (Uint64)((desc >> 5) & 0x7) << 36;
+                       pi->Size = 24;
+                       pi->Domain = 0; // Supersections default to zero
+                       pi->AP = ((desc >> 10) & 3) | (((desc >> 15) & 1) << 2);
+                       return 0;
+               }
+               
+               // Section
+               pi->PhysAddr = desc & 0xFFF80000;
+               pi->Size = 20;
+               pi->Domain = (desc >> 5) & 7;
+               pi->AP = ((desc >> 10) & 3) | (((desc >> 15) & 1) << 2);
+               return 0;
+
+       // 3: Reserved (invalid)
+       case 3:
+               pi->PhysAddr = 0;
+               pi->Size = 20;
+               pi->Domain = 0;
+               return 2;
+       }
+       return 2;
+}
+
+// --- Exports ---
+tPAddr MM_GetPhysAddr(const void *Ptr)
+{
+       tVAddr  VAddr = (tPAddr)Ptr;
+       tMM_PageInfo    pi;
+       if( MM_int_GetPageInfo(VAddr, &pi) )
+               return 0;
+       return pi.PhysAddr | (VAddr & ((1 << pi.Size)-1));
+}
+
+Uint MM_GetFlags(tVAddr VAddr)
+{
+       tMM_PageInfo    pi;
+        int    ret;
+
+       if( MM_int_GetPageInfo(VAddr, &pi) )
+               return 0;
+
+       ret = 0;
+       
+       switch(pi.AP)
+       {
+       case 0:
+               break;
+       case AP_KRW_ONLY:
+               ret |= MM_PFLAG_KERNEL;
+               break;
+       case AP_KRO_ONLY:
+               ret |= MM_PFLAG_KERNEL|MM_PFLAG_RO;
+               break;
+       case AP_RW_BOTH:
+               break;
+       case AP_RO_BOTH:
+               ret |= MM_PFLAG_COW;
+               break;
+       case AP_RO_USER:
+               ret |= MM_PFLAG_RO;
+               break;
+       }
+
+       if( pi.bExecutable )    ret |= MM_PFLAG_EXEC;
+       return ret;
+}
+
+void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask)
+{
+       tMM_PageInfo    pi;
+       Uint    curFlags;
+       
+       if( MM_int_GetPageInfo(VAddr, &pi) )
+               return ;
+       
+       curFlags = MM_GetFlags(VAddr);
+       if( (curFlags & Mask) == Flags )
+               return ;
+       curFlags &= ~Mask;
+       curFlags |= Flags;
+
+       if( curFlags & MM_PFLAG_COW )
+               pi.AP = AP_RO_BOTH;
+       else
+       {
+               switch(curFlags & (MM_PFLAG_KERNEL|MM_PFLAG_RO) )
+               {
+               case 0:
+                       pi.AP = AP_RW_BOTH;     break;
+               case MM_PFLAG_KERNEL:
+                       pi.AP = AP_KRW_ONLY;    break;
+               case MM_PFLAG_RO:
+                       pi.AP = AP_RO_USER;     break;
+               case MM_PFLAG_KERNEL|MM_PFLAG_RO:
+                       pi.AP = AP_KRO_ONLY;    break;
+               }
+       }
+       
+       pi.bExecutable = !!(curFlags & MM_PFLAG_EXEC);
+
+       MM_int_SetPageInfo(VAddr, &pi);
+}
+
+int MM_IsValidBuffer(tVAddr Addr, size_t Size)
+{
+       tMM_PageInfo    pi;
+        int    bUser = 0;
+       
+       Size += Addr & (PAGE_SIZE-1);
+       Addr &= ~(PAGE_SIZE-1);
+
+       if( MM_int_GetPageInfo(Addr, &pi) )     return 0;
+       Addr += PAGE_SIZE;
+
+       if(pi.AP != AP_KRW_ONLY && pi.AP != AP_KRO_ONLY)
+               bUser = 1;
+
+       while( Size >= PAGE_SIZE )
+       {
+               if( MM_int_GetPageInfo(Addr, &pi) )
+                       return 0;
+               if(bUser && (pi.AP == AP_KRW_ONLY || pi.AP == AP_KRO_ONLY))
+                       return 0;
+               Addr += PAGE_SIZE;
+               Size -= PAGE_SIZE;
+       }
+       
+       return 1;
+}
+
+int MM_Map(tVAddr VAddr, tPAddr PAddr)
+{
+       tMM_PageInfo    pi = {0};
+       #if TRACE_MAPS
+       Log("MM_Map %P=>%p", PAddr, VAddr);
+       #endif
+       
+       pi.PhysAddr = PAddr;
+       pi.Size = 12;
+       if(VAddr < USER_STACK_TOP)
+               pi.AP = AP_RW_BOTH;
+       else
+               pi.AP = AP_KRW_ONLY;    // Kernel Read/Write
+       pi.bExecutable = 1;
+       if( MM_int_SetPageInfo(VAddr, &pi) ) {
+//             MM_DerefPhys(pi.PhysAddr);
+               return 0;
+       }
+       return pi.PhysAddr;
+}
+
+tPAddr MM_Allocate(tVAddr VAddr)
+{
+       tMM_PageInfo    pi = {0};
+       
+       ENTER("pVAddr", VAddr);
+
+       pi.PhysAddr = MM_AllocPhys();
+       if( pi.PhysAddr == 0 )  LEAVE_RET('i', 0);
+       pi.Size = 12;
+       if(VAddr < USER_STACK_TOP)
+               pi.AP = AP_RW_BOTH;
+       else
+               pi.AP = AP_KRW_ONLY;
+       pi.bExecutable = 0;
+       if( MM_int_SetPageInfo(VAddr, &pi) ) {
+               MM_DerefPhys(pi.PhysAddr);
+               LEAVE('i', 0);
+               return 0;
+       }
+       LEAVE('x', pi.PhysAddr);
+       return pi.PhysAddr;
+}
+
+tPAddr MM_AllocateZero(tVAddr VAddr)
+{
+       if( !giMM_ZeroPage ) {
+               giMM_ZeroPage = MM_Allocate(VAddr);
+               MM_RefPhys(giMM_ZeroPage);
+               memset((void*)VAddr, 0, PAGE_SIZE);
+       }
+       else {
+               MM_RefPhys(giMM_ZeroPage);
+               MM_Map(VAddr, giMM_ZeroPage);
+       }
+       MM_SetFlags(VAddr, MM_PFLAG_COW, MM_PFLAG_COW);
+       return giMM_ZeroPage;
+}
+
+void MM_Deallocate(tVAddr VAddr)
+{
+       tMM_PageInfo    pi;
+       
+       if( MM_int_GetPageInfo(VAddr, &pi) )    return ;
+       if( pi.PhysAddr == 0 )  return;
+       MM_DerefPhys(pi.PhysAddr);
+       
+       pi.PhysAddr = 0;
+       pi.AP = 0;
+       pi.bExecutable = 0;
+       MM_int_SetPageInfo(VAddr, &pi);
+}
+
+tPAddr MM_AllocateRootTable(void)
+{
+       tPAddr  ret;
+       
+       ret = MM_AllocPhysRange(2, -1);
+       if( ret & 0x1000 ) {
+               MM_DerefPhys(ret);
+               MM_DerefPhys(ret+0x1000);
+               ret = MM_AllocPhysRange(3, -1);
+               if( ret & 0x1000 ) {
+                       MM_DerefPhys(ret);
+                       ret += 0x1000;
+//                     Log("MM_AllocateRootTable: Second try not aligned, %P", ret);
+               }
+               else {
+                       MM_DerefPhys(ret + 0x2000);
+//                     Log("MM_AllocateRootTable: Second try aligned, %P", ret);
+               }
+       }
+//     else
+//             Log("MM_AllocateRootTable: Got it in one, %P", ret);
+       return ret;
+}
+
+void MM_int_CloneTable(Uint32 *DestEnt, int Table)
+{
+       tPAddr  table;
+       Uint32  *tmp_map;
+       Uint32  *cur = (void*)MM_TABLE1USER;
+//     Uint32  *cur = &FRACTAL(MM_TABLE1USER,0);
+        int    i;
+       
+       table = MM_AllocPhys();
+       if(!table)      return ;
+
+       cur += 256*Table;
+       
+       tmp_map = MM_MapTemp(table);
+       
+       for( i = 0; i < 1024; i ++ )
+       {
+//             Log_Debug("MMVirt", "cur[%i] (%p) = %x", Table*256+i, &cur[Table*256+i], cur[Table*256+i]);
+               switch(cur[i] & 3)
+               {
+               case 0: tmp_map[i] = 0; break;
+               case 1:
+                       tmp_map[i] = 0;
+                       Log_Error("MMVirt", "TODO: Support large pages in MM_int_CloneTable (%p)", (Table*256+i)*0x1000);
+                       // Large page?
+                       break;
+               case 2:
+               case 3:
+                       // Small page
+                       // - If full RW
+//                     Debug("%p cur[%i] & 0x230 = 0x%x", Table*256*0x1000, i, cur[i] & 0x230);
+                       if( (cur[i] & 0x230) == 0x010 )
+                       {
+                               void    *dst, *src;
+                               tPAddr  newpage;
+                               newpage = MM_AllocPhys();
+                               src = (void*)( (Table*256+i)*0x1000 );
+                               dst = MM_MapTemp(newpage);
+//                             Debug("Taking a copy of kernel page %p (%P)", src, cur[i] & ~0xFFF);
+                               memcpy(dst, src, PAGE_SIZE);
+                               MM_FreeTemp( dst );
+                               tmp_map[i] = newpage | (cur[i] & 0xFFF);
+                       }
+                       else
+                       {
+                               if( (cur[i] & 0x230) == 0x030 )
+                                       cur[i] |= 0x200;        // Set to full RO (Full RO=COW, User RO = RO)
+                               tmp_map[i] = cur[i];
+                               MM_RefPhys( tmp_map[i] & ~0xFFF );
+                       }
+                       break;
+               }
+       }
+       MM_FreeTemp( tmp_map );
+
+       DestEnt[0] = table + 0*0x400 + 1;
+       DestEnt[1] = table + 1*0x400 + 1;
+       DestEnt[2] = table + 2*0x400 + 1;
+       DestEnt[3] = table + 3*0x400 + 1;
+}
+
+tPAddr MM_Clone(void)
+{
+       tPAddr  ret;
+       Uint32  *new_lvl1_1, *new_lvl1_2, *cur;
+       Uint32  *tmp_map;
+        int    i;
+
+//     MM_DumpTables(0, KERNEL_BASE);
+       
+       ret = MM_AllocateRootTable();
+
+       cur = (void*)MM_TABLE0USER;
+       new_lvl1_1 = MM_MapTemp(ret);
+       new_lvl1_2 = MM_MapTemp(ret+0x1000);
+       tmp_map = new_lvl1_1;
+       for( i = 0; i < 0x800-4; i ++ )
+       {
+               // HACK! Ignore the original identity mapping
+               if( i == 0 && Threads_GetTID() == 0 ) {
+                       tmp_map[0] = 0;
+                       continue;
+               }
+               if( i == 0x400 )
+                       tmp_map = &new_lvl1_2[-0x400];
+               switch( cur[i] & 3 )
+               {
+               case 0: tmp_map[i] = 0; break;
+               case 1:
+                       MM_int_CloneTable(&tmp_map[i], i);
+                       i += 3; // Tables are alocated in blocks of 4
+                       break;
+               case 2:
+               case 3:
+                       Log_Error("MMVirt", "TODO: Support Sections/Supersections in MM_Clone (i=%i)", i);
+                       tmp_map[i] = 0;
+                       break;
+               }
+       }
+
+       // Allocate Fractal table
+       {
+                int    j, num;
+               tPAddr  tmp = MM_AllocPhys();
+               Uint32  *table = MM_MapTemp(tmp);
+               Uint32  sp;
+               register Uint32 __SP asm("sp");
+
+               // Map table to last 4MiB of user space
+               new_lvl1_2[0x3FC] = tmp + 0*0x400 + 1;
+               new_lvl1_2[0x3FD] = tmp + 1*0x400 + 1;
+               new_lvl1_2[0x3FE] = tmp + 2*0x400 + 1;
+               new_lvl1_2[0x3FF] = tmp + 3*0x400 + 1;
+               
+               tmp_map = new_lvl1_1;
+               for( j = 0; j < 512; j ++ )
+               {
+                       if( j == 256 )
+                               tmp_map = &new_lvl1_2[-0x400];
+                       if( (tmp_map[j*4] & 3) == 1 )
+                       {
+                               table[j] = tmp_map[j*4] & PADDR_MASK_LVL1;// 0xFFFFFC00;
+                               table[j] |= 0x813;      // nG, Kernel Only, Small page, XN
+                       }
+                       else
+                               table[j] = 0;
+               }
+               // Fractal
+               table[j++] = (ret + 0x0000) | 0x813;
+               table[j++] = (ret + 0x1000) | 0x813;
+               // Nuke the rest
+               for(      ; j < 1024; j ++ )
+                       table[j] = 0;
+               
+               // Get kernel stack bottom
+               sp = __SP & ~(MM_KSTACK_SIZE-1);
+               j = (sp / 0x1000) % 1024;
+               num = MM_KSTACK_SIZE/0x1000;
+
+//             Log("num = %i, sp = %p, j = %i", num, sp, j);
+               
+               // Copy stack pages
+               for(; num--; j ++, sp += 0x1000)
+               {
+                       tVAddr  page;
+                       void    *tmp_page;
+                       
+                       page = MM_AllocPhys();
+//                     Log("page = %P", page);
+                       table[j] = page | 0x813;
+
+                       tmp_page = MM_MapTemp(page);
+                       memcpy(tmp_page, (void*)sp, 0x1000);
+                       MM_FreeTemp( tmp_page );
+               }
+
+               MM_FreeTemp( table );
+       }
+
+       MM_FreeTemp( new_lvl1_1 );
+       MM_FreeTemp( new_lvl1_2 );
+
+//     Log("MM_Clone: ret = %P", ret);
+
+       return ret;
+}
+
+void MM_ClearUser(void)
+{
+        int    i, j;
+       const int       user_table_count = USER_STACK_TOP / (256*0x1000);
+       Uint32  *cur = (void*)MM_TABLE0USER;
+       Uint32  *tab;
+       
+//     MM_DumpTables(0, 0x80000000);
+
+//     Log("user_table_count = %i (as opposed to %i)", user_table_count, 0x800-4);
+
+       for( i = 0; i < user_table_count; i ++ )
+       {
+               switch( cur[i] & 3 )
+               {
+               case 0: break;  // Already unmapped
+               case 1: // Sub pages
+                       tab = (void*)(MM_TABLE1USER + i*256*sizeof(Uint32));
+                       for( j = 0; j < 1024; j ++ )
+                       {
+                               switch( tab[j] & 3 )
+                               {
+                               case 0: break;  // Unmapped
+                               case 1:
+                                       Log_Error("MMVirt", "TODO: Support large pages in MM_ClearUser");
+                                       break;
+                               case 2:
+                               case 3:
+                                       MM_DerefPhys( tab[j] & ~(PAGE_SIZE-1) );
+                                       break;
+                               }
+                       }
+                       MM_DerefPhys( cur[i] & ~(PAGE_SIZE-1) );
+                       cur[i+0] = 0;
+                       cur[i+1] = 0;
+                       cur[i+2] = 0;
+                       i += 3;
+                       break;
+               case 2:
+               case 3:
+                       Log_Error("MMVirt", "TODO: Implement sections/supersections in MM_ClearUser");
+                       break;
+               }
+               cur[i] = 0;
+       }
+       
+       // Final block of 4 tables are KStack
+       i = 0x800 - 4;
+       
+       // Clear out unused stacks
+       {
+               register Uint32 __SP asm("sp");
+                int    cur_stack_base = ((__SP & ~(MM_KSTACK_SIZE-1)) / PAGE_SIZE) % 1024;
+
+               tab = (void*)(MM_TABLE1USER + i*256*sizeof(Uint32));
+               
+               // First 512 is the Table1 mapping + 2 for Table0 mapping
+               for( j = 512+2; j < 1024; j ++ )
+               {
+                       // Skip current stack
+                       if( j == cur_stack_base ) {
+                               j += (MM_KSTACK_SIZE / PAGE_SIZE) - 1;
+                               continue ;
+                       }
+                       if( !(tab[j] & 3) )     continue;
+                       ASSERT( (tab[j] & 3) == 2 );
+                       MM_DerefPhys( tab[j] & ~(PAGE_SIZE) );
+                       tab[j] = 0;
+               }
+       }
+       
+
+//     MM_DumpTables(0, 0x80000000);
+}
+
+void *MM_MapTemp(tPAddr PAddr)
+{
+       tVAddr  ret;
+       tMM_PageInfo    pi;
+
+       for( ret = MM_TMPMAP_BASE; ret < MM_TMPMAP_END - PAGE_SIZE; ret += PAGE_SIZE )
+       {
+               if( MM_int_GetPageInfo(ret, &pi) == 0 )
+                       continue;
+
+//             Log("MapTemp %P at %p by %p", PAddr, ret, __builtin_return_address(0));
+               MM_RefPhys(PAddr);      // Counter the MM_Deallocate in FreeTemp
+               MM_Map(ret, PAddr);
+               
+               return (void*)ret;
+       }
+       Log_Warning("MMVirt", "MM_MapTemp: All slots taken");
+       return 0;
+}
+
+void MM_FreeTemp(void *Ptr)
+{
+       tVAddr  VAddr = (tVAddr)Ptr;
+       if( VAddr < MM_TMPMAP_BASE || VAddr >= MM_TMPMAP_END ) {
+               Log_Warning("MMVirt", "MM_FreeTemp: Passed an addr not from MM_MapTemp (%p)", VAddr);
+               return ;
+       }
+       
+       MM_Deallocate(VAddr);
+}
+
+tVAddr MM_MapHWPages(tPAddr PAddr, Uint NPages)
+{
+       tVAddr  ret;
+        int    i;
+       tMM_PageInfo    pi;
+
+       ENTER("xPAddr iNPages", PAddr, NPages);
+
+       // Scan for a location
+       for( ret = MM_HWMAP_BASE; ret < MM_HWMAP_END - NPages * PAGE_SIZE; ret += PAGE_SIZE )
+       {
+//             LOG("checking %p", ret);
+               // Check if there is `NPages` free pages
+               for( i = 0; i < NPages; i ++ )
+               {
+                       if( MM_int_GetPageInfo(ret + i*PAGE_SIZE, &pi) == 0 )
+                               break;
+               }
+               // Nope, jump to after the used page found and try again
+//             LOG("i = %i, ==? %i", i, NPages);
+               if( i != NPages ) {
+                       ret += i * PAGE_SIZE;
+                       continue ;
+               }
+       
+               // Map the pages        
+               for( i = 0; i < NPages; i ++ )
+                       MM_Map(ret+i*PAGE_SIZE, PAddr+i*PAGE_SIZE);
+               // and return
+               LEAVE('p', ret);
+               return ret;
+       }
+       Log_Warning("MMVirt", "MM_MapHWPages: No space for a %i page block", NPages);
+       LEAVE('p', 0);
+       return 0;
+}
+
+tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PAddr)
+{
+       tPAddr  phys;
+       tVAddr  ret;
+
+       phys = MM_AllocPhysRange(Pages, MaxBits);
+       if(!phys) {
+               Log_Warning("MMVirt", "No space left for a %i page block (MM_AllocDMA)", Pages);
+               return 0;
+       }
+       
+       ret = MM_MapHWPages(phys, Pages);
+       *PAddr = phys;
+
+       return ret;
+}
+
+void MM_UnmapHWPages(tVAddr Vaddr, Uint Number)
+{
+       Log_Error("MMVirt", "TODO: Implement MM_UnmapHWPages");
+}
+
+tVAddr MM_NewKStack(int bShared)
+{
+       tVAddr  min_addr, max_addr;
+       tVAddr  addr, ofs;
+
+       if( bShared ) {
+               min_addr = MM_GLOBALSTACKS;
+               max_addr = MM_GLOBALSTACKS_END;
+       }
+       else {
+               min_addr = MM_KSTACK_BASE;
+               max_addr = MM_KSTACK_END;
+       }
+
+       // Locate a free slot
+       for( addr = min_addr; addr < max_addr; addr += MM_KSTACK_SIZE )
+       {
+               tMM_PageInfo    pi;
+               if( MM_int_GetPageInfo(addr+MM_KSTACK_SIZE-PAGE_SIZE, &pi) )    break;
+       }
+
+       // Check for an error   
+       if(addr >= max_addr) {
+               return 0;
+       }
+
+       // 1 guard page
+       for( ofs = PAGE_SIZE; ofs < MM_KSTACK_SIZE; ofs += PAGE_SIZE )
+       {
+               if( MM_Allocate(addr + ofs) == 0 )
+               {
+                       while(ofs)
+                       {
+                               ofs -= PAGE_SIZE;
+                               MM_Deallocate(addr + ofs);
+                       }
+                       Log_Warning("MMVirt", "MM_NewKStack: Unable to allocate");
+                       return 0;
+               }
+       }
+       return addr + ofs;
+}
+
+tVAddr MM_NewUserStack(void)
+{
+       tVAddr  addr, ofs;
+
+       addr = USER_STACK_TOP - USER_STACK_SIZE;
+       if( MM_GetPhysAddr( (void*)(addr + PAGE_SIZE) ) ) {
+               Log_Error("MMVirt", "Unable to create initial user stack, addr %p taken",
+                       addr + PAGE_SIZE
+                       );
+               return 0;
+       }
+
+       // 1 guard page
+       for( ofs = PAGE_SIZE; ofs < USER_STACK_SIZE; ofs += PAGE_SIZE )
+       {
+               tPAddr  rv;
+               if(ofs >= USER_STACK_SIZE - USER_STACK_COMM)
+                       rv = MM_Allocate(addr + ofs);
+               else
+                       rv = MM_AllocateZero(addr + ofs);
+               if(rv == 0)
+               {
+                       while(ofs)
+                       {
+                               ofs -= PAGE_SIZE;
+                               MM_Deallocate(addr + ofs);
+                       }
+                       Log_Warning("MMVirt", "MM_NewUserStack: Unable to allocate");
+                       return 0;
+               }
+               MM_SetFlags(addr+ofs, 0, MM_PFLAG_KERNEL);
+       }
+//     Log("Return %p", addr + ofs);
+//     MM_DumpTables(0, 0x80000000);
+       return addr + ofs;
+}
+
+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",
+                       Start, "ZERO", Len,
+                       Info->Domain, Info->AP,
+                       Info->bGlobal ? "G" : "nG"
+                       );
+       }
+       else
+       {
+               Debug("%p => %8x - 0x%7x %i %x %s",
+                       Start, Info->PhysAddr-Len, Len,
+                       Info->Domain, Info->AP,
+                       Info->bGlobal ? "G" : "nG"
+                       );
+       }
+}
+
+void MM_DumpTables(tVAddr Start, tVAddr End)
+{
+       tVAddr  range_start = 0, addr;
+       tMM_PageInfo    pi, pi_old;
+        int    i = 0, inRange=0;
+       
+       memset(&pi_old, 0, sizeof(pi_old));
+
+       Debug("Page Table Dump (%p to %p):", Start, End);
+       range_start = Start;
+       for( addr = Start; i == 0 || (addr && addr < End); i = 1 )
+       {
+                int    rv;
+//             Log("addr = %p", addr);
+               rv = MM_int_GetPageInfo(addr, &pi);
+               if( rv
+                || pi.Size != pi_old.Size
+                || pi.Domain != pi_old.Domain
+                || pi.AP != pi_old.AP
+                || pi.bGlobal != pi_old.bGlobal
+                || pi_old.PhysAddr != pi.PhysAddr )
+               {
+                       if(inRange) {
+                               MM_int_DumpTableEnt(range_start, addr - range_start, &pi_old);
+                       }
+                       addr &= ~((1 << pi.Size)-1);
+                       range_start = addr;
+               }
+               
+               pi_old = pi;
+               // Handle the zero page
+               if( !giMM_ZeroPage || pi_old.Size != 12 || pi_old.PhysAddr != giMM_ZeroPage )
+                       pi_old.PhysAddr += 1 << pi_old.Size;
+               addr += 1 << pi_old.Size;
+               inRange = (rv == 0);
+       }
+       if(inRange)
+               MM_int_DumpTableEnt(range_start, addr - range_start, &pi);
+       Debug("Done");
+}
+
+// NOTE: Runs in abort context, not much difference, just a smaller stack
+void MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch)
+{
+        int    rv;
+       tMM_PageInfo    pi;
+       
+       rv = MM_int_GetPageInfo(Addr, &pi);
+       
+       // Check for COW
+       if( rv == 0 &&  pi.AP == AP_RO_BOTH )
+       {
+               pi.AP = AP_RW_BOTH;
+               if( giMM_ZeroPage && pi.PhysAddr == giMM_ZeroPage )
+               {
+                       tPAddr  newpage;
+                       newpage = MM_AllocPhys();
+                       if( !newpage ) {
+                               Log_Error("MMVirt", "Unable to allocate new page for COW of ZERO");
+                               for(;;);
+                       }
+                       
+                       #if TRACE_COW
+                       Log_Notice("MMVirt", "COW %p caused by %p, ZERO duped to %P (RefCnt(%i)--)", Addr, PC,
+                               newpage, MM_GetRefCount(pi.PhysAddr));
+                       #endif
+
+                       MM_DerefPhys(pi.PhysAddr);
+                       pi.PhysAddr = newpage;
+                       pi.AP = AP_RW_BOTH;
+                       MM_int_SetPageInfo(Addr, &pi);
+                       
+                       memset( (void*)(Addr & ~(PAGE_SIZE-1)), 0, PAGE_SIZE );
+
+                       return ;
+               }
+               else if( MM_GetRefCount(pi.PhysAddr) > 1 )
+               {
+                       // Duplicate the page
+                       tPAddr  newpage;
+                       void    *dst, *src;
+                       
+                       newpage = MM_AllocPhys();
+                       if(!newpage) {
+                               Log_Error("MMVirt", "Unable to allocate new page for COW");
+                               for(;;);
+                       }
+                       dst = MM_MapTemp(newpage);
+                       src = (void*)(Addr & ~(PAGE_SIZE-1));
+                       memcpy( dst, src, PAGE_SIZE );
+                       MM_FreeTemp( dst );
+                       
+                       #if TRACE_COW
+                       Log_Notice("MMVirt", "COW %p caused by %p, %P duped to %P (RefCnt(%i)--)", Addr, PC,
+                               pi.PhysAddr, newpage, MM_GetRefCount(pi.PhysAddr));
+                       #endif
+
+                       MM_DerefPhys(pi.PhysAddr);
+                       pi.PhysAddr = newpage;
+               }
+               #if TRACE_COW
+               else {
+                       Log_Notice("MMVirt", "COW %p caused by %p, took last reference to %P",
+                               Addr, PC, pi.PhysAddr);
+               }
+               #endif
+               // Unset COW
+               pi.AP = AP_RW_BOTH;
+               MM_int_SetPageInfo(Addr, &pi);
+               return ;
+       }
+       
+
+       Log_Error("MMVirt", "Code at %p accessed %p (DFSR = 0x%x)%s", PC, Addr, DFSR,
+               (bPrefetch ? " - Prefetch" : "")
+               );
+       if( Addr < 0x80000000 )
+               MM_DumpTables(0, 0x80000000);
+       else
+               MM_DumpTables(0x80000000, -1);
+       for(;;);
+}
+
diff --git a/KernelLand/Kernel/arch/armv6/pci.c b/KernelLand/Kernel/arch/armv6/pci.c
new file mode 100644 (file)
index 0000000..2e674bb
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *
+ */
+#include <acess.h>
+#include <drv_pci_int.h>
+
+// Realview
+//#define PCI_BASE     0x60000000
+
+//#define PCI_BASE     0xF0400000      // VMM Mapping
+#define PCI_BASE       0
+
+// === CODE ===
+void PCI_CfgWriteDWord(Uint32 Addr, Uint32 Data)
+{
+       #if PCI_BASE
+       Uint32  address = PCI_BASE | Addr;
+       *(Uint32*)(address) = Data;
+       #else
+       #endif
+}
+
+Uint32 PCI_CfgReadDWord(Uint32 Addr)
+{
+       #if PCI_BASE
+       Uint32  address = PCI_BASE | Addr;
+       return *(Uint32*)address;
+       #else
+       return 0xFFFFFFFF;
+       #endif
+}
+
diff --git a/KernelLand/Kernel/arch/armv6/proc.S b/KernelLand/Kernel/arch/armv6/proc.S
new file mode 100644 (file)
index 0000000..1979058
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Acess2 ARM
+ * - By John Hodge (thePowersGang)
+ *
+ * arch/arm7/proc.S
+ * - Process management assembly
+ */
+
+#include "include/assembly.h"
+
+.globl KernelThreadHeader
+@ SP+12: Argument 1
+@ SP+8: Argument Count
+@ SP+4: Function
+@ SP+0: Thread Pointer
+KernelThreadHeader:
+       ldr r0, [sp],#4
+       @ TODO: Do something with the thread pointer
+       
+       ldr r4, [sp],#4 @ Function
+       @ Get argument
+       ldr r0, [sp],#4
+
+       blx r4
+       
+       ldr r0, =0
+       bl Threads_Exit
+       b .
+
+.globl SwitchTask
+@ R0: New stack
+@ R1: Pointer to where to save old stack
+@ R2: New IP
+@ R3: Pointer to save old IP
+@ SP+0: New address space
+SwitchTask:
+       push {r4-r12,lr}
+
+       @ Save IP       
+       ldr r4, =.return
+       str r4, [r3]
+       @ Save SP
+       str sp, [r1]
+
+       @ Only update TTBR0 if the task has an explicit address space
+       ldr r1, [sp,#4*10]
+       tst r1, r1
+       mcrne p15, 0, r1, c2, c0, 0     @ Set TTBR0 to r0
+#      mov r1, #1
+       mcrne p15, 0, r1, c8, c7, 0     @ TLBIALL - Invalid user space
+
+       @ Restore state
+       mov sp, r0
+       bx r2
+
+.return:
+       pop {r4-r12,pc}
+
+.extern MM_Clone
+.extern MM_DumpTables
+.globl Proc_CloneInt
+Proc_CloneInt:
+       @ R0: SP Destination
+       @ R1: Mem Destination
+       push {r4-r12,lr}
+       mov r4, r1      @ Save mem destination
+       str sp, [r0]    @ Save SP to SP dest
+
+       bl MM_Clone
+       str r0, [r4]    @ Save clone return to Mem Dest
+
+       ldr r0, =Proc_CloneInt_new
+       pop {r4-r12,pc}
+Proc_CloneInt_new:
+       mov r0, #0
+       pop {r4-r12,pc}
+
+@ R0: New user SP
+@ Return: Old user SP
+.globl Proc_int_SwapUserSP
+Proc_int_SwapUserSP:
+       cps #31 @ Go to system mode
+       mov r1, sp
+       tst r0, r0      @ Only update if non-zero
+       movne sp, r0
+       mov r0, r1
+       cps #19
+       mov pc, lr
+
+.section .usertext, "ax"
+.globl Proc_int_DropToUser
+@ R0: User IP
+@ R1: User SP
+Proc_int_DropToUser:
+       cps #16
+       mov sp, r1
+       mov pc, r0
+
+.section .rodata
+csProc_CloneInt_NewTaskMessage:
+       .asciz "New task PC=%p, R4=%p, sp=%p"
+csProc_CloneInt_OldTaskMessage:
+       .asciz "Parent task PC=%p, R4=%p, SP=%p"
+
+@ vim: ft=armv7
diff --git a/KernelLand/Kernel/arch/armv6/proc.c b/KernelLand/Kernel/arch/armv6/proc.c
new file mode 100644 (file)
index 0000000..cd998f2
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Acess2
+ * - By John Hodge (thePowersGang)
+ *
+ * arch/arm7/proc.c
+ * - ARM7 Process Switching
+ */
+#include <acess.h>
+#include <threads_int.h>
+#include <hal_proc.h>
+
+// === IMPORTS ===
+extern tThread gThreadZero;
+extern tProcess        gProcessZero;
+extern void    SwitchTask(Uint32 NewSP, Uint32 *OldSP, Uint32 NewIP, Uint32 *OldIP, Uint32 MemPtr);
+extern void    KernelThreadHeader(void);       // Actually takes args on stack
+extern void    Proc_int_DropToUser(Uint32 IP, Uint32 SP) NORETURN __attribute__((long_call));
+extern Uint32  Proc_int_SwapUserSP(Uint32 NewSP);
+extern Uint32  Proc_CloneInt(Uint32 *SP, Uint32 *MemPtr);
+extern tVAddr  MM_NewKStack(int bGlobal);      // TODO: Move out into a header
+extern tVAddr  MM_NewUserStack(void);
+extern char    kernel_table0[];
+
+// === PROTOTYPES ===
+void   Proc_IdleThread(void *unused);
+
+// === GLOBALS ===
+tThread        *gpCurrentThread = &gThreadZero;
+tThread *gpIdleThread = NULL;
+
+// === CODE ===
+void ArchThreads_Init(void)
+{
+       gProcessZero.MemState.Base = (tPAddr)&kernel_table0 - KERNEL_BASE;
+}
+
+void Proc_IdleThread(void *unused)
+{
+       Threads_SetPriority(gpIdleThread, -1);
+       for(;;) {
+               Proc_Reschedule();
+               __asm__ __volatile__ ("wfi");
+       }
+}
+
+void Proc_Start(void)
+{
+       tTID    tid;
+
+       tid = Proc_NewKThread( Proc_IdleThread, NULL );
+       gpIdleThread = Threads_GetThread(tid);
+       gpIdleThread->ThreadName = (char*)"Idle Thread";
+}
+
+int GetCPUNum(void)
+{
+       return 0;
+}
+
+tThread *Proc_GetCurThread(void)
+{
+       return gpCurrentThread;
+}
+
+void Proc_StartUser(Uint Entrypoint, Uint Base, int ArgC, const char **ArgV, int DataSize)
+{
+       Uint32  *usr_sp;
+        int    i;
+       const char      **envp;
+       tVAddr  delta;
+
+//     Log_Debug("Proc", "Proc_StartUser: (Entrypoint=%p, Base=%p, ArgC=%i, ArgV=%p, DataSize=0x%x)",
+//             Entrypoint, Base, ArgC, ArgV, DataSize);
+
+       // Write data to the user's stack
+       usr_sp = (void*)MM_NewUserStack();
+       usr_sp -= (DataSize+3)/4;
+       memcpy(usr_sp, ArgV, DataSize);
+       free(ArgV);
+
+       // Adjust user's copy of the arguments
+       delta = (tVAddr)usr_sp -  (tVAddr)ArgV;
+       ArgV = (void*)usr_sp;
+       for(i = 0; ArgV[i]; i ++)       ArgV[i] += delta;
+       envp = &ArgV[i+1];
+       for(i = 0; envp[i]; i ++)       envp[i] += delta;
+       
+       *--usr_sp = (Uint32)envp;
+       *--usr_sp = (Uint32)ArgV;
+       *--usr_sp = (Uint32)ArgC;
+       *--usr_sp = Base;
+       
+       // Drop to user code
+       Log_Debug("Proc", "Proc_int_DropToUser(%p, %p)", Entrypoint, usr_sp);
+       Proc_int_DropToUser(Entrypoint, (Uint32)usr_sp);
+}
+
+void Proc_ClearProcess(tProcess *Process)
+{
+       Log_Warning("Proc", "TODO: Nuke address space etc");
+}
+
+void Proc_ClearThread(tThread *Thread)
+{
+}
+
+tTID Proc_Clone(Uint Flags)
+{
+       tThread *new;
+       Uint32  pc, sp, mem;
+
+       new = Threads_CloneTCB(Flags);
+       if(!new)        return -1;
+
+       // Actual clone magic
+       pc = Proc_CloneInt(&sp, &mem);
+       if(pc == 0) {
+               Log("Proc_Clone: In child");
+               return 0;
+       }
+       
+       new->SavedState.IP = pc;
+       new->SavedState.SP = sp;
+       new->SavedState.UserSP = Proc_int_SwapUserSP(0);
+       new->SavedState.UserIP = Proc_GetCurThread()->SavedState.UserIP;
+       new->Process->MemState.Base = mem;
+
+       Threads_AddActive(new);
+
+       return new->TID;
+}
+
+int Proc_SpawnWorker( void (*Fnc)(void*), void *Ptr )
+{
+       tThread *new;
+       Uint32  sp;
+
+       new = Threads_CloneThreadZero();
+       if(!new)        return -1;
+       if(new->ThreadName)     free(new->ThreadName);
+       new->ThreadName = NULL;
+
+       new->KernelStack = MM_NewKStack(1);
+       if(!new->KernelStack) {
+               // TODO: Delete thread
+               Log_Error("Proc", "Unable to allocate kernel stack");
+               return -1;
+       }       
+
+       sp = new->KernelStack;
+       
+       *(Uint32*)(sp -= 4) = (Uint)Ptr;
+       *(Uint32*)(sp -= 4) = (Uint)Fnc;
+       *(Uint32*)(sp -= 4) = (Uint)new;
+
+       new->SavedState.SP = sp;
+       new->SavedState.IP = (Uint)KernelThreadHeader;
+
+       Threads_AddActive(new);
+
+       return new->TID;
+}
+
+tTID Proc_NewKThread( void (*Fnc)(void*), void *Ptr )
+{
+       tThread *new;
+       Uint32  sp;
+
+       new = Threads_CloneTCB(0);
+       if(!new)        return -1;
+       free(new->ThreadName);
+       new->ThreadName = NULL;
+
+       // TODO: Non-shared stack
+       new->KernelStack = MM_NewKStack(1);
+       if(!new->KernelStack) {
+               // TODO: Delete thread
+               Log_Error("Proc", "Unable to allocate kernel stack");
+               return -1;
+       }       
+
+       sp = new->KernelStack;
+       
+       *(Uint32*)(sp -= 4) = (Uint)Ptr;
+       *(Uint32*)(sp -= 4) = (Uint)Fnc;
+       *(Uint32*)(sp -= 4) = (Uint)new;
+
+       new->SavedState.SP = sp;
+       new->SavedState.IP = (Uint)KernelThreadHeader;
+
+       Threads_AddActive(new);
+
+       return new->TID;
+}
+
+void Proc_CallFaultHandler(tThread *Thread)
+{
+
+}
+
+void Proc_Reschedule(void)
+{
+       tThread *cur, *next;
+
+       cur = gpCurrentThread;
+
+       next = Threads_GetNextToRun(0, cur);
+       if(!next)       next = gpIdleThread;
+       if(!next || next == cur)        return;
+
+       Log("Switching to %p (%i %s) IP=%p SP=%p TTBR0=%p UsrSP=%p",
+               next, next->TID, next->ThreadName,
+               next->SavedState.IP, next->SavedState.SP, next->Process->MemState.Base,
+               next->SavedState.UserSP
+               );
+
+       Log("Requested by %p", __builtin_return_address(0));
+       
+       gpCurrentThread = next;
+
+       cur->SavedState.UserSP = Proc_int_SwapUserSP( next->SavedState.UserSP );
+
+       SwitchTask(
+               next->SavedState.SP, &cur->SavedState.SP,
+               next->SavedState.IP, &cur->SavedState.IP,
+               next->Process->MemState.Base
+               );
+       
+}
+
+void Proc_DumpThreadCPUState(tThread *Thread)
+{
+       
+}
+
diff --git a/KernelLand/Kernel/arch/armv6/start.S b/KernelLand/Kernel/arch/armv6/start.S
new file mode 100644 (file)
index 0000000..4be9767
--- /dev/null
@@ -0,0 +1,370 @@
+
+#include "include/assembly.h"
+#include "include/options.h"
+
+@
+@ Exception defs taken from ARM DDI 0406B
+@ 
+.section .init
+interrupt_vector_table:
+ivt_reset:     b _start        @ 0x00 Reset
+ivt_undef:     b Undef_Handler @ 0x04 #UD
+ivt_svc:       b SVC_Handler   @ 0x08 SVC (used to be called SWI)
+ivt_prefetch:  b PrefetchAbort @ 0x0C Prefetch abort
+ivt_data:      b DataAbort     @ 0x10 Data abort
+ivt_unused:    b .             @ 0x14 Not Used
+ivt_irq:       b IRQHandler    @ 0x18 IRQ
+ivt_fiq:       b .             @ 0x1C FIQ (Fast interrupt)
+
+.globl _start
+_start:
+       ldr r2, =UART0_PADDR
+       mov r1, #'A'
+       str r1, [r2]    
+
+       ldr r0, =kernel_table0-KERNEL_BASE
+       mcr p15, 0, r0, c2, c0, 1       @ Set TTBR1 to r0
+       mcr p15, 0, r0, c2, c0, 0       @ Set TTBR0 to r0 too (for identity)
+
+       mov r1, #'c'
+       str r1, [r2]    
+
+       mov r0, #1
+       mcr p15, 0, r0, c2, c0, 2       @ Set TTCR to 1 (50/50 split)
+
+       mov r1, #'e'
+       str r1, [r2]    
+       
+       mov r0, #3
+       mcr p15, 0, r0, c3, c0, 0       @ Set Domain 0 to Manager
+
+       mov r1, #'s'
+       str r1, [r2]    
+
+       @ Enable VMSA
+       mrc p15, 0, r0, c1, c0, 0
+       orr r0, r0, #1
+       orr r0, r0, #1 << 23
+       mcr p15, 0, r0, c1, c0, 0
+
+       @ HACK: Set ASID to non zero
+       mov r0, #1
+       MCR p15,0,r0,c13,c0,1
+
+       ldr r2, =0xF1000000
+       mov r1, #'s'
+       str r1, [r2]    
+
+       @ Enable access faults on domains 0 & 1
+       mov r0, #0x55   @ 01010101b
+       mcr p15, 0, r0, c3, c0, 0
+
+       mov r1, #'2'
+       str r1, [r2]    
+
+       @
+       @ Check for security extensions
+       @
+       mrc p15, 0, r0, c0, c1, 1
+       and r0, #0xF0
+       @ - Present
+       ldrne r0,=KERNEL_BASE
+       mcrne p15, 0, r0, c12, c0, 0    @ Set the VBAR (brings exceptions into high memory)
+       @ - Absent
+       mrceq p15, 0, r0, c1, c0, 0     @ Set SCTLR.V
+       orreq r0, #0x2000
+       mcreq p15, 0, r0, c1, c0, 0
+
+       mov r1, #'-'
+       str r1, [r2]    
+
+       @ Prepare for interrupts
+       cps #18 @ IRQ Mode
+       ldr sp, =irqstack+0x1000        @ Set up stack
+       cps #23 @ Abort Mode
+       ldr sp, =abortstack+0x1000
+       cps #19
+
+       mov r1, #'a'
+       str r1, [r2]    
+       mov r1, #'r'
+       str r1, [r2]    
+       mov r1, #'m'
+       str r1, [r2]    
+       mov r1, #13
+       str r1, [r2]    
+       mov r1, #10
+       str r1, [r2]    
+
+.extern bss_start
+.extern bss_size_div_4
+.zero_bss:
+       ldr r0, =bss_start
+       ldr r1, =bss_end
+       mov r3, #0
+.zero_bss_loop:
+       str r3, [r0],#4
+       cmp r0, r1
+       bls .zero_bss_loop
+
+.goto_c:
+       ldr sp, =0x80000000-8   @ Set up stack (top of user range)
+       ldr r0, =kmain
+       mov pc, r0
+1:     b 1b    @ Infinite loop
+
+.comm irqstack, 0x1000 @ ; 4KiB Stack
+.comm abortstack, 0x1000       @ ; 4KiB Stack
+
+.extern SyscallHandler
+SVC_Handler:
+@      sub lr, #4
+       srsdb sp!, #19  @ Save state to stack
+       cpsie ifa, #19  @ Ensure we're in supervisor with interrupts enabled (should already be there)
+       push {r0-r12}
+
+       ldr r4, [lr,#-4]
+       mvn r5, #0xFF000000
+       and r4, r5
+
+       tst r4, #0x1000 
+       bne .arm_specifics
+
+       push {r4}
+
+       mov r0, sp
+       ldr r4, =SyscallHandler
+       blx r4
+       
+@      ldr r0, =csSyscallPrintRetAddr
+@      ldr r1, [sp,#9*4+5*4]
+@      ldr r4, =Log
+@      blx r4
+       
+       pop {r2}        @ errno
+       pop {r0,r1}     @ Ret/RetHi
+       add sp, #2*4    @ Saved r2/r3
+
+       pop {r4-r12}
+       rfeia sp!       @ Pop state (actually RFEFD)
+.arm_specifics:
+       and r4, #0xFF
+       mov r0, r4      @ Number
+       mov r1, sp      @ Arguments
+       
+       ldr r4, =ARMv7_int_HandleSyscalls
+       blx r4
+
+       add sp, #4*4
+       pop {r4-r12}
+       rfeia sp!
+
+
+.globl gpIRQHandler
+gpIRQHandler:  .long   0
+IRQ_saved_sp:  .long   0
+IRQ_saved_lr:  .long   0
+.globl IRQHandler
+IRQHandler:
+       sub lr, #4      @ Adjust LR to the correct value
+       srsdb sp!, #19  @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
+       cps #19
+
+       PUSH_GPRS
+
+@      ldr r0, =csIRQ_Tag
+@      ldr r1, =csIRQ_Fmt
+@      ldr r4, =Log_Debug
+@      blx r4
+       
+       @ Call the registered handler
+       ldr r0, gpIRQHandler
+       blx r0
+
+       @ Restore CPU state
+       POP_GPRS
+       cpsie i
+       rfeia sp!       @ Pop state (actually RFEFD)
+       bx lr
+
+.globl DataAbort
+DataAbort:
+       sub lr, #8      @ Adjust LR to the correct value
+       srsdb sp!, #23  @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
+@      cpsid ifa, #19
+       PUSH_GPRS
+
+       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
+
+       POP_GPRS
+       rfeia sp!       @ Pop state (actually RFEFD)
+
+.globl PrefetchAbort
+PrefetchAbort:
+       sub lr, #4      @ Adjust LR to the correct value
+       srsdb sp!, #23  @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
+@      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
+.globl Undef_Handler
+Undef_Handler:
+       wfi
+       b Undef_Handler
+
+.globl abort
+abort:
+       wfi
+       b abort
+
+
+.section .rodata
+csIRQ_Tag:
+csAbort_Tag:
+       .asciz "ARMv7"
+csIRQ_Fmt:
+       .asciz "IRQ"
+csDataAbort_Fmt:
+       .asciz "Data Abort - %p accessed %p, DFSR=%x Unk:%x Unk:%x"
+csPrefetchAbort_Fmt:
+       .asciz "Prefetch Abort at %p, IFSR=%x"
+csSyscallPrintRetAddr:
+       .asciz "Syscall ret to %p"
+
+.section .padata
+.globl kernel_table0
+
+kernel_table0:
+       .long 0x00000402        @ Identity map the first 1 MiB
+       .rept 0x7FC - 1
+               .long 0
+       .endr
+       .long user_table1_map + 0x000 - KERNEL_BASE + 1 @ 0x7FC00000
+       .long user_table1_map + 0x400 - KERNEL_BASE + 1 @ 0x7FD00000
+       .long user_table1_map + 0x800 - KERNEL_BASE + 1 @ KStacks
+       .long user_table1_map + 0xC00 - KERNEL_BASE + 1
+       @ 0x80000000 - User/Kernel split
+       .long 0x00000402        @ Map first 4 MiB to 2GiB (KRW only)
+       .long 0x00100402        @ 
+       .long 0x00200402        @ 
+       .long 0x00300402        @ 
+       .rept 0xF00 - 0x800 - 4
+               .long 0
+       .endr
+#if PCI_PADDR
+       .long PCI_PADDR +  0*(1 << 20) + 0x402  @ Map PCI config space
+       .long PCI_PADDR +  1*(1 << 20) + 0x402
+       .long PCI_PADDR +  2*(1 << 20) + 0x402
+       .long PCI_PADDR +  3*(1 << 20) + 0x402
+       .long PCI_PADDR +  4*(1 << 20) + 0x402
+       .long PCI_PADDR +  5*(1 << 20) + 0x402
+       .long PCI_PADDR +  6*(1 << 20) + 0x402
+       .long PCI_PADDR +  7*(1 << 20) + 0x402
+       .long PCI_PADDR +  8*(1 << 20) + 0x402
+       .long PCI_PADDR +  9*(1 << 20) + 0x402
+       .long PCI_PADDR + 10*(1 << 20) + 0x402
+       .long PCI_PADDR + 11*(1 << 20) + 0x402
+       .long PCI_PADDR + 12*(1 << 20) + 0x402
+       .long PCI_PADDR + 13*(1 << 20) + 0x402
+       .long PCI_PADDR + 14*(1 << 20) + 0x402
+       .long PCI_PADDR + 15*(1 << 20) + 0x402
+#else
+       .rept 16
+               .long 0
+       .endr
+#endif
+       .long hwmap_table_0 + 0x000 - KERNEL_BASE + 1
+       .long hwmap_table_0 + 0x400 - KERNEL_BASE + 1
+       .long hwmap_table_0 + 0x800 - KERNEL_BASE + 1
+       .long hwmap_table_0 + 0xC00 - KERNEL_BASE + 1
+       .rept 0xFF8 - 0xF00 - 16 - 4
+               .long 0
+       .endr
+       @ Page fractals
+       .long kernel_table1_map + 0x000 - KERNEL_BASE + 1
+       .long kernel_table1_map + 0x400 - KERNEL_BASE + 1
+       .long kernel_table1_map + 0x800 - KERNEL_BASE + 1
+       .long kernel_table1_map + 0xC00 - KERNEL_BASE + 1
+       .long kernel_exception_map + 0x000 - KERNEL_BASE + 1
+       .long kernel_exception_map + 0x400 - KERNEL_BASE + 1
+       .long kernel_exception_map + 0x800 - KERNEL_BASE + 1
+       .long kernel_exception_map + 0xC00 - KERNEL_BASE + 1
+
+@ PID0 user table
+.globl user_table1_map
+@ User table1 data table (only the first half is needed)
+@ - Abused to provide kernel stacks in the unused half of the table
+user_table1_map:       @ Size = 4KiB (only 2KiB used)
+       .rept 0x800/4-1
+               .long 0
+       .endr
+       .long user_table1_map - KERNEL_BASE + 0x13      @ ...1FF000 = 0x7FDFF000
+       @ Kernel stack zone
+       .long kernel_table0 + 0x0000 - KERNEL_BASE + 0x13       @ ...200000 = 0x7FE00000
+       .long kernel_table0 + 0x1000 - KERNEL_BASE + 0x13       @ ...201000 = 0x7FE01000
+       .rept (0x800/4)-(MM_KSTACK_SIZE/0x1000)-2
+               .long 0
+       .endr
+       #if MM_KSTACK_SIZE != 0x2000
+       #error Kernel stack size not changed in start.S
+       #endif
+       .long stack + 0x0000 - KERNEL_BASE + 0x13       @ Kernel Stack
+       .long stack + 0x1000 - KERNEL_BASE + 0x13       @ 
+
+.globl kernel_table1_map
+kernel_table1_map:     @ Size = 4KiB
+       .rept (0xF00+16)/4
+               .long 0
+       .endr
+       .long hwmap_table_0 - KERNEL_BASE + 0x13
+       .rept 0xFF8/4 - (0xF00+16)/4 - 1
+               .long 0
+       .endr
+       .long kernel_table1_map - KERNEL_BASE + 0x13
+       .long kernel_exception_map - KERNEL_BASE + 0x13
+
+@ Hardware mappings 
+.globl hwmap_table_0
+hwmap_table_0:
+       .long UART0_PADDR + 0x13        @ UART0
+       .rept 1024 - 1
+               .long 0
+       .endr
+.globl kernel_exception_map
+kernel_exception_map:
+       @ Padding
+       .rept 1024-256
+               .long 0
+       .endr
+       @ Align to nearly the end
+       .rept 256-16
+               .long   0
+       .endr
+       .long 0x212     @ Map first page for exceptions (Kernel RO, Execute)
+       .rept 16-1-2
+               .long 0
+       .endr
+       .long gUsertextPhysStart + 0x22 @ User .text (User RO, Kernel RW, because both is COW)
+       .long 0
+       
+.section .padata
+stack:
+       .space MM_KSTACK_SIZE, 0        @ Original kernel stack
+
+// vim: ts=8 ft=armv7
+
diff --git a/KernelLand/Kernel/arch/armv6/time.c b/KernelLand/Kernel/arch/armv6/time.c
new file mode 100644 (file)
index 0000000..d4ae4fa
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Acess2
+ *
+ * ARM7 Time code
+ * arch/arm7/time.c
+ */
+#include <acess.h>
+
+// === GLOBALS ===
+tTime  giTimestamp;
+
+// === CODE ===
+tTime now(void)
+{
+       return giTimestamp;
+}
index c83a5af..c3223d0 100644 (file)
@@ -20,7 +20,7 @@ endif
 ASFLAGS += -D USE_MP=$(USE_MP)
 CPPFLAGS += -DUSE_MP=$(USE_MP)
 
-A_OBJ  = start.ao main.o lib.o desctab.ao errors.o irq.o
+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
index b6ac974..af9007d 100644 (file)
@@ -30,18 +30,12 @@ extern int  Time_Setup(void);
 
 // === GLOBALS ===
 char   *gsBootCmdLine = NULL;
-struct {
-       Uint32  PBase;
-       void    *Base;
-       Uint    Size;
-       char    *ArgString;
-}      *gaArch_BootModules;
+tBootModule    *gaArch_BootModules;
  int   giArch_NumBootModules = 0;
 
 // === CODE ===
 int kmain(Uint MbMagic, void *MbInfoPtr)
 {
-       tMBoot_Module   *mods;
        tMBoot_Info     *mbInfo;
        tPMemMapEnt     pmemmap[MAX_PMEMMAP_ENTS];
         int    nPMemMapEnts;
@@ -58,61 +52,13 @@ int kmain(Uint MbMagic, void *MbInfoPtr)
        case MULTIBOOT_MAGIC: {
                // TODO: Handle when this isn't in the mapped area
                gsBootCmdLine = (char*)(mbInfo->CommandLine + KERNEL_BASE);
-               
-               tMBoot_MMapEnt  *ent = (void*)mbInfo->MMapAddr;
-               tMBoot_MMapEnt  *last = (void*)(mbInfo->MMapAddr + mbInfo->MMapLength);
-               
-               // Build up memory map
-               nPMemMapEnts = 0;
-               while( ent < last && nPMemMapEnts < MAX_PMEMMAP_ENTS )
-               {
-                       tPMemMapEnt     *nent = &pmemmap[nPMemMapEnts];
-                       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 );
-               }
-
-               // Ensure it's valid
-               nPMemMapEnts = PMemMap_ValidateMap(pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS);
-               // TODO: Error handling
-
-               // Replace kernel with PMEMTYPE_USED
-               nPMemMapEnts = PMemMap_MarkRangeUsed(
-                       pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS,
-                       KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_LOAD - KERNEL_BASE
-                       );
-
-               // Replace modules with PMEMTYPE_USED
-               nPMemMapEnts = PMemMap_MarkRangeUsed(pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS,
-                       mbInfo->Modules, mbInfo->ModuleCount*sizeof(*mods)
-                       );
-               mods = (void*)mbInfo->Modules;
-               for( int i = 0; i < mbInfo->ModuleCount; i ++ )
-               {
-                       nPMemMapEnts = PMemMap_MarkRangeUsed(
-                               pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS,
-                               mods->Start, mods->End - mods->Start
-                               );
-               }
-               
-               // Debug - Output map
-               PMemMap_DumpBlocks(pmemmap, nPMemMapEnts);
 
                // Adjust Multiboot structure address
                mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE );
-               
+
+               nPMemMapEnts = Multiboot_LoadMemoryMap(mbInfo, KERNEL_BASE, pmemmap, MAX_PMEMMAP_ENTS,
+                       KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_BASE);
+
                break; }
        
        // Multiboot 2
@@ -145,36 +91,7 @@ int kmain(Uint MbMagic, void *MbInfoPtr)
        VFS_Init();
        
        // Load initial modules
-       mods = (void*)( mbInfo->Modules + KERNEL_BASE );
-       giArch_NumBootModules = mbInfo->ModuleCount;
-       gaArch_BootModules = malloc( giArch_NumBootModules * sizeof(*gaArch_BootModules) );
-       for( int i = 0; i < mbInfo->ModuleCount; i ++ )
-       {
-                int    ofs;
-       
-               Log_Log("Arch", "Multiboot Module at 0x%08x, 0x%08x bytes (String at 0x%08x)",
-                       mods[i].Start, mods[i].End-mods[i].Start, mods[i].String);
-       
-               gaArch_BootModules[i].PBase = mods[i].Start;
-               gaArch_BootModules[i].Size = mods[i].End - mods[i].Start;
-       
-               // Always HW map the module data        
-               ofs = mods[i].Start&0xFFF;
-               gaArch_BootModules[i].Base = (void*)( MM_MapHWPages(mods[i].Start,
-                       (gaArch_BootModules[i].Size+ofs+0xFFF) / 0x1000
-                       ) + ofs );
-               
-               // Only map the string if needed
-               if( (tVAddr)mods[i].String > MAX_ARGSTR_POS )
-               {
-                       // Assumes the string is < 4096 bytes long)
-                       gaArch_BootModules[i].ArgString = (void*)(
-                               MM_MapHWPages(mods[i].String, 2) + (mods[i].String&0xFFF)
-                               );
-               }
-               else
-                       gaArch_BootModules[i].ArgString = (char *)mods[i].String + KERNEL_BASE;
-       }
+       gaArch_BootModules = Multiboot_LoadModules(mbInfo, KERNEL_BASE, &giArch_NumBootModules);
        
        // Pass on to Independent Loader
        Log_Log("Arch", "Starting system");
@@ -193,7 +110,9 @@ void Arch_LoadBootModules(void)
        {
                Log_Log("Arch", "Loading '%s'", gaArch_BootModules[i].ArgString);
                
-               if( !Module_LoadMem( gaArch_BootModules[i].Base, gaArch_BootModules[i].Size, 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");
                }
@@ -209,5 +128,6 @@ void Arch_LoadBootModules(void)
                        MM_UnmapHWPages( (tVAddr)gaArch_BootModules[i].ArgString, 2 );
        }
        Log_Log("Arch", "Boot modules loaded");
-       free( gaArch_BootModules );
+       if( gaArch_BootModules )
+               free( gaArch_BootModules );
 }
diff --git a/KernelLand/Kernel/arch/x86/mboot.c b/KernelLand/Kernel/arch/x86/mboot.c
new file mode 100644 (file)
index 0000000..5fe4068
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Acess2 Kernel x86 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * mboot.c
+ * - Multiboot Support
+ */
+#define DEBUG  0
+#include <acess.h>
+#include <mboot.h>
+
+// === CODE ===
+int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *Map, const int MapSize, tPAddr KStart, tPAddr KEnd)
+{
+        int    nPMemMapEnts = 0;
+       tMBoot_MMapEnt  *ent = (void*)((tVAddr)MBInfo->MMapAddr + MapOffset);
+       tMBoot_MMapEnt  *last = (void*)((tVAddr)ent + MBInfo->MMapLength);
+       
+       ENTER("pMBInfo pMapOffset pMap iMapSize PKStart PKEnd",
+               MBInfo, MapOffset, Map, MapSize, KStart, KEnd);
+
+       // Build up memory map
+       nPMemMapEnts = 0;
+       while( ent < last && nPMemMapEnts < MapSize )
+       {
+               tPMemMapEnt     *nent = &Map[nPMemMapEnts];
+               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 );
+       }
+
+       // Ensure it's valid
+       nPMemMapEnts = PMemMap_ValidateMap(Map, nPMemMapEnts, MapSize);
+       // TODO: Error handling
+
+       // Replace kernel with PMEMTYPE_USED
+       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 ++ )
+       {
+               nPMemMapEnts = PMemMap_MarkRangeUsed(
+                       Map, nPMemMapEnts, MapSize,
+                       mods->Start, mods->End - mods->Start
+                       );
+       }
+       
+       // Debug - Output map
+       PMemMap_DumpBlocks(Map, nPMemMapEnts);
+
+       LEAVE('i', nPMemMapEnts);
+       return nPMemMapEnts;
+}
+
+tBootModule *Multiboot_LoadModules(tMBoot_Info *MBInfo, tVAddr MapOffset, int *ModuleCount)
+{
+       tMBoot_Module   *mods = (void*)( MBInfo->Modules + MapOffset );
+       *ModuleCount = MBInfo->ModuleCount;
+       tBootModule *ret = malloc( MBInfo->ModuleCount * sizeof(*ret) );
+       for( int i = 0; i < MBInfo->ModuleCount; i ++ )
+       {
+                int    ofs;
+       
+               Log_Log("Arch", "Multiboot Module at 0x%08x, 0x%08x bytes (String at 0x%08x)",
+                       mods[i].Start, mods[i].End-mods[i].Start, mods[i].String);
+       
+               ret[i].PBase = mods[i].Start;
+               ret[i].Size = mods[i].End - mods[i].Start;
+       
+               // Always HW map the module data        
+               ofs = mods[i].Start&0xFFF;
+               ret[i].Base = (void*)( MM_MapHWPages(mods[i].Start,
+                       (ret[i].Size+ofs+0xFFF) / 0x1000
+                       ) + ofs );
+               
+               // Only map the string if needed
+               if( !MM_GetPhysAddr( (void*)(mods[i].String + MapOffset) ) )
+               {
+                       // Assumes the string is < 4096 bytes long)
+                       ret[i].ArgString = (void*)(
+                               MM_MapHWPages(mods[i].String, 2) + (mods[i].String&0xFFF)
+                               );
+               }
+               else
+                       ret[i].ArgString = (char*)(tVAddr)mods[i].String + MapOffset;
+       }
+
+       return ret;
+}
+
index b0f1c61..f785ba4 100644 (file)
@@ -152,7 +152,6 @@ void MM_DumpStatistics(void)
  */
 tPAddr MM_AllocPhys(void)
 {
-       // int  a, b, c;
         int    indx = -1;
        tPAddr  ret;
        
@@ -161,7 +160,6 @@ tPAddr MM_AllocPhys(void)
        Mutex_Acquire( &glPhysAlloc );
        
        // Classful scan
-       #if 1
        {
         int    i;
         int    first, last;
@@ -202,52 +200,6 @@ tPAddr MM_AllocPhys(void)
        // Out of memory?
        if( i <= 1 )    indx = -1;
        }
-       #elif 0
-       // Find free page
-       // Scan downwards
-       LOG("giLastPossibleFree = %i", giLastPossibleFree);
-       for( indx = giLastPossibleFree; indx >= 0; )
-       {
-               if( gaSuperBitmap[indx>>10] == -1 ) {
-                       indx -= 1024;
-                       continue;
-               }
-               
-               if( gaPageBitmap[indx>>5] == -1 ) {
-                       indx -= 32;
-                       continue;
-               }
-               
-               if( gaPageBitmap[indx>>5] & (1 << (indx&31)) ) {
-                       indx --;
-                       continue;
-               }
-               break;
-       }
-       if( indx >= 0 )
-               giLastPossibleFree = indx;
-       LOG("indx = %i", indx);
-       #else
-       c = giLastPossibleFree % 32;
-       b = (giLastPossibleFree / 32) % 32;
-       a = giLastPossibleFree / 1024;
-       
-       LOG("a=%i,b=%i,c=%i", a, b, c);
-       for( ; gaSuperBitmap[a] == -1 && a >= 0; a-- );
-       if(a < 0) {
-               Mutex_Release( &glPhysAlloc );
-               Warning("MM_AllocPhys - OUT OF MEMORY (Called by %p) - %lli/%lli used",
-                       __builtin_return_address(0), giPhysAlloc, giPageCount);
-               LEAVE('i', 0);
-               return 0;
-       }
-       for( ; gaSuperBitmap[a] & (1<<b); b-- );
-       for( ; gaPageBitmap[a*32+b] & (1<<c); c-- );
-       LOG("a=%i,b=%i,c=%i", a, b, c);
-       indx = (a << 10) | (b << 5) | c;
-       if( indx >= 0 )
-               giLastPossibleFree = indx;
-       #endif
        
        if( indx < 0 ) {
                Mutex_Release( &glPhysAlloc );
@@ -330,29 +282,6 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits)
        idx = sidx / 32;
        sidx %= 32;
        
-       #if 0
-       LOG("a=%i, b=%i, idx=%i, sidx=%i", a, b, idx, sidx);
-       
-       // Find free page
-       for( ; gaSuperBitmap[a] == -1 && a --; )        b = 31;
-       if(a < 0) {
-               Mutex_Release( &glPhysAlloc );
-               Warning("MM_AllocPhysRange - OUT OF MEMORY (Called by %p)", __builtin_return_address(0));
-               LEAVE('i', 0);
-               return 0;
-       }
-       LOG("a = %i", a);
-       for( ; gaSuperBitmap[a] & (1 << b); b-- )       sidx = 31;
-       LOG("b = %i", b);
-       idx = a * 32 + b;
-       for( ; gaPageBitmap[idx] & (1 << sidx); sidx-- )
-               LOG("gaPageBitmap[%i] = 0x%08x", idx, gaPageBitmap[idx]);
-       
-       LOG("idx = %i, sidx = %i", idx, sidx);
-       #else
-       
-       #endif
-       
        // Check if the gap is large enough
        while( idx >= 0 )
        {
index a72216a..4c030a5 100644 (file)
@@ -27,6 +27,7 @@ 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 += ../x86/mboot.o
 # rme.o
 
 POSTBUILD = objcopy $(BIN) -F elf32-i386 $(BIN)
index f7da7f9..e7812c3 100644 (file)
@@ -134,14 +134,14 @@ void Error_Backtrace(Uint IP, Uint BP)
                LogF("Backtrace: %p", IP);
        //else
        //      LogF("Backtrace: %s+0x%x", str, delta);
-       if( !MM_GetPhysAddr(BP) )
+       if( !MM_GetPhysAddr( (void*)BP ) )
        {
                LogF("\nBacktrace: Invalid BP, stopping\n");
                return;
        }
        
        
-       while( MM_GetPhysAddr(BP) && MM_GetPhysAddr(BP+8+7) && i < MAX_BACKTRACE )
+       while( MM_GetPhysAddr( (void*)BP) && MM_GetPhysAddr((void*)(BP+8+7)) && i < MAX_BACKTRACE )
        {
                //str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta);
                //if(str == NULL)
diff --git a/KernelLand/Kernel/arch/x86_64/include/archinit.h b/KernelLand/Kernel/arch/x86_64/include/archinit.h
new file mode 100644 (file)
index 0000000..68988b8
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Acess2 Kernel x86_64
+ * - By John Hodge (thePowersGang)
+ *
+ * include/init.h
+ * - Arch-internal init functions
+ */
+#ifndef _ARCH__INIT_H_
+#define _ARCH__INIT_H_
+
+#include <pmemmap.h>
+
+extern void    MM_InitPhys(int NPMemRanges, tPMemMapEnt *PMemRanges);
+
+#endif
+
index 49fe7ae..8defcc5 100644 (file)
@@ -12,7 +12,8 @@ OUTPUT_FORMAT(elf32-i386)
 OUTPUT_ARCH(i386:x86-64)
 */
 OUTPUT_FORMAT(elf64-x86-64)
-ENTRY(start)
+lstart = start - _kernel_base;
+ENTRY(lstart)
 
 SECTIONS {
        . = 0x100000;
index 3532c80..0348de6 100644 (file)
@@ -1,19 +1,27 @@
 /*
- * Acess2 x86_64 Project
+ * Acess2 Kernel x86_64
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Kernel C entrypoint
  */
 #include <acess.h>
 #include <mboot.h>
 #include <init.h>
+#include <archinit.h>
+#include <pmemmap.h>
+
+// === CONSTANTS ===
+#define KERNEL_LOAD    0x100000
+#define MAX_PMEMMAP_ENTS       16
 
 // === IMPORTS ===
 extern void    Desctab_Init(void);
 extern void    MM_InitVirt(void);
 extern void    Heap_Install(void);
-extern void    Threads_Init(void);
 extern int     Time_Setup(void);
-extern void    System_Init(char *Commandline);
 
-extern void    MM_InitPhys_Multiboot(tMBoot_Info *MBoot);
+extern char    gKernelEnd[];
 
 // === PROTOTYPES ===
 void   kmain(Uint MbMagic, void *MbInfoPtr);
@@ -25,9 +33,10 @@ char *gsBootCmdLine = NULL;
 void kmain(Uint MbMagic, void *MbInfoPtr)
 {
        tMBoot_Info     *mbInfo;
+       tPMemMapEnt     pmemmap[MAX_PMEMMAP_ENTS];
+        int    nPMemMapEnts;
 
-       LogF("Acess2 x86_64 v"EXPAND_STR(KERNEL_VERSION)"\n");
-       LogF(" Build %i, Git Hash %s\n", BUILD_NUM, gsGitHash);
+       LogF("%s\r\n", gsBuildInfo);
        
        Desctab_Init();
 
@@ -41,7 +50,9 @@ void kmain(Uint MbMagic, void *MbInfoPtr)
                // Adjust Multiboot structure address
                mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE );
                gsBootCmdLine = (char*)( (Uint)mbInfo->CommandLine + KERNEL_BASE);
-               MM_InitPhys_Multiboot( mbInfo );        // Set up physical memory manager
+               nPMemMapEnts = Multiboot_LoadMemoryMap(mbInfo, KERNEL_BASE, pmemmap, MAX_PMEMMAP_ENTS,
+                       KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_BASE
+                       );
                break;
        default:
                Panic("Multiboot magic invalid %08x, expected %08x\n",
@@ -49,6 +60,7 @@ void kmain(Uint MbMagic, void *MbInfoPtr)
                return ;
        }
        
+       MM_InitPhys( nPMemMapEnts, pmemmap );   // Set up physical memory manager
        Log("gsBootCmdLine = '%s'", gsBootCmdLine);
        
        *(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'D';
index 274b21c..27c4946 100644 (file)
@@ -5,7 +5,8 @@
  */
 #define DEBUG  0
 #include <acess.h>
-#include <mboot.h>
+#include <archinit.h>
+#include <pmemmap.h>
 #include <mm_virt.h>
 
 #define TRACE_REF      0
@@ -25,7 +26,7 @@ extern char   gKernelBase[];
 extern char    gKernelEnd[];
 
 // === PROTOTYPES ===
-void   MM_InitPhys_Multiboot(tMBoot_Info *MBoot);
+//void MM_InitPhys(int NPMemRanges, tPMemMapEnt *PMemRanges);
 //tPAddr       MM_AllocPhysRange(int Num, int Bits);
 //tPAddr       MM_AllocPhys(void);
 //void MM_RefPhys(tPAddr PAddr);
@@ -52,6 +53,7 @@ Uint64        giPhysRangeFree[NUM_MM_PHYS_RANGES];    // Number of free pages in each rang
 Uint64 giPhysRangeFirst[NUM_MM_PHYS_RANGES];   // First free page in each range
 Uint64 giPhysRangeLast[NUM_MM_PHYS_RANGES];    // Last free page in each range
 Uint64 giMaxPhysPage = 0;      // Maximum Physical page
+Uint64 giTotalMemorySize = 0;
 // Only used in init, allows the init code to provide pages for use by
 // the allocator before the bitmaps exist.
 // 3 entries because the are three calls to MM_AllocPhys in MM_Map
@@ -62,10 +64,8 @@ tPAddr       gaiStaticAllocPages[NUM_STATIC_ALLOC] = {0};
 /**
  * \brief Initialise the physical memory map using a Multiboot 1 map
  */
-void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
+void MM_InitPhys(int NPMemRanges, tPMemMapEnt *PMemRanges)
 {
-       tMBoot_MMapEnt  *mmapStart;
-       tMBoot_MMapEnt  *ent;
        Uint64  maxAddr = 0;
         int    numPages, superPages;
         int    i;
@@ -73,226 +73,165 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
        tVAddr  vaddr;
        tPAddr  paddr, firstFreePage;
        
-       ENTER("pMBoot=%p", MBoot);
+       ENTER("iNPMemRanges pPMemRanges",
+               NPMemRanges, PMemRanges);
        
        // Scan the physical memory map
        // Looking for the top of physical memory
-       mmapStart = (void *)( KERNEL_BASE | MBoot->MMapAddr );
-       LOG("mmapStart = %p", mmapStart);
-       ent = mmapStart;
-       while( (Uint)ent < (Uint)mmapStart + MBoot->MMapLength )
+       for( i = 0; i < NPMemRanges; i ++ )
        {
+               tPMemMapEnt     *ent = &PMemRanges[i];
                // Adjust for the size of the entry
-               ent->Size += 4;
-               LOG("ent={Type:%i,Base:0x%x,Length:%x",
-                       ent->Type, ent->Base, ent->Length);
+               LOG("%i: ent={Type:%i,Base:0x%x,Length:%x}", i, ent->Type, ent->Start, ent->Length);
                
                // If entry is RAM and is above `maxAddr`, change `maxAddr`
-               if(ent->Type == 1 && ent->Base + ent->Length > maxAddr)
-                       maxAddr = ent->Base + ent->Length;
-               
-               // Go to next entry
-               ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size );
+               if(ent->Type == PMEMTYPE_FREE || ent->Type == PMEMTYPE_USED )
+               {
+                       if( ent->Start + ent->Length > maxAddr)
+                               maxAddr = ent->Start + ent->Length;
+                       giTotalMemorySize += ent->Length >> 12;
+               }
        }
        
-       // Did we find a valid end?
-       if(maxAddr == 0) {
-               // No, darn, let's just use the HighMem hack
-               giMaxPhysPage = (MBoot->HighMem >> 2) + 256;    // HighMem is a kByte value
-       }
-       else {
-               // Goodie, goodie gumdrops
-               giMaxPhysPage = maxAddr >> 12;
-       }
+       giMaxPhysPage = maxAddr >> 12;
        LOG("giMaxPhysPage = 0x%x", giMaxPhysPage);
-       
-       // Find a contigous section of memory to hold it in
-       // - Starting from the end of the kernel
-       // - We also need a region for the super bitmap
+
+       // Get counts of pages needed for basic structures
        superPages = ((giMaxPhysPage+64*8-1)/(64*8) + 0xFFF) >> 12;
-       numPages = (giMaxPhysPage + 7) / 8;
-       numPages = (numPages + 0xFFF) >> 12;
+       numPages = ((giMaxPhysPage+7)/8 + 0xFFF) >> 12; // bytes to hold bitmap, divided up to nearest page
        LOG("numPages = %i, superPages = %i", numPages, superPages);
-       if(maxAddr == 0)
+       
+       // --- Allocate Bitmaps ---
+        int    todo = numPages*2 + superPages;
+        int    mapent = NPMemRanges-1;
+       vaddr = MM_PAGE_BITMAP;
+       paddr = -1;
+       while( todo )
        {
-                int    todo = numPages*2 + superPages;
-               // Ok, naieve allocation, just put it after the kernel
-               // - Allocated Bitmap
-               vaddr = MM_PAGE_BITMAP;
-               paddr = (tPAddr)&gKernelEnd - KERNEL_BASE;
-               while(todo )
+               while(PMemRanges[mapent].Type != PMEMTYPE_FREE && mapent != -1)
+                       mapent --;
+               if( paddr + 1 == 0 )
+                       paddr = PMemRanges[mapent].Start;
+               if( mapent == -1 ) {
+                       // OOM During init, bad thing
+                       Log_KernelPanic("PMem", "Out of memory during init");
+                       for(;;);
+               }
+               
+               // Ensure that the static allocation pool has pages
+               for( i = 0; i < NUM_STATIC_ALLOC; i++)
                {
-                       // Allocate statics
-                       for( i = 0; i < NUM_STATIC_ALLOC; i++) {
-                               if(gaiStaticAllocPages[i] != 0) continue;
+                       if(gaiStaticAllocPages[i] == 0)
+                       {
                                gaiStaticAllocPages[i] = paddr;
-                               paddr += 0x1000;
+                               // break to ensure we update the address correctly
+                               break;
                        }
-                       
+               }
+               
+               if( i == NUM_STATIC_ALLOC )
+               {
+                       // Map
                        MM_Map(vaddr, paddr);
-                       vaddr += 0x1000;
-                       paddr += 0x1000;
-                       
                        todo --;
                        
+                       // Update virtual pointer
+                       vaddr += 0x1000;
                        if( todo == numPages + superPages )
                                vaddr = MM_PAGE_DBLBMP;
                        if( todo == superPages )
                                vaddr = MM_PAGE_SUPBMP;
+               }               
+
+               // Update physical pointer
+               // (underflows are detected at the top of the loop)
+               paddr += 0x1000;
+               if( paddr - PMemRanges[mapent].Start > PMemRanges[mapent].Length )
+                       mapent --;
+               else {
+                       // NOTE: This hides some actually valid memory, but since the pmm
+                       // structures have an "infinite" lifetime, this is of no concequence.
+                       PMemRanges[mapent].Start += 0x1000;
+                       PMemRanges[mapent].Length -= 0x1000;
                }
        }
-       // Scan for a nice range
-       else
-       {
-                int    todo = numPages*2 + superPages;
-               paddr = 0;
-               vaddr = MM_PAGE_BITMAP;
-               // Scan!
-               for(
-                       ent = mmapStart;
-                       (Uint)ent < (Uint)mmapStart + MBoot->MMapLength;
-                       ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size )
-                       )
-               {
-                        int    avail;
-                       
-                       // RAM only please
-                       if( ent->Type != 1 )
-                               continue;
-                       
-                       // Let's not put it below the kernel, shall we?
-                       if( ent->Base + ent->Size < (tPAddr)&gKernelBase )
-                               continue;
-                       
-                       LOG("%x <= %x && %x > %x",
-                               ent->Base, (tPAddr)&gKernelBase,
-                               ent->Base + ent->Size, (tPAddr)&gKernelEnd - KERNEL_BASE
-                               );
-                       // Check if the kernel is in this range
-                       if( ent->Base <= (tPAddr)&gKernelBase
-                       && ent->Base + ent->Length > (tPAddr)&gKernelEnd - KERNEL_BASE )
-                       {
-                               avail = ent->Length >> 12;
-                               avail -= ((tPAddr)&gKernelEnd - KERNEL_BASE - ent->Base) >> 12;
-                               paddr = (tPAddr)&gKernelEnd - KERNEL_BASE;
-                       }
-                       // No? then we can use all of the block
-                       else
-                       {
-                               avail = ent->Length >> 12;
-                               paddr = ent->Base;
-                       }
-                       
-                       Log("MM_InitPhys_Multiboot: paddr=0x%x, avail=0x%x pg", paddr, avail);
-                       
-                       // Map
-                       while( todo && avail --)
-                       {
-                               // Static Allocations
-                               for( i = 0; i < NUM_STATIC_ALLOC && avail; i++) {
-                                       if(gaiStaticAllocPages[i] != 0) continue;
-                                       gaiStaticAllocPages[i] = paddr;
-                                       paddr += 0x1000;
-                                       avail --;
-                               }
-                               if(!avail)      break;
-                               
-                               // Map
-                               MM_Map(vaddr, paddr);
-                               todo --;
-                               vaddr += 0x1000;
-                               paddr += 0x1000;
-                               
-                               // Alter the destination address when needed
-                               if(todo == superPages+numPages)
-                                       vaddr = MM_PAGE_DBLBMP;
-                               if(todo == superPages)
-                                       vaddr = MM_PAGE_SUPBMP;
-                       }
-                       
-                       // Fast quit if there's nothing left to allocate
-                       if( !todo )             break;
-               }
-       }
+
+       PMemMap_DumpBlocks(PMemRanges, NPMemRanges);
+
        // Save the current value of paddr to simplify the allocation later
        firstFreePage = paddr;
        
        LOG("Clearing multi bitmap");
-       // Fill the bitmaps
-       memset(gaMultiBitmap, 0, (numPages<<12)/8);
-       // - initialise to one, then clear the avaliable areas
-       memset(gaMainBitmap, -1, (numPages<<12)/8);
-       memset(gaSuperBitmap, -1, (numPages<<12)/(8*64));
-       LOG("Setting main bitmap");
+       // Fill the bitmaps (set most to "allocated")
+       memset(gaMultiBitmap, 0, numPages<<12);
+       memset(gaMainBitmap,  255, numPages<<12);
        // - Clear all Type=1 areas
        LOG("Clearing valid regions");
-       for(
-               ent = mmapStart;
-               (Uint)ent < (Uint)mmapStart + MBoot->MMapLength;
-               ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size )
-               )
+       for( i = 0; i < NPMemRanges; i ++ )
        {
+               tPMemMapEnt *ent = &PMemRanges[i];
                // Check if the type is RAM
-               if(ent->Type != 1)      continue;
+               if(ent->Type != PMEMTYPE_FREE)  continue;
                
                // Main bitmap
-               base = ent->Base >> 12;
-               size = ent->Size >> 12;
-               
-               if(base & 63) {
-                       Uint64  val = -1LL << (base & 63);
-                       gaMainBitmap[base / 64] &= ~val;
-                       size -= (base & 63);
-                       base += 64 - (base & 63);
-               }
-               memset( &gaMainBitmap[base / 64], 0, size/8 );
-               if( size & 7 ) {
-                       Uint64  val = -1LL << (size & 7);
-                       val <<= (size/8)&7;
-                       gaMainBitmap[base / 64] &= ~val;
+               base = ent->Start >> 12;
+               size = ent->Length >> 12;
+
+               LOG("%i: base=%x, size=%x", i, base, size);
+               if( base % 64 + size < 64 )
+               {
+                       Uint64  bits = (1ULL << size) - 1;
+                       bits <<= base % 64;
+                       gaMainBitmap[base / 64] &= ~bits;
                }
-               
-               // Super Bitmap
-               base = ent->Base >> 12;
-               size = ent->Size >> 12;
-               size = (size + (base & 63) + 63) >> 6;
-               base = base >> 6;
-               if(base & 63) {
-                       Uint64  val = -1LL << (base & 63);
-                       gaSuperBitmap[base / 64] &= ~val;
-//                     size -= (base & 63);
-//                     base += 64 - (base & 63);
+               else
+               {
+                       if(base & 63)
+                       {
+                               // Keep lower bits
+                               Uint64  bits = (1ULL << (base & 63)) - 1;
+                               gaMainBitmap[base / 64] &= bits;
+                               
+                               size -= 64 - base % 64;
+                               base += 64 - base % 64;
+                       }
+                       LOG("%i: base=%x, size=%x", i, base, size);
+                       memset( &gaMainBitmap[base / 64], 0, (size/64)*8 );
+                       base += size & ~(64-1);
+                       size -= size & ~(64-1);
+                       LOG("%i: base=%x, size=%x", i, base, size);
+                       if( size & 63 )
+                       {
+                               // Unset lower bits (hence the bitwise not)
+                               Uint64  val = (1ULL << (size & 63)) - 1;
+                               gaMainBitmap[base / 64] &= ~val;
+                       }
                }
        }
        
-       // Reference the used pages
-       base = (tPAddr)&gKernelBase >> 12;
-       size = firstFreePage >> 12;
-       memset( &gaMainBitmap[base / 64], -1, size/8 );
-       if( size & 7 ) {
-               Uint64  val = -1LL << (size & 7);
-               val <<= (size/8)&7;
-               gaMainBitmap[base / 64] |= val;
-       }
-       
        // Free the unused static allocs
-       for( i = 0; i < NUM_STATIC_ALLOC; i++) {
-               if(gaiStaticAllocPages[i] != 0)
-                       continue;
-               gaMainBitmap[ gaiStaticAllocPages[i] >> (12+6) ]
-                       &= ~(1LL << ((gaiStaticAllocPages[i]>>12)&63));
+       LOG("Freeing unused static allocations");
+       for( i = 0; i < NUM_STATIC_ALLOC; i++)
+       {
+               if(gaiStaticAllocPages[i] == 0)
+               {
+                       gaMainBitmap[ gaiStaticAllocPages[i] >> (12+6) ]
+                               &= ~(1LL << ((gaiStaticAllocPages[i]>>12)&63));
+                       gaiStaticAllocPages[i] = 0;
+               }
        }
        
        // Fill the super bitmap
        LOG("Filling super bitmap");
        memset(gaSuperBitmap, 0, superPages<<12);
-       for( base = 0; base < (size+63)/64; base ++)
+       int nsuperbits = giMaxPhysPage / 64;    // 64 pages per bit
+       for( i = 0; i < (nsuperbits+63)/64; i ++)
        {
-               if( gaMainBitmap[ base ] + 1 == 0 )
-                       gaSuperBitmap[ base/64 ] |= 1LL << (base&63);
+               if( gaMainBitmap[ i ] + 1 == 0 )
+                       gaSuperBitmap[ i/64 ] |= 1ULL << (i % 64);
        }
        
-       // Set free page counts
+       // Set free page counts for each address class
        for( base = 1; base < giMaxPhysPage; base ++ )
        {
                 int    rangeID;
@@ -311,8 +250,8 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
                // Set last (when the last free page is reached, this won't be
                // updated anymore, hence will be correct)
                giPhysRangeLast[ rangeID ] = base;
-       }
-       
+       }       
+
        LEAVE('-');
 }
 
@@ -440,7 +379,7 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits)
        for( i = 0; i < Pages; i++, addr++ )
        {
                gaMainBitmap[addr >> 6] |= 1LL << (addr & 63);
-               if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[addr] ) )
+               if( MM_GetPhysAddr( &gaiPageReferences[addr] ) )
                        gaiPageReferences[addr] = 1;
 //             Log("page %P refcount = %i", MM_GetRefCount(addr<<12)); 
                rangeID = MM_int_GetRangeID(addr << 12);
@@ -504,7 +443,7 @@ void MM_RefPhys(tPAddr PAddr)
        {
                tVAddr  ref_base = ((tVAddr)&gaiPageReferences[ page ]) & ~0xFFF;
                // Allocate reference page
-               if( !MM_GetPhysAddr(ref_base) )
+               if( !MM_GetPhysAddr(&gaiPageReferences[page]) )
                {
                        const int       pages_per_refpage = PAGE_SIZE/sizeof(gaiPageReferences[0]);
                         int    i;
@@ -528,7 +467,7 @@ void MM_RefPhys(tPAddr PAddr)
                PAGE_ALLOC_SET(page);
                if( gaMainBitmap[page >> 6] + 1 == 0 )
                        gaSuperBitmap[page>> 12] |= 1LL << ((page >> 6) & 63);
-               if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[page] ) )
+               if( MM_GetPhysAddr( &gaiPageReferences[page] ) )
                        gaiPageReferences[page] = 1;
        }
 
@@ -546,7 +485,7 @@ void MM_DerefPhys(tPAddr PAddr)
        
        if( PAddr >> 12 > giMaxPhysPage )       return ;
        
-       if( MM_GetPhysAddr( (tVAddr) &gaiPageReferences[page] ) )
+       if( MM_GetPhysAddr( &gaiPageReferences[page] ) )
        {
                gaiPageReferences[ page ] --;
                if( gaiPageReferences[ page ] == 0 )
@@ -583,7 +522,7 @@ int MM_GetRefCount( tPAddr PAddr )
        
        if( PAddr > giMaxPhysPage )     return 0;
 
-       if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[PAddr] ) ) {
+       if( MM_GetPhysAddr( &gaiPageReferences[PAddr] ) ) {
                return gaiPageReferences[PAddr];
        }
 
@@ -620,7 +559,7 @@ int MM_SetPageNode(tPAddr PAddr, void *Node)
 
 //     if( !MM_GetRefCount(PAddr) )    return 1;
        
-       if( !MM_GetPhysAddr(node_page) ) {
+       if( !MM_GetPhysAddr((void*)node_page) ) {
                if( !MM_Allocate(node_page) )
                        return -1;
                memset( (void*)node_page, 0, PAGE_SIZE );
@@ -635,7 +574,7 @@ int MM_GetPageNode(tPAddr PAddr, void **Node)
 //     if( !MM_GetRefCount(PAddr) )    return 1;
        PAddr >>= 12;
        
-       if( !MM_GetPhysAddr( (tVAddr)&gapPageNodes[PAddr] ) ) {
+       if( !MM_GetPhysAddr( &gapPageNodes[PAddr] ) ) {
                *Node = NULL;
                return 0;
        }
index 3d723e1..14117f4 100644 (file)
@@ -269,9 +269,9 @@ void MM_int_DumpTablesEnt(tVAddr RangeStart, size_t Length, tPAddr Expected)
        #define CANOICAL(addr)  ((addr)&0x800000000000?(addr)|0xFFFF000000000000:(addr))
        LogF("%016llx => ", CANOICAL(RangeStart));
 //     LogF("%6llx %6llx %6llx %016llx => ",
-//             MM_GetPhysAddr( (tVAddr)&PAGEDIRPTR(RangeStart>>30) ),
-//             MM_GetPhysAddr( (tVAddr)&PAGEDIR(RangeStart>>21) ),
-//             MM_GetPhysAddr( (tVAddr)&PAGETABLE(RangeStart>>12) ),
+//             MM_GetPhysAddr( &PAGEDIRPTR(RangeStart>>30) ),
+//             MM_GetPhysAddr( &PAGEDIR(RangeStart>>21) ),
+//             MM_GetPhysAddr( &PAGETABLE(RangeStart>>12) ),
 //             CANOICAL(RangeStart)
 //             );
        if( gMM_ZeroPage && (PAGETABLE(RangeStart>>12) & PADDR_MASK) == gMM_ZeroPage )
@@ -576,7 +576,7 @@ void MM_Deallocate(tVAddr VAddr)
 {
        tPAddr  phys;
        
-       phys = MM_GetPhysAddr(VAddr);
+       phys = MM_GetPhysAddr( (void*)VAddr );
        if(!phys)       return ;
        
        MM_Unmap(VAddr);
@@ -609,8 +609,9 @@ int MM_GetPageEntry(tVAddr Addr, tPAddr *Phys, Uint *Flags)
 /**
  * \brief Get the physical address of a virtual location
  */
-tPAddr MM_GetPhysAddr(tVAddr Addr)
+tPAddr MM_GetPhysAddr(const void *Ptr)
 {
+       tVAddr  Addr = (tVAddr)Ptr;
        tPAddr  *ptr;
         int    ret;
        
@@ -776,7 +777,8 @@ tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number)
        {
                for( num = Number; num -- && ret < MM_HWMAP_TOP; ret += 0x1000 )
                {
-                       if( MM_GetPhysAddr(ret) != 0 )  break;
+                       if( MM_GetPhysAddr( (void*)ret ) != 0 )
+                               break;
                }
                if( num >= 0 )  continue;
                
@@ -807,7 +809,7 @@ void MM_UnmapHWPages(tVAddr VAddr, Uint Number)
 //     Log_KernelPanic("MM", "TODO: Implement MM_UnmapHWPages");
        while( Number -- )
        {
-               MM_DerefPhys( MM_GetPhysAddr(VAddr) );
+               MM_DerefPhys( MM_GetPhysAddr((void*)VAddr) );
                MM_Unmap(VAddr);
                VAddr += 0x1000;
        }
@@ -970,7 +972,7 @@ tPAddr MM_Clone(void)
                MM_MapEx(kstackbase+i*0x1000, phys, 1, 0);
                
                tmpmapping = MM_MapTemp(phys);
-               if( MM_GetPhysAddr( kstackbase+i*0x1000 ) )
+               if( MM_GetPhysAddr( (void*)(kstackbase+i*0x1000) ) )
                        memcpy(tmpmapping, (void*)(kstackbase+i*0x1000), 0x1000);
                else
                        memset(tmpmapping, 0, 0x1000);
@@ -1088,7 +1090,7 @@ tVAddr MM_NewKStack(void)
        Uint    i;
        for( ; base < MM_KSTACK_TOP; base += KERNEL_STACK_SIZE )
        {
-               if(MM_GetPhysAddr(base+KERNEL_STACK_SIZE-0x1000) != 0)
+               if(MM_GetPhysAddr( (void*)(base+KERNEL_STACK_SIZE-0x1000) ) != 0)
                        continue;
                
                //Log("MM_NewKStack: Found one at %p", base + KERNEL_STACK_SIZE);
index 5f71a45..18cfd02 100644 (file)
@@ -86,7 +86,9 @@ tMPInfo       *gMPFloatPtr = NULL;
 tAPIC  *gpMP_LocalAPIC = NULL;
 Uint8  gaAPIC_to_CPU[256] = {0};
 #endif
-tCPU   gaCPUs[MAX_CPUS];
+tCPU   gaCPUs[MAX_CPUS] = {
+       {.Current = &gThreadZero}
+       };
 tTSS   *gTSSs = NULL;
 tTSS   gTSS0 = {0};
 // --- Error Recovery ---
@@ -579,7 +581,7 @@ Uint Proc_MakeUserStack(void)
        // Check Prospective Space
        for( i = USER_STACK_SZ >> 12; i--; )
        {
-               if( MM_GetPhysAddr( base + (i<<12) ) != 0 )
+               if( MM_GetPhysAddr( (void*)(base + (i<<12)) ) != 0 )
                        break;
        }
        
index 52b133c..ac05971 100644 (file)
@@ -183,6 +183,6 @@ gInitialKernelStack:
 
 [section .rodata]
 csNot64BitCapable:
-       db "Not 64-bit Capable",0
+       db "CPU does not support long-mode, please use the x86 build",0
 
 ; vim: ft=nasm
index 98acb99..f09389b 100644 (file)
@@ -173,8 +173,9 @@ int PCI_ScanBus(int BusID, int bFill)
                        {\r
                                #if LIST_DEVICES\r
                                if( !bFill )\r
-                                       Log_Log("PCI", "Device %i,%i:%i %06x => 0x%04x:0x%04x",\r
-                                               BusID, dev, fcn, devInfo.class, devInfo.vendor, devInfo.device);\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
                        \r
@@ -494,7 +495,7 @@ int PCI_int_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info)
        info->Node.NumACLs = 1;\r
        info->Node.ACLs = &gVFS_ACL_EveryoneRO;\r
        \r
-       info->Node.Type = &gPCI_RootNodeType;\r
+       info->Node.Type = &gPCI_DevNodeType;\r
        \r
        return 1;\r
 }\r
index 05fa102..2bee791 100644 (file)
@@ -265,12 +265,16 @@ int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t
                                                px = (void*)dest;
                                        }
                                }
+                               if( x > 0 ) {
+                                       dest += FBInfo->Pitch;
+                               }
                        }
                        else
                        {
                                ofs = Offset;
                                dest += ofs;
                                memcpy(dest, Buffer, Length);
+                               dest += Length;
                        }
                        break;
                default:
@@ -293,9 +297,11 @@ int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t
                return -1;
        }
        if( FBInfo->BackBuffer && dest ) {
-               memcpy((char*)FBInfo->Framebuffer + ofs, (char*)FBInfo->BackBuffer + ofs,
-                       ((tVAddr)dest - (tVAddr)FBInfo->BackBuffer) - ofs
-                       );
+               void    *_dst = (char*)FBInfo->Framebuffer + ofs;
+               void    *_src = (char*)FBInfo->BackBuffer + ofs;
+               size_t  len = ((tVAddr)dest - (tVAddr)FBInfo->BackBuffer) - ofs;
+       //      Log_Debug("DrvUtil", "Copy from BB %p to FB %p 0x%x bytes", _src, _dst, len);
+               memcpy(_dst, _src, len);
        }
 
        DrvUtil_Video_DrawCursor(FBInfo, csr_x, csr_y);
index 4c7ffd9..af2bde4 100644 (file)
@@ -153,8 +153,8 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes)
        size_t  Bytes;
 
        if( __Bytes == 0 ) {
-               //return NULL;  // TODO: Return a known un-mapped range.
-               return INVLPTR;
+               return NULL;    // TODO: Return a known un-mapped range.
+//             return INVLPTR;
        }
        
        // Get required size
diff --git a/KernelLand/Kernel/include/bootmod.h b/KernelLand/Kernel/include/bootmod.h
new file mode 100644 (file)
index 0000000..0979389
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ * 
+ * include/bootmod.h
+ * - Common boot modules type
+ */
+#ifndef _BOOTMOD_H_
+#define _BOOTMOD_H_
+
+typedef struct sBootModule     tBootModule;
+
+struct sBootModule {
+       tPAddr  PBase;
+       void    *Base;
+       Uint    Size;
+       char    *ArgString;
+};
+
+#endif
+
index c7f33dd..61c689b 100644 (file)
@@ -4,9 +4,13 @@
  */
 #ifndef _MBOOT_H
 #define _MBOOT_H
+#include <acess.h>
 
 #define MULTIBOOT_MAGIC        0x2BADB002
 
+#include <pmemmap.h>
+#include <bootmod.h>
+
 // === TYPES ===
 typedef struct {
        Uint32  Flags;
@@ -35,4 +39,7 @@ typedef struct {
        Uint32  Type;   //1:RAM,Else Reserved
 } __attribute__ ((packed)) tMBoot_MMapEnt;
 
+extern int     Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *Map, const int MapSize, tPAddr KStart, tPAddr KEnd);
+extern tBootModule     *Multiboot_LoadModules(tMBoot_Info *MBInfo, tVAddr MapOffset, int *ModuleCount);
+
 #endif
index cf3018f..005a2f8 100644 (file)
@@ -83,7 +83,7 @@ void MM_Tpl_InitPhys(int MaxRAMPage, void *MemoryMap)
                bitmap_page &= ~(PAGE_SIZE-1);
 
                // Only need to allocate bitmaps
-               if( !MM_GetPhysAddr( bitmap_page ) ) {
+               if( !MM_GetPhysAddr( (void*)bitmap_page ) ) {
                        if( !MM_Allocate( bitmap_page ) ) {
                                Log_KernelPanic("PMM", "Out of memory during init, this is bad");
                                return ;
@@ -220,7 +220,7 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits)
        
                LOG("if( MM_GetPhysAddr( %p ) )", &gaiPageReferences[addr]);
                // Mark as referenced if the reference count page is valid      
-               if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[addr] ) ) {
+               if( MM_GetPhysAddr( &gaiPageReferences[addr] ) ) {
                        gaiPageReferences[addr] = 1;
                }
        }
@@ -276,7 +276,7 @@ tPAddr MM_AllocPhys(void)
                tPAddr  ret = 0;
                for( ret = 0; ret < giMaxPhysPage; ret ++ )
                {
-                       if( !MM_GetPhysAddr( (tVAddr)&gaPageBitmaps[ret/32] ) ) {
+                       if( !MM_GetPhysAddr( &gaPageBitmaps[ret/32] ) ) {
                                ret += PAGE_SIZE*8;
                                continue ;
                        }
@@ -317,13 +317,13 @@ void MM_RefPhys(tPAddr PAddr)
                if( gaPageBitmaps[page / 32] == 0 )
                        gaSuperBitmap[page / (32*32)] &= ~(1LL << ((page / 32) & 31));
                #endif
-               if( MM_GetPhysAddr( refpage ) )
+               if( MM_GetPhysAddr( (void*)refpage ) )
                        gaiPageReferences[page] = 1;
        }
        else
        {
                // Reference again
-               if( !MM_GetPhysAddr( refpage ) )
+               if( !MM_GetPhysAddr( (void*)refpage ) )
                {
                         int    pages_per_page, basepage, i;
                        if( MM_Allocate(refpage) == 0 ) {
@@ -350,7 +350,7 @@ void MM_RefPhys(tPAddr PAddr)
 int MM_GetRefCount(tPAddr PAddr)
 {
        PAddr >>= 12;
-       if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[PAddr] ) ) {
+       if( MM_GetPhysAddr( &gaiPageReferences[PAddr] ) ) {
                return gaiPageReferences[PAddr];
        }
        
@@ -372,7 +372,7 @@ void MM_DerefPhys(tPAddr PAddr)
 
        ENTER("PPAddr", PAddr);
        
-       if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[page] ) )
+       if( MM_GetPhysAddr( &gaiPageReferences[page] ) )
        {
                if( gaiPageReferences[page] > 0 )
                        gaiPageReferences[ page ] --;
@@ -384,7 +384,7 @@ void MM_DerefPhys(tPAddr PAddr)
        else
                gaPageBitmaps[ page / 32 ] |= 1 << (page&31);
        // Clear node if needed
-       if( MM_GetPhysAddr( (tVAddr)&gapPageNodes[page] ) ) {
+       if( MM_GetPhysAddr( &gapPageNodes[page] ) ) {
                gapPageNodes[page] = NULL;
                // TODO: Catch when all pages in this range are not using nodes
        }
@@ -415,7 +415,7 @@ int MM_SetPageNode(tPAddr PAddr, void *Node)
 
        if( !MM_GetRefCount(PAddr) )    return 1;
        
-       if( !MM_GetPhysAddr(node_page) ) {
+       if( !MM_GetPhysAddr( (void*)node_page ) ) {
                if( !MM_Allocate(node_page) )
                        return -1;
                memset( (void*)node_page, 0, PAGE_SIZE );
@@ -430,7 +430,7 @@ int MM_GetPageNode(tPAddr PAddr, void **Node)
        if( !MM_GetRefCount(PAddr) )    return 1;
        PAddr >>= 12;
        
-       if( !MM_GetPhysAddr( (tVAddr)&gapPageNodes[PAddr] ) ) {
+       if( !MM_GetPhysAddr( &gapPageNodes[PAddr] ) ) {
                *Node = NULL;
                return 0;
        }
index d067e49..9617b83 100644 (file)
@@ -69,14 +69,16 @@ EXPORT(Log_Debug);
 
 // === GLOBALS ===
 tShortSpinlock glLogOutput;
-#if USE_RING_BUFFER
+#if CACHE_MESSAGES
+# if USE_RING_BUFFER
 Uint8  gaLog_RingBufferData[sizeof(tRingBuffer)+RING_BUFFER_SIZE];
 tRingBuffer    *gpLog_RingBuffer = (void*)gaLog_RingBufferData;
-#else
+# else
 tMutex glLog;
 tLogList       gLog;
 tLogList       gLog_Levels[NUM_LOG_LEVELS];
-#endif
+# endif        // USE_RING_BUFFER
+#endif // CACHE_MESSAGES
 
 // === CODE ===
 /**
index 6099621..17cccca 100644 (file)
@@ -504,15 +504,13 @@ tThread *Threads_GetThread(Uint TID)
        tThread *thread;
        
        // Search global list
-       for(thread = gAllThreads;
-               thread;
-               thread = thread->GlobalNext)
+       for( thread = gAllThreads; thread; thread = thread->GlobalNext )
        {
                if(thread->TID == TID)
                        return thread;
        }
 
-       Log("Unable to find TID %i on main list\n", TID);
+       Log_Notice("Threads", "Unable to find TID %i on main list\n", TID);
        
        return NULL;
 }
index dacf720..7379e3d 100644 (file)
@@ -38,6 +38,12 @@ Uint64 VFS_Read(int FD, Uint64 Length, void *Buffer)
                LOG("No read method");
                LEAVE_RET('i', -1);
        }
+
+       if( !MM_GetPhysAddr(h->Node->Type->Read) ) {
+               Log_Error("VFS", "Node type %p(%s) read method is junk %p", h->Node->Type, h->Node, h->Node->Type->TypeName,
+                       h->Node->Type->Read);
+               LEAVE_RET('i', -1);
+       }
        
        ret = h->Node->Type->Read(h->Node, h->Position, Length, Buffer);
        if(ret == -1)   LEAVE_RET('i', -1);
@@ -66,6 +72,13 @@ Uint64 VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer)
                Warning("VFS_ReadAt - Node %p, does not have a read method", h->Node);
                return 0;
        }
+
+       if( !MM_GetPhysAddr(h->Node->Type->Read) ) {
+               Log_Error("VFS", "Node type %p(%s) read method is junk %p", h->Node->Type, h->Node, h->Node->Type->TypeName,
+                       h->Node->Type->Read);
+               LEAVE_RET('i', -1);
+       }
+       
        ret = h->Node->Type->Read(h->Node, Offset, Length, Buffer);
        if(ret == -1)   return -1;
        return ret;
@@ -87,6 +100,12 @@ Uint64 VFS_Write(int FD, Uint64 Length, const void *Buffer)
        if( h->Node->Flags & VFS_FFLAG_DIRECTORY )      return -1;
 
        if( !h->Node->Type || !h->Node->Type->Write )   return 0;
+
+       if( !MM_GetPhysAddr(h->Node->Type->Write) ) {
+               Log_Error("VFS", "Node type %p(%s) write method is junk %p", h->Node->Type, h->Node, h->Node->Type->TypeName,
+                       h->Node->Type->Write);
+               return -1;
+       }
        
        ret = h->Node->Type->Write(h->Node, h->Position, Length, Buffer);
        if(ret == -1)   return -1;
@@ -111,8 +130,13 @@ Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, const void *Buffer)
        if( h->Node->Flags & VFS_FFLAG_DIRECTORY )      return -1;
 
        if(!h->Node->Type || !h->Node->Type->Write)     return 0;
-       ret = h->Node->Type->Write(h->Node, Offset, Length, Buffer);
 
+       if( !MM_GetPhysAddr(h->Node->Type->Write) ) {
+               Log_Error("VFS", "Node type %p(%s) write method is junk %p", h->Node->Type, h->Node, h->Node->Type->TypeName,
+                       h->Node->Type->Write);
+               return -1;
+       }
+       ret = h->Node->Type->Write(h->Node, Offset, Length, Buffer);
        if(ret == -1)   return -1;
        return ret;
 }
index 344b2a1..983a2b2 100644 (file)
@@ -702,7 +702,7 @@ int VFS_ChDir(const char *Dest)
                *cwdptr = buf;
        }
        
-       Log("Updated CWD to '%s'", buf);
+       Log_Debug("VFS", "Updated CWD to '%s'", buf);
        
        return 1;
 }
index c34700c..412cb1a 100644 (file)
@@ -402,6 +402,7 @@ int VFS_int_Select_AddThread(tVFS_SelectList *List, tThread *Thread, int MaxAllo
                        }
                        count ++;
                        if( MaxAllowed && count >= MaxAllowed ) {
+                               Mutex_Release(&List->Lock);
                                LEAVE('i', 1);
                                return 1;
                        }
diff --git a/KernelLand/Modules/Display/NVidia/main.c b/KernelLand/Modules/Display/NVidia/main.c
new file mode 100644 (file)
index 0000000..7ebbca3
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Acess2 NVidia Graphics Driver
+ * - By John Hodge (thePowersGang)
+ * 
+ * main.c
+ * - Driver Core
+ *
+ * Reference: linux/drivers/video/nvidia
+ */
+#define DEBUG  1
+#define VERSION VER2(0,1)
+#include <acess.h>
+#include <modules.h>
+#include <fs_devfs.h>
+#include <drv_pci.h>
+#include "regs.h"
+
+// === PROTOTYPES ===
+ int   NV_Install(char **Arguments);
+ int   NV_Cleanup(void);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, Video_NVidia, VERSION, NV_Install, NV_Cleanup, NULL);
+
+// === CODE ===
+int NV_Install(char **Arguments)
+{
+       return MODERR_NOTNEEDED;
+}
+
+int NV_Cleanup(void)
+{
+       return 0;
+}
+
diff --git a/KernelLand/Modules/Display/NVidia/regs.c b/KernelLand/Modules/Display/NVidia/regs.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/KernelLand/Modules/Display/NVidia/regs.h b/KernelLand/Modules/Display/NVidia/regs.h
new file mode 100644 (file)
index 0000000..6c6fd56
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Acess2 NVidia Graphics Driver
+ * - By John Hodge (thePowersGang)
+ * 
+ * regs.h
+ * - Register definitions
+ */
+#ifndef _NVIDIA__REGS_H_
+#define _NVIDIA__REGS_H_
+
+// CRT Controller Registers
+enum eNVRegs_CRTC
+{
+       NUM_CRTC_REGS
+};
+
+// Attribute Controller registers
+enum eNVRegs_ATC
+{
+       NUM_ATC_REGS
+};
+
+enum eNVRegs_GRC
+{
+       NUM_GRC_REGS
+};
+
+// Sequencer registers
+enum eNVRegs_SEQ
+{
+       NUM_SEQ_REGS
+};
+
+struct sNVRegDump
+{
+       Uint8   atc_regs[NUM_ATC_REGS];
+       Uint8   crtc_regs[NUM_CRTC_REGS];
+       Uint8   gra_regs[NUM_GRC_REGS];
+       Uint8   seq_regs[NUM_SEQ_REGS];
+};
+
+#endif
+
diff --git a/KernelLand/Modules/Display/Tegra2Vid/Registers.txt b/KernelLand/Modules/Display/Tegra2Vid/Registers.txt
new file mode 100644 (file)
index 0000000..42dce4e
--- /dev/null
@@ -0,0 +1,212 @@
+Display CMD Registers
+00000000000000d [Tegra2Vi] 0 - [0x000] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x001] = 0x00000100 (-)
+00000000000000d [Tegra2Vi] 0 - [0x002] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x003] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x004] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x005] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x006] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x007] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x008] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x009] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x00A] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x00B] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x00C] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x00D] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x00E] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x00F] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x010] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x011] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x012] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x013] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x014] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x015] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x016] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x017] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x018] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x019] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x01A] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x028] = 0x0000011A (-)
+00000000000000d [Tegra2Vi] 0 - [0x029] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x02A] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x02B] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x02C] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x02D] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x02E] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x02F] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x030] = 0xF000F800 (-)
+00000000000000d [Tegra2Vi] 0 - [0x031] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x032] = 0x00000020 (-)
+00000000000000d [Tegra2Vi] 0 - [0x033] = 0x00000114 (-)
+00000000000000d [Tegra2Vi] 0 - [0x034] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x035] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x036] = 0x00050155 (-)
+00000000000000d [Tegra2Vi] 0 - [0x037] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x038] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x039] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x03A] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x03B] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x03C] = 0x0009060C (-)
+00000000000000d [Tegra2Vi] 0 - [0x03D] = 0x000F021C (-)
+00000000000000d [Tegra2Vi] 0 - [0x03E] = 0x000D0210 (-)
+00000000000000d [Tegra2Vi] 0 - [0x03F] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x040] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x041] = 0x00000000 (DC_CMD_STATE_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x042] = 0x00000010 (DC_CMD_DISPLAY_WINDOW_HEADER_0)
+00000000000000d [Tegra2Vi] 0 - [0x043] = 0x00000000 (DC_CMD_REG_ACT_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - Display COM Registers
+00000000000000d [Tegra2Vi] 0 - [0x300] = 0x00000000 (DC_COM_CRC_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x301] = 0x00000000 (DC_COM_CRC_CHECKSUM_0)
+00000000000000d [Tegra2Vi] 0 - [0x302] = 0x00000000 (DC_COM_PIN_OUTPUT_ENABLE0_0)
+00000000000000d [Tegra2Vi] 0 - [0x303] = 0x00000000 (DC_COM_PIN_OUTPUT_ENABLE1_0)
+00000000000000d [Tegra2Vi] 0 - [0x304] = 0x00000000 (DC_COM_PIN_OUTPUT_ENABLE2_0)
+00000000000000d [Tegra2Vi] 0 - [0x305] = 0x00000000 (DC_COM_PIN_OUTPUT_ENABLE3_0)
+00000000000000d [Tegra2Vi] 0 - [0x306] = 0x00000000 (DC_COM_PIN_OUTPUT_POLARITY0_0)
+00000000000000d [Tegra2Vi] 0 - [0x307] = 0x01000000 (DC_COM_PIN_OUTPUT_POLARITY1_0)
+00000000000000d [Tegra2Vi] 0 - [0x308] = 0x00000000 (DC_COM_PIN_OUTPUT_POLARITY2_0)
+00000000000000d [Tegra2Vi] 0 - [0x309] = 0x00000000 (DC_COM_PIN_OUTPUT_POLARITY3_0)
+00000000000000d [Tegra2Vi] 0 - [0x30A] = 0x00000000 (DC_COM_PIN_OUTPUT_DATA0_0)
+00000000000000d [Tegra2Vi] 0 - [0x30B] = 0x00000000 (DC_COM_PIN_OUTPUT_DATA1_0)
+00000000000000d [Tegra2Vi] 0 - [0x30C] = 0x00000000 (DC_COM_PIN_OUTPUT_DATA2_0)
+00000000000000d [Tegra2Vi] 0 - [0x30D] = 0x00000000 (DC_COM_PIN_OUTPUT_DATA3_0)
+00000000000000d [Tegra2Vi] 0 - [0x30E] = 0x00000000 (DC_COM_PIN_INPUT_ENABLE0_0)
+00000000000000d [Tegra2Vi] 0 - [0x30F] = 0x00000000 (DC_COM_PIN_INPUT_ENABLE1_0)
+00000000000000d [Tegra2Vi] 0 - [0x310] = 0x00000000 (DC_COM_PIN_INPUT_ENABLE2_0)
+00000000000000d [Tegra2Vi] 0 - [0x311] = 0x00000000 (DC_COM_PIN_INPUT_ENABLE3_0)
+00000000000000d [Tegra2Vi] 0 - [0x312] = 0x00000000 (DC_COM_PIN_INPUT_DATA0_0)
+00000000000000d [Tegra2Vi] 0 - [0x313] = 0x00000000 (DC_COM_PIN_INPUT_DATA1_0)
+00000000000000d [Tegra2Vi] 0 - [0x314] = 0x00000000 (DC_COM_PIN_OUTPUT_SELECT0_0)
+00000000000000d [Tegra2Vi] 0 - [0x315] = 0x00000000 (DC_COM_PIN_OUTPUT_SELECT1_0)
+00000000000000d [Tegra2Vi] 0 - [0x316] = 0x00000000 (DC_COM_PIN_OUTPUT_SELECT2_0)
+00000000000000d [Tegra2Vi] 0 - [0x317] = 0x00000000 (DC_COM_PIN_OUTPUT_SELECT3_0)
+00000000000000d [Tegra2Vi] 0 - [0x318] = 0x00210222 (DC_COM_PIN_OUTPUT_SELECT4_0)
+00000000000000d [Tegra2Vi] 0 - [0x319] = 0x00002200 (DC_COM_PIN_OUTPUT_SELECT5_0)
+00000000000000d [Tegra2Vi] 0 - [0x31A] = 0x00020000 (DC_COM_PIN_OUTPUT_SELECT6_0)
+00000000000000d [Tegra2Vi] 0 - [0x31B] = 0x00000000 (DC_COM_PIN_MISC_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x31C] = 0x00840152 (-)
+00000000000000d [Tegra2Vi] 0 - [0x31D] = 0x00000144 (-)
+00000000000000d [Tegra2Vi] 0 - [0x31E] = 0x00700111 (-)
+00000000000000d [Tegra2Vi] 0 - [0x31F] = 0x00000077 (-)
+00000000000000d [Tegra2Vi] 0 - [0x320] = 0x01070023 (-)
+00000000000000d [Tegra2Vi] 0 - [0x321] = 0x0000D317 (-)
+00000000000000d [Tegra2Vi] 0 - [0x322] = 0xEAEE54C2 (-)
+00000000000000d [Tegra2Vi] 0 - [0x323] = 0x6BDC5DA4 (-)
+00000000000000d [Tegra2Vi] 0 - [0x324] = 0x05004210 (-)
+00000000000000d [Tegra2Vi] 0 - [0x325] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x326] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x327] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x328] = 0x00000400 (-)
+00000000000000d [Tegra2Vi] 0 - [0x329] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - Display DISP Registers
+00000000000000d [Tegra2Vi] 0 - [0x400] = 0x00000000 (DC_DISP_DISP_SIGNAL_OPTIONS0_0)
+00000000000000d [Tegra2Vi] 0 - [0x401] = 0x00000000 (DC_DISP_DISP_SIGNAL_OPTIONS1_0)
+00000000000000d [Tegra2Vi] 0 - [0x402] = 0x00000000 (DC_DISP_DISP_WIN_OPTIONS_0)
+00000000000000d [Tegra2Vi] 0 - [0x403] = 0x00000020 (DC_DISP_MEM_HIGH_PRIORITY_0)
+00000000000000d [Tegra2Vi] 0 - [0x404] = 0x00000001 (DC_DISP_MEM_HIGH_PRIORITY_TIMER_0)
+00000000000000d [Tegra2Vi] 0 - [0x405] = 0x00000000 (DC_DISP_DISP_TIMING_OPTIONS_0)
+00000000000000d [Tegra2Vi] 0 - [0x406] = 0x0001000B (DC_DISP_REF_TO_SYNC_0)
+00000000000000d [Tegra2Vi] 0 - [0x407] = 0x0004003A (DC_DISP_SYNC_WIDTH_0)
+00000000000000d [Tegra2Vi] 0 - [0x408] = 0x0004003A (DC_DISP_BACK_PORCH_0)
+00000000000000d [Tegra2Vi] 0 - [0x409] = 0x03000400 (DC_DISP_DISP_ACTIVE_0)
+00000000000000d [Tegra2Vi] 0 - [0x40A] = 0x0004003A (DC_DISP_FRONT_PORCH_0)
+00000000000000d [Tegra2Vi] 0 - [0x40B] = 0x00000918 (DC_DISP_H_PULSE0_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x40C] = 0x1D970F55 (DC_DISP_H_PULSE0_POSITION_A_0)
+00000000000000d [Tegra2Vi] 0 - [0x40D] = 0x02AA0AC5 (DC_DISP_H_PULSE0_POSITION_B_0)
+00000000000000d [Tegra2Vi] 0 - [0x40E] = 0x039B00AA (DC_DISP_H_PULSE0_POSITION_C_0)
+00000000000000d [Tegra2Vi] 0 - [0x40F] = 0x044D1989 (DC_DISP_H_PULSE0_POSITION_D_0)
+00000000000000d [Tegra2Vi] 0 - [0x410] = 0x00000480 (DC_DISP_H_PULSE1_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x411] = 0x198B1E2D (DC_DISP_H_PULSE1_POSITION_A_0)
+00000000000000d [Tegra2Vi] 0 - [0x412] = 0x04910669 (DC_DISP_H_PULSE1_POSITION_B_0)
+00000000000000d [Tegra2Vi] 0 - [0x413] = 0x08381FA4 (DC_DISP_H_PULSE1_POSITION_C_0)
+00000000000000d [Tegra2Vi] 0 - [0x414] = 0x009C0625 (DC_DISP_H_PULSE1_POSITION_D_0)
+00000000000000d [Tegra2Vi] 0 - [0x415] = 0x00000608 (DC_DISP_H_PULSE2_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x416] = 0x0C001469 (DC_DISP_H_PULSE2_POSITION_A_0)
+00000000000000d [Tegra2Vi] 0 - [0x417] = 0x07690B17 (DC_DISP_H_PULSE2_POSITION_B_0)
+00000000000000d [Tegra2Vi] 0 - [0x418] = 0x00360257 (DC_DISP_H_PULSE2_POSITION_C_0)
+00000000000000d [Tegra2Vi] 0 - [0x419] = 0x1F1809D6 (DC_DISP_H_PULSE2_POSITION_D_0)
+00000000000000d [Tegra2Vi] 0 - [0x41A] = 0x000007D0 (DC_DISP_V_PULSE0_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x41B] = 0x15CB1886 (DC_DISP_V_PULSE0_POSITION_A_0)
+00000000000000d [Tegra2Vi] 0 - [0x41C] = 0x02401EA8 (DC_DISP_V_PULSE0_POSITION_B_0)
+00000000000000d [Tegra2Vi] 0 - [0x41D] = 0x09750264 (DC_DISP_V_PULSE0_POSITION_C_0)
+00000000000000d [Tegra2Vi] 0 - [0x41E] = 0x00000010 (DC_DISP_V_PULSE1_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x41F] = 0x16BA0A17 (DC_DISP_V_PULSE1_POSITION_A_0)
+00000000000000d [Tegra2Vi] 0 - [0x420] = 0x1AE21A90 (DC_DISP_V_PULSE1_POSITION_B_0)
+00000000000000d [Tegra2Vi] 0 - [0x421] = 0x06860AD7 (DC_DISP_V_PULSE1_POSITION_C_0)
+00000000000000d [Tegra2Vi] 0 - [0x422] = 0x00000000 (DC_DISP_V_PULSE2_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x423] = 0x0CC31C03 (DC_DISP_V_PULSE2_POSITION_A_0)
+00000000000000d [Tegra2Vi] 0 - [0x424] = 0x00000000 (DC_DISP_V_PULSE3_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x425] = 0x07071A0E (DC_DISP_V_PULSE3_POSITION_A_0)
+00000000000000d [Tegra2Vi] 0 - [0x426] = 0x02960DA3 (DC_DISP_M0_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x427] = 0x1F8C1951 (DC_DISP_M1_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x428] = 0x15070003 (DC_DISP_DI_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x429] = 0x0000CEF5 (DC_DISP_PP_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x42A] = 0x10D08381 (DC_DISP_PP_SELECT_A_0)
+00000000000000d [Tegra2Vi] 0 - [0x42B] = 0x1C2CB600 (DC_DISP_PP_SELECT_B_0)
+00000000000000d [Tegra2Vi] 0 - [0x42C] = 0x73B3DE7D (DC_DISP_PP_SELECT_C_0)
+00000000000000d [Tegra2Vi] 0 - [0x42D] = 0x0779CA03 (DC_DISP_PP_SELECT_D_0)
+00000000000000d [Tegra2Vi] 0 - [0x42E] = 0x00000005 (DC_DISP_DISP_CLOCK_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x42F] = 0x00000000 (DC_DISP_DISP_INTERFACE_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x430] = 0x00000200 (DC_DISP_DISP_COLOR_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x431] = 0x00010001 (DC_DISP_SHIFT_CLOCK_OPTIONS_0)
+00000000000000d [Tegra2Vi] 0 - [0x432] = 0x00000005 (DC_DISP_DATA_ENABLE_OPTIONS_0)
+00000000000000d [Tegra2Vi] 0 - [0x433] = 0x00000000 (DC_DISP_SERIAL_INTERFACE_OPTIONS_0)
+00000000000000d [Tegra2Vi] 0 - [0x434] = 0x00000000 (DC_DISP_LCD_SPI_OPTIONS_0)
+00000000000000d [Tegra2Vi] 0 - [0x435] = 0x00DA0731 (DC_DISP_BORDER_COLOR_0)
+00000000000000d [Tegra2Vi] 0 - [0x436] = 0x00E9B832 (DC_DISP_COLOR_KEY0_LOWER_0)
+00000000000000d [Tegra2Vi] 0 - [0x437] = 0x006B4475 (DC_DISP_COLOR_KEY0_UPPER_0)
+00000000000000d [Tegra2Vi] 0 - [0x438] = 0x000FA6FB (DC_DISP_COLOR_KEY1_LOWER_0)
+00000000000000d [Tegra2Vi] 0 - [0x439] = 0x00304301 (DC_DISP_COLOR_KEY1_UPPER_0)
+00000000000000d [Tegra2Vi] 0 - [0x43A] = 0x00000000 (_DC_DISP_UNUSED_43A)
+00000000000000d [Tegra2Vi] 0 - [0x43B] = 0x00000000 (_DC_DISP_UNUSED_43B)
+00000000000000d [Tegra2Vi] 0 - [0x43C] = 0x004962ED (DC_DISP_CURSOR_FOREGROUND_0)
+00000000000000d [Tegra2Vi] 0 - [0x43D] = 0x0063462E (DC_DISP_CURSOR_BACKGROUND_0)
+00000000000000d [Tegra2Vi] 0 - [0x43E] = 0x3021352C (DC_DISP_CURSOR_START_ADDR_0)
+00000000000000d [Tegra2Vi] 0 - [0x43F] = 0x3021352C (DC_DISP_CURSOR_START_ADDR_NS_0)
+00000000000000d [Tegra2Vi] 0 - [0x440] = 0x21B10B4B (DC_DISP_CURSOR_POSITION_0)
+00000000000000d [Tegra2Vi] 0 - [0x441] = 0x21B10B4B (DC_DISP_CURSOR_POSITION_NS_0)
+00000000000000d [Tegra2Vi] 0 - [0x442] = 0x00000030 (DC_DISP_INIT_SEQ_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x443] = 0x8C0BF46E (DC_DISP_SPI_INIT_SEQ_DATA_A_0)
+00000000000000d [Tegra2Vi] 0 - [0x444] = 0xE08C7EBA (DC_DISP_SPI_INIT_SEQ_DATA_B_0)
+00000000000000d [Tegra2Vi] 0 - [0x445] = 0x89A6A8FD (DC_DISP_SPI_INIT_SEQ_DATA_C_0)
+00000000000000d [Tegra2Vi] 0 - [0x446] = 0x80D5BC36 (DC_DISP_SPI_INIT_SEQ_DATA_D_0)
+00000000000000d [Tegra2Vi] 0 - [0x480] = 0x00000000 (DC_DISP_DC_MCCIF_FIFOCTRL_0)
+00000000000000d [Tegra2Vi] 0 - [0x481] = 0xCF401F1F (DC_DISP_MCCIF_DISPLAY0A_HYST_0)
+00000000000000d [Tegra2Vi] 0 - [0x482] = 0xCF081F1F (DC_DISP_MCCIF_DISPLAY0B_HYST_0)
+00000000000000d [Tegra2Vi] 0 - [0x483] = 0xCF081F1F (DC_DISP_MCCIF_DISPLAY0C_HYST_0)
+00000000000000d [Tegra2Vi] 0 - [0x484] = 0xCF081F1F (DC_DISP_MCCIF_DISPLAY1B_HYST_0)
+00000000000000d [Tegra2Vi] 0 - [0x4C0] = 0x00000000 (DC_DISP_DAC_CRT_CTRL_0)
+00000000000000d [Tegra2Vi] 0 - [0x4C1] = 0x00000002 (DC_DISP_DISP_MISC_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - WINC_A Registers
+00000000000000d [Tegra2Vi] 0 - [0x700] = 0x40000040 (DC_WIN_A_WIN_OPTIONS_0)
+00000000000000d [Tegra2Vi] 0 - [0x701] = 0x00000000 (DC_WIN_A_BYTE_SWAP_0)
+00000000000000d [Tegra2Vi] 0 - [0x702] = 0x00000000 (DC_WIN_A_BUFFER_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x703] = 0x00000006 (DC_WIN_A_COLOR_DEPTH_0)
+00000000000000d [Tegra2Vi] 0 - [0x704] = 0x00000000 (DC_WIN_A_POSITION_0)
+00000000000000d [Tegra2Vi] 0 - [0x705] = 0x03000400 (DC_WIN_A_SIZE_0)
+00000000000000d [Tegra2Vi] 0 - [0x706] = 0x03000800 (DC_WIN_A_PRESCALED_SIZE_0)
+00000000000000d [Tegra2Vi] 0 - [0x707] = 0x00000000 (DC_WIN_A_H_INITIAL_DDA_0)
+00000000000000d [Tegra2Vi] 0 - [0x708] = 0x00000000 (DC_WIN_A_V_INITIAL_DDA_0)
+00000000000000d [Tegra2Vi] 0 - [0x709] = 0x10051004 (DC_WIN_A_DDA_INCREMENT_0)
+00000000000000d [Tegra2Vi] 0 - [0x70A] = 0x00000800 (DC_WIN_A_LINE_STRIDE_0)
+00000000000000d [Tegra2Vi] 0 - [0x70B] = 0x00000000 (DC_WIN_A_BUF_STRIDE_0)
+00000000000000d [Tegra2Vi] 0 - [0x70C] = 0x00000000 (DC_WIN_A_BUFFER_ADDR_MODE_0)
+00000000000000d [Tegra2Vi] 0 - [0x70D] = 0x00000000 (DC_WIN_A_DV_CONTROL_0)
+00000000000000d [Tegra2Vi] 0 - [0x70E] = 0x00000404 (DC_WIN_A_BLEND_NOKEY_0)
+00000000000000d [Tegra2Vi] 0 - [0x70F] = 0x0000FF00 (-)
+00000000000000d [Tegra2Vi] 0 - [0x710] = 0x0000FF00 (-)
+00000000000000d [Tegra2Vi] 0 - [0x711] = 0x00EB0B0D (-)
+00000000000000d [Tegra2Vi] 0 - [0x712] = 0x000C270E (-)
+00000000000000d [Tegra2Vi] 0 - [0x713] = 0x00263E09 (-)
+00000000000000d [Tegra2Vi] 0 - [0x714] = 0x446996C9 (-)
+00000000000000d [Tegra2Vi] 0 - WINBUF_A
+00000000000000d [Tegra2Vi] 0 - [0x800] = 0x1C022000 (DC_WINBUF_A_START_ADDR_0)
+00000000000000d [Tegra2Vi] 0 - [0x801] = 0x1C022000 (DC_WINBUF_A_START_ADDR_NS_0)
+00000000000000d [Tegra2Vi] 0 - [0x802] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x803] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x804] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x805] = 0x00000000 (-)
+00000000000000d [Tegra2Vi] 0 - [0x806] = 0x00000000 (DC_WINBUF_A_ADDR_H_OFFSET_0)
+00000000000000d [Tegra2Vi] 0 - [0x807] = 0x00000000 (DC_WINBUF_A_ADDR_H_OFFSET_NS_0)
+00000000000000d [Tegra2Vi] 0 - [0x808] = 0x00000000 (DC_WINBUF_A_ADDR_V_OFFSET_0)
+00000000000000d [Tegra2Vi] 0 - [0x809] = 0x00000000 (DC_WINBUF_A_ADDR_V_OFFSET_NS_0)
+00000000000000d [Tegra2Vi] 0 - [0x80A] = 0x00000000 (DC_WINBUF_A_UFLOW_STATUS)
index 41afc7f..e19a5ff 100644 (file)
@@ -3,6 +3,7 @@
  * - Driver core
  */
 #define DEBUG  0
+#define DUMP_REGISTERS 1
 #define VERSION        ((0<<8)|10)
 #include <acess.h>
 #include <errno.h>
@@ -63,6 +64,11 @@ tDrvUtil_Video_BufInfo       gTegra2Vid_DrvUtil_BufInfo;
 tVideo_IOCtl_Pos       gTegra2Vid_CursorPos;
 
 // === CODE ===
+inline void _dumpreg(int i)
+{
+       Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x (%s)", i, gpTegra2Vid_IOMem[i],
+               (csaTegra2Vid_RegisterNames[i] ? csaTegra2Vid_RegisterNames[i] : "-"));
+}
 /**
  */
 int Tegra2Vid_Install(char **Arguments)
@@ -71,33 +77,23 @@ int Tegra2Vid_Install(char **Arguments)
 //     KeyVal_Parse(&gTegra2Vid_KeyValueParser, Arguments);
 
        gpTegra2Vid_IOMem = (void*)MM_MapHWPages(gTegra2Vid_PhysBase, 256/4);
-       #if 0
+       #if DUMP_REGISTERS
        {
                Log_Debug("Tegra2Vid", "Display CMD Registers");
-               for( int i = 0x000; i <= 0x01A; i ++ )
-                       Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
-               for( int i = 0x028; i <= 0x043; i ++ )
-                       Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
+               for( int i = 0x000; i <= 0x01A; i ++ )  _dumpreg(i);
+               for( int i = 0x028; i <= 0x043; i ++ )  _dumpreg(i);
                Log_Debug("Tegra2Vid", "Display COM Registers");
-               for( int i = 0x300; i <= 0x329; i ++ )
-                       Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
+               for( int i = 0x300; i <= 0x329; i ++ )  _dumpreg(i);
                Log_Debug("Tegra2Vid", "Display DISP Registers");
-               for( int i = 0x400; i <= 0x446; i ++ )
-                       Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
-               for( int i = 0x480; i <= 0x484; i ++ )
-                       Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
-               for( int i = 0x4C0; i <= 0x4C1; i ++ )
-                       Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
-
+               for( int i = 0x400; i <= 0x446; i ++ )  _dumpreg(i);
+               for( int i = 0x480; i <= 0x484; i ++ )  _dumpreg(i);
+               for( int i = 0x4C0; i <= 0x4C1; i ++ )  _dumpreg(i);
                Log_Debug("Tegra2Vid", "WINC_A Registers");
-               for( int i = 0x700; i <= 0x714; i ++ )
-                       Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
+               for( int i = 0x700; i <= 0x714; i ++ )  _dumpreg(i);
                Log_Debug("Tegra2Vid", "WINBUF_A");
-               for( int i = 0x800; i <= 0x80A; i ++ )
-                       Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
+               for( int i = 0x800; i <= 0x80A; i ++ )  _dumpreg(i);
        }
        #endif
-//     return 1;
 
        // HACK!!!
 #if 0
@@ -120,13 +116,26 @@ int Tegra2Vid_Install(char **Arguments)
                );
        memset(gpTegra2Vid_Framebuffer, 0xFF, 0x1000);
 
-//     gpTegra2Vid_IOMem[DC_WIN_A_WIN_OPTIONS_0] &= ~0x40;
+#if 0
+       gpTegra2Vid_IOMem[DC_WIN_A_WIN_OPTIONS_0] = (1 << 30);
        gpTegra2Vid_IOMem[DC_WIN_A_COLOR_DEPTH_0] = 12; // Could be 13 (BGR/RGB)
+       gpTegra2Vid_IOMem[DC_WIN_A_PRESCALED_SIZE_0] = gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0];
+       gpTegra2Vid_IOMem[DC_WIN_A_LINE_STRIDE_0] =
+               gTegra2Vid_DrvUtil_BufInfo.Pitch =
+               1680*4;
+       gTegra2Vid_DrvUtil_BufInfo.Depth = 32;
+       gTegra2Vid_DrvUtil_BufInfo.Width = 1680;
+       gTegra2Vid_DrvUtil_BufInfo.Height = 1050;
+#else
+       gpTegra2Vid_IOMem[DC_WIN_A_COLOR_DEPTH_0] = 13; // Could be 13 (BGR/RGB)
+       gpTegra2Vid_IOMem[DC_WIN_A_LINE_STRIDE_0] =
+               gTegra2Vid_DrvUtil_BufInfo.Pitch = 1024*4;
+       gTegra2Vid_DrvUtil_BufInfo.Depth = 32;
        gTegra2Vid_DrvUtil_BufInfo.Width = 1024;
        gTegra2Vid_DrvUtil_BufInfo.Height = 768;
-       gTegra2Vid_DrvUtil_BufInfo.Pitch = 1024*4;
-       gTegra2Vid_DrvUtil_BufInfo.Depth = 32;
        gTegra2Vid_DrvUtil_BufInfo.Framebuffer = gpTegra2Vid_Framebuffer;
+#endif
+       gpTegra2Vid_IOMem[DC_CMD_STATE_CONTROL_0] = WIN_A_ACT_REQ;
 
 
 //     Tegra2Vid_int_SetMode(4);
@@ -309,16 +318,16 @@ int Tegra2Vid_int_SetMode(int Mode)
 {
        const struct sTegra2_Disp_Mode  *mode = &caTegra2Vid_Modes[Mode];
         int    w = mode->W, h = mode->H;       // Horizontal/Vertical Active
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_FRONT_PORCH_0) = (mode->VFP << 16) | mode->HFP; 
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_SYNC_WIDTH_0)  = (mode->HS << 16)  | mode->HS;
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_BACK_PORCH_0)  = (mode->VBP << 16) | mode->HBP;
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_DISP_ACTIVE_0) = (mode->H << 16)   | mode->W;
-
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_POSITION_0) = 0;
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_SIZE_0) = (h << 16) | w;
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_DISP_COLOR_CONTROL_0) = 0x8;     // BASE888
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_COLOR_DEPTH_0) = 12;    // Could be 13 (BGR/RGB)
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_PRESCALED_SIZE_0) = (h << 16) | w;
+       gpTegra2Vid_IOMem[DC_DISP_FRONT_PORCH_0] = (mode->VFP << 16) | mode->HFP; 
+       gpTegra2Vid_IOMem[DC_DISP_SYNC_WIDTH_0]  = (mode->HS << 16)  | mode->HS;
+       gpTegra2Vid_IOMem[DC_DISP_BACK_PORCH_0]  = (mode->VBP << 16) | mode->HBP;
+       gpTegra2Vid_IOMem[DC_DISP_DISP_ACTIVE_0] = (mode->H << 16)   | mode->W;
+
+       gpTegra2Vid_IOMem[DC_WIN_A_POSITION_0] = 0;
+       gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0] = (h << 16) | w;
+       gpTegra2Vid_IOMem[DC_DISP_DISP_COLOR_CONTROL_0] = 0x8;  // BASE888
+       gpTegra2Vid_IOMem[DC_WIN_A_COLOR_DEPTH_0] = 12; // Could be 13 (BGR/RGB)
+       gpTegra2Vid_IOMem[DC_WIN_A_PRESCALED_SIZE_0] = (h << 16) | w;
 
        Log_Debug("Tegra2Vid", "Mode %i (%ix%i) selected", Mode, w, h);
 
@@ -331,6 +340,7 @@ int Tegra2Vid_int_SetMode(int Mode)
 
                giTegra2Vid_FramebufferSize = w*h*4;            
 
+               // TODO: Does this need RAM or unmapped space?
                gpTegra2Vid_Framebuffer = (void*)MM_AllocDMA(
                        (giTegra2Vid_FramebufferSize + PAGE_SIZE-1) / PAGE_SIZE,
                        32,
@@ -344,10 +354,12 @@ int Tegra2Vid_int_SetMode(int Mode)
                                );
                
                // Tell hardware
-               *(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_START_ADDR_0) = gTegra2Vid_FramebufferPhys;
-               *(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_ADDR_V_OFFSET_0) = 0;        // Y offset
-               *(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_ADDR_H_OFFSET_0) = 0;        // X offset
+               gpTegra2Vid_IOMem[DC_WINBUF_A_START_ADDR_0] = gTegra2Vid_FramebufferPhys;
+               gpTegra2Vid_IOMem[DC_WINBUF_A_ADDR_V_OFFSET_0] = 0;     // Y offset
+               gpTegra2Vid_IOMem[DC_WINBUF_A_ADDR_H_OFFSET_0] = 0;     // X offset
        }
 
+       gpTegra2Vid_IOMem[DC_CMD_STATE_CONTROL_0] = WIN_A_ACT_REQ;
+       
        return 0;
 }
index c36b05e..7e3fdf5 100644 (file)
@@ -18,11 +18,13 @@ const struct sTegra2_Disp_Mode
        Uint16  HBP, VBP;
 }      caTegra2Vid_Modes[] = {
        // TODO: VESA timings
-//     {720,  487,  16,33,   63, 33,   59, 133},       // NTSC 2
-//     {720,  576,  12,33,   63, 33,   69, 193},       // PAL 2 (VFP shown as 2/33, used 33)
-//     {720,  483,  16, 6,   63,  6,   59,  30},       // 480p
-//     {1280, 720,  70, 5,  804,  6,  220,  20},       // 720p
-//     {1920,1080,  44, 4,  884,  5,  148,  36},       // 1080p
+       {1024, 768,  58, 4,   58,  4,   58,   4},       // 1024x768 (reset), RtS=11,4
+       // TV Timings
+       {720,  487,  16,33,   63, 33,   59, 133},       // NTSC 2
+       {720,  576,  12,33,   63, 33,   69, 193},       // PAL 2 (VFP shown as 2/33, used 33)
+       {720,  483,  16, 6,   63,  6,   59,  30},       // 480p
+       {1280, 720,  70, 5,  804,  6,  220,  20},       // 720p
+       {1920,1080,  44, 4,  884,  5,  148,  36},       // 1080p
        // TODO: Can all but HA/VA be constant and those select the resolution?
 };
 const int ciTegra2Vid_ModeCount = sizeof(caTegra2Vid_Modes)/sizeof(caTegra2Vid_Modes[0]);
@@ -161,6 +163,12 @@ enum eTegra2_Disp_Regs
        DC_WIN_A_BUFFER_ADDR_MODE_0,
        DC_WIN_A_DV_CONTROL_0,
        DC_WIN_A_BLEND_NOKEY_0,
+       DC_WIN_A_BLEND_1WIN_0,
+       DC_WIN_A_BLEND_2WIN_B_0,
+       DC_WIN_A_BLEND_2WIN_C_0,
+       DC_WIN_A_BLEND_3WIN_BC_0,
+       DC_WIN_A_HP_FETCH_CONTROL_0,
+
        
        DC_WINBUF_A_START_ADDR_0 = 0x800,
        DC_WINBUF_A_START_ADDR_NS_0,
@@ -170,5 +178,192 @@ enum eTegra2_Disp_Regs
        DC_WINBUF_A_ADDR_V_OFFSET_NS_0,
 };
 
+#if DEBUG || DUMP_REGISTERS
+const char * const csaTegra2Vid_RegisterNames[] = {
+       [0x000] = "DC_CMD_GENERAL_INCR_SYNCPT_0",
+       "DC_CMD_GENERAL_INCR_SYNCPT_CNTRL_0",
+       "DC_CMD_GENERAL_INCR_SYNCPT_ERROR_0",
+       [0x008] = "DC_CMD_WIN_A_INCR_SYNCPT_0",
+       "DC_CMD_WIN_A_INCR_SYNCPT_CNTRL_0",
+       "DC_CMD_WIN_A_INCR_SYNCPT_ERROR_0",
+       [0x010] = "DC_CMD_WIN_B_INCR_SYNCPT_0",
+       "DC_CMD_WIN_B_INCR_SYNCPT_CNTRL_0",
+       "DC_CMD_WIN_B_INCR_SYNCPT_ERROR_0",
+       [0x018] = "DC_CMD_WIN_C_INCR_SYNCPT_0",
+       "DC_CMD_WIN_C_INCR_SYNCPT_CNTRL_0",
+       "DC_CMD_WIN_C_INCR_SYNCPT_ERROR_0",
+       [0x028] = "DC_CMD_CONT_SYNCPT_VSYNC_0",
+       [0x030] = "DC_CMD_CTXSW_0",
+       "DC_CMD_DISPLAY_COMMAND_OPTION0_0",
+       "DC_CMD_DISPLAY_COMMAND_0",
+       "DC_CMD_SIGNAL_RAISE_0",
+       [0x036] = "DC_CMD_DISPLAY_POWER_CONTROL_0",
+       "DC_CMD_INT_STATUS_0",
+       "DC_CMD_INT_MASK_0",
+       "DC_CMD_INT_ENABLE_0",
+       "DC_CMD_INT_TYPE_0",
+       "DC_CMD_INT_POLARITY_0",
+       "DC_CMD_SIGNAL_RAISE1_0",
+       "DC_CMD_SIGNAL_RAISE2_0",
+       "DC_CMD_SIGNAL_RAISE3_0",
+       
+       [0x040] = "DC_CMD_STATE_ACCESS_0",
+       "DC_CMD_STATE_CONTROL_0",
+       "DC_CMD_DISPLAY_WINDOW_HEADER_0",       // 042
+       "DC_CMD_REG_ACT_CONTROL_0",     // 043
+
+       [0x300] = "DC_COM_CRC_CONTROL_0",
+       "DC_COM_CRC_CHECKSUM_0",        // 301
+       "DC_COM_PIN_OUTPUT_ENABLE0_0",  // 302
+       "DC_COM_PIN_OUTPUT_ENABLE1_0",  // 303
+       "DC_COM_PIN_OUTPUT_ENABLE2_0",  // 304
+       "DC_COM_PIN_OUTPUT_ENABLE3_0",  // 305
+       "DC_COM_PIN_OUTPUT_POLARITY0_0",        // 306
+       "DC_COM_PIN_OUTPUT_POLARITY1_0",        // 307
+       "DC_COM_PIN_OUTPUT_POLARITY2_0",        // 308
+       "DC_COM_PIN_OUTPUT_POLARITY3_0",        // 309
+       "DC_COM_PIN_OUTPUT_DATA0_0",    // 30A
+       "DC_COM_PIN_OUTPUT_DATA1_0",    // 30B
+       "DC_COM_PIN_OUTPUT_DATA2_0",    // 30C
+       "DC_COM_PIN_OUTPUT_DATA3_0",    // 30D
+       "DC_COM_PIN_INPUT_ENABLE0_0",   // 30E
+       "DC_COM_PIN_INPUT_ENABLE1_0",   // 30F
+       "DC_COM_PIN_INPUT_ENABLE2_0",   // 310
+       "DC_COM_PIN_INPUT_ENABLE3_0",   // 311
+       "DC_COM_PIN_INPUT_DATA0_0",     // 312
+       "DC_COM_PIN_INPUT_DATA1_0",     // 313
+       "DC_COM_PIN_OUTPUT_SELECT0_0",  // 314
+       "DC_COM_PIN_OUTPUT_SELECT1_0",  // 315
+       "DC_COM_PIN_OUTPUT_SELECT2_0",  // 316
+       "DC_COM_PIN_OUTPUT_SELECT3_0",  // 317
+       "DC_COM_PIN_OUTPUT_SELECT4_0",  // 318
+       "DC_COM_PIN_OUTPUT_SELECT5_0",  // 319
+       "DC_COM_PIN_OUTPUT_SELECT6_0",  // 31A
+       "DC_COM_PIN_MISC_CONTROL_0",    // 31B
+       // TODO: Complete
+
+       [0x400] = "DC_DISP_DISP_SIGNAL_OPTIONS0_0",
+       "DC_DISP_DISP_SIGNAL_OPTIONS1_0", // 401
+       "DC_DISP_DISP_WIN_OPTIONS_0",   // 402
+       "DC_DISP_MEM_HIGH_PRIORITY_0",  // 403
+       "DC_DISP_MEM_HIGH_PRIORITY_TIMER_0",    // 404
+       "DC_DISP_DISP_TIMING_OPTIONS_0",        // 405
+       "DC_DISP_REF_TO_SYNC_0",        // 406 (TrimSlice 0x0001 000B)
+       "DC_DISP_SYNC_WIDTH_0",         // 407 (TrimSlice 0x0004 003A)
+       "DC_DISP_BACK_PORCH_0",         // 408 (TrimSlice 0x0004 003A)
+       "DC_DISP_DISP_ACTIVE_0",        // 409 (TrimSlice 0x0300 0400)
+       "DC_DISP_FRONT_PORCH_0",        // 40A (TrimSlice 0x0004 003A)
+       "DC_DISP_H_PULSE0_CONTROL_0",   // 40B
+       "DC_DISP_H_PULSE0_POSITION_A_0",        // 40C
+       "DC_DISP_H_PULSE0_POSITION_B_0",        // 40D
+       "DC_DISP_H_PULSE0_POSITION_C_0",        // 40E
+       "DC_DISP_H_PULSE0_POSITION_D_0",        // 40F
+       "DC_DISP_H_PULSE1_CONTROL_0",   // 410
+       "DC_DISP_H_PULSE1_POSITION_A_0",        // 411
+       "DC_DISP_H_PULSE1_POSITION_B_0",        // 412
+       "DC_DISP_H_PULSE1_POSITION_C_0",        // 413
+       "DC_DISP_H_PULSE1_POSITION_D_0",        // 414
+       "DC_DISP_H_PULSE2_CONTROL_0",   // 415
+       "DC_DISP_H_PULSE2_POSITION_A_0",        // 416
+       "DC_DISP_H_PULSE2_POSITION_B_0",        // 417
+       "DC_DISP_H_PULSE2_POSITION_C_0",        // 418
+       "DC_DISP_H_PULSE2_POSITION_D_0",        // 419
+       "DC_DISP_V_PULSE0_CONTROL_0",   // 41A
+       "DC_DISP_V_PULSE0_POSITION_A_0",        // 41B
+       "DC_DISP_V_PULSE0_POSITION_B_0",        // 41C
+       "DC_DISP_V_PULSE0_POSITION_C_0",        // 41D
+       "DC_DISP_V_PULSE1_CONTROL_0",   // 41E
+       "DC_DISP_V_PULSE1_POSITION_A_0",        // 41F
+       "DC_DISP_V_PULSE1_POSITION_B_0",        // 420
+       "DC_DISP_V_PULSE1_POSITION_C_0",        // 421
+       "DC_DISP_V_PULSE2_CONTROL_0",   // 422
+       "DC_DISP_V_PULSE2_POSITION_A_0",        // 423
+       "DC_DISP_V_PULSE3_CONTROL_0",   // 424
+       "DC_DISP_V_PULSE3_POSITION_A_0",        // 425
+       "DC_DISP_M0_CONTROL_0",         // 426
+       "DC_DISP_M1_CONTROL_0",         // 427
+       "DC_DISP_DI_CONTROL_0",         // 428
+       "DC_DISP_PP_CONTROL_0",         // 429
+       "DC_DISP_PP_SELECT_A_0",        // 42A
+       "DC_DISP_PP_SELECT_B_0",        // 42B
+       "DC_DISP_PP_SELECT_C_0",        // 42C
+       "DC_DISP_PP_SELECT_D_0",        // 42D
+       "DC_DISP_DISP_CLOCK_CONTROL_0", // 42E
+       "DC_DISP_DISP_INTERFACE_CONTROL_0",//42F
+       "DC_DISP_DISP_COLOR_CONTROL_0", // 430
+       "DC_DISP_SHIFT_CLOCK_OPTIONS_0",        // 431
+       "DC_DISP_DATA_ENABLE_OPTIONS_0",        // 432
+       "DC_DISP_SERIAL_INTERFACE_OPTIONS_0",   // 433
+       "DC_DISP_LCD_SPI_OPTIONS_0",    // 434
+       "DC_DISP_BORDER_COLOR_0",       // 435
+       "DC_DISP_COLOR_KEY0_LOWER_0",   // 436
+       "DC_DISP_COLOR_KEY0_UPPER_0",   // 437
+       "DC_DISP_COLOR_KEY1_LOWER_0",   // 438
+       "DC_DISP_COLOR_KEY1_UPPER_0",   // 439
+       "_DC_DISP_UNUSED_43A",
+       "_DC_DISP_UNUSED_43B",
+       "DC_DISP_CURSOR_FOREGROUND_0",  // 43C - IMPORTANT
+       "DC_DISP_CURSOR_BACKGROUND_0",  // 43D - IMPORTANT
+       "DC_DISP_CURSOR_START_ADDR_0",  // 43E - IMPORTANT
+       "DC_DISP_CURSOR_START_ADDR_NS_0",       // 43F - IMPORTANT
+       "DC_DISP_CURSOR_POSITION_0",    // 440 - IMPORTANT
+       "DC_DISP_CURSOR_POSITION_NS_0", // 441 - IMPORTANT
+       "DC_DISP_INIT_SEQ_CONTROL_0",   // 442
+       "DC_DISP_SPI_INIT_SEQ_DATA_A_0",        // 443
+       "DC_DISP_SPI_INIT_SEQ_DATA_B_0",        // 444
+       "DC_DISP_SPI_INIT_SEQ_DATA_C_0",        // 445
+       "DC_DISP_SPI_INIT_SEQ_DATA_D_0",        // 446
+
+       [0x480] = "DC_DISP_DC_MCCIF_FIFOCTRL_0",
+       "DC_DISP_MCCIF_DISPLAY0A_HYST_0",       // 481
+       "DC_DISP_MCCIF_DISPLAY0B_HYST_0",       // 482
+       "DC_DISP_MCCIF_DISPLAY0C_HYST_0",       // 483
+       "DC_DISP_MCCIF_DISPLAY1B_HYST_0",       // 484
+
+       [0x4C0] = "DC_DISP_DAC_CRT_CTRL_0",
+       "DC_DISP_DISP_MISC_CONTROL_0",  // 4C1
+
+       [0x500] = "DC_WINC_A_COLOR_PALETTE_0",
+       [0x600] = "DC_WINC_A_PALETTE_COLOR_EXT_0",
+       [0x700] = "DC_WIN_A_WIN_OPTIONS_0",
+       "DC_WIN_A_BYTE_SWAP_0",         // 701
+       "DC_WIN_A_BUFFER_CONTROL_0",    // 702
+       "DC_WIN_A_COLOR_DEPTH_0",       // 703
+       "DC_WIN_A_POSITION_0",          // 704
+       "DC_WIN_A_SIZE_0",              // 705 (TrimSlice 0x0300 0400)
+       "DC_WIN_A_PRESCALED_SIZE_0",
+       "DC_WIN_A_H_INITIAL_DDA_0",
+       "DC_WIN_A_V_INITIAL_DDA_0",
+       "DC_WIN_A_DDA_INCREMENT_0",
+       "DC_WIN_A_LINE_STRIDE_0",
+       "DC_WIN_A_BUF_STRIDE_0",
+       "DC_WIN_A_BUFFER_ADDR_MODE_0",
+       "DC_WIN_A_DV_CONTROL_0",
+       "DC_WIN_A_BLEND_NOKEY_0",
+       "DC_WIN_A_BLEND_1WIN_0",
+       "DC_WIN_A_BLEND_2WIN_B_0",
+       "DC_WIN_A_BLEND_2WIN_C_0",
+       "DC_WIN_A_BLEND_3WIN_BC_0",
+       "DC_WIN_A_HP_FETCH_CONTROL_0",
+       
+       [0x800] = "DC_WINBUF_A_START_ADDR_0",
+       [0x801] = "DC_WINBUF_A_START_ADDR_NS_0",
+       [0x806] = "DC_WINBUF_A_ADDR_H_OFFSET_0",
+       [0x807] = "DC_WINBUF_A_ADDR_H_OFFSET_NS_0",
+       [0x808] = "DC_WINBUF_A_ADDR_V_OFFSET_0",
+       [0x809] = "DC_WINBUF_A_ADDR_V_OFFSET_NS_0",
+       [0x80A] = "DC_WINBUF_A_UFLOW_STATUS"
+};
+#endif
+
+// Bit definitions
+/// \name DC_CMD_STATE_CONTROL_0
+/// \{
+#define GEN_ACT_REQ    0x0001
+#define WIN_A_ACT_REQ  0x0002
+#define WIN_B_ACT_REQ  0x0004
+#define WIN_C_ACT_REQ  0x0008
+/// \}
+
 #endif
 
index 1291113..30844eb 100644 (file)
@@ -24,8 +24,8 @@ const struct sVGA_Timings
         int    HFP, HSync, HDisplay, HBP;
         int    VFP, VSync, VDisplay, VBP;
 } csaTimings[] = {
-       {40, 128, 800, 88,    1, 4, 600, 23},   // SVGA @ 60Hz
-       {24, 136, 1024, 160,  3, 6, 768, 29},   // XGA @ 60Hz
+       {40, 128,  800,  88,  1, 4,  600, 23},  // SVGA @ 60Hz
+       {24, 136, 1024, 160,  3, 6,  768, 29},  // XGA @ 60Hz
        {38, 112, 1280, 248,  1, 3, 1024, 38}   // 1280x1024 @ 60Hz
 };
 const Uint16   caVIAVideo_CardIDs[][2] = {
index da00e99..fe2fc4d 100644 (file)
@@ -8,6 +8,7 @@ Dir "Bin" {
        File "ls" "__BIN__/Bin/ls"
        File "cat" "__BIN__/Bin/cat"
        File "mount" "__BIN__/Bin/mount"
+       File "lspci" "__BIN__/Bin/lspci"
        File "ip" "__BIN__/Bin/ip"
        File "ping" "__BIN__/Bin/ping"
        File "telnet" "__BIN__/Bin/telnet"
@@ -37,7 +38,7 @@ Dir "Apps" {
                }
        }
 }
-#$Dir "Keen5" {
+#Dir "Keen5" {
 #      File "keen5e" "/home/tpg/Projects/AcessPorts/omnispeak/bin/keen5e"
 #      File "EGADICT.CK5"  "/home/tpg/Projects/AcessPorts/omnispeak/bin/original/EGADICT.CK5"
 #      File "EGAGRAPH.CK5" "/home/tpg/Projects/AcessPorts/omnispeak/bin/original/EGAGRAPH.CK5"
@@ -46,4 +47,5 @@ Dir "Apps" {
 #      File "GFXINFOE.CK5" "/home/tpg/Projects/AcessPorts/omnispeak/bin/original/GFXINFOE.CK5"
 #      File "MAPHEAD.CK5"  "/home/tpg/Projects/AcessPorts/omnispeak/bin/original/MAPHEAD.CK5"
 #      File "TILEINFO.CK5" "/home/tpg/Projects/AcessPorts/omnispeak/bin/original/TILEINFO.CK5"
+#      File "ACTION.CK5" "/home/tpg/Projects/AcessPorts/omnispeak/bin/ACTION.CK5"
 #}
index adfc38a..defa50b 100644 (file)
@@ -16,7 +16,7 @@
 
 // === PROTOTYPES ===
  int   RAMFS_Install(char **Arguments);
-void   RAMFS_Cleanup(void);
+ int   RAMFS_Cleanup(void);
 // --- Mount/Unmount ---
 tVFS_Node      *RAMFS_InitDevice(const char *Device, const char **Options);
 void   RAMFS_Unmount(tVFS_Node *Node);
@@ -65,9 +65,9 @@ int RAMFS_Install(char **Arguments)
        return 0;
 }
 
-void RAMFS_Cleanup(void)
+int RAMFS_Cleanup(void)
 {
-       
+       return 0;
 }
 
 
index 90c0b24..16e0f97 100644 (file)
@@ -344,7 +344,9 @@ void IPStack_SendDebugText(const char *Text)
        if( CPU_HAS_LOCK(&lLock) )
                return ;        // Nested!
        SHORTLOCK(&lLock);
+       #if ARCHDIR_is_x86
        __asm__ __volatile__ ("sti");   // Start interrupts (x86 specific)
+       #endif
 
        // Cache packets until a newline
        static char     cache[1500 - (sizeof(pkt_hdr) + 4)];
index 6c6611e..19fd77e 100644 (file)
@@ -13,7 +13,7 @@ CPPFLAGS := -I$(ACESSDIR)/KernelLand/Kernel/include -I$(ACESSDIR)/KernelLand/Ker
 CPPFLAGS += -I$(ACESSDIR)/KernelLand/Modules
 CPPFLAGS += -DARCH=$(ARCH) -DARCH_is_$(ARCH) -DARCHDIR_is_$(ARCHDIR)
 CPPFLAGS += $(_CPPFLAGS)
-CPPFLAGS += $(LIBINCLUDES)
+CPPFLAGS += $(LIBINCLUDES) -ffreestanding
 CFLAGS := -std=gnu99 -Wall -fno-stack-protector -g -O3
 CFLAGS += -Werror
 
index c9ce9a8..cf1a60d 100644 (file)
@@ -30,6 +30,12 @@ int LVM_AddVolume(const tLVM_VolType *Type, const char *Name, void *Ptr, size_t
        tLVM_Format     *fmt;
        void    *first_block;
 
+       if( BlockCount == 0 || BlockSize == 0 ) {
+               Log_Error("LVM", "BlockSize(0x%x)/BlockCount(0x%x) invalid in LVM_AddVolume",
+                       BlockSize, BlockCount);
+               return 1;
+       }
+
        dummy_vol.Type = Type;
        dummy_vol.Ptr = Ptr;
        dummy_vol.BlockCount = BlockCount;
@@ -37,6 +43,10 @@ int LVM_AddVolume(const tLVM_VolType *Type, const char *Name, void *Ptr, size_t
 
        // Read the first block of the volume   
        first_block = malloc(BlockSize);
+       if( !first_block ) {
+               Log_Error("VLM", "LVM_AddVolume - malloc error on %i bytes", BlockSize);
+               return -1;
+       }
        Type->Read(Ptr, 0, 1, first_block);
        
        // Determine Format
index 5f494cb..04a6ab9 100644 (file)
@@ -69,7 +69,7 @@ extern void   USB_Request(tUSBInterface *Dev, int Endpoint, int Type, int Req, int
 // TODO: Async
 extern void    USB_SendData(tUSBInterface *Dev, int Endpoint, size_t Length, const void *Data);
 extern void    USB_RecvData(tUSBInterface *Dev, int Endpoint, size_t Length, void *Data);
-extern void    USB_RecvDataA(tUSBInterface *Dev, int Endpoint, size_t Length, void *DataBuf, tUSB_DataCallback Callback);
+extern void    USB_RecvDataA(tUSBInterface *Dev, int Endpoint, size_t Length, void *DataBuf);
 
 #endif
 
index ab37279..8b4f96d 100644 (file)
@@ -15,24 +15,40 @@ typedef struct sUSBHostDef  tUSBHostDef;
 
 typedef void   (*tUSBHostCb)(void *DataPtr, void *Data, size_t Length);
 
-typedef void   *(*tUSBHostOp)(void *Ptr, int Dest, int DataTgl, tUSBHostCb CB, void *CbData, void *Data, size_t Length);
-typedef void   *(*tUSBIntOp)(void *Ptr, int Dest, int Period, tUSBHostCb CB, void *CbData, void *Data, size_t Length);
+typedef void   *(*tUSBInitInt)(void *Ptr, int Endpt, int bOutbound, int Period, tUSBHostCb Cb, void *CbData, void *Buf, size_t Len);
+typedef void   *(*tUSBInit)(void *Ptr, int Endpt, size_t MaxPacketSize);
+typedef void   *(*tUSBDataOp)(void *Dest, tUSBHostCb Cb, void *CbData, void *Data, size_t Length);
+
+typedef void   *(*tUSBControlOp)(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData,
+       int bOutbound,  // (1) SETUP, OUT, IN vs (0) SETUP, IN, OUT
+       const void *SetupData, size_t SetupLength,
+       const void *OutData, size_t OutLength,
+       void *InData, size_t InLength
+       );
+typedef void   *(*tUSBBulkOp)(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData,
+       int bOutbound, void *Data, size_t Length
+       );
+typedef void   *(*tUSBIsochOp)(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData,
+       int bOutbound, void *Data, size_t Length, int When
+       );
 
 /**
  * \brief Defines a USB Host Controller type
  */
 struct sUSBHostDef
 {
-       tUSBIntOp       InterruptIN;
-       tUSBIntOp       InterruptOUT;
-       void    (*StopInterrupt)(void *Ptr, void *Handle);
-
-       void    *(*ControlSETUP)(void *Ptr, int Dest, int DataTgl, void *Data, size_t Length);
-       tUSBHostOp      ControlIN;
-       tUSBHostOp      ControlOUT;
+       tUSBInitInt     InitInterrupt;
+       tUSBInit        InitIsoch;
+       tUSBInit        InitControl;
+       tUSBInit        InitBulk;
+       void    (*RemEndpoint)(void *Ptr, void *Handle);
        
-       tUSBHostOp      BulkIN;
-       tUSBHostOp      BulkOUT;
+       // NOTE: If \a Cb is ERRPTR, the handle returned must be free'd by the calling code
+       //       otherwise the controller will free it once done
+       tUSBIsochOp     SendIsoch;
+       tUSBControlOp   SendControl;
+       tUSBBulkOp      SendBulk;
+       void    (*FreeOp)(void *Ptr, void *Handle);
 
        void    (*CheckPorts)(void *Ptr);
 };
index e20f53c..9a0e2bc 100644 (file)
@@ -43,6 +43,7 @@ tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts)
        host->RootHubDev.ParentHub = NULL;
        host->RootHubDev.Host = host;
        host->RootHubDev.Address = 0;
+       host->RootHubDev.EndpointHandles[0] = HostDef->InitControl(ControllerPtr, 0, 64);
 
 //     host->RootHubIf.Next = NULL;
        host->RootHubIf.Dev = &host->RootHubDev;
index 0b6a3c1..24cd80a 100644 (file)
@@ -35,6 +35,7 @@ struct sUSBEndpoint
        tUSBInterface   *Interface;
         int    EndpointIdx;    // Interface endpoint index
         int    EndpointNum;    // Device endpoint num
+       void    *EndpointHandle;
        
         int    PollingPeriod;  // In 1ms intervals
         int    MaxPacketSize;  // In bytes
@@ -74,6 +75,8 @@ struct sUSBDevice
        tUSBHost        *Host;
         int    Address;
 
+       void    *EndpointHandles[16];
+
        struct sDescriptor_Device       DevDesc;
 
         int    nInterfaces;
index d260f62..6143bdb 100644 (file)
@@ -5,7 +5,7 @@
  * usb_devinit.c
  * - USB Device Initialisation
  */
-#define DEBUG  1
+#define DEBUG  0
 #include <acess.h>
 #include <vfs.h>
 #include <drv_pci.h>
@@ -21,6 +21,7 @@ void  USB_DeviceDisconnected(tUSBHub *Hub, int Port);
 void   *USB_GetDeviceDataPtr(tUSBInterface *Dev);
 void   USB_SetDeviceDataPtr(tUSBInterface *Dev, void *Ptr);
  int   USB_int_AllocateAddress(tUSBHost *Host);
+void   USB_int_DeallocateAddress(tUSBHost *Host, int Address);
 
 // === CODE ===
 void USB_DeviceConnected(tUSBHub *Hub, int Port)
@@ -49,14 +50,32 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
        }
        USB_int_SendSetupSetAddress(dev->Host, dev->Address);
        LOG("Assigned address %i", dev->Address);
-       
+
+       dev->EndpointHandles[0] = dev->Host->HostDef->InitControl(dev->Host->Ptr, dev->Address << 4, 64);
+       for( int i = 1; i < 16; i ++ )
+               dev->EndpointHandles[i] = 0;
+
        // 2. Get device information
        {
                struct sDescriptor_Device       desc;
+               desc.Length = 0;
                LOG("Getting device descriptor");
                // Endpoint 0, Desc Type 1, Index 0
                USB_int_ReadDescriptor(dev, 0, 1, 0, sizeof(desc), &desc);
 
+               if( desc.Length < sizeof(desc) ) {
+                       Log_Error("USB", "Device descriptor undersized (%i<%i)", desc.Length, sizeof(desc));
+                       USB_int_DeallocateAddress(dev->Host, dev->Address);
+                       LEAVE('-');
+                       return;
+               }
+               if( desc.Type != 1 ) {
+                       Log_Error("USB", "Device descriptor type invalid (%i!=1)", desc.Type);
+                       USB_int_DeallocateAddress(dev->Host, dev->Address);
+                       LEAVE('-');
+                       return;
+               }
+
                #if DUMP_DESCRIPTORS            
                LOG("Device Descriptor = {");
                LOG(" .Length = %i", desc.Length);
@@ -75,7 +94,7 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                LOG(" .NumConfigurations = %i", desc.NumConfigurations);
                LOG("}");
        
-               #if DEBUG       
+               #if DEBUG
                if( desc.ManufacturerStr )
                {
                        char    *tmp = USB_int_GetDeviceString(dev, 0, desc.ManufacturerStr);
@@ -106,9 +125,8 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                memcpy(&dev->DevDesc, &desc, sizeof(desc));
        }
 
-       // TODO: Support alternate configurations
-       
        // 3. Get configurations
+       // TODO: Support alternate configurations
        for( int i = 0; i < 1; i ++ )
        {
                struct sDescriptor_Configuration        desc;
@@ -117,6 +135,12 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                size_t  total_length;
        
                USB_int_ReadDescriptor(dev, 0, 2, i, sizeof(desc), &desc);
+               if( desc.Length < sizeof(desc) ) {
+                       // ERROR: 
+               }
+               if( desc.Type != 2 ) {
+                       // ERROR: 
+               }
                // TODO: Check return length? (Do we get a length?)
                #if DUMP_DESCRIPTORS
                LOG("Configuration Descriptor %i = {", i);
@@ -232,7 +256,14 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                                LOG(" .MaxPacketSize = %i", LittleEndian16(endpt->MaxPacketSize));
                                LOG(" .PollingInterval = %i", endpt->PollingInterval);
                                LOG("}");
-                               
+       
+                               // Make sure things don't break
+                               if( !((endpt->Address & 0x7F) < 15) ) {
+                                       Log_Error("USB", "Endpoint number %i>16", endpt->Address & 0x7F);
+                                       k --;
+                                       continue ;
+                               }
+
                                dev_if->Endpoints[k].Next = NULL;
                                dev_if->Endpoints[k].Interface = dev_if;
                                dev_if->Endpoints[k].EndpointIdx = k;
@@ -242,6 +273,33 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                                dev_if->Endpoints[k].Type = endpt->Attributes | (endpt->Address & 0x80);
                                dev_if->Endpoints[k].PollingAtoms = 0;
                                dev_if->Endpoints[k].InputData = NULL;
+                               
+                               // TODO: Register endpoint early
+                                int    ep_num = endpt->Address & 15;
+                               if( dev->EndpointHandles[ep_num] ) {
+                                       Log_Notice("USB", "Device %p:%i ep %i reused", dev->Host->Ptr, dev->Address, ep_num);
+                               }
+                               else {
+                                        int    addr = dev->Address*16+ep_num;
+                                        int    mps = dev_if->Endpoints[k].MaxPacketSize;
+                                       void *handle = NULL;
+                                       switch( endpt->Attributes & 3)
+                                       {
+                                       case 0: // Control
+                                               handle = dev->Host->HostDef->InitControl(dev->Host->Ptr, addr, mps);
+                                               break;
+                                       case 1: // Isochronous
+                                       //      handle = dev->Host->HostDef->InitIsoch(dev->Host->Ptr, addr, mps);
+                                               break;
+                                       case 2: // Bulk
+                                               handle = dev->Host->HostDef->InitBulk(dev->Host->Ptr, addr, mps);
+                                               break;
+                                       case 3: // Interrupt
+                                       //      handle = dev->Host->HostDef->InitInterrupt(dev->Host->Ptr, addr, ...);
+                                               break;
+                                       }
+                                       dev->EndpointHandles[ep_num] = handle;
+                               }
                        }
                        
                        // Initialise driver
@@ -266,14 +324,35 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                
                free(full_buf);
        }
-
+       
+       Hub->Devices[Port] = dev;
+       
        // Done.
        LEAVE('-');
 }
 
 void USB_DeviceDisconnected(tUSBHub *Hub, int Port)
 {
-       
+       tUSBDevice      *dev;
+       if( !Hub->Devices[Port] ) {
+               Log_Error("USB", "Non-registered device disconnected");
+               return;
+       }
+       dev = Hub->Devices[Port];
+
+       // TODO: Free related resources
+       // - Endpoint registrations
+       for( int i = 0; i < 16; i ++ )
+       {
+               if(dev->EndpointHandles[i])
+                       dev->Host->HostDef->RemEndpoint(dev->Host->Ptr, dev->EndpointHandles[i]);
+       }
+
+       // - Bus Address
+       USB_int_DeallocateAddress(dev->Host, dev->Address);
+       // - Inform handler
+       // - Allocate memory
+       free(dev);
 }
 
 void *USB_GetDeviceDataPtr(tUSBInterface *Dev) { return Dev->Data; }
index 9d58c75..de6f6f1 100644 (file)
@@ -45,7 +45,7 @@ void USB_Request(tUSBInterface *Iface, int Endpoint, int Type, int Req, int Valu
        else
                endpt = 0;
        
-       USB_int_Request(Iface->Dev->Host, Iface->Dev->Address, endpt, Type, Req, Value, Index, Len, Data);
+       USB_int_Request(Iface->Dev, endpt, Type, Req, Value, Index, Len, Data);
 }
 
 
@@ -53,22 +53,21 @@ void USB_SendData(tUSBInterface *Dev, int Endpoint, size_t Length, const void *D
 {
        tUSBHost *host;
        tUSBEndpoint    *ep;
+       void    *dest_hdl;
        ENTER("pDev iEndpoint iLength pData", Dev, Endpoint, Length, Data);
 
-       ep = &Dev->Endpoints[Endpoint-1];
        host = Dev->Dev->Host;
+       ep = &Dev->Endpoints[Endpoint-1];
+       dest_hdl = Dev->Dev->EndpointHandles[ep->EndpointNum];
+       LOG("dest_hdl = %p", dest_hdl);
+       if( !dest_hdl ) {
+               Log_Notice("USB", "_SendData on uninitialised enpoint (%p#%i)", Dev->Dev, ep->EndpointNum);
+               LEAVE('-');
+               return;
+       }
 
        Threads_ClearEvent(THREAD_EVENT_SHORTWAIT);
-       for( size_t ofs = 0; ofs < Length; ofs += ep->MaxPacketSize )
-       {
-               size_t  len = MIN(Length - ofs, ep->MaxPacketSize);
-               
-               host->HostDef->BulkOUT(
-                       host->Ptr, Dev->Dev->Address*16 + Dev->Endpoints[Endpoint-1].EndpointNum,
-                       0, (len == Length - ofs ? USB_WakeCallback : NULL), Proc_GetCurThread(),
-                       (char*)Data + ofs, len
-                       );
-       }
+       host->HostDef->SendBulk(host->Ptr, dest_hdl, USB_WakeCallback, Proc_GetCurThread(), 1, (void*)Data, Length);
        Threads_WaitEvents(THREAD_EVENT_SHORTWAIT);
        
        LEAVE('-');
@@ -78,31 +77,31 @@ void USB_RecvData(tUSBInterface *Dev, int Endpoint, size_t Length, void *Data)
 {
        tUSBHost *host;
        tUSBEndpoint    *ep;
+       void    *dest_hdl;
        ENTER("pDev iEndpoint iLength pData", Dev, Endpoint, Length, Data);
 
-       ep = &Dev->Endpoints[Endpoint-1];
        host = Dev->Dev->Host;
+       ep = &Dev->Endpoints[Endpoint-1];
+       dest_hdl = Dev->Dev->EndpointHandles[ep->EndpointNum];
+       LOG("dest_hdl = %p", dest_hdl);
+       if( !dest_hdl ) {
+               Log_Notice("USB", "_RecvData on uninitialised enpoint (%p#%i)", Dev->Dev, ep->EndpointNum);
+               LEAVE('-');
+               return;
+       }
 
        Threads_ClearEvent(THREAD_EVENT_SHORTWAIT);
-       for( size_t ofs = 0; ofs < Length; ofs += ep->MaxPacketSize )
-       {
-               size_t  len = MIN(Length - ofs, ep->MaxPacketSize);
-               
-               host->HostDef->BulkIN(
-                       host->Ptr, Dev->Dev->Address*16 + Dev->Endpoints[Endpoint-1].EndpointNum,
-                       0, (len == Length - ofs ? USB_WakeCallback : NULL), Proc_GetCurThread(),
-                       (char*)Data + ofs, len
-                       );
-       }
+       host->HostDef->SendBulk(host->Ptr, dest_hdl, USB_WakeCallback, Proc_GetCurThread(), 0, Data, Length);
        Threads_WaitEvents(THREAD_EVENT_SHORTWAIT);
        
        LEAVE('-');
 }
 
-void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, size_t Length, void *DataBuf, tUSB_DataCallback Callback)
+void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, size_t Length, void *DataBuf)
 {
        tAsyncOp *op;
        tUSBHost *host;
+       void    *dest_hdl;
 
        ENTER("pDev iEndpoint iLength pDataBuf", Dev, Endpoint, Length, DataBuf); 
 
@@ -112,22 +111,16 @@ void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, size_t Length, void *DataBu
        op->Length = Length;
        op->Data = DataBuf;
 
-       // TODO: Handle transfers that are larger than one packet
-       // TODO: Data toggle
-
        host = Dev->Dev->Host;
+       dest_hdl = Dev->Dev->EndpointHandles[op->Endpt->EndpointNum];
+       if( !dest_hdl ) {
+               Log_Notice("USB", "_SendData on uninitialised enpoint (%p#%i)", Dev->Dev, op->Endpt->EndpointNum);
+               LEAVE('-');
+               return;
+       }
        
        LOG("IN from %p %i:%i", host->Ptr, Dev->Dev->Address, op->Endpt->EndpointNum);
-       for( size_t ofs = 0; ofs < Length; ofs += op->Endpt->MaxPacketSize )
-       {
-               size_t  len = MIN(Length - ofs, op->Endpt->MaxPacketSize);
-               
-               host->HostDef->BulkIN(
-                       host->Ptr, Dev->Dev->Address*16 + op->Endpt->EndpointNum,
-                       0, (len == Length - ofs ? USB_AsyncCallback : NULL), op,
-                       (char*)DataBuf + ofs, len
-                       );
-       }
+       host->HostDef->SendBulk(host->Ptr, dest_hdl, USB_AsyncCallback, op, 0, DataBuf, Length);
        
        LEAVE('-');
 
index dce7c33..57948ce 100644 (file)
@@ -14,7 +14,7 @@
 #include <events.h>
 
 // === PROTOTYPES ===
-void   *USB_int_Request(tUSBHost *Host, int Addr, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data);
+void   *USB_int_Request(tUSBDevice *Dev, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data);
 void   USB_int_WakeThread(void *Thread, void *Data, size_t Length);
  int   USB_int_SendSetupSetAddress(tUSBHost *Host, int Address);
  int   USB_int_ReadDescriptor(tUSBDevice *Dev, int Endpoint, int Type, int Index, int Length, void *Dest);
@@ -22,16 +22,28 @@ char        *USB_int_GetDeviceString(tUSBDevice *Dev, int Endpoint, int Index);
  int   _UTF16to8(Uint16 *Input, int InputLen, char *Dest);
 
 // === CODE ===
-void *USB_int_Request(tUSBHost *Host, int Addr, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data)
+void *USB_int_Request(tUSBDevice *Device, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data)
 {
+       tUSBHost        *Host = Device->Host;
        void    *hdl;
        // TODO: Sanity check (and check that Type is valid)
        struct sDeviceRequest   req;
-        int    dest = Addr * 16 + EndPt;       // TODO: Validate
        tThread *thisthread = Proc_GetCurThread();
+       void *dest_hdl;
+
+       ENTER("pDevice xEndPt iType iReq iVal iIndx iLen pData",
+               Device, EndPt, Type, Req, Val, Indx, Len, Data);
        
-       ENTER("pHost xdest iType iReq iVal iIndx iLen pData",
-               Host, dest, Type, Req, Val, Indx, Len, Data);
+       if( EndPt < 0 || EndPt >= 16 ) {
+               LEAVE('n');
+               return NULL;
+       }
+
+       dest_hdl = Device->EndpointHandles[EndPt];
+       if( !dest_hdl ) {
+               LEAVE('n');
+               return NULL;
+       }
        
        req.ReqType = Type;
        req.Request = Req;
@@ -41,36 +53,22 @@ void *USB_int_Request(tUSBHost *Host, int Addr, int EndPt, int Type, int Req, in
 
        Threads_ClearEvent(THREAD_EVENT_SHORTWAIT);
 
-       LOG("SETUP");   
-       hdl = Host->HostDef->ControlSETUP(Host->Ptr, dest, 0, &req, sizeof(req));
-
-       // TODO: Data toggle?
-       // TODO: Multi-packet transfers
-       if( Len > 0 )
-       {
-               if( Type & 0x80 )
-               {
-                       LOG("IN");
-                       hdl = Host->HostDef->ControlIN(Host->Ptr, dest, 1, NULL, NULL, Data, Len);
-       
-                       LOG("OUT (Status)");
-                       hdl = Host->HostDef->ControlOUT(Host->Ptr, dest, 1, USB_int_WakeThread, thisthread, NULL, 0);
-               }
-               else
-               {
-                       LOG("OUT");
-                       Host->HostDef->ControlOUT(Host->Ptr, dest, 1, NULL, NULL, Data, Len);
-                       
-                       // Status phase (DataToggle=1)
-                       LOG("IN (Status)");
-                       hdl = Host->HostDef->ControlIN(Host->Ptr, dest, 1, USB_int_WakeThread, thisthread, NULL, 0);
-               }
+       LOG("Send");
+       if( Type & 0x80 ) {
+               // Inbound data
+               hdl = Host->HostDef->SendControl(Host->Ptr, dest_hdl, USB_int_WakeThread, thisthread, 0,
+                       &req, sizeof(req),
+                       NULL, 0,
+                       Data, Len
+                       );
        }
-       else
-       {
-               // Zero length, IN status
-               LOG("IN (Status)");
-               hdl = Host->HostDef->ControlIN(Host->Ptr, dest, 1, USB_int_WakeThread, thisthread, NULL, 0);
+       else {
+               // Outbound data
+               hdl = Host->HostDef->SendControl(Host->Ptr, dest_hdl, USB_int_WakeThread, thisthread, 1,
+                       &req, sizeof(req),
+                       Data, Len,
+                       NULL, 0
+                       );
        }
        LOG("Wait...");
        Threads_WaitEvents(THREAD_EVENT_SHORTWAIT);
@@ -86,19 +84,22 @@ void USB_int_WakeThread(void *Thread, void *Data, size_t Length)
 
 int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address)
 {
-       USB_int_Request(Host, 0, 0, 0x00, 5, Address & 0x7F, 0, 0, NULL);
+       USB_int_Request(&Host->RootHubDev, 0, 0x00, 5, Address & 0x7F, 0, 0, NULL);
        return 0;
 }
 
 int USB_int_ReadDescriptor(tUSBDevice *Dev, int Endpoint, int Type, int Index, int Length, void *Dest)
 {
-       const int       ciMaxPacketSize = 0x400;
        struct sDeviceRequest   req;
-        int    bToggle = 0;
-        int    dest = Dev->Address*16 + Endpoint;
+       void    *dest_hdl;
+       
+       dest_hdl = Dev->EndpointHandles[Endpoint];
+       if( !dest_hdl ) {
+               return -1;
+       }
 
-       ENTER("pDev xdest iType iIndex iLength pDest",
-               Dev, dest, Type, Index, Length, Dest);
+       ENTER("pDev xEndpoint iType iIndex iLength pDest",
+               Dev, Endpoint, Type, Index, Length, Dest);
 
        req.ReqType = 0x80;
        req.ReqType |= ((Type >> 8) & 0x3) << 5;        // Bits 5/6
@@ -109,36 +110,19 @@ int USB_int_ReadDescriptor(tUSBDevice *Dev, int Endpoint, int Type, int Index, i
        req.Index = LittleEndian16( 0 );        // TODO: Language ID / Interface
        req.Length = LittleEndian16( Length );
 
-       LOG("SETUP");   
-       Dev->Host->HostDef->ControlSETUP(Dev->Host->Ptr, dest, 0, &req, sizeof(req));
-       
-       bToggle = 1;
-       while( Length > ciMaxPacketSize )
-       {
-               LOG("IN (%i rem)", Length - ciMaxPacketSize);
-               Dev->Host->HostDef->ControlIN(
-                       Dev->Host->Ptr, dest,
-                       bToggle, NULL, NULL,
-                       Dest, ciMaxPacketSize
-                       );
-               bToggle = !bToggle;
-               Length -= ciMaxPacketSize;
-       }
-
-       LOG("IN (final)");
-       Dev->Host->HostDef->ControlIN( Dev->Host->Ptr, dest, bToggle, NULL, NULL, Dest, Length );
-
        Threads_ClearEvent(THREAD_EVENT_SHORTWAIT);
-       LOG("OUT (Status)");
-       Dev->Host->HostDef->ControlOUT(
-               Dev->Host->Ptr, dest, 1,
-               USB_int_WakeThread, Proc_GetCurThread(),
-               NULL, 0
+       
+       LOG("Send");
+       Dev->Host->HostDef->SendControl(Dev->Host->Ptr, dest_hdl, USB_int_WakeThread, Proc_GetCurThread(), 0,
+               &req, sizeof(req),
+               NULL, 0,
+               Dest, Length
                );
 
        LOG("Waiting");
+       // TODO: Detect errors?
        Threads_WaitEvents(THREAD_EVENT_SHORTWAIT);
-
+       
        LEAVE('i', 0);
        return 0;
 }
index 9159cba..4282f28 100644 (file)
@@ -8,7 +8,7 @@
 #ifndef _USB_LOWLEVEL_H_
 #define _USB_LOWLEVEL_H_
 
-extern void    *USB_int_Request(tUSBHost *Host, int Addr, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data);
+extern void    *USB_int_Request(tUSBDevice *Dev, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data);
 extern int     USB_int_SendSetupSetAddress(tUSBHost *Host, int Address);
 extern int     USB_int_ReadDescriptor(tUSBDevice *Dev, int Endpoint, int Type, int Index, int Length, void *Dest);
 extern char    *USB_int_GetDeviceString(tUSBDevice *Dev, int Endpoint, int Index);
index 9cdd6b4..a32e08e 100644 (file)
@@ -61,10 +61,9 @@ void USB_StartPollingEndpoint(tUSBInterface *Iface, int Endpoint)
 
        endpt->InputData = malloc(endpt->MaxPacketSize);
        LOG("Polling 0x%x at %i ms", Iface->Dev->Address * 16 + endpt->EndpointNum, endpt->PollingPeriod);
-       Iface->Dev->Host->HostDef->InterruptIN(
-               Iface->Dev->Host->Ptr,
-               Iface->Dev->Address * 16 + endpt->EndpointNum,
-               endpt->PollingPeriod,
+       Iface->Dev->Host->HostDef->InitInterrupt(
+               Iface->Dev->Host->Ptr, Iface->Dev->Address * 16 + endpt->EndpointNum,
+               0, endpt->PollingPeriod,
                USB_int_PollCallback, endpt,
                endpt->InputData, endpt->MaxPacketSize
                );
diff --git a/KernelLand/Modules/USB/EHCI/Makefile b/KernelLand/Modules/USB/EHCI/Makefile
new file mode 100644 (file)
index 0000000..069d030
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Acess2 EHCI Driver
+#
+
+OBJ = ehci.o
+CPPFLAGS = -I../Core/include
+NAME = EHCI
+
+-include ../Makefile.tpl
diff --git a/KernelLand/Modules/USB/EHCI/ehci.c b/KernelLand/Modules/USB/EHCI/ehci.c
new file mode 100644 (file)
index 0000000..8a316e3
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * Acess2 EHCI Driver
+ * - By John Hodge (thePowersGang)
+ * 
+ * ehci.c
+ * - Driver Core
+ */
+#define DEBUG  1
+#define VERSION        VER2(0,1)
+#include <acess.h>
+#include <modules.h>
+#include <usb_host.h>
+#include "ehci.h"
+#include <drv_pci.h>
+#include <limits.h>
+
+// === CONSTANTS ===
+#define EHCI_MAX_CONTROLLERS   4
+
+// === PROTOTYPES ===
+ int   EHCI_Initialise(char **Arguments);
+ int   EHCI_Cleanup(void);
+ int   EHCI_InitController(tPAddr BaseAddress, Uint8 InterruptNum);
+void   EHCI_InterruptHandler(int IRQ, void *Ptr);
+// -- API ---
+void   *EHCI_InitInterrupt(void *Ptr, int Endpoint, int bInput, int Period, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length);
+void   *EHCI_InitIsoch  (void *Ptr, int Endpoint, size_t MaxPacketSize);
+void   *EHCI_InitControl(void *Ptr, int Endpoint, size_t MaxPacketSize);
+void   *EHCI_InitBulk   (void *Ptr, int Endpoint, size_t MaxPacketSize);
+void   EHCI_RemEndpoint(void *Ptr, void *Handle);
+void   *EHCI_SendControl(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData,
+       int isOutbound,
+       const void *SetupData, size_t SetupLength,
+       const void *OutData, size_t OutLength,
+       void *InData, size_t InLength
+       );
+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);
+// --- 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);
+tEHCI_QH       *EHCI_int_AllocateQH(tEHCI_Controller *Cont, int Endpoint, size_t MaxPacketSize);
+void   EHCI_int_DeallocateQH(tEHCI_Controller *Cont, tEHCI_QH *QH);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, VERSION, USB_EHCI, EHCI_Initialise, NULL, "USB_Core", NULL);
+tEHCI_Controller       gaEHCI_Controllers[EHCI_MAX_CONTROLLERS];
+tUSBHostDef    gEHCI_HostDef = {
+       .InitInterrupt = EHCI_InitInterrupt,
+       .InitIsoch     = EHCI_InitIsoch,
+       .InitBulk      = EHCI_InitBulk,
+       .RemEndpoint   = EHCI_RemEndpoint,
+       .SendIsoch   = NULL,
+       .SendControl = EHCI_SendControl,
+       .SendBulk    = EHCI_SendBulk,
+       .FreeOp      = EHCI_FreeOp
+       };
+
+// === CODE ===
+int EHCI_Initialise(char **Arguments)
+{
+       for( int id = -1; (id = PCI_GetDeviceByClass(0x0C0320, 0xFFFFFF, id)) >= 0;  )
+       {
+               Uint32  addr = PCI_GetBAR(id, 0);
+               if( addr == 0 ) {
+                       // Oops, PCI BIOS emulation time
+               }
+               Uint8   irq = PCI_GetIRQ(id);
+               if( irq == 0 ) {
+                       // TODO: The same
+               }
+
+               if( EHCI_InitController(addr, irq) ) {
+                       // TODO: Detect other forms of failure than "out of slots"
+                       break ;
+               }
+       }
+       return 0;
+}
+
+int EHCI_Cleanup(void)
+{
+       return 0;
+}
+
+// --- Driver Init ---
+int EHCI_InitController(tPAddr BaseAddress, Uint8 InterruptNum)
+{
+       tEHCI_Controller        *cont = NULL;
+
+       for( int i = 0; i < EHCI_MAX_CONTROLLERS; i ++ )
+       {
+               if( gaEHCI_Controllers[i].PhysBase == 0 ) {
+                       cont = &gaEHCI_Controllers[i];
+                       cont->PhysBase = BaseAddress;
+                       break;
+               }
+       }
+
+       if(!cont) {
+               return 1;
+       }
+
+       // -- Build up structure --
+       cont->CapRegs = (void*)MM_MapHWPages(BaseAddress, 1);
+       // TODO: Error check
+       cont->OpRegs = (void*)( (Uint32*)cont->CapRegs + cont->CapRegs->CapLength / 4 );
+       // - Allocate periodic queue
+       cont->PeriodicQueue = (void*)MM_AllocDMA(1, 32, NULL);
+       // TODO: Error check
+       //  > Populate queue
+
+       // -- Bind IRQ --
+       IRQ_AddHandler(InterruptNum, EHCI_InterruptHandler, cont);
+
+       // -- Initialisation procedure (from ehci-r10) --
+       // - Reset controller
+       cont->OpRegs->USBCmd = USBCMD_HCReset;
+       // - Set CTRLDSSEGMENT (TODO: 64-bit support)
+       // - Set USBINTR
+       cont->OpRegs->USBIntr = USBINTR_IOC|USBINTR_PortChange|USBINTR_FrameRollover;
+       // - Set PERIODICLIST BASE
+       cont->OpRegs->PeridocListBase = MM_GetPhysAddr( cont->PeriodicQueue );
+       // - Enable controller
+       cont->OpRegs->USBCmd = (0x40 << 16) | USBCMD_PeriodicEnable | USBCMD_Run;
+       // - Route all ports
+       cont->OpRegs->ConfigFlag = 1;
+       
+       return 0;
+}
+
+void EHCI_InterruptHandler(int IRQ, void *Ptr)
+{
+       tEHCI_Controller *cont = Ptr;
+       Uint32  sts = cont->OpRegs->USBSts;
+       
+       // Clear interrupts
+       cont->OpRegs->USBSts = sts;     
+
+       if( sts & USBINTR_IOC ) {
+               // IOC
+               sts &= ~USBINTR_IOC;
+       }
+
+       if( sts & USBINTR_PortChange ) {
+               // Port change, determine what port and poke helper thread
+               sts &= ~USBINTR_PortChange;
+       }
+       
+       if( sts & USBINTR_FrameRollover ) {
+               // Frame rollover, used to aid timing (trigger per-second operations)
+               sts &= ~USBINTR_FrameRollover;
+       }
+
+       if( sts ) {
+               // Unhandled interupt bits
+               // TODO: Warn
+       }
+}
+
+// --------------------------------------------------------------------
+// USB API
+// --------------------------------------------------------------------
+void *EHCI_InitInterrupt(void *Ptr, int Endpoint, int bOutbound, int Period,
+       tUSBHostCb Cb, void *CbData, void *Buf, size_t Length)
+{
+       tEHCI_Controller        *Cont = Ptr;
+        int    pow2period, period_pow;
+       
+       if( Endpoint >= 256*16 )
+               return NULL;
+       if( Period <= 0 )
+               return NULL;
+       if( Period > 256 )
+               Period = 256;
+
+       // Round the period to the closest power of two
+       pow2period = 1;
+       period_pow = 0;
+       // - Find the first power above the period
+       while( pow2period < Period )
+       {
+               pow2period *= 2;
+               period_pow ++;
+       }
+       // - Check which is closest
+       if( Period - pow2period / 2 > pow2period - Period )
+               Period = pow2period;
+       else {
+               Period = pow2period/2;
+               period_pow --;
+       }
+       
+       // Allocate a QH
+       tEHCI_QH *qh = EHCI_int_AllocateQH(Cont, Endpoint, Length);
+       qh->Impl.IntPeriodPow = period_pow;
+
+       // Choose an interrupt slot to use      
+       int minslot = 0, minslot_load = INT_MAX;
+       for( int slot = 0; slot < Period; slot ++ )
+       {
+                int    load = 0;
+               for( int i = 0; i < PERIODIC_SIZE; i += Period )
+                       load += Cont->InterruptLoad[i+slot];
+               if( load == 0 ) break;
+               if( load < minslot_load ) {
+                       minslot = slot;
+                       minslot_load = load;
+               }
+       }
+       // Increase loading on the selected slot
+       for( int i = 0; i < PERIODIC_SIZE; i += Period )
+               Cont->InterruptLoad[i+minslot] += 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);
+
+       // Insert into the periodic list
+
+       return qh;
+}
+
+void *EHCI_InitIsoch(void *Ptr, int Endpoint, size_t MaxPacketSize)
+{
+       return (void*)(tVAddr)(Endpoint + 1);
+}
+void *EHCI_InitControl(void *Ptr, int Endpoint, size_t MaxPacketSize)
+{
+       tEHCI_Controller *Cont = Ptr;
+       
+       // Allocate a QH
+       tEHCI_QH *qh = EHCI_int_AllocateQH(Cont, Endpoint, MaxPacketSize);
+
+       // Append to async list 
+       if( Cont->LastAsyncHead ) {
+               Cont->LastAsyncHead->HLink = MM_GetPhysAddr(qh)|2;
+               Cont->LastAsyncHead->Impl.Next = qh;
+       }
+       else
+               Cont->OpRegs->AsyncListAddr = MM_GetPhysAddr(qh)|2;
+       Cont->LastAsyncHead = qh;
+
+       return qh;
+}
+void *EHCI_InitBulk(void *Ptr, int Endpoint, size_t MaxPacketSize)
+{
+       return EHCI_InitControl(Ptr, Endpoint, MaxPacketSize);
+}
+void EHCI_RemEndpoint(void *Ptr, void *Handle)
+{
+       if( Handle == NULL )
+               return ;
+       else if( (tVAddr)Handle <= 256*16 )
+               return ;        // Isoch
+       else {
+               // Remove QH from list
+               // - If it's a polling endpoint, need to remove from all periodic lists
+               
+               // Deallocate QH
+               EHCI_int_DeallocateQH(Ptr, Handle);
+       }
+}
+
+void *EHCI_SendControl(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData,
+       int isOutbound,
+       const void *SetupData, size_t SetupLength,
+       const void *OutData, size_t OutLength,
+       void *InData, size_t InLength
+       )
+{
+       tEHCI_Controller *Cont = Ptr;
+       tEHCI_qTD       *td_setup, *td_data, *td_status;
+
+       // Sanity checks
+       if( (tVAddr)Dest <= 256*16 )
+               return NULL;
+
+       // Check size of SETUP and status
+       
+       // Allocate TDs
+       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_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_status = EHCI_int_AllocateTD(Cont, PID_OUT, (void*)OutData, OutLength, Cb, CbData);
+       }
+
+       // Append TDs
+       EHCI_int_AppendTD(Dest, td_setup);
+       EHCI_int_AppendTD(Dest, td_data);
+       EHCI_int_AppendTD(Dest, td_status);
+
+       return td_status;
+}
+
+void *EHCI_SendBulk(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData, int Dir, void *Data, size_t Length)
+{
+       tEHCI_Controller        *Cont = Ptr;
+       
+       // Sanity check the pointer
+       // - Can't be NULL or an isoch
+       if( (tVAddr)Dest <= 256*16 )
+               return NULL;
+       
+       // Allocate single TD
+       tEHCI_qTD       *td = EHCI_int_AllocateTD(Cont, (Dir ? PID_OUT : PID_IN), Data, Length, Cb, CbData);
+       EHCI_int_AppendTD(Dest, td);    
+
+       return td;
+}
+
+void EHCI_FreeOp(void *Ptr, void *Handle)
+{
+       tEHCI_Controller        *Cont = Ptr;
+
+       EHCI_int_DeallocateTD(Cont, Handle);
+}
+
+// --------------------------------------------------------------------
+// Internals
+// --------------------------------------------------------------------
+tEHCI_qTD *EHCI_int_AllocateTD(tEHCI_Controller *Cont, int PID, void *Data, size_t Length, tUSBHostCb Cb, void *CbData)
+{
+       return NULL;
+}
+
+void EHCI_int_DeallocateTD(tEHCI_Controller *Cont, tEHCI_qTD *TD)
+{
+}
+
+void EHCI_int_AppendTD(tEHCI_QH *QH, tEHCI_qTD *TD)
+{
+}
+
+tEHCI_QH *EHCI_int_AllocateQH(tEHCI_Controller *Cont, int Endpoint, size_t MaxPacketSize)
+{
+       return NULL;
+}
+
+void EHCI_int_DeallocateQH(tEHCI_Controller *Cont, tEHCI_QH *QH)
+{
+}
+
index 431b039..f76b93b 100644 (file)
@@ -8,6 +8,16 @@
 #ifndef _EHCI_H_
 #define _EHCI_H_
 
+#define PERIODIC_SIZE  1024
+
+typedef struct sEHCI_CapRegs   tEHCI_CapRegs;
+typedef struct sEHCI_OpRegs    tEHCI_OpRegs;
+typedef struct sEHCI_iTD       tEHCI_iTD;
+typedef struct sEHCI_siTD      tEHCI_siTD;
+typedef struct sEHCI_qTD       tEHCI_qTD;
+typedef struct sEHCI_QH        tEHCI_QH;
+typedef struct sEHCI_Controller        tEHCI_Controller;
+
 struct sEHCI_CapRegs
 {
        Uint8   CapLength;      // Byte offset of Operational registers
@@ -152,5 +162,98 @@ struct sEHCI_OpRegs
        Uint32  PortSC[15];
 };
 
+#define USBCMD_Run     0x0001
+#define USBCMD_HCReset 0x0002
+#define USBCMD_PeriodicEnable  0x0010
+#define USBCMD_AsyncEnable     0x0020
+
+#define USBINTR_IOC    0x0001
+#define USBINTR_Error  0x0002
+#define USBINTR_PortChange     0x0004
+#define USBINTR_FrameRollover  0x0008
+#define USBINTR_HostSystemError        0x0010
+#define USBINTR_AsyncAdvance   0x0020
+
+// Isochronous (High-Speed) Transfer Descriptor
+struct sEHCI_iTD
+{
+       Uint32  Link;
+       struct {
+               Uint16  Offset;
+               Uint16  LengthSts;
+       } Transactions[8];
+       // -- 0 --
+       // 0:6  - Device
+       // 7    - Reserved
+       // 8:11 - Endpoint
+       // -- 1 --
+       // 0:10 - Max packet size
+       // 11   - IN/OUT
+       Uint32  BufferPointers[8];      // Page aligned, low 12 bits are overloaded
+};
+
+// Split Transaction Isochronous Transfer Descriptor
+struct sEHCI_siTD
+{
+       Uint32  Link;
+       Uint32  Dest;
+       Uint32  uFrame;
+       Uint32  StatusLength;
+       Uint32  Page0;
+       Uint32  Page1;
+       Uint32  BackLink;
+};
+
+// Queue Element Transfer Descriptor
+struct sEHCI_qTD
+{
+       Uint32  Link;
+       Uint32  Link2;  // Used when there's a short packet
+       Uint32  Token;
+       Uint32  Pages[5];       //First has offset in low 12 bits
+       
+       // Internals (32 bytes = 4x 64-bit pointers)
+       tUSBHostCb      *Callback;
+       void    *CallbackData;
+       tEHCI_qTD       *Next;
+} __attribute__((aligned(32)));
+// sizeof = 64
+
+// Queue Head
+struct sEHCI_QH
+{
+       Uint32  HLink;  // Horizontal link
+       Uint32  Endpoint;
+       Uint32  EndpointExt;
+       Uint32  CurrentTD;
+       tEHCI_qTD       Overlay;
+       struct {
+               Uint8   IntOfs;
+               Uint8   IntPeriodPow;
+               tEHCI_QH        *Next;
+       } Impl;
+} __attribute__((aligned(32)));
+// sizeof = 48 (64)
+
+#define PID_OUT        0
+#define PID_IN         1
+#define PID_SETUP      2
+
+struct sEHCI_Controller
+{
+       tPAddr  PhysBase;
+       tEHCI_CapRegs   *CapRegs;
+       tEHCI_OpRegs    *OpRegs;
+
+        int    InterruptLoad[PERIODIC_SIZE];
+       tEHCI_QH        *LastAsyncHead;
+       
+       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)];
+};
+
 #endif
 
index 6b36809..c280273 100644 (file)
@@ -149,7 +149,7 @@ void HID_DeviceConnected(tUSBInterface *Dev, void *Descriptors, size_t Descripto
        
        // --- Read and parse report descriptor ---
        // NOTE: Also does sub-driver selection and initialisation
-       Uint8   *report_data = alloca(report_len);
+       Uint8   report_data[report_len];
        USB_ReadDescriptor(Dev, 0x1022, 0, report_len, report_data);
        HID_int_ParseReport(Dev, report_data, report_len, &gHID_RootCallbacks);
        
index 257171a..0fe80dc 100644 (file)
@@ -35,14 +35,19 @@ tUHCI_TD    *UHCI_int_AllocateTD(tUHCI_Controller *Cont);
 void   UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_QH *QH, tUHCI_TD *TD);
 tUHCI_TD       *UHCI_int_CreateTD(tUHCI_Controller *Cont, int Addr, Uint8 Type, int bTgl, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length);
 // --- API
-void   *UHCI_InterruptIN(void *Ptr, int Dest, int Period, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length);
-void   *UHCI_InterruptOUT(void *Ptr, int Dest, int Period, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length);
-void   UHCI_StopInterrupt(void *Ptr, void *Handle);
-void   *UHCI_ControlSETUP(void *Ptr, int Dest, int Tgl, void *Data, size_t Length);
-void   *UHCI_ControlOUT(void *Ptr, int Dest, int Tgl, tUSBHostCb Cb, void *CbData, void *Data, size_t Length);
-void   *UHCI_ControlIN(void *Ptr, int Dest, int Tgl, tUSBHostCb Cb, void *CbData, void *Data, size_t Length);
-void   *UHCI_BulkOUT(void *Ptr, int Dest, int bToggle, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length);
-void   *UHCI_BulkIN(void *Ptr, int Dest, int bToggle, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length);
+void   *UHCI_InitInterrupt(void *Ptr, int Endpt, int bOutbound, int Period, tUSBHostCb Cb, void *CbData, void *Buf, size_t Len);
+void   *UHCI_InitIsoch(void *Ptr, int Endpt, size_t MaxPacketSize);
+void   *UHCI_InitControl(void *Ptr, int Endpt, size_t MaxPacketSize);
+void   *UHCI_InitBulk(void *Ptr, int Endpt, size_t MaxPacketSize);
+void   UHCI_RemoveEndpoint(void *Ptr, void *EndptHandle);
+void   *UHCI_SendIsoch(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData, int Dir, void *Data, size_t Length, int When);
+void   *UHCI_SendControl(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData,
+       int isOutbound,
+       const void *SetupData, size_t SetupLength,
+       const void *OutData, size_t OutLength,
+       void *InData, size_t InLength
+       );
+void   *UHCI_SendBulk(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData, int Dir, void *Data, size_t Length);
 
 void   UHCI_CheckPortUpdate(void *Ptr);
 void   UHCI_int_InterruptThread(void *Unused);
@@ -58,18 +63,22 @@ MODULE_DEFINE(0, VERSION, USB_UHCI, UHCI_Initialise, NULL, "USB_Core", NULL);
 tUHCI_TD       *gaUHCI_TDPool;
 tUHCI_Controller       gUHCI_Controllers[MAX_CONTROLLERS];
 tUSBHostDef    gUHCI_HostDef = {
-       .InterruptIN   = UHCI_InterruptIN,
-       .InterruptOUT  = UHCI_InterruptOUT,
-       .StopInterrupt = UHCI_StopInterrupt,
+       .InitInterrupt = UHCI_InitInterrupt,
+//     .InitIsoch     = UHCI_InitIsoch,
+       .InitControl   = UHCI_InitControl,
+       .InitBulk      = UHCI_InitBulk,
+       .RemEndpoint   = UHCI_RemoveEndpoint,
        
-       .ControlSETUP = UHCI_ControlSETUP,
-       .ControlIN    = UHCI_ControlIN,
-       .ControlOUT   = UHCI_ControlOUT,
-
-       .BulkOUT = UHCI_BulkOUT,
-       .BulkIN = UHCI_BulkIN,
+//     .SendIsoch   = UHCI_SendIsoch,
+       .SendControl = UHCI_SendControl,
+       .SendBulk    = UHCI_SendBulk,
+       .FreeOp      = NULL,
        
-       .CheckPorts = UHCI_CheckPortUpdate
+       .CheckPorts = UHCI_CheckPortUpdate,
+//     .ClearPortFeature = NULL,
+//     .GetBusState      = NULL,
+//     .GetPortStatus    = NULL,
+//     .SetPortFeature   = NULL
        };
 tSemaphore     gUHCI_InterruptSempahore;
 
@@ -481,135 +490,227 @@ void UHCI_int_SetInterruptPoll(tUHCI_Controller *Cont, tUHCI_TD *TD, int Period)
        UHCI_int_AppendTD(Cont, qh, TD);
 }
 
-void *UHCI_InterruptIN(void *Ptr, int Dest, int Period, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length)
+// --------------------------------------------------------------------
+// API
+// --------------------------------------------------------------------
+void *UHCI_InitInterrupt(void *Ptr, int Endpt, int bOutbound,
+       int Period, tUSBHostCb Cb, void *CbData, void *Buf, size_t Len)
 {
        tUHCI_TD        *td;
-
-       if( Period < 0 )        return NULL;
-
-       ENTER("pPtr xDest iPeriod pCb pCbData pBuf iLength",
-               Ptr, Dest, Period, Cb, CbData, Buf, Length);
+       if( Period <= 0 )       return NULL;
+       
+       ENTER("pPtr xEndpt bbOutbound iPeriod pCb pCbData pBuf iLen",
+               Ptr, Endpt, bOutbound, Period, Cb, CbData, Buf, Len);
 
        // TODO: Data toggle?
-       td = UHCI_int_CreateTD(Ptr, Dest, PID_IN, 0, Cb, CbData, Buf, Length);
+       td = UHCI_int_CreateTD(Ptr, Endpt, (bOutbound ? PID_OUT : PID_IN), 0, Cb, CbData, Buf, Len);
        if( !td )       return NULL;
        
        UHCI_int_SetInterruptPoll(Ptr, td, Period);
-       
-       LEAVE('p', td); 
+
+       LEAVE('p', td);
        return td;
 }
-// TODO: Does interrupt OUT make sense?
-void *UHCI_InterruptOUT(void *Ptr, int Dest, int Period, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length)
+
+void *UHCI_int_InitEndpt(tUHCI_Controller *Cont, int Type, int Endpt, size_t MaxPacketSize)
 {
-       tUHCI_TD        *td;
+       if( Endpt >= 256*16 )
+               return NULL;    
 
-       if( Period < 0 )        return NULL;
+       if( MaxPacketSize > MAX_PACKET_SIZE) {
+               Log_Warning("UHCI", "MaxPacketSize for %x greater than controller max (%i > %i)",
+                       Endpt, MaxPacketSize, MAX_PACKET_SIZE);
+               return NULL;
+       }
 
-       ENTER("pPtr xDest iPeriod pCb pCbData pBuf, iLength",
-               Ptr, Dest, Period, Cb, CbData, Buf, Length);
+       if( Cont->DevInfo[Endpt / 16] == NULL ) {
+               Cont->DevInfo[Endpt / 16] = calloc( 1, sizeof(*Cont->DevInfo[0]) );
+       }
+       tUHCI_EndpointInfo *epi = &Cont->DevInfo[Endpt/16]->EndpointInfo[Endpt%16];
+       if( epi->Type ) {
+               // oops, in use
+               Log_Warning("UHCI", "Endpoint %x reused?", Endpt);
+               return NULL;
+       }
 
-       // TODO: Data toggle?
-       td = UHCI_int_CreateTD(Ptr, Dest, PID_OUT, 0, Cb, CbData, Buf, Length);
-       if( !td )       return NULL;
-       
-       UHCI_int_SetInterruptPoll(Ptr, td, Period);
+       epi->MaxPacketSize = MaxPacketSize;
+       epi->Type = Type;
+       epi->Tgl = 0;
+
+       return (void*)(tVAddr)(Endpt+1);
 
-       LEAVE('p', td); 
-       return td;
 }
 
-void UHCI_StopInterrupt(void *Ptr, void *Handle)
+void *UHCI_InitControl(void *Ptr, int Endpt, size_t MaxPacketSize)
 {
-       // TODO: Stop interrupt transaction
-       Log_Error("UHCI", "TODO: Implement UHCI_StopInterrupt");
+       return UHCI_int_InitEndpt(Ptr, 1, Endpt, MaxPacketSize);
 }
 
-void *UHCI_ControlSETUP(void *Ptr, int Dest, int Tgl, void *Data, size_t Length)
+void *UHCI_InitBulk(void *Ptr, int Endpt, size_t MaxPacketSize)
 {
-       tUHCI_Controller        *Cont = Ptr;
-       tUHCI_QH        *qh = &Cont->TDQHPage->ControlQH;
-       tUHCI_TD        *td;
+       return UHCI_int_InitEndpt(Ptr, 2, Endpt, MaxPacketSize);
+}
 
-       ENTER("pPtr xDest iTgl pData iLength", Ptr, Dest, Tgl, Data, Length);
+void UHCI_RemoveEndpoint(void *Ptr, void *Handle)
+{
+       tUHCI_Controller *Cont = Ptr;
+       if( Handle == NULL )
+               return ;
        
-       td = UHCI_int_CreateTD(Cont, Dest, PID_SETUP, Tgl, NULL, NULL, Data, Length);
-       UHCI_int_AppendTD(Cont, qh, td);
-
-       LEAVE('p', td); 
-
-       return td;
+       if( (tVAddr)Handle <= 256*16 ) {
+                int    addr = (tVAddr)Handle;
+               Cont->DevInfo[addr/16]->EndpointInfo[addr%16].Type = 0;
+       }
+       else {
+               // TODO: Stop interrupt transaction
+               Log_Error("UHCI", "TODO: Implement stopping interrupt polling");
+       }
 }
-void *UHCI_ControlOUT(void *Ptr, int Dest, int Tgl, tUSBHostCb Cb, void *CbData, void *Data, size_t Length)
+
+void *UHCI_SendControl(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData,
+       int bOutbound,  // (1) SETUP, OUT, IN vs (0) SETUP, IN, OUT
+       const void *SetupData, size_t SetupLength,
+       const void *OutData, size_t OutLength,
+       void *InData, size_t InLength
+       )
 {
+       ENTER("pPtr pEndpt ibOutbound", Ptr, Endpt, bOutbound);
+       
        tUHCI_Controller        *Cont = Ptr;
        tUHCI_QH        *qh = &Cont->TDQHPage->ControlQH;
        tUHCI_TD        *td;
+       tUHCI_EndpointInfo *epi;
+        int    dest, tgl;
+       size_t  mps;
 
-       ENTER("pPtr xDest iTgl pCb pCbData pData iLength", Ptr, Dest, Tgl, Cb, CbData, Data, Length);
+       if( Endpt == NULL ) {
+               Log_Error("UHCI", "Passed a NULL Endpoint handle");
+               LEAVE('n');
+               return NULL;
+       }
 
-       td = UHCI_int_CreateTD(Cont, Dest, PID_OUT, Tgl, Cb, CbData, Data, Length);
-       UHCI_int_AppendTD(Cont, qh, td);
+       // Sanity check Endpt
+       if( (tVAddr)Endpt > 0x800 ) {
+               LEAVE('n');
+               return NULL;
+       }
+       dest = (tVAddr)Endpt - 1;
+       if( Cont->DevInfo[dest/16] == NULL )    LEAVE_RET('n', NULL);
+       epi = &Cont->DevInfo[dest/16]->EndpointInfo[dest%16];
+       if( epi->Type != 1 )    LEAVE_RET('n', NULL);
+       mps = epi->MaxPacketSize;
+       tgl = epi->Tgl;
+
+       // TODO: Build up list and then append to QH in one operation
+
+       char    *data_ptr, *status_ptr;
+       size_t  data_len,   status_len;
+       Uint8   data_pid,   status_pid;
+       
+       if( bOutbound ) {
+               data_pid   = PID_OUT; data_ptr   = (void*)OutData; data_len   = OutLength;
+               status_pid = PID_IN;  status_ptr = InData;  status_len = InLength;
+       }
+       else {
+               data_pid   = PID_IN;  data_ptr   = InData;  data_len   = InLength;
+               status_pid = PID_OUT; status_ptr = (void*)OutData; status_len = OutLength;
+       }
 
-       LEAVE('p', td);
-       return td;
-}
-void *UHCI_ControlIN(void *Ptr, int Dest, int Tgl, tUSBHostCb Cb, void *CbData, void *Data, size_t Length)
-{
-       tUHCI_Controller        *Cont = Ptr;
-       tUHCI_QH        *qh = &Cont->TDQHPage->ControlQH;
-       tUHCI_TD        *td;
+       // Sanity check data lengths
+       if( SetupLength > mps ) LEAVE_RET('n', NULL);
+       if( status_len > mps )  LEAVE_RET('n', NULL);
 
-       ENTER("pPtr xDest iTgl pCb pCbData pData iLength", Ptr, Dest, Tgl, Cb, CbData, Data, Length);
-       
-       td = UHCI_int_CreateTD(Cont, Dest, PID_IN, !!Tgl, Cb, CbData, Data, Length);
+       // Create and append SETUP packet
+       td = UHCI_int_CreateTD(Cont, dest, PID_SETUP, tgl, NULL, NULL, (void*)SetupData, SetupLength);
        UHCI_int_AppendTD(Cont, qh, td);
+       tgl = !tgl;
 
-       LEAVE('p', td);
+       // Send data packets
+       while( data_len > 0 )
+       {
+               size_t len = MIN(data_len, mps);
+               td = UHCI_int_CreateTD(Cont, dest, data_pid, tgl, NULL, NULL, data_ptr, len);
+               UHCI_int_AppendTD(Cont, qh, td);
+               tgl = !tgl;
+               
+               data_ptr += len;
+               data_len -= len;
+       }
+       
+       // Send status
+       td = UHCI_int_CreateTD(Cont, dest, status_pid, tgl, Cb, CbData, status_ptr, status_len);
+       UHCI_int_AppendTD(Cont, qh, td);
+       tgl = !tgl;
+       
+       // Update toggle value
+       epi->Tgl = tgl;
+       
+       LEAVE('p', td); 
        return td;
 }
 
-void *UHCI_BulkOUT(void *Ptr, int Dest, int bToggle, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length)
+void *UHCI_SendBulk(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData, int bOutbound, void *Data, size_t Length)
 {
        tUHCI_Controller        *Cont = Ptr;
        tUHCI_QH        *qh = &Cont->TDQHPage->BulkQH;
-       tUHCI_TD        *td;
-       char    *src = Buf;
+       tUHCI_TD        *td = NULL;
+       tUHCI_EndpointInfo *epi;
+        int    dest, tgl;
+       size_t  mps;
 
-       ENTER("pPtr xDest ibToggle pCb pCbData pData iLength", Ptr, Dest, bToggle, Cb, CbData, Buf, Length);
+       ENTER("pPtr pEndpt pCb pCbData bOutbound pData iLength", Ptr, Dest, Cb, CbData, bOutbound, Data, Length);
 
-       if( Length > MAX_PACKET_SIZE ) {
-               Log_Error("UHCI", "Passed an oversized packet by the USB code (%i > %i)", Length, MAX_PACKET_SIZE);
+       if( Endpt == NULL ) {
+               Log_Error("UHCI", "_SendBulk passed a NULL endpoint handle");
                LEAVE('n');
+               return NULL;
        }
-       
-       td = UHCI_int_CreateTD(Cont, Dest, PID_OUT, bToggle, Cb, CbData, src, Length);
-       UHCI_int_AppendTD(Cont, qh, td);
-
-       LEAVE('p', td);
-       return td;
-}
-void *UHCI_BulkIN(void *Ptr, int Dest, int bToggle, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length)
-{
-       tUHCI_Controller        *Cont = Ptr;
-       tUHCI_QH        *qh = &Cont->TDQHPage->BulkQH;
-       tUHCI_TD        *td;
-       char    *dst = Buf;
 
-       ENTER("pPtr xDest ibToggle pCb pCbData pData iLength", Ptr, Dest, bToggle, Cb, CbData, Buf, Length);
-       if( Length > MAX_PACKET_SIZE ) {
-               Log_Error("UHCI", "Passed an oversized packet by the USB code (%i > %i)", Length, MAX_PACKET_SIZE);
+       // Sanity check Endpt
+       if( (tVAddr)Endpt > 256*16 ) {
+               Log_Error("UHCI", "_SendBulk passed an interrupt endpoint handle");
                LEAVE('n');
+               return NULL;
        }
+       dest = (tVAddr)Endpt - 1;
+       if( Cont->DevInfo[dest/16] == NULL ) {
+               Log_Error("UHCI", "_SendBulk passed an uninitialised handle");
+               LEAVE('n');
+               return NULL;
+       }
+       epi = &Cont->DevInfo[dest/16]->EndpointInfo[dest%16];
+       if( epi->Type != 2 ) {
+               Log_Error("UHCI", "_SendBulk passed an invalid endpoint type (%i!=2)", epi->Type);
+               LEAVE('n');
+               return NULL;
+       }
+       tgl = epi->Tgl;
+       mps = epi->MaxPacketSize;
 
-       td = UHCI_int_CreateTD(Cont, Dest, PID_IN, bToggle, Cb, CbData, dst, Length);
-       UHCI_int_AppendTD(Cont, qh, td);
+       Uint8   pid = (bOutbound ? PID_OUT : PID_IN);
+
+       char *pos = Data;
+       while( Length > 0 )
+       {
+               size_t len = MIN(mps, Length);
+
+               td = UHCI_int_CreateTD(Cont, dest, pid, tgl, Cb, (len == Length ? CbData : NULL), pos, len);
+               UHCI_int_AppendTD(Cont, qh, td);
+               
+               pos += len;
+               Length -= len;
+               tgl = !tgl;
+       }
+       
+       epi->Tgl = tgl;
 
        LEAVE('p', td);
        return td;
 }
 
+// ==========================
 // === INTERNAL FUNCTIONS ===
+// ==========================
 void UHCI_CheckPortUpdate(void *Ptr)
 {
        tUHCI_Controller        *Host = Ptr;
index 6eff0eb..fbbeba3 100644 (file)
@@ -8,6 +8,7 @@
 
 // === TYPES ===
 typedef struct sUHCI_Controller        tUHCI_Controller;
+typedef struct sUHCI_EndpointInfo      tUHCI_EndpointInfo;
 typedef struct sUHCI_ExtraTDInfo       tUHCI_ExtraTDInfo;
 
 typedef struct sUHCI_TD        tUHCI_TD;
@@ -24,8 +25,14 @@ struct sUHCI_ExtraTDInfo
        void    *CallbackPtr;
 };
 
-#define TD_CTL_IOC     (1 << 24)
+struct sUHCI_EndpointInfo
+{
+       unsigned MaxPacketSize : 12;
+       unsigned Type : 3;
+       unsigned Tgl : 1;
+};
 
+#define TD_CTL_IOC     (1 << 24)
 #define TD_CTL_ACTIVE  (1 << 23)
 #define TD_CTL_STALLED (1 << 22)
 #define TD_CTL_DATABUFERR      (1 << 21)
@@ -113,7 +120,6 @@ struct sUHCI_QH
         */
        Uint32  Next;
 
-       
        /**
         * \brief Next Entry in list
         * 
@@ -200,6 +206,10 @@ struct sUHCI_Controller
                
                tUHCI_TD        LocalTDPool[ (4096-(128+2)*sizeof(tUHCI_QH)) / sizeof(tUHCI_TD) ];
        }       *TDQHPage;
+       
+       struct {
+               tUHCI_EndpointInfo EndpointInfo[16];
+       } *DevInfo[256];
 };
 
 // === ENUMERATIONS ===
index 01b0906..e16a7b2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,8 +15,8 @@ USRLIBS += libreadline.so libnet.so liburi.so libpsocket.so
 USRLIBS += libimage_sif.so
 
 USRAPPS := init login CLIShell cat ls mount
-USRAPPS += bomb dhcpclient
-USRAPPS += ip ping telnet irc wget telnetd
+USRAPPS += bomb lspci
+USRAPPS += ip dhcpclient ping telnet irc wget telnetd
 USRAPPS += axwin3
 
 ALL_DYNMODS = $(addprefix all-,$(DYNMODS))
index 14d5065..7b0ad8c 100644 (file)
@@ -51,6 +51,7 @@ endif
 DRIVERS := 
 MODULES :=
 
+MODULES += Filesystems/RAMDisk
 MODULES += Filesystems/Ext2
 MODULES += Filesystems/FAT
 MODULES += Filesystems/NTFS
diff --git a/Notes/SIF.txt b/Notes/SIF.txt
new file mode 100644 (file)
index 0000000..57c1fa7
--- /dev/null
@@ -0,0 +1,28 @@
+=== Simple Image Format ===
+
+U16    Magic   0x51F0  - This determines the endianness of the file
+U16    Flags
+       > 0-2: Compression (0: Uncompressed, 1: RLE, 2: zlib, 3: RLE-Channel)
+       > 3-5: Format (0: ARGB, 1: RGB
+U16    Width
+U16    Height
+<DATA>
+
+
+=== Compression Formats ===
+0 - Uncompressed
+       The file data is a linear sequence of Width * Height 32-bit ARGB
+       words (in file endianness, determined by the magic)
+
+1 - RLE-4
+       7-bit length followed by a 32-bit value that is repeated `n` times
+       (if bit 7 of the length byte is set, the next `n` 32-bit words are
+       verbatim)
+
+2 - zlib
+       The image data is a zlib stream of 32-bit xRGB words
+
+3 - RLE-Channel
+       The data is the alpha values, followed by red, then green, then blue
+       encoded as RLE with a 7-bit length and a verbatim flag (same as mode
+       1, except with 8-bit values instead of 32-bit) 
diff --git a/RunQemu b/RunQemu
index aeb68c3..74316df 100755 (executable)
--- a/RunQemu
+++ b/RunQemu
@@ -3,8 +3,9 @@
 
 QEMU=qemu-system-x86_64
 USE_GDB=
+BOOTOPT="-fda DiskImage.img -boot a"
 
-QEMU_PARAMS="-fda DiskImage.img -boot a"
+QEMU_PARAMS=""
 QEMU_PARAMS=$QEMU_PARAMS" -hda AcessHDD.img"
 QEMU_PARAMS=$QEMU_PARAMS" -vga std"
 QEMU_PARAMS=$QEMU_PARAMS" -smp 2"
@@ -17,6 +18,18 @@ while [ $# -ne 0 ]; do
        -gdb)
                QEMU_PARAMS=$QEMU_PARAMS" -s -S"
                ;;
+       -dbin)
+               shift
+               if [ "x$2" = "xdefault" ] || [ "x$2" = "x" ]; then
+                       _kfile="KernelLand/Acess2.$1.bin"
+               else
+                       _kfile="KernelLand/Acess2.$1-$2.bin"
+               fi
+               BOOTOPT="-kernel $_kfile"
+               BOOTOPT=$BOOTOPT" -initrd KernelLand/Modules/Filesystems/FS_InitRD.kmd.$1 -append $3"
+               shift
+               shift
+               ;;
        -dbgbin)
                QEMU=/home/tpg/apps/bin/qemu-system-x86_64
                ;;
@@ -54,8 +67,9 @@ 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 $QEMU_PARAMS -serial stdio | tee QemuLog.txt
+       $QEMU $BOOTOPT $QEMU_PARAMS -serial stdio | tee QemuLog.txt
 else
-       $QEMU $QEMU_PARAMS -serial stdio
+       $QEMU $BOOTOPT $QEMU_PARAMS -serial stdio
 fi
index 8a75c21..5ac59f4 100644 (file)
--- a/TODO.txt
+++ b/TODO.txt
@@ -47,9 +47,11 @@ TODO:
  > Text editor (with a GP formatted text field?)
  > Maybe a basic web browser using the surface support?
  > Port freetype for nice font support
+ > Configuration (via lib/server)
 
 - Omnispeak
  > Debug speed issues (tracing agian)
  > Port to AxWin3
+ > Trace memory corruption
 
 - Port dropbear!
index ff2347b..7eff8c9 100644 (file)
@@ -132,5 +132,7 @@ static inline void SHORTLOCK(tShortSpinlock *Lock) {
 }
 static inline void SHORTREL(tShortSpinlock *m) { *m = 0; }
 
+static inline intptr_t MM_GetPhysAddr(void *Ptr) { return 1; }
+
 #endif
 
index 7abed27..24889fa 100644 (file)
@@ -352,7 +352,7 @@ void Command_Dir(int argc, char **argv)
        \r
        fileName = (char*)(tmpPath+dirLen);\r
        // Read Directory Content\r
-       while( (fp = readdir(dp, fileName)) )\r
+       while( (fp = SysReadDir(dp, fileName)) )\r
        {\r
                if(fp < 0)\r
                {\r
index e5ef7ea..0e89a7c 100644 (file)
@@ -8,7 +8,8 @@ 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 `$(CC) -print-libgcc-file-name`
+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
+LIBGCC_PATH = $(shell $(CC) -print-libgcc-file-name)
 
 # Extra-verbose errors!
 #CFLAGS += -Wall -Wextra -Wwrite-strings -Wshadow -Wswitch-default -Wswitch-enum -Wstrict-overflow=5 -Wfloat-equal -Wundef -Wmissing-declarations -Wlogical-op
index 27cf9e5..c1245ae 100644 (file)
@@ -35,9 +35,9 @@ $(_BIN): $(OUTPUTDIR)Libs/acess.ld $(OUTPUTDIR)Libs/crt0.o $(_LIBS) $(OBJ)
        @mkdir -p $(dir $(_BIN))
        @echo [LD] -o $@
 ifneq ($(_DBGMAKEFILE),)
-       $(LD) -g $(LDFLAGS) -o $@ $(OBJ) -Map $(_OBJPREFIX)Map.txt
+       $(LD) -g $(LDFLAGS) -o $@ $(OBJ) -Map $(_OBJPREFIX)Map.txt $(LIBGCC_PATH)
 else
-       @$(LD) -g $(LDFLAGS) -o $@ $(OBJ) -Map $(_OBJPREFIX)Map.txt
+       @$(LD) -g $(LDFLAGS) -o $@ $(OBJ) -Map $(_OBJPREFIX)Map.txt $(LIBGCC_PATH)
 endif
        @$(DISASM) $(_BIN) > $(_OBJPREFIX)$(BIN).dsm
 
diff --git a/Usermode/Applications/axwin2_src/Makefile b/Usermode/Applications/axwin2_src/Makefile
deleted file mode 100644 (file)
index 89f1584..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-
-NAME = AxWin2
-DIRS = WM Shell_src
-
-SUBMAKE = $(MAKE) --no-print-directory
-
-all:
-       @$(foreach DIR,$(DIRS), echo --- $(NAME)/$(DIR) && $(SUBMAKE) -C $(DIR) $@ &&) true
-install:
-       @$(foreach DIR,$(DIRS), echo --- $(NAME)/$(DIR) && $(SUBMAKE) -C $(DIR) $@ &&) true
-
-clean:
-       @$(foreach DIR,$(DIRS), $(SUBMAKE) -C $(DIR) $@ &&) true
diff --git a/Usermode/Applications/axwin2_src/SIF.txt b/Usermode/Applications/axwin2_src/SIF.txt
deleted file mode 100644 (file)
index 57c1fa7..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-=== Simple Image Format ===
-
-U16    Magic   0x51F0  - This determines the endianness of the file
-U16    Flags
-       > 0-2: Compression (0: Uncompressed, 1: RLE, 2: zlib, 3: RLE-Channel)
-       > 3-5: Format (0: ARGB, 1: RGB
-U16    Width
-U16    Height
-<DATA>
-
-
-=== Compression Formats ===
-0 - Uncompressed
-       The file data is a linear sequence of Width * Height 32-bit ARGB
-       words (in file endianness, determined by the magic)
-
-1 - RLE-4
-       7-bit length followed by a 32-bit value that is repeated `n` times
-       (if bit 7 of the length byte is set, the next `n` 32-bit words are
-       verbatim)
-
-2 - zlib
-       The image data is a zlib stream of 32-bit xRGB words
-
-3 - RLE-Channel
-       The data is the alpha values, followed by red, then green, then blue
-       encoded as RLE with a 7-bit length and a verbatim flag (same as mode
-       1, except with 8-bit values instead of 32-bit) 
diff --git a/Usermode/Applications/axwin2_src/Shell_src/Makefile b/Usermode/Applications/axwin2_src/Shell_src/Makefile
deleted file mode 100644 (file)
index 55744b9..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# Project: Acess GUI Default Shell
-
--include ../../Makefile.cfg
-
-CPPFLAGS +=
-LDFLAGS += -laxwin2
-
-DIR = Apps/AxWin/1.0
-BIN = Shell
-OBJ = main.o
-
--include ../../Makefile.tpl
diff --git a/Usermode/Applications/axwin2_src/Shell_src/main.c b/Usermode/Applications/axwin2_src/Shell_src/main.c
deleted file mode 100644 (file)
index f1c0416..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Acess2 GUI Test App
- * - By John Hodge (thePowersGang)
- */
-#include <axwin2/axwin.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-// === CONSTANTS ===
-enum eTerminal_Events
-{
-       EVENT_NULL,
-       EVENT_NEW_TAB,
-       EVENT_CLOSE_TAB,
-       EVENT_EXIT
-};
-
-// === PROTOTYPES ===
- int   main(int argc, char *argv[]);
- int   Global_HandleMessage(tAxWin_Message *Message);
- int   Shell_HandleMessage(tAxWin_Message *Message);
-
-// === GLOBALS ===
-tAxWin_Element *geConsole;
-
-// === CODE ===
-int main(int argc, char *argv[])
-{
-       tAxWin_Element  *menu, *tab;
-       
-       if(argc != 1)
-       {
-               fprintf(stderr, "Usage: %s\n", argv[0]);
-               fprintf(stderr, "\tThis application takes no arguments\n");
-               return 0;
-       }
-
-       AxWin_Register("Terminal", Global_HandleMessage);
-
-       menu = AxWin_AddMenuItem(NULL, "File", 0);
-       AxWin_AddMenuItem(menu, "&New Tab\tCtrl-Shift-N", EVENT_NEW_TAB);
-       AxWin_AddMenuItem(menu, NULL, 0);
-       AxWin_AddMenuItem(menu, "&Close Tab\tCtrl-Shift-W", EVENT_CLOSE_TAB);
-       AxWin_AddMenuItem(menu, "E&xit\tAlt-F4", EVENT_EXIT);
-
-       tab = AxWin_CreateWindow("root@acess: ~");
-       //geConsole = AxWin_CreateElement();
-       
-       AxWin_MessageLoop();
-       
-       return 0;
-}
-
-/**
- */
-int Global_HandleMessage(tAxWin_Message *Message)
-{
-       switch(Message->ID)
-       {
-       default:
-               return 0;
-       }
-}
-
-int Shell_HandleMessage(tAxWin_Message *Message)
-{
-       switch(Message->ID)
-       {
-       default:
-               return 0;
-       }
-}
diff --git a/Usermode/Applications/axwin2_src/WM/Makefile b/Usermode/Applications/axwin2_src/WM/Makefile
deleted file mode 100644 (file)
index 19687e1..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# Project: Acess GUI Window Manager
-
--include ../../Makefile.cfg
-
-CPPFLAGS += 
-
-DIR := Apps/AxWin/1.0
-BIN := AxWinWM
-OBJ := main.o helpers.o commandline.o video.o input.o video_text.o
-OBJ += messages.o interface.o wm.o decorator.o render.o
-OBJ += image.o
-
-LDFLAGS += -limage_sif -luri -lnet
-
--include ../../Makefile.tpl
-
-all: resources/LogoSmall.sif.res.h
-
-%.res.h: % Makefile
-       echo "#define RESOURCE_$(notdir $<) \\"| sed -e 's/\./_/g' > $@
-       base64 $< | sed -e 's/.*/"&"\\/' >> $@
-       echo "" >> $@
diff --git a/Usermode/Applications/axwin2_src/WM/commandline.c b/Usermode/Applications/axwin2_src/WM/commandline.c
deleted file mode 100644 (file)
index 67db574..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include "common.h"
-#include <string.h>
-
-// === PROTOTYPES ===
-void   ShowUsage(char *ProgName);
-void   ShowHelp(char *ProgName);
-
-// === CODE ===
-void ParseCommandline(int argc, char *argv[])
-{
-        int    i;
-       char    *arg;
-       
-       for( i = 1; i < argc; i++ )
-       {
-               arg = argv[i];
-               if(arg[0] == '-')
-               {
-                       if( arg[1] == '-' )
-                       {
-                               if( strcmp(&arg[2], "help") == 0 ) {
-                                       ShowHelp(argv[0]);
-                                       exit(EXIT_SUCCESS);
-                               }
-                               else {
-                                       ShowUsage(argv[0]);
-                                       exit(EXIT_FAILURE);
-                               }
-                       }
-                       else
-                       {
-                               while( *++arg )
-                               {
-                                       switch(*arg)
-                                       {
-                                       case 'h':
-                                       case '?':
-                                               ShowHelp(argv[0]);
-                                               exit(EXIT_SUCCESS);
-                                               break;
-                                       default:
-                                               break;
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-void ShowUsage(char *ProgName)
-{
-       fprintf(stderr, "Usage: %s [-h|--help]\n", ProgName);
-}
-
-void ShowHelp(char *ProgName)
-{
-       ShowUsage(ProgName);
-       fprintf(stderr, "\n");
-       fprintf(stderr, "\t--help\tShow this message\n");
-}
diff --git a/Usermode/Applications/axwin2_src/WM/common.h b/Usermode/Applications/axwin2_src/WM/common.h
deleted file mode 100644 (file)
index b00d697..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#ifndef _COMMON_H_
-#define _COMMON_H_
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <acess/sys.h> // _SysDebug
-
-// === TYPES ===
-typedef struct sIPC_Type       tIPC_Type;
-typedef struct sFont   tFont;
-
-struct sIPC_Type
-{
-        int    (*GetIdentSize)(void *Ident);
-        int    (*CompareIdent)(void *Ident1, void *Ident2);
-       void    (*SendMessage)(void *Ident, size_t, void *Data);
-};
-
-#include "wm.h"
-#include "image.h"
-//#include "font.h"
-
-// === MACROS ===
-static inline uint32_t Video_AlphaBlend(uint32_t _orig, uint32_t _new, uint8_t _alpha)
-{
-       uint16_t        ao,ro,go,bo;
-       uint16_t        an,rn,gn,bn;
-       if( _alpha == 0 )       return _orig;
-       if( _alpha == 255 )     return _new;
-       
-       ao = (_orig >> 24) & 0xFF;
-       ro = (_orig >> 16) & 0xFF;
-       go = (_orig >>  8) & 0xFF;
-       bo = (_orig >>  0) & 0xFF;
-       
-       an = (_new >> 24) & 0xFF;
-       rn = (_new >> 16) & 0xFF;
-       gn = (_new >>  8) & 0xFF;
-       bn = (_new >>  0) & 0xFF;
-
-       if( _alpha == 0x80 ) {
-               ao = (ao + an) / 2;
-               ro = (ro + rn) / 2;
-               go = (go + gn) / 2;
-               bo = (bo + bn) / 2;
-       }
-       else {
-               ao = ao*(255-_alpha) + an*_alpha;
-               ro = ro*(255-_alpha) + rn*_alpha;
-               go = go*(255-_alpha) + gn*_alpha;
-               bo = bo*(255-_alpha) + bn*_alpha;
-               ao /= 255*2;
-               ro /= 255*2;
-               go /= 255*2;
-               bo /= 255*2;
-       }
-
-       return (ao << 24) | (ro << 16) | (go << 8) | bo;
-}
-
-// === GLOBALS ===
-extern const char      *gsTerminalDevice;
-extern const char      *gsMouseDevice;
-
-extern int     giScreenWidth;
-extern int     giScreenHeight;
-extern uint32_t        *gpScreenBuffer;
-
-extern int     giTerminalFD;
-extern int     giMouseFD;
-
-// === Functions ===
-extern void    memset32(void *ptr, uint32_t val, size_t count);
-// --- Initialisation ---
-extern void    ParseCommandline(int argc, char *argv[]);
-// --- Messages / IPC ---
-extern void    IPC_Init(void);
-extern void    IPC_FillSelect(int *nfds, fd_set *set);
-extern void    IPC_HandleSelect(fd_set *set);
-// --- Input ---
-extern void    Input_FillSelect(int *nfds, fd_set *set);
-extern void    Input_HandleSelect(fd_set *set);
-// --- Local WM ---
-extern tApplication    *AxWin_RegisterClient(tIPC_Type *Method, void *Ident, const char *Name);
-extern void    AxWin_DeregisterClient(tApplication *App);
-extern tApplication    *AxWin_GetClient(tIPC_Type *Method, void *Ident);
-extern tElement        *AxWin_CreateAppWindow(tApplication *App, const char *Name);
-// --- Video ---
-extern void    Video_Setup(void);
-extern void    Video_SetCursorPos(short X, short Y);
-extern void    Video_Update(void);
-extern void    Video_FillRect(short X, short Y, short W, short H, uint32_t Color);
-extern void    Video_DrawRect(short X, short Y, short W, short H, uint32_t Color);
-extern int     Video_DrawText(short X, short Y, short W, short H, tFont *Font, uint32_t Color, char *Text);
-extern void    Video_DrawImage(short X, short Y, short W, short H, tImage *Image);
-// --- Interface ---
-extern void    Interface_Init(void);
-extern void    Interface_Update(void);
-extern void    Interface_Render(void);
-// --- Decorator ---
-extern void    Decorator_RenderWidget(tElement *Element);
-
-#endif
diff --git a/Usermode/Applications/axwin2_src/WM/decorator.c b/Usermode/Applications/axwin2_src/WM/decorator.c
deleted file mode 100644 (file)
index 171b526..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- * 
- * Widget Decorator
- */
-#include "common.h"
-#include "wm.h"
-
-#define BORDER_EVERYTHING      1
-
-#define BOX_BGCOLOUR    0xC0C0C0
-#define BOX_BORDER      0xA0A0A0
-#define BUTTON_BGCOLOUR 0xD0D0D0
-#define BUTTON_BORDER   0xF0F0F0
-#define        TEXT_COLOUR     0x000000
-
-// === CODE ===
-void Decorator_RenderWidget(tElement *Element)
-{
-       _SysDebug("Decorator_RenderWidget: (Element={Type:%i,(%i,%i) %ix%i})",
-               Element->Type,
-               Element->CachedX, Element->CachedY,
-               Element->CachedW, Element->CachedH
-               );
-       
-       #if BORDER_EVERYTHING
-       Video_DrawRect(Element->CachedX, Element->CachedY,
-                       Element->CachedW, Element->CachedH,
-                       0
-                       );
-       #endif
-       
-       switch(Element->Type)
-       {
-       case ELETYPE_NONE:
-       case ELETYPE_BOX:       break;  // Box is a meta-element
-       
-       case ELETYPE_TABBAR:    // Tab Bar
-               Video_DrawRect(
-                       Element->CachedX, Element->CachedY,
-                       Element->CachedW, Element->CachedH,
-                       BOX_BORDER
-                       );
-               Video_FillRect(
-                       Element->CachedX+1, Element->CachedY+1,
-                       Element->CachedW-2, Element->CachedH-2,
-                       BOX_BGCOLOUR
-                       );
-               // Enumerate Items.
-               break;
-       case ELETYPE_TOOLBAR:   // Tool Bar
-               Video_DrawRect(
-                       Element->CachedX, Element->CachedY,
-                       Element->CachedW, Element->CachedH,
-                       BOX_BORDER
-                       );
-               Video_FillRect(
-                       Element->CachedX+1, Element->CachedY+1,
-                       Element->CachedW-2, Element->CachedH-2,
-                       BOX_BGCOLOUR
-                       );
-               break;
-       
-       case ELETYPE_SPACER:    // Spacer (subtle line)
-               Video_FillRect(
-                       Element->CachedX+3, Element->CachedY+3,
-                       Element->CachedW-6, Element->CachedH-6,
-                       BOX_BORDER
-                       );
-               break;
-       
-       case ELETYPE_BUTTON:    // Button
-               Video_FillRect(
-                       Element->CachedX+1, Element->CachedY+1,
-                       Element->CachedW-2, Element->CachedH-2,
-                       BUTTON_BGCOLOUR
-                       );
-               Video_DrawRect(
-                       Element->CachedX, Element->CachedY,
-                       Element->CachedW-1, Element->CachedH-1,
-                       BUTTON_BORDER
-                       );
-               break;
-       
-       case ELETYPE_TEXT:
-               Video_DrawText(
-                       Element->CachedX+1, Element->CachedY+1,
-                       Element->CachedW-2, Element->CachedH-2,
-                       NULL,
-                       TEXT_COLOUR,
-                       Element->Text
-                       );
-               break;
-       
-       case ELETYPE_IMAGE:
-               Video_DrawImage(
-                       Element->CachedX, Element->CachedY,
-                       Element->CachedW, Element->CachedH,
-                       Element->Data
-                       );
-               break;
-               
-       default:
-               _SysDebug(" ERROR: Unknown type %i", Element->Type);
-               break;
-       }
-}
diff --git a/Usermode/Applications/axwin2_src/WM/font_8x16.h b/Usermode/Applications/axwin2_src/WM/font_8x16.h
deleted file mode 100644 (file)
index b9bad5d..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Taken from http://cvs.savannah.gnu.org/viewvc/vgabios/vgafonts.h?root=vgabios&view=markup
- * Altered for Acess2
- */
-#define FONT_WIDTH     8
-#define FONT_HEIGHT    16
-static uint8_t VTermFont[256*16]=
-{
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
-       0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,
-       0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
-       0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
-       0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
-       0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
-       0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00,
-       0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
-       0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
-       0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
-       0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00,
-       0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
-       0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00,
-       0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00,
-       0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
-       0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
-       0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-       0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-       0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-       0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-       0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-       0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-       0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-       0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
-       0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-       0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
diff --git a/Usermode/Applications/axwin2_src/WM/helpers.c b/Usermode/Applications/axwin2_src/WM/helpers.c
deleted file mode 100644 (file)
index 194c024..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include "common.h"
-
-// === CODE ===
-void memset32(void *ptr, uint32_t val, size_t count)
-{
-       uint32_t *dst = ptr;
-       while(count --) *dst++ = val;
-}
diff --git a/Usermode/Applications/axwin2_src/WM/image.c b/Usermode/Applications/axwin2_src/WM/image.c
deleted file mode 100644 (file)
index 1d7d343..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- * 
- * Window Manager and Widget Control
- */
-#include "common.h"
-#include <stdlib.h>
-#include <string.h>
-#include <uri.h>
-
-// === IMPORTS ===
-extern tImage *Image_SIF_Parse(void *Buffer, size_t Size);
-
-// === PROTOTYPES ===
- int   UnBase64(uint8_t *Dest, char *Src, int BufSize);
-
-// === CODE ===
-/**
- * \brief Open an image from a URI
- */
-tImage *Image_Load(const char *URI)
-{
-       tURI    *uri;
-        int    filesize;
-       void    *buf;
-       tImage  *img;
-       
-       uri = URI_Parse(URI);
-       if( !uri ) {
-               _SysDebug("Image_Load: Unable parse as URI '%s'\n", URI);
-               return NULL;
-       }
-       
-       if( strcmp(uri->Proto, "file") == 0 )
-       {
-               FILE    *fp;
-               fp = fopen(uri->Path, "rb");
-               if(!fp) {
-                       _SysDebug("Image_Load: Unable to open '%s'\n", uri->Path);
-                       free(uri);
-                       return NULL;
-               }
-               
-               fseek(fp, 0, SEEK_END);
-               filesize = ftell(fp);
-               buf = malloc( filesize );
-               if(!buf) {
-                       _SysDebug("Image_Load: malloc() failed!\n");
-                       fclose(fp);
-                       free(uri);
-                       return NULL;
-               }
-               
-               fread(buf, filesize, 1, buf);
-               fclose(fp);
-       }
-       else if( strcmp(uri->Proto, "base64") == 0 )
-       {
-               // 4 bytes of base64 = 3 bytes of binary (base 256)
-               filesize = strlen( uri->Path ) * 3 / 4;
-               buf = malloc(filesize);
-               if(!buf) {
-                       _SysDebug("Image_Load: malloc() failed!\n");
-                       free(uri);
-                       return NULL;
-               }
-               
-               filesize = UnBase64(buf, uri->Path, filesize);
-       }
-       else
-       {
-               _SysDebug("Image_Load: Unknow protocol '%s'\n", uri->Proto);
-               free(uri);
-               return NULL;
-       }
-       
-       img = Image_SIF_Parse(buf, filesize);
-       free(buf);
-       free(uri);
-       if( !img ) {
-               _SysDebug("Image_Load: Unable to parse SIF from '%s'\n", URI);
-               return NULL;
-       }
-       
-       return img;
-}
-
-/**
- * \brief Decode a Base64 value
- */
-int UnBase64(uint8_t *Dest, char *Src, int BufSize)
-{
-       uint32_t        val;
-        int    i, j;
-       char    *start_src = Src;
-       
-       for( i = 0; i+2 < BufSize; i += 3 )
-       {
-               val = 0;
-               for( j = 0; j < 4; j++, Src ++ ) {
-                       if('A' <= *Src && *Src <= 'Z')
-                               val |= (*Src - 'A') << ((3-j)*6);
-                       else if('a' <= *Src && *Src <= 'z')
-                               val |= (*Src - 'a' + 26) << ((3-j)*6);
-                       else if('0' <= *Src && *Src <= '9')
-                               val |= (*Src - '0' + 52) << ((3-j)*6);
-                       else if(*Src == '+')
-                               val |= 62 << ((3-j)*6);
-                       else if(*Src == '/')
-                               val |= 63 << ((3-j)*6);
-                       else if(!*Src)
-                               break;
-                       else if(*Src != '=')
-                               j --;   // Ignore invalid characters
-               }
-               Dest[i  ] = (val >> 16) & 0xFF;
-               Dest[i+1] = (val >> 8) & 0xFF;
-               Dest[i+2] = val & 0xFF;
-               if(j != 4)      break;
-       }
-       
-       // Finish things off
-       if(i   < BufSize)
-               Dest[i] = (val >> 16) & 0xFF;
-       if(i+1 < BufSize)
-               Dest[i+1] = (val >> 8) & 0xFF;
-       
-       return Src - start_src;
-}
diff --git a/Usermode/Applications/axwin2_src/WM/image.h b/Usermode/Applications/axwin2_src/WM/image.h
deleted file mode 100644 (file)
index 6cda85b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#ifndef _IMAGE_H_
-#define _IMAGE_H_
-
-typedef struct sImage  tImage;
-
-struct sImage
-{
-       short   Width;
-       short   Height;
-        int    Format;
-       uint8_t Data[];
-};
-
-enum eImageFormats
-{
-       IMGFMT_BGRA,
-       IMGFMT_RGB,
-       NUM_IMGFMTS
-};
-
-// === PROTOTYPES ===
-extern tImage  *Image_Load(const char *URI);
-
-#endif
diff --git a/Usermode/Applications/axwin2_src/WM/input.c b/Usermode/Applications/axwin2_src/WM/input.c
deleted file mode 100644 (file)
index 9386932..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include "common.h"
-#include <acess/sys.h>
-
-#define JOY_IOCTL_GETSETAXISLIMIT      6
-#define JOY_IOCTL_GETSETAXISPOSITION   7
-
-// === CODE ===
-int Input_Init(void)
-{
-       struct {
-                int    Num, Value;
-       }       num_value;
-
-       // Open mouse for RW
-       giMouseFD = open(gsMouseDevice, 3);
-
-       // Set mouse limits
-       num_value.Num = 0;
-       num_value.Value = giScreenWidth;
-       ioctl(giMouseFD, JOY_IOCTL_GETSETAXISLIMIT, &num_value);
-       num_value.Value = giScreenWidth/2;
-       ioctl(giMouseFD, JOY_IOCTL_GETSETAXISPOSITION, &num_value);
-
-       num_value.Num = 1;
-       num_value.Value = giScreenHeight;
-       ioctl(giMouseFD, JOY_IOCTL_GETSETAXISLIMIT, &num_value);
-       num_value.Value = giScreenHeight/2;
-       ioctl(giMouseFD, JOY_IOCTL_GETSETAXISPOSITION, &num_value);
-
-       return 0;
-}
-
-void Input_FillSelect(int *nfds, fd_set *set)
-{
-       if(*nfds < giTerminalFD)        *nfds = giTerminalFD;
-       if(*nfds < giMouseFD)   *nfds = giMouseFD;
-       FD_SET(giTerminalFD, set);
-       FD_SET(giMouseFD, set);
-}
-
-void Input_HandleSelect(fd_set *set)
-{
-       if(FD_ISSET(giTerminalFD, set))
-       {
-               uint32_t        codepoint;
-               if( read(giTerminalFD, &codepoint, sizeof(codepoint)) != sizeof(codepoint) )
-               {
-                       // oops, error
-               }
-               // TODO: pass on to message handler
-               _SysDebug("Keypress 0x%x", codepoint);
-       }
-
-       if(FD_ISSET(giMouseFD, set))
-       {
-               struct sMouseInfo {
-                       uint16_t        NAxies;
-                       uint16_t        NButtons;
-                       struct sMouseAxis {
-                                int16_t        MinValue;
-                                int16_t        MaxValue;
-                                int16_t        CurValue;
-                               uint16_t        CursorPos;
-                       }       Axies[2];
-                       uint8_t Buttons[3];
-               }       mouseinfo;
-       
-               seek(giMouseFD, 0, SEEK_SET);
-               if( read(giMouseFD, &mouseinfo, sizeof(mouseinfo)) != sizeof(mouseinfo) )
-               {
-                       // Not a 3 button mouse, oops
-                       return ;
-               }
-
-//             _SysDebug("sizeof(uint16_t) = %i, sizeof(int16_t) = %i",
-//                     sizeof(uint16_t), sizeof(int16_t));
-//             _SysDebug("NAxies=%i,NButtons=%i", mouseinfo.NAxies, mouseinfo.NButtons);
-//             _SysDebug("offsetof(Axies[0].MinValue) = %i", offsetof(struct sMouseInfo, Axies[0].MinValue));
-//             _SysDebug("[0] = {MinValue=%i,MaxValue=%i,CurValue=%i}",
-//                     mouseinfo.Axies[0].MinValue, mouseinfo.Axies[0].MaxValue,
-//                     mouseinfo.Axies[0].CurValue
-//                     );
-               // Handle movement
-               Video_SetCursorPos( mouseinfo.Axies[0].CursorPos, mouseinfo.Axies[1].CursorPos );
-//             _SysDebug("Cursor to %i,%i", mouseinfo.Axies[0].CursorPos, mouseinfo.Axies[1].CursorPos);
-       }
-}
diff --git a/Usermode/Applications/axwin2_src/WM/interface.c b/Usermode/Applications/axwin2_src/WM/interface.c
deleted file mode 100644 (file)
index 91396ee..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- * 
- * interface.c
- * > Main Overarching UI
- */
-#include "common.h"
-#include "resources/LogoSmall.sif.res.h"
-
-// === GLOBALS ==
- int   giInterface_Width = 0;
- int   giInterface_HeaderBarSize = 20;
- int   giInterface_TabBarSize = 20;
-tElement       *gpInterface_Sidebar;
-tElement       *gpInterface_ProgramList;
-tElement       *gpInterface_MainArea;
-tElement       *gpInterface_HeaderBar;
-tElement       *gpInterface_TabBar;
-tElement       *gpInterface_TabContent;
-const char     csLogoSmall[] = "base64:///"RESOURCE_LogoSmall_sif;
-tApplication   *gpInterface_CurrentApp;
-
-typedef struct sApplicationLink        tApplicationLink;
-
-struct sApplicationLink {
-       tApplication    *App;
-       tElement        *Button;
-       char    Name[];
-};
-
-// === CODE ===
-/**
- * \brief Initialise the UI
- */
-void Interface_Init(void)
-{
-       tElement        *btn, *text;
-       tElement        *ele;
-
-       // Calculate sizes
-       giInterface_Width = giScreenWidth/16;
-       
-       // Set root window to no-border
-       AxWin_SetFlags(NULL, 0);
-       
-       // -- Create Sidebar (Menu and Window List) --
-       gpInterface_Sidebar = AxWin_CreateElement(NULL, ELETYPE_TOOLBAR, ELEFLAG_VERTICAL, "Sidebar");
-       AxWin_SetSize( gpInterface_Sidebar, giInterface_Width );
-       
-       // > System Menu Button
-       btn = AxWin_CreateElement(gpInterface_Sidebar, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH, "SystemMenu");
-       AxWin_SetSize(btn, giInterface_Width-4);
-       //text = AxWin_CreateElement(btn, ELETYPE_IMAGE, ELEFLAG_SCALE, "MenuLogo");
-       text = AxWin_CreateElement(btn, ELETYPE_IMAGE, 0, "MenuLogo");
-       //AxWin_SetText(text, "file:///LogoSmall.sif");
-       AxWin_SetText(text, csLogoSmall);
-       
-       // > Plain <hr/> style spacer
-       ele = AxWin_CreateElement(gpInterface_Sidebar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, "SideBar Spacer Top");
-       AxWin_SetSize(ele, 4);
-       
-       // > Application List (Window list on most OSs)
-       gpInterface_ProgramList = AxWin_CreateElement(gpInterface_Sidebar, ELETYPE_BOX, ELEFLAG_VERTICAL, "ProgramList");
-       
-       // > Plain <hr/> style spacer
-       ele = AxWin_CreateElement(gpInterface_Sidebar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, "SideBar Spacer Bottom");
-       AxWin_SetSize(ele, 4);
-       
-       // > Version/Time
-       text = AxWin_CreateElement(gpInterface_Sidebar, ELETYPE_TEXT, ELEFLAG_NOSTRETCH, "Version String");
-       AxWin_SetSize(text, 20);
-       AxWin_SetText(text, "2.0");
-       
-       // --
-       // -- Create Main Area and regions within --
-       // --
-       // > Righthand Area
-       gpInterface_MainArea = AxWin_CreateElement(NULL, ELETYPE_BOX, ELEFLAG_VERTICAL, "MainArea");
-       //  > Header Bar (Title)
-       gpInterface_HeaderBar = AxWin_CreateElement(gpInterface_MainArea, ELETYPE_BOX, 0, "HeaderBar");
-       AxWin_SetSize(gpInterface_HeaderBar, giInterface_HeaderBarSize);
-       text = AxWin_CreateElement(gpInterface_HeaderBar, ELETYPE_TEXT, 0, NULL);
-       AxWin_SetText(text, "Acess2 GUI - By thePowersGang (John Hodge)");
-       //  > Tab Bar (Current windows)
-       gpInterface_TabBar = AxWin_CreateElement(gpInterface_MainArea, ELETYPE_TABBAR, 0, "TabBar");
-       AxWin_SetSize(gpInterface_TabBar, giInterface_TabBarSize);
-       //  > Application Space
-       gpInterface_TabContent = AxWin_CreateElement(gpInterface_MainArea, ELETYPE_BOX, 0, "TabContent");
-}
-
-void Interface_Update(void)
-{
-//     tApplication    *app;
-//     tApplicationLink        *lnk;
-       giInterface_Width = giScreenWidth/16;
-       AxWin_SetSize( gpInterface_Sidebar, giInterface_Width );
-
-       // Scan application list for changes
-       // - HACK for now, just directly access it
-//     for( app = gWM_Applications; app; app = app->Next )
-//     {
-//             AxWin_CreateElement();
-//     }
-
-       // Update current tab list
-}
-
-void Interface_Render(void)
-{
-       Video_FillRect(
-               0, 0,
-               giInterface_Width, giScreenHeight,
-               0xDDDDDD);
-       
-       Video_Update();
-}
diff --git a/Usermode/Applications/axwin2_src/WM/main.c b/Usermode/Applications/axwin2_src/WM/main.c
deleted file mode 100644 (file)
index 48e47ff..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include "common.h"
-#include <acess/sys.h>
-
-// === IMPORTS ===
-extern void    WM_Update(void);
-extern int     Input_Init(void);
-
-// === GLOBALS ===
-const char     *gsTerminalDevice = NULL;
-const char     *gsMouseDevice = NULL;
-
- int   giScreenWidth = 640;
- int   giScreenHeight = 480;
-uint32_t       *gpScreenBuffer = NULL;
-
- int   giTerminalFD = -1;
- int   giMouseFD = -1;
-
-// === CODE ===
-/**
- * \brief Program Entrypoint
- */
-int main(int argc, char *argv[])
-{
-       ParseCommandline(argc, argv);
-       
-       if( gsTerminalDevice == NULL ) {
-               gsTerminalDevice = "/Devices/VTerm/6";
-       }
-       if( gsMouseDevice == NULL ) {
-               gsMouseDevice = "/Devices/PS2Mouse";
-       }
-       
-       Video_Setup();
-       Interface_Init();
-       IPC_Init();
-       Input_Init();
-       
-       WM_Update();
-       
-       // Main Loop
-       for(;;)
-       {
-               fd_set  fds;
-                int    nfds = 0;
-               FD_ZERO(&fds);
-       
-               Input_FillSelect(&nfds, &fds);
-               IPC_FillSelect(&nfds, &fds);
-               
-               nfds ++;
-               select(nfds, &fds, NULL, NULL, NULL);
-
-               Input_HandleSelect(&fds);
-               IPC_HandleSelect(&fds);
-       }
-       return 0;
-}
-
diff --git a/Usermode/Applications/axwin2_src/WM/messages.c b/Usermode/Applications/axwin2_src/WM/messages.c
deleted file mode 100644 (file)
index f25e1c4..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include "common.h"
-#include <acess/sys.h>
-#include <net.h>
-#include <axwin2/messages.h>
-#include <string.h>
-
-#define AXWIN_PORT     4101
-
-#define STATICBUF_SIZE 64
-
-// === TYPES ===
-
-// === PROTOTYPES ===
-void   IPC_Init(void);
-void   IPC_FillSelect(int *nfds, fd_set *set);
-void   IPC_HandleSelect(fd_set *set);
-void   IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_Message *Msg);
-void   IPC_ReturnValue(tIPC_Type *IPCType, void *Ident, int MessageID, uint32_t Value);
- int   IPC_Type_Datagram_GetSize(void *Ident);
- int   IPC_Type_Datagram_Compare(void *Ident1, void *Ident2);
-void   IPC_Type_Datagram_Send(void *Ident, size_t Length, void *Data);
- int   IPC_Type_Sys_GetSize(void *Ident);
- int   IPC_Type_Sys_Compare(void *Ident1, void *Ident2);
-void   IPC_Type_Sys_Send(void *Ident, size_t Length, void *Data);
-
-// === GLOBALS ===
- int   giNetworkFileHandle = -1;
- int   giMessagesFileHandle = -1;
-tIPC_Type      gIPC_Type_Datagram = {
-       IPC_Type_Datagram_GetSize,
-       IPC_Type_Datagram_Compare, 
-       IPC_Type_Datagram_Send
-};
-tIPC_Type      gIPC_Type_SysMessage = {
-       IPC_Type_Sys_GetSize,
-       IPC_Type_Sys_Compare,
-       IPC_Type_Sys_Send
-};
-
-// === CODE ===
-void IPC_Init(void)
-{
-        int    tmp;
-       // TODO: Check this
-       giNetworkFileHandle = open("/Devices/ip/loop/udp", OPENFLAG_READ);
-       tmp = AXWIN_PORT;       ioctl(giNetworkFileHandle, 4, &tmp);    // TODO: Don't hard-code IOCtl number
-}
-
-void IPC_FillSelect(int *nfds, fd_set *set)
-{
-       if( giNetworkFileHandle > *nfds )       *nfds = giNetworkFileHandle;
-       FD_SET(giNetworkFileHandle, set);
-}
-
-void IPC_HandleSelect(fd_set *set)
-{
-       if( FD_ISSET(giNetworkFileHandle, set) )
-       {
-               char    staticBuf[STATICBUF_SIZE];
-                int    readlen, identlen;
-               char    *msg;
-
-               readlen = read(giNetworkFileHandle, staticBuf, sizeof(staticBuf));
-               
-               identlen = 4 + Net_GetAddressSize( ((uint16_t*)staticBuf)[1] );
-               msg = staticBuf + identlen;
-
-               IPC_Handle(&gIPC_Type_Datagram, staticBuf, readlen - identlen, (void*)msg);
-               _SysDebug("IPC_HandleSelect: UDP handled");
-       }
-
-       while(SysGetMessage(NULL, NULL))
-       {
-               pid_t   tid;
-                int    len = SysGetMessage(&tid, NULL);
-               char    data[len];
-               SysGetMessage(NULL, data);
-
-               IPC_Handle(&gIPC_Type_SysMessage, &tid, len, (void*)data);
-               _SysDebug("IPC_HandleSelect: Message handled");
-       }
-}
-
-void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_Message *Msg)
-{
-       tApplication    *app;
-       tElement        *ele;
-       
-       _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)",
-               IPCType, Ident, MsgLen, Msg);
-       
-       if( MsgLen < sizeof(tAxWin_Message) )
-               return ;
-       if( MsgLen < sizeof(tAxWin_Message) + Msg->Size )
-               return ;
-       
-       app = AxWin_GetClient(IPCType, Ident);
-
-       switch((enum eAxWin_Messages) Msg->ID)
-       {
-       // --- Ping message (reset timeout and get server version)
-       case MSG_SREQ_PING:
-               _SysDebug(" IPC_Handle: MSG_SREQ_PING");
-               if( MsgLen < sizeof(tAxWin_Message) + 4 )       return;
-               Msg->ID = MSG_SRSP_VERSION;
-               Msg->Size = 4;
-               Msg->Data[0] = 0;
-               Msg->Data[1] = 1;
-               *(uint16_t*)&Msg->Data[2] = -1;
-               IPCType->SendMessage(Ident, sizeof(Msg->ID), Msg);
-               break;
-
-
-       // --- Register an application
-       case MSG_SREQ_REGISTER:
-               _SysDebug(" IPC_Handle: MSG_SREQ_REGISTER");
-               if( Msg->Data[Msg->Size-1] != '\0' ) {
-                       // Invalid message
-                       _SysDebug("IPC_Handle: RETURN - Not NULL terminated");
-                       return ;
-               }
-               
-               if( app != NULL ) {
-                       _SysDebug("Notice: Duplicate registration (%s)\n", Msg->Data);
-                       return ;
-               }
-               
-               // TODO: Should this function be implemented here?
-               AxWin_RegisterClient(IPCType, Ident, Msg->Data);
-               break;
-       
-       // --- Create a window
-       case MSG_SREQ_ADDWIN:
-               _SysDebug(" IPC_Handle: MSG_SREQ_ADDWIN");
-               if( Msg->Data[Msg->Size-1] != '\0' ) {
-                       // Invalid message
-                       return ;
-               }
-               
-               ele = AxWin_CreateAppWindow(app, Msg->Data);
-               IPC_ReturnValue(IPCType, Ident, MSG_SREQ_ADDWIN, ele->ApplicationID);
-               break;
-       
-       // --- Set a window's icon
-       case MSG_SREQ_SETICON:
-               _SysDebug(" IPC_Handle: MSG_SREQ_SETICON");
-               // TODO: Find a good way of implementing this
-               break;
-       
-       // --- Create an element
-       case MSG_SREQ_INSERT: {
-               _SysDebug(" IPC_Handle: MSG_SREQ_INSERT");
-               struct sAxWin_SReq_NewElement   *info = (void *)Msg->Data;
-               
-               if( Msg->Size != sizeof(*info) )        return;
-               
-               if( !app || info->Parent > app->MaxElementIndex )       return ;
-               
-               ele = AxWin_CreateElement( app->EleIndex[info->Parent], info->Type, info->Flags, NULL );
-               IPC_ReturnValue(IPCType, Ident, MSG_SREQ_ADDWIN, ele->ApplicationID);
-               break; }
-       
-       // --- Unknown message
-       default:
-               fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
-               _SysDebug("WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
-               break;
-       }
-}
-
-void IPC_ReturnValue(tIPC_Type *IPCType, void *Ident, int MessageID, uint32_t Value)
-{
-       char    data[sizeof(tAxWin_Message) + sizeof(tAxWin_RetMsg)];
-       tAxWin_Message  *msg = (void *)data;
-       tAxWin_RetMsg   *ret_msg = (void *)msg->Data;
-       
-       msg->Source = 0;        // 0 = Server
-       msg->ID = MSG_SRSP_RETURN;
-       msg->Size = sizeof(tAxWin_RetMsg);
-       ret_msg->ReqID = MessageID;
-       ret_msg->Rsvd = 0;
-       ret_msg->Value = Value;
-       
-       IPCType->SendMessage(Ident, sizeof(data), data);
-}
-
-int IPC_Type_Datagram_GetSize(void *Ident)
-{
-       return 4 + Net_GetAddressSize( ((uint16_t*)Ident)[1] );
-}
-
-int IPC_Type_Datagram_Compare(void *Ident1, void *Ident2)
-{
-       // Pass the buck :)
-       // - No need to worry about mis-matching sizes, as the size is computed
-       //   from the 3rd/4th bytes, hence it will differ before the size is hit.
-       return memcmp(Ident1, Ident2, IPC_Type_Datagram_GetSize(Ident1));
-}
-
-void IPC_Type_Datagram_Send(void *Ident, size_t Length, void *Data)
-{
-        int    identlen = IPC_Type_Datagram_GetSize(Ident);
-       char    tmpbuf[ identlen + Length ];
-       memcpy(tmpbuf, Ident, identlen);        // Header
-       memcpy(tmpbuf + identlen, Data, Length);        // Data
-       // TODO: Handle fragmented packets
-       write(giNetworkFileHandle, tmpbuf, sizeof(tmpbuf));
-}
-
-int IPC_Type_Sys_GetSize(void *Ident)
-{
-       return sizeof(pid_t);
-}
-
-int IPC_Type_Sys_Compare(void *Ident1, void *Ident2)
-{
-       return *(int*)Ident1 - *(int*)Ident2;
-}
-
-void IPC_Type_Sys_Send(void *Ident, size_t Length, void *Data)
-{
-       SysSendMessage( *(tid_t*)Ident, Length, Data );
-}
diff --git a/Usermode/Applications/axwin2_src/WM/render.c b/Usermode/Applications/axwin2_src/WM/render.c
deleted file mode 100644 (file)
index 0ee9e80..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- * 
- * Rendering code
- */
-#include "common.h"
-#include <stdlib.h>
-#include <string.h>
-#include "wm.h"
-#include <acess/sys.h> // _SysDebug
-
-// === IMPORTS ===
-extern void    Decorator_RenderWidget(tElement *Element);
-extern tElement        gWM_RootElement;
-extern tApplication    *gWM_Applications;
-extern int     giWM_MaxAreaX;
-extern int     giWM_MaxAreaY;
-extern int     giWM_MaxAreaW;
-extern int     giWM_MaxAreaH;
-
-// === PROTOTYPES ===
-void   WM_UpdateMinDims(tElement *Element);
-void   WM_UpdateDimensions(tElement *Element, int Pass);
-void   WM_UpdatePosition(tElement *Element);
-void   WM_RenderWidget(tElement *Element);
-void   WM_Update(void);
-
-// === CODE ===
-/**
- * \brief Updates the dimensions of an element
- * \todo What is the \a Pass parameter for
- * 
- * The dimensions of an element are calculated from the parent's
- * cross dimension (the side at right angles to the alignment) sans some
- * padding.
- */
-void WM_UpdateDimensions(tElement *Element, int Pass)
-{
-       tElement        *child;
-        int    nChildren = 0;
-        int    nFixed = 0;
-        int    maxCross = 0;
-        int    fixedSize = 0;
-        int    fullCross, dynWith;
-       
-       _SysDebug("WM_UpdateDimensions %p'%s'", Element, Element->DebugName);
-       _SysDebug(" -> Flags = 0x%x", Element->Flags);
-       _SysDebug(" ->CachedH = %i, ->PaddingT = %i, ->PaddingB = %i",
-               Element->CachedH, Element->PaddingT, Element->PaddingB
-               );
-       _SysDebug(" ->CachedW = %i, ->PaddingL = %i, ->PaddingR = %i",
-               Element->CachedW, Element->PaddingL, Element->PaddingR
-               );
-       
-       // Pass 1
-       for( child = Element->FirstChild; child; child = child->NextSibling )
-       {
-               if( child->Flags & ELEFLAG_ABSOLUTEPOS )
-                       continue ;
-               
-               _SysDebug(" > %p'%s' ->FixedWith = %i", child, child->DebugName, child->FixedWith);
-               if( child->FixedWith )
-               {
-                       nFixed ++;
-                       fixedSize += child->FixedWith;
-               }
-               
-               if( child->FixedCross && maxCross < child->FixedCross )
-                       maxCross = child->FixedCross;
-               if( child->MinCross && maxCross < child->MinCross )
-                       maxCross = child->MinCross;
-               nChildren ++;
-       }
-       
-       _SysDebug(" - nChildren = %i, nFixed = %i", Element, nChildren, nFixed);
-       if( nChildren > nFixed ) {
-               if( Element->Flags & ELEFLAG_VERTICAL )
-                       dynWith = Element->CachedH - Element->PaddingT
-                               - Element->PaddingB;
-               else
-                       dynWith = Element->CachedW - Element->PaddingL
-                               - Element->PaddingR;
-               dynWith -= fixedSize;
-               if( dynWith < 0 )       return ;
-               dynWith /= nChildren - nFixed;
-               _SysDebug(" - dynWith = %i", dynWith);
-       }
-       
-       if( Element->Flags & ELEFLAG_VERTICAL )
-               fullCross = Element->CachedW - Element->PaddingL - Element->PaddingR;
-       else
-               fullCross = Element->CachedH - Element->PaddingT - Element->PaddingB;
-       
-       _SysDebug(" - fullCross = %i", Element, fullCross);
-       
-       // Pass 2 - Set sizes and recurse
-       for( child = Element->FirstChild; child; child = child->NextSibling )
-       {
-                int    cross, with;
-               
-               _SysDebug(" > %p'%s' ->MinCross = %i", child, child->DebugName, child->MinCross);
-
-               
-               // --- Cross Size ---
-               if( child->FixedCross )
-                       cross = child->FixedCross;
-               // Expand to fill?
-               // TODO: Extra flag so options are (Expand, Equal, Wrap)
-               else if( child->Flags & ELEFLAG_NOEXPAND )
-                       cross = child->MinCross;
-               else
-                       cross = fullCross;
-               _SysDebug(" > %p'%s' - cross = %i", child, child->DebugName, cross);
-               if( Element->Flags & ELEFLAG_VERTICAL )
-                       child->CachedW = cross;
-               else
-                       child->CachedH = cross;
-               
-               // --- With Size ---
-               if( child->FixedWith)
-                       with = child->FixedWith;
-               else if( child->Flags & ELEFLAG_NOSTRETCH )
-                       with = child->MinWith;
-               else
-                       with = dynWith;
-               _SysDebug(" > %p'%s' - with = %i", child, child->DebugName, with);
-               if( Element->Flags & ELEFLAG_VERTICAL )
-                       child->CachedH = with;
-               else
-                       child->CachedW = with;
-               
-               WM_UpdateDimensions(child, Pass);
-       }
-       
-       _SysDebug("%p'%s' Done", Element, Element->DebugName);
-}
-
-/**
- * \brief Updates the position of an element
- * 
- * The parent element sets the positions of its children
- */
-void WM_UpdatePosition(tElement *Element)
-{
-       tElement        *child;
-        int    x, y;
-       static int      depth = 0;
-       char    indent[depth+1];
-       
-       if( Element->Flags & ELEFLAG_NORENDER ) return ;
-       
-       memset(indent, ' ', depth);
-       indent[depth] = '\0';
-       depth ++;
-       
-       _SysDebug("%sWM_UpdatePosition %p'%s'{PaddingL:%i, PaddingT:%i}",
-               indent, Element, Element->DebugName, Element->PaddingL, Element->PaddingT);
-       
-       // Initialise
-       x = Element->CachedX + Element->PaddingL;
-       y = Element->CachedY + Element->PaddingT;
-       
-       _SysDebug("%s- Alignment = %s", indent,
-               (Element->Flags & ELEFLAG_VERTICAL) ? "vertical" : "horizontal");
-
-       // Update each child
-       for(child = Element->FirstChild; child; child = child->NextSibling)
-       {
-               _SysDebug("%s- x = %i, y = %i", indent, x, y);
-               child->CachedX = x;
-               child->CachedY = y;
-               
-               // Set Alignment
-               if( Element->Flags & ELEFLAG_ALIGN_CENTER ) {
-                       _SysDebug("%sChild being aligned to center", indent);
-                       if(Element->Flags & ELEFLAG_VERTICAL)
-                               child->CachedX += Element->CachedW/2 - child->CachedW/2;
-                       else
-                               child->CachedY += Element->CachedH/2 - child->CachedH/2;
-               }
-               else if( Element->Flags & ELEFLAG_ALIGN_END) {
-                       _SysDebug("%sChild being aligned to end", indent);
-                       if(Element->Flags & ELEFLAG_VERTICAL )
-                               child->CachedX += Element->CachedW
-                                       - Element->PaddingL - Element->PaddingR
-                                       - child->CachedW;
-                       else
-                               child->CachedY += Element->CachedH
-                                       - Element->PaddingT
-                                       - Element->PaddingB
-                                       - child->CachedH;
-               }
-               
-               _SysDebug("%s> %p'%s' at (%i,%i)", indent, child, child->DebugName,
-                       child->CachedX, child->CachedY);
-       
-               // Update child's children positions
-               WM_UpdatePosition(child);
-               
-               // Increment
-               if(Element->Flags & ELEFLAG_VERTICAL ) {
-                       y += child->CachedH + Element->GapSize;
-               }
-               else {
-                       x += child->CachedW + Element->GapSize;
-               }
-       }
-       
-       _SysDebug("%sElement %p'%s' (%i,%i)",
-               indent, Element, Element->DebugName, Element->CachedX, Element->CachedY
-               );
-       depth --;
-}
-
-/**
- * \brief Update the minimum dimensions of the element
- * \note Called after a child's minimum dimensions have changed
- */
-void WM_UpdateMinDims(tElement *Element)
-{
-       tElement        *child;
-       
-       if(!Element)    return;
-       
-       Element->MinCross = 0;
-       Element->MinWith = 0;
-       
-       for(child = Element->FirstChild; child; child = child->NextSibling)
-       {
-               if( Element->Parent &&
-                       (Element->Flags & ELEFLAG_VERTICAL) == (Element->Parent->Flags & ELEFLAG_VERTICAL)
-                       )
-               {
-                       if(child->FixedCross)
-                               Element->MinCross += child->FixedCross;
-                       else
-                               Element->MinCross += child->MinCross;
-                       if(child->FixedWith)
-                               Element->MinWith += child->FixedWith;
-                       else
-                               Element->MinWith += child->MinWith;
-               }
-               else
-               {
-                       if(child->FixedCross)
-                               Element->MinWith += child->FixedCross;
-                       else
-                               Element->MinWith += child->MinCross;
-                       if(child->FixedWith)
-                               Element->MinCross += child->FixedWith;
-                       else
-                               Element->MinCross += child->MinWith;
-               }
-       }
-       
-       // Recurse upwards
-       WM_UpdateMinDims(Element->Parent);
-}
-
-// --- Render ---
-void WM_RenderWidget(tElement *Element)
-{
-       tElement        *child;
-       
-       if( Element->Flags & ELEFLAG_NORENDER ) return ;
-       if( Element->Flags & ELEFLAG_INVISIBLE )        return ;
-       
-       Decorator_RenderWidget(Element);
-       
-       for(child = Element->FirstChild; child; child = child->NextSibling)
-       {
-               WM_RenderWidget(child);
-       }
-}
-
-void WM_UpdateWindow(tElement *Ele)
-{      
-       WM_UpdateDimensions( Ele, 0 );
-       WM_UpdatePosition( Ele );
-       WM_RenderWidget( Ele );
-}
-
-void WM_Update(void)
-{
-       tApplication    *app;
-       tElement        *ele;
-       
-       for( app = gWM_Applications; app; app = app->Next )
-       {
-               for( ele = app->MetaElement.FirstChild; ele; ele = ele->NextSibling ) {
-                       if( ele->Flags & ELEFLAG_WINDOW_MAXIMISED ) {
-                               ele->CachedX = giWM_MaxAreaX;
-                               ele->CachedY = giWM_MaxAreaY;
-                               ele->CachedW = giWM_MaxAreaW;
-                               ele->CachedH = giWM_MaxAreaH;
-                       }
-                       ele->Flags |= ELEFLAG_NOEXPAND|ELEFLAG_ABSOLUTEPOS|ELEFLAG_FIXEDSIZE;
-                       WM_UpdateWindow(ele);
-               }
-       }
-       
-       gWM_RootElement.CachedX = 0;
-       gWM_RootElement.CachedY = 0;
-       gWM_RootElement.CachedW = giScreenWidth;
-       gWM_RootElement.CachedH = giScreenHeight;
-       gWM_RootElement.Flags |= ELEFLAG_NOEXPAND|ELEFLAG_ABSOLUTEPOS|ELEFLAG_FIXEDSIZE;
-       
-       WM_UpdateWindow( &gWM_RootElement );
-       
-       Video_Update();
-}
diff --git a/Usermode/Applications/axwin2_src/WM/resources/LogoSmall.sif b/Usermode/Applications/axwin2_src/WM/resources/LogoSmall.sif
deleted file mode 100644 (file)
index 2064e48..0000000
Binary files a/Usermode/Applications/axwin2_src/WM/resources/LogoSmall.sif and /dev/null differ
diff --git a/Usermode/Applications/axwin2_src/WM/resources/cursor.h b/Usermode/Applications/axwin2_src/WM/resources/cursor.h
deleted file mode 100644 (file)
index 3cce1f2..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- */
-#ifndef _RESORUCE_CURSOR_H
-#define _RESORUCE_CURSOR_H
-
-#include <stdint.h>
-
-static struct {
-       uint16_t        W, H, OfsX, OfsY;
-       uint32_t        Data[];
-} cCursorBitmap = {
-       8, 16, 0, 0,
-       {
-               0xFF000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-               0xFF000000, 0xFF000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-               0xFF000000, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-               0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-               0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000, 0x00000000,
-               0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000,
-               0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000,
-               0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0xFF000000, 0xFF000000,
-               0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000,
-               0xFF000000, 0xFF000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000,
-               0xFF000000, 0x00000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000,
-               0x00000000, 0x00000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000,
-               0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000,
-               0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000,
-               0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFF000000, 0xFF000000, 0x00000000,
-               0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
-       }
-};
-
-#endif
-
diff --git a/Usermode/Applications/axwin2_src/WM/video.c b/Usermode/Applications/axwin2_src/WM/video.c
deleted file mode 100644 (file)
index 4121fbe..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include "common.h"
-#include <acess/sys.h>
-#include <acess/devices/terminal.h>
-#include <image.h>
-#include "resources/cursor.h"
-
-// === PROTOTYPES ===
-void   Video_Setup(void);
-void   Video_SetCursorPos(short X, short Y);
-void   Video_Update(void);
-void   Video_FillRect(short X, short Y, short W, short H, uint32_t Color);
-void   Video_DrawRect(short X, short Y, short W, short H, uint32_t Color);
-
-// === GLOBALS ===
- int   giVideo_CursorX;
- int   giVideo_CursorY;
-
-// === CODE ===
-void Video_Setup(void)
-{
-        int    tmpInt;
-       
-       // Open terminal
-       giTerminalFD = open(gsTerminalDevice, OPENFLAG_READ|OPENFLAG_WRITE);
-       if( giTerminalFD == -1 )
-       {
-               fprintf(stderr, "ERROR: Unable to open '%s' (%i)\n", gsTerminalDevice, _errno);
-               exit(-1);
-       }
-       
-       // Set width
-       tmpInt = giScreenWidth;
-       tmpInt = ioctl( giTerminalFD, TERM_IOCTL_WIDTH, &tmpInt );
-       if(tmpInt != giScreenWidth)
-       {
-               fprintf(stderr, "Warning: Selected width (%i) is invalid, clipped to %i\n",
-                       giScreenWidth, tmpInt);
-               giScreenWidth = tmpInt;
-       }
-       
-       // Set height
-       tmpInt = giScreenHeight;
-       tmpInt = ioctl( giTerminalFD, TERM_IOCTL_HEIGHT, &tmpInt );
-       if(tmpInt != giScreenHeight)
-       {
-               fprintf(stderr, "Warning: Selected height (%i) is invalid, clipped to %i\n",
-                       giScreenHeight, tmpInt);
-               giScreenHeight = tmpInt;
-       }
-       
-       // Set mode to video
-       tmpInt = TERM_MODE_FB;
-       ioctl( giTerminalFD, TERM_IOCTL_MODETYPE, &tmpInt );
-       
-       // Force VT to be shown
-       ioctl( giTerminalFD, TERM_IOCTL_FORCESHOW, NULL );
-       
-       // Create local framebuffer (back buffer)
-       gpScreenBuffer = malloc( giScreenWidth*giScreenHeight*4 );
-       memset32( gpScreenBuffer, 0x8888FF, giScreenWidth*giScreenHeight );
-
-       // Set cursor position and bitmap
-       ioctl(giTerminalFD, TERM_IOCTL_SETCURSORBITMAP, &cCursorBitmap);
-       Video_SetCursorPos( giScreenWidth/2, giScreenHeight/2 );
-
-       Video_Update();
-}
-
-void Video_Update(void)
-{
-       //seek(giTerminalFD, 0, SEEK_SET);
-       seek(giTerminalFD, 0, 1);
-       write(giTerminalFD, gpScreenBuffer, giScreenWidth*giScreenHeight*4);
-}
-
-void Video_SetCursorPos(short X, short Y)
-{
-       struct {
-               uint16_t        x;
-               uint16_t        y;
-       } pos;
-       pos.x = giVideo_CursorX = X;
-       pos.y = giVideo_CursorY = Y;
-       ioctl(giTerminalFD, TERM_IOCTL_GETSETCURSOR, &pos);
-}
-
-void Video_FillRect(short X, short Y, short W, short H, uint32_t Color)
-{
-       uint32_t        *buf = gpScreenBuffer + Y*giScreenWidth + X;
-       
-       _SysDebug("Video_FillRect: (X=%i, Y=%i, W=%i, H=%i, Color=%08x)",
-               X, Y, W, H, Color);
-       
-       if(W < 0 || X < 0 || X >= giScreenWidth)        return ;
-       if(X + W > giScreenWidth)       W = giScreenWidth - X;
-       
-       if(H < 0 || Y < 0 || Y >= giScreenHeight)       return ;
-       if(Y + H > giScreenHeight)      H = giScreenHeight - Y;
-       
-       while( H -- )
-       {
-               memset32( buf, Color, W );
-               buf += giScreenWidth;
-       }
-}
-
-void Video_DrawRect(short X, short Y, short W, short H, uint32_t Color)
-{      
-       Video_FillRect(X, Y, W, 1, Color);
-       Video_FillRect(X, Y+H-1, W, 1, Color);
-       Video_FillRect(X, Y, 1, H, Color);
-       Video_FillRect(X+W-1, Y, 1, H, Color);
-}
-
-/**
- * \brief Draw an image to the screen
- * \todo Maybe have support for an offset in the image
- */
-void Video_DrawImage(short X, short Y, short W, short H, tImage *Image)
-{
-        int    x, y;
-       uint8_t *buf = (uint8_t *)(gpScreenBuffer + Y*giScreenWidth + X);
-       uint8_t *data;
-       
-       // Sanity please
-       if( !Image )
-               return ;
-       
-       // Bounds Check
-       if( X >= giScreenWidth )        return ;
-       if( Y >= giScreenHeight )       return ;
-       
-       // Wrap to image size
-       if( W > Image->Width )  W = Image->Width;
-       if( H > Image->Height ) H = Image->Height;
-       
-       // Wrap to screen size
-       if( X + W > giScreenWidth )     W = giScreenWidth - X;
-       if( Y + H > giScreenHeight )    H = giScreenHeight - Y;
-       
-       // Do the render
-       data = Image->Data;
-       switch( Image->Format )
-       {
-       case IMGFMT_BGRA:
-               for( y = 0; y < H; y ++ )
-               {
-                        int    r, g, b, a;     // New
-                        int    or, og, ob;     // Original
-                       for( x = 0; x < W; x ++ )
-                       {
-                               b = data[x*4+0]; g = data[x*4+1]; r = data[x*4+2]; a = data[x*4+3];
-                               if( a == 0 )    continue;       // 100% transparent
-                               ob = buf[x*4+0]; og = buf[x*4+1]; or = buf[x*4+2];
-                               // Handle Alpha
-                               switch(a)
-                               {
-                               // Transparent: Handled above
-                               // Solid
-                               case 0xFF:      break;
-                               // Half
-                               case 0x80:
-                                       r = (or + r) / 2;
-                                       g = (og + g) / 2;
-                                       b = (ob + b) / 2;
-                                       break;
-                               // General
-                               default:
-                                       r = (or * (255-a) + r * a) / 255;
-                                       g = (og * (255-a) + g * a) / 255;
-                                       b = (ob * (255-a) + b * a) / 255;
-                                       break;
-                               }
-                               buf[x*4+0] = b; buf[x*4+1] = g; buf[x*4+2] = r;
-                       }
-                       data += Image->Width * 4;
-                       buf += giScreenWidth * 4;
-               }
-               break;
-       
-       // RGB
-       case IMGFMT_RGB:
-               for( y = 0; y < H; y ++ )
-               {
-                       for( x = 0; x < W; x ++ )
-                       {
-                               buf[x*4+0] = data[x*3+2];       // Blue
-                               buf[x*4+1] = data[x*3+1];       // Green
-                               buf[x*4+2] = data[x*3+0];       // Red
-                       }
-                       data += W * 3;
-                       buf += giScreenWidth * 4;
-               }
-               break;
-       default:
-               _SysDebug("ERROR: Unknown image format %i\n", Image->Format);
-               break;
-       }
-}
diff --git a/Usermode/Applications/axwin2_src/WM/video_text.c b/Usermode/Applications/axwin2_src/WM/video_text.c
deleted file mode 100644 (file)
index 3d680d5..0000000
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include <acess/sys.h>
-#include "common.h"
-
-typedef struct sGlyph {
-       struct sGlyph   *Next;
-       struct sGlyph   *Prev;
-       
-       uint32_t        Codepoint;
-       
-       // Effective dimensions (distance to move 'cursor')
-       short   Width;
-       short   Height;
-       
-       // Distance from the current cursor position to render at
-       short   OffsetX;
-       short   OffsetY;
-       
-       // True dimensions (size of the bitmap
-       short   TrueWidth;
-       short   TrueHeight;
-       
-       // Bitmap Data
-       uint8_t Bitmap[];       // 8-bit alpha
-       
-}      tGlyph;
-
-struct sFont {
-       struct sFont    *Next;
-        int    ReferenceCount;
-       
-       tGlyph  *AsciiGlyphs[128];      // Glyphs 0-127
-       
-       tGlyph  *FirstGlyph;
-       tGlyph  *LastGlyph;
-       
-       tGlyph  *(*CacheGlyph)(struct sFont *this, uint32_t Codepoint);
-       
-};
-
-
-// === PROTOTYPES ===
- int   Video_DrawText(short X, short Y, short W, short H, tFont *Font, uint32_t Color, char *Text);
-void   Video_GetTextDims(tFont *Font, const char *Text, int *W, int *H);
-tGlyph *_GetGlyph(tFont *Font, uint32_t Codepoint);
-void   _RenderGlyph(short X, short Y, tGlyph *Glyph, uint32_t Color);
-tGlyph *_SystemFont_CacheGlyph(tFont *Font, uint32_t Codepoint);
- int   ReadUTF8(const char *Input, uint32_t *Output);
-
-// === GLOBALS ===
-tFont  gSystemFont = {
-       .CacheGlyph = _SystemFont_CacheGlyph
-};
-
-// === CODE ===
-/**
- * \brief Draw text to the screen
- */
-int Video_DrawText(short X, short Y, short W, short H, tFont *Font, uint32_t Color, char *Text)
-{
-        int    xOfs = 0;
-       tGlyph  *glyph;
-       uint32_t        ch = 0;
-
-       _SysDebug("Video_DrawText: (X=%i,Y=%i,W=%i,H=%i,Font=%p,", X, Y, W, H, Font);
-       _SysDebug("  Color=%08x,Text='%s')", Color, Text);
-       
-       // Check the bounds
-       if(W < 0 || X < 0 || X >= giScreenWidth)        return 0;
-       if(X + W > giScreenWidth)       W = giScreenWidth - X;
-       
-       if(H < 0 || Y < 0 || Y >= giScreenHeight)       return 0;
-       if(Y + H > giScreenHeight)      H = giScreenHeight - Y;
-       
-       // Handle NULL font (system default monospace)
-       if( !Font )     Font = &gSystemFont;
-       
-       while( *Text )
-       {
-               // Read character
-               Text += ReadUTF8(Text, &ch);
-               
-               // Find (or load) the glyph
-               glyph = _GetGlyph(Font, ch);
-               if( !glyph )    continue ;      // If not found, just don't render it
-               
-               // End render if it will overflow the perscribed range
-               if( xOfs + glyph->TrueWidth > W )
-                       break;
-               
-               xOfs += glyph->Width;
-               _RenderGlyph(X + xOfs, Y, glyph, Color);
-       }
-       
-       return xOfs;
-}
-
-void Video_GetTextDims(tFont *Font, const char *Text, int *W, int *H)
-{
-        int    w=0, h=0;
-       uint32_t        ch;
-       tGlyph  *glyph;
-       if( !Font )     Font = &gSystemFont;
-       
-       while( *Text )
-       {
-               Text += ReadUTF8(Text, &ch);
-               glyph = _GetGlyph(Font, ch);
-               if( !glyph )    continue;
-               
-               w += glyph->Width;
-               if( h < glyph->Height ) h = glyph->Height;
-       }
-       
-       if(W)   *W = w;
-       if(H)   *H = h;
-}
-
-tGlyph *_GetGlyph(tFont *Font, uint32_t Codepoint)
-{
-       tGlyph  *next = NULL, *prev = NULL;
-       tGlyph  *new;
-       
-       // Check for ASCII
-       if( Codepoint < 128 )
-       {
-               if( Font->AsciiGlyphs[Codepoint] == NULL ) {
-                       Font->AsciiGlyphs[Codepoint] = Font->CacheGlyph(Font, Codepoint);
-               }
-               
-               return Font->AsciiGlyphs[Codepoint];
-       }
-       
-       // If within the range
-       if( Font->FirstGlyph && Font->FirstGlyph->Codepoint < Codepoint && Codepoint < Font->LastGlyph->Codepoint )
-       {
-               // Find what end is "closest"
-               if( Codepoint - Font->FirstGlyph->Codepoint < Font->LastGlyph->Codepoint - Codepoint )
-               {
-                       // Start from the bottom
-                       for( next = Font->FirstGlyph;
-                                next && next->Codepoint < Codepoint;
-                                prev = next, next = next->Next
-                                );
-                       
-                       if( next->Codepoint == Codepoint )
-                               return next;
-                       
-               }
-               else
-               {
-                       // Start at the top
-                       // NOTE: The roles of next and prev are reversed here to allow 
-                       //       the insert to be able to assume that `prev` is the
-                       //       previous entry, and `next` is the next.
-                       for( prev = Font->LastGlyph;
-                                prev && prev->Codepoint > Codepoint;
-                                next = prev, prev = prev->Prev
-                                );
-                       if( prev->Codepoint == Codepoint )
-                               return prev;
-               }
-       }
-       else
-       {
-               // If below first
-               if( !Font->FirstGlyph ||  Font->FirstGlyph->Codepoint > Codepoint ) {
-                       prev = NULL;
-                       next = Font->FirstGlyph;
-               }
-               // Above last
-               else {
-                       prev = Font->LastGlyph;
-                       next = NULL;
-               }
-       }
-       
-       // Load new
-       new = Font->CacheGlyph(Font, Codepoint);
-       if( !new )      return NULL;
-       
-       // Add to list
-       // - Forward link
-       if( prev ) {
-               new->Next = prev->Next;
-               prev->Next = new;
-       }
-       else {
-               new->Next = Font->FirstGlyph;
-               Font->FirstGlyph = new;
-       }
-       
-       // - Backlink
-       if( next ) {
-               new->Prev = next->Prev;
-               next->Prev = new;
-       }
-       else {
-               new->Prev = Font->LastGlyph;
-               Font->LastGlyph = new;
-       }
-       
-       // Return
-       return new;
-}
-
-/**
- */
-void _RenderGlyph(short X, short Y, tGlyph *Glyph, uint32_t Color)
-{
-        int    xStart = 0, yStart = 0;
-        int    x, y;
-       uint32_t        *outBuf;
-       uint8_t *inBuf;
-       // TODO: Implement
-
-       X += Glyph->OffsetX;
-       if( X < 0 ) {   // If -ve, skip the first -X collums
-               xStart = -X;
-               X = 0;
-       }
-
-       Y += Glyph->OffsetY;
-       if( Y < 0 ) {   // If -ve, skip the first -Y lines
-               yStart = -Y;
-               Y = 0;
-       }
-
-       outBuf = gpScreenBuffer + Y*giScreenWidth + X;
-       inBuf = Glyph->Bitmap + yStart*Glyph->TrueWidth;
-
-       for( y = yStart; y < Glyph->TrueHeight; y ++ )
-       {
-               for( x = xStart; x < Glyph->TrueWidth; x ++ )
-               {
-                       outBuf[x] = Video_AlphaBlend( outBuf[x], Color, inBuf[x] );
-               }
-               outBuf += giScreenWidth;
-               inBuf += Glyph->TrueWidth;
-
-       }
-}
-
-// Load system font (8x16 monospace)
-#include "font_8x16.h"
-
-/*
- */
-tGlyph *_SystemFont_CacheGlyph(tFont *Font, uint32_t Codepoint)
-{
-        int    i;
-       uint8_t index = 0;
-       tGlyph  *ret;
-       uint8_t *data;
-
-       _SysDebug("_SystemFont_CacheGlyph: (Font=%p, Codepoint=0x%06x)", Font, Codepoint);
-       
-       if( Codepoint < 128 ) {
-               index = Codepoint;
-       }
-       else {
-               index = '?';    // Unknowns come out as a question mark
-       }
-
-       _SysDebug(" index = %i", index);
-
-       ret = malloc( sizeof(tGlyph) + FONT_WIDTH*FONT_HEIGHT );
-       if( !ret ) {
-               _SysDebug("ERROR: malloc(%i) failed", sizeof(tGlyph) + FONT_WIDTH*FONT_HEIGHT);
-               return NULL;
-       }
-
-       ret->Codepoint = Codepoint;
-
-       ret->Width = FONT_WIDTH;
-       ret->Height = FONT_HEIGHT;
-       
-       ret->TrueWidth = FONT_WIDTH;
-       ret->TrueHeight = FONT_HEIGHT;
-
-       ret->OffsetX = 0;
-       ret->OffsetY = 0;
-       
-       data = &VTermFont[index * FONT_HEIGHT];
-
-       for( i = 0; i < FONT_HEIGHT; i ++ )
-       {
-               ret->Bitmap[ i * 8 + 0 ] = data[i] & (1 << 7) ? 255 : 0;
-               ret->Bitmap[ i * 8 + 1 ] = data[i] & (1 << 6) ? 255 : 0;
-               ret->Bitmap[ i * 8 + 2 ] = data[i] & (1 << 5) ? 255 : 0;
-               ret->Bitmap[ i * 8 + 3 ] = data[i] & (1 << 4) ? 255 : 0;
-               ret->Bitmap[ i * 8 + 4 ] = data[i] & (1 << 3) ? 255 : 0;
-               ret->Bitmap[ i * 8 + 5 ] = data[i] & (1 << 2) ? 255 : 0;
-               ret->Bitmap[ i * 8 + 6 ] = data[i] & (1 << 1) ? 255 : 0;
-               ret->Bitmap[ i * 8 + 7 ] = data[i] & (1 << 0) ? 255 : 0;
-       }
-
-       return ret;
-}
-
-
-/**
- * \fn int ReadUTF8(char *Input, uint32_t *Val)
- * \brief Read a UTF-8 character from a string
- */
-int ReadUTF8(const char *Input, uint32_t *Val)
-{
-       const uint8_t   *str = (const uint8_t *)Input;
-       *Val = 0xFFFD;  // Assume invalid character
-       
-       // ASCII
-       if( !(*str & 0x80) ) {
-               *Val = *str;
-               return 1;
-       }
-       
-       // Middle of a sequence
-       if( (*str & 0xC0) == 0x80 ) {
-               return 1;
-       }
-       
-       // Two Byte
-       if( (*str & 0xE0) == 0xC0 ) {
-               *Val = (*str & 0x1F) << 6;      // Upper 6 Bits
-               str ++;
-               if( (*str & 0xC0) != 0x80)      return -1;      // Validity check
-               *Val |= (*str & 0x3F);  // Lower 6 Bits
-               return 2;
-       }
-       
-       // Three Byte
-       if( (*str & 0xF0) == 0xE0 ) {
-               *Val = (*str & 0x0F) << 12;     // Upper 4 Bits
-               str ++;
-               if( (*str & 0xC0) != 0x80)      return -1;      // Validity check
-               *Val |= (*str & 0x3F) << 6;     // Middle 6 Bits
-               str ++;
-               if( (*str & 0xC0) != 0x80)      return -1;      // Validity check
-               *Val |= (*str & 0x3F);  // Lower 6 Bits
-               return 3;
-       }
-       
-       // Four Byte
-       if( (*str & 0xF1) == 0xF0 ) {
-               *Val = (*str & 0x07) << 18;     // Upper 3 Bits
-               str ++;
-               if( (*str & 0xC0) != 0x80)      return -1;      // Validity check
-               *Val |= (*str & 0x3F) << 12;    // Middle-upper 6 Bits
-               str ++;
-               if( (*str & 0xC0) != 0x80)      return -1;      // Validity check
-               *Val |= (*str & 0x3F) << 6;     // Middle-lower 6 Bits
-               str ++;
-               if( (*str & 0xC0) != 0x80)      return -1;      // Validity check
-               *Val |= (*str & 0x3F);  // Lower 6 Bits
-               return 4;
-       }
-       
-       // UTF-8 Doesn't support more than four bytes
-       return 4;
-}
-
-
-
-
diff --git a/Usermode/Applications/axwin2_src/WM/wm.c b/Usermode/Applications/axwin2_src/WM/wm.c
deleted file mode 100644 (file)
index b073223..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- * 
- * Window Manager and Widget Control
- */
-#include "common.h"
-#include <stdlib.h>
-#include <string.h>
-#include "wm.h"
-#include <acess/sys.h> // _SysDebug
-
-// === IMPORTS ===
-extern void    Video_GetTextDims(tFont *Font, const char *Text, int *W, int *H);
-
-// === PROTOTYPES ===
-tApplication   *AxWin_RegisterClient(tIPC_Type *IPCType, void *Ident, const char *Name);
-void   AxWin_DeregisterClient(tApplication *App);
-tApplication   *AxWin_GetClient(tIPC_Type *Method, void *Ident);
-tElement       *AxWin_CreateElement(tElement *Parent, int Type, int Flags, const char *DebugName);
-void   AxWin_DeleteElement(tElement *Element);
-void   AxWin_SetFlags(tElement *Element, int Flags);
-void   AxWin_SetSize(tElement *Element, int Size);
-void   AxWin_SetText(tElement *Element, const char *Text);
-
-// === GLOBALS ===
-// - TODO: Handle windows by having multiple root elements
-tElement       gWM_RootElement = {
-       .DebugName = "ROOT"
-};
-tWindow        *gWM_WindowFirst;
-tWindow        *gWM_WindowLast;
-tApplication   *gWM_Applications;
- int   giWM_MaxAreaX = 0;
- int   giWM_MaxAreaY = 0;
- int   giWM_MaxAreaW = -1;
- int   giWM_MaxAreaH = -1;
-
-// --- Element type flags
-struct {
-       void    (*Init)(tElement *This);
-       void    (*Delete)(tElement *This);
-       void    (*UpdateFlags)(tElement *This);
-       void    (*UpdateSize)(tElement *This);
-       void    (*UpdateText)(tElement *This);
-}      gaWM_WidgetTypes[MAX_ELETYPES] = {
-       {NULL, NULL, NULL, NULL, NULL}, // NULL
-       {NULL, NULL, NULL, NULL, NULL}, // Window
-       {NULL, NULL, NULL, NULL, NULL}  // Box
-};
-const int      ciWM_NumWidgetTypes = sizeof(gaWM_WidgetTypes)/sizeof(gaWM_WidgetTypes[0]);
-
-// === CODE ===
-tApplication *AxWin_RegisterClient(tIPC_Type *Method, void *Ident, const char *Name)
-{
-        int    identlen = Method->GetIdentSize(Ident);
-       // Structure, empty string, Name, Ident
-       tApplication    *ret = calloc( 1, sizeof(tApplication) + 1 + strlen(Name) + 1 + identlen );
-       
-       // DebugName is empty
-       
-       // Name/Title
-       ret->Name = &ret->MetaElement.DebugName[1];
-       strcpy(ret->Name, Name);
-       // Ident
-       ret->Ident = ret->Name + strlen(Name) + 1;
-       memcpy(ret->Ident, Ident, identlen);
-       // IPC Type
-       ret->IPCType = Method;
-
-       // Element index
-       ret->MaxElementIndex = DEFAULT_ELEMENTS_PER_APP;
-       ret->EleIndex = calloc( 1, ret->MaxElementIndex * sizeof(*ret->EleIndex) );
-
-       // Add to global list
-       ret->Next = gWM_Applications;
-       gWM_Applications = ret;
-
-       // TODO: Inform listeners of the new application
-
-       return ret;
-}
-
-void AxWin_DeregisterClient(tApplication *App)
-{
-       // TODO: Complete implementing DeregisterClient
-       tElement        *win, *next;
-
-       for( win = App->MetaElement.FirstChild; win; win = next )
-       {
-               next = win->NextSibling;
-               AxWin_DeleteElement(win);
-       }
-
-       // TODO: Inform listeners of deleted application
-       
-       // Remove from list
-       {
-               tApplication    *app, *prev = NULL;
-               for( app = gWM_Applications; app; app = app->Next )
-               {
-                       if( app == App )        break;
-                       prev = app;
-               }
-               
-               if( app )
-               {
-                       if(prev)
-                               prev->Next = App->Next;
-                       else
-                               gWM_Applications = App->Next;
-               }
-       }
-       
-       free(App);
-}
-
-/**
- * \brief Get an application handle from a client identifier
- */
-tApplication *AxWin_GetClient(tIPC_Type *Method, void *Ident)
-{
-       // TODO: Faster and smarter technique
-       tApplication    *app;
-       for( app = gWM_Applications; app; app = app->Next )
-       {
-               if( app->IPCType != Method )    continue;
-               if( Method->CompareIdent( app->Ident, Ident ) != 0 ) continue;
-               return app;
-       }
-       return NULL;
-}
-
-tElement *AxWin_CreateAppWindow(tApplication *App, const char *Name)
-{
-       tElement        *ret;
-       tWindow *win;
-       
-       win = calloc(1, sizeof(tWindow) + 1);
-       if(!win)        return NULL;
-       
-       ret = &win->RootElement;
-       ret->Type = ELETYPE_WINDOW;
-       ret->Data = win;
-       ret->Parent = &App->MetaElement;
-       
-       // Add to parent list
-       if(ret->Parent->LastChild)
-               ret->Parent->LastChild->NextSibling = ret;
-       ret->Parent->LastChild = ret;
-       if(!ret->Parent->FirstChild)
-               ret->Parent->FirstChild = ret;
-       
-       ret->Text = strdup(Name);
-       
-       return ret;
-}
-
-// --- Widget Creation and Control ---
-tAxWin_Element *AxWin_CreateElement(tElement *Parent, int Type, int Flags, const char *DebugName)
-{
-       tElement        *ret;
-       const char      *dbgName = DebugName ? DebugName : "";
-       
-       ret = calloc(sizeof(tElement)+strlen(dbgName)+1, 1);
-       if(!ret)        return NULL;
-       
-       // Prepare
-       ret->Type = Type;
-       strcpy(ret->DebugName, dbgName);
-       if(Parent == NULL)      Parent = &gWM_RootElement;
-       ret->Parent = Parent;
-       ret->Flags = Flags;
-       
-       // Append to parent's list
-       if(Parent->LastChild)
-               Parent->LastChild->NextSibling = ret;
-       Parent->LastChild = ret;
-       if(!Parent->FirstChild) Parent->FirstChild = ret;
-       
-       ret->PaddingL = 2;
-       ret->PaddingR = 2;
-       ret->PaddingT = 2;
-       ret->PaddingB = 2;
-       
-       if( Type < ciWM_NumWidgetTypes && gaWM_WidgetTypes[Type].Init )
-               gaWM_WidgetTypes[Type].Init(ret);
-       
-       WM_UpdateMinDims(ret->Parent);
-       
-       return ret;
-}
-
-/**
- * \brief Delete an element
- */
-void AxWin_DeleteElement(tElement *Element)
-{
-       tElement        *child, *next;
-       
-       for(child = Element->FirstChild; child; child = next)
-       {
-               next = child->NextSibling;
-               AxWin_DeleteElement(child);
-       }
-
-       // TODO: Implement AxWin_DeleteElement
-       // TODO: Clean up related data.
-       if( Element->Type < ciWM_NumWidgetTypes && gaWM_WidgetTypes[Element->Type].Delete )
-               gaWM_WidgetTypes[Element->Type].Delete(Element);
-
-       if(Element->Owner)
-               Element->Owner->EleIndex[ Element->ApplicationID ] = NULL;
-
-       Element->Type = 0;
-       Element->Owner = 0;
-       Element->Flags = 0;
-
-       free(Element);
-}
-
-/**
- * \brief Alter an element's flags 
- */
-void AxWin_SetFlags(tElement *Element, int Flags)
-{
-       // Permissions are handled in the message handler
-       if(!Element) {
-               gWM_RootElement.Flags = Flags;
-               return ;
-       }
-       
-       Element->Flags = Flags;
-       return ;
-}
-
-/**
- * \brief Set the fixed lenghthways size of an element
- */
-void AxWin_SetSize(tElement *Element, int Size)
-{
-       if(!Element)    return ;
-       Element->FixedWith = Size;
-       return ;
-}
-
-/**
- * \brief Set the text field of an element
- * \note Used for the image path on ELETYPE_IMAGE
- */
-void AxWin_SetText(tElement *Element, const char *Text)
-{
-       if(!Element)    return ;
-       if(Element->Text)       free(Element->Text);
-       Element->Text = strdup(Text);
-       
-       switch(Element->Type)
-       {
-       case ELETYPE_IMAGE:
-               if(Element->Data)       free(Element->Data);
-               Element->Data = Image_Load( Element->Text );
-               if(!Element->Data) {
-                       Element->Flags &= ~ELEFLAG_FIXEDSIZE;
-                       return ;
-               }
-               
-               //Element->Flags |= ELEFLAG_FIXEDSIZE;
-               Element->CachedW = ((tImage*)Element->Data)->Width;
-               Element->CachedH = ((tImage*)Element->Data)->Height;
-               
-               if(Element->Parent && Element->Parent->Flags & ELEFLAG_VERTICAL) {
-                       Element->MinCross = ((tImage*)Element->Data)->Width;
-                       Element->MinWith = ((tImage*)Element->Data)->Height;
-               }
-               else {
-                       Element->MinWith = ((tImage*)Element->Data)->Width;
-                       Element->MinCross = ((tImage*)Element->Data)->Height;
-               }
-               break;
-       
-       case ELETYPE_TEXT:
-               {
-                int    w=0, h=0;
-               Video_GetTextDims(NULL, Element->Text, &w, &h);
-               if(Element->Parent && Element->Parent->Flags & ELEFLAG_VERTICAL) {
-                       Element->MinCross = w;
-                       Element->MinWith = h;
-               }
-               else {
-                       Element->MinWith = w;
-                       Element->MinCross = h;
-               }
-               }
-               break;
-       default:        // Any other, no special case
-               break ; 
-       }
-       
-       return ;
-}
diff --git a/Usermode/Applications/axwin2_src/WM/wm.h b/Usermode/Applications/axwin2_src/WM/wm.h
deleted file mode 100644 (file)
index 5977fd6..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Acess2 Window Manager (AxWin2)
- */
-#ifndef _WM_H_
-#define _WM_H_
-
-#include <axwin2/axwin.h>
-#include "common.h"
-
-/**
- * \brief Number of elements that can be owned by each application
- */
-// TODO: Fine tune these values
-#define MAX_ELEMENTS_PER_APP   1024
-#define DEFAULT_ELEMENTS_PER_APP       128
-
-typedef struct sAxWin_Element  tElement;
-typedef struct sMenuItem       tMenuItem;
-typedef struct sWindow tWindow;
-typedef struct sApplication    tApplication;
-
-struct sAxWin_Element
-{
-       enum eElementTypes      Type;
-       
-       // Element Tree
-       tElement        *Parent;
-       tElement        *FirstChild;
-       tElement        *LastChild;
-       tElement        *NextSibling;
-       
-       // Application
-       tApplication    *Owner; //!< Owning application
-       uint16_t        ApplicationID;  //!< Index into sApplication::EleIndex
-
-       // User modifiable attributes   
-       short   PaddingL, PaddingR;
-       short   PaddingT, PaddingB;
-       short   GapSize;
-       
-       uint32_t        Flags;
-       
-       short   FixedWith;      //!< Fixed lengthways Size attribute (height)
-       short   FixedCross;     //!< Fixed Cross Size attribute (width)
-       
-       char    *Text;
-       
-       // -- Attributes maitained by the element code
-       // Not touched by the user
-       short   MinWith;        //!< Minimum long size
-       short   MinCross;       //!< Minimum cross size
-       void    *Data;  //!< Per-type data
-       
-       // -- Render Cache
-       short   CachedX, CachedY;
-       short   CachedW, CachedH;
-       
-       char    DebugName[];
-};
-
-struct sMenuItem
-{
-       tMenuItem       *Next;
-        int    Flags;
-        int    ID;     //!< ID number sent to application
-       const char      *Label;
-       const char      *Right;
-       tMenuItem       *FirstChild;
-};
-
-struct sWindow
-{
-        int    X, Y, W, H;
-       void    *Icon;
-       
-       tApplication    *App;
-       
-       tWindow *OrderNext;     // Render order
-       
-       tMenuItem       *Menus;
-       
-       tElement        RootElement;
-};
-
-struct sApplication
-{
-       tApplication    *Next;
-
-       tIPC_Type       *IPCType;
-       void    *Ident; //!< Client Identifier
-       
-       char    *Name;  //!< Application name
-       
-        int    MaxElementIndex;        //!< Number of entries in \a EleIndex
-       tElement        **EleIndex;     //!< Array of pointers to elements owned by this application
-       
-       tElement        MetaElement;    //!< Tabs child off this
-};
-
-// === FUNCTIONS ===
-
-// --- Render
-extern void    WM_UpdateMinDims(tElement *Element);
-extern void    WM_UpdateDimensions(tElement *Element, int Pass);
-extern void    WM_UpdatePosition(tElement *Element);
-extern void    WM_RenderWidget(tElement *Element);
-extern void    WM_Update(void);
-
-#endif
diff --git a/Usermode/Applications/axwin2_src/notes.txt b/Usermode/Applications/axwin2_src/notes.txt
deleted file mode 100644 (file)
index d4090b9..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Applications can have 0-* windows
-Windows can have 1-* tabs
-Each window has a menu based on a template from the application
index e34968c..fee178a 100644 (file)
@@ -19,6 +19,7 @@
 void   create_sidebar(void);
 void   create_mainmenu(void);
 void   create_run_dialog(void);
+void   mainmenu_run_dialog(void *unused);
 
 // === GLOBALS ===
 tHWND  gSidebar;
@@ -49,6 +50,10 @@ int main(int argc, char *argv[])
        create_mainmenu();
        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);
+
        // Idle loop
        AxWin3_MainLoop();
        
@@ -113,6 +118,7 @@ void mainmenu_app_terminal(void *unused)
 void mainmenu_run_dialog(void *unused)
 {
        AxWin3_ShowWindow(gRunDialog, 1);
+       AxWin3_FocusWindow(gRunDialog);
 }
 
 void create_mainmenu(void)
@@ -130,6 +136,7 @@ void create_mainmenu(void)
 // --------------------------------------------------------------------
 int run_dorun(tAxWin3_Widget *unused)
 {
+       _SysDebug("DoRun pressed");
        char *cmd = AxWin3_Widget_GetText(gRunInput);
        _SysDebug("Command string '%s'", cmd);
        AxWin3_ShowWindow(gRunDialog, 0);
index 33fa974..592f46b 100644 (file)
@@ -14,7 +14,7 @@ all:
 install:
        @$(xMKDIR) $(DISTROOT)/Apps ; true
        @$(xMKDIR) $(DISTROOT)/Apps/AxWin ; true
-       @$(xMKDIR) $(DISTROOT)/Apps/3.0 ; true
+       @$(xMKDIR) $(DISTROOT)/Apps/AxWin/3.0 ; true
        @$(foreach DIR,$(DIRS), echo --- $(NAME)/$(DIR) && $(SUBMAKE) -C $(DIR) $@ &&) true
        @$(foreach FILE,$(FILES), $(xCP) $(FILE:-%=%) $(DISTROOT)/Apps/AxWin/3.0/$(FILE:-%=%) &&) true
 
index 44675d2..1a7ca7e 100644 (file)
@@ -33,6 +33,7 @@ struct sHotkeyTarget
 
 
 extern void    WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName);
+extern void    WM_Hotkey_RegisterAction(const char *ActionName, tWindow *Target, uint16_t Index);
 extern void    WM_Hotkey_KeyDown(uint32_t Scancode);
 extern void    WM_Hotkey_KeyUp(uint32_t Scancode);
 
index b3648bb..cbed7fd 100644 (file)
@@ -13,6 +13,7 @@
 #include <stdio.h>
 #include <wm.h>
 #include <wm_internals.h>
+#include <wm_hotkeys.h>
 
 #define AXWIN_PORT     4101
 
@@ -495,7 +496,26 @@ int IPC_Msg_SetWinPos(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
 
 int IPC_Msg_RegisterAction(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
 {
+       tIPCMsg_RegAction       *info = (void*)Msg->Data;
+       tWindow *win;
+       
        ASSERT(Msg->ID == IPCMSG_REGACTION);
+
+       if( Msg->Size < sizeof(*info) + 1 )
+               return -1;
+       
+       win = IPC_int_GetWindow(Client, Msg->Window);
+       if(!win)        return 1;
+
+       if( strnlen(info->Action, Msg->Size - sizeof(*info)) == Msg->Size - sizeof(*info) )
+               return 1;
+
+       _SysDebug("RegisterAction %p:%i [%i]\"%s\"",
+               Client, Msg->Window, info->Index, info->Action
+               );
+
+       WM_Hotkey_RegisterAction(info->Action, win, info->Index);
+
        return 0;
 }
 
index 7aa5534..0996f90 100644 (file)
@@ -9,6 +9,7 @@
 #include <acess/sys.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <axwin3/keysyms.h>
 
 // === IMPORTS ===
 extern void    Video_Setup(void);
@@ -18,6 +19,7 @@ extern int    Renderer_Widget_Init(void);
 extern int     Renderer_Background_Init(void);
 extern int     Renderer_Framebuffer_Init(void);
 extern void    WM_Update(void);
+extern void    WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName);
 
 // === PROTOTYPES ===
 void   ParseCommandline(int argc, char **argv);
@@ -63,6 +65,11 @@ int main(int argc, char *argv[])
        Renderer_Background_Init();
        Renderer_Framebuffer_Init();
        WM_Initialise();
+
+       // TODO: Config
+       uint32_t        keys[4];
+       keys[0] = KEYSYM_LEFTGUI;       keys[1] = KEYSYM_r;
+       WM_Hotkey_Register(2, keys, "Interface>Run");
        
        // Spawn interface root
        if( clone(CLONE_VM, 0) == 0 )
index 7668cbd..46b3198 100644 (file)
@@ -552,6 +552,34 @@ void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg)
 //     }
 }
 
+int Widget_GetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg)
+{
+       if( Len < sizeof(*Msg) )
+               return 0;
+       if( Len > sizeof(*Msg) )
+               return 1;       // Pass to user
+       
+       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;
+       
+       if( text ) {
+               omsg->WidgetID = Msg->WidgetID;
+               strcpy(omsg->Text, text);
+       }
+       else {
+               omsg->WidgetID = -1;
+               omsg->Text[0] = 0;
+       }
+       
+       WM_SendMessage(Info->RootElement.Window, Info->RootElement.Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf);
+       return 0;
+}
+
 int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
 {
        tWidgetWin      *info = Target->RendererInfo;
@@ -691,6 +719,8 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void
        case MSG_WIDGET_SETTEXT:
                Widget_SetText(info, Len, Data);
                return 0;
+       case MSG_WIDGET_GETTEXT:
+               return Widget_GetText(info, Len, Data);
        
        // 
        default:
index 3fbe4f7..bdea09c 100644 (file)
@@ -40,6 +40,11 @@ void WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName)
        h->Target = (void*)( h->Keys + nKeys );
        strcpy((char*)h->Target, ActionName);
        memcpy(h->Keys, Keys, nKeys * sizeof(uint32_t));
+       
+       h->Next = NULL;
+       if( gpWM_Hotkeys )
+               gpWM_Hotkeys->Next = h;
+       gpWM_Hotkeys = h;
 }
 
 void WM_Hotkey_RegisterAction(const char *ActionName, tWindow *Target, uint16_t Index)
@@ -82,6 +87,8 @@ void WM_Hotkey_KeyUp(uint32_t Scancode)
 {
        _UnsetKey(Scancode);
 
+       // Ensure that hotkeys are triggered on the longest sequence
+       // (so Win-Shift-R doesn't trigger Win-R if shift is released)
        if( !gbWM_HasBeenKeyDown )
                return ;
 
@@ -94,7 +101,8 @@ void WM_Hotkey_KeyUp(uint32_t Scancode)
                        if( _IsKeySet(hk->Keys[i]) )    continue ;
                        break;
                }
-               if( i == hk->nKeys )
+               _SysDebug("%i/%i satisfied for %s", i, hk->nKeys, hk->Target);
+               if( i != hk->nKeys )
                        continue ;
                
                // Fire shortcut
@@ -108,6 +116,7 @@ void WM_Hotkey_KeyUp(uint32_t Scancode)
 
 void WM_Hotkey_FireEvent(const char *Target)
 {
+//     _SysDebug("WM_Hotkey_FireEvent: (%s)", Target);
        // - Internal events (Alt-Tab, Close, Maximize, etc...)
        // TODO: Internal event handling
        
@@ -133,11 +142,13 @@ void WM_Hotkey_FireEvent(const char *Target)
 
 static void _SetKey(uint32_t sc)
 {
+//     _SysDebug("_SetKey: (%x)", sc);
        if( sc >= MAX_STATE_SCANCODE )  return;
        gWM_KeyStates[sc/8] |= 1 << (sc % 8);
 }
 static void _UnsetKey(uint32_t sc)
 {
+//     _SysDebug("_UnsetKey: (%x)", sc);
        if( sc >= MAX_STATE_SCANCODE )  return;
        gWM_KeyStates[sc/8] &= ~(1 << (sc % 8));
 }
index 751bcbb..5f6ef85 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->W )        continue;
-                       if( Y < win->Y || Y >= win->Y + win->H )        continue;
+                       if( X < win->X || X >= win->X + win->RealW )    continue;
+                       if( Y < win->Y || Y >= win->Y + win->RealH )    continue;
                        next_win = win; // Overwrite as we want the final rendered window
                }
        }
index e7424fe..6e61ba8 100644 (file)
@@ -17,6 +17,7 @@ typedef struct sIPCMsg_CreateWin      tIPCMsg_CreateWin;
 typedef struct sIPCMsg_Boolean tIPCMsg_Boolean;
 typedef struct sIPCMsg_SetWindowPos    tIPCMsg_SetWindowPos;
 typedef struct sIPCMsg_SendMsg tIPCMsg_SendMsg;
+typedef struct sIPCMsg_RegAction       tIPCMsg_RegAction;
 
 typedef struct sIPCMsg_GetDisplayDims  tIPCMsg_GetDisplayDims;
 typedef struct sIPCMsg_RetDisplayDims  tIPCMsg_RetDisplayDims;
@@ -73,6 +74,12 @@ struct sIPCMsg_SetWindowPos
        uint8_t         bSetDims;
 };
 
+struct sIPCMsg_RegAction
+{
+       uint16_t        Index;
+       char    Action[];
+};
+
 struct sIPCMsg_GetDisplayDims
 {
        uint16_t        DisplayID;
index 875f14b..450e4b4 100644 (file)
@@ -8,7 +8,6 @@
 #include <axwin3/axwin.h>
 #include <axwin3/widget.h>
 #include "include/internal.h"
-#include "include/ipc.h"
 #include <stdlib.h>
 #include <widget_messages.h>
 #include <string.h>
@@ -232,23 +231,20 @@ char *AxWin3_Widget_GetText(tAxWin3_Widget *Widget)
 {
        char    buf[sizeof(tWidgetMsg_SetText)];
        tWidgetMsg_SetText      *msg = (void*)buf;
-       tAxWin_IPCMessage       *retmsg;
-       char    *ret;
+       size_t  retmsg_size;
        
        msg->WidgetID = Widget->ID;
 
        AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf);
 
-       retmsg = AxWin3_int_WaitIPCMessage(MSG_WIDGET_GETTEXT);
-       msg = (void*)retmsg->Data;
-
-       if( retmsg->Size < sizeof(*msg) ) {
-               free(retmsg);
+       msg = AxWin3_WaitMessage(Widget->Window, MSG_WIDGET_GETTEXT, &retmsg_size);
+       if( retmsg_size < sizeof(*msg) ) {
+               free(msg);
                return NULL;
        }
 
-       ret = strndup(msg->Text, retmsg->Size - sizeof(*msg));
-       free(retmsg);
+       char    *ret = strndup(msg->Text, retmsg_size - sizeof(*msg));
+       free(msg);
        return ret;
 }
 
index 8b13860..4a6d8d3 100644 (file)
 #include <string.h>
 #include "include/internal.h"
 #include "include/ipc.h"
+#include <wm_messages.h>
 
-#define WINDOWS_PER_ALLOC      (63)
+#define WINDOWS_PER_ALLOC      (64-1)  // -1 to make it 64 pointers (+ Next)
+#define MAX_HOTKEYS    32
 
 typedef struct sWindowBlock    tWindowBlock;
 
@@ -28,6 +30,7 @@ struct sWindowBlock
  int   giAxWin3_LowestFreeWinID;
  int   giAxWin3_HighestUsedWinID;
 tWindowBlock   gAxWin3_WindowList;
+tAxWin3_HotkeyCallback gAxWin3_Hotkeys[MAX_HOTKEYS];
 
 // === CODE ===
 tWindow *AxWin3_int_CreateWindowStruct(uint32_t ServerID, int ExtraBytes)
@@ -198,7 +201,26 @@ void AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg)
                        return ;
                }
                _SysDebug("IPC Message 0x%x - %i bytes", info->ID, info->Length);
-               dest->Handler(dest, info->ID, info->Length, info->Data);
+
+               if( dest->Handler(dest, info->ID, info->Length, info->Data) )
+                       ;
+               else {
+                       switch( info->ID )
+                       {
+                       case WNDMSG_HOTKEY: {
+                               const struct sWndMsg_Hotkey *mi = (void*)info->Data;
+                               if( mi->ID >= MAX_HOTKEYS ) 
+                                       ;       // TODO: Error when hotkey is out of range
+                               else if( gAxWin3_Hotkeys[mi->ID] == 0 )
+                                       _SysDebug("--- Unmapped hotkey ID %i fired", mi->ID);
+                               else
+                                       gAxWin3_Hotkeys[mi->ID]();
+                               }break;
+                       default:
+                               _SysDebug("--- Unhandled SENDMSG %i", info->ID);
+                               break;
+                       }
+               }
                break; }
        default:
                _SysDebug("Unknow message ID %i", Msg->ID);
@@ -235,6 +257,32 @@ void AxWin3_SendMessage(tHWND Window, tHWND Destination, int Message, int Length
        free(msg);
 }
 
+void *AxWin3_WaitMessage(tHWND Window, int MessageID, size_t *Length)
+{
+       tAxWin_IPCMessage       *msg;
+       
+       for( ;; )
+       {
+               msg = AxWin3_int_WaitIPCMessage(IPCMSG_SENDMSG);
+               if( msg->Window != AxWin3_int_GetWindowID(Window) ) {
+                       AxWin3_int_HandleMessage(msg);
+                       continue ;
+               }
+               tIPCMsg_SendMsg *info = (void*)msg->Data;
+               if( info->ID != MessageID ) {
+                       AxWin3_int_HandleMessage(msg);
+                       continue ;
+               }
+
+               *Length = info->Length;
+               void    *ret = malloc(info->Length);    
+               memcpy(ret, info->Data, info->Length);
+               free(msg);
+       
+               return ret;
+       }
+}
+
 void AxWin3_FocusWindow(tHWND Window)
 {
        tAxWin_IPCMessage       *msg;
@@ -326,3 +374,28 @@ void AxWin3_ResizeWindow(tHWND Window, short W, short H)
        free(msg);
 }
 
+int AxWin3_RegisterAction(tHWND Window, const char *Action, tAxWin3_HotkeyCallback cb)
+{
+        int    i;
+       for( i = 0; i < MAX_HOTKEYS; i ++ )
+       {
+               if( gAxWin3_Hotkeys[i] == NULL )
+               {
+                       tAxWin_IPCMessage       *msg;
+                       struct sIPCMsg_RegAction        *info;
+                       gAxWin3_Hotkeys[i] = cb;
+                       
+                       msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_REGACTION, 0, sizeof(*info)+strlen(Action)+1);
+                       info = (void*)msg->Data;
+               
+                       info->Index = i;
+                       strcpy(info->Action, Action);
+                       
+                       AxWin3_int_SendIPCMessage(msg);
+                       free(msg);
+                       return i;
+               }
+       }
+       return -1;
+}
+
index 820a119..8831cd6 100644 (file)
@@ -171,7 +171,7 @@ void Scan_Dir(tInterface **IfaceList, const char *Directory)
                fprintf(stderr, "Unable to open directory '%s'\n", Directory);
        }
 
-       while( readdir(dp, filename) )
+       while( SysReadDir(dp, filename) )
        {
                if( filename[0] == '.' )        continue ;              
                if( strcmp(filename, "lo") == 0 )       continue ;
index 579aa47..cf5d5dc 100644 (file)
@@ -131,7 +131,7 @@ void DumpInterfaces(void)
        
        dp = open(IPSTACK_ROOT, OPENFLAG_READ);
        
-       while( readdir(dp, filename) )
+       while( SysReadDir(dp, filename) )
        {
                if(filename[0] == '.')  continue;
                DumpInterface(filename);
index 1d60fbc..f074bff 100644 (file)
@@ -118,7 +118,7 @@ void DumpRoutes(void)
        
        printf("Type\tNetwork \tGateway \tMetric\tIFace\n");
        
-       while( readdir(dp, filename) )
+       while( SysReadDir(dp, filename) )
        {
                if(filename[0] == '.')  continue;
                DumpRoute(filename);
index 4be8f0a..2394af6 100644 (file)
@@ -75,7 +75,7 @@ int main(int argc, char *argv[])
        }
 
        // Traverse Directory
-       while( (tmp = readdir(fd, buf)) > 0 )
+       while( (tmp = SysReadDir(fd, buf)) > 0 )
        {
                // Error check
                if(tmp < 0) {
diff --git a/Usermode/Applications/lspci_src/Makefile b/Usermode/Applications/lspci_src/Makefile
new file mode 100644 (file)
index 0000000..b0c5e4f
--- /dev/null
@@ -0,0 +1,10 @@
+# Project: PCI Device Listing
+
+-include ../Makefile.cfg
+
+LDFLAGS += 
+
+OBJ = main.o
+BIN = lspci
+
+-include ../Makefile.tpl
diff --git a/Usermode/Applications/lspci_src/main.c b/Usermode/Applications/lspci_src/main.c
new file mode 100644 (file)
index 0000000..c24fde9
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Acess2 lspci
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <acess/sys.h>
+
+#define PCI_BASE       "/Devices/pci"
+// === PROTOTYPES ===
+ int   main(int argc, char *argv[]);
+void   show_device(int PFD, const char *File, int bVerbose);
+
+// === CODE ===
+int main(int argc, char *argv[])
+{
+       int fd = open(PCI_BASE, OPENFLAG_READ);
+
+       char name[256]; 
+
+       while( SysReadDir(fd, name) )
+       {
+               if(name[0] == '.')      continue ;
+               
+               show_device(fd, name, 0);
+       }
+
+       return 0;
+}
+
+void show_device(int PFD, const char *File, int bVerbose)
+{
+        int    fd;
+        int    rv;
+
+       struct {
+               uint16_t        vendor;
+               uint16_t        device;
+               uint32_t        _unused;
+               uint32_t        revclass;
+       } pciinfo;
+
+       fd = _SysOpenChild(PFD, File, OPENFLAG_READ);
+       if( fd == -1 ) {
+               printf("%s - ERR (open failure)\n", File);
+               return ;
+       }
+       rv = read(fd, &pciinfo, sizeof(pciinfo));
+       if( rv != sizeof(pciinfo) ) {
+               printf("%s - ERR (read %i < %i)\n", File, rv, sizeof(pciinfo));
+               close(fd);
+               return ;
+       }
+       uint32_t        class_if = pciinfo.revclass >> 8;
+       uint8_t         revision = pciinfo.revclass & 0xFF;
+       printf("%s - %04x:%04x %06x:%02x\n",
+               File,
+               pciinfo.vendor, pciinfo.device,
+               class_if, revision
+               );
+
+       if( bVerbose )
+       {
+               printf("\n");
+       }
+
+       close(fd);
+}
+
index 54b203a..e252210 100644 (file)
@@ -37,7 +37,7 @@ endif
 $(_BIN): $(OBJ) $(_LIBS)
        @mkdir -p $(dir $(_BIN))
        @echo [LD] -o $(BIN) $(OBJ)
-       @$(LD) $(LDFLAGS) -o $(_BIN) $(OBJ)
+       @$(LD) $(LDFLAGS) -o $(_BIN) $(OBJ) $(shell $(CC) -print-libgcc-file-name)
        @$(DISASM) -S $(_BIN) > $(_OBJPREFIX)$(BIN).dsm
 
 $(_OBJPREFIX)%.o: %.c
diff --git a/Usermode/Libraries/acess.ld_src/acess_armv6.ld.h b/Usermode/Libraries/acess.ld_src/acess_armv6.ld.h
new file mode 100644 (file)
index 0000000..0ea7f90
--- /dev/null
@@ -0,0 +1,235 @@
+/* Script for -z combreloc: combine and sort reloc sections */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+             "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SEARCH_DIR(__LIBDIR)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x8000)); . = SEGMENT_START("text-segment", 0x8000);
+  .interp         : { *(.interp) }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+  .hash           : { *(.hash) }
+  .gnu.hash       : { *(.gnu.hash) }
+  .dynsym         : { *(.dynsym) }
+  .dynstr         : { *(.dynstr) }
+  .gnu.version    : { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+  .rel.dyn        :
+    {
+      *(.rel.init)
+      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+      *(.rel.fini)
+      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+      *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+      *(.rel.ctors)
+      *(.rel.dtors)
+      *(.rel.got)
+      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+      PROVIDE_HIDDEN (__rel_iplt_start = .);
+      *(.rel.iplt)
+      PROVIDE_HIDDEN (__rel_iplt_end = .);
+      PROVIDE_HIDDEN (__rela_iplt_start = .);
+      PROVIDE_HIDDEN (__rela_iplt_end = .);
+    }
+  .rela.dyn       :
+    {
+      *(.rela.init)
+      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+      *(.rela.fini)
+      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+      *(.rela.ctors)
+      *(.rela.dtors)
+      *(.rela.got)
+      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+      PROVIDE_HIDDEN (__rel_iplt_start = .);
+      PROVIDE_HIDDEN (__rel_iplt_end = .);
+      PROVIDE_HIDDEN (__rela_iplt_start = .);
+      *(.rela.iplt)
+      PROVIDE_HIDDEN (__rela_iplt_end = .);
+    }
+  .rel.plt        :
+    {
+      *(.rel.plt)
+    }
+  .rela.plt       :
+    {
+      *(.rela.plt)
+    }
+  .init           :
+  {
+    KEEP (*(.init))
+  } =0
+  .plt            : { *(.plt) }
+  .iplt           : { *(.iplt) }
+  .text           :
+  {
+    *(.text.unlikely .text.*_unlikely)
+    *(.text.exit .text.exit.*)
+    *(.text.startup .text.startup.*)
+    *(.text.hot .text.hot.*)
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+    *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
+  } =0
+  .fini           :
+  {
+    KEEP (*(.fini))
+  } =0
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1        : { *(.rodata1) }
+  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
+   PROVIDE_HIDDEN(__exidx_start = .);
+  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+   PROVIDE_HIDDEN(__exidx_end = .);
+  .eh_frame_hdr : { *(.eh_frame_hdr) }
+  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
+  /* Adjust the address for the data segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  . = ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1));
+  /* Exception handling  */
+  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+  /* Thread Local Storage sections  */
+  .tdata         : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+  .tbss                  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+  .preinit_array     :
+  {
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+  }
+  .init_array     :
+  {
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array))
+    PROVIDE_HIDDEN (__init_array_end = .);
+  }
+  .fini_array     :
+  {
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(SORT(.fini_array.*)))
+    KEEP (*(.fini_array))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  }
+  .ctors          :
+  {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*crtbegin?.o(.ctors))
+    /* We don't want to include the .ctor section from
+       the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+  .dtors          :
+  {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*crtbegin?.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  }
+  .jcr            : { KEEP (*(.jcr)) }
+  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
+  .dynamic        : { *(.dynamic) }
+  .got            : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+  .data           :
+  {
+    __data_start = . ;
+    *(.data .data.* .gnu.linkonce.d.*)
+    SORT(CONSTRUCTORS)
+  }
+  .data1          : { *(.data1) }
+  _edata = .; PROVIDE (edata = .);
+  __bss_start = .;
+  __bss_start__ = .;
+  .bss            :
+  {
+   *(.dynbss)
+   *(.bss .bss.* .gnu.linkonce.b.*)
+   *(COMMON)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections.
+      FIXME: Why do we need it? When there is no .bss section, we don't
+      pad the .data section.  */
+   . = ALIGN(. != 0 ? 32 / 8 : 1);
+  }
+  _bss_end__ = . ; __bss_end__ = . ;
+  . = ALIGN(32 / 8);
+  . = ALIGN(32 / 8);
+  __end__ = . ;
+  _end = .; PROVIDE (end = .);
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment       0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo .zdebug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames .zdebug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges .zdebug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames .zdebug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.* .zdebug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev .zdebug_abbrev) }
+  .debug_line     0 : { *(.debug_line .zdebug_line) }
+  .debug_frame    0 : { *(.debug_frame .zdebug_frame) }
+  .debug_str      0 : { *(.debug_str .zdebug_str) }
+  .debug_loc      0 : { *(.debug_loc .zdebug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo .zdebug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames .zdebug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames .zdebug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames .zdebug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames .zdebug_varnames) }
+  /* DWARF 3 */
+  .debug_pubtypes 0 : { *(.debug_pubtypes .zdebug_pubtypes) }
+  .debug_ranges   0 : { *(.debug_ranges .zdebug_ranges) }
+    .stack         0x80000 :
+  {
+    _stack = .;
+    *(.stack)
+  }
+  .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
+  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+}
+
+
index 44af24a..d451b2c 100644 (file)
@@ -20,7 +20,7 @@ include ../Makefile.tpl
 # create libld-acess.so
 $(_XBIN): $(_OBJPREFIX)_stublib.o
        @echo [LD] -o -shared libld-acess.so
-       $(LD) -shared -o $@ $<
+       $(LD) -shared -o $@ $< $(LDFLAGS)
 #      @$(LD) $(LDFLAGS) -o $@ $(OBJ)
 
 
index abf8043..1136226 100644 (file)
@@ -14,6 +14,7 @@ int _errno;
 #include "arch/syscalls.s.h"
 
 // libgcc functions
+#if 0
 uint64_t __udivdi3(uint64_t Num, uint64_t Den){return 0;}
 uint64_t __umoddi3(uint64_t Num, uint64_t Den){return 0;}
 
@@ -21,6 +22,8 @@ int32_t __divsi3(int32_t Num, int32_t Den){return 0;}
 int32_t __modsi3(int32_t Num, int32_t Den){return 0;}
 uint32_t __udivsi3(uint32_t Num, uint32_t Den){return 0;}
 uint32_t __umodsi3(uint32_t Num, uint32_t Den){return 0;}
+#endif
 
 void   *_crt0_exit_handler;
+void   abort(void){}
 
diff --git a/Usermode/Libraries/ld-acess.so_src/arch/armv6.S.h b/Usermode/Libraries/ld-acess.so_src/arch/armv6.S.h
new file mode 100644 (file)
index 0000000..3564392
--- /dev/null
@@ -0,0 +1,137 @@
+//
+// Acess2 ARMv7 - System Calls
+//
+
+.globl _start
+.extern SoMain
+_start:
+       pop {r0}
+       ldm sp, {r1,r2,r3}
+       bl SoMain
+       
+       mov r4, r0
+
+       pop {r0,r1,r2}
+       blx r4
+       
+       b _exit
+
+@ Stupid GCC
+.globl __ucmpdi2
+__ucmpdi2:
+       cmp r0, r2
+       movmi r0, #0
+       movmi pc, lr
+       movhi r0, #2
+       movhi pc, lr
+       cmp r1, r2
+       movmi r0, #0
+       movmi pc, lr
+       movhi r0, #2
+       movhi pc, lr
+       mov r0, #1
+       mov pc, lr
+
+@ Well, can't blame it
+@ - Clear the instruction cache
+.globl __clear_cache
+__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
+@
+.globl _errno
+_errno:        .long   0       @ Placed in .text, to allow use of relative addressing
+
+.macro syscall0 _name, _num    
+.globl \_name
+\_name:
+       push {lr}
+       svc #\_num
+       str r2, _errno
+       pop {pc}
+.endm
+
+.macro syscall5 _name, _num
+.globl \_name
+\_name:
+       push {r4, lr}
+       ldr r4, [sp,#8]
+       svc #\_num
+       str r2, _errno
+       pop {r4, pc}
+.endm
+
+.macro syscall6 _name, _num
+.globl \_name
+\_name:
+       push {r4,r5,lr}
+       ldr r4, [sp,#12]
+       ldr r5, [sp,#16]
+       svc #\_num
+       str r2, _errno
+       pop {r4,r5,pc}
+.endm
+
+#define SYSCALL0(_name,_num)   syscall0 _name, _num
+#define SYSCALL1(_name,_num)   SYSCALL0(_name, _num)
+#define SYSCALL2(_name,_num)   SYSCALL0(_name, _num)
+#define SYSCALL3(_name,_num)   SYSCALL0(_name, _num)
+#define SYSCALL4(_name,_num)   SYSCALL0(_name, _num)
+// TODO: 5/6 need special handling, because the args are on the stack
+#define SYSCALL5(_name,_num)   syscall5 _name, _num
+#define SYSCALL6(_name,_num)   syscall6 _name, _num
+
+// Override the clone syscall
+#define _exit  _exit_raw
+#define _clone _clone_raw
+#include "syscalls.s.h"
+#undef _exit
+#undef _clone
+
+.globl _clone
+_clone:
+       push {r4}
+       mov r4, r1
+       svc #SYS_CLONE
+       str r2, _errno
+       tst r4, r4
+       beq _clone_ret
+       @ If in child, set SP
+       tst r0,r0
+       movne sp, r4
+_clone_ret:
+       pop {r4}
+       mov pc, lr
+
+.globl _exit
+_exit:
+       svc #0
+       b .
+
+.globl abort
+abort:
+       mov r0, #0
+       svc #0
+       b .
+
+.globl __exidx_start
+__exidx_start:
+       b .
+.globl __exidx_end
+__exidx_end:
+       b .
+
diff --git a/Usermode/Libraries/ld-acess.so_src/arch/armv6.ld b/Usermode/Libraries/ld-acess.so_src/arch/armv6.ld
new file mode 100644 (file)
index 0000000..7f1b3c8
--- /dev/null
@@ -0,0 +1,69 @@
+ENTRY(_start)
+OUTPUT_FORMAT(elf32-littlearm)
+
+SECTIONS {
+       . = 0x6FFF0000;
+       gLinkedBase = .;
+       . += SIZEOF_HEADERS;
+       .interp          : { *(.interp) }
+       .note.gnu.build-id : { *(.note.gnu.build-id) }
+       .hash              : { *(.hash) }
+       .gnu.hash          : { *(.gnu.hash) }
+       .dynsym          : { *(.dynsym) }
+       .dynstr          : { *(.dynstr) }
+       .gnu.version    : { *(.gnu.version) }
+       .gnu.version_d  : { *(.gnu.version_d) }
+       .gnu.version_r  : { *(.gnu.version_r) }
+       .rel.dyn                :
+       {
+               *(.rel.init)
+               *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+               *(.rel.fini)
+               *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+               *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+               *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+               *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+               *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+               *(.rel.ctors)
+               *(.rel.dtors)
+               *(.rel.got)
+               *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+       }
+       .rela.dyn          :
+       {
+               *(.rela.init)
+               *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+               *(.rela.fini)
+               *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+               *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+               *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+               *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+               *(.rela.ctors)
+               *(.rela.dtors)
+               *(.rela.got)
+               *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+       }
+
+       .text : AT(ADDR(.text)) {
+               code = .;
+               *(.text)
+               *(.rodata*)
+               PROVIDE_HIDDEN(__exidx_start = .);
+               .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+               PROVIDE_HIDDEN(__exidx_end = .);
+       }
+
+       .data ALIGN (0x1000) : AT(ADDR(.data)) {
+               data = .;
+               *(.data)
+       }
+
+       .bss ALIGN (0x1000) : AT(ADDR(.bss)) {
+               _sbss = .;
+               *(COMMON)
+               *(.bss)
+               _ebss = .;
+               bss = .;
+       }
+       _end = .;
+}
index cd7b8fe..aef2247 100644 (file)
@@ -46,7 +46,7 @@ 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(readdir, SYS_READDIR) // int, char*
+SYSCALL2(SysReadDir, SYS_READDIR)      // int, char*
 SYSCALL2(_SysGetACL,SYS_GETACL)        // int, void*
 SYSCALL1(chdir, SYS_CHDIR)     // char*
 SYSCALL3(ioctl, SYS_IOCTL)     // int, int, void*
index 1062d7e..1cec11e 100644 (file)
@@ -16,71 +16,33 @@ extern uint32_t     __umodsi3(uint32_t Num, uint32_t Den);
 #define STR(x) _STR(x)
 #define EXP(sym)       {&sym, STR(sym)}
 
+#define SYSCALL0(name,num)     EXP(name),
+#define SYSCALL1(name,num)     EXP(name),
+#define SYSCALL2(name,num)     EXP(name),
+#define SYSCALL3(name,num)     EXP(name),
+#define SYSCALL4(name,num)     EXP(name),
+#define SYSCALL5(name,num)     EXP(name),
+#define SYSCALL6(name,num)     EXP(name),
+
 // === CONSTANTS ===
 const struct {
        void    *Value;
        char    *Name;
 }      caLocalExports[] = {
        EXP(gLoadedLibraries),
-       EXP(_exit),
-       EXP(clone),
-       EXP(kill),
-       EXP(yield),
-       EXP(sleep),
-       EXP(_SysWaitEvent),
-       EXP(waittid),
-       EXP(gettid),
-       EXP(getpid),
-       EXP(getuid),
-       EXP(getgid),
-
-       EXP(setuid),
-       EXP(setgid),
-
-       EXP(SysSetName),
-       //EXP(SysGetName),
-
-       EXP(_SysTimestamp),
-
-       //EXP(SysSetPri),
-
-       EXP(SysSendMessage),
-       EXP(SysGetMessage),
-
-       EXP(_SysSpawn),
-       EXP(execve),
-       EXP(SysLoadBin),
-       EXP(SysUnloadBin),
-
-       EXP(_SysSetFaultHandler),
+       EXP(_errno),
        
-       EXP(open),
-       EXP(reopen),
-       EXP(close),
-       EXP(read),
-       EXP(write),
-       EXP(seek),
-       EXP(tell),
-       EXP(finfo),
-       EXP(readdir),
-       EXP(_SysGetACL),
-       EXP(chdir),
-       EXP(ioctl),
-       EXP(_SysMount),
-       EXP(_SysSelect),
-
-       EXP(_SysOpenChild),
-       
-       EXP(_SysGetPhys),
-       EXP(_SysAllocate),
-       EXP(_SysDebug),
-
+       #define __ASSEMBLER__
+       #include "arch/syscalls.s.h"
+       #undef __ASSEMBLER__
+#if 0
        EXP(__umoddi3),
        EXP(__udivdi3),
        EXP(__divsi3),
        EXP(__modsi3),
        EXP(__udivsi3),
        EXP(__umodsi3)
+#endif
 };
 
 const int      ciNumLocalExports = sizeof(caLocalExports)/sizeof(caLocalExports[0]);
index 46a06c4..36086d0 100644 (file)
@@ -22,7 +22,7 @@ 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)
+#elif defined(ARCHDIR_is_armv7) | defined(ARCHDIR_is_armv6)
 typedef __int32_t      __intptr_t;
 typedef __uint32_t     __uintptr_t;
 #else
index 368f2cc..25a91be 100644 (file)
@@ -52,7 +52,8 @@ extern int    gettid(void);
 extern int     getpid(void);
 extern int     _SysSetFaultHandler(int (*Handler)(int));
 extern void    SysSetName(const char *Name);
-//extern int   SysGetName(const char *Name);
+extern int     SysGetName(char *NameDest);
+extern int     SysSetPri(int Priority);
 extern int64_t _SysTimestamp(void);
 
 // --- Permissions ---
@@ -72,8 +73,8 @@ 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     readdir(int fd, char *dest);
-extern int     _SysOpenChild(int fd, char *name, int flags);
+extern int     SysReadDir(int fd, char *dest);
+extern int     _SysOpenChild(int fd, const char *name, int flags);
 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);
index da37dea..0672102 100644 (file)
@@ -112,6 +112,7 @@ uint64_t __divmod64(uint64_t Num, uint64_t Den, uint64_t *Rem)
        return ret;
 }
 
+#if 0
 uint32_t __divmod32(uint32_t Num, uint32_t Den, uint32_t *Rem)
 {
        uint32_t        ret = 0, add = 1;
@@ -198,4 +199,5 @@ uint32_t __umodsi3(uint32_t Num, uint32_t Den)
        __divmod32(Num, Den, &ret);
        return ret;
 }
+#endif
 
diff --git a/Usermode/Libraries/libaxwin2.so_src/Makefile b/Usermode/Libraries/libaxwin2.so_src/Makefile
deleted file mode 100644 (file)
index 240646b..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# Acess 2 - AxWin GUI Library
-#
-
-include ../Makefile.cfg
-
-CPPFLAGS +=
-CFLAGS   += -Wall
-LDFLAGS  += -lc -soname libaxwin2.so
-
-OBJ = main.o messages.o
-BIN = libaxwin2.so
-
-include ../Makefile.tpl
diff --git a/Usermode/Libraries/libaxwin2.so_src/common.h b/Usermode/Libraries/libaxwin2.so_src/common.h
deleted file mode 100644 (file)
index 4e80c7f..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * AxWin Window Manager Interface Library
- * By John Hodge (thePowersGang)
- * This file is published under the terms of the Acess Licence. See the
- * file COPYING for details.
- * 
- * common.h - Internal Variable and Constant definitions
- */
-#ifndef _COMMON_H_
-#define _COMMON_H_
-
-// === Includes ===
-#include <acess/sys.h>
-#include <axwin2/axwin.h>
-#include <stdlib.h>
-
-// === Constants ===
-enum eAxWin_Modes
-{
-       AXWIN_MODE_IPC
-};
-
-// === Variables ===
-extern int     giAxWin_Mode;
-extern int     giAxWin_PID;
-
-#endif
diff --git a/Usermode/Libraries/libaxwin2.so_src/include_exp/axwin2/axwin.h b/Usermode/Libraries/libaxwin2.so_src/include_exp/axwin2/axwin.h
deleted file mode 100644 (file)
index 77db620..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * \file axwin2/axwin.h
- * \author John Hodge (thePowersGang)
- * \brief AxWin Core functions
- */
-#ifndef _AXWIN2_AXWIN_H
-#define _AXWIN2_AXWIN_H
-
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <axwin2/messages.h>
-
-// === Core Types ===
-typedef struct sAxWin_Element  tAxWin_Element;
-typedef int    tAxWin_MessageCallback(tAxWin_Message *);
-
-// === Functions ===
-extern int     AxWin_Register(const char *ApplicationName, tAxWin_MessageCallback *DefaultHandler);
-extern tAxWin_Element  *AxWin_CreateWindow(const char *TabTitle);
-extern tAxWin_Element  *AxWin_AddMenuItem(tAxWin_Element *Parent, const char *Label, int Message);
-
-extern int     AxWin_MessageLoop(void);
-extern int     AxWin_SendMessage(tAxWin_Message *Message);
-extern tAxWin_Message  *AxWin_WaitForMessage(void);
-extern int     AxWin_HandleMessage(tAxWin_Message *Message);
-
-// === Window Control ===
-
-extern tAxWin_Element  *AxWin_CreateElement(tAxWin_Element *Parent, int ElementType, int Flags, const char *DebugName);
-extern void    AxWin_SetFlags(tAxWin_Element *Element, int Flags);
-extern void    AxWin_SetText(tAxWin_Element *Element, const char *Text);
-extern void    AxWin_SetSize(tAxWin_Element *Element, int Size);
-extern void    AxWin_DeleteElement(tAxWin_Element *Element);
-
-// === CONSTANTS ===
-enum eElementFlags
-{
-       /**
-        * \brief Rendered
-        * 
-        * If set, the element will be ignored in calculating sizes and
-        * rendering.
-        */
-       ELEFLAG_NORENDER    = 0x001,
-       /**
-        * \brief Element visibility
-        * 
-        * If set, the element is not drawn (but still is used for size calculations)
-        */
-       ELEFLAG_INVISIBLE   = 0x002,
-       
-       /**
-        * \brief Position an element absulutely (ignored in size calcs)
-        */
-       ELEFLAG_ABSOLUTEPOS = 0x004,
-       
-       /**
-        * \brief Fixed size element
-        */
-       ELEFLAG_FIXEDSIZE   = 0x008,
-       
-       /**
-        * \brief Element "orientation"
-        * 
-        * Vertical means that the children of this element are stacked,
-        * otherwise they list horizontally
-        */
-       ELEFLAG_VERTICAL    = 0x010,//  ELEFLAG_HORIZONTAL  = 0x000,
-       /**
-        * \brief Action for text that overflows
-        */
-       ELEFLAG_WRAP        = 0x020,//  ELEFLAG_NOWRAP      = 0x000,
-       /**
-        * \brief Cross size action
-        * 
-        * If this flag is set, the element will only be as large (across
-        * its parent) as is needed to encase the contents of the element.
-        * Otherwise, the element will expand to fill all avaliable space.
-        */
-       ELEFLAG_NOEXPAND    = 0x040,
-       
-       /**
-        * \brief With (length) size action
-        * If this flag is set, the element will only be as large as
-        * is required along it's parent
-        */
-       ELEFLAG_NOSTRETCH   = 0x080,
-       
-       /**
-        * \brief Center alignment
-        */
-       ELEFLAG_ALIGN_CENTER= 0x100,
-       /**
-        * \brief Right/Bottom alignment
-        * 
-        * If set, the element aligns to the end of avaliable space (instead
-        * of the beginning)
-        */
-       ELEFLAG_ALIGN_END       = 0x200
-};
-
-#define ELEFLAG_WINDOW_MAXIMISED       0x10000
-
-/**
- */
-enum eElementTypes
-{
-       ELETYPE_NONE,
-
-       ELETYPE_WINDOW, //!< Window root element
-       
-       ELETYPE_BOX,    //!< Content box (invisible in itself)
-       ELETYPE_TABBAR, //!< Tab Bar
-       ELETYPE_TOOLBAR,        //!< Tool Bar
-       
-       ELETYPE_BUTTON, //!< Push Button
-       
-       ELETYPE_TEXT,   //!< Text
-       ELETYPE_IMAGE,  //!< Image
-       
-       ELETYPE_SPACER, //!< Visual Spacer (horizontal / vertical rule)
-       
-       MAX_ELETYPES    = 0x100
-};
-
-#endif
diff --git a/Usermode/Libraries/libaxwin2.so_src/include_exp/axwin2/messages.h b/Usermode/Libraries/libaxwin2.so_src/include_exp/axwin2/messages.h
deleted file mode 100644 (file)
index 61536f3..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * \file messages.h
- * \author John Hodge (thePowersGang)
- * \brief AxWin Control Messages and structures
- */
-#ifndef _AXWIN_MESSAGES_H
-#define _AXWIN_MESSAGES_H
-
-#include <stdint.h>
-
-typedef struct sAxWin_Message  tAxWin_Message;
-typedef struct sAxWin_RetMsg   tAxWin_RetMsg;
-
-// Higherarchy:
-// - HANDLE
-//  + ELEMENT
-//   > DIALOG
-//   > TAB
-
-/**
- * \brief Message IDs
- */
-enum eAxWin_Messages
-{
-       // Client->Server Requests
-       MSG_SREQ_PING,
-       // - Windows
-       MSG_SREQ_REGISTER,      // bool (char[] Name) - Registers this PID with the Window Manager
-       
-       MSG_SREQ_ADDWIN,        // ELEMENT (char[] Name) - Adds a tab to the window
-       
-       MSG_SREQ_SETICON,       // void (TAB Tab, char[] IconURI)       - Set the icon of a tab (or application)
-
-       MSG_SREQ_NEWDIALOG,     // DIALOG (TAB Parent, char[] Name)     - Creates a dialog
-       MSG_SREQ_DELDIALOG,     // void (DIALOG Dialog) - Closes a dialog
-       
-       MSG_SREQ_SETNAME,       // void (ELEMENT Element, char[] Name)
-       MSG_SREQ_GETNAME,       // char[] (ELEMENT Element)
-       
-       // - Builtin Elements
-       MSG_SREQ_INSERT,        // ELEMENT (ELEMENT Parent, eAxWin_Controls Type, u32 Flags)
-       MSG_SREQ_DELETE,        // void (ELEMENT Element)
-       
-       // - Drawing
-       //  All drawing functions take an ELEMENT as their first parameter.
-       //  This must be either a Window or Canvas control
-       MSG_SREQ_SETCOL,
-       MSG_SREQ_PSET,
-       MSG_SREQ_LINE,  MSG_SREQ_CURVE,
-       MSG_SREQ_RECT,  MSG_SREQ_FILLRECT,
-       MSG_SREQ_RIMG,  MSG_SREQ_SIMG,  // Register/Set Image
-       MSG_SREQ_SETFONT,       MSG_SREQ_PUTTEXT,
-
-       // - Callback Registration
-
-       // - WM Control
-       MSG_SREQ_SET_MAXIMIZE_AREA,     // void (uint16_t X, Y, W, H)
-       
-       // Server->Client Responses
-       MSG_SRSP_VERSION,
-       MSG_SRSP_RETURN,        // {int RequestID, void[] Return Value} - Returns a value from a server request
-       
-       NUM_MSG
-};
-
-// --- Server Requests (Requests from the client of the server)
-/**
- * \brief Server Request - Ping (Get Server Version)
- */
-struct sAxWin_SReq_Ping
-{
-};
-
-/**
- * \brief Server Request - New Window
- * \see eAxWin_Messages.MSG_SREQ_NEWWINDOW
- */
-struct sAxWin_SReq_NewWindow
-{
-       uint16_t        X, Y, W, H;
-       uint32_t        Flags;
-};
-
-struct sAxWin_SReq_NewElement
-{
-       uint16_t        Parent;
-       uint16_t        Type;
-       uint32_t        Flags;
-};
-
-
-// --- Server Responses
-/**
- * \brief Server Response - Pong
- * \see eAxWin_Messages.MSG_SRSP_PONG
- */
-struct sAxWin_SRsp_Version
-{
-       uint8_t Major;
-       uint8_t Minor;
-       uint16_t        Build;
-};
-
-
-// === Core Message Structure
-/**
- * \brief Overarching Message Structure
- * \note sizeof(tAxWin_Message) is never valid
- */
-struct sAxWin_Message
-{
-       uint32_t        Source;
-       uint16_t        ID;
-       uint16_t        Size;   // Size of data
-       char    Data[];
-};
-
-struct sAxWin_RetMsg
-{
-       uint16_t        ReqID;
-       uint16_t        Rsvd;
-       uint32_t        Value;
-};
-
-#endif
diff --git a/Usermode/Libraries/libaxwin2.so_src/main.c b/Usermode/Libraries/libaxwin2.so_src/main.c
deleted file mode 100644 (file)
index de08442..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * AxWin Window Manager Interface Library
- * By John Hodge (thePowersGang)
- * This file is published under the terms of the Acess Licence. See the
- * file COPYING for details.
- * 
- * main.c - Library Initialisation
- */
-#include "common.h"
-#include <string.h>
-
-// === GLOBALS ===
- int   giAxWin_Mode = 0;
- int   giAxWin_PID = 9;        // HACK!
-tAxWin_MessageCallback *gAxWin_DefaultCallback;
-
-// === CODE ===
-int SoMain()
-{
-       return 0;
-}
-
-tAxWin_Message *AxWin_int_SendAndWait(int RetID, tAxWin_Message *Message)
-{
-       tAxWin_Message  *msg;
-       tAxWin_RetMsg   *rmsg;
-
-       AxWin_SendMessage(Message);
-       
-       for(;;)
-       {
-               msg = AxWin_WaitForMessage();
-               
-               rmsg = (void*)msg->Data;
-               if(msg->ID == MSG_SRSP_RETURN && rmsg->ReqID == Message->ID )
-                       break;
-               
-               AxWin_HandleMessage(msg);
-               free(msg);
-       }
-       
-       return msg;
-}
-
-int AxWin_Register(const char *Name, tAxWin_MessageCallback *DefaultCallback)
-{
-       tAxWin_Message  req;
-       tAxWin_Message  *msg;
-        int    ret;
-        int    len = strlen(Name);
-       
-       req.ID = MSG_SREQ_REGISTER;
-       req.Size = 1 + (len+1)/4;
-       strcpy(req.Data, Name);
-       
-       msg = AxWin_int_SendAndWait(MSG_SRSP_RETURN, &req);
-       ret = ((tAxWin_RetMsg*)msg->Data)->Value;
-       free(msg);
-
-       gAxWin_DefaultCallback = DefaultCallback;
-       
-       return !!ret;
-}
-
-tAxWin_Element *AxWin_CreateWindow(const char *Title)
-{
-       tAxWin_Message  req;
-       tAxWin_Message  *msg;
-       tAxWin_Element  *ret;
-        int    len = strlen(Title);
-       
-       req.ID = MSG_SREQ_ADDWIN;
-       req.Size = 1 + (len+1)/4;
-       strcpy(req.Data, Title);
-       
-       msg = AxWin_int_SendAndWait(MSG_SRSP_RETURN, &req);
-       ret = (tAxWin_Element*) ((tAxWin_RetMsg*)msg->Data)->Value;
-       free(msg);
-       
-       return ret;
-}
-
-tAxWin_Element *AxWin_AddMenuItem(tAxWin_Element *Parent, const char *Label, int Message)
-{
-       return NULL;
-}
diff --git a/Usermode/Libraries/libaxwin2.so_src/messages.c b/Usermode/Libraries/libaxwin2.so_src/messages.c
deleted file mode 100644 (file)
index a314703..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * AxWin Window Manager Interface Library
- * By John Hodge (thePowersGang)
- * This file is published under the terms of the Acess Licence. See the
- * file COPYING for details.
- * 
- * messages.c - Message Handling
- */
-#include "common.h"
-
-// === PROTOTYPES ===
- int   AxWin_MessageLoop();
-tAxWin_Message *AxWin_WaitForMessage();
- int   AxWin_HandleMessage(tAxWin_Message *Message);
-
-// ===  ===
-
-// === CODE ===
-int AxWin_SendMessage(tAxWin_Message *Message)
-{
-       switch(giAxWin_Mode)
-       {
-       case AXWIN_MODE_IPC:
-               SysSendMessage(giAxWin_PID, Message->Size*4, Message);
-               break;
-       default:
-               break;
-       }
-       return 0;
-}
-
-/**
- * \brief Loop forever, checking and waiting for messages
- */
-int AxWin_MessageLoop()
-{
-       tAxWin_Message  *msg;
-        int    ret;
-       for(;;)
-       {
-               msg = AxWin_WaitForMessage();
-               ret = AxWin_HandleMessage(msg);
-               
-               if(ret < 0)     return 0;
-       }
-       return 0;
-}
-
-/**
- * \brief Wait for a message
- */
-tAxWin_Message *AxWin_WaitForMessage()
-{
-        int    length;
-       pid_t   src;
-       tAxWin_Message  *ret = NULL;
-       
-       switch( giAxWin_Mode )
-       {
-       case AXWIN_MODE_IPC:
-               while( (length = SysGetMessage(&src, NULL)) == 0 )      sleep();
-               ret = malloc(length);
-               SysGetMessage(NULL, ret);
-               break;
-       default:
-               break;
-       }
-       return ret;
-}
-
-/**
- * \brief Handles a recieved message
- */
-int AxWin_HandleMessage(tAxWin_Message *Message)
-{
-       switch(Message->ID)
-       {
-       default:        return 0;
-       }
-}
diff --git a/Usermode/Libraries/libaxwin2.so_src/windows.c b/Usermode/Libraries/libaxwin2.so_src/windows.c
deleted file mode 100644 (file)
index efb418b..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * AxWin Window Manager Interface Library
- * By John Hodge (thePowersGang)
- * This file is published under the terms of the Acess Licence. See the
- * file COPYING for details.
- * 
- * window.c - Window Control
- */
-#include "common.h"
-
-// === TYPES & STRUCTURES ===
-struct sAxWin_Window
-{
-       struct sAxWin_Window    *Next;
-       uint32_t        WmHandle;
-       tAxWin_MessageCallback  *Callback;
-};
-
-// === PROTOTYPES ===
-tAxWin_Window  *AxWin_CreateWindow(
-       int16_t X, int16_t Y, int16_t W, int16_t H,
-       uint32_t Flags, tAxWin_MessageCallback *Callback
-       );
-
-// === GLOBALS ===
-//mutex_t      glProcessWindows;
-tAxWin_Window  *gProcessWindows;
-
-// === CODE ===
-tAxWin_Window  *AxWin_CreateWindow(
-       int16_t X, int16_t Y,
-       int16_t W, int16_t H,
-       uint32_t Flags, tAxWin_MessageCallback *Callback)
-{
-       tAxWin_Message  req;
-       tAxWin_Message  *msg;
-       tAxWin_Window   *win;
-       
-       req.ID = MSG_SREQ_NEWWINDOW;
-       req.Size = 1 + sizeof(struct sAxWin_SReq_NewWindow)/4;
-       req.SReq_NewWindow.X = X;
-       req.SReq_NewWindow.Y = Y;
-       req.SReq_NewWindow.W = W;
-       req.SReq_NewWindow.H = H;
-       req.SReq_NewWindow.Flags = Flags;
-       
-       AxWin_SendMessage(&msg);
-       
-       for(;;)
-       {
-               msg = AxWin_WaitForMessage();
-               
-               if(msg.ID == MSG_SRSP_WINDOW)
-                       break;
-               
-               AxWin_HandleMessage(msg);
-               free(msg);
-       }
-       
-       win = malloc(sizeof(tAxWin_Window));
-       win->WmHandle = msg->SRsp_Window.Handle;
-       win->Callback = Callback;
-       
-       //mutex_acquire(glProcessWindows);
-       win->Next = gProcessWindows;
-       gProcessWindows = win;
-       //mutex_release(glProcessWindows);
-       
-       return 0;
-}
index fe116e9..8d91173 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef _AXWIN3_AXWIN_H_
 #define _AXWIN3_AXWIN_H_
 
+#include <stddef.h>    // size_t
+
 // === CONSTANTS ===
 
 // === TYPES ===
@@ -15,6 +17,7 @@ typedef struct sAxWin3_Window *tHWND;
 typedef unsigned int   tAxWin3_Colour; // TODO: Actual 32-bit
 
 typedef void   (*tAxWin3_MessageCallback)(int SourceTID, int Length);
+typedef void   (*tAxWin3_HotkeyCallback)(void);
 
 typedef int    (*tAxWin3_WindowMessageHandler)(tHWND Window, int Message, int Length, void *Data);
 
@@ -49,9 +52,11 @@ extern tHWND AxWin3_CreateWindow(
  * \param Window       Handle to a window to destroy
  */
 extern void    AxWin3_DestroyWindow(tHWND Window);
+extern int     AxWin3_RegisterAction(tHWND Window, const char *Action, tAxWin3_HotkeyCallback cb);
 
 // --- Core window management functions
 extern void    AxWin3_SendMessage(tHWND Window, tHWND Dest, int Message, int Length, void *Data);
+extern void    *AxWin3_WaitMessage(tHWND Window, int MessageID, size_t *Length);
 extern void    AxWin3_SetWindowTitle(tHWND Window, const char *Title);
 extern void    AxWin3_FocusWindow(tHWND Window);
 extern void    AxWin3_ShowWindow(tHWND Window, int bShow);
diff --git a/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/keysyms.h b/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/keysyms.h
new file mode 120000 (symlink)
index 0000000..93c2064
--- /dev/null
@@ -0,0 +1 @@
+../../../../../KernelLand/Kernel/include/keysyms.h
\ No newline at end of file
index 29a0225..9eca0b0 100644 (file)
@@ -46,6 +46,8 @@ enum eElementTypes
 {
        ELETYPE_NONE,
 
+       ELETYPE_SUBWIN,
+
        ELETYPE_BOX,    //!< Content box (invisible in itself)
        ELETYPE_TEXT,   //!< Text
        ELETYPE_IMAGE,  //!< Image
diff --git a/Usermode/Libraries/libc.so_src/arch/armv6.S b/Usermode/Libraries/libc.so_src/arch/armv6.S
new file mode 100644 (file)
index 0000000..be4887e
--- /dev/null
@@ -0,0 +1,24 @@
+@ 
+@ Acess2 C Library
+@ - By John Hodge (thePowersGang)
+@ 
+@ arch/armv6.S
+@ - ARMv6 specific code
+.globl setjmp
+setjmp:
+       @ RO: Buffer
+       stm r0, {r0-r14}
+       eor r0, r0
+       mov pc, lr
+
+.globl longjmp
+longjmp:
+       @ R0: Buffer
+       @ R1: Value
+       add r0, #8
+       ldm r0, {r2-r14}
+       mov r0, r1
+       tst r0, r0
+       addeq r0, #1
+       mov pc, lr      @ Will return to after setjmp
+
index 4fcc8be..d529f65 100644 (file)
@@ -7,6 +7,12 @@ heap.c - Heap Manager
 #include <string.h>\r
 #include "lib.h"\r
 \r
+#if 0\r
+# define DEBUGS(s...)  _SysDebug(s)\r
+#else\r
+# define DEBUGS(s...)  do{}while(0)\r
+#endif\r
+\r
 // === Constants ===\r
 #define MAGIC  0xACE55051      //AcessOS1\r
 #define MAGIC_FREE     (~MAGIC)\r
@@ -19,6 +25,7 @@ typedef unsigned int Uint;
 typedef struct {\r
        uint32_t        magic;\r
        size_t  size;\r
+       char    data[];\r
 }      heap_head;\r
 typedef struct {\r
        heap_head       *header;\r
@@ -38,6 +45,7 @@ EXPORT void   *sbrk(int increment);
 LOCAL void     *extendHeap(int bytes);\r
 static void    *FindHeapBase();\r
 LOCAL uint     brk(uintptr_t newpos);\r
+LOCAL void     Heap_Dump(void);\r
 \r
 //Code\r
 \r
@@ -53,7 +61,7 @@ EXPORT void *malloc(size_t bytes)
        size_t  closestMatch = 0;\r
        void    *bestMatchAddr = 0;\r
        heap_head       *curBlock;\r
-       \r
+\r
 //     _SysDebug("&_heap_start = %p, _heap_start = %p", &_heap_start, _heap_start);\r
        // Initialise Heap\r
        if(_heap_start == NULL)\r
@@ -84,6 +92,7 @@ EXPORT void *malloc(size_t bytes)
                else if(curBlock->magic != MAGIC)\r
                {\r
                        //Corrupt Heap\r
+                       Heap_Dump();\r
                        _SysDebug("malloc: Corrupt Heap\n");\r
                        return NULL;\r
                }\r
@@ -109,9 +118,12 @@ EXPORT void *malloc(size_t bytes)
                        return NULL;\r
                }\r
                curBlock->magic = MAGIC;\r
-               return (void*)((uintptr_t)curBlock + sizeof(heap_head));\r
+               DEBUGS("malloc(0x%x) = %p (extend) 0x%x", bytes, curBlock->data, bestSize);\r
+               return curBlock->data;\r
        }\r
        \r
+       heap_head *besthead = (void*)bestMatchAddr;\r
+       \r
        //Split Block?\r
        if(closestMatch - bestSize > BLOCK_SIZE) {\r
                heap_foot       *foot;\r
@@ -129,13 +141,15 @@ EXPORT void *malloc(size_t bytes)
                foot = (heap_foot*)(bestMatchAddr + closestMatch - sizeof(heap_foot));\r
                foot->header = curBlock;\r
                \r
-               ((heap_head*)bestMatchAddr)->magic = MAGIC;     //mark as used\r
-               return (void*)(bestMatchAddr + sizeof(heap_head));\r
+               besthead->magic = MAGIC;        //mark as used\r
+               DEBUGS("malloc(0x%x) = %p (split) 0x%x", bytes, besthead->data, bestSize);\r
+               return besthead->data;\r
        }\r
        \r
        //Don't Split the block\r
-       ((heap_head*)bestMatchAddr)->magic = MAGIC;\r
-       return (void*)(bestMatchAddr+sizeof(heap_head));\r
+       besthead->magic = MAGIC;\r
+       DEBUGS("malloc(0x%x) = %p (reuse) 0x%x", bytes, besthead->data, besthead->size);\r
+       return besthead->data;\r
 }\r
 \r
 /**\r
@@ -168,6 +182,7 @@ EXPORT void free(void *mem)
                return;\r
        \r
        head->magic = MAGIC_FREE;\r
+       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
@@ -429,3 +444,25 @@ LOCAL uint brk(uintptr_t newpos)
        \r
        return ret;     // Return old curpos\r
 }\r
+\r
+void Heap_Dump(void)\r
+{\r
+       heap_head *cur = _heap_start;\r
+       while( cur < (heap_head*)_heap_end )\r
+       {\r
+               switch( cur->magic )\r
+               {\r
+               case MAGIC:\r
+                       _SysDebug("Used block %p[0x%x] - ptr=%p", cur, cur->size, cur->data);\r
+                       break;\r
+               case MAGIC_FREE:\r
+                       _SysDebug("Free block %p[0x%x] - ptr=%p", cur, cur->size, cur->data);\r
+                       break;\r
+               default:\r
+                       _SysDebug("Block %p bad magic (0x%x)", cur, cur->magic);\r
+                       return ;\r
+               }\r
+               cur = (void*)( (char*)cur + cur->size );\r
+       }\r
+}\r
+\r
index 0e6d9e0..8acfb8b 100644 (file)
 \r
 /* --- StdLib --- */\r
 extern void    _exit(int code) __attribute__((noreturn));      /* NOTE: Also defined in acess/sys.h */\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 int     atoi(const char *ptr);\r
 extern void    exit(int status) __attribute__((noreturn));\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
+extern long int        labs(long int j);\r
+extern long long int   llabs(long long int j);\r
 \r
 /* --- Environment --- */\r
 extern char    *getenv(const char *name);\r
index ddd1234..c91106c 100644 (file)
@@ -2,12 +2,12 @@
  * AcessOS Basic C Library\r
  * stdlib.c\r
  */\r
-/**\r
- * \todo Move half of these to stdio\r
- */\r
 #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
@@ -71,70 +71,96 @@ EXPORT void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void
        }\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
+EXPORT long long strtoll(const char *str, char **end, int base)\r
 {\r
         int    neg = 0;\r
-        int    ret = 0;\r
-       \r
-       // NULL Check\r
-       if(!str)        return 0;\r
+       long long       ret = 0;\r
        \r
-       while(*str == ' ' || *str == '\t')      str++;\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\r
-       if(*str == '-') {\r
-               neg = 1;\r
+       // Check for negative (or positive) sign\r
+       if(*str == '-' || *str == '+') {\r
+               neg = (*str == '-');\r
                str++;\r
        }\r
        \r
-       if(*str == '0') {\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
-               if(*str == 'x') {\r
-                       str++;\r
-                       // Hex\r
-                       while( ('0' <= *str && *str <= '9')\r
-                               || ('A' <= *str && *str <= 'F' )\r
-                               || ('a' <= *str && *str <= 'f' )\r
-                               )\r
-                       {\r
-                               ret *= 16;\r
-                               if(*str <= '9') {\r
-                                       ret += *str - '0';\r
-                               } else if (*str <= 'F') {\r
-                                       ret += *str - 'A' + 10;\r
-                               } else {\r
-                                       ret += *str - 'a' + 10;\r
-                               }\r
-                               str++;\r
-                       }\r
-               } else {\r
-                       // Octal\r
-                       while( '0' <= *str && *str <= '7' )\r
-                       {\r
-                               ret *= 8;\r
-                               ret += *str - '0';\r
-                               str++;\r
-                       }\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
-               // Decimal\r
-               while( '0' <= *str && *str <= '9' )\r
-               {\r
-                       ret *= 10;\r
-                       ret += *str - '0';\r
-                       str++;\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
-       // Negate if needed\r
-       if(neg) ret = -ret;\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
 \r
index e9e1574..3cadee9 100644 (file)
@@ -273,10 +273,11 @@ 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)dest > (intptr_t)src && (intptr_t)dest < (intptr_t)src+count )
-               for(;count--;) dp[count] = sp[count];
+       if( (intptr_t)src < (intptr_t)dest && (intptr_t)dest < (intptr_t)src+count )
+               for(;count--;)
+                       dp[count] = sp[count];
        else
-               for(;count--;) *dp++ = *sp++;
+               memcpy(dest, src, count);
        return dest;
 }
 

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