Merge branch 'master' of git://localhost/acess2
authorJohn Hodge <[email protected]>
Tue, 22 Jan 2013 06:27:11 +0000 (14:27 +0800)
committerJohn Hodge <[email protected]>
Tue, 22 Jan 2013 06:27:11 +0000 (14:27 +0800)
99 files changed:
.travis.yml [new file with mode: 0644]
AcessNative/.gitignore
AcessNative/acesskernel_src/helpers.c
AcessNative/acesskernel_src/nativefs.c
AcessNative/acesskernel_src/syscalls.c
AcessNative/ld-acess_src/binary.c
AcessNative/ld-acess_src/common.h
AcessNative/ld-acess_src/elf_load.c
AcessNative/ld-acess_src/exports.c
AcessNative/ld-acess_src/exports.h
AcessNative/ld-acess_src/main.c
AcessNative/ld-acess_src/syscalls.c
AcessNative/syscalls.h
AcessNative/syscalls_list.h [new file with mode: 0644]
BuildConf/armv7/default.mk
BuildConf/armv7/realview_pb.mk
BuildConf/armv7/tegra2.mk
KernelLand/Kernel/arch/armv7/Makefile
KernelLand/Kernel/arch/armv7/main.c
KernelLand/Kernel/arch/armv7/mm_virt.c
KernelLand/Kernel/arch/armv7/platform_realview_pb.c [new file with mode: 0644]
KernelLand/Kernel/arch/armv7/platform_tegra2.c [new file with mode: 0644]
KernelLand/Kernel/arch/armv7/platform_tegra2.h [new file with mode: 0644]
KernelLand/Kernel/arch/armv7/vpci_tegra2.c
KernelLand/Kernel/arch/x86/acpica.c
KernelLand/Kernel/arch/x86/main.c
KernelLand/Kernel/arch/x86/vm8086.c
KernelLand/Kernel/arch/x86_64/main.c
KernelLand/Kernel/arch/x86_64/proc.c
KernelLand/Kernel/debug.c
KernelLand/Kernel/drv/fifo.c
KernelLand/Kernel/drv/pci.c
KernelLand/Kernel/drv/vpci.c
KernelLand/Kernel/drv/vterm.c
KernelLand/Kernel/drv/vterm.h
KernelLand/Kernel/drv/vterm_termbuf.c
KernelLand/Kernel/drv/vterm_vt100.c
KernelLand/Kernel/include/acess.h
KernelLand/Kernel/include/events.h
KernelLand/Kernel/include/init.h
KernelLand/Kernel/include/threads_int.h
KernelLand/Kernel/libc.c
KernelLand/Kernel/messages.c
KernelLand/Kernel/syscalls.c
KernelLand/Kernel/system.c
KernelLand/Kernel/threads.c
KernelLand/Kernel/vfs/handle.c
KernelLand/Kernel/vfs/select.c
KernelLand/Modules/Display/BochsGA/bochsvbe.c
KernelLand/Modules/Display/RPi/main.c [new file with mode: 0644]
KernelLand/Modules/Display/Tegra2Vid/main.c
KernelLand/Modules/Display/Tegra2Vid/tegra2.h
KernelLand/Modules/Filesystems/InitRD/Makefile
KernelLand/Modules/Filesystems/InitRD/files.lst
KernelLand/Modules/IPStack/udp.c
KernelLand/Modules/Network/VIARhineII/rhine2.c
KernelLand/Modules/Storage/FDDv2/main.c
KernelLand/Modules/USB/EHCI/ehci.c
KernelLand/Modules/armv7/GIC/gic.c
Makefile
Notes/3D.txt [new file with mode: 0644]
Tools/GCCProxy/gccproxy.sh
Usermode/Applications/axwin3_src/Interface/main.c
Usermode/Applications/axwin3_src/WM/Makefile
Usermode/Applications/axwin3_src/WM/include/utf8.h [deleted file]
Usermode/Applications/axwin3_src/WM/ipc.c
Usermode/Applications/axwin3_src/WM/main.c
Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c
Usermode/Applications/axwin3_src/WM/renderers/richtext.c
Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c
Usermode/Applications/axwin3_src/WM/utf-8.c [deleted file]
Usermode/Applications/axwin3_src/WM/video.c
Usermode/Applications/axwin3_src/WM/wm.c
Usermode/Applications/axwin3_src/WM/wm_render_text.c
Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c
Usermode/Applications/dhcpclient_src/main.c
Usermode/Applications/gui_shell_src/Makefile
Usermode/Applications/gui_shell_src/display.c [new file with mode: 0644]
Usermode/Applications/gui_shell_src/include/display.h
Usermode/Applications/gui_shell_src/main.c
Usermode/Applications/gui_shell_src/vt100.c
Usermode/Applications/init_src/common.h [new file with mode: 0644]
Usermode/Applications/init_src/main.c
Usermode/Applications/irc_src/main.c
Usermode/Applications/telnetd_src/main.c
Usermode/Filesystem/Conf/inittab [new file with mode: 0644]
Usermode/Filesystem/Makefile
Usermode/Libraries/ld-acess.so_src/Makefile
Usermode/Libraries/ld-acess.so_src/arch/armv7.S.h
Usermode/Libraries/ld-acess.so_src/elf.c
Usermode/Libraries/ld-acess.so_src/include_exp/acess/fd_set.h
Usermode/Libraries/ld-acess.so_src/include_exp/acess/sys.h
Usermode/Libraries/libc.so_src/scanf.c
Usermode/Libraries/libc.so_src/stdio.c
Usermode/Libraries/libposix.so_src/include_exp/sys/types.h
Usermode/Libraries/libunicode.so_src/Makefile [new file with mode: 0644]
Usermode/Libraries/libunicode.so_src/include_exp/unicode.h [new file with mode: 0644]
Usermode/Libraries/libunicode.so_src/main.c [new file with mode: 0644]
Usermode/Libraries/libunicode.so_src/utf-8.c [new file with mode: 0644]

diff --git a/.travis.yml b/.travis.yml
new file mode 100644 (file)
index 0000000..6154547
--- /dev/null
@@ -0,0 +1,9 @@
+language: c
+compiler: clang
+before_install:
+ - sudo apt-get update -qq
+ - sudo apt-get install -qq nasm
+env:
+ - ARCH=host HOST_ARCH=x86 USE_ACPICA=0
+ - ARCH=host HOST_ARCH=x86_64 CC="$CC -m64"
+script: "make all"
index 82eea12..13714aa 100644 (file)
@@ -2,3 +2,4 @@ ld-acess
 ld-acess.exe
 AcessKernel
 AcessKernel.exe
+Makefile.BuildNum
index 51b9653..6396d16 100644 (file)
@@ -144,7 +144,6 @@ int strpos(const char *str, char ch)
 {
        const char *retptr = strchr(str, ch);
        int rv = retptr ? retptr - str : -1;
-       fprintf(stderr, "strpos: str = %p'%s', retptr = %p, rv = %i\n", str, str, retptr, rv);
        return rv;
 }
 
@@ -152,7 +151,6 @@ int CheckString(const char *string)
 {
        if( (intptr_t)string < 0x1000 )
                return 0;
-       strlen(string);
        return 1;
 }
 
@@ -163,3 +161,38 @@ int CheckMem(const void *buf, size_t len)
        return 1;
 }
 
+void itoa(char *buf, Uint64 num, int base, int minLength, char pad)
+{
+       static const char cUCDIGITS[] = "0123456789ABCDEF";
+       char    tmpBuf[64+1];
+        int    pos=0, i;
+       Uint64  rem;
+
+       // Sanity check
+       if(!buf)        return;
+       
+       // Sanity Check
+       if(base > 16 || base < 2) {
+               buf[0] = 0;
+               return;
+       }
+       
+       // Convert 
+       while(num > base-1) {
+               rem = num % base;
+               num = num / base;       // Shift `num` and get remainder
+               tmpBuf[pos] = cUCDIGITS[ rem ];
+               pos++;
+       }
+       tmpBuf[pos++] = cUCDIGITS[ num ];               // Last digit of `num`
+       
+       // Put in reverse
+       i = 0;
+       minLength -= pos;
+       while(minLength-- > 0)
+               buf[i++] = pad;
+       while(pos-- > 0)
+               buf[i++] = tmpBuf[pos]; // Reverse the order of characters
+       buf[i] = 0;
+}
+
index af25e3c..cca9e7d 100644 (file)
@@ -205,8 +205,9 @@ size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void *
                LEAVE('i', 0);\r
                return 0;\r
        }\r
-       LEAVE('-');\r
-       return fread( Buffer, 1, Length, (FILE *)(tVAddr)Node->Inode );\r
+       size_t ret = fread( Buffer, 1, Length, (FILE *)(tVAddr)Node->Inode );\r
+       LEAVE('x', ret);\r
+       return ret;\r
 }\r
 \r
 size_t NativeFS_Write(tVFS_Node *Node, _acess_off_t Offset, size_t Length, const void *Buffer)\r
index 827d611..4458846 100644 (file)
@@ -30,7 +30,7 @@ typedef int   (*tSyscallHandler)(Uint *Errno, const char *Format, void *Args, int
        a3 = *(_t3*)Args;Args+=sizeof(_t3);\
        a4 = *(_t4*)Args;Args+=sizeof(_t4);\
        a5 = *(_t5*)Args;Args+=sizeof(_t5);\
-       LOG("SYSCALL5 '%s' %p %p %p %p %p %p", Fmt, (intptr_t)a0,(intptr_t)a1,(intptr_t)a2,(intptr_t)a3,(intptr_t)a4,(intptr_t)a5);\
+       LOG("SYSCALL6 '%s' %p %p %p %p %p %p", Fmt, (intptr_t)a0,(intptr_t)a1,(intptr_t)a2,(intptr_t)a3,(intptr_t)a4,(intptr_t)a5);\
        _call\
 }
 #define SYSCALL5(_name, _fmtstr, _t0, _t1, _t2, _t3, _t4, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
@@ -281,12 +281,15 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
         int    argListLen = 0;
         int    i, retVal;
        tRequestHeader  *ret;
-        int    retValueCount = 1;
-        int    retDataLen = sizeof(Uint64);
+        int    retValueCount;
+        int    retDataLen;
        void    *returnData[Request->NParams];
         int    argSizes[Request->NParams];
        Uint    ret_errno = 0;
        
+       // Clear errno (Acess verson) at the start of the request
+       errno = 0;
+       
        // Sanity check
        if( Request->CallID >= ciNumSyscalls ) {
                Log_Notice("Syscalls", "Unknown syscall number %i", Request->CallID);
@@ -297,7 +300,11 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                Log_Notice("Syscalls", "Unimplemented syscall %i", Request->CallID);
                return NULL;
        }
-       
+
+       // Init return count/size
+       retValueCount = 2;
+       retDataLen = sizeof(Uint64) + sizeof(Uint32);   
+
        // Get size of argument list
        for( i = 0; i < Request->NParams; i ++ )
        {
@@ -318,12 +325,19 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                case ARG_TYPE_DATA:
                        formatString[i] = 'd';
                        argListLen += sizeof(void*);
+                       // Prepare the return values
+                       if( Request->Params[i].Flags & ARG_FLAG_RETURN )
+                       {
+                               retDataLen += Request->Params[i].Length;
+                               retValueCount ++;
+                       }
                        break;
                case ARG_TYPE_STRING:
                        formatString[i] = 's';
                        argListLen += sizeof(char*);
                        break;
                default:
+                       Log_Error("Syscalls", "Unknown param type %i", Request->Params[i].Type);
                        return NULL;    // ERROR!
                }
        }
@@ -364,13 +378,6 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                        // Data gets special handling, because only it can be returned to the user
                        // (ARG_TYPE_DATA is a pointer)
                        case ARG_TYPE_DATA:
-                               // Prepare the return values
-                               if( Request->Params[i].Flags & ARG_FLAG_RETURN )
-                               {
-                                       retDataLen += Request->Params[i].Length;
-                                       retValueCount ++;
-                               }
-                               
                                // Check for non-resident data
                                if( Request->Params[i].Length == 0 )
                                {
@@ -406,9 +413,9 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
        
        // ---------- Return
        
-       if( ret_errno == 0 ) {
-               perror("Syscall?");
+       if( ret_errno == 0 && errno != 0 ) {
                ret_errno = errno;
+               LOG("errno = %i", errno);
        }
        
        // Allocate the return
@@ -427,9 +434,18 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
        *(Uint64*)inData = retVal;
        inData += sizeof(Uint64);
        
+       // Static Uint32 errno value
+       ret->Params[1].Type = ARG_TYPE_INT32;
+       ret->Params[1].Flags = 0;
+       ret->Params[1].Length = sizeof(Uint32);
+       *(Uint32*)inData = ret_errno;
+       inData += sizeof(Uint32);
+
+       LOG("Ret: %llx, errno=%i", retVal, ret_errno);  
+
        //Log_Debug("Syscalls", "Return 0x%llx", retVal);
        
-       retValueCount = 1;
+       retValueCount = 2;
        for( i = 0; i < Request->NParams; i ++ )
        {
                if( Request->Params[i].Type != ARG_TYPE_DATA )  continue;
@@ -450,9 +466,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                retValueCount ++;
        }
        
-       *ReturnLength = sizeof(tRequestHeader)
-               + retValueCount * sizeof(tRequestValue)
-               + retDataLen;
+       *ReturnLength = ret->MessageLength;
        
        return ret;
 }
index d04ac6d..59be829 100644 (file)
@@ -65,9 +65,9 @@ char *Binary_LocateLibrary(const char *Name)
                strcat(tmp, "/");
                strcat(tmp, Name);
                
-               fd = acess_open(tmp, 4);        // OPENFLAG_EXEC
+               fd = acess__SysOpen(tmp, 4);    // OPENFLAG_EXEC
                if(fd != -1) {
-                       acess_close(fd);
+                       acess__SysClose(fd);
                        return strdup(tmp);
                }
        }               
@@ -84,9 +84,9 @@ char *Binary_LocateLibrary(const char *Name)
                printf("Binary_LocateLibrary: tmp = '%s'\n", tmp);
                #endif
 
-               fd = acess_open(tmp, 4);        // OPENFLAG_EXEC
+               fd = acess__SysOpen(tmp, 4);    // OPENFLAG_EXEC
                if(fd != -1) {
-                       acess_close(fd);
+                       acess__SysClose(fd);
                        return strdup(tmp);
                }
        }               
@@ -156,22 +156,22 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
                }
        }
 
-       fd = acess_open(Filename, 2|1); // Execute and Read
+       fd = acess__SysOpen(Filename, 2|1);     // Execute and Read
        if( fd == -1 ) {
                // TODO: Handle libary directories
                perror("Opening binary");
                return NULL;
        }
 
-       acess_read(fd, &dword, 4);
-       acess_seek(fd, 0, ACESS_SEEK_SET);
+       acess__SysRead(fd, &dword, 4);
+       acess__SysSeek(fd, 0, ACESS_SEEK_SET);
        
        if( memcmp(&dword, "\x7F""ELF", 4) == 0 ) {
                fmt = &gElf_FormatDef;
        }
        else {
                fprintf(stderr, "Unknown executable format (0x%08x)\n", dword);
-               acess_close(fd);
+               acess__SysClose(fd);
                return NULL;
        }
        
@@ -179,7 +179,7 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
        printf("fmt->Load(0x%x)...\n", fd);
        #endif
        ret = fmt->Load(fd);
-       acess_close(fd);
+       acess__SysClose(fd);
        #if DEBUG
        printf("fmt->Load(0x%x): %p\n", fd, ret);
        #endif
index 376faa5..9f67e9c 100644 (file)
@@ -36,6 +36,7 @@ static inline int _SysSetMemFlags(uintptr_t Addr, unsigned int flags, unsigned i
        return 0;
 }
 
+
 extern int     AllocateMemory(uintptr_t VirtAddr, size_t ByteCount);
 extern uintptr_t       FindFreeRange(size_t ByteCount, int MaxBits);
 
index d661622..19a8c13 100644 (file)
@@ -42,7 +42,7 @@ void *Elf_Load(int FD)
        Elf64_Ehdr      hdr;\r
        \r
        // Read ELF Header\r
-       acess_read(FD, &hdr, sizeof(hdr));\r
+       acess__SysRead(FD, &hdr, sizeof(hdr));\r
        \r
        // Check the file type\r
        if(hdr.e_ident[0] != 0x7F || hdr.e_ident[1] != 'E' || hdr.e_ident[2] != 'L' || hdr.e_ident[3] != 'F') {\r
@@ -89,8 +89,8 @@ void *Elf32Load(int FD, Elf32_Ehdr *hdr)
                return NULL;\r
        }\r
        LOG("hdr.phoff = 0x%08x\n", hdr->phoff);\r
-       acess_seek(FD, hdr->phoff, ACESS_SEEK_SET);\r
-       acess_read(FD, phtab, sizeof(Elf32_Phdr) * hdr->phentcount);\r
+       acess__SysSeek(FD, hdr->phoff, ACESS_SEEK_SET);\r
+       acess__SysRead(FD, phtab, sizeof(Elf32_Phdr) * hdr->phentcount);\r
        \r
        // Count Pages\r
        iPageCount = 0;\r
@@ -146,8 +146,8 @@ void *Elf32Load(int FD, Elf32_Ehdr *hdr)
                        char *tmp;\r
                        //if(ret->Interpreter)  continue;\r
                        tmp = malloc(phtab[i].FileSize);\r
-                       acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET);\r
-                       acess_read(FD, tmp, phtab[i].FileSize);\r
+                       acess__SysSeek(FD, phtab[i].Offset, ACESS_SEEK_SET);\r
+                       acess__SysRead(FD, tmp, phtab[i].FileSize);\r
                        //ret->Interpreter = Binary_RegInterp(tmp);\r
                        LOG("Interpreter '%s'\n", tmp);\r
                        free(tmp);\r
@@ -168,8 +168,8 @@ void *Elf32Load(int FD, Elf32_Ehdr *hdr)
                        return NULL;\r
                }\r
                \r
-               acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET);\r
-               acess_read(FD, PTRMK(void, addr), phtab[i].FileSize);\r
+               acess__SysSeek(FD, phtab[i].Offset, ACESS_SEEK_SET);\r
+               acess__SysRead(FD, PTRMK(void, addr), phtab[i].FileSize);\r
                memset( PTRMK(char, addr) + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize );\r
        }\r
        \r
@@ -211,8 +211,8 @@ void *Elf64Load(int FD, Elf64_Ehdr *hdr)
                return NULL;\r
        }\r
        LOG("hdr.phoff = 0x%08llx\n", (long long)hdr->e_phoff);\r
-       acess_seek(FD, hdr->e_phoff, ACESS_SEEK_SET);\r
-       acess_read(FD, phtab, sizeof(Elf64_Phdr) * hdr->e_phnum);\r
+       acess__SysSeek(FD, hdr->e_phoff, ACESS_SEEK_SET);\r
+       acess__SysRead(FD, phtab, sizeof(Elf64_Phdr) * hdr->e_phnum);\r
        \r
        // Count Pages\r
        iPageCount = 0;\r
@@ -270,8 +270,8 @@ void *Elf64Load(int FD, Elf64_Ehdr *hdr)
                        //if(ret->Interpreter)  continue;\r
                        tmp = malloc(phtab[i].p_filesz+1);\r
                        tmp[ phtab[i].p_filesz ] = 0;\r
-                       acess_seek(FD, phtab[i].p_offset, ACESS_SEEK_SET);\r
-                       acess_read(FD, tmp, phtab[i].p_filesz);\r
+                       acess__SysSeek(FD, phtab[i].p_offset, ACESS_SEEK_SET);\r
+                       acess__SysRead(FD, tmp, phtab[i].p_filesz);\r
                        //ret->Interpreter = Binary_RegInterp(tmp);\r
                        LOG("Interpreter '%s'\n", tmp);\r
                        free(tmp);\r
@@ -295,8 +295,8 @@ void *Elf64Load(int FD, Elf64_Ehdr *hdr)
                        return NULL;\r
                }\r
                \r
-               acess_seek(FD, phtab[i].p_offset, ACESS_SEEK_SET);\r
-               acess_read(FD, PTRMK(void, addr), phtab[i].p_filesz);\r
+               acess__SysSeek(FD, phtab[i].p_offset, ACESS_SEEK_SET);\r
+               acess__SysRead(FD, PTRMK(void, addr), phtab[i].p_filesz);\r
                memset( PTRMK(char, addr) + phtab[i].p_filesz, 0, phtab[i].p_memsz - phtab[i].p_filesz );\r
        }\r
        \r
index d7e4922..dcfc526 100644 (file)
@@ -42,12 +42,12 @@ char        *gsExecutablePath = "./ld-acess";
 
 // === CODE ===
 // --- VFS Calls
-int acess_chdir(const char *Path)
+int acess__SysChdir(const char *Path)
 {
        return _Syscall(SYS_CHDIR, ">s", Path);
 }
 
-int acess_open(const char *Path, int Flags)
+int acess__SysOpen(const char *Path, int Flags)
 {
        if( strncmp(Path, "$$$$", 4) == 0 )
        {
@@ -57,7 +57,8 @@ int acess_open(const char *Path, int Flags)
        return _Syscall(SYS_OPEN, ">s >i", Path, Flags);
 }
 
-void acess_close(int FD) {
+void acess__SysClose(int FD)
+{
        if(FD & NATIVE_FILE_MASK) {
                return native_close(FD & (NATIVE_FILE_MASK-1));
        }
@@ -65,12 +66,12 @@ void acess_close(int FD) {
        _Syscall(SYS_CLOSE, ">i", FD);
 }
 
-int acess_reopen(int FD, const char *Path, int Flags) {
+int acess__SysReopen(int FD, const char *Path, int Flags) {
        DEBUG("reopen(0x%x, \"%s\", 0x%x)", FD, Path, Flags);
        return _Syscall(SYS_REOPEN, ">i >s >i", FD, Path, Flags);
 }
 
-size_t acess_read(int FD, void *Dest, size_t Bytes) {
+size_t acess__SysRead(int FD, void *Dest, size_t Bytes) {
        if(FD & NATIVE_FILE_MASK)
                return native_read(FD & (NATIVE_FILE_MASK-1), Dest, Bytes);
 //     if( FD > 2 )
@@ -78,7 +79,7 @@ size_t acess_read(int FD, void *Dest, size_t Bytes) {
        return _Syscall(SYS_READ, ">i >i <d", FD, Bytes, Bytes, Dest);
 }
 
-size_t acess_write(int FD, const void *Src, size_t Bytes) {
+size_t acess__SysWrite(int FD, const void *Src, size_t Bytes) {
        if(FD & NATIVE_FILE_MASK)
                return native_write(FD & (NATIVE_FILE_MASK-1), Src, Bytes);
 //     if( FD > 2 )
@@ -86,7 +87,8 @@ size_t acess_write(int FD, const void *Src, size_t Bytes) {
        return _Syscall(SYS_WRITE, ">i >i >d", FD, Bytes, Bytes, Src);
 }
 
-int acess_seek(int FD, int64_t Ofs, int Dir) {
+int acess__SysSeek(int FD, int64_t Ofs, int Dir)
+{
        if(FD & NATIVE_FILE_MASK) {
                return native_seek(FD & (NATIVE_FILE_MASK-1), Ofs, Dir);
        }
@@ -94,14 +96,15 @@ int acess_seek(int FD, int64_t Ofs, int Dir) {
        return _Syscall(SYS_SEEK, ">i >I >i", FD, Ofs, Dir);
 }
 
-uint64_t acess_tell(int FD) {
+uint64_t acess__SysTell(int FD)
+{
        if(FD & NATIVE_FILE_MASK)
                return native_tell( FD & (NATIVE_FILE_MASK-1) );
        DEBUG("tell(0x%x)", FD);
        return _Syscall(SYS_TELL, ">i", FD);
 }
 
-int acess_ioctl(int fd, int id, void *data) {
+int acess__SysIOCtl(int fd, int id, void *data) {
         int    len;
        DEBUG("ioctl(%i, %i, %p)", fd, id, data);
        // NOTE: The length here is hacky and could break
@@ -111,7 +114,7 @@ int acess_ioctl(int fd, int id, void *data) {
                len = PAGE_SIZE - ((uintptr_t)data % PAGE_SIZE);
        return _Syscall(SYS_IOCTL, ">i >i ?d", fd, id, len, data);
 }
-int acess_finfo(int fd, t_sysFInfo *info, int maxacls) {
+int acess__SysFInfo(int fd, t_sysFInfo *info, int maxacls) {
 //     DEBUG("offsetof(size, t_sysFInfo) = %i", offsetof(t_sysFInfo, size));
        DEBUG("finfo(%i, %p, %i)", fd, info, maxacls);
        return _Syscall(SYS_FINFO, ">i <d >i",
@@ -121,7 +124,7 @@ int acess_finfo(int fd, t_sysFInfo *info, int maxacls) {
                );
 }
 
-int acess_SysReadDir(int fd, char *dest) {
+int acess__SysReadDir(int fd, char *dest) {
        DEBUG("SysReadDir(%i, %p)", fd, dest);
        return _Syscall(SYS_READDIR, ">i <d", fd, 256, dest);
 }
@@ -138,12 +141,6 @@ int acess__SysSelect(int nfds, fd_set *read, fd_set *write, fd_set *error, int64
                );
 }
 
-int acess_select(int nfds, fd_set *read, fd_set *write, fd_set *error, int64_t *timeout)
-{
-       return acess__SysSelect(nfds, read, write, error, timeout, 0);
-}
-
-
 int acess__SysOpenChild(int fd, char *name, int flags) {
        DEBUG("_SysOpenChild(0x%x, '%s', 0x%x)", fd, name, flags);
        return _Syscall(SYS_OPENCHILD, ">i >s >i", fd, name, flags);
@@ -176,7 +173,7 @@ uint64_t acess__SysAllocate(uintptr_t vaddr)
 }
 
 // --- Process Management ---
-int acess_clone(int flags, void *stack)
+int acess__SysClone(int flags, void *stack)
 {
        #ifdef __WIN32__
        Warning("Win32 does not support anything like fork(2), cannot emulate");
@@ -212,7 +209,7 @@ int acess_clone(int flags, void *stack)
        #endif
 }
 
-int acess_execve(char *path, char **argv, const char **envp)
+int acess__SysExecVE(char *path, char **argv, const char **envp)
 {
         int    i, argc;
        
@@ -289,13 +286,13 @@ int acess__SysSpawn(const char *binary, const char **argv, const char **envp, in
        return kernel_tid;
 }
 
-void acess_sleep(void)
-{
-       DEBUG("%s()", __func__);
-       _Syscall(SYS_SLEEP, "");
-}
+//void acess_sleep(void)
+//{
+//     DEBUG("%s()", __func__);
+//     _Syscall(SYS_SLEEP, "");
+//}
 
-int acess_waittid(int TID, int *ExitStatus)
+int acess__SysWaitTID(int TID, int *ExitStatus)
 {
        DEBUG("%s(%i, %p)", __func__, TID, ExitStatus);
        return _Syscall(SYS_WAITTID, ">i <d", TID, sizeof(int), &ExitStatus);
@@ -308,13 +305,13 @@ int acess_getpid(void) { return _Syscall(SYS_GETPID, ""); }
 int acess_getuid(void) { return _Syscall(SYS_GETUID, ""); }
 int acess_getgid(void) { return _Syscall(SYS_GETGID, ""); }
 
-int acess_SysSendMessage(int DestTID, int Length, void *Data)
+int acess__SysSendMessage(int DestTID, int Length, void *Data)
 {
        DEBUG("%s(%i, 0x%x, %p)", __func__, DestTID, Length, Data);
        return _Syscall(SYS_SENDMSG, ">i >d", DestTID, Length, Data);
 }
 
-int acess_SysGetMessage(int *SourceTID, int BufLen, void *Data)
+int acess__SysGetMessage(int *SourceTID, int BufLen, void *Data)
 {
        DEBUG("%s(%p, %p)", __func__, SourceTID, Data);
        return _Syscall(SYS_GETMSG, "<d <d",
@@ -362,37 +359,36 @@ uint32_t acess__SysSetMemFlags(uintptr_t vaddr, uint32_t flags, uint32_t mask)
 const tSym     caBuiltinSymbols[] = {
        DEFSYM(_exit),
        
-       DEFSYM(chdir),
-       DEFSYM(open),
-       DEFSYM(close),
-       DEFSYM(reopen),
-       DEFSYM(read),
-       DEFSYM(write),
-       DEFSYM(seek),
-       DEFSYM(tell),
-       DEFSYM(ioctl),
-       DEFSYM(finfo),
-       DEFSYM(SysReadDir),
-       DEFSYM(select),
+       DEFSYM(_SysChdir),
+       DEFSYM(_SysOpen),
        DEFSYM(_SysOpenChild),
+       DEFSYM(_SysReopen),
+       DEFSYM(_SysClose),
+       DEFSYM(_SysRead),
+       DEFSYM(_SysWrite),
+       DEFSYM(_SysSeek),
+       DEFSYM(_SysTell),
+       DEFSYM(_SysIOCtl),
+       DEFSYM(_SysFInfo),
+       DEFSYM(_SysReadDir),
        DEFSYM(_SysGetACL),
        DEFSYM(_SysMount),
        DEFSYM(_SysSelect),
        
-       DEFSYM(clone),
-       DEFSYM(execve),
+       DEFSYM(_SysClone),
+       DEFSYM(_SysExecVE),
        DEFSYM(_SysSpawn),
-       DEFSYM(sleep),
+//     DEFSYM(sleep),
        
-       DEFSYM(waittid),
+       DEFSYM(_SysWaitTID),
        DEFSYM(gettid),
        DEFSYM(setuid),
        DEFSYM(setgid),
        DEFSYM(getuid),
        DEFSYM(getgid),
 
-       DEFSYM(SysSendMessage),
-       DEFSYM(SysGetMessage),
+       DEFSYM(_SysSendMessage),
+       DEFSYM(_SysGetMessage),
        
        DEFSYM(_SysAllocate),
        DEFSYM(_SysSetMemFlags),
index dc319ac..e9a4b3b 100644 (file)
@@ -13,6 +13,8 @@
 // Syscall request (used by acess_*)
 extern uint64_t        _Syscall(int SyscallID, const char *ArgTypes, ...);
 
+extern int     acess__errno;
+
 extern int     native_open(const char *Path, int Flags);
 extern void    native_close(int FD);
 extern size_t  native_read(int FD, void *Dest, size_t Bytes);
@@ -24,10 +26,10 @@ extern int  native_execve(const char *filename, const char *const argv[], const c
 extern int     native_spawn(const char *filename, const char *const argv[], const char *const envp[]);
 
 // Syscalls used by the linker
-extern int     acess_open(const char *Path, int Flags);
-extern void    acess_close(int FD);
-extern size_t  acess_read(int FD, void *Dest, size_t Bytes);
-extern int     acess_seek(int FD, int64_t Offset, int Dir);
+extern int     acess__SysOpen(const char *Path, int Flags);
+extern void    acess__SysClose(int FD);
+extern size_t  acess__SysRead(int FD, void *Dest, size_t Bytes);
+extern int     acess__SysSeek(int FD, int64_t Offset, int Dir);
 
 // Symbol type
 typedef struct {
index 3f1cb2b..a03e963 100644 (file)
@@ -53,7 +53,7 @@ int main(int argc, char *argv[], char **envp)
                }
                
                if(strcmp(argv[i], "--open") == 0) {
-                       if( acess_open(argv[++i], 6) == -1 ) {  // Read/Write
+                       if( acess__SysOpen(argv[++i], 6) == -1 ) {      // Read/Write
                                fprintf(stderr, "Unable to open '%s'\n", argv[i]);
                                exit(1);
                        }
index d659fe5..c649f28 100644 (file)
 #define DEBUG(...)     do{}while(0)
 #endif
 
+#define assert(cnd) do{ \
+       if( !(cnd) ) { \
+               fprintf(stderr, "%s:%i - assert failed - " #cnd, __FILE__, __LINE__);\
+               exit(-1); \
+       } \
+}while(0)
+
 #define        MAX_FPS 16
 
 // === Types ===
@@ -163,7 +170,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
 {
        va_list args;
         int    paramCount, dataLength;
-        int    retCount = 1, retLength = sizeof(uint64_t);
+        int    retCount = 2, retLength = sizeof(uint64_t) + sizeof(uint32_t);
        void    **retPtrs;      // Pointers to return buffers
        const char      *str;
        tRequestHeader  *req;
@@ -236,38 +243,33 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        }
        va_end(args);
        
-       // Send syscall request
+       // --- Send syscall request
        if( SendRequest(req, dataLength, retLength) < 0 ) {
                fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID);
                exit(127);
        }
        
-       // Parse return value
-       dataPtr = &req->Params[req->NParams];
-       retValue = 0;
-       if( req->NParams >= 1 )
-       {
-               switch(req->Params[0].Type)
-               {
-               case ARG_TYPE_INT64:
-                       retValue = *(uint64_t*)dataPtr;
-                       dataPtr += req->Params[0].Length;
-                       break;
-               case ARG_TYPE_INT32:
-                       retValue = *(uint32_t*)dataPtr;
-                       dataPtr += req->Params[0].Length;
-                       break;
-               }       
-       }
+       Debug("req->NParams = %i", req->NParams);
+       assert(req->NParams >= 2);
+       // return
+       assert(req->Params[0].Type == ARG_TYPE_INT64);
+       assert(req->Params[0].Length == sizeof(uint64_t));
+       retValue = *(uint64_t*)dataPtr;
+       dataPtr += sizeof(uint64_t);
+       // errno
+       assert(req->Params[1].Type == ARG_TYPE_INT32);
+       assert(req->Params[1].Length == sizeof(uint32_t));
+       acess__errno = *(uint32_t*)dataPtr;
+       dataPtr += sizeof(uint32_t);
        
        // Write changes to buffers
-       if( req->NParams - 1 != retCount ) {
+       if( req->NParams - 2 != retCount ) {
                fprintf(stderr, "syscalls.c: Return count inbalance (%i - 1 != exp %i) [Call %i]\n",
                        req->NParams, retCount, SyscallID);
                exit(127);
        }
        retCount = 0;
-       for( i = 1; i < req->NParams; i ++ )
+       for( i = 2; i < req->NParams; i ++ )
        {
                #if 0
                 int     j;
@@ -276,6 +278,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
                        printf(" %02x", ((uint8_t*)dataPtr)[j]);
                printf("\n");
                #endif
+               assert( req->Params[i].Type == ARG_TYPE_DATA );
                memcpy( retPtrs[retCount++], dataPtr, req->Params[i].Length );
                dataPtr += req->Params[i].Length;
        }
index 21a9cb5..b9661bc 100644 (file)
@@ -35,84 +35,20 @@ typedef struct sRequestHeader {
        tRequestValue   Params[];
 }      tRequestHeader;
 
-enum eSyscalls {
-       SYS_NULL,
-       
-       SYS_EXIT,
-       
-       SYS_OPEN,
-       SYS_CLOSE,
-       SYS_READ,
-       SYS_WRITE,
-       SYS_SEEK,
-       SYS_TELL,
-       SYS_IOCTL,
-       SYS_FINFO,
-       SYS_READDIR,
-       SYS_OPENCHILD,
-       SYS_GETACL,
-       SYS_MOUNT,
-       SYS_REOPEN,
-       SYS_CHDIR,
-       
-       SYS_WAITTID,
-       SYS_SETUID,
-       SYS_SETGID,
-
-       SYS_GETTID,
-       SYS_GETPID,
-       SYS_GETUID,
-       SYS_GETGID,
 
-       // IPC
-       SYS_SLEEP,
-       SYS_AN_FORK,
-       SYS_AN_SPAWN,
-       SYS_SENDMSG,
-       SYS_GETMSG,
-       SYS_SELECT,
-       SYS_WAITEVENT,
-       
+enum eSyscalls {
+       #define _(n) n
+       #include "syscalls_list.h"
+       #undef _
        N_SYSCALLS
 };
 
 #ifndef DONT_INCLUDE_SYSCALL_NAMES
 static const char * casSYSCALL_NAMES[] = {
-       "SYS_NULL",
-       
-       "SYS_EXIT",
-       
-       "SYS_OPEN",
-       "SYS_CLOSE",
-       "SYS_READ",
-       "SYS_WRITE",
-       "SYS_SEEK",
-       "SYS_TELL",
-       "SYS_IOCTL",
-       "SYS_FINFO",
-       "SYS_READDIR",
-       "SYS_OPENCHILD",
-       "SYS_GETACL",
-       "SYS_MOUNT",
-       "SYS_REOPEN",
-       "SYS_CHDIR",
-       
-       "SYS_WAITTID",
-       "SYS_SETUID",
-       "SYS_SETGID",
-       
-       "SYS_GETTID",
-       "SYS_GETPID",
-       "SYS_GETUID",
-       "SYS_GETGID",
-       
-       // IPC
-       "SYS_SLEEP",
-       "SYS_AN_FORK",
-       "SYS_SENDMSG",
-       "SYS_GETMSG",
-       "SYS_SELECT",
-       "SYS_WAITEVENT"
+       #define _(n) #n
+       #include "syscalls_list.h"
+       #undef _
+       "-"
 };
 #endif
 
diff --git a/AcessNative/syscalls_list.h b/AcessNative/syscalls_list.h
new file mode 100644 (file)
index 0000000..9ab9098
--- /dev/null
@@ -0,0 +1,37 @@
+_(SYS_NULL),
+
+_(SYS_EXIT),
+
+_(SYS_OPEN),
+_(SYS_CLOSE),
+_(SYS_READ),
+_(SYS_WRITE),
+_(SYS_SEEK),
+_(SYS_TELL),
+_(SYS_IOCTL),
+_(SYS_FINFO),
+_(SYS_READDIR),
+_(SYS_OPENCHILD),
+_(SYS_GETACL),
+_(SYS_MOUNT),
+_(SYS_REOPEN),
+_(SYS_CHDIR),
+
+_(SYS_WAITTID),
+_(SYS_SETUID),
+_(SYS_SETGID),
+
+_(SYS_GETTID),
+_(SYS_GETPID),
+_(SYS_GETUID),
+_(SYS_GETGID),
+
+// IPC
+_(SYS_SLEEP),
+_(SYS_AN_FORK),
+_(SYS_AN_SPAWN),
+_(SYS_SENDMSG),
+_(SYS_GETMSG),
+_(SYS_SELECT),
+_(SYS_WAITEVENT),
+
index 29ef50a..7867b16 100644 (file)
@@ -5,5 +5,4 @@ endif
 
 # Core ARMv7 modules
 
-MODULES += armv7/GIC
 MODULES += Filesystems/InitRD
index abb08e2..ce122f3 100644 (file)
@@ -2,5 +2,6 @@
 include $(ACESSDIR)/BuildConf/armv7/default.mk
 
 ARM_CPUNAME = cortex-a8
+MODULES += armv7/GIC
 MODULES += Input/PS2KbMouse
 MODULES += Display/PL110
index 24eddf5..cd20c37 100644 (file)
@@ -2,5 +2,6 @@
 include $(ACESSDIR)/BuildConf/armv7/default.mk
 
 ARM_CPUNAME = cortex-a9
+MODULES += armv7/GIC
 MODULES += Display/Tegra2Vid
 MODULES += USB/Core USB/EHCI
index 5429fe6..1d9f436 100644 (file)
@@ -12,7 +12,7 @@ LDFLAGS += `$(CC) --print-libgcc-file-name`
 
 A_OBJ  = start.ao main.o lib.o lib.ao time.o pci.o debug.o
 A_OBJ += mm_phys.o mm_virt.o proc.o proc.ao
-A_OBJ += vpci_$(PLATFORM).o
+A_OBJ += vpci_$(PLATFORM).o platform_$(PLATFORM).o
 
 #main.c: Makefile.BuildNum.$(ARCH)
 
index 248c17c..d05c01e 100644 (file)
@@ -15,6 +15,7 @@ extern void   Arch_LoadBootModules(void);
 extern void    Heap_Install(void);
 extern void    Threads_Init(void);
 extern void    System_Init(const char *Commandline);
+extern void    Time_Setup(void);
 
 // === PROTOTYPES ===
  int   kmain(void);
@@ -44,7 +45,7 @@ int kmain(void)
        //
        LogF("Moving to arch-independent init\n");
        #if PLATFORM_is_tegra2
-       System_Init("Acess2.armv7.bin /Acess=initrd: -VTerm:Video=Tegra2Vid");
+       System_Init("Acess2.armv7.bin /Acess=initrd: -VTerm:Video=Tegra2Vid -USB_EHCI:C5000000-14,C5004000-15");
        #else
        System_Init("Acess2.armv7.bin /Acess=initrd: -VTerm:Video=PL110");
        #endif
index 146caea..8003420 100644 (file)
@@ -10,7 +10,7 @@
 #include <hal_proc.h>
 
 #define TRACE_MAPS     0
-#define TRACE_COW      1
+#define TRACE_COW      0
 
 #define AP_KRW_ONLY    1       // Kernel page
 #define AP_KRO_ONLY    5       // Kernel RO page
diff --git a/KernelLand/Kernel/arch/armv7/platform_realview_pb.c b/KernelLand/Kernel/arch/armv7/platform_realview_pb.c
new file mode 100644 (file)
index 0000000..4077f69
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Acess2 Kernel ARMv7 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * platform_realviewpb.c
+ * - RealviewPB core code
+ */
+#include <acess.h>
+
+// === PROTOTYPES ===
+void   Time_Setup(void);
+
+// === GLOBALS ===
+tPAddr gGIC_DistributorAddr = 0x1e001000;
+tPAddr gGIC_InterfaceAddr = 0x1e000000;
+
+// === CODE ===
+void Time_Setup(void)
+{
+       // TODO: 
+}
diff --git a/KernelLand/Kernel/arch/armv7/platform_tegra2.c b/KernelLand/Kernel/arch/armv7/platform_tegra2.c
new file mode 100644 (file)
index 0000000..36dbb56
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Acess2 Kernel ARMv7 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * platform_tegra2.c
+ * - Tegra2 Core code
+ */
+#include <acess.h>
+#include "platform_tegra2.h"
+
+// === CONSTANTS ===
+#define TIMER0_INT     (0*32+0)        // Pri #0
+#define TIMER1_INT     (0*32+1)        // Pri #1
+#define TIMER2_INT     (1*32+9)        // Sec #9
+#define TIMER3_INT     (1*32+10)       // Sec #10
+
+// === Imports ===
+extern volatile Sint64 giTimestamp;
+extern volatile Uint64 giTicks;
+extern volatile Uint64 giPartMiliseconds;
+extern void    Timer_CallTimers(void);
+
+// === PROTORTYPES ===
+void   Timer_IRQHandler_SysClock(int IRQ, void *_unused);
+void   Time_Setup(void);
+
+// === GLOBALS ===
+// - Addresses for the GIC to use
+tPAddr gGIC_InterfaceAddr = 0x50040000;
+tPAddr gGIC_DistributorAddr = 0x50041000;
+// - Map of timer registers
+struct sTimersMap *gpTimersMap;
+// - Interrupt controller code commented out, because the Tegra2 also has a GIC
+#if 0
+struct sIRQMap gpIRQMap;
+#endif
+
+// === CODE ===
+
+// -- Timers --
+void Timer_IRQHandler_SysClock(int IRQ, void *_unused)
+{
+       giTimestamp += 100;
+       gpTimersMap->TMR0.PCR_0 = (1<<31);
+}
+
+void Time_Setup(void)
+{
+       gpTimersMap = (void*)MM_MapHWPages(0x60005000, 1);
+       // Timer 1 (used for system timekeeping)
+       IRQ_AddHandler(0*32+0, Timer_IRQHandler_SysClock, NULL);
+       gpTimersMap->TMR0.PTV_0 = (1<31)|(1<30)|(100*1000);     // enable, periodic, 100 ms
+}
+
+#if 0
+// -- Interrupt Controller --
+void IRQ_CtrlrHandler(struct sIRQRegs *Ctrlr, int Ofs)
+{
+       // Primary CPU only?
+       // TODO: 
+}
+
+void IRQ_RootHandler(void)
+{
+       IRQ_CtrlrHandler(&gpIRQMap->Pri, 0*32);
+       IRQ_CtrlrHandler(&gpIRQMap->Sec, 1*32);
+       IRQ_CtrlrHandler(&gpIRQMap->Tri, 2*32);
+       IRQ_CtrlrHandler(&gpIRQMap->Quad, 3*32);
+}
+
+void IRQ_Setup(void)
+{
+       gpIRQMap = (void*)MM_MapHWPages(0x60004000, 1);
+       
+       gpIRQHandler = IRQ_RootHandler;
+}
+#endif
diff --git a/KernelLand/Kernel/arch/armv7/platform_tegra2.h b/KernelLand/Kernel/arch/armv7/platform_tegra2.h
new file mode 100644 (file)
index 0000000..67f7582
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Acess2 Kernel ARMv7 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * platform_tegra2.c
+ * - Tegra2 Core code
+ */
+#ifndef _PLATFORM__TEGRA2_H_
+#define _PLATFORM__TEGRA2_H_
+
+struct sTimerRegs
+{
+       Uint32  PTV_0;  // Control / Target value
+       Uint32  PCR_0;  // Current value / IRQ clear
+};
+struct sTimersMap
+{
+       struct sTimerRegs       TMR0;
+       struct sTimerRegs       TMR1;
+       // TMRUS
+       char _padding[ 0x50-0x10 ];
+
+       struct sTimerRegs       TMR2;
+       struct sTimerRegs       TMR3;
+};
+
+#if 0
+struct sIRQRegs
+{
+       Uint32  VIRQ_CPU;
+       Uint32  VIRQ_COP;
+       Uint32  VFIQ_CPU;
+       Uint32  VFIQ_COP;
+       Uint32  ISR;
+       Uint32  FIR;    // Force interrupt status
+       Uint32  FIR_SET;        // Set bit in FIR
+       Uint32  FIR_CLR;        // Clear bit in FIR
+       Uint32  CPU_IER;        // RO - Interrupt Enable register
+       Uint32  CPU_IER_SET;
+       Uint32  CPU_IER_CLR;
+       Uint32  CPU_IEP;        // 1 = FIQ
+       Uint32  COP_IER;        // RO - Interrupt Enable register
+       Uint32  COP_IER_SET;
+       Uint32  COP_IER_CLR;
+       Uint32  COP_IEP;        // 1 = FIQ
+};
+struct sArbGntRegs
+{
+       Uint32  CPU_Status;
+       Uint32  CPU_Enable;
+       Uint32  COP_Status;
+       Uint32  COP_Enable;
+};
+struct sIRQMap
+{
+       struct sIRQRegs Pri;
+       struct sArbGntRegs      Arb;
+       char    _pad1[0x100-sizeof(struct sIRQRegs)-sizeof(struct sIRQRegs)];
+       struct sIRQRegs Sec;
+       char    _pad2[0x100-sizeof(struct sIRQRegs)];
+       struct sIRQRegs Tri;
+       char    _pad3[0x100-sizeof(struct sIRQRegs)];
+       struct sIRQRegs Quad;
+};
+#endif
+
+#endif
+
index d44e9d5..1d01fb0 100644 (file)
 
 // === GLOBALS ===
 tVPCI_Device   gaVPCI_Devices[] = {
+       // NOTE: USB Controllers moved to command line arguments
+       #if 0
        {
        .Vendor=0x0ACE,.Device=0x1100,
-       .Class = 0x0C032000,    // Serial, USB, ECHI
+       .Class = 0x0C032100,    // Serial, USB, ECHI
        .BARs = {0xC5000000,0,0,0,0,0},
        .IRQ = 0*32+20,
        },
@@ -29,6 +31,7 @@ tVPCI_Device  gaVPCI_Devices[] = {
        .BARs = {0xC5008000,0,0,0,0,0},
        .IRQ = 4*32+1,
        }
+       #endif
 };
 int giVPCI_DeviceCount = sizeof(gaVPCI_Devices)/sizeof(gaVPCI_Devices[0]);
 
index 43a1854..57d7fe8 100644 (file)
@@ -5,7 +5,7 @@
  * acpica.c
  * - ACPICA Interface
  */
-#define ACPI_DEBUG_OUTPUT      1
+#define ACPI_DEBUG_OUTPUT      0
 #define DEBUG  0
 #define _AcpiModuleName "Shim"
 #define _COMPONENT     "Acess"
index 3abf548..97a7c75 100644 (file)
@@ -19,7 +19,6 @@
 
 // === IMPORTS ===
 extern char    gKernelEnd[];
-extern void    Heap_Install(void);
 extern void    MM_PreinitVirtual(void);
 extern void    MM_Install(int NPMemRanges, tPMemMapEnt *PMemRanges);
 extern void    MM_InstallVirtual(void);
index 397ec14..77b0d1a 100644 (file)
@@ -77,7 +77,7 @@ int VM8086_Install(char **Arguments)
        
        // Create BIOS Call process
        pid = Proc_Clone(CLONE_VM);
-       Log_Debug("VM8086", "pid = %i", pid);
+       //Log_Debug("VM8086", "pid = %i", pid);
        if(pid == -1)
        {
                Log_Error("VM8086", "Unable to clone kernel into VM8086 worker");
@@ -89,7 +89,7 @@ int VM8086_Install(char **Arguments)
                Uint16  * volatile rmstack;     // Real Mode Stack
                 int    i;
 
-               Log_Debug("VM8086", "Initialising worker");     
+               //Log_Debug("VM8086", "Initialising worker");   
        
                // Set Image Name
                Threads_SetName("VM8086");
index a855a47..f4c4a81 100644 (file)
@@ -53,7 +53,6 @@ void kmain(Uint MbMagic, void *MbInfoPtr)
                // Adjust Multiboot structure address
                mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE );
                gsBootCmdLine = (char*)( (Uint)mbInfo->CommandLine + KERNEL_BASE);
-               // TODO: ref above?
                nPMemMapEnts = Multiboot_LoadMemoryMap(mbInfo, KERNEL_BASE, pmemmap, MAX_PMEMMAP_ENTS,
                        KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_BASE
                        );
@@ -87,6 +86,8 @@ void kmain(Uint MbMagic, void *MbInfoPtr)
        Log_Log("Arch", "Starting VFS...");
        VFS_Init();
        
+       // Multiboot_InitFramebuffer(mbInfo);
+
        gaArch_BootModules = Multiboot_LoadModules(mbInfo, KERNEL_BASE, &giArch_NumBootModules);
        
        *(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'Z';
index 46e2b21..b35b507 100644 (file)
@@ -458,9 +458,8 @@ void Proc_ClearThread(tThread *Thread)
 tTID Proc_NewKThread(void (*Fcn)(void*), void *Data)
 {
        Uint    rsp;
-       tThread *newThread, *cur;
+       tThread *newThread;
        
-       cur = Proc_GetCurThread();
        newThread = Threads_CloneTCB(0);
        if(!newThread)  return -1;
        
@@ -537,11 +536,9 @@ tTID Proc_Clone(Uint Flags)
  */
 tThread *Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
 {
-       tThread *new, *cur;
+       tThread *new;
        Uint    stack_contents[3];
 
-       cur = Proc_GetCurThread();
-       
        // Create new thread
        new = Threads_CloneThreadZero();
        if(!new) {
index 6132bd9..5e17c0e 100644 (file)
@@ -149,7 +149,7 @@ void Debug(const char *Fmt, ...)
        va_list args;
        
        #if LOCK_DEBUG_OUTPUT
-       SHORTLOCK(&glDebug_Lock);
+       if(!CPU_HAS_LOCK(&glDebug_Lock)) SHORTLOCK(&glDebug_Lock);
        #endif
 
        Debug_Puts(0, "Debug: ");
@@ -227,7 +227,8 @@ void Panic(const char *Fmt, ...)
        va_list args;
        
        #if LOCK_DEBUG_OUTPUT
-       SHORTLOCK(&glDebug_Lock);
+       if( !CPU_HAS_LOCK(&glDebug_Lock) )
+               SHORTLOCK(&glDebug_Lock);
        #endif
        // And never SHORTREL
        
index 2adaec7..1e6fcdb 100644 (file)
@@ -1,5 +1,9 @@
-/* AcessOS
- * FIFO Pipe Driver
+/* 
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * drv/fifo.c
+ * - FIFO Pipe Driver
  */
 #define DEBUG  0
 #include <acess.h>
@@ -126,9 +130,8 @@ tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename)
        if(Filename[0] == '\0') return NULL;
        
        // Anon Pipe
-       if(Filename[0] == 'a' && Filename[1] == 'n'
-       && Filename[2] == 'o' && Filename[3] == 'n'
-       && Filename[4] == '\0') {
+       if( strcmp(Filename, "anon") == 0 )
+       {
                tmp = FIFO_Int_NewPipe(DEFAULT_RING_SIZE, "anon");
                return &tmp->Node;
        }
@@ -277,6 +280,7 @@ size_t FIFO_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
                
                // Mark some flags
                if( pipe->ReadPos == pipe->WritePos ) {
+                       LOG("%i == %i, marking none to read", pipe->ReadPos, pipe->WritePos);
                        VFS_MarkAvaliable(Node, 0);
                }
                VFS_MarkFull(Node, 0);  // Buffer can't still be full
@@ -312,9 +316,12 @@ size_t FIFO_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buff
        while(remaining)
        {
                // Wait for buffer to empty
-               if(pipe->Flags & PF_BLOCKING) {
-                       if( pipe->ReadPos == (pipe->WritePos+1)%pipe->BufSize )
+               if(pipe->Flags & PF_BLOCKING)
+               {
+                       if( pipe->ReadPos == (pipe->WritePos+1)%pipe->BufSize ) {
+                               LOG("Blocking write on FIFO");
                                VFS_SelectNode(Node, VFS_SELECT_WRITE, NULL, "FIFO_Write");
+                       }
 
                        len = remaining;
                        if( pipe->ReadPos > pipe->WritePos )
@@ -346,11 +353,14 @@ size_t FIFO_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buff
                if(len > pipe->BufSize - pipe->WritePos)
                {
                        int ofs = pipe->BufSize - pipe->WritePos;
+                       LOG("pipe->Buffer = %p, pipe->WritePos = %i, ofs=%i, len=%i",
+                               pipe->Buffer, pipe->WritePos, ofs, len);
                        memcpy(&pipe->Buffer[pipe->WritePos], Buffer, ofs);
-                       memcpy(&pipe->Buffer, (Uint8*)Buffer + ofs, len-ofs);
+                       memcpy(&pipe->Buffer[0], (Uint8*)Buffer + ofs, len-ofs);
                }
                else
                {
+                       LOG("pipe->Buffer = %p, pipe->WritePos = %i", pipe->Buffer, pipe->WritePos);
                        memcpy(&pipe->Buffer[pipe->WritePos], Buffer, len);
                }
                
@@ -360,6 +370,7 @@ size_t FIFO_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buff
                
                // Mark some flags
                if( pipe->ReadPos == pipe->WritePos ) {
+                       LOG("Buffer is full");
                        VFS_MarkFull(Node, 1);  // Buffer full
                }
                VFS_MarkAvaliable(Node, 1);
@@ -384,11 +395,13 @@ tPipe *FIFO_Int_NewPipe(int Size, const char *Name)
        tPipe   *ret;
         int    namelen = strlen(Name) + 1;
         int    allocsize = sizeof(tPipe) + sizeof(tVFS_ACL) + Size + namelen;
-       
+
+       ENTER("iSize sName", Size, Name);       
+
        ret = calloc(1, allocsize);
-       if(!ret)        return NULL;
+       if(!ret)        LEAVE_RET('n', NULL);
        
-       // Clear Return
+       // Set default flags
        ret->Flags = PF_BLOCKING;
        
        // Allocate Buffer
@@ -417,6 +430,8 @@ tPipe *FIFO_Int_NewPipe(int Size, const char *Name)
                = ret->Node.MTime
                = ret->Node.ATime = now();
        ret->Node.Type = &gFIFO_PipeNodeType;
+
+       LEAVE('p', ret);
        
        return ret;
 }
index 2e1ce15..1df421e 100644 (file)
@@ -150,9 +150,15 @@ int PCI_Install(char **Arguments)
                devinfo->revision = gaVPCI_Devices[i].Class & 0xFF;\r
                devinfo->class = gaVPCI_Devices[i].Class >> 8;\r
                snprintf(devinfo->Name, sizeof(devinfo->Name), "%02x.%02x:%x", 0xFF, i, 0);\r
+               \r
+               #if LIST_DEVICES\r
+               Log_Log("PCI", "Device %i,%i:%i %06x => 0x%04x:0x%04x Rev %i",\r
+                       0xFF, i, 0, devinfo->class,\r
+                       devinfo->vendor, devinfo->device, devinfo->revision);\r
+               #endif\r
 \r
                for(int j = 0; j < 256/4; j ++ )\r
-                       devinfo->ConfigCache[i] = VPCI_Read(&gaVPCI_Devices[i], j*4, 4);\r
+                       devinfo->ConfigCache[j] = VPCI_Read(&gaVPCI_Devices[i], j*4, 4);\r
 \r
                memset(&devinfo->Node, 0, sizeof(devinfo->Node));\r
                devinfo->Node.Inode = giPCI_DeviceCount;\r
index 4fccdb8..e4288b6 100644 (file)
@@ -22,12 +22,14 @@ Uint32 VPCI_Read(tVPCI_Device *Dev, Uint8 Offset, Uint8 Size)
        case 0: // Vendor[0:15], Device[16:31]
                tmp_dword = (Dev->Vendor) | (Dev->Device << 16);
                break;
+       // 1: Command[0:15], Status[16:31]
        case 2: // Class Code
                tmp_dword = Dev->Class;
                break;
-       // 1: Command[0:15], Status[16:31]
        // 3: Cache Line Size, Latency Timer, Header Type, BIST
-       // 4-9: BARs
+       case 4 ... 9:   // 4-9: BARs
+               tmp_dword = Dev->BARs[ (Offset>>2) - 4 ];
+               break;
        // 10: Unused (Cardbus CIS Pointer)
        // 11: Subsystem Vendor ID, Subsystem ID
        // 12: Expansion ROM Address
@@ -35,7 +37,8 @@ Uint32 VPCI_Read(tVPCI_Device *Dev, Uint8 Offset, Uint8 Size)
        // 14: Reserved
        // 15: Interrupt Line, Interrupt Pin, Min Grant, Max Latency
        default:
-               tmp_dword = Dev->Read(Dev->Ptr, Offset >> 2);
+               if( Dev->Read )
+                       tmp_dword = Dev->Read(Dev->Ptr, Offset >> 2);
                break;
        }
 
@@ -66,7 +69,10 @@ void VPCI_Write(tVPCI_Device *Dev, Uint8 Offset, Uint8 Size, Uint32 Data)
                return ;
        }
 
-       tmp_dword = Dev->Read(Dev->Ptr, Offset>>2);
+       if( Size != 4 && Dev->Read )
+               tmp_dword = Dev->Read(Dev->Ptr, Offset>>2);
+       else
+               tmp_dword = 0;
        switch(Size)
        {
        case 4: tmp_dword = 0;  break;
@@ -80,5 +86,6 @@ void VPCI_Write(tVPCI_Device *Dev, Uint8 Offset, Uint8 Size, Uint32 Data)
                break;
        }
        tmp_dword |= Data << ((Offset&3)*8);
-       Dev->Write(Dev->Ptr, Offset>>2, tmp_dword);
+       if( Dev->Write )
+               Dev->Write(Dev->Ptr, Offset>>2, tmp_dword);
 }
index 5316ba5..3ff1a53 100644 (file)
@@ -129,6 +129,9 @@ int VT_Install(char **Arguments)
                        else if( strcmp(opt, "Scrollback") == 0 ) {
                                giVT_Scrollback = atoi( val );
                        }
+                       else {
+                               Log_Notice("VTerm", "Unknown option '%s'", opt);
+                       }
                }
        }
        
@@ -448,8 +451,8 @@ size_t VT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer
                // - Sanity Checking
                size = term->Width*term->Height*4;
                if( Offset > size ) {
-                       Log_Notice("VTerm", "VT_Write: Offset (0x%llx) > FBSize (0x%x)",
-                               Offset, size);
+                       Log_Notice("VTerm", "VT_Write: %i Offset (0x%llx) > FBSize (0x%x)",
+                               (int)Node->Inode, Offset, size);
                        return 0;
                }
                if( Offset + Length > size ) {
index 55eea0e..abd786c 100644 (file)
@@ -112,7 +112,7 @@ extern void VT_InitInput(void);
 extern void    VT_KBCallBack(Uint32 Codepoint);
 // --- VT100 Emulation ---
 extern void    VT_int_ParseEscape_StandardLarge(tVTerm *Term, char CmdChar, int argc, int *args);
-extern int     VT_int_ParseEscape(tVTerm *Term, const char *Buffer);
+extern int     VT_int_ParseEscape(tVTerm *Term, const char *Buffer, size_t Bytes);
 // --- Terminal Buffer ---
 extern void    VT_int_PutString(tVTerm *Term, const Uint8 *Buffer, Uint Count);
 extern void    VT_int_PutChar(tVTerm *Term, Uint32 Ch);
index 7c29656..525f1a4 100644 (file)
  */
 void VT_int_PutString(tVTerm *Term, const Uint8 *Buffer, Uint Count)
 {
-       Uint32  val;
         int    i;
        
        // Iterate
        for( i = 0; i < Count; i++ )
        {
                // Handle escape sequences
-               if( Buffer[i] == 0x1B )
+               if( Buffer[i] == 0x1B && Count - i > 1 )
                {
-                       i ++;
-                       i += VT_int_ParseEscape(Term, (const char*)&Buffer[i]) - 1;
-                       continue;
+                       int ret = VT_int_ParseEscape(Term, (const char*)&Buffer[i+1], Count-(i+1));
+                       if( ret > 0 )
+                       {
+                               i += ret;
+                               continue;
+                       }
                }
                
                // Fast check for non UTF-8
                if( Buffer[i] < 128 )   // Plain ASCII
                        VT_int_PutChar(Term, Buffer[i]);
                else {  // UTF-8
+                       Uint32  val;
                        i += ReadUTF8(&Buffer[i], &val) - 1;
                        VT_int_PutChar(Term, val);
                }
index fb152a3..d86ee0f 100644 (file)
@@ -211,30 +211,39 @@ void VT_int_ParseEscape_StandardLarge(tVTerm *Term, char CmdChar, int argc, int
  * \fn int VT_int_ParseEscape(tVTerm *Term, const char *Buffer)
  * \brief Parses a VT100 Escape code
  */
-int VT_int_ParseEscape(tVTerm *Term, const char *Buffer)
+int VT_int_ParseEscape(tVTerm *Term, const char *Buffer, size_t Bytes)
 {
        char    c;
-        int    argc = 0, j = 1;
+        int    argc = 0, j = 0;
         int    args[6] = {0,0,0,0};
         int    bQuestionMark = 0;
-       
-       switch(Buffer[0])
+
+       if( Bytes == j )        return j;
+       c = Buffer[j++];
+
+       switch(c)
        {
        //Large Code
        case '[':
                // Get Arguments
+               if(Bytes == j)  return j;
                c = Buffer[j++];
                if(c == '?') {
                        bQuestionMark = 1;
+                       if(Bytes == j)  return j;
                        c = Buffer[j++];
                }
                if( '0' <= c && c <= '9' )
                {
                        do {
-                               if(c == ';')    c = Buffer[j++];
+                               if(c == ';') {
+                                       if(Bytes == j)  return j;
+                                       c = Buffer[j++];
+                               }
                                while('0' <= c && c <= '9') {
                                        args[argc] *= 10;
                                        args[argc] += c-'0';
+                                       if(Bytes == j)  return j;
                                        c = Buffer[j++];
                                }
                                argc ++;
@@ -242,51 +251,64 @@ int VT_int_ParseEscape(tVTerm *Term, const char *Buffer)
                }
                
                // Get Command
-               if( ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
+               if( !('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z') )
                {
-                       if( bQuestionMark )
+                       // Error
+                       return j;
+               }
+               
+               if( bQuestionMark )
+               {
+                       switch(c)
                        {
-                               switch(c)
+                       // DEC Private Mode Set
+                       case 'h':
+                               if(argc != 1)   break;
+                               switch(args[0])
                                {
-                               // DEC Private Mode Set
-                               case 'h':
-                                       if(argc != 1)   break;
-                                       switch(args[0])
-                                       {
-                                       case 25:
-                                               Term->Flags &= ~VT_FLAG_HIDECSR;
-                                               break;
-                                       case 1047:
-                                               VT_int_ToggleAltBuffer(Term, 1);
-                                               break;
-                                       }
+                               case 25:
+                                       Term->Flags &= ~VT_FLAG_HIDECSR;
+                                       break;
+                               case 1047:
+                                       VT_int_ToggleAltBuffer(Term, 1);
                                        break;
-                               case 'l':
-                                       if(argc != 1)   break;
-                                       switch(args[0])
-                                       {
-                                       case 25:
-                                               Term->Flags |= VT_FLAG_HIDECSR;
-                                               break;
-                                       case 1047:
-                                               VT_int_ToggleAltBuffer(Term, 0);
-                                               break;
-                                       }
+                               }
+                               break;
+                       case 'l':
+                               if(argc != 1)   break;
+                               switch(args[0])
+                               {
+                               case 25:
+                                       Term->Flags |= VT_FLAG_HIDECSR;
                                        break;
-                               default:
-                                       Log_Warning("VTerm", "Unknown control sequence '\\x1B[?%c'", c);
+                               case 1047:
+                                       VT_int_ToggleAltBuffer(Term, 0);
                                        break;
                                }
+                               break;
+                       default:
+                               Log_Warning("VTerm", "Unknown control sequence '\\x1B[?%c'", c);
+                               break;
                        }
-                       else
-                       {
-                               VT_int_ParseEscape_StandardLarge(Term, c, argc, args);
-                       }
+               }
+               else
+               {
+                       VT_int_ParseEscape_StandardLarge(Term, c, argc, args);
                }
                break;
-               
+       case '\0':
+               // Ignore \0
+               break;
        default:
-               Log_Notice("VTerm", "TODO: Handle short escape codes");
+               //Log_Notice("VTerm", "TODO: Handle short escape codes");
+               {
+                       static volatile int tmp = 0;
+                       if(tmp == 0) {
+                               tmp = 1;
+                               Debug("VTerm: Unknown short 0x%x", c);
+                               tmp = 0;
+                       }
+               }
                break;
        }
        
index 24148e1..e8ca0d3 100644 (file)
@@ -378,6 +378,10 @@ extern int strpos(const char *Str, char Ch);
 extern int     strpos8(const char *str, Uint32 search);
 extern void    itoa(char *buf, Uint64 num, int base, int minLength, char pad);
 extern int     atoi(const char *string);
+extern unsigned long long      strtoull(const char *str, char **end, int base);
+extern unsigned long   strtoul(const char *str, char **end, int base);
+extern signed long long        strtoll(const char *str, char **end, int base);
+extern signed long     strtol(const char *str, char **end, int base);
 extern int     ParseInt(const char *string, int *Val);
 extern int     ReadUTF8(const Uint8 *str, Uint32 *Val);
 extern int     WriteUTF8(Uint8 *str, Uint32 Val);
index dc9d654..17143e8 100644 (file)
@@ -25,6 +25,8 @@
 //! General purpose event for short waits
 //! e.g. waiting for an IRQ in a Read() call
 #define THREAD_EVENT_SHORTWAIT 0x00000010
+//! Fired when a child process quits
+#define THREAD_EVENT_DEADCHILD 0x00000020
 
 #define THREAD_EVENT_USER1     0x10000000
 #define THREAD_EVENT_USER2     0x20000000
index 6af177d..876aa78 100644 (file)
@@ -9,5 +9,6 @@ extern void     Arch_LoadBootModules(void);
 extern void    StartupPrint(const char *String);
 extern void    System_Init(char *Commandline);
 extern void    Threads_Init(void);
+extern void    Heap_Install(void);
 
 #endif
index 578fdcf..4845264 100644 (file)
@@ -71,7 +71,10 @@ struct sThread
        struct sProcess *Process;       //!< Thread Group / Process
        struct sThread  *Parent;        //!< Parent Thread
        char    *ThreadName;    //!< Name of thread
-       
+
+       struct sThread  *LastDeadChild; //!< Last child to die (will have the \a DeadChildren lock)
+       tMutex  DeadChildLock;  //!< Lock to prevent clobbering of \a LastDeadChild, acquired by child, released by parent
+
        // --- arch/proc.c's responsibility
        //! Kernel Stack Base
        tVAddr  KernelStack;
index 58c2e1a..a16687e 100644 (file)
 #define        RANDOM_SPRUCE   0xf12b039
 
 // === PROTOTYPES ===
+#if 0
 unsigned long long     strtoull(const char *str, char **end, int base);
 unsigned long  strtoul(const char *str, char **end, int base);
 signed long long       strtoll(const char *str, char **end, int base);
 signed long    strtol(const char *str, char **end, int base);
-#if 0
  int   atoi(const char *string);
  int   ParseInt(const char *string, int *Val);
 void   itoa(char *buf, Uint64 num, int base, int minLength, char pad);
index 8237423..b9d7a6f 100644 (file)
@@ -88,10 +88,11 @@ int Proc_GetMessage(Uint *Source, Uint BufSize, void *Buffer)
        void    *tmp;
        tThread *cur = Proc_GetCurThread();
 
-       ENTER("pSource pBuffer", Source, Buffer);
+       ENTER("pSource xBufSize pBuffer", Source, BufSize, Buffer);
        
        // Check if queue has any items
        if(!cur->Messages) {
+               LOG("empty queue");
                LEAVE('i', 0);
                return 0;
        }
index 1f2f798..635f69a 100644 (file)
@@ -29,8 +29,8 @@
 #define CHECK_STR_ARRAY(arr)   do {\
         int    i;\
        char    **tmp = (char**)arr; \
-       CHECK_NUM_NONULL( tmp, sizeof(char**) ); \
-       for(i=0;tmp[i];i++) { \
+       CHECK_NUM_NULLOK( tmp, sizeof(char**) ); \
+       for(i=0;tmp&&tmp[i];i++) { \
                CHECK_STR_NONULL( tmp[i] ); \
                CHECK_NUM_NONULL( &tmp[i+1], sizeof(char*) ); \
        }\
@@ -172,7 +172,8 @@ void SyscallHandler(tSyscallRegs *Regs)
                CHECK_STR_NONULL((const char*)Regs->Arg1);
                CHECK_STR_ARRAY((const char**)Regs->Arg2);
                CHECK_STR_ARRAY((const char**)Regs->Arg3);
-               CHECK_NUM_NULLOK((void*)Regs->Arg5, Regs->Arg4*sizeof(int));
+               if( Regs->Arg4 > 0 )
+                       CHECK_NUM_NONULL((void*)Regs->Arg5, Regs->Arg4*sizeof(int));
                ret = Proc_SysSpawn(
                        (const char*)Regs->Arg1, (const char**)Regs->Arg2, (const char**)Regs->Arg3,
                        Regs->Arg4, (int*)Regs->Arg5
index 9224db5..7938723 100644 (file)
@@ -48,6 +48,8 @@ void System_Init(char *CommandLine)
        if(Proc_Clone(CLONE_VM|CLONE_NOUSER) == 0)
        {
                const char      *args[] = {gsInitBinary, 0};
+               VFS_Open("/Devices/VTerm/0", VFS_OPENFLAG_READ|VFS_OPENFLAG_USER);      // 0: stdin
+               VFS_Open("/Devices/VTerm/0", VFS_OPENFLAG_WRITE|VFS_OPENFLAG_USER);     // 1: stdout
                Proc_Execve(gsInitBinary, args, &args[1], 0);
                Log_KernelPanic("System", "Unable to spawn init '%s'", gsInitBinary);
        }
index 92a7a57..a86eba0 100644 (file)
@@ -11,6 +11,7 @@
 #include <hal_proc.h>
 #include <semaphore.h>
 #include <vfs_threads.h>       // VFS Handle maintainence
+#include <events.h>
 
 // Configuration
 #define DEBUG_TRACE_TICKETS    0       // Trace ticket counts
@@ -442,9 +443,30 @@ tThread *Threads_CloneThreadZero(void)
 tTID Threads_WaitTID(int TID, int *Status)
 {      
        // Any Child
-       if(TID == -1) {
-               Log_Error("Threads", "TODO: Threads_WaitTID(TID=-1) - Any Child");
-               return -1;
+       if(TID == -1)
+       {
+               Uint32 ev = Threads_WaitEvents(THREAD_EVENT_DEADCHILD);
+               tTID    ret = -1;
+               if( ev & THREAD_EVENT_DEADCHILD )
+               {
+                       // A child died, get the TID
+                       tThread *us = Proc_GetCurThread();
+                       ASSERT(us->LastDeadChild);
+                       ret = us->LastDeadChild->TID;
+                       // - Mark as dead (as opposed to undead)
+                       ASSERT(us->LastDeadChild->Status == THREAD_STAT_ZOMBIE);
+                       us->LastDeadChild->Status = THREAD_STAT_DEAD;
+                       // - Set return status
+                       if(Status)
+                               *Status = us->LastDeadChild->RetStatus;
+                       us->LastDeadChild = NULL;
+                       Mutex_Release(&us->DeadChildLock);
+               }
+               else
+               {
+                       Log_Error("Threads", "TODO: Threads_WaitTID(TID=-1) - Any Child");
+               }
+               return ret;
        }
        
        // Any peer/child thread
@@ -460,33 +482,14 @@ tTID Threads_WaitTID(int TID, int *Status)
        }
        
        // Specific Thread
-       if(TID > 0) {
-               tThread *t = Threads_GetThread(TID);
+       if(TID > 0)
+       {
                tTID    ret;
-               
-               // Wait for the thread to die!
-               // TODO: Handle child also being suspended if wanted
-               while(t->Status != THREAD_STAT_ZOMBIE) {
-                       Threads_Sleep();
-                       Log_Debug("Threads", "%i waiting for %i, t->Status = %i",
-                               Threads_GetTID(), t->TID, t->Status);
-               }
-               
-               // Set return status
-               ret = t->TID;
-               switch(t->Status)
+               // NOTE: Race condition - Other child dies, desired child dies, first death is 'lost'
+               while( (ret = Threads_WaitTID(-1, Status)) != TID )
                {
-               case THREAD_STAT_ZOMBIE:
-                       // Kill the thread
-                       t->Status = THREAD_STAT_DEAD;
-                       // TODO: Child return value?
-                       if(Status)      *Status = t->RetStatus;
-                       // add to delete queue
-                       Threads_Delete( t );
-                       break;
-               default:
-                       if(Status)      *Status = -1;
-                       break;
+                       if( ret == -1 )
+                               break;
                }
                return ret;
        }
@@ -685,8 +688,10 @@ void Threads_Kill(tThread *Thread, int Status)
 
        Thread->Status = THREAD_STAT_ZOMBIE;
        SHORTREL( &glThreadListLock );
-       // TODO: Send something like SIGCHLD
-       Threads_Wake( Thread->Parent );
+       // TODO: It's possible that we could be timer-preempted here, should disable that... somehow
+       Mutex_Acquire( &Thread->Parent->DeadChildLock );        // released by parent
+       Thread->Parent->LastDeadChild = Thread;
+       Threads_PostEvent( Thread->Parent, THREAD_EVENT_DEADCHILD );
        
        Log("Thread %i went *hurk* (%i)", Thread->TID, Status);
        
index 88877ab..cb4fae1 100644 (file)
@@ -19,6 +19,7 @@
 #if 0
 tVFS_Handle    *VFS_GetHandle(int FD);
 #endif
+inline void    _ReferenceNode(tVFS_Node *Node);
  int   VFS_AllocHandle(int FD, tVFS_Node *Node, int Mode);
 
 // === GLOBALS ===
@@ -195,7 +196,14 @@ void *VFS_SaveHandles(int NumFDs, int *FDs)
                tVFS_Handle     *h;
                if( FDs == NULL )
                        h = &gaUserHandles[i];
-               else {
+               else if( FDs[i] == -1 )
+               {
+                       Log_Warning("VFS", "VFS_SaveHandles - Slot %i error FD (-1), ignorning", i);
+                       memset(&ret[i], 0, sizeof(tVFS_Handle));
+                       continue ;
+               }
+               else
+               {
                        h = VFS_GetHandle(FDs[i] & (VFS_KERNEL_FLAG - 1));
                        if(!h) {
                                Log_Warning("VFS", "VFS_SaveHandles - Invalid FD %i",
index 412cb1a..8bd0deb 100644 (file)
@@ -129,8 +129,8 @@ int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set
        tThread *thisthread = Proc_GetCurThread();
         int    ret;
        
-       ENTER("iMaxHandle pReadHandles pWriteHandles pErrHandles pTimeout bIsKernel",
-               MaxHandle, ReadHandles, WriteHandles, ErrHandles, Timeout, IsKernel);
+       ENTER("iMaxHandle pReadHandles pWriteHandles pErrHandles pTimeout xExtraEvents bIsKernel",
+               MaxHandle, ReadHandles, WriteHandles, ErrHandles, Timeout, ExtraEvents, IsKernel);
        
        // Notes: The idea is to make sure we only enter wait (Threads_WaitEvents)
        // if we are going to be woken up (either by an event at a later time,
@@ -140,6 +140,8 @@ int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set
        // or the semaphore is incremeneted (or both, but never none)
        
        // Register with nodes
+       if( ReadHandles )
+               LOG(" - ReadHandles[0] = %x", ReadHandles->flags[0]);
        ret  = VFS_int_Select_Register(thisthread, MaxHandle, ReadHandles, 0, IsKernel);
        ret += VFS_int_Select_Register(thisthread, MaxHandle, WriteHandles, 1, IsKernel);
        ret += VFS_int_Select_Register(thisthread, MaxHandle, ErrHandles, 2, IsKernel);
@@ -149,9 +151,11 @@ int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set
        // If there were events waiting, de-register and return
        if( ret > 0 )
        {
+               LOG(" - ReadHandles[0] = %x", ReadHandles->flags[0]);
                ret  = VFS_int_Select_Deregister(thisthread, MaxHandle, ReadHandles, 0, IsKernel);
                ret += VFS_int_Select_Deregister(thisthread, MaxHandle, WriteHandles, 1, IsKernel);
                ret += VFS_int_Select_Deregister(thisthread, MaxHandle, ErrHandles, 2, IsKernel);
+               LOG(" - ReadHandles[0] = %x", ReadHandles->flags[0]);
                LEAVE('i', ret);
                return ret;
        }
@@ -306,8 +310,10 @@ int VFS_int_Select_Register(tThread *Thread, int MaxHandle, fd_set *Handles, int
                }
                
                // Check for the flag
-               if( !!*flag == !!wantedFlagValue )
+               if( !!*flag == !!wantedFlagValue ) {
+                       LOG(" %i == want %i", !!*flag, !!wantedFlagValue);
                        numFlagged ++;
+               }
        }
        
        LEAVE('i', numFlagged);
@@ -348,8 +354,6 @@ int VFS_int_Select_Deregister(tThread *Thread, int MaxHandle, fd_set *Handles, i
                        continue;
                }
        
-               // Get the type of the listen
-       
                // Get the type of the listen
                if( VFS_int_Select_GetType(Type, handle->Node, &list, &flag, &wantedFlagValue, NULL) ) {
                        LEAVE('i', 0);
@@ -362,6 +366,8 @@ int VFS_int_Select_Deregister(tThread *Thread, int MaxHandle, fd_set *Handles, i
                // Check for the flag
                if( !!*flag == !!wantedFlagValue ) {
                        numFlagged ++;
+                       LOG(" %i == want %i", !!*flag, !!wantedFlagValue);
+                       FD_SET(i, Handles);
                }
                else {
                        FD_CLR(i, Handles);
index 5988ee7..50e76d3 100644 (file)
@@ -82,6 +82,7 @@ Uint  *gBGA_Framebuffer;
 const tBGA_Mode        *gpBGA_CurrentMode;\r
 const tBGA_Mode        gBGA_Modes[] = {\r
        {640,480,32, 640*480*4},\r
+       {800,480,32, 800*480*4},        // Nice mode for VM testing\r
        {800,600,32, 800*600*4},\r
        {1024,768,32, 1024*768*4}\r
 };\r
diff --git a/KernelLand/Modules/Display/RPi/main.c b/KernelLand/Modules/Display/RPi/main.c
new file mode 100644 (file)
index 0000000..a0df903
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * Acess2 Raspberry Pi (BCM2835)
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Driver core
+ *
+ * http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/os/screen01.html
+ */
+#define DEBUG  0
+#define VERSION        ((0<<8)|1)
+#include <acess.h>
+#include <errno.h>
+#include <modules.h>
+#include <vfs.h>
+#include <fs_devfs.h>
+#include <drv_pci.h>
+#include <api_drv_video.h>
+
+// === PROTOCOLS ===
+ int   RPiVid_Install(const char **Arguments);
+// - GPU Communication
+ int   RPiVid_int_MBoxCheck(Uint8 Box);
+Uint32 RPiVid_int_MBoxRecv(Uint8 Box);
+void   RPiVid_int_MBoxSend(Uint8 Box, Uint32 Message);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, VERSION, RPiVid, RPiVid_Install, NULL, NULL);
+
+// === CODE ===
+int RPiVid_Install(const char **Arguments)
+{
+       return 0;
+}
+
+
+// --- GPU Comms ---
+int RPiVid_int_MBoxCheck(Uint8 Box)
+{
+       return 0;
+}
+
+Uint32 RPiVid_int_MBoxRecv(Uint8 Box)
+{
+       Uint32  val;
+       do {
+               while( gRPiVid_Mbox->Status & (1 << 30) )
+                       ;
+               val = gRPiVid_Mbox->Read;
+       } while( (val & 0xF) != Box );
+       
+       return 0;
+}
+
+void RPiVid_int_MBoxSend(Uint8 Box, Uint32 Message)
+{
+       while( gRPiVid_Mbox.Status & (1 << 31) )
+               ;
+       gRPiVid_Mbox.Write = (Message << 4) | (Box & 0xF);
+}
+
index e19a5ff..34b58f1 100644 (file)
@@ -59,6 +59,7 @@ size_t        giTegra2Vid_FramebufferSize;
 Uint32 *gpTegra2Vid_IOMem;
 tPAddr gTegra2Vid_FramebufferPhys;
 void   *gpTegra2Vid_Framebuffer;
+void   *gpTegra2Vid_Cursor;
 // -- Misc
 tDrvUtil_Video_BufInfo gTegra2Vid_DrvUtil_BufInfo;
 tVideo_IOCtl_Pos       gTegra2Vid_CursorPos;
@@ -69,6 +70,24 @@ inline void _dumpreg(int i)
        Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x (%s)", i, gpTegra2Vid_IOMem[i],
                (csaTegra2Vid_RegisterNames[i] ? csaTegra2Vid_RegisterNames[i] : "-"));
 }
+
+void Tegra2Vid_int_DumpRegisters(void)
+{
+       Log_Debug("Tegra2Vid", "Display CMD Registers");
+       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 ++ )  _dumpreg(i);
+       Log_Debug("Tegra2Vid", "Display DISP Registers");
+       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 ++ )  _dumpreg(i);
+       Log_Debug("Tegra2Vid", "WINBUF_A");
+       for( int i = 0x800; i <= 0x80A; i ++ )  _dumpreg(i);
+}
+
 /**
  */
 int Tegra2Vid_Install(char **Arguments)
@@ -77,22 +96,9 @@ int Tegra2Vid_Install(char **Arguments)
 //     KeyVal_Parse(&gTegra2Vid_KeyValueParser, Arguments);
 
        gpTegra2Vid_IOMem = (void*)MM_MapHWPages(gTegra2Vid_PhysBase, 256/4);
+
        #if DUMP_REGISTERS
-       {
-               Log_Debug("Tegra2Vid", "Display CMD Registers");
-               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 ++ )  _dumpreg(i);
-               Log_Debug("Tegra2Vid", "Display DISP Registers");
-               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 ++ )  _dumpreg(i);
-               Log_Debug("Tegra2Vid", "WINBUF_A");
-               for( int i = 0x800; i <= 0x80A; i ++ )  _dumpreg(i);
-       }
+       Tegra2Vid_int_DumpRegisters();
        #endif
 
        // HACK!!!
@@ -105,6 +111,7 @@ int Tegra2Vid_Install(char **Arguments)
        }
 #endif
 
+#if 0
        giTegra2Vid_FramebufferSize =
                (gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0]&0xFFFF)
                *(gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0]>>16)*4;
@@ -114,7 +121,9 @@ int Tegra2Vid_Install(char **Arguments)
                gpTegra2Vid_IOMem[DC_WINBUF_A_START_ADDR_0],
                (giTegra2Vid_FramebufferSize+PAGE_SIZE-1)/PAGE_SIZE
                );
-       memset(gpTegra2Vid_Framebuffer, 0xFF, 0x1000);
+       Log_Debug("Tegra2Vid", "gpTegra2Vid_Framebuffer = %p", gpTegra2Vid_Framebuffer);
+       memset(gpTegra2Vid_Framebuffer, 0xFF, giTegra2Vid_FramebufferSize);
+#endif
 
 #if 0
        gpTegra2Vid_IOMem[DC_WIN_A_WIN_OPTIONS_0] = (1 << 30);
@@ -126,7 +135,8 @@ int Tegra2Vid_Install(char **Arguments)
        gTegra2Vid_DrvUtil_BufInfo.Depth = 32;
        gTegra2Vid_DrvUtil_BufInfo.Width = 1680;
        gTegra2Vid_DrvUtil_BufInfo.Height = 1050;
-#else
+       gpTegra2Vid_IOMem[DC_CMD_STATE_CONTROL_0] = WIN_A_ACT_REQ;
+#elif 0
        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;
@@ -134,11 +144,12 @@ int Tegra2Vid_Install(char **Arguments)
        gTegra2Vid_DrvUtil_BufInfo.Width = 1024;
        gTegra2Vid_DrvUtil_BufInfo.Height = 768;
        gTegra2Vid_DrvUtil_BufInfo.Framebuffer = gpTegra2Vid_Framebuffer;
-#endif
        gpTegra2Vid_IOMem[DC_CMD_STATE_CONTROL_0] = WIN_A_ACT_REQ;
+#endif
 
+       gpTegra2Vid_Cursor = (void*)MM_AllocDMA(1, 26, NULL);
 
-//     Tegra2Vid_int_SetMode(4);
+       Tegra2Vid_int_SetMode(0);
 
        DevFS_AddDevice( &gTegra2Vid_DriverStruct );
 
@@ -225,8 +236,11 @@ int Tegra2Vid_IOCtl(tVFS_Node *Node, int ID, void *Data)
                        LEAVE_RET('i', 0);
 
                // DEBUG!!!
-               mode->width = 1024;
-               mode->height = 768;
+               mode->id = 1;   mode->width = 1680;     mode->height = 1050;
+               mode->id = 0;   mode->width = 1024;     mode->height = 768;
+
+               // DEBUG!
+               for( int i = 0x800; i <= 0x80A; i ++ )  _dumpreg(i);
                break;
 
                ret = 0;
@@ -234,7 +248,8 @@ int Tegra2Vid_IOCtl(tVFS_Node *Node, int ID, void *Data)
                for( int i = 0; i < ciTegra2Vid_ModeCount; i ++ )
                {
                         int    area;
-                       if(mode->width == caTegra2Vid_Modes[i].W && mode->height == caTegra2Vid_Modes[i].H) {
+                       if(mode->width == caTegra2Vid_Modes[i].W
+                       && mode->height == caTegra2Vid_Modes[i].H) {
                                mode->id = i;
                                ret = 1;
                                break;
@@ -287,6 +302,8 @@ int Tegra2Vid_IOCtl(tVFS_Node *Node, int ID, void *Data)
                DrvUtil_Video_RemoveCursor( &gTegra2Vid_DrvUtil_BufInfo );
                
                gTegra2Vid_CursorPos = *(tVideo_IOCtl_Pos*)Data;
+               // TODO: Set DC_DISP_CURSOR_POSITION_0
+               // TODO: Set DC_DISP_CURSOR_FOREGROUND_0 etc from image?
                if(gTegra2Vid_DrvUtil_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT)
                        DrvUtil_Video_DrawCursor(
                                &gTegra2Vid_DrvUtil_BufInfo,
@@ -318,16 +335,21 @@ int Tegra2Vid_int_SetMode(int Mode)
 {
        const struct sTegra2_Disp_Mode  *mode = &caTegra2Vid_Modes[Mode];
         int    w = mode->W, h = mode->H;       // Horizontal/Vertical Active
-       gpTegra2Vid_IOMem[DC_DISP_FRONT_PORCH_0] = (mode->VFP << 16) | mode->HFP; 
+       gpTegra2Vid_IOMem[DC_DISP_REF_TO_SYNC_0] = (1 << 16) | 11;      // TODO: <--
        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_DISP_FRONT_PORCH_0] = (mode->VFP << 16) | mode->HFP; 
 
+       gpTegra2Vid_IOMem[DC_DISP_DISP_COLOR_CONTROL_0] = 0x8;  // BASE888 - TODO: useful?
        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;
+       gpTegra2Vid_IOMem[DC_WIN_A_LINE_STRIDE_0] = w * 4;
+       gpTegra2Vid_IOMem[DC_WIN_A_DV_CONTROL_0] = 0;
+       
+       gpTegra2Vid_IOMem[DC_DISP_BORDER_COLOR_0] = 0x70F010;
 
        Log_Debug("Tegra2Vid", "Mode %i (%ix%i) selected", Mode, w, h);
 
@@ -340,13 +362,17 @@ int Tegra2Vid_int_SetMode(int Mode)
 
                giTegra2Vid_FramebufferSize = w*h*4;            
 
-               // TODO: Does this need RAM or unmapped space?
+               // Uses RAM I think
                gpTegra2Vid_Framebuffer = (void*)MM_AllocDMA(
                        (giTegra2Vid_FramebufferSize + PAGE_SIZE-1) / PAGE_SIZE,
                        32,
                        &gTegra2Vid_FramebufferPhys
                        );
-               // TODO: Catch allocation failures
+               if( !gpTegra2Vid_Framebuffer ) {
+                       Log_Error("Tegra2Vid", "Can't allocate pages for 0x%x byte framebuffer",
+                               giTegra2Vid_FramebufferSize);
+                       return -1;
+               }
                Log_Debug("Tegra2Vid", "0x%x byte framebuffer at %p (%P phys)",
                                giTegra2Vid_FramebufferSize,
                                gpTegra2Vid_Framebuffer,
@@ -360,6 +386,10 @@ int Tegra2Vid_int_SetMode(int Mode)
        }
 
        gpTegra2Vid_IOMem[DC_CMD_STATE_CONTROL_0] = WIN_A_ACT_REQ;
+       gpTegra2Vid_IOMem[DC_CMD_STATE_CONTROL_0] = GEN_ACT_REQ;
+       
+       // DEBUG!
+       for( int i = 0x800; i <= 0x80A; i ++ )  _dumpreg(i);
        
        return 0;
 }
index 7e3fdf5..9b33668 100644 (file)
@@ -19,6 +19,7 @@ const struct sTegra2_Disp_Mode
 }      caTegra2Vid_Modes[] = {
        // TODO: VESA timings
        {1024, 768,  58, 4,   58,  4,   58,   4},       // 1024x768 (reset), RtS=11,4
+       {1680,1050, 104, 1,  184,  3 , 288,  33},       // 1680x1050 @ 60Hz
        // 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)
@@ -160,6 +161,7 @@ enum eTegra2_Disp_Regs
        DC_WIN_A_DDA_INCREMENT_0,
        DC_WIN_A_LINE_STRIDE_0,
        DC_WIN_A_BUF_STRIDE_0,
+       _DC_WIN_A_70C,
        DC_WIN_A_BUFFER_ADDR_MODE_0,
        DC_WIN_A_DV_CONTROL_0,
        DC_WIN_A_BLEND_NOKEY_0,
@@ -337,6 +339,7 @@ const char * const csaTegra2Vid_RegisterNames[] = {
        "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",
index 5aa0e65..5758f99 100644 (file)
@@ -13,4 +13,8 @@ LDFLAGS += @files.$(ARCH).c.ldopts
 files.$(ARCH).c: GenerateInitRD.php files.lst
        ARCH=$(ARCH) ACESSDIR=$(ACESSDIR) php GenerateInitRD.php files.lst $@ [email protected] [email protected]
 
+# Override default install method, because the floppy is small :)
+install:
+       true
+
 -include files.$(ARCH).c.dep
index ccbbe0c..5b17070 100644 (file)
@@ -13,6 +13,7 @@ Dir "Bin" {
        File "ping" "__BIN__/Bin/ping"
        File "telnet" "__BIN__/Bin/telnet"
        File "irc" "__BIN__/Bin/irc"
+       File "bomb" "__BIN__/Bin/bomb"
        File "dhcpc" "__BIN__/SBin/dhcpc"
 }
 Dir "Libs" {
@@ -26,9 +27,10 @@ Dir "Libs" {
        File "libaxwin3.so" "__BIN__/Libs/libaxwin3.so"
        File "libposix.so" "__BIN__/Libs/libposix.so"
        File "libpsocket.so" "__BIN__/Libs/libpsocket.so"
+       File "libunicode.so" "__BIN__/Libs/libunicode.so"
 }
 Dir "Conf" {
-       File "BootConf.cfg" "__FS__/Conf/BootConf.cfg"
+       File "inittab" "__FS__/Conf/inittab"
 }
 Dir "Apps" {
        Dir "AxWin" {
@@ -36,6 +38,7 @@ Dir "Apps" {
                        File "AxWinWM" "__BIN__/Apps/AxWin/3.0/AxWinWM"
                        File "AxWinUI" "__BIN__/Apps/AxWin/3.0/AxWinUI"
                        File "ate" "__BIN__/Apps/AxWin/3.0/ate"
+                       File "terminal" "__BIN__/Apps/AxWin/3.0/terminal"
                        File "AcessLogoSmall.sif" "__SRC__/Usermode/Applications/axwin3_src/AcessLogoSmall.sif"
                }
        }
index 1d80569..ae3806b 100644 (file)
@@ -268,7 +268,7 @@ size_t UDP_Channel_Write(tVFS_Node *Node, off_t Offset, size_t Length, const voi
 
        UDP_SendPacketTo(chan, ep->AddrType, &ep->Addr, ep->Port, data, (size_t)Length - ofs);
        
-       return 0;
+       return Length;
 }
 
 /**
index f9f4d25..9bdbafb 100644 (file)
@@ -80,11 +80,9 @@ int Rhine2_Install(char **Options)
 {
         int    id = -1;
         int    i = 0;
-//     Uint16  base;
        tCard   *card;
        
        giRhine2_CardCount = PCI_CountDevices(VENDOR_ID, DEVICE_ID);
-       Log_Debug("Rhine2", "giRhine2_CardCount = %i", giRhine2_CardCount);
        if( giRhine2_CardCount == 0 )   return MODULE_ERR_NOTNEEDED;
        
        gaRhine2_Cards = calloc( giRhine2_CardCount, sizeof(tCard) );
index f6290d9..90cff7f 100644 (file)
@@ -115,7 +115,7 @@ int FDD_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        if(Pos < 0 || Pos > MAX_DISKS )
                return -ENOENT;
-       if(gaFDD_Disks[Pos].bValid)
+       if(!gaFDD_Disks[Pos].bValid)
                return 1;
        
        Dest[0] = '0' + Pos;
index 2dd8610..a2acca2 100644 (file)
@@ -94,9 +94,32 @@ int EHCI_Initialise(char **Arguments)
                        // TODO: Detect other forms of failure than "out of slots"
                        break ;
                }
+       }
 
-               // TODO: Register with the USB stack
+       for( int i = 0; Arguments[i]; i ++ )
+       {
+               char *pos = Arguments[i], *next;
+               LOG("pos = '%s'", pos);
+               tPAddr base = strtoull(pos, &next, 16);
+               if( base == 0 )
+                       continue;
+               pos = next;
+               LOG("pos = '%s'", pos);
+               if( *pos++ != '-' )
+                       continue;
+               LOG("pos = '%s'", pos);
+               int irq = strtol(pos, &next, 16);
+               if( irq == 0 )
+                       continue ;
+               if( *next != 0 )
+                       continue;
+               LOG("base=%x, irq=%i", base, irq);
+               if( EHCI_InitController(base, irq) )
+               {
+                       continue ;
+               }
        }
+
        return 0;
 }
 
@@ -137,7 +160,8 @@ int EHCI_InitController(tPAddr BaseAddress, Uint8 InterruptNum)
        }
        // TODO: Error check
        if( (cont->CapRegs->CapLength & 3) ) {
-               Log_Warning("EHCI", "Controller at %P non-aligned op regs", BaseAddress);
+               Log_Warning("EHCI", "Controller at %P non-aligned op regs (%x)",
+                       BaseAddress, cont->CapRegs->CapLength);
                goto _error;
        }
        cont->OpRegs = (void*)( (Uint32*)cont->CapRegs + cont->CapRegs->CapLength / 4 );
index 8dbab3a..6544179 100644 (file)
@@ -16,6 +16,8 @@
 
 // === IMPORTS ===
 extern void    *gpIRQHandler;
+extern tPAddr  gGIC_DistributorAddr;
+extern tPAddr  gGIC_InterfaceAddr;
 
 // === TYPES ===
 typedef void (*tIRQ_Handler)(int, void*);
@@ -28,18 +30,12 @@ void        GIC_IRQHandler(void);
 MODULE_DEFINE(0, 0x100, armv7_GIC, GIC_Install, NULL, NULL);
 Uint32 *gpGIC_DistributorBase;
 Uint32 *gpGIC_InterfaceBase;
-tPAddr gGIC_DistributorAddr;
-tPAddr gGIC_InterfaceAddr;
 tIRQ_Handler   gaIRQ_Handlers[N_IRQS];
 void   *gaIRQ_HandlerData[N_IRQS];
 
 // === CODE ===
 int GIC_Install(char **Arguments)
 {
-       // Realview PB
-       gGIC_InterfaceAddr   = 0x1e000000;
-       gGIC_DistributorAddr = 0x1e001000;
-
        // Initialise
        gpGIC_InterfaceBase = (void*)MM_MapHWPages(gGIC_InterfaceAddr, 1);
        LOG("gpGIC_InterfaceBase = %p", gpGIC_InterfaceBase);
index 32f1ffb..c2ef59f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -12,12 +12,12 @@ SUBMAKE = $(MAKE) --no-print-directory
 
 USRLIBS := crt0.o acess.ld ld-acess.so libc.so libposix.so
 USRLIBS += libreadline.so libnet.so liburi.so libpsocket.so
-USRLIBS += libimage_sif.so
+USRLIBS += libimage_sif.so libunicode.so
 
 USRAPPS := init login CLIShell cat ls mount
 USRAPPS += bomb lspci
 USRAPPS += ip dhcpclient ping telnet irc wget telnetd
-USRAPPS += axwin3 gui_ate
+USRAPPS += axwin3 gui_ate gui_shell
 
 ALL_DYNMODS = $(addprefix all-,$(DYNMODS))
 ALL_MODULES := $(addprefix all-,$(MODULES))
diff --git a/Notes/3D.txt b/Notes/3D.txt
new file mode 100644 (file)
index 0000000..a530e3c
--- /dev/null
@@ -0,0 +1,8 @@
+GL control channel:
+  App -> GUI -> VTerm -> Driver
+- App creates 3D window
+- GUI passes X,Y WxH to VTerm (and can issue resize notices upwards)
+- VTerm passes to driver (and can disable display of local regions when VT switch)
+
+Allocates command ring buffer for libgl
+
index a3183d3..477c476 100755 (executable)
@@ -55,6 +55,16 @@ while [[ $# -gt 0 ]]; do
        -l*|-L*)
                _libs=$_libs" $1"
                ;;
+       -v|--version|-V)
+               _verarg=$_verarg" $1"
+               ;;
+       --inv=ld)
+               _actas=ld
+               ;;
+       -print-prog-name=ld)
+               echo $0 --inv=ld
+               exit 0
+               ;;
        *)
                _miscargs=$_miscargs" $1"
                ;;
@@ -63,7 +73,7 @@ while [[ $# -gt 0 ]]; do
 done
 
 run() {
-#      echo --- $*
+       #echo --- $*
        $*
        return $?
 }
@@ -75,6 +85,11 @@ rm $cfgfile
 
 #echo "_compile = $_compile, _preproc = $_preproc"
 
+if [[ "x$_actas" == "xld" ]]; then
+       run $_LD $LDFLAGS $_ldflags $_outfile $_miscargs $LIBGCC_PATH $_libs
+       exit $?
+fi
+
 if [[ $_preproc -eq 1 ]]; then
        run $_CC -E $CFLAGS $_cflags $_miscargs $_outfile
 elif [[ $_makedep -eq 1 ]]; then
@@ -84,8 +99,10 @@ elif [[ $_compile -eq 1 ]]; then
 elif echo " $_miscargs" | grep '\.c' >/dev/null; then
        tmpout=`mktemp acess_gccproxy.XXXXXXXXXX.o --tmpdir`
        run $_CC $CFLAGS $_cflags $_miscargs -c -o $tmpout
-       run $_LD $LDFLAGS $_ldflags $_libs $tmpout $_outfile -lgcc $_libs
+       run $_LD $LDFLAGS $_ldflags $_libs $tmpout $_outfile $LIBGCC_PATH $_libs
+       _rv=$?
        rm $tmpout
+       exit $_rv
 else
        run $_LD$_ldflags $_miscargs $_outfile $LDFLAGS  $_libs
 fi
index e8b5834..a098614 100644 (file)
@@ -111,14 +111,16 @@ void create_sidebar(void)
 
 void mainmenu_app_textedit(void *unused)
 {
-       const char      *args[] = {"ate",NULL};
 //     _SysDebug("TODO: Launch text editor");
+       const char      *args[] = {"ate",NULL};
        _SysSpawn("/Acess/Apps/AxWin/3.0/ate", args, (const char **)gEnvion, 0, NULL, NULL);
 }
 
 void mainmenu_app_terminal(void *unused)
 {
-       _SysDebug("TODO: Launch terminal emulator");
+       _SysDebug("Launch terminal emulator");
+       const char      *args[] = {"terminal",NULL};
+       _SysSpawn("/Acess/Apps/AxWin/3.0/terminal", args, (const char **)gEnvion, 0, NULL, NULL);
 }
 
 void mainmenu_run_dialog(void *unused)
index 1d67450..1112ffe 100644 (file)
@@ -7,7 +7,7 @@ CFLAGS += -std=gnu99
 
 DIR := Apps/AxWin/3.0
 BIN := AxWinWM
-OBJ := main.o input.o video.o ipc.o image.o utf-8.o
+OBJ := main.o input.o video.o ipc.o image.o
 OBJ += wm.o wm_input.o wm_render.o wm_render_text.o wm_hotkeys.o
 OBJ += decorator.o
 OBJ += renderers/framebuffer.o
@@ -23,7 +23,7 @@ OBJ += renderers/widget/textinput.o
 OBJ += renderers/widget/spacer.o
 OBJ += renderers/widget/subwin.o
 
-LDFLAGS += -limage_sif -luri -lnet
+LDFLAGS += -limage_sif -luri -lnet -lunicode
 
 -include ../../Makefile.tpl
 
diff --git a/Usermode/Applications/axwin3_src/WM/include/utf8.h b/Usermode/Applications/axwin3_src/WM/include/utf8.h
deleted file mode 100644 (file)
index 3ecaeb0..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Acess2 GUI (AxWin) Version 3
- * - By John Hodge (thePowersGang)
- *
- * utf8.h
- * - UTF-8 Parsing header
- */
-#ifndef _UTF8_H_
-#define _UTF8_H_
-
-#include <stdint.h>
-
-extern int     ReadUTF8(const char *Input, uint32_t *Val);
-extern int     ReadUTF8Rev(const char *Base, int Offset, uint32_t *Val);
-extern int     WriteUTF8(char *buf, uint32_t Val);
-
-#endif
-
index 5b600ee..7874335 100644 (file)
@@ -461,8 +461,8 @@ int IPC_Msg_FocusWindow(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
        ASSERT(Msg->ID == IPCMSG_FOCUSWINDOW);
        
        // Don't allow the focus to be changed unless the client has the focus
-       if(!gpWM_FocusedWindow) return 1;
-       if(gpWM_FocusedWindow->Client != Client)        return 1;
+//     if(!gpWM_FocusedWindow) return 1;
+//     if(gpWM_FocusedWindow->Client != Client)        return 1;
 
        win = IPC_int_GetWindow(Client, Msg->Window);
        if(!win)        return 1;
index 7d2d391..9db1c15 100644 (file)
@@ -66,10 +66,12 @@ int main(int argc, char *argv[])
        Renderer_RichText_Init();
        WM_Initialise();
 
-       // TODO: Config
+       // TODO: Move these to config
        uint32_t        keys[4];
        keys[0] = KEYSYM_LEFTGUI;       keys[1] = KEYSYM_r;
        WM_Hotkey_Register(2, keys, "Interface>Run");
+       keys[0] = KEYSYM_LEFTGUI;       keys[1] = KEYSYM_t;
+       WM_Hotkey_Register(2, keys, "Interface>Terminal");
        
        // Spawn interface root
        {
@@ -83,7 +85,7 @@ int main(int argc, char *argv[])
                sprintf(server_info, "AXWIN3_SERVER=%i", server_tid);
                // TODO: Does the client need FDs?
                 int    rv = _SysSpawn(csInterfaceApp, argv, envp, 0, NULL, NULL);
-               if( rv ) {
+               if( rv < 0 ) {
                        _SysDebug("_SysSpawn chucked a sad, rv=%i, errno=%i", rv, _errno);
                }
        }
index fc838cb..68a3f8c 100644 (file)
@@ -16,7 +16,6 @@ typedef struct
 {
        short   W, H;
        void    *Data;
-       char    _data[];
 } tFBBuffer;
 typedef struct
 {
@@ -162,7 +161,7 @@ int _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data)
        buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4);
        buf->W = msg->W;
        buf->H = msg->H;
-       buf->Data = buf->_data;
+       buf->Data = buf + 1;
        
        info->Buffers[msg->Buffer] = buf;
        
index 28be1ae..c62dd7f 100644 (file)
@@ -224,6 +224,27 @@ void Renderer_RichText_Redraw(tWindow *Window)
                Window->W, (info->DispLines-i)*info->LineHeight,
                info->DefaultBG
                );
+
+       // HACK!
+       info->DispCols = Window->W / 8; 
+
+       // TODO: Text cursor
+       _SysDebug("Cursor at %i,%i", info->CursorCol, info->CursorRow);
+       _SysDebug(" Range [%i+%i],[%i+%i]", info->FirstVisRow, info->DispLines, info->FirstVisCol, info->DispCols);
+       if( info->CursorRow >= info->FirstVisRow && info->CursorRow < info->FirstVisRow + info->DispLines )
+       {
+               if( info->CursorCol >= info->FirstVisCol && info->CursorCol < info->FirstVisCol + info->DispCols )
+               {
+                       // TODO: Kill hardcoded 8 with cached text distance
+                       WM_Render_FillRect(Window,
+                               (info->CursorCol - info->FirstVisCol) * 8,
+                               (info->CursorRow - info->FirstVisRow) * info->LineHeight,
+                               1,
+                               info->LineHeight,
+                               info->DefaultFG
+                               );
+               }
+       }
 }
 
 int Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void *Data)
@@ -241,6 +262,10 @@ int Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void
        case _ATTR_DEFFG:
                info->DefaultFG = msg->Value;
                break;
+       case _ATTR_CURSORPOS:
+               info->CursorRow = msg->Value >> 12;
+               info->CursorCol = msg->Value & 0xFFF;
+               break;
        case _ATTR_SCROLL:
                // TODO: Set scroll flag
                break;
@@ -298,7 +323,9 @@ int Renderer_RichText_HandleIPC_WriteLine(tWindow *Window, size_t Len, const voi
        }
        line->ByteLength = Len - sizeof(*msg);
        memcpy(line->Data, msg->LineData, Len - sizeof(*msg));
-       
+
+       WM_Invalidate( Window );
+
        return  0;
 }
 
@@ -312,6 +339,10 @@ int Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const voi
                if(Len < sizeof(*msg))  return -1;
                info->DispLines = msg->H / info->LineHeight;
                return 1; }
+       case WNDMSG_KEYDOWN:
+       case WNDMSG_KEYUP:
+       case WNDMSG_KEYFIRE:
+               return 1;
        }
        return 0;
 }
index 6d34a8e..fc7e107 100644 (file)
@@ -10,7 +10,7 @@
 #include <common.h>
 #include "./common.h"
 #include "./colours.h"
-#include <utf8.h>
+#include <unicode.h>
 #include <string.h>
 
 // TODO: Include a proper keysym header
diff --git a/Usermode/Applications/axwin3_src/WM/utf-8.c b/Usermode/Applications/axwin3_src/WM/utf-8.c
deleted file mode 100644 (file)
index 93e0318..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Acess2 GUI (AxWin) Version 3
- * - By John Hodge (thePowersGang)
- *
- * utf-8.c
- * - UTF-8 Parsing code
- */
-#include <stdint.h>
-#include <utf8.h>
-
-/**
- * \brief Read a UTF-8 character from a string
- * \param Input        Source UTF-8 encoded string
- * \param Val  Destination for read codepoint
- * \return Number of bytes read/used
- */
-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 & 0xF8) == 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;
-}
-
-/**
- * \brief Get the UTF-8 character before the 
- * \
- */
-int ReadUTF8Rev(const char *Base, int Offset, uint32_t *Val)
-{
-        int    len = 0;
-       
-       // Scan backwards for the beginning of the character
-       while( Offset > 0 && (Base[Offset--] & 0xC0) == 0x80 )
-               len ++;
-       // Invalid string (no beginning)
-       if(Offset == 0 && (Base[Offset] & 0xC0) == 0x80 )
-               return len;
-       
-       len ++; // First character
-       if( ReadUTF8(Base+Offset, Val) != len ) {
-               *Val = 0xFFFD;
-       }
-       return len;
-}
-
-/**
- * \brief Write a UTF-8 character sequence to a string
- * \param buf  Destination buffer (must have at least 4 bytes available)
- * \param Val  Unicode codepoint to write
- * \return Number of bytes written
- * \note Does not NULL terminate the string in \a buf
- */
-int WriteUTF8(char *buf, uint32_t Val)
-{
-       uint8_t *str = (void*)buf;
-       
-       // ASCII
-       if( Val < 128 ) {
-               if(str) {
-                       *str = Val;
-               }
-               return 1;
-       }
-       
-       // Two Byte
-       if( Val < 0x8000 ) {
-               if(str) {
-                       *str = 0xC0 | (Val >> 6);
-                       str ++;
-                       *str = 0x80 | (Val & 0x3F);
-               }
-               return 2;
-       }
-       
-       // Three Byte
-       if( Val < 0x10000 ) {
-               if(str) {
-                       *str = 0xE0 | (Val >> 12);
-                       str ++;
-                       *str = 0x80 | ((Val >> 6) & 0x3F);
-                       str ++;
-                       *str = 0x80 | (Val & 0x3F);
-               }
-               return 3;
-       }
-       
-       // Four Byte
-       if( Val < 0x110000 ) {
-               if(str) {
-                       *str = 0xF0 | (Val >> 18);
-                       str ++;
-                       *str = 0x80 | ((Val >> 12) & 0x3F);
-                       str ++;
-                       *str = 0x80 | ((Val >> 6) & 0x3F);
-                       str ++;
-                       *str = 0x80 | (Val & 0x3F);
-               }
-               return 4;
-       }
-       
-       // UTF-8 Doesn't support more than four bytes
-       return 0;
-}
-
index 60f2155..1b9ffab 100644 (file)
@@ -87,7 +87,7 @@ void Video_Update(void)
 
        _SysDebug("Video_Update - Updating lines %i to %i (0x%x+0x%x px)",
                giVideo_FirstDirtyLine, giVideo_LastDirtyLine, ofs, size);
-       _SysSeek(giTerminalFD, ofs*4, 1);
+       _SysSeek(giTerminalFD, ofs*4, SEEK_SET);
        _SysDebug("Video_Update - Sending FD %i %p 0x%x", giTerminalFD, gpScreenBuffer+ofs, size*4);
        _SysWrite(giTerminalFD, gpScreenBuffer+ofs, size*4);
        _SysDebug("Video_Update - Done");
index f9592db..8886af1 100644 (file)
@@ -173,6 +173,8 @@ void WM_FocusWindow(tWindow *Destination)
 {
        struct sWndMsg_Bool     _msg;
        
+       _SysDebug("WM_FocusWindow(%p)", Destination);
+
        if( gpWM_FocusedWindow == Destination )
                return ;
        if( Destination && !(Destination->Flags & WINFLAG_SHOW) )
index 6ad72be..8258531 100644 (file)
@@ -8,7 +8,7 @@
 #include <common.h>
 #include <wm_internals.h>
 #include <stdlib.h>
-#include <utf8.h>
+#include <unicode.h>
 #include <limits.h>    // INT_MAX
 
 // === TYPES ===
index fd1cf39..9fed544 100644 (file)
@@ -10,6 +10,7 @@
 #include "include/internal.h"
 #include <richtext_messages.h>
 #include <string.h>
+#include <wm_messages.h>
 //#include <alloca.h>
 
 // === TYPES ===
@@ -23,6 +24,16 @@ typedef struct sRichText_Window
 // === CODE ===
 int AxWin3_RichText_MessageHandler(tHWND Window, int MessageID, int Size, void *Data)
 {
+       tRichText_Window        *info = AxWin3_int_GetDataPtr(Window);
+       struct sWndMsg_KeyAction        *keyaction = Data;
+       _SysDebug("MessageID = %i", MessageID);
+       switch(MessageID)
+       {
+       case WNDMSG_KEYFIRE:
+               if(Size < sizeof(*keyaction))   return -1;
+               info->KeyCallback(Window, 2, keyaction->KeySym, keyaction->UCS32);
+               return 1;
+       }
        return 0;
 }
 
index b9b2814..73e85d8 100644 (file)
@@ -528,7 +528,7 @@ void SetAddress(tInterface *Iface, void *Addr, void *Mask, void *Router)
        _SysIOCtl(Iface->IfaceFD, 6, Addr);
        _SysIOCtl(Iface->IfaceFD, 7, &mask_bits);
 
-       if( Router );
+       if( Router )
        {
                uint8_t *addr = Router;
                _SysDebug("Router %i.%i.%i.%i", addr[0], addr[1], addr[2], addr[3]);
index 7ccfff4..a38f135 100644 (file)
@@ -2,9 +2,9 @@
 
 -include ../Makefile.cfg
 
-LDFLAGS += -laxwin3
+LDFLAGS += -laxwin3 -lunicode
 
-OBJ = main.o
+OBJ = main.o vt100.o display.o
 BIN = terminal
 DIR := Apps/AxWin/3.0
 
diff --git a/Usermode/Applications/gui_shell_src/display.c b/Usermode/Applications/gui_shell_src/display.c
new file mode 100644 (file)
index 0000000..1665e44
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Acess GUI Terminal
+ * - By John Hodge (thePowersGang)
+ *
+ * display.c
+ * - Abstract display manipulation methods
+ */
+#include "include/display.h"
+#include <acess/sys.h> // _SysDebug
+#include <stdlib.h>    // exit
+#include <string.h>
+#include <unicode.h>
+#include <stdio.h>
+#include <axwin3/axwin.h>
+#include <axwin3/richtext.h>
+
+#define UNIMPLIMENTED()        do{_SysDebug("UNIMPLIMENTED %s", __func__); exit(-1);}while(0)
+
+// === EXTERN ==
+extern tHWND   gMainWindow;
+
+// === GLOBALS ===
+ int   giDisplayCols;
+ int   giDisplayLines;
+ int   giDisplayTotalLines;
+ int   giDisplayBufSize;
+ int   giCurrentLine;
+ int   giCurrentLinePos;       // byte offset, not column
+ int   giCurrentCol;
+ int   giFirstDispLine;        // First displayed line
+ int   giFirstLine;    // Ring buffer start
+char   **gasDisplayLines;
+ int   *gaiDisplayLineSizes;
+char   *gabDisplayLinesDirty;
+
+// === CODE ===
+void Display_Init(int Cols, int Lines, int ExtraScrollbackLines)
+{
+       giDisplayCols = Cols;
+       giDisplayLines = Lines;
+       giDisplayTotalLines = Lines + ExtraScrollbackLines;
+       gasDisplayLines = calloc( sizeof(char*), (Lines + ExtraScrollbackLines) );
+       gaiDisplayLineSizes = calloc( sizeof(int), (Lines + ExtraScrollbackLines) );
+       gabDisplayLinesDirty = calloc( sizeof(char), (Lines + ExtraScrollbackLines) );
+       
+       AxWin3_RichText_SetLineCount(gMainWindow, Lines+ExtraScrollbackLines);
+       AxWin3_RichText_SetCursorType(gMainWindow, 1);  // TODO: enum
+}
+
+void Display_int_PushString(int Length, const char *Text)
+{
+       _SysDebug("Line %i += %i '%*C'", giCurrentLine, Length, Length, Text);
+       if( !gasDisplayLines[giCurrentLine] || giCurrentLinePos + Length >= gaiDisplayLineSizes[giCurrentLine] )
+       {
+                int    reqsize = giCurrentLinePos + Length;
+               gaiDisplayLineSizes[giCurrentLine] = (reqsize + 32-1) & ~(32-1);
+               void *tmp = realloc(gasDisplayLines[giCurrentLine], gaiDisplayLineSizes[giCurrentLine]);
+               if( !tmp )      perror("Display_AddText - realloc");
+               gasDisplayLines[giCurrentLine] = tmp;
+       }
+
+       memcpy(gasDisplayLines[giCurrentLine]+giCurrentLinePos, Text, Length);
+       gabDisplayLinesDirty[giCurrentLine] = 1;
+       gasDisplayLines[giCurrentLine][giCurrentLinePos+Length] = 0;
+       giCurrentLinePos += Length;
+       
+}
+
+void Display_AddText(int Length, const char *UTF8Text)
+{
+       _SysDebug("%i '%.*s'", Length, Length, UTF8Text);
+       // Copy as many characters (not bytes, have to trim off the last char) as we can to the current line
+       // - then roll over to the next line
+       while( Length > 0 )
+       {
+                int    space = giDisplayCols - giCurrentCol;
+                int    bytes = 0;
+               while( space && bytes < Length )
+               {
+                       uint32_t        cp;
+                       bytes += ReadUTF8(UTF8Text+bytes, &cp);
+                       if( Unicode_IsPrinting(cp) ) {
+                               space --;
+                               giCurrentCol ++;
+                       }
+               }
+       
+               Display_int_PushString(bytes, UTF8Text);
+
+               UTF8Text += bytes;
+               _SysDebug("Length(%i) -= bytes(%i)", Length, bytes);
+               Length -= bytes;
+               if( Length != 0 )
+               {
+                       // Next line
+                       giCurrentLinePos = 0;
+                       giCurrentCol = 0;
+                       giCurrentLine ++;
+               }
+       }
+}
+
+void Display_Newline(int bCarriageReturn)
+{
+       Display_Flush();
+
+       // Going down!
+       giCurrentLine ++;
+       if( giCurrentLine == giDisplayLines )
+               giCurrentLine = 0;
+       if( giCurrentLine == giFirstLine )
+       {
+               giFirstLine ++;
+               if(giFirstLine == giDisplayLines)
+                       giFirstLine = 0;
+       }
+       
+       if( bCarriageReturn ) {
+               giCurrentLinePos = 0;
+               giCurrentCol = 0;
+       }
+       else {
+               giCurrentLinePos = 0;
+                int    i = giCurrentCol;
+               if( !gasDisplayLines[giCurrentLine] )
+               {
+                       giCurrentCol = 0;
+                       while(i--)
+                               Display_AddText(1, " ");
+               }
+               else
+               {
+                       while( i -- )
+                       {
+                               uint32_t        cp;
+                               giCurrentLinePos += ReadUTF8(gasDisplayLines[giCurrentLine]+giCurrentLinePos, &cp);
+                               if( !Unicode_IsPrinting(cp) )
+                                       i ++;
+                       }
+               }
+       }
+}
+
+void Display_SetCursor(int Row, int Col)
+{
+       UNIMPLIMENTED();
+}
+
+void Display_MoveCursor(int RelRow, int RelCol)
+{
+       if( RelRow < 0 )
+       {
+               for( ; RelRow < 0; RelRow ++ )
+               {
+                       uint32_t        cp;
+                       int delta = ReadUTF8Rev(gasDisplayLines[giCurrentLine], giCurrentLinePos, &cp);
+                       if( !Unicode_IsPrinting(cp) )
+                               RelRow --;
+                       else
+                               giCurrentCol --;
+                       giCurrentLinePos -= delta;
+               }
+       }
+       else
+       {
+               UNIMPLIMENTED();
+       }
+}
+
+void Display_ClearLine(int Dir)        // 0: All, 1: Forward, -1: Reverse
+{
+       if( Dir == 0 )
+       {
+               // Completely clear line
+               if( gasDisplayLines[giCurrentLine] )
+                       free(gasDisplayLines[giCurrentLine]);
+               gasDisplayLines[giCurrentLine] = NULL;
+               gabDisplayLinesDirty[giCurrentLine] = 1;
+       }
+       else if( Dir == 1 )
+       {
+               // Forward clear (truncate)
+       }
+       else if( Dir == -1 )
+       {
+               // Reverse clear (replace with spaces)
+       }
+       else
+       {
+               // BUGCHECK
+       }
+}
+
+void Display_ClearLines(int Dir)       // 0: All, 1: Forward, -1: Reverse
+{
+       if( Dir == 0 )
+       {
+               // Push giDisplayLines worth of empty lines
+               // Move cursor back up by giDisplayLines
+       }
+       else if( Dir == 1 )
+       {
+               // Push (giDisplayLines - (giCurrentLine-giFirstDispLine)) and reverse
+       }
+       else if( Dir == -1 )
+       {
+               // Reverse clear (replace with spaces)
+       }
+       else
+       {
+               // BUGCHECK
+       }
+}
+
+void Display_SetForeground(uint32_t RGB)
+{
+       char    buf[7+1];
+       sprintf(buf, "\1%06x", RGB&0xFFFFFF);
+       Display_int_PushString(7, buf);
+}
+
+void Display_SetBackground(uint32_t RGB)
+{
+       char    buf[7+1];
+       sprintf(buf, "\2%06x", RGB&0xFFFFFF);
+       Display_int_PushString(7, buf);
+}
+
+void Display_Flush(void)
+{
+        int    i;
+       for( i = 0; i < giDisplayCols; i ++ )
+       {
+                int    line = (giFirstLine + i) % giDisplayTotalLines;
+               if( !gabDisplayLinesDirty[line] )
+                       continue;
+               _SysDebug("Line %i+%i '%s'", giFirstLine, i, gasDisplayLines[line]);
+               AxWin3_RichText_SendLine(gMainWindow, giFirstLine + i, gasDisplayLines[line] );
+               gabDisplayLinesDirty[line] = 0;
+       }
+       
+       // force redraw?
+       AxWin3_RichText_SetCursorPos(gMainWindow, giCurrentLine, giCurrentCol);
+}
+
+void Display_ShowAltBuffer(int AltBufEnabled)
+{
+       UNIMPLIMENTED();
+}
+
index 80bc69c..4feaf35 100644 (file)
@@ -3,11 +3,15 @@
  * - By John Hodge (thePowersGang)
  *
  * display.h
- * - RichText Termianl Translation
+ * - RichText terminal translation
  */
 #ifndef _DISPLAY_H_
 #define _DISPLAY_H_
 
+#include <stdint.h>
+
+extern void    Display_Init(int Cols, int Lines, int ExtraScrollbackLines);
+
 extern void    Display_AddText(int Length, const char *UTF8Text);
 extern void    Display_Newline(int bCarriageReturn);
 extern void    Display_SetCursor(int Row, int Col);
@@ -16,6 +20,16 @@ extern void  Display_ClearLine(int Dir);     // 0: All, 1: Forward, -1: Reverse
 extern void    Display_ClearLines(int Dir);    // 0: All, 1: Forward, -1: Reverse
 extern void    Display_SetForeground(uint32_t RGB);
 extern void    Display_SetBackground(uint32_t RGB);
+/**
+ * \brief Ensure that recent updates are flushed to the server
+ * \note Called at the end of an "input" buffer
+ */
+extern void    Display_Flush(void);
+
+/**
+ * \brief Switch the display to the alternate buffer (no scrollback)
+ */
+extern void    Display_ShowAltBuffer(int AltBufEnabled);
 
 #endif
 
index c7aac85..4b82d0e 100644 (file)
@@ -8,14 +8,19 @@
 #include <axwin3/axwin.h>
 #include <axwin3/menu.h>
 #include <axwin3/richtext.h>
+#include <axwin3/keysyms.h>
 #include <stdio.h>
+#include <acess/sys.h>
 #include "include/display.h"
 #include "include/vt100.h"
+#include <string.h>
+#include <unicode.h>
 
 // === PROTOTYPES ===
  int   main(int argc, char *argv[], const char **envp);
  int   Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated);
  int   Term_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col);
+void   Term_HandleOutput(int Len, const char *Buf);
 
 // === GLOBALS ===
 tHWND  gMainWindow;
@@ -52,22 +57,30 @@ int main(int argc, char *argv[], const char **envp)
        // <testing>
        AxWin3_RichText_SetLineCount(gMainWindow, 3);
        AxWin3_RichText_SendLine(gMainWindow, 0, "First line!");
-       AxWin3_RichText_SendLine(gMainWindow, 2, "Third line! \x01""ff0000A red");
+       AxWin3_RichText_SendLine(gMainWindow, 2, "Third line! \1ff0000A red");
        // </testing>
 
-       AxWin3_ResizeWindow(gMainWindow, 600, 400);
-       AxWin3_MoveWindow(gMainWindow, 50, 50);
+       Display_Init(80, 25, 100);
+       AxWin3_ResizeWindow(gMainWindow, 80*8, 25*16);
+       AxWin3_MoveWindow(gMainWindow, 20, 50);
        AxWin3_ShowWindow(gMainWindow, 1);
        AxWin3_FocusWindow(gMainWindow);
 
        // Spawn shell
-       giChildStdout = open("/Devices/FIFO/anon", O_RDWR);
-       giChildStdin = open("/Devices/FIFO/anon", O_RDWR);
+       giChildStdin = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
+       giChildStdout = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
+       if( giChildStdout == -1 || giChildStdin == -1 ) {
+               perror("Oh, fsck");
+               _SysDebug("out,in = %i,%i", giChildStdout, giChildStdin);
+               return -1;
+       }
 
        {
                 int    fds[] = {giChildStdin, giChildStdout, giChildStdout};
                const char      *argv[] = {"CLIShell", NULL};
-               _SysSpawn("/Acess/Bin/CLIShell", argv, envp, 3, fds, NULL);
+               int pid = _SysSpawn("/Acess/Bin/CLIShell", argv, envp, 3, fds, NULL);
+               if( pid < 0 )
+                       _SysDebug("ERROR: Shell spawn failed");
        }
 
        // Main loop
@@ -81,9 +94,10 @@ int main(int argc, char *argv[], const char **envp)
                
                if( FD_ISSET(giChildStdout, &fds) )
                {
+                       _SysDebug("Activity on child stdout");
                        // Read and update screen
                        char    buf[32];
-                       int len = read(giChildStdout, buf, sizeof(buf));
+                       int len = _SysRead(giChildStdout, buf, sizeof(buf));
                        if( len <= 0 )  break;
                        
                        Term_HandleOutput(len, buf);
@@ -101,35 +115,51 @@ int Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translat
        #define _bitset(var,bit,set) do{if(set)var|=1<<(bit);else var&=1<<(bit);}while(0)
        switch(KeySym)
        {
-       case KEY_LCTRL:
-               _bitset(ctrl_state, 0, bPress);
+       case KEYSYM_LEFTCTRL:
+               _bitset(ctrl_state, 0, bPress!=0);
                return 0;
-       case KEY_RCTRL:
-               _bitset(ctrl_state, 0, bPress);
+       case KEYSYM_RIGHTCTRL:
+               _bitset(ctrl_state, 1, bPress!=0);
                return 0;
        }
        #undef _bitset
 
        // Handle shortcuts
        // - Ctrl-A -- Ctrl-Z
-       if( ctrl_state && KeySym >= KEY_a && KeySym <= KEY_z )
+       if( ctrl_state && KeySym >= KEYSYM_a && KeySym <= KEYSYM_z )
        {
-               Translated = KeySym - KEY_a + 1;
+               Translated = KeySym - KEYSYM_a + 1;
        }
 
-       if( Translated )
+       // == 2 :: FIRE
+       if( bPress == 2 )
        {
-               // Encode and send
+               if( Translated )
+               {
+                       char    buf[6];
+                        int    len;
+                       
+                       // Encode and send
+                       len = WriteUTF8(buf, Translated);
+                       
+                       _SysDebug("Keystroke translated to '%.*s'", len, buf);
+                       _SysWrite(giChildStdin, buf, len);
+                       
+                       return 0;
+               }
                
-               return 0;
-       }
-       
-       // No translation, look for escape sequences to send
-       switch(KeySym)
-       {
-       case KEY_LEFTARROW:
-       //      str = "\x1b[D";
-               break;
+               // No translation, look for escape sequences to send
+               const char *str = NULL;
+               switch(KeySym)
+               {
+               case KEYSYM_LEFTARROW:
+                       str = "\x1b[D";
+                       break;
+               }
+               if( str )
+               {
+                       _SysWrite(giChildStdin, str, strlen(str));
+               }
        }
        return 0;
 }
@@ -153,8 +183,10 @@ void Term_HandleOutput(int Len, const char *Buf)
                        Display_AddText(-esc_len, Buf + ofs);
                        esc_len = -esc_len;
                }
-               Len -= esc_len;
                ofs += esc_len;
+               _SysDebug("Len = %i, ofs = %i", Len, ofs);
        }
+       
+       Display_Flush();
 }
 
index 51c8016..2a87ca4 100644 (file)
@@ -2,42 +2,86 @@
  * Acess GUI Terminal
  * - By John Hodge (thePowersGang)
  *
- * main.c
- * - Core
+ * vt100.c
+ * - VT100/xterm Emulation
  */
 #include <string.h>
+#include <limits.h>
 #include "include/vt100.h"
 #include "include/display.h"
+#include <ctype.h>     // isalpha
+#include <acess/sys.h> // _SysDebug
+
+const uint32_t caVT100Colours[] = {
+       // Black, Red, Green, Yellow, Blue, Purple, Cyan, Gray
+       // Same again, but bright
+       0x000000, 0x770000, 0x007700, 0x777700, 0x000077, 0x770077, 0x007777, 0xAAAAAAA,
+       0xCCCCCC, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFFF
+};
+
+ int   Term_HandleVT100_Long(int Len, const char *Buf);
+
+static inline int min(int a, int b)
+{
+       return a < b ? a : b;
+}
 
 int Term_HandleVT100(int Len, const char *Buf)
 {
-       const int       max_length = 16;
-       static char     inc_buf[max_length]
+       #define MAX_VT100_ESCAPE_LEN    16
+       static char     inc_buf[MAX_VT100_ESCAPE_LEN];
        static int      inc_len = 0;
 
        if( inc_len > 0 || *Buf == '\x1b' )
        {
-               memcpy(inc_buf + inc_len, Buf, min(max_length - inc_len, Len));
                // Handle VT100 (like) escape sequence
-               
-               inc_len = 0;
-               return 1;
+                int    new_bytes = min(MAX_VT100_ESCAPE_LEN - inc_len, Len);
+                int    ret = 0, old_inc_len = inc_len;
+               memcpy(inc_buf + inc_len, Buf, new_bytes);
+
+               inc_len += new_bytes;
+
+               if( inc_len <= 1 )
+                       return 1;       // Skip 1 character (the '\x1b')
+
+               switch(inc_buf[1])
+               {
+               case '[':       // Multibyte, funtime starts    
+                       ret = Term_HandleVT100_Long(inc_len-2, inc_buf+2);
+                       if( ret > 0 ) {
+                               ret += 2;
+                       }
+                       break;
+               default:
+                       ret = 2;
+                       break;
+               }       
+
+               if( ret != 0 ) {
+                       inc_len = 0;
+                       ret -= old_inc_len;     // counter cached bytes
+               }
+               return ret;
        }
 
        switch( *Buf )
        {
        case '\b':
                // TODO: Backspace
+               Display_MoveCursor(-1, 0);
+               Display_AddText(1, " ");
+               Display_MoveCursor(-1, 0);
                return 1;
        case '\t':
-               // TODO: tab
+               // TODO: tab (get current cursor pos, space until multiple of 8)
                return 1;
        case '\n':
                Display_Newline(1);
                return 1;
        case '\r':
                // TODO: Carriage return
-               return ;
+               Display_MoveCursor(INT_MIN, 0);
+               return 1;
        }
 
         int    ret = 0;
@@ -52,3 +96,100 @@ int Term_HandleVT100(int Len, const char *Buf)
        }
        return -ret;
 }
+
+int Term_HandleVT100_Long(int Len, const char *Buffer)
+{
+       char    c;
+        int    argc = 0, j = 0;
+        int    args[6] = {0,0,0,0,0,0};
+        int    bQuestionMark = 0;
+       
+       // Get Arguments
+       if(j == Len)    return 0;
+       c = Buffer[j++];
+       if(c == '?') {
+               bQuestionMark = 1;
+               if(j == Len)    return 0;
+               c = Buffer[j++];
+       }
+       if( '0' <= c && c <= '9' )
+       {
+               do {
+                       if(c == ';') {
+                               if(j == Len)    return 0;
+                               c = Buffer[j++];
+                       }
+                       while('0' <= c && c <= '9') {
+                               args[argc] *= 10;
+                               args[argc] += c-'0';
+                               if(j == Len)    return 0;
+                               c = Buffer[j++];
+                       }
+                       argc ++;
+               } while(c == ';');
+       }
+       
+       // Get Command
+       if( !isalpha(c) ) {
+               // Bother.
+               _SysDebug("Unexpected char 0x%x in VT100 escape code", c);
+               return 1;
+       }
+
+       if( bQuestionMark )
+       {
+               // Special commands
+               switch( c )
+               {
+               default:
+                       _SysDebug("Unknown VT100 extended escape char 0x%x", c);
+                       break;
+               }
+       }
+       else
+       {
+               // Standard commands
+               switch( c )
+               {
+               case 'J':
+                       if( argc == 0 )
+                               Display_ClearLine(0);
+                       else if( args[0] == 2 )
+                               Display_ClearLines(0);  // Entire screen!
+                       else
+                               _SysDebug("TODO: VT100 %i J", args[0]);
+                       break;
+               case 'm':
+                       if( argc == 0 )
+                       {
+                               // Reset
+                       }
+                       else
+                       {
+                               int i;
+                               for( i = 0; i < argc; i ++ )
+                               {
+                                       if( args[i] < 8 )
+                                       {
+                                               // Flags?
+                                       }
+                                       else if( 30 <= args[i] && args[i] <= 37 )
+                                       {
+                                               // TODO: Bold/bright
+                                               Display_SetForeground( caVT100Colours[ args[i]-30 ] );
+                                       } 
+                                       else if( 40 <= args[i] && args[i] <= 47 )
+                                       {
+                                               // TODO: Bold/bright
+                                               Display_SetBackground( caVT100Colours[ args[i]-30 ] );
+                                       } 
+                               }
+                       }
+                       break;
+               default:
+                       _SysDebug("Unknown VT100 escape char 0x%x", c);
+                       break;
+               }
+       }
+       return j;
+}
diff --git a/Usermode/Applications/init_src/common.h b/Usermode/Applications/init_src/common.h
new file mode 100644 (file)
index 0000000..406fe6f
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Acess2 Userland init(8)
+ * - Userland root process
+ * 
+ * common.h
+ * - Common type definitions
+ */
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+typedef struct sInitProgram    tInitProgram;
+
+struct sKTerm
+{
+        int    ID;
+};
+
+struct sSTerm
+{
+       uint32_t        FormatBits;
+       unsigned int    BaudRate;
+       char    Path[];
+};
+
+struct sDaemon
+{
+       char    *StdoutPath;    // heap
+       char    *StderrPath;    // heap
+};
+
+union uProgTypes
+{
+       struct sKTerm   KTerm;
+       struct sSTerm   STerm;
+       struct sDaemon  Daemon;
+};
+
+enum eProgType
+{
+       PT_KTERM,
+       PT_STERM,
+       PT_DAEMON
+};
+
+struct sInitProgram
+{
+       tInitProgram    *Next;
+       enum eProgType  Type;
+        int    CurrentPID;
+       char    **Command;
+       union uProgTypes        TypeInfo;
+};
+
+#endif
+
index 51b9194..a3d737d 100644 (file)
@@ -4,16 +4,37 @@
 #include <acess/sys.h>
 #include <stdlib.h>
 #include <stdio.h>
-//#include "common.h"
+#include <string.h>
+#include "common.h"
+#include <ctype.h>
 
 // === CONSTANTS ===
-#define NUM_TERMS      4
-#define        DEFAULT_TERMINAL        "/Devices/VTerm/0"
 #define DEFAULT_SHELL  "/Acess/SBin/login"
+#define INITTAB_FILE   "/Acess/Conf/inittab"
 
 #define ARRAY_SIZE(x)  ((sizeof(x))/(sizeof((x)[0])))
 
 // === PROTOTYPES ===
+ int   ProcessInittab(const char *Path);
+char   *ReadQuotedString(FILE *FP);
+char   **ReadCommand(FILE *FP);
+void   FreeCommand(char **Command);
+
+tInitProgram   *AllocateProgram(char **Command, enum eProgType Type, size_t ExtraSpace);
+void   RespawnProgam(tInitProgram *Program);
+
+ int   AddKTerminal(int TerminalSpec, char **Command);
+ int   AddSerialTerminal(const char *DevPathSegment, const char *ModeStr, char **Command);
+ int   AddDaemon(char *StdoutPath, char *StderrPath, char **Command);
+
+ int   SpawnCommand(int c_stdin, int c_stdout, int c_stderr, char **ArgV);
+ int   SpawnKTerm(tInitProgram *Program);
+ int   SpawnSTerm(tInitProgram *Program);
+ int   SpawnDaemon(tInitProgram *Program);
+
+// === GLOBALS ===
+const char     *gsInittabPath = INITTAB_FILE;
+tInitProgram   *gpInitPrograms;
 
 // === CODE ===
 /**
  */
 int main(int argc, char *argv[])
 {
-        int    tid;
-        int    i;
-       char    termpath[sizeof(DEFAULT_TERMINAL)] = DEFAULT_TERMINAL;
-       char    *child_argv[2] = {DEFAULT_SHELL, 0};
+       // Parse commandline args
+       // TODO: cmdline
+
+       // TODO: Behave differently if not invoked as first process?
+
+       // Begin init process
+       if( ProcessInittab(gsInittabPath) != 0 )
+       {
+               // No inittab file found, default to:
+               _SysDebug("inittab '%s' is invalid, falling back to one VT", gsInittabPath);
+               
+               #if 0
+               for( ;; )
+               {
+                       int pid = SpawnCommand(0, 1, 1, (char *[]){DEFAULT_SHELL, NULL});
+                       // TODO: Detect errors
+                       _SysWaitTID(pid, NULL);
+               }
+               #else
+               return 41;
+               #endif
+       }
+
+       // TODO: Implement message watching
+       for(;;)
+       {
+                int    pid, status;
+               pid = _SysWaitTID(-1, &status);
+               _SysDebug("PID %i died, looking for respawn entry", pid);
+       }
        
-       // - Parse init script
+       return 42;
+}
+
+char *ReadQuotedString(FILE *FP)
+{
+       char    ch;
+       
+       while( isblank(ch = fgetc(FP)) )
+               ;
+
+       if( ch == '\n' ) {
+               return NULL;
+       }
+
+       char    *retstr = NULL;
+        int    mode = 0;
+        int    pos = 0, space = 0;
+       for( ; !feof(FP); ch = fgetc(FP) )
+       {
+                int    skip;
+               skip = 1;
+               if( mode & 4 ) {
+                       // Add escaped/special character
+                       skip = 0;
+                       mode &= 3;
+               }
+               else if( mode == 0 )
+               {
+                       if( isspace(ch) ) {
+                               fseek(FP, -1, SEEK_CUR);
+                               break;
+                       }
+                       else if( ch == '\\' )
+                               mode |= 4;
+                       else if( ch == '"' )
+                               mode = 1;
+                       else if( ch == '\'')
+                               mode = 2;
+                       else {
+                               // Add character
+                               skip = 0;
+                       }
+               }
+               // Double-quoted string
+               else if( mode == 1 )
+               {
+                       if( ch == '"' )
+                               mode = 0;
+                       else if( ch == '\\' )
+                               mode |= 4;
+                       else {
+                               // Add character
+                               skip = 0;
+                       }
+               }
+               // Single-quoted string
+               else if( mode == 2 )
+               {
+                       if( ch == '\'' )
+                               mode = 0;
+                       else if( ch == '\\' )
+                               mode |= 4;
+                       else {
+                               // Add character
+                               skip = 0;
+                       }
+               }
        
-       // - Start virtual terminals
-       for( i = 0; i < NUM_TERMS; i++ )
-       {               
-               tid = _SysClone(CLONE_VM, 0);
-               if(tid == 0)
+               if( !skip )
                {
-                       termpath[sizeof(DEFAULT_TERMINAL)-2] = '0' + i;
+                       if( pos == space ) {
+                               space += 32;
+                               void *tmp = realloc(retstr, space+1);
+                               if( !tmp ) {
+                                       _SysDebug("ReadQuotedString - realloc(%i) failure", space+1);
+                                       free(retstr);
+                                       return NULL;
+                               }
+                               retstr = tmp;
+                       }
+                       retstr[pos++] = ch;
+               }
+       }
+       retstr[pos] = '\0';
+       return retstr;
+}
+
+char **ReadCommand(FILE *FP)
+{
+       const int       space = 8;
+        int    pos = 0;
+       char    **ret = malloc(space*sizeof(char*));
+       char    *arg;
+       do {
+               arg = ReadQuotedString(FP);
+               if(arg == NULL)
+                       break;
+               if( pos == space - 1 ) {
+                       _SysDebug("Too many arguments %i", pos);
+                       ret[pos] = NULL;
+                       FreeCommand(ret);
+                       return NULL;
+               }
+               ret[pos++] = arg;
+       } while(arg != NULL);
+       ret[pos] = NULL;
+       return ret;
+}
+
+void FreeCommand(char **Command)
+{
+       int pos = 0;
+       while( Command[pos] )
+       {
+               free(Command[pos]);
+               pos ++;
+       }
+       free(Command);
+}
+
+int ProcessInittab(const char *Path)
+{
+       FILE    *fp = fopen(Path, "r");
+
+       if( !fp )
+               return 1;       
+
+       while(!feof(fp))
+       {
+               char cmdbuf[64+1];
+               
+                int    rv;
+               if( (rv = fscanf(fp, "%64s%*[ \t]", &cmdbuf)) != 1 ) {
+                       _SysDebug("fscanf rv %i != exp 1", rv);
+                       break;
+               }
+               
+               // Clear comments
+               if( cmdbuf[0] == '#' ) {
+                       while( !feof(fp) && fgetc(fp) != '\n' )
+                               ;
+                       continue ;
+               }
+               if( cmdbuf[0] == '\0' ) {
+                       char    ch = fgetc(fp);
+                       if( ch != '\n' && ch != -1 ) {
+                               fclose(fp);
+                               _SysDebug("Unexpected char 0x%x, expecting EOL", ch);
+                               return 2;       // Unexpected character?
+                       }
+                       continue ;
+               }
+
+               // Check commands
+               if( strcmp(cmdbuf, "ktty") == 0 ) {
+                       // ktty <ID> <command...>
+                       // - Spins off a console on the specified kernel TTY
+                        int    id = 0;
+                       if( fscanf(fp, "%d ", &id) != 1 ) {
+                               _SysDebug("init[ktty] - TTY ID read failed");
+                               goto lineError;
+                       }
+                       char    **command = ReadCommand(fp);
+                       if( !command ) {
+                               _SysDebug("init[ktty] - Command read failure");
+                               goto lineError;
+                       }
+                       AddKTerminal(id, command);
+                       free(command);
+               }
+               else if(strcmp(cmdbuf, "stty") == 0 ) {
+                       // stty <devpath> [78][NOE][012][bB]<baud> <command...>
+                       char    path_seg[32+1];
+                       char    modespec[4+6+1];
+                       if( fscanf(fp, "%32s %6s ", &path_seg, &modespec) != 2 ) {
+                               goto lineError;
+                       }
+                       char **command = ReadCommand(fp);
+                       if( !command )
+                               goto lineError;
+                       AddSerialTerminal(path_seg, modespec, command);
+               }
+               else if(strcmp(cmdbuf, "daemon") == 0 ) {
+                       // daemon <stdout> <stderr> <command...>
+                       // - Runs a daemon (respawning) that logs to the specified files
+                       // - Will append a header whenever the daemon starts
+                       char    *stdout_path = ReadQuotedString(fp);
+                       char    *stderr_path = ReadQuotedString(fp);
+                       char    **command = ReadCommand(fp);
                        
-                       _SysOpen(termpath, OPENFLAG_READ);      // Stdin
-                       _SysOpen(termpath, OPENFLAG_WRITE);     // Stdout
-                       _SysOpen(termpath, OPENFLAG_WRITE);     // Stderr
-                       _SysExecVE(DEFAULT_SHELL, child_argv, NULL);
-                       for(;;) ;
+                       AddDaemon(stdout_path, stderr_path, command);
+               }
+               else if(strcmp(cmdbuf, "exec") == 0 ) {
+                       // exec <command...>
+                       // - Runs a command and waits for it to complete before continuing
+                       // - NOTE: No other commands will respawn while this is running
+                       char **command = ReadCommand(fp);
+                       if(!command)
+                               goto lineError;
+
+                       int handles[] = {0, 1, 2};
+                       int pid = _SysSpawn(command[0], (const char **)command, NULL, 3, handles, NULL);
+                       int retstatus;
+                       _SysWaitTID(pid, &retstatus);
+                       _SysDebug("Command '%s' returned %i", command[0], retstatus);
+
+                       FreeCommand(command);
+               }
+               else {
+                       // Unknown command.
+                       _SysDebug("Unknown command '%s'", cmdbuf);
+                       goto lineError;
                }
+               fscanf(fp, " ");
+               continue;
+       lineError:
+               _SysDebug("label lineError: goto'd");
+               while( !feof(fp) && fgetc(fp) != '\n' )
+                       ;
+               continue ;
        }
+
+       fclose(fp);
+       return 0;
+}
+
+tInitProgram *AllocateProgram(char **Command, enum eProgType Type, size_t ExtraSpace)
+{
+       tInitProgram    *ret;
        
-       // TODO: Implement message watching
-       for(;;)
-               _SysWaitEvent(THREAD_EVENT_IPCMSG);
+       ret = malloc( sizeof(tInitProgram) - sizeof(union uProgTypes) + ExtraSpace );
+       ret->Next = NULL;
+       ret->CurrentPID = 0;
+       ret->Type = Type;
+       ret->Command = Command;
        
-       return 42;
+       // Append
+       ret->Next = gpInitPrograms;
+       gpInitPrograms = ret;
+       
+       return ret;
+}
+
+void RespawnProgam(tInitProgram *Program)
+{
+        int    rv = 0;
+       switch(Program->Type)
+       {
+       case PT_KTERM:  rv = SpawnKTerm(Program);       break;
+       case PT_STERM:  rv = SpawnSTerm(Program);       break;
+       case PT_DAEMON: rv = SpawnDaemon(Program);      break;
+       default:
+               _SysDebug("BUGCHECK - Program Type %i unknown", Program->Type);
+               break;
+       }
+       if( !rv ) {
+               _SysDebug("Respawn failure!");
+               // TODO: Remove from list?
+       }
+}
+
+int AddKTerminal(int TerminalID, char **Command)
+{
+       // TODO: Smarter validation
+       if( TerminalID < 0 || TerminalID > 7 )
+               return -1;
+       
+       tInitProgram    *ent = AllocateProgram(Command, PT_KTERM, sizeof(struct sKTerm));
+       ent->TypeInfo.KTerm.ID = TerminalID;
+
+       RespawnProgam(ent);
+       return 0;
+}
+
+int AddSerialTerminal(const char *DevPathSegment, const char *ModeStr, char **Command)
+{
+       char    dbit, parity, sbit;
+        int    baud;
+
+       // Parse mode string
+       if( sscanf(ModeStr, "%1[78]%1[NOE]%1[012]%*1[bB]%d", &dbit, &parity, &sbit, &baud) != 5 ) {
+               // Oops?
+               return -1;
+       }
+       
+       // Validate baud rate / build mode word
+       // TODO: Does baud rate need validation?
+       uint32_t        modeword = 0;
+       modeword |= (dbit == '7' ? 1 : 0) << 0;
+       modeword |= (parity == 'O' ? 1 : (parity == 'E' ? 2 : 0)) << 1;
+       modeword |= (sbit - '0') << 3;
+       
+       // Create info
+       const char DEVPREFIX[] = "/Devices/";
+       int pathlen = sizeof(DEVPREFIX) + strlen(DevPathSegment);
+       tInitProgram    *ent = AllocateProgram(Command, PT_STERM, sizeof(struct sSTerm)+pathlen);
+       ent->TypeInfo.STerm.FormatBits = modeword;
+       ent->TypeInfo.STerm.BaudRate = baud;
+       strcpy(ent->TypeInfo.STerm.Path, DEVPREFIX);
+       strcat(ent->TypeInfo.STerm.Path, DevPathSegment);
+
+       RespawnProgam(ent);
+       return 0;
+}
+
+int AddDaemon(char *StdoutPath, char *StderrPath, char **Command)
+{
+       tInitProgram    *ent = AllocateProgram(Command, PT_DAEMON, sizeof(struct sDaemon));
+       ent->TypeInfo.Daemon.StdoutPath = StdoutPath;
+       ent->TypeInfo.Daemon.StderrPath = StderrPath;
+       
+       RespawnProgam(ent);
+       return 0;
+}
+
+int SpawnCommand(int c_stdin, int c_stdout, int c_stderr, char **ArgV)
+{
+        int    handles[] = {c_stdin, c_stdout, c_stderr};
+
+       int rv = _SysSpawn(ArgV[0], (const char **)ArgV, NULL, 3, handles, NULL);
+
+       _SysClose(c_stdin);
+       if( c_stdout != c_stdin )
+               _SysClose(c_stdout);
+       if( c_stderr != c_stdin && c_stderr != c_stdout )
+               _SysClose(c_stderr);
+
+       return rv;
+}
+
+int SpawnKTerm(tInitProgram *Program)
+{
+       const char fmt[] = "/Devices/VTerm/%i";
+       char    path[sizeof(fmt)];
+       
+       snprintf(path, sizeof(path), fmt, Program->TypeInfo.KTerm.ID);
+       
+        int    in = _SysOpen(path, OPENFLAG_READ);
+        int    out = _SysOpen(path, OPENFLAG_WRITE);
+       
+       return SpawnCommand(in, out, out, Program->Command);
+}
+
+int SpawnSTerm(tInitProgram *Program)
+{
+        int    in = _SysOpen(Program->TypeInfo.STerm.Path, OPENFLAG_READ);
+        int    out = _SysOpen(Program->TypeInfo.STerm.Path, OPENFLAG_WRITE);
+
+       #if 0
+       if( _SysIOCtl(in, 0, NULL) != DRV_TYPE_SERIAL )
+       {
+               // Oops?
+               return -2;
+       }
+       _SysIOCtl(in, SERIAL_IOCTL_GETSETBAUD, &Program->TypeInfo.STerm.BaudRate);
+       _SysIOCtl(in, SERIAL_IOCTL_GETSETFORMAT, &Program->TypeInfo.STerm.FormatBits);
+       #endif
+
+       return SpawnCommand(in, out, out, Program->Command);
+}
+
+int SpawnDaemon(tInitProgram *Program)
+{
+        int    in = _SysOpen("/Devices/null", OPENFLAG_READ);
+        int    out = _SysOpen(Program->TypeInfo.Daemon.StdoutPath, OPENFLAG_WRITE);
+        int    err = _SysOpen(Program->TypeInfo.Daemon.StderrPath, OPENFLAG_WRITE);
+       
+       if( in == -1 || out == -1 || err == -1 ) {
+               _SysClose(in);
+               _SysClose(out);
+               _SysClose(err);
+               return -2;
+       }
+       
+       return SpawnCommand(in, out, err, Program->Command);
 }
 
index 9e5a075..16eee39 100644 (file)
@@ -78,7 +78,7 @@ char  *gsNickname = "acess";
 tServer        *gpServers;\r
 tWindow        gWindow_Status = {\r
        NULL, NULL, NULL,       // No next, empty list, no server\r
-       0, ""   // No activity, empty name (rendered as status)\r
+       0, {""} // No activity, empty name (rendered as status)\r
 };\r
 tWindow        *gpWindows = &gWindow_Status;\r
 tWindow        *gpCurrentWindow = &gWindow_Status;\r
index a4f5e0d..bf6de99 100644 (file)
@@ -55,17 +55,17 @@ int main(int argc, char *argv[])
        return 0;
 }
 
+static void FD_SET_MAX(fd_set *set, int fd, int *maxfd)
+{
+       FD_SET(fd, set);
+       if(*maxfd < fd) *maxfd = fd;
+}
+
 void EventLoop(void)
 {
        fd_set  fds;
         int    maxfd;
 
-       void FD_SET_MAX(fd_set *set, int fd, int *maxfd)
-       {
-               FD_SET(fd, set);
-               if(*maxfd < fd) *maxfd = fd;
-       }
-
        for( ;; )
        {
                FD_ZERO(&fds);
diff --git a/Usermode/Filesystem/Conf/inittab b/Usermode/Filesystem/Conf/inittab
new file mode 100644 (file)
index 0000000..a64bfc0
--- /dev/null
@@ -0,0 +1,8 @@
+exec /Acess/Bin/dhcpc
+
+ktty 0 /Acess/SBin/login
+ktty 1 /Acess/SBin/login
+stty serial/0 /Acess/SBin/login
+
+
+#vim: ft=text
index 7eb0694..a49d887 100644 (file)
@@ -5,7 +5,7 @@
 
 DIRS  = Bin SBin Libs Modules Apps
 DIRS += Conf Conf/Auth
-FILES = Conf/BootConf.cfg
+FILES = Conf/inittab
 # Conf/Auth/Users Conf/Auth/Passwords Conf/Auth/Groups
 
 #DIRS  := $(addprefix $(DISTROOT)/,$(DIRS))
index c77ff05..5475fdc 100644 (file)
@@ -11,7 +11,8 @@ EXTRABIN := libld-acess.so
 EXTRACLEAN := $(_OBJPREFIX)_stublib.o
 INCFILES := sys/sys.h
 
-CFLAGS   = -g -Wall -fno-builtin -fno-leading-underscore -fno-stack-protector -fPIC
+CFLAGS   = -g -Wall -fno-builtin -fno-stack-protector -fPIC
+# -fno-leading-underscore
 CFLAGS  += $(CPPFLAGS) -Werror
 LDFLAGS  = -g -T arch/$(ARCHDIR).ld -Map map.txt --export-dynamic
 
index 2c85b14..351c841 100644 (file)
@@ -100,9 +100,23 @@ _errno:    .long   0       @ Placed in .text, to allow use of relative addressing
 // Override the clone syscall
 #define _exit  _exit_raw
 #define _clone _clone_raw
+#define _SysSeek       _SysSeek_borken
 #include "syscalls.s.h"
 #undef _exit
 #undef _clone
+#undef _SysSeek 
+
+// NOTE: _SysSeek needs special handling for alignment
+.globl _SysSeek
+_SysSeek:
+       push {lr}
+       mov r1,r2
+       mov r2,r3
+       ldr r3, [sp,#4]
+       svc #SYS_SEEK
+       ldr r3, =_errno
+       str r2, [r3]
+       pop {pc}
 
 .globl _clone
 _clone:
@@ -120,6 +134,7 @@ _clone_ret:
        pop {r4}
        mov pc, lr
 
+
 .globl _exit
 _exit:
        svc #0
index 13347a6..531b32d 100644 (file)
@@ -571,6 +571,47 @@ int Elf32GetSymbol(void *Base, const char *Name, void **ret, size_t *Size)
 }
 
 #ifdef SUPPORT_ELF64
+typedef int (*t_elf64_doreloc)(void *Base, const char *strtab, Elf64_Sym *symtab, Elf64_Xword r_info, void *ptr, Elf64_Sxword addend);
+
+int _Elf64DoReloc_X86_64(void *Base, const char *strtab, Elf64_Sym *symtab, Elf64_Xword r_info, void *ptr, Elf64_Sxword addend)
+{
+        int    sym = ELF64_R_SYM(r_info);
+        int    type = ELF64_R_TYPE(r_info);
+       const char      *symname = strtab + symtab[sym].st_name;
+       void    *symval;
+       //DEBUGS("_Elf64DoReloc: %s", symname);
+       switch( type )
+       {
+       case R_X86_64_NONE:
+               break;
+       case R_X86_64_64:
+               if( !GetSymbol(symname, &symval, NULL)  )       return 1;
+               *(uint64_t*)ptr = (uintptr_t)symval + addend;
+               break;
+       case R_X86_64_COPY: {
+               size_t  size;
+               if( !GetSymbol(symname, &symval, &size)  )      return 1;
+               memcpy(ptr, symval, size);
+               } break;
+       case R_X86_64_GLOB_DAT:
+               if( !GetSymbol(symname, &symval, NULL)  )       return 1;
+               *(uint64_t*)ptr = (uintptr_t)symval;
+               break;
+       case R_X86_64_JUMP_SLOT:
+               if( !GetSymbol(symname, &symval, NULL)  )       return 1;
+               *(uint64_t*)ptr = (uintptr_t)symval;
+               break;
+       case R_X86_64_RELATIVE:
+               *(uint64_t*)ptr = (uintptr_t)Base + addend;
+               break;
+       default:
+               SysDebug("ld-acess - _Elf64DoReloc: Unknown relocation type %i", type);
+               return 2;
+       }
+       //DEBUGS("_Elf64DoReloc: - Good");
+       return 0;
+}
+
 void *Elf64Relocate(void *Base, char **envp, const char *Filename)
 {
         int    i;
@@ -711,45 +752,8 @@ void *Elf64Relocate(void *Base, char **envp, const char *Filename)
        }
 
        // Relocation function
-       auto int _Elf64DoReloc(Elf64_Xword r_info, void *ptr, Elf64_Sxword addend);
-       int _Elf64DoReloc(Elf64_Xword r_info, void *ptr, Elf64_Sxword addend)
-       {
-                int    sym = ELF64_R_SYM(r_info);
-                int    type = ELF64_R_TYPE(r_info);
-               const char      *symname = strtab + symtab[sym].st_name;
-               void    *symval;
-               //DEBUGS("_Elf64DoReloc: %s", symname);
-               switch( type )
-               {
-               case R_X86_64_NONE:
-                       break;
-               case R_X86_64_64:
-                       if( !GetSymbol(symname, &symval, NULL)  )       return 1;
-                       *(uint64_t*)ptr = (uintptr_t)symval + addend;
-                       break;
-               case R_X86_64_COPY: {
-                       size_t  size;
-                       if( !GetSymbol(symname, &symval, &size)  )      return 1;
-                       memcpy(ptr, symval, size);
-                       } break;
-               case R_X86_64_GLOB_DAT:
-                       if( !GetSymbol(symname, &symval, NULL)  )       return 1;
-                       *(uint64_t*)ptr = (uintptr_t)symval;
-                       break;
-               case R_X86_64_JUMP_SLOT:
-                       if( !GetSymbol(symname, &symval, NULL)  )       return 1;
-                       *(uint64_t*)ptr = (uintptr_t)symval;
-                       break;
-               case R_X86_64_RELATIVE:
-                       *(uint64_t*)ptr = (uintptr_t)Base + addend;
-                       break;
-               default:
-                       SysDebug("ld-acess - _Elf64DoReloc: Unknown relocation type %i", type);
-                       return 2;
-               }
-               //DEBUGS("_Elf64DoReloc: - Good");
-               return 0;
-       }
+       t_elf64_doreloc fpElf64DoReloc = &_Elf64DoReloc_X86_64;
+       #define _Elf64DoReloc(info, ptr, addend)        fpElf64DoReloc(Base, strtab, symtab, info, ptr, addend)
 
        int fail = 0;
        if( rel )
index 8972cbe..b2367d1 100644 (file)
@@ -30,17 +30,20 @@ static inline void  FD_ZERO(fd_set *fdsetp)
 static inline  void    FD_CLR(int fd, fd_set *fdsetp)
 {
        if(fd < 0 || fd > FD_SETSIZE)   return;
-       fdsetp->flags[fd/16] &= (fd_set_ent_t) ((~1 << (fd%16))) & 0xFFFF;
+       fd_set_ent_t    mask = 1 << (fd % 16);
+       fdsetp->flags[fd/16] &= ~mask;
 }
 static inline  void    FD_SET(int fd, fd_set *fdsetp)
 {
        if(fd < 0 || fd > FD_SETSIZE)   return;
-       fdsetp->flags[fd/16] |= (fd_set_ent_t) (1 << (fd%16));
+       fd_set_ent_t    mask = 1 << (fd % 16);
+       fdsetp->flags[fd/16] |= mask;
 }
 static inline  int     FD_ISSET(int fd, fd_set *fdsetp)
 {
        if(fd < 0 || fd > FD_SETSIZE)   return 0;
-       return !!( fdsetp->flags[fd/16] & (1<<(fd%16)) );
+       fd_set_ent_t    mask = 1 << (fd % 16);
+       return !!( fdsetp->flags[fd/16] & mask );
 }
 
 #endif
index c798702..d9d3173 100644 (file)
@@ -33,6 +33,8 @@
 #define GETMSG_IGNORE  ((void*)-1)
 #define FILEFLAG_DIRECTORY     0x10
 #define FILEFLAG_SYMLINK       0x20
+#define CLONE_VM       0x10
+
 
 // === TYPES ===
 
index 6a1d584..3d45ed1 100644 (file)
@@ -152,6 +152,8 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char
                // int  offset = -1;
                enum e_vcscanf_sizes    size = _VCSCANF_UNDEF;
                enum e_vcscanf_types    valtype;
+                int    fail = 0;
+                int    nnewch;
 
                const char      *set_start;
                 int    set_len;                
@@ -161,6 +163,7 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char
                {
                        while( (ich = __getc(h)) && isspace(ich) )
                                nch ++;
+                       if(ich) __rewind(h);
                        continue ;
                }
                
@@ -262,22 +265,30 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char
                {
                // Decimal integer
                case 'd':
-                       nch += _vcscanf_int(__getc, __rewind, h, 10, maxlen, &ival);
+                       nnewch = _vcscanf_int(__getc, __rewind, h, 10, maxlen, &ival);
+                       if(nnewch==0)   fail=1;
+                       nch += nnewch;
                        valtype = _VCSCANF_INT;
                        break;
                // variable-base integer
                case 'i':
-                       nch += _vcscanf_int(__getc, __rewind, h, 0, maxlen, &ival);
+                       nnewch = _vcscanf_int(__getc, __rewind, h, 0, maxlen, &ival);
+                       if(nnewch==0)   fail=1;
+                       nch += nnewch;
                        valtype = _VCSCANF_INT;
                        break;
                // Octal integer
                case 'o':
-                       nch += _vcscanf_int(__getc, __rewind, h, 8, maxlen, &ival);
+                       nnewch = _vcscanf_int(__getc, __rewind, h, 8, maxlen, &ival);
+                       if(nnewch==0)   fail=1;
+                       nch += nnewch;
                        valtype = _VCSCANF_INT;
                        break;
                // Hexadecimal integer
                case 'x': case 'X':
-                       nch += _vcscanf_int(__getc, __rewind, h, 16, maxlen, &ival);
+                       nnewch = _vcscanf_int(__getc, __rewind, h, 16, maxlen, &ival);
+                       if(nnewch==0)   fail=1;
+                       nch += nnewch;
                        valtype = _VCSCANF_INT;
                        break;
                // strtod format float
@@ -304,13 +315,14 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char
                                maxlen = -1;
 
                        ich = 0;
-                       while( maxlen -- && (ich = __getc(h)) && !isblank(ich) )
+                       while( maxlen -- && (ich = __getc(h)) && !isspace(ich) )
                        {
                                if(ptr._char)   *ptr._char++ = ich;
                                nch ++;
                        }
                        if( maxlen >= 0 && ich )
                                __rewind(h);
+                       if(ptr._char)   *ptr._char++ = 0;
                        valtype = _VCSCANF_NOTYPE;
                        break;
                // match a set of characters
@@ -329,6 +341,8 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char
                                fch = *format++;
                        } while( fch && fch != ']' );
 
+                       if( maxlen == 0 )
+                               maxlen = -1;
                        ich = 0;
                        while( maxlen -- && (ich = __getc(h)) && memchr(set_start, set_len, ich) )
                        {
@@ -337,6 +351,7 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char
                        }
                        if( maxlen >= 0 && ich )
                                __rewind(h);
+                       if(ptr._char)   *ptr._char++ = 0;
                        valtype = _VCSCANF_NOTYPE;
                        break;
                case 'p': // read back printf("%p")
@@ -354,7 +369,10 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char
                        valtype = _VCSCANF_NOTYPE;
                        break;
                }
-               
+
+               if(fail)
+                       break;          
+
                switch(valtype)
                {
                case _VCSCANF_NOTYPE:
@@ -406,7 +424,8 @@ int vsscanf(const char *str, const char *format, va_list ap)
 
 int _vfscanf_getc(void *h)
 {
-       return fgetc(h);        // TODO: Handle -1 -> 0
+       int ch = fgetc(h);
+       return ch == -1 ? 0 : ch;
 }
 void _vfscanf_rewind(void *h)
 {
index 840e24d..39d37a4 100644 (file)
@@ -348,6 +348,12 @@ EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp)
        }\r
        else {\r
                ret = _SysRead(fp->FD, ptr, size*num);\r
+               if( ret == (size_t)-1)\r
+                       return -1;\r
+               if( ret == 0 && size*num > 0 ) {\r
+                       fp->Flags |= FILE_FLAG_EOF;\r
+                       return 0;\r
+               }\r
                ret /= size;\r
        }\r
                \r
@@ -403,7 +409,7 @@ EXPORT int putchar(int c)
 EXPORT int fgetc(FILE *fp)\r
 {\r
        char    ret = 0;\r
-       if( fread(&ret, 1, 1, fp) == (size_t)-1 )\r
+       if( fread(&ret, 1, 1, fp) != 1 )\r
                return -1;\r
        return ret;\r
 }\r
@@ -452,7 +458,7 @@ EXPORT int vsprintf(char * __s, const char *__format, va_list __args)
        return vsnprintf(__s, 0x7FFFFFFF, __format, __args);\r
 }\r
 \r
-//sprintfv\r
+\r
 /**\r
  * \fn EXPORT void vsnprintf(char *buf, const char *format, va_list args)\r
  * \brief Prints a formatted string to a buffer\r
@@ -470,11 +476,11 @@ EXPORT int vsnprintf(char *buf, size_t __maxlen, const char *format, va_list arg
        uint64_t        arg;\r
         int    bLongLong, bPadLeft;\r
 \r
-       void _addchar(char ch)\r
-       {\r
-               if(buf && pos < __maxlen)       buf[pos] = ch;\r
-               pos ++;\r
-       }\r
+       #define _addchar(ch) do { \\r
+               if(buf && pos < __maxlen)       buf[pos] = (ch); \\r
+               else (void)(ch); \\r
+               pos ++; \\r
+       } while(0)\r
 \r
        tmp[32] = '\0';\r
        \r
@@ -637,6 +643,7 @@ EXPORT int vsnprintf(char *buf, size_t __maxlen, const char *format, va_list arg
        }\r
        _addchar('\0');\r
        pos --;\r
+       #undef _addchar\r
        \r
        //_SysDebug("vsnprintf: buf = '%s'", buf);\r
        \r
@@ -708,7 +715,7 @@ EXPORT int printf(const char *format, ...)
        va_end(args);\r
        \r
        // Send to stdout\r
-       _SysWrite(_stdout, buf, size+1);\r
+       _SysWrite(_stdout, buf, size);\r
        \r
        // Free buffer\r
        free(buf);\r
index db78b5a..9b7aac0 100644 (file)
@@ -13,8 +13,6 @@ typedef unsigned int  u_int;
 typedef struct stat    t_fstat;
 
 
-#define CLONE_VM       0x10
-
 typedef unsigned int   id_t;
 typedef unsigned long  pid_t;
 typedef unsigned long  tid_t;
diff --git a/Usermode/Libraries/libunicode.so_src/Makefile b/Usermode/Libraries/libunicode.so_src/Makefile
new file mode 100644 (file)
index 0000000..d515f3d
--- /dev/null
@@ -0,0 +1,14 @@
+# Acess 2 "libunicode"
+#
+
+include ../Makefile.cfg
+
+CPPFLAGS +=
+CFLAGS   += -Wall
+LDFLAGS  += -lc -soname libunicode.so
+
+OBJ = main.o utf-8.o
+BIN = libunicode.so
+
+include ../Makefile.tpl
+
diff --git a/Usermode/Libraries/libunicode.so_src/include_exp/unicode.h b/Usermode/Libraries/libunicode.so_src/include_exp/unicode.h
new file mode 100644 (file)
index 0000000..ef0eb56
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Acess2 "libunicode" UTF Parser
+ * - By John Hodge (thePowersGang)
+ *
+ * unicode.h
+ * - Main header
+ */
+#ifndef _LIBUNICODE__UNICODE_H_
+#define _LIBUNICODE__UNICODE_H_
+
+#include <stdint.h>
+
+/**
+ * \breif Read a single codepoint from  a UTF-8 stream
+ * \return Number of bytes read
+ */
+extern int     ReadUTF8(const char *Input, uint32_t *Val);
+/**
+ * \brief Read backwards in the stream
+ */
+extern int     ReadUTF8Rev(const char *Base, int Offset, uint32_t *Val);
+/**
+ * \breif Write a single codepoint to a UTF-8 stream
+ */
+extern int     WriteUTF8(char *buf, uint32_t Val);
+
+
+static inline int      Unicode_IsPrinting(uint32_t Codepoint) { return 1; }
+
+#endif
+
diff --git a/Usermode/Libraries/libunicode.so_src/main.c b/Usermode/Libraries/libunicode.so_src/main.c
new file mode 100644 (file)
index 0000000..e39dc9b
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Acess2 "libunicode"
+ * - By John Hoge
+ *
+ * main.c
+ * - Stub main
+ */
+
+int SoMain(void)
+{
+       return 0;
+}
diff --git a/Usermode/Libraries/libunicode.so_src/utf-8.c b/Usermode/Libraries/libunicode.so_src/utf-8.c
new file mode 100644 (file)
index 0000000..3aa9d1a
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Acess2 "libunicode" UTF Parser
+ * - By John Hodge (thePowersGang)
+ *
+ * utf-8.c
+ * - UTF-8 Parsing code
+ */
+#include <stdint.h>
+#include <unicode.h>
+
+/**
+ * \brief Read a UTF-8 character from a string
+ * \param Input        Source UTF-8 encoded string
+ * \param Val  Destination for read codepoint
+ * \return Number of bytes read/used
+ */
+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 & 0xF8) == 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;
+}
+
+/**
+ * \brief Get the UTF-8 character before the 
+ * \
+ */
+int ReadUTF8Rev(const char *Base, int Offset, uint32_t *Val)
+{
+        int    len = 0;
+       
+       // Scan backwards for the beginning of the character
+       while( Offset > 0 && (Base[Offset--] & 0xC0) == 0x80 )
+               len ++;
+       // Invalid string (no beginning)
+       if(Offset == 0 && (Base[Offset] & 0xC0) == 0x80 )
+               return len;
+       
+       len ++; // First character
+       if( ReadUTF8(Base+Offset, Val) != len ) {
+               *Val = 0xFFFD;
+       }
+       return len;
+}
+
+/**
+ * \brief Write a UTF-8 character sequence to a string
+ * \param buf  Destination buffer (must have at least 4 bytes available)
+ * \param Val  Unicode codepoint to write
+ * \return Number of bytes written
+ * \note Does not NULL terminate the string in \a buf
+ */
+int WriteUTF8(char *buf, uint32_t Val)
+{
+       uint8_t *str = (void*)buf;
+       
+       // ASCII
+       if( Val < 128 ) {
+               if(str) {
+                       *str = Val;
+               }
+               return 1;
+       }
+       
+       // Two Byte
+       if( Val < 0x8000 ) {
+               if(str) {
+                       *str = 0xC0 | (Val >> 6);
+                       str ++;
+                       *str = 0x80 | (Val & 0x3F);
+               }
+               return 2;
+       }
+       
+       // Three Byte
+       if( Val < 0x10000 ) {
+               if(str) {
+                       *str = 0xE0 | (Val >> 12);
+                       str ++;
+                       *str = 0x80 | ((Val >> 6) & 0x3F);
+                       str ++;
+                       *str = 0x80 | (Val & 0x3F);
+               }
+               return 3;
+       }
+       
+       // Four Byte
+       if( Val < 0x110000 ) {
+               if(str) {
+                       *str = 0xF0 | (Val >> 18);
+                       str ++;
+                       *str = 0x80 | ((Val >> 12) & 0x3F);
+                       str ++;
+                       *str = 0x80 | ((Val >> 6) & 0x3F);
+                       str ++;
+                       *str = 0x80 | (Val & 0x3F);
+               }
+               return 4;
+       }
+       
+       // UTF-8 Doesn't support more than four bytes
+       return 0;
+}
+

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