--- /dev/null
+
+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
+
--- /dev/null
+
+ifeq ($(PLATFORM),default)
+ $(error Please select a platform)
+endif
+
+#MODULES += armv7/GIC
+MODULES += Filesystems/InitRD
--- /dev/null
+
+include $(ACESSDIR)/BuildConf/armv6/default.mk
+ARM_CPUNAME = arm1176jzf-s
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
ARM_CPUNAME = cortex-a9
MODULES += Display/Tegra2Vid
+MODULES += USB/Core USB/EHCI
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
# - 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)_
--- /dev/null
+#
+# 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
--- /dev/null
+/**
+ * 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)
+{
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+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 = .;
+}
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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
+}
--- /dev/null
+/*
+ * 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(;;);
+}
+
--- /dev/null
+/*
+ *
+ */
+#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
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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)
+{
+
+}
+
--- /dev/null
+
+#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
+
--- /dev/null
+/*
+ * Acess2
+ *
+ * ARM7 Time code
+ * arch/arm7/time.c
+ */
+#include <acess.h>
+
+// === GLOBALS ===
+tTime giTimestamp;
+
+// === CODE ===
+tTime now(void)
+{
+ return giTimestamp;
+}
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
// === 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;
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
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");
{
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");
}
MM_UnmapHWPages( (tVAddr)gaArch_BootModules[i].ArgString, 2 );
}
Log_Log("Arch", "Boot modules loaded");
- free( gaArch_BootModules );
+ if( gaArch_BootModules )
+ free( gaArch_BootModules );
}
--- /dev/null
+/*
+ * 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;
+}
+
*/
tPAddr MM_AllocPhys(void)
{
- // int a, b, c;
int indx = -1;
tPAddr ret;
Mutex_Acquire( &glPhysAlloc );
// Classful scan
- #if 1
{
int i;
int first, last;
// 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 );
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 )
{
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)
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)
--- /dev/null
+/*
+ * 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
+
OUTPUT_ARCH(i386:x86-64)
*/
OUTPUT_FORMAT(elf64-x86-64)
-ENTRY(start)
+lstart = start - _kernel_base;
+ENTRY(lstart)
SECTIONS {
. = 0x100000;
/*
- * 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);
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();
// 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",
return ;
}
+ MM_InitPhys( nPMemMapEnts, pmemmap ); // Set up physical memory manager
Log("gsBootCmdLine = '%s'", gsBootCmdLine);
*(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'D';
*/
#define DEBUG 0
#include <acess.h>
-#include <mboot.h>
+#include <archinit.h>
+#include <pmemmap.h>
#include <mm_virt.h>
#define TRACE_REF 0
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);
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
/**
* \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;
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;
// Set last (when the last free page is reached, this won't be
// updated anymore, hence will be correct)
giPhysRangeLast[ rangeID ] = base;
- }
-
+ }
+
LEAVE('-');
}
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);
{
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;
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;
}
if( PAddr >> 12 > giMaxPhysPage ) return ;
- if( MM_GetPhysAddr( (tVAddr) &gaiPageReferences[page] ) )
+ if( MM_GetPhysAddr( &gaiPageReferences[page] ) )
{
gaiPageReferences[ page ] --;
if( gaiPageReferences[ page ] == 0 )
if( PAddr > giMaxPhysPage ) return 0;
- if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[PAddr] ) ) {
+ if( MM_GetPhysAddr( &gaiPageReferences[PAddr] ) ) {
return gaiPageReferences[PAddr];
}
// 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 );
// if( !MM_GetRefCount(PAddr) ) return 1;
PAddr >>= 12;
- if( !MM_GetPhysAddr( (tVAddr)&gapPageNodes[PAddr] ) ) {
+ if( !MM_GetPhysAddr( &gapPageNodes[PAddr] ) ) {
*Node = NULL;
return 0;
}
#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 )
{
tPAddr phys;
- phys = MM_GetPhysAddr(VAddr);
+ phys = MM_GetPhysAddr( (void*)VAddr );
if(!phys) return ;
MM_Unmap(VAddr);
/**
* \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;
{
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;
// 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;
}
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);
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);
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 ---
// 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;
}
[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
{\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
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
px = (void*)dest;
}
}
+ if( x > 0 ) {
+ dest += FBInfo->Pitch;
+ }
}
else
{
ofs = Offset;
dest += ofs;
memcpy(dest, Buffer, Length);
+ dest += Length;
}
break;
default:
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);
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
--- /dev/null
+/*
+ * 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
+
*/
#ifndef _MBOOT_H
#define _MBOOT_H
+#include <acess.h>
#define MULTIBOOT_MAGIC 0x2BADB002
+#include <pmemmap.h>
+#include <bootmod.h>
+
// === TYPES ===
typedef struct {
Uint32 Flags;
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
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 ;
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;
}
}
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 ;
}
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 ) {
int MM_GetRefCount(tPAddr PAddr)
{
PAddr >>= 12;
- if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[PAddr] ) ) {
+ if( MM_GetPhysAddr( &gaiPageReferences[PAddr] ) ) {
return gaiPageReferences[PAddr];
}
ENTER("PPAddr", PAddr);
- if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[page] ) )
+ if( MM_GetPhysAddr( &gaiPageReferences[page] ) )
{
if( gaiPageReferences[page] > 0 )
gaiPageReferences[ page ] --;
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
}
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 );
if( !MM_GetRefCount(PAddr) ) return 1;
PAddr >>= 12;
- if( !MM_GetPhysAddr( (tVAddr)&gapPageNodes[PAddr] ) ) {
+ if( !MM_GetPhysAddr( &gapPageNodes[PAddr] ) ) {
*Node = NULL;
return 0;
}
// === 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 ===
/**
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;
}
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);
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;
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;
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;
}
*cwdptr = buf;
}
- Log("Updated CWD to '%s'", buf);
+ Log_Debug("VFS", "Updated CWD to '%s'", buf);
return 1;
}
}
count ++;
if( MaxAllowed && count >= MaxAllowed ) {
+ Mutex_Release(&List->Lock);
LEAVE('i', 1);
return 1;
}
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+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)
* - Driver core
*/
#define DEBUG 0
+#define DUMP_REGISTERS 1
#define VERSION ((0<<8)|10)
#include <acess.h>
#include <errno.h>
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)
// 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
);
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);
{
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);
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,
);
// 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;
}
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]);
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,
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
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] = {
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"
}
}
}
-#$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"
# 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"
#}
// === 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);
return 0;
}
-void RAMFS_Cleanup(void)
+int RAMFS_Cleanup(void)
{
-
+ return 0;
}
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)];
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
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;
// 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
// 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
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);
};
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;
tUSBInterface *Interface;
int EndpointIdx; // Interface endpoint index
int EndpointNum; // Device endpoint num
+ void *EndpointHandle;
int PollingPeriod; // In 1ms intervals
int MaxPacketSize; // In bytes
tUSBHost *Host;
int Address;
+ void *EndpointHandles[16];
+
struct sDescriptor_Device DevDesc;
int nInterfaces;
* usb_devinit.c
* - USB Device Initialisation
*/
-#define DEBUG 1
+#define DEBUG 0
#include <acess.h>
#include <vfs.h>
#include <drv_pci.h>
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)
}
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);
LOG(" .NumConfigurations = %i", desc.NumConfigurations);
LOG("}");
- #if DEBUG
+ #if DEBUG
if( desc.ManufacturerStr )
{
char *tmp = USB_int_GetDeviceString(dev, 0, desc.ManufacturerStr);
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;
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);
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;
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
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; }
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);
}
{
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('-');
{
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);
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('-');
#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);
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;
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);
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
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;
}
#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);
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
);
--- /dev/null
+#
+# Acess2 EHCI Driver
+#
+
+OBJ = ehci.o
+CPPFLAGS = -I../Core/include
+NAME = EHCI
+
+-include ../Makefile.tpl
--- /dev/null
+/*
+ * 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)
+{
+}
+
#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
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
// --- 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);
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);
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;
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;
// === 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;
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)
*/
Uint32 Next;
-
/**
* \brief Next Entry in list
*
tUHCI_TD LocalTDPool[ (4096-(128+2)*sizeof(tUHCI_QH)) / sizeof(tUHCI_TD) ];
} *TDQHPage;
+
+ struct {
+ tUHCI_EndpointInfo EndpointInfo[16];
+ } *DevInfo[256];
};
// === ENUMERATIONS ===
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))
DRIVERS :=
MODULES :=
+MODULES += Filesystems/RAMDisk
MODULES += Filesystems/Ext2
MODULES += Filesystems/FAT
MODULES += Filesystems/NTFS
--- /dev/null
+=== 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)
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"
-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
;;
# /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
> 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!
}
static inline void SHORTREL(tShortSpinlock *m) { *m = 0; }
+static inline intptr_t MM_GetPhysAddr(void *Ptr) { return 1; }
+
#endif
\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
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
@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
+++ /dev/null
-
-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
+++ /dev/null
-=== 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)
+++ /dev/null
-# Project: Acess GUI Default Shell
-
--include ../../Makefile.cfg
-
-CPPFLAGS +=
-LDFLAGS += -laxwin2
-
-DIR = Apps/AxWin/1.0
-BIN = Shell
-OBJ = main.o
-
--include ../../Makefile.tpl
+++ /dev/null
-/*
- * 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;
- }
-}
+++ /dev/null
-# 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 "" >> $@
+++ /dev/null
-/*
- * 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");
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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;
- }
-}
+++ /dev/null
-/*
- * 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
-};
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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);
- }
-}
+++ /dev/null
-/*
- * 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();
-}
+++ /dev/null
-/*
- * 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;
-}
-
+++ /dev/null
-/*
- * 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 );
-}
+++ /dev/null
-/*
- * 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();
-}
+++ /dev/null
-/*
- */
-#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
-
+++ /dev/null
-/*
- * 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;
- }
-}
+++ /dev/null
-/*
- * 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;
-}
-
-
-
-
+++ /dev/null
-/*
- * 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 ;
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-Applications can have 0-* windows
-Windows can have 1-* tabs
-Each window has a menu based on a template from the application
void create_sidebar(void);
void create_mainmenu(void);
void create_run_dialog(void);
+void mainmenu_run_dialog(void *unused);
// === GLOBALS ===
tHWND gSidebar;
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();
void mainmenu_run_dialog(void *unused)
{
AxWin3_ShowWindow(gRunDialog, 1);
+ AxWin3_FocusWindow(gRunDialog);
}
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);
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
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);
#include <stdio.h>
#include <wm.h>
#include <wm_internals.h>
+#include <wm_hotkeys.h>
#define AXWIN_PORT 4101
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;
}
#include <acess/sys.h>
#include <stdlib.h>
#include <stdio.h>
+#include <axwin3/keysyms.h>
// === IMPORTS ===
extern void Video_Setup(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);
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 )
// }
}
+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;
case MSG_WIDGET_SETTEXT:
Widget_SetText(info, Len, Data);
return 0;
+ case MSG_WIDGET_GETTEXT:
+ return Widget_GetText(info, Len, Data);
//
default:
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)
{
_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 ;
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
void WM_Hotkey_FireEvent(const char *Target)
{
+// _SysDebug("WM_Hotkey_FireEvent: (%s)", Target);
// - Internal events (Alt-Tab, Close, Maximize, etc...)
// TODO: Internal event handling
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));
}
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
}
}
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;
uint8_t bSetDims;
};
+struct sIPCMsg_RegAction
+{
+ uint16_t Index;
+ char Action[];
+};
+
struct sIPCMsg_GetDisplayDims
{
uint16_t DisplayID;
#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>
{
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;
}
#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;
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)
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);
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;
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;
+}
+
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 ;
dp = open(IPSTACK_ROOT, OPENFLAG_READ);
- while( readdir(dp, filename) )
+ while( SysReadDir(dp, filename) )
{
if(filename[0] == '.') continue;
DumpInterface(filename);
printf("Type\tNetwork \tGateway \tMetric\tIFace\n");
- while( readdir(dp, filename) )
+ while( SysReadDir(dp, filename) )
{
if(filename[0] == '.') continue;
DumpRoute(filename);
}
// Traverse Directory
- while( (tmp = readdir(fd, buf)) > 0 )
+ while( (tmp = SysReadDir(fd, buf)) > 0 )
{
// Error check
if(tmp < 0) {
--- /dev/null
+# Project: PCI Device Listing
+
+-include ../Makefile.cfg
+
+LDFLAGS +=
+
+OBJ = main.o
+BIN = lspci
+
+-include ../Makefile.tpl
--- /dev/null
+/*
+ * 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);
+}
+
$(_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
--- /dev/null
+/* 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_*) }
+}
+
+
# 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)
#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;}
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){}
--- /dev/null
+//
+// 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 .
+
--- /dev/null
+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 = .;
+}
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*
#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]);
#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
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 ---
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);
return ret;
}
+#if 0
uint32_t __divmod32(uint32_t Num, uint32_t Den, uint32_t *Rem)
{
uint32_t ret = 0, add = 1;
__divmod32(Num, Den, &ret);
return ret;
}
+#endif
+++ /dev/null
-# 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
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/**
- * \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
+++ /dev/null
-/**
- * \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
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
- }
-}
+++ /dev/null
-/*
- * 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;
-}
#ifndef _AXWIN3_AXWIN_H_
#define _AXWIN3_AXWIN_H_
+#include <stddef.h> // size_t
+
// === CONSTANTS ===
// === TYPES ===
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);
* \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);
--- /dev/null
+../../../../../KernelLand/Kernel/include/keysyms.h
\ No newline at end of file
{
ELETYPE_NONE,
+ ELETYPE_SUBWIN,
+
ELETYPE_BOX, //!< Content box (invisible in itself)
ELETYPE_TEXT, //!< Text
ELETYPE_IMAGE, //!< Image
--- /dev/null
+@
+@ 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
+
#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
typedef struct {\r
uint32_t magic;\r
size_t size;\r
+ char data[];\r
} heap_head;\r
typedef struct {\r
heap_head *header;\r
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
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
else if(curBlock->magic != MAGIC)\r
{\r
//Corrupt Heap\r
+ Heap_Dump();\r
_SysDebug("malloc: Corrupt Heap\n");\r
return NULL;\r
}\r
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
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
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
\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
\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
* 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
}\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
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;
}