Merge branch 'master' of [email protected]:acess2
authorJohn Hodge <[email protected]>
Wed, 25 May 2011 14:29:08 +0000 (14:29 +0000)
committerJohn Hodge <[email protected]>
Wed, 25 May 2011 14:29:08 +0000 (14:29 +0000)
94 files changed:
AcessNative/acesskernel_src/Makefile
AcessNative/acesskernel_src/helpers.c
AcessNative/acesskernel_src/include/arch.h
AcessNative/acesskernel_src/include/heap.h
AcessNative/acesskernel_src/keyboard.c
AcessNative/acesskernel_src/main.c
AcessNative/acesskernel_src/nativefs.c
AcessNative/acesskernel_src/server.c
AcessNative/acesskernel_src/syscalls.c
AcessNative/acesskernel_src/threads.c
AcessNative/acesskernel_src/ui_sdl.c
AcessNative/acesskernel_src/vfs_handle.c
AcessNative/acesskernel_src/video.c
AcessNative/ld-acess_src/Makefile
AcessNative/ld-acess_src/binary.c
AcessNative/ld-acess_src/common.h
AcessNative/ld-acess_src/elf.c
AcessNative/ld-acess_src/main.c
AcessNative/ld-acess_src/request.c
AcessNative/ld-acess_src/request.h
AcessNative/ld-acess_src/syscalls.c
AcessNative/syscalls.h
Kernel/Makefile
Kernel/Makefile.BuildNum.x86_64
Kernel/arch/arm7/Makefile [new file with mode: 0644]
Kernel/arch/arm7/include/arch.h [new file with mode: 0644]
Kernel/arch/arm7/include/lock.h [new file with mode: 0644]
Kernel/arch/arm7/include/mm_virt.h [new file with mode: 0644]
Kernel/arch/arm7/include/proc.h [new file with mode: 0644]
Kernel/arch/arm7/lib.c [new file with mode: 0644]
Kernel/arch/arm7/main.c [new file with mode: 0644]
Kernel/arch/arm7/start.s [new file with mode: 0644]
Kernel/arch/x86/Makefile
Kernel/arch/x86/desctab.asm
Kernel/arch/x86/errors.c
Kernel/arch/x86/include/arch.h
Kernel/arch/x86/include/proc.h
Kernel/arch/x86/lib.c
Kernel/arch/x86/proc.asm
Kernel/arch/x86/proc.c
Kernel/arch/x86/start.asm
Kernel/arch/x86_64/Makefile
Kernel/arch/x86_64/include/arch.h
Kernel/arch/x86_64/lib.c
Kernel/arch/x86_64/mm_phys.c
Kernel/arch/x86_64/proc.c
Kernel/debug.c
Kernel/drv/dma.c [deleted file]
Kernel/drv/kb.c [deleted file]
Kernel/drv/kb_kbdus.h [deleted file]
Kernel/drv/proc.c
Kernel/drv/vterm.c
Kernel/drvutil.c
Kernel/heap.c
Kernel/include/acess.h
Kernel/include/heap.h
Kernel/include/mutex.h [new file with mode: 0644]
Kernel/include/threads.h
Kernel/include/threads_int.h [new file with mode: 0644]
Kernel/messages.c
Kernel/modules.c
Kernel/threads.c
Kernel/vfs/fs/root.c
Kernel/vfs/open.c
Kernel/vfs/select.c
Makefile
Makefile.cfg
Modules/Display/BochsGA/bochsvbe.c
Modules/Filesystems/Ext2/ext2fs.h
Modules/IPStack/firewall.c
Modules/IPStack/ipstack.h
Modules/IPStack/ipv6.c
Modules/IPStack/main.c
Modules/IPStack/tcp.c
Modules/Input/PS2KbMouse/Makefile [new file with mode: 0644]
Modules/Input/PS2KbMouse/kb.c [new file with mode: 0644]
Modules/Input/PS2KbMouse/kb_kbdus.h [new file with mode: 0644]
Modules/Input/PS2KbMouse/main.c [new file with mode: 0644]
Modules/Input/PS2KbMouse/ps2mouse.c [new file with mode: 0644]
Modules/USB/Core/uhci.c
Modules/USB/Core/uhci.h
Modules/x86/ISADMA/Makefile [new file with mode: 0644]
Modules/x86/ISADMA/dma.c [new file with mode: 0644]
Modules/x86/Makefile.tpl [new file with mode: 0644]
Usermode/Applications/axwin2_src/Shell_src/main.c
Usermode/Applications/axwin2_src/WM/interface.c
Usermode/Applications/axwin2_src/WM/wm.h
Usermode/Applications/imageview_src/Makefile [new file with mode: 0644]
Usermode/Applications/imageview_src/main.c [new file with mode: 0644]
Usermode/Libraries/libc.so_src/fileIO.c
Usermode/Libraries/libspiderscript.so_src/exec_ast.c
Usermode/include/acess/sys.h
Usermode/include/stdint.h
Usermode/include/sys/types.h

index c69cf06..ed79684 100644 (file)
@@ -7,8 +7,9 @@ endif
 \r
 KERNEL_SRC = ../../Kernel/\r
 \r
-KERNEL_OBJ := logging.o adt.o lib.o drvutil.o\r
-KERNEL_OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o vfs/nodecache.o vfs/mount.o vfs/memfile.o\r
+KERNEL_OBJ := logging.o adt.o lib.o drvutil.o debug.o\r
+KERNEL_OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o\r
+KERNEL_OBJ += vfs/nodecache.o vfs/mount.o vfs/memfile.o vfs/select.o\r
 KERNEL_OBJ += vfs/fs/root.o vfs/fs/devfs.o\r
 KERNEL_OBJ += drv/vterm.o drv/fifo.o drv/proc.o\r
 \r
@@ -17,6 +18,8 @@ OBJ += video.o keyboard.o mouse.o nativefs.o vfs_handle.o ui_sdl.o
 OBJ += $(addprefix $(KERNEL_SRC),$(KERNEL_OBJ))\r
 \r
 OBJ := $(addsuffix .$(PLATFORM),$(OBJ))\r
+DEPFILES  = $(filter %.o.$(PLATFORM),$(OBJ))\r
+DEPFILES := $(DEPFILES:%.o.$(PLATFORM)=%.d.$(PLATFORM))\r
 \r
 CPPFLAGS += -I include/ -I $(KERNEL_SRC)include/\r
 CFLAGS += -Wall -g\r
@@ -35,10 +38,15 @@ endif
 all: $(BIN)\r
 \r
 clean:\r
-       $(RM) $(BIN) $(OBJ)\r
+       $(RM) $(BIN) $(OBJ) $(DEPFILES)\r
 \r
 $(BIN): $(OBJ)\r
-       $(CC) $(LDFLAGS) -o $@ $(OBJ)\r
+       @echo [LINK] -o $@\r
+       @$(CC) $(LDFLAGS) -o $@ $(OBJ)\r
 \r
 %.o.$(PLATFORM): %.c\r
-       $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)\r
+       @echo [CC] -o $@\r
+       @$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)\r
+       @$(CC) -M $(CPPFLAGS) -MT $@ -o $*.d.$(PLATFORM) $<\r
+\r
+-include $(DEPFILES)\r
index e598ef1..b08906c 100644 (file)
@@ -10,6 +10,7 @@
 #include <stdarg.h>
 #include <sys/time.h>
 
+#if 0
 void LogF(const char *Fmt, ...)
 {
        va_list args;
@@ -51,7 +52,25 @@ void Panic(const char *Format, ...)
 
 void Debug_SetKTerminal(const char *Path)
 {
-       // Ignored, kernel debug goes to stdout
+       // Ignored, kernel debug goes to stdout instead of a virtual terminal
+}
+#endif
+
+void KernelPanic_SetMode(void)
+{
+       // NOP - No need
+}
+void KernelPanic_PutChar(char ch)
+{
+       fprintf(stderr, "%c", ch);
+}
+void Debug_PutCharDebug(char ch)
+{
+       printf("%c", ch);
+}
+void Debug_PutStringDebug(const char *String)
+{
+       printf("%s", String);
 }
 
 void *Heap_Allocate(const char *File, int Line, int ByteCount)
@@ -59,6 +78,21 @@ void *Heap_Allocate(const char *File, int Line, int ByteCount)
        return malloc(ByteCount);
 }
 
+void *Heap_AllocateZero(const char *File, int Line, int ByteCount)
+{
+       return calloc(ByteCount, 1);
+}
+
+void *Heap_Reallocate(const char *File, int Line, void *Ptr, int Bytes)
+{
+       return realloc(Ptr, Bytes);
+}
+
+void Heap_Deallocate(void *Ptr)
+{
+       free(Ptr);
+}
+
 tPAddr MM_GetPhysAddr(tVAddr VAddr)
 {
        return VAddr;   // HACK!
index a6685b2..849eba8 100644 (file)
@@ -28,10 +28,10 @@ typedef intptr_t    tPAddr;
 
 typedef        int     BOOL;
 
-typedef uint32_t       tTID;
-typedef uint32_t       tPID;
-typedef uint32_t       tUID;
-typedef uint32_t       tGID;
+//typedef uint32_t     tTID;
+//typedef uint32_t     tPID;
+//typedef uint32_t     tUID;
+//typedef uint32_t     tGID;
 
 struct sShortSpinlock
 {
@@ -42,7 +42,7 @@ struct sShortSpinlock
 #define SHORTLOCK(...)
 #define SHORTREL(...)
 
-#define        NUM_CFG_ENTRIES 10
+//#define      NUM_CFG_ENTRIES 10
 
 #endif
 
index 9315142..287250c 100644 (file)
@@ -6,5 +6,18 @@
 // NOP (stdlib.h defines the heap functions)
 // Heap_Allocate is used in _strdup
 extern void    *Heap_Allocate(const char *File, int Line, int ByteCount);
+extern void    *Heap_AllocateZero(const char *File, int Line, size_t Bytes);
+extern void    *Heap_Reallocate(const char *File, int Line, void *Ptr, size_t Bytes);
+extern void    Heap_Deallocate(void *Ptr);
+extern int     Heap_IsHeapAddr(void *Ptr);
+extern void    Heap_Validate(void);
+
+#define malloc(size)   Heap_Allocate(_MODULE_NAME_"/"__FILE__, __LINE__, (size))
+#define calloc(num,size)       Heap_AllocateZero(_MODULE_NAME_"/"__FILE__, __LINE__, (num)*(size))
+#define realloc(ptr,size)      Heap_Reallocate(_MODULE_NAME_"/"__FILE__, __LINE__, (ptr), (size))
+#define        free(ptr)       Heap_Deallocate((ptr))
+#define IsHeap(ptr)    Heap_IsHeapAddr((ptr))
+
+#define strdup(Str)    _strdup(_MODULE_NAME_"/"__FILE__, __LINE__, (Str))
 
 #endif
index 7689483..86f3787 100644 (file)
@@ -35,7 +35,7 @@ int NativeKeyboard_Install(char **Arguments)
        return MODULE_ERR_OK;
 }
 
-static const char * const csaIOCTL_NAMES[] = {
+static const char * csaIOCTL_NAMES[] = {
        DRV_IOCTLNAMES,
        DRV_KEYBAORD_IOCTLNAMES,
        NULL
index 3f152ef..363fea1 100644 (file)
@@ -13,21 +13,26 @@ extern int  VFS_Init(void);
 extern int     Video_Install(char **Arguments);
 extern int     NativeKeyboard_Install(char **Arguments);
 extern int     VT_Install(char **Arguments);
+extern int     VFS_Mount(const char *Device, const char *MountPoint, const char *Filesystem, const char *Options);
 extern int     SyscallServer(void);
 
+// === GLOBALS ===
+const char     *gsAcessDir = "../Usermode/Output/i386";
+
 // === CODE ===
 int main(int argc, char *argv[])
 {
        // Parse command line settings
        
        // Start UI subsystem
-       UI_Initialise(640, 480);
+       UI_Initialise(800, 480);
        
        // Initialise VFS
        VFS_Init();
        // - Start IO Drivers
        Video_Install(NULL);
        NativeKeyboard_Install(NULL);
+       NativeFS_Install(NULL);
        // - Start VTerm
        {
                char    *args[] = {
@@ -38,6 +43,10 @@ int main(int argc, char *argv[])
                VT_Install(args);
        }
        
+       VFS_Mount(gsAcessDir, "/Acess", "nativefs", "");
+
+       Debug_SetKTerminal("/Devices/VTerm/8");
+       
        // Start syscall server
        // - Blocks
        SyscallServer();
index 71774e2..6d6e2fe 100644 (file)
  * nativefs.c\r
  * - Host filesystem access\r
  */\r
-#include <acess.h>\r
-#include <vfs.h>\r
+#define DEBUG  1\r
+#include <acess.h>     // Acess\r
+#include <vfs.h>       // Acess\r
+#include <dirent.h>    // Posix\r
+#include <sys/stat.h>  // Posix\r
+#include <stdio.h>     // Posix\r
+\r
+//NOTES:\r
+// tVFS_Node->ImplPtr is a pointer to the filesystem flags (tNativeFS)\r
+// tVFS_Node->Data is the path string (heap string)\r
+// tVFS_Node->ImplInt is the path length\r
+\r
+// === STRUCTURES ===\r
+typedef struct\r
+{\r
+        int    InodeHandle;\r
+        int    bReadOnly;\r
+}      tNativeFS;\r
+\r
+// === PROTOTYPES ===\r
+ int   NativeFS_Install(char **Arguments);\r
+tVFS_Node      *NativeFS_Mount(const char *Device, const char **Arguments);\r
+void   NativeFS_Unmount(tVFS_Node *Node);\r
+tVFS_Node      *NativeFS_FindDir(tVFS_Node *Node, const char *Name);\r
+char   *NativeFS_ReadDir(tVFS_Node *Node, int Position);\r
+Uint64 NativeFS_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);\r
 \r
 // === GLOBALS ===\r
+tVFS_Driver    gNativeFS_Driver = {\r
+       "nativefs", 0,\r
+       NativeFS_Mount, NativeFS_Unmount,\r
+       NULL,\r
+};\r
 \r
 // === CODE ===\r
-tVFS_Node *Native_Mount(const char *Device, const char **Arguments)\r
+int NativeFS_Install(char **Arguments)\r
+{\r
+       VFS_AddDriver(&gNativeFS_Driver);\r
+       return 0;\r
+}\r
+\r
+tVFS_Node *NativeFS_Mount(const char *Device, const char **Arguments)\r
+{\r
+       tVFS_Node       *ret;\r
+       tNativeFS       *info;\r
+       DIR     *dp;\r
+       \r
+       dp = opendir(Device);\r
+       if(!dp) return NULL;\r
+       \r
+       // Check if directory exists\r
+       // Parse flags from arguments\r
+       info = malloc(sizeof(tNativeFS));\r
+       info->InodeHandle = Inode_GetHandle();\r
+       info->bReadOnly = 0;\r
+       // Create node\r
+       ret = malloc(sizeof(tVFS_Node));\r
+       memset(ret, 0, sizeof(tVFS_Node));\r
+       ret->Data = strdup(Device);\r
+       ret->ImplInt = strlen(ret->Data);\r
+       ret->ImplPtr = info;\r
+       ret->Inode = (Uint64)dp;\r
+       \r
+       ret->FindDir = NativeFS_FindDir;\r
+       ret->ReadDir = NativeFS_ReadDir;\r
+       \r
+       return ret;\r
+}\r
+\r
+void NativeFS_Unmount(tVFS_Node *Node)\r
 {\r
+       tNativeFS       *info = Node->ImplPtr;\r
+       Inode_ClearCache( info->InodeHandle );\r
+       closedir( (void *)Node->Inode );\r
+       free(Node->Data);\r
+       free(Node);\r
+       free(info);\r
+}\r
+\r
+void NativeFS_Close(tVFS_Node *Node)\r
+{\r
+       tNativeFS       *info = Node->ImplPtr;\r
+       Inode_UncacheNode( info->InodeHandle, Node->Inode );\r
+}\r
+\r
+tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name)\r
+{\r
+       char    *path = malloc(Node->ImplInt + 1 + strlen(Name) + 1);\r
+       tNativeFS       *info = Node->ImplPtr;\r
+       tVFS_Node       baseRet;\r
+       struct stat statbuf;\r
+\r
+       ENTER("pNode sName", Node, Name);\r
+       \r
+       // Create path\r
+       strcpy(path, Node->Data);\r
+       path[Node->ImplInt] = '/';\r
+       strcpy(path + Node->ImplInt + 1, Name);\r
+       \r
+       LOG("path = '%s'", path);\r
+       \r
+       // Check if file exists\r
+       if( stat(path, &statbuf) ) {\r
+               free(path);\r
+               LOG("Doesn't exist");\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       \r
+       memset(&baseRet, 0, sizeof(tVFS_Node));\r
+       \r
+       // Check file type\r
+       if( S_ISDIR(statbuf.st_mode) )\r
+       {\r
+               LOG("Directory");\r
+               baseRet.Inode = (Uint64) opendir(path);\r
+               baseRet.FindDir = NativeFS_FindDir;\r
+               baseRet.ReadDir = NativeFS_ReadDir;\r
+               baseRet.Flags |= VFS_FFLAG_DIRECTORY;\r
+       }\r
+       else\r
+       {\r
+               LOG("File");\r
+               baseRet.Inode = (Uint64) fopen(path, "r+");\r
+               baseRet.Read = NativeFS_Read;\r
+       }\r
+       \r
+       // Create new node\r
+       baseRet.ImplPtr = info;\r
+       baseRet.ImplInt = strlen(path);\r
+       baseRet.Data = path;\r
+       \r
+       LEAVE('-');\r
+       return Inode_CacheNode(info->InodeHandle, &baseRet);\r
+}\r
+\r
+char *NativeFS_ReadDir(tVFS_Node *Node, int Position)\r
+{\r
+       // Keep track of the current directory position\r
        return NULL;\r
 }\r
+\r
+Uint64 NativeFS_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
+{\r
+       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);\r
+       if( fseek( (void *)Node->Inode, Offset, SEEK_SET ) != 0 )\r
+       {\r
+               LEAVE('i', 0);\r
+               return 0;\r
+       }\r
+       LEAVE('-');\r
+       return fread( Buffer, 1, Length, (void *)Node->Inode );\r
+}\r
index 5d46f20..0cede83 100644 (file)
@@ -17,6 +17,7 @@
 # include <netinet/in.h>
 #endif
 #include "../syscalls.h"
+//#include <debug.h>
 
 #define        USE_TCP 0
 #define MAX_CLIENTS    16
@@ -36,6 +37,10 @@ typedef struct {
 
 // === IMPORTS ===
 extern tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength);
+extern int     Threads_CreateRootProcess(void);
+// HACK: Should have these in a header
+extern void    Log_Debug(const char *Subsys, const char *Message, ...);
+extern void    Log_Notice(const char *Subsys, const char *Message, ...);
 
 // === PROTOTYPES ===
 tClient        *Server_GetClient(int ClientID);
@@ -50,7 +55,6 @@ SOCKET        gSocket = INVALID_SOCKET;
 # define INVALID_SOCKET -1
  int   gSocket = INVALID_SOCKET;
 #endif
- int   giServer_NextClientID = 1;
 tClient        gaServer_Clients[MAX_CLIENTS];
 
 // === CODE ===
@@ -75,12 +79,17 @@ tClient *Server_GetClient(int ClientID)
        tClient *ret = NULL;
         int    i;
        
+       // Allocate an ID if needed
+       if(ClientID == 0)
+               ClientID = Threads_CreateRootProcess();
+       
        for( i = 0; i < MAX_CLIENTS; i ++ )
        {
                if( gaServer_Clients[i].ClientID == ClientID ) {
-                       ret = &gaServer_Clients[i];
-                       break;
+                       return &gaServer_Clients[i];
                }
+               if(!ret && gaServer_Clients[i].ClientID == 0)
+                       ret = &gaServer_Clients[i];
        }
        
        // Uh oh, no free slots
@@ -88,20 +97,18 @@ tClient *Server_GetClient(int ClientID)
        if( !ret )
                return NULL;
        
-       if( ClientID == 0 )
-       {
-               ret->ClientID = giServer_NextClientID ++;
-               ret->CurrentRequest = NULL;
+       // Allocate a thread for the process
+       ret->ClientID = ClientID;
+       ret->CurrentRequest = NULL;
                
-               if( !ret->WorkerThread ) {
-                       ret->WaitFlag = SDL_CreateCond();
-                       ret->Mutex = SDL_CreateMutex();
-                       SDL_mutexP( ret->Mutex );
-                       ret->WorkerThread = SDL_CreateThread( Server_WorkerThread, ret );
-               }
+       if( !ret->WorkerThread ) {
+               ret->WaitFlag = SDL_CreateCond();
+               ret->Mutex = SDL_CreateMutex();
+               SDL_mutexP( ret->Mutex );
+               ret->WorkerThread = SDL_CreateThread( Server_WorkerThread, ret );
        }
        
-       return &gaServer_Clients[i];
+       return ret;
 }
 
 int Server_WorkerThread(void *ClientPtr)
@@ -111,6 +118,7 @@ int Server_WorkerThread(void *ClientPtr)
        tRequestHeader  errorHeader;
         int    retSize = 0;
         int    sentSize;
+        int    cur_client_id = 0;
        
        #if USE_TCP
        #else
@@ -120,14 +128,20 @@ int Server_WorkerThread(void *ClientPtr)
                while( Client->CurrentRequest == NULL )
                        SDL_CondWait(Client->WaitFlag, Client->Mutex);
                
-               printf("Worker for %i, Job: %p\n", Client->ClientID, Client->CurrentRequest);
+               if(Client->ClientID != cur_client_id) {
+                       Threads_SetThread( Client->ClientID );
+                       cur_client_id = Client->ClientID;
+               }
+               
+               Log_Debug("AcessSrv", "Worker %i takes %p",
+                       Client->ClientID, Client->CurrentRequest);
                
                // Get the response
                retHeader = SyscallRecieve(Client->CurrentRequest, &retSize);
                
                if( !retHeader ) {
                        // Return an error to the client
-                       printf("Error returned by SyscallRecieve\n");
+                       printf("ERROR: SyscallRecieve failed\n");
                        errorHeader.CallID = Client->CurrentRequest->CallID;
                        errorHeader.NParams = 0;
                        retHeader = &errorHeader;
@@ -140,9 +154,10 @@ int Server_WorkerThread(void *ClientPtr)
                // Mark the thread as ready for another job
                Client->CurrentRequest = 0;
                
-               printf("Sending %i to %x:%i\n",
+               Log_Debug("AcessSrv", "Sending %i to %x:%i (Client %i)",
                        retSize, ntohl(Client->ClientAddr.sin_addr.s_addr),
-                       ntohs(Client->ClientAddr.sin_port)
+                       ntohs(Client->ClientAddr.sin_port),
+                       Client->ClientID
                        );
                
                // Return the data
@@ -213,7 +228,7 @@ int SyscallServer(void)
        listen(gSocket, 5);
        #endif
        
-       Log_Notice("Syscall", "Listening on 0.0.0.0:%i\n", SERVER_PORT);
+       Log_Notice("AcessSrv", "Listening on 0.0.0.0:%i", SERVER_PORT);
        
        // Wait for something to do :)
        for( ;; )
@@ -227,7 +242,7 @@ int SyscallServer(void)
                        break ;
                }
                
-               printf("Client connection %x:%i",
+               Log("Client connection %x:%i\n",
                        ntohl(client.sin_addr), ntohs(client.sin_port)
                        );
                
@@ -236,9 +251,11 @@ int SyscallServer(void)
                tRequestHeader  *req = (void*)data;
                struct sockaddr_in      addr;
                uint    clientSize = sizeof(addr);
-                int    length = recvfrom(gSocket, data, BUFSIZ, 0, (struct sockaddr*)&addr, &clientSize);
+                int    length;
                tClient *client;
                
+               length = recvfrom(gSocket, data, BUFSIZ, 0, (struct sockaddr*)&addr, &clientSize);
+               
                if( length == -1 ) {
                        perror("SyscallServer - recv");
                        break;
@@ -269,7 +286,8 @@ int SyscallServer(void)
                        continue;
                }
                
-               printf("client = %p, ClientID = %i\n", client, client->ClientID);
+               Log_Debug("AcessSrv", "Message from Client %i (%p)",
+                       client->ClientID, client);
                
                client->CurrentRequest = req;
                SDL_CondSignal(client->WaitFlag);
index eb9d8a2..f48b1a9 100644 (file)
@@ -5,13 +5,27 @@
  * Syscall Distribution
  */
 #include <acess.h>
+#include <threads.h>
 #include "../syscalls.h"
 
+// === IMPORTS ===
+extern int     Threads_Fork(void);     // AcessNative only function
+
 // === TYPES ===
-typedef int    (*tSyscallHandler)(const char *Format, void *Args, int *Sizes);
+typedef int    (*tSyscallHandler)(Uint *Errno, const char *Format, void *Args, int *Sizes);
 
 // === MACROS ===
-#define SYSCALL3(_name, _fmtstr, _t0, _t1, _t2, _call) int _name(const char*Fmt,void*Args,int*Sizes){\
+#define SYSCALL4(_name, _fmtstr, _t0, _t1, _t2, _t3, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
+       _t0 a0;_t1 a1;_t2 a2;_t3 a3;\
+       if(strcmp(Fmt,_fmtstr)!=0)return 0;\
+       a0 = *(_t0*)Args;Args+=sizeof(_t0);\
+       a1 = *(_t1*)Args;Args+=sizeof(_t1);\
+       a2 = *(_t2*)Args;Args+=sizeof(_t2);\
+       a3 = *(_t3*)Args;Args+=sizeof(_t3);\
+       _call\
+}
+
+#define SYSCALL3(_name, _fmtstr, _t0, _t1, _t2, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
        _t0 a0;_t1 a1;_t2 a2;\
        if(strcmp(Fmt,_fmtstr)!=0)return 0;\
        a0 = *(_t0*)Args;Args+=sizeof(_t0);\
@@ -20,7 +34,7 @@ typedef int   (*tSyscallHandler)(const char *Format, void *Args, int *Sizes);
        _call\
 }
 
-#define SYSCALL2(_name, _fmtstr, _t0, _t1, _call) int _name(const char*Fmt,void*Args,int*Sizes){\
+#define SYSCALL2(_name, _fmtstr, _t0, _t1, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
        _t0 a0;_t1 a1;\
        if(strcmp(Fmt,_fmtstr)!=0)return 0;\
        a0 = *(_t0*)Args;Args+=sizeof(_t0);\
@@ -28,19 +42,29 @@ typedef int (*tSyscallHandler)(const char *Format, void *Args, int *Sizes);
        _call;\
 }
 
-#define SYSCALL1(_name, _fmtstr, _t0, _call) int _name(const char*Fmt, void*Args,int*Sizes){\
+#define SYSCALL1(_name, _fmtstr, _t0, _call) int _name(Uint*Errno,const char*Fmt, void*Args,int*Sizes){\
        _t0 a0;\
        if(strcmp(Fmt,_fmtstr)!=0)return 0;\
        a0 = *(_t0*)Args;Args+=sizeof(_t0);\
        _call;\
 }
 
+#define SYSCALL0(_name, _call) int _name(Uint*Errno,const char*Fmt, void*Args,int*Sizes){\
+       if(strcmp(Fmt,"")!=0)return 0;\
+       _call;\
+}
+
 // === CODE ===
-int Syscall_Null(const char *Format, void *Args, int *Sizes)
+int Syscall_Null(Uint*Errno, const char *Format, void *Args, int *Sizes)
 {
        return 0;
 }
 
+SYSCALL1(Syscall_Exit, "i", int,
+       Threads_Exit(0, a0);
+       return 0;
+);
+
 SYSCALL2(Syscall_Open, "si", const char *, int,
        return VFS_Open(a0, a1|VFS_OPENFLAG_USER);
 );
@@ -49,12 +73,12 @@ SYSCALL1(Syscall_Close, "i", int,
        return 0;
 );
 SYSCALL3(Syscall_Read, "iid", int, int, void *,
-       if( Sizes[2] <= a1 )
+       if( Sizes[2] < a1 )
                return -1;
        return VFS_Read(a0, a1, a2);
 );
 SYSCALL3(Syscall_Write, "iid", int, int, const void *,
-       if( Sizes[2] <= a1 )
+       if( Sizes[2] < a1 )
                return -1;
        return VFS_Write(a0, a1, a2);
 );
@@ -72,10 +96,53 @@ SYSCALL3(Syscall_FInfo, "idi", int, void *, int,
                return -1;
        return VFS_FInfo(a0, a1, a2);
 );
+SYSCALL2(Syscall_ReadDir, "id", int, char *,
+       if(Sizes[1] < 255)
+               return -1;
+       return VFS_ReadDir(a0, a1);
+);
+SYSCALL3(Syscall_OpenChild, "isi", int, const char *, int,
+       return VFS_OpenChild(NULL, a0, a1, a2|VFS_OPENFLAG_USER);
+);
+SYSCALL2(Syscall_GetACL, "id", int, void *,
+       if(Sizes[1] < sizeof(tVFS_ACL))
+               return -1;
+       return VFS_GetACL(a0, (void*)a1);
+);
+SYSCALL4(Syscall_Mount, "ssss", const char *, const char *, const char *, const char *,
+       return VFS_Mount(a0, a1, a2, a3);
+);
+SYSCALL0(Syscall_Sleep,
+       Threads_Sleep();
+       return 0;
+);
+SYSCALL2(Syscall_WaitTID, "id", int, int *,
+       if(Sizes[1] < sizeof(int))
+               return -1;
+       return Threads_WaitTID(a0, a1);
+);
+SYSCALL1(Syscall_SetUID, "i", int,
+       if(Sizes[0] < sizeof(int)) {
+               *Errno = -EINVAL;       // TODO: Better message
+               return -1;
+       }
+       return Threads_SetUID(Errno, a0);
+);
+SYSCALL1(Syscall_SetGID, "i", int,
+       if(Sizes[0] < sizeof(int)) {
+               *Errno = -EINVAL;       // TODO: Better message
+               return -1;
+       }
+       return Threads_SetGID(Errno, a0);
+);
 
+SYSCALL0(Syscall_Fork,
+       return Threads_Fork();
+);
 
 const tSyscallHandler  caSyscalls[] = {
        Syscall_Null,
+       Syscall_Exit,
        Syscall_Open,
        Syscall_Close,
        Syscall_Read,
@@ -83,7 +150,19 @@ const tSyscallHandler       caSyscalls[] = {
        Syscall_Seek,
        Syscall_Tell,
        Syscall_IOCtl,
-       Syscall_FInfo
+       Syscall_FInfo,
+       Syscall_ReadDir,
+       Syscall_OpenChild,
+       Syscall_GetACL,
+       Syscall_Mount,
+       NULL,   // SYS_REOPEN
+       
+       Syscall_WaitTID,
+       Syscall_SetUID,
+       Syscall_SetGID,
+       
+       Syscall_Sleep,
+       Syscall_Fork
 };
 const int      ciNumSyscalls = sizeof(caSyscalls)/sizeof(caSyscalls[0]);
 /**
@@ -100,6 +179,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
         int    retDataLen = sizeof(Uint64);
        void    *returnData[Request->NParams];
         int    argSizes[Request->NParams];
+       Uint    ret_errno = 0;
        
        // Sanity check
        if( Request->CallID >= ciNumSyscalls ) {
@@ -107,6 +187,11 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                return NULL;
        }
        
+       if( !caSyscalls[Request->CallID] ) {
+               Log_Notice("Syscalls", "Unimplemented syscall %i", Request->CallID);
+               return NULL;
+       }
+       
        // Get size of argument list
        for( i = 0; i < Request->NParams; i ++ )
        {
@@ -138,7 +223,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
        }
        formatString[i] = '\0';
        
-       Log_Debug("Syscalls", "Request %i '%s'", Request->CallID, formatString);
+       LOG("Request %i(%s) '%s'", Request->CallID, casSYSCALL_NAMES[Request->CallID], formatString);
        
        {
                char    argListData[argListLen];
@@ -152,19 +237,19 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                        case ARG_TYPE_VOID:
                                break;
                        case ARG_TYPE_INT32:
-                               Log_Debug("Syscalls", "Arg %i: 0x%x", i, *(Uint32*)inData);
+                               LOG("Syscalls", "%i INT32: 0x%x", i, *(Uint32*)inData);
                                *(Uint32*)&argListData[argListLen] = *(Uint32*)inData;
                                argListLen += sizeof(Uint32);
                                inData += sizeof(Uint32);
                                break;
                        case ARG_TYPE_INT64:
-                               Log_Debug("Syscalls", "Arg %i: 0x%llx", i, *(Uint64*)inData);
+                               LOG("Syscalls", "%i INT64: 0x%llx", i, *(Uint64*)inData);
                                *(Uint64*)&argListData[argListLen] = *(Uint64*)inData;
                                argListLen += sizeof(Uint64);
                                inData += sizeof(Uint64);
                                break;
                        case ARG_TYPE_STRING:
-                               Log_Debug("Syscalls", "Arg %i: '%s'", i, (char*)inData);
+                               LOG("Syscalls", "%i STR: '%s'", i, (char*)inData);
                                *(char**)&argListData[argListLen] = (char*)inData;
                                argListLen += sizeof(void*);
                                inData += Request->Params[i].Length;
@@ -185,7 +270,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                                {
                                        // Allocate and zero the buffer
                                        returnData[i] = calloc(1, Request->Params[i].Length);
-                                       Log_Debug("Syscalls", "Arg %i: %i %p", i,
+                                       LOG("Syscalls", "%i ZDAT: %i %p", i,
                                                Request->Params[i].Length, returnData[i]);
                                        *(void**)&argListData[argListLen] = returnData[i];
                                        argListLen += sizeof(void*);
@@ -193,7 +278,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                                else
                                {
                                        returnData[i] = (void*)inData;
-                                       Log_Debug("Syscalls", "Arg %i: %i %p", i,
+                                       LOG("Syscalls", "%i DATA: %i %p", i,
                                                Request->Params[i].Length, returnData[i]);
                                        *(void**)&argListData[argListLen] = (void*)inData;
                                        argListLen += sizeof(void*);
@@ -203,7 +288,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                        }
                }
                
-               retVal = caSyscalls[Request->CallID](formatString, argListData, argSizes);
+               retVal = caSyscalls[Request->CallID](&ret_errno, formatString, argListData, argSizes);
        }
        
        // Allocate the return
@@ -221,22 +306,27 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
        *(Uint64*)inData = retVal;
        inData += sizeof(Uint64);
        
-       Log_Debug("Syscalls", "Return 0x%llx", retVal);
+       LOG("Syscalls", "Return 0x%llx", retVal);
        
+       retValueCount = 1;
        for( i = 0; i < Request->NParams; i ++ )
        {
                if( Request->Params[i].Type != ARG_TYPE_DATA )  continue;
                if( !(Request->Params[i].Flags & ARG_FLAG_RETURN) )     continue;
                
-               ret->Params[1 + i].Type = Request->Params[i].Type;
-               ret->Params[1 + i].Flags = 0;
-               ret->Params[1 + i].Length = Request->Params[i].Length;
+               ret->Params[retValueCount].Type = Request->Params[i].Type;
+               ret->Params[retValueCount].Flags = 0;
+               ret->Params[retValueCount].Length = Request->Params[i].Length;
+               
+               LOG("Syscalls", "Ret %i: Type %i, Len %i",
+                       i, Request->Params[i].Type, Request->Params[i].Length);
                
                memcpy(inData, returnData[i], Request->Params[i].Length);
                inData += Request->Params[i].Length;
                
                if( Request->Params[i].Flags & ARG_FLAG_ZEROED )
                        free( returnData[i] );  // Free temp buffer from above
+               retValueCount ++;
        }
        
        *ReturnLength = sizeof(tRequestHeader)
index 5a0ce13..9d12517 100644 (file)
@@ -5,13 +5,23 @@
  * threads.c
  * - Thread and process handling
  */
-#define _SIGNAL_H_
+#define _SIGNAL_H_     // Stop the acess signal.h being used
+#define _HEAP_H_       // Stop heap.h being imported (collides with stdlib heap)
+#define _VFS_EXT_H     // Stop vfs_ext.h being imported (collides with fd_set)
 #undef CLONE_VM        // Such a hack
 #include <arch.h>
+#undef NULL    // Remove acess definition
+#include <acess.h>
+#include <mutex.h>
+#include <semaphore.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <stdint.h>
 #include "/usr/include/signal.h"
+#include <SDL/SDL.h>
+
+// === IMPORTS ===
+void   VFS_CloneHandleList(int PID);
 
 // === STRUCTURES ===
 #if 0
@@ -24,6 +34,7 @@ typedef struct sState
 
 typedef struct sThread
 {
+       struct sThread  *GlobalNext;
        struct sThread  *Next;
 
         int    KernelTID;
@@ -36,27 +47,55 @@ typedef struct sThread
        char    *ThreadName;
 
         int    State;  // 0: Dead, 1: Active, 2: Paused, 3: Asleep
+        int    ExitStatus;
        #if 0
        tState  CurState;
        #endif
 
+       // Threads waiting for this thread to exit.
+       // Quit logic:
+       // - Wait for `WaitingThreads` to be non-null (maybe?)
+       // - Wake first in the queue, wait for it to be removed
+       // - Repeat
+       // - Free thread and quit kernel thread
+       struct sThread  *WaitingThreads;
+       struct sThread  *WaitingThreadsEnd;
+
        // Config?
        Uint    Config[NUM_CFG_ENTRIES];
 }      tThread;
 
+// === PROTOTYPES ===
+ int   Threads_Wake(tThread *Thread);
+
 // === GLOBALS ===
-tThread        gThread_Zero = {
+tThread        gThreadZero = {
        State: 1,
        ThreadName: "ThreadZero"
 };
-tThread        *gpThreads = &gThread_Zero;
-__thread tThread       *gpCurrentThread = &gThread_Zero;
+tThread        *gpThreads = &gThreadZero;
+__thread tThread       *gpCurrentThread = &gThreadZero;
+ int   giThreads_NextThreadID = 1;
 
 // === CODE ===
+void Threads_Dump(void)
+{
+       tThread *thread;
+       for( thread = gpThreads; thread; thread = thread->GlobalNext )
+       {
+               Log_Log("Threads", "TID %i (%s), PID %i",
+                       thread->TID, thread->ThreadName, thread->PID);
+               Log_Log("Threads", "User: %i, Group: %i",
+                       thread->UID, thread->GID);
+               Log_Log("Threads", "Kernel Thread ID: %i",
+                       thread->KernelTID);
+       }
+}
+
 tThread        *Threads_GetThread(int TID)
 {
        tThread *thread;
-       for( thread = gpThreads; thread; thread = thread->Next )
+       for( thread = gpThreads; thread; thread = thread->GlobalNext )
        {
                if( thread->TID == TID )
                        return thread;
@@ -64,12 +103,55 @@ tThread    *Threads_GetThread(int TID)
        return NULL;
 }
 
+/**
+ * \brief Clone a thread control block (with a different TID)
+ */
+tThread *Threads_CloneTCB(tThread *TemplateThread)
+{
+       tThread *ret = malloc(sizeof(tThread));
+       
+       memcpy(ret, TemplateThread, sizeof(tThread));
+       
+       ret->TID = giThreads_NextThreadID ++;
+       
+       ret->ThreadName = strdup(TemplateThread->ThreadName);
+       
+       ret->WaitingThreads = NULL;
+       ret->WaitingThreadsEnd = NULL;
+       
+       // Add to the end of the queue
+       // TODO: Handle concurrency issues
+       ret->GlobalNext = gpThreads;
+       gpThreads = ret;
+       
+       return ret;
+}
+
 tUID Threads_GetUID() { return gpCurrentThread->UID; }
 tGID Threads_GetGID() { return gpCurrentThread->GID; }
 tTID Threads_GetTID() { return gpCurrentThread->TID; }
-tPID Threads_GetPID() {
-       return SDL_ThreadID();
-       //return gpCurrentThread->PID;
+tPID Threads_GetPID() { return gpCurrentThread->PID; }
+
+int Threads_SetUID(int *Errno, tUID NewUID)
+{
+       if(Threads_GetUID() != 0) {
+               if(Errno)       *Errno = -EACCES;
+               return -1;
+       }
+       
+       gpCurrentThread->UID = NewUID;
+       return 0;
+}
+
+int Threads_SetGID(int *Errno, tGID NewGID)
+{
+       if(Threads_GetUID() != 0) {
+               if(Errno)       *Errno = -EACCES;
+               return -1;
+       }
+       
+       gpCurrentThread->GID = NewGID;
+       return 0;
 }
 
 Uint *Threads_GetCfgPtr(int Index)
@@ -81,8 +163,62 @@ Uint *Threads_GetCfgPtr(int Index)
        return &gpCurrentThread->Config[Index];
 }
 
+int Threads_WaitTID(int TID, int *Status)
+{
+       // Any Child
+       if(TID == -1) {
+               Log_Error("Threads", "TODO: Threads_WaitTID(TID=-1) - Any Child");
+               return -1;
+       }
+       
+       // Any peer/child thread
+       if(TID == 0) {
+               Log_Error("Threads", "TODO: Threads_WaitTID(TID=0) - Any Child/Sibling");
+               return -1;
+       }
+       
+       // TGID = abs(TID)
+       if(TID < -1) {
+               Log_Error("Threads", "TODO: Threads_WaitTID(TID<0) - TGID");
+               return -1;
+       }
+       
+       // Specific Thread
+       if(TID > 0) {
+               
+               tThread *thread = Threads_GetThread(TID);
+               tThread *us = gpCurrentThread;
+               if(!thread)     return -1;
+               
+               us->Next = NULL;
+               us->State = 3;
+               if(thread->WaitingThreadsEnd)
+               {
+                       thread->WaitingThreadsEnd->Next = us;
+                       thread->WaitingThreadsEnd = us;
+               }
+               else
+               {
+                       thread->WaitingThreads = us;
+                       thread->WaitingThreadsEnd = us;
+               }
+               
+               while(thread->State != 0)
+                       pause();
+               
+               if(Status)      *Status = thread->ExitStatus;
+               thread->WaitingThreads = thread->WaitingThreads->Next;
+               us->Next = NULL;
+               
+               return TID;
+       }
+       
+       return 0;
+}
+
 void Threads_Sleep(void)
 {
+       // TODO: Add to a sleeping queue
        pause();
 }
 
@@ -91,22 +227,70 @@ void Threads_Yield(void)
 //     yield();
 }
 
+void Threads_Exit(int TID, int Status)
+{
+       tThread *toWake;
+       
+//     VFS_Handles_Cleanup();
+       
+       #if 1
+       // Wait for the thread to be waited upon
+       while( gpCurrentThread->WaitingThreads == NULL )
+               SDL_Delay(10);
+       #endif
+       
+       while( (toWake = gpCurrentThread->WaitingThreads) )
+       {
+               Threads_Wake(toWake);
+               
+               while(gpCurrentThread->WaitingThreads == toWake)
+                       SDL_Delay(10);
+       }
+}
+
+int Threads_Wake(tThread *Thread)
+{
+       kill( Thread->KernelTID, SIGUSR1 );
+       return 0;
+}
+
 int Threads_WakeTID(tTID TID)
 {
        tThread *thread;
        thread = Threads_GetThread(TID);
        if( !thread )   return -1;
-       kill( thread->KernelTID, SIGUSR1 );
-       return 0;
+       return Threads_Wake(thread);
+}
+
+int Threads_CreateRootProcess(void)
+{
+       tThread *thread = Threads_CloneTCB(&gThreadZero);
+       thread->PID = thread->TID;
+       
+       // Handle list is created on first open
+       
+       return thread->PID;
+}
+
+int Threads_Fork(void)
+{
+       tThread *thread = Threads_CloneTCB(gpCurrentThread);
+       thread->PID = thread->TID;
+       // Duplicate the VFS handles (and nodes) from vfs_handle.c
+       
+       VFS_CloneHandleList(thread->PID);
+       
+       return thread->PID;
 }
 
-void Mutex_Acquire(tMutex *Mutex)
+int Mutex_Acquire(tMutex *Mutex)
 {
        if(!Mutex->Protector.IsValid) {
                pthread_mutex_init( &Mutex->Protector.Mutex, NULL );
                Mutex->Protector.IsValid = 1;
        }
        pthread_mutex_lock( &Mutex->Protector.Mutex );
+       return 0;
 }
 
 void Mutex_Release(tMutex *Mutex)
@@ -114,6 +298,27 @@ void Mutex_Release(tMutex *Mutex)
        pthread_mutex_unlock( &Mutex->Protector.Mutex );
 }
 
+void Semaphore_Init(tSemaphore *Sem, int InitValue, int MaxValue, const char *Module, const char *Name)
+{
+       memset(Sem, 0, sizeof(tSemaphore));
+       // HACK: Use `Sem->Protector` as space for the semaphore pointer
+       *(void**)(&Sem->Protector) = SDL_CreateSemaphore(InitValue);
+}
+
+int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
+{
+       SDL_SemWait( *(void**)(&Sem->Protector) );
+       return 1;
+}
+
+int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
+{
+        int    i;
+       for( i = 0; i < AmmountToAdd; i ++ )
+               SDL_SemPost( *(void**)(&Sem->Protector) );
+       return AmmountToAdd;
+}
+
 #if 0
 void Threads_Sleep()
 {
index 546021a..3f3cb13 100644 (file)
@@ -39,6 +39,9 @@ int UI_Initialise(int MaxWidth, int MaxHeight)
        // Start main thread
        gInputThread = SDL_CreateThread(UI_MainThread, NULL);
        
+       while(gScreen == NULL)
+               SDL_Delay(10);
+       
        return 0;
 }
 
@@ -152,15 +155,21 @@ void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap)
        SDL_Surface     *tmp;
        SDL_Rect        dstRect;
        
+//     printf("UI_BlitBitmap: Blit to (%i,%i) from %p (%ix%i 32bpp bitmap)\n",
+//             DstX, DstY, Bitmap, SrcW, SrcH);
+       
        tmp = SDL_CreateRGBSurfaceFrom(Bitmap, SrcW, SrcH, 32, SrcW*4,
                0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
        SDL_SetAlpha(tmp, 0, SDL_ALPHA_OPAQUE);
        
        dstRect.x = DstX;       dstRect.y = DstY;
+       dstRect.w = -1; dstRect.h = -1;
        
        SDL_BlitSurface(tmp, NULL, gScreen, &dstRect);
+       //SDL_BlitSurface(tmp, NULL, gScreen, NULL);
        
        SDL_FreeSurface(tmp);
+//     SDL_Flip(gScreen);
 }
 
 void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H)
@@ -182,10 +191,12 @@ void UI_FillBitmap(int X, int Y, int W, int H, Uint32 Value)
        dstRect.x = X;  dstRect.y = Y;
        dstRect.w = W;  dstRect.h = H;
        
+//     printf("UI_FillBitmap: gScreen = %p\n", gScreen);
        SDL_FillRect(gScreen, &dstRect, Value);
 }
 
 void UI_Redraw(void)
 {
-       // No-Op, we're not using double buffering
+       // TODO: Keep track of changed rectangle
+       SDL_UpdateRect(gScreen, 0, 0, giUI_Width, giUI_Height);
 }
index 5a94e6d..91caeff 100644 (file)
@@ -2,11 +2,11 @@
  * Acess2 VFS
  * - AllocHandle, GetHandle
  */
-#define DEBUG  0
+#define DEBUG  1
 #include <acess.h>
-#include "vfs.h"
-#include "vfs_int.h"
-#include "vfs_ext.h"
+#include <vfs.h>
+#include <vfs_int.h>
+#include <vfs_ext.h>
 
 // === CONSTANTS ===
 #define MAX_KERNEL_FILES       128
@@ -32,6 +32,59 @@ tUserHandles *gpUserHandles = NULL;
 tVFS_Handle    gaKernelHandles[MAX_KERNEL_FILES];
 
 // === CODE ===
+tUserHandles *VFS_int_GetUserHandles(int PID, int bCreate)
+{
+       tUserHandles    *ent, *prev = NULL;
+       for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) {
+               if( ent->PID == PID ) {
+                       Log_Warning("VFS", "Process %i already has a handle list", PID);
+                       return ent;
+               }
+               if( ent->PID > PID )    break;
+       }
+       
+       if(!bCreate)
+               return NULL;
+       
+       ent = calloc( 1, sizeof(tUserHandles) );
+       ent->PID = PID;
+       if( prev ) {
+               ent->Next = prev->Next;
+               prev->Next = ent;
+       }
+       else {
+               ent->Next = gpUserHandles;
+               gpUserHandles = ent;
+       }
+       Log_Notice("VFS", "Created handle list for process %i", PID);
+       return ent;
+}
+
+/**
+ * \brief Clone the handle list of the current process into another
+ */
+void VFS_CloneHandleList(int PID)
+{
+       tUserHandles    *ent;
+       tUserHandles    *cur;
+        int    i;
+       
+       cur = VFS_int_GetUserHandles(Threads_GetPID(), 0);
+       if(!cur)        return ;        // Don't need to do anything if the current list is empty
+       
+       ent = VFS_int_GetUserHandles(PID, 1);
+       
+       memcpy(ent->Handles, cur->Handles, CFGINT(CFG_VFS_MAXFILES)*sizeof(tVFS_Handle));
+       
+       for( i = 0; i < CFGINT(CFG_VFS_MAXFILES); i ++ )
+       {
+               if(!cur->Handles[i].Node)       continue;
+               
+               if(ent->Handles[i].Node->Reference)
+                       ent->Handles[i].Node->Reference(ent->Handles[i].Node);
+       }
+}
+
 /**
  * \fn tVFS_Handle *VFS_GetHandle(int FD)
  * \brief Gets a pointer to the handle information structure
@@ -42,32 +95,42 @@ tVFS_Handle *VFS_GetHandle(int FD)
        
        //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
        
-       if(FD < 0)      return NULL;
+       if(FD < 0) {
+               LOG("FD (%i) < 0, RETURN NULL", FD);
+               return NULL;
+       }
        
        if(FD & VFS_KERNEL_FLAG) {
                FD &= (VFS_KERNEL_FLAG - 1);
-               if(FD >= MAX_KERNEL_FILES)      return NULL;
+               if(FD >= MAX_KERNEL_FILES) {
+                       LOG("FD (%i) > MAX_KERNEL_FILES (%i), RETURN NULL", FD, MAX_KERNEL_FILES);
+                       return NULL;
+               }
                h = &gaKernelHandles[ FD ];
        }
-       else {
+       else
+       {
                tUserHandles    *ent;
-                int    pid = Server_GetClientID();
-               for( ent = gpUserHandles; ent; ent = ent->Next ) {
-                       if( ent->PID == pid )   break;
-                       if( ent->PID > pid ) {
-                               Log_Error("VFS", "PID %i does not have a handle list", pid);
-                               return NULL;
-                       }
+                int    pid = Threads_GetPID();
+               
+               ent = VFS_int_GetUserHandles(pid, 0);
+               if(!ent) {
+                       Log_Error("VFS", "Client %i does not have a handle list (>)", pid);
+                       return NULL;
                }
-               if( !ent ) {
-                       Log_Error("VFS", "PID %i does not have a handle list", pid);
+               
+               if(FD >= CFGINT(CFG_VFS_MAXFILES)) {
+                       LOG("FD (%i) > Limit (%i), RETURN NULL", FD, CFGINT(CFG_VFS_MAXFILES));
                        return NULL;
                }
-               if(FD >= CFGINT(CFG_VFS_MAXFILES))      return NULL;
                h = &ent->Handles[ FD ];
+               LOG("FD (%i) -> %p (Mode:0x%x,Node:%p)", FD, h, h->Mode, h->Node);
        }
        
-       if(h->Node == NULL)     return NULL;
+       if(h->Node == NULL) {
+               LOG("FD (%i) Unused", FD);
+               return NULL;
+       }
        //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
        return h;
 }
@@ -79,24 +142,9 @@ int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
        // Check for a user open
        if(bIsUser)
        {
-               tUserHandles    *ent, *prev = NULL;
-                int    pid = Server_GetClientID();
-               for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) {
-                       if( ent->PID == pid )   break;
-                       if( ent->PID > pid )    break;
-               }
-               if( !ent || ent->PID > pid ) {
-                       ent = calloc( 1, sizeof(tUserHandles) );
-                       ent->PID = pid;
-                       if( prev ) {
-                               ent->Next = prev->Next;
-                               prev->Next = ent;
-                       }
-                       else {
-                               ent->Next = gpUserHandles;
-                               gpUserHandles = ent;
-                       }
-               }
+               tUserHandles    *ent;
+               // Find the PID's handle list
+               ent = VFS_int_GetUserHandles(Threads_GetPID(), 1);
                // Get a handle
                for(i=0;i<CFGINT(CFG_VFS_MAXFILES);i++)
                {
index 4645b95..f3903fb 100644 (file)
@@ -4,6 +4,7 @@
  * Video Driver
  */
 #define VERSION        ((0<<8)|10)
+#define DEBUG  0
 #include <acess.h>
 #include <vfs.h>
 #include <fs_devfs.h>
@@ -90,6 +91,8 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                
                // Sanity Check
                if( Offset > (Uint64)(heightInChars*widthInChars) ) {
+                       Log_Notice("Video", "Offset (%i) > %i*%i (%i)", Offset,
+                               heightInChars, widthInChars, heightInChars*widthInChars);
                        LEAVE('i', 0);
                        return 0;
                }
@@ -106,21 +109,36 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                        Log_Notice("Video", "Clipping write size to %i characters", (int)Length);
                }
                
+//             Log_Debug("Video", "(%i,%i) %i chars", x, y, (int)Length);
+               
                // Print characters
                for( i = 0; i < (int)Length; i++ )
                {
-                       VT_Font_Render(
-                               chars->Ch,
-                               //dest + x*giVT_CharWidth, pitch,
-                               tmpBuf, giVT_CharWidth,
-                               VT_Colour12to24(chars->BGCol),
-                               VT_Colour12to24(chars->FGCol)
-                               );
-                       UI_BlitBitmap(
-                               x*giVT_CharWidth, y*giVT_CharHeight,
-                               giVT_CharWidth, giVT_CharHeight,
-                               tmpBuf
-                               );
+                       if( chars->Ch )
+                       {
+//                             Log_Debug("Video", "Render Char 0x%x in 0x%03x:%03x",
+//                                     chars->Ch, chars->FGCol, chars->BGCol);
+                               memset(tmpBuf, 0xFF, giVT_CharWidth*giVT_CharHeight*4);
+                               VT_Font_Render(
+                                       chars->Ch,
+                                       tmpBuf, 32, giVT_CharWidth*4,
+                                       VT_Colour12to24(chars->BGCol),
+                                       VT_Colour12to24(chars->FGCol)
+                                       );
+                               UI_BlitBitmap(
+                                       x*giVT_CharWidth, y*giVT_CharHeight,
+                                       giVT_CharWidth, giVT_CharHeight,
+                                       tmpBuf
+                                       );
+                       }
+                       else
+                       {
+                               UI_FillBitmap(
+                                       x*giVT_CharWidth, y*giVT_CharHeight,
+                                       giVT_CharWidth, giVT_CharHeight,
+                                       VT_Colour12to24(chars->BGCol)
+                                       );
+                       }
                        
                        chars ++;
                        x ++;
@@ -146,7 +164,6 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                }
                
                LOG("buffer = %p", Buffer);
-               LOG("Updating Framebuffer (%p to %p)", destBuf, destBuf + (Uint)Length);
                
                startX = Offset % giUI_Width;
                startY = Offset / giUI_Width;
@@ -211,7 +228,7 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        return Length;
 }
 
-const char * const csaVIDEO_IOCTLS[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};
+const char * csaVIDEO_IOCTLS[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};
 /**
  * \brief Handle messages to the device
  */
index 4fb6ae2..eb84ad8 100644 (file)
@@ -19,21 +19,29 @@ endif
 
 CFLAGS += -Wall -Werror -g -m32
 
+DEPFILES  = $(filter %.o.$(PLATFORM),$(OBJ))
+DEPFILES := $(DEPFILES:%.o.$(PLATFORM)=%.d.$(PLATFORM))
+
 .PHONY: all clean
 
 all: $(BIN)
 
 clean:
-       $(RM) $(BIN) $(OBJ)
+       $(RM) $(BIN) $(OBJ) $(DEPFILES)
 
 $(BIN): link.ld.$(PLATFORM) $(OBJ)
 #      $(LD) -g -o $@ $(OBJ) -T link.ld.$(PLATFORM)
        $(CC) -g -o $@ $(OBJ) -m32 -Wl,-T,link.ld.$(PLATFORM)
 
 %.o.$(PLATFORM): %.c
-       $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)
+       @echo [CC] -o $@
+       @$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)
+       @$(CC) -M $(CPPFLAGS) -MT $@ -o $*.d.$(PLATFORM) $<
 
 # Modify the default makefile to put the executable at 1MB instead
 link.ld.lin:
-       $(LD) --verbose | awk '{ if( substr($$0,0,5) == "====="){ bPrint = !bPrint; } else { if(bPrint){ print $$0;} } }' | sed 's/\b0x0[08][0-9]*\b/0x00100000/g' > $@
+       @echo Making Linker Script ($@)
+       @$(LD) --verbose | awk '{ if( substr($$0,0,5) == "====="){ bPrint = !bPrint; } else { if(bPrint){ print $$0;} } }' | sed 's/\b0x0[08][0-9]*\b/0x00100000/g' > $@
+
+-include $(DEPFILES)
 
index 0ce9fac..6439fb9 100644 (file)
@@ -6,7 +6,7 @@
 #include <stdio.h>
 #include <string.h>
 
-#define LIBRARY_PATH   "../Usermode/Output/i386/Libs"
+#define LIBRARY_PATH   "$$$$../Usermode/Output/i386/Libs"
 
 // === TYPES ===
 typedef struct sBinary {
@@ -18,7 +18,7 @@ typedef struct sBinary {
 }      tBinary;
 
 // === IMPORTS ===
-extern void    *Elf_Load(FILE *FP);
+extern void    *Elf_Load(int fd);
 extern uintptr_t       Elf_Relocate(void *Base);
 extern int     Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret);
 extern int     ciNumBuiltinSymbols;
@@ -43,7 +43,7 @@ char *Binary_LocateLibrary(const char *Name)
 {
        char    *envPath = getenv("ACESS_LIBRARY_PATH");
         int    nameLen = strlen(Name);
-       FILE    *fp;
+        int    fd;
        
        if( strcmp(Name, "libld-acess.so") == 0 ) {
                return strdup("libld-acess.so");
@@ -59,9 +59,9 @@ char *Binary_LocateLibrary(const char *Name)
                strcat(tmp, "/");
                strcat(tmp, Name);
                
-               fp = fopen(tmp, "r");
-               if(fp) {
-                       fclose(fp);
+               fd = acess_open(tmp, 4);        // OPENFLAG_EXEC
+               if(fd != -1) {
+                       acess_close(fd);
                        return strdup(tmp);
                }
        }               
@@ -74,16 +74,20 @@ char *Binary_LocateLibrary(const char *Name)
                strcat(tmp, "/");
                strcat(tmp, Name);
                
+               #if DEBUG
                printf("Binary_LocateLibrary: tmp = '%s'\n", tmp);
+               #endif
 
-               fp = fopen(tmp, "r");
-               if(fp) {
-                       fclose(fp);
+               fd = acess_open(tmp, 4);        // OPENFLAG_EXEC
+               if(fd != -1) {
+                       acess_close(fd);
                        return strdup(tmp);
                }
        }               
 
+       #if DEBUG
        fprintf(stderr, "Unable to locate library '%s'\n", Name);
+       #endif
 
        return NULL;
 }
@@ -96,7 +100,9 @@ void *Binary_LoadLibrary(const char *Name)
 
        // Find File
        path = Binary_LocateLibrary(Name);
+       #if DEBUG
        printf("Binary_LoadLibrary: path = '%s'\n", path);
+       #endif
        if( !path ) {
                return NULL;
        }
@@ -104,10 +110,14 @@ void *Binary_LoadLibrary(const char *Name)
        ret = Binary_Load(path, (uintptr_t*)&entry);
        free(path);
        
+       #if DEBUG
        printf("Binary_LoadLibrary: ret = %p, entry = %p\n", ret, entry);
+       #endif
        if( entry ) {
                char    *argv[] = {NULL};
+               #if DEBUG
                printf("Calling '%s' entry point %p\n", Name, entry);
+               #endif
                entry(0, argv, NULL);
        }
 
@@ -116,8 +126,8 @@ void *Binary_LoadLibrary(const char *Name)
 
 void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
 {
-       FILE    *fp;
-       uint32_t        dword;
+        int    fd;
+       uint32_t        dword = 0xFA17FA17;
        void    *ret;
        uintptr_t       entry = 0;
        tBinFmt *fmt;
@@ -138,36 +148,43 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
                }
        }
 
-       fp = fopen(Filename, "r");
-       if( !fp ) {
+       fd = acess_open(Filename, 2|1); // Execute and Read
+       if( fd == -1 ) {
                // TODO: Handle libary directories
                perror("Opening binary");
                return NULL;
        }
 
-       fread(&dword, 1, 4, fp);
-       fseek(fp, 0, SEEK_SET);
+       acess_read(fd, 4, &dword);
+       acess_seek(fd, 0, ACESS_SEEK_SET);
        
        if( memcmp(&dword, "\x7F""ELF", 4) == 0 ) {
                fmt = &gElf_FormatDef;
        }
        else {
-               fclose(fp);
+               fprintf(stderr, "Unknown executable format (0x%08x)\n", dword);
+               acess_close(fd);
                return NULL;
        }
        
-       printf("fmt->Load(%p)...\n", fp);
-       ret = fmt->Load(fp);
-       printf("fmt->Load(%p): %p\n", fp, ret);
+       #if DEBUG
+       printf("fmt->Load(%i)...\n", fd);
+       #endif
+       ret = fmt->Load(fd);
+       acess_close(fd);
+       #if DEBUG
+       printf("fmt->Load(%p): %p\n", fd, ret);
+       #endif
        if( !ret ) {
-               fclose(fp);
                return NULL;
        }
        
        Binary_AddToList(Filename, ret, fmt);
 
        entry = fmt->Relocate(ret);
+       #if DEBUG
        printf("fmt->Relocate(%p): %p\n", ret, (void*)entry);
+       #endif
        if( !entry ) {
                // TODO: Clean up
                return NULL;
@@ -176,8 +193,6 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
        if( EntryPoint )
                *EntryPoint = entry;
 
-       fclose(fp);
-
        Binary_SetReadyToUse(ret);
 
        return ret;
@@ -224,7 +239,7 @@ int Binary_GetSymbol(const char *SymbolName, uintptr_t *Value)
                }
        }
        
-       // TODO: Search list of loaded binaries
+       // Search list of loaded binaries
        for(bin = gLoadedBinaries; bin; bin = bin->Next)
        {
                if( !bin->Ready )       continue;
index 4667acb..b544a45 100644 (file)
@@ -18,6 +18,15 @@ extern uintptr_t     FindFreeRange(size_t ByteCount, int MaxBits);
 extern void    Warning(const char *Format, ...);
 extern void    Notice(const char *Format, ...);
 
+#define ACESS_SEEK_CUR 0
+#define ACESS_SEEK_SET 1
+#define ACESS_SEEK_END -1
+
+extern int     acess_open(const char *Path, int Flags);
+extern void    acess_close(int FD);
+extern size_t  acess_read(int FD, size_t Bytes, void *Dest);
+extern int     acess_seek(int FD, int64_t Offset, int Dir);
+
 typedef struct {
        char    *Name;
        void    *Value;
@@ -26,7 +35,7 @@ typedef struct {
 typedef struct sBinFmt {
        struct sBinFmt  *Next;
        char    *Name;
-       void    *(*Load)(FILE *fp);
+       void    *(*Load)(int fd);
        uintptr_t       (*Relocate)(void *base);
         int    (*GetSymbol)(void*,char*,uintptr_t*);
 }      tBinFmt;
index a79b591..daea044 100644 (file)
 #endif\r
 \r
 // === PROTOTYPES ===\r
-void   *Elf_Load(FILE *FP);\r
+void   *Elf_Load(int FD);\r
 uintptr_t      Elf_Relocate(void *Base);\r
  int   Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret);\r
  int   Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *Base);\r
 uint32_t       Elf_Int_HashString(char *str);\r
 \r
 // === CODE ===\r
-void *Elf_Load(FILE *FP)\r
+void *Elf_Load(int FD)\r
 {\r
        Elf32_Ehdr      hdr;\r
        Elf32_Phdr      *phtab;\r
@@ -46,10 +46,10 @@ void *Elf_Load(FILE *FP)
        uint32_t        addr;\r
        uint32_t        baseDiff = 0;\r
        \r
-       ENTER("pFP", FP);\r
+       ENTER("iFD", FD);\r
        \r
        // Read ELF Header\r
-       fread(&hdr, sizeof(hdr), 1, FP);\r
+       acess_read(FD, sizeof(hdr), &hdr);\r
        \r
        // Check the file type\r
        if(hdr.ident[0] != 0x7F || hdr.ident[1] != 'E' || hdr.ident[2] != 'L' || hdr.ident[3] != 'F') {\r
@@ -74,8 +74,8 @@ void *Elf_Load(FILE *FP)
                return NULL;\r
        }\r
        LOG("hdr.phoff = 0x%08x\n", hdr.phoff);\r
-       fseek(FP, hdr.phoff, SEEK_SET);\r
-       fread(phtab, sizeof(Elf32_Phdr), hdr.phentcount, FP);\r
+       acess_seek(FD, hdr.phoff, ACESS_SEEK_SET);\r
+       acess_read(FD, sizeof(Elf32_Phdr) * hdr.phentcount, phtab);\r
        \r
        // Count Pages\r
        iPageCount = 0;\r
@@ -108,8 +108,8 @@ void *Elf_Load(FILE *FP)
                        continue;\r
                if( phtab[i].VAddr < base )\r
                        base = phtab[i].VAddr;\r
-               if( phtab[i].VAddr > max )\r
-                       max = phtab[i].VAddr;\r
+               if( phtab[i].VAddr + phtab[i].MemSize > max )\r
+                       max = phtab[i].VAddr + phtab[i].MemSize;\r
        }\r
 \r
        LOG("base = %08x, max = %08x\n", base, max);\r
@@ -143,8 +143,8 @@ void *Elf_Load(FILE *FP)
                        char *tmp;\r
                        //if(ret->Interpreter)  continue;\r
                        tmp = malloc(phtab[i].FileSize);\r
-                       fseek(FP, phtab[i].Offset, SEEK_SET);\r
-                       fread(tmp, phtab[i].FileSize, 1, FP);\r
+                       acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET);\r
+                       acess_read(FD, phtab[i].FileSize, tmp);\r
                        //ret->Interpreter = Binary_RegInterp(tmp);\r
                        LOG("Interpreter '%s'\n", tmp);\r
                        free(tmp);\r
@@ -165,8 +165,8 @@ void *Elf_Load(FILE *FP)
                        return NULL;\r
                }\r
                \r
-               fseek(FP, phtab[i].Offset, SEEK_SET);\r
-               fread( PTRMK(void, addr), phtab[i].FileSize, 1, FP );\r
+               acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET);\r
+               acess_read(FD, phtab[i].FileSize, PTRMK(void, addr) );\r
                memset( PTRMK(char, addr) + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize );\r
        }\r
        \r
@@ -248,6 +248,9 @@ uintptr_t Elf_Relocate(void *Base)
 \r
        hdr->entrypoint += iBaseDiff;\r
        \r
+       hdr->misc.SymTable = 0;\r
+       hdr->misc.HashTable = 0;\r
+       \r
        // === Get Symbol table and String Table ===\r
        for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)\r
        {\r
@@ -274,6 +277,9 @@ uintptr_t Elf_Relocate(void *Base)
                        break;\r
                }\r
        }\r
+       \r
+       LOG("hdr->misc.SymTable = %x, hdr->misc.HashTable = %x",\r
+               hdr->misc.SymTable, hdr->misc.HashTable);\r
 \r
 \r
        // Alter Symbols to true base\r
@@ -486,6 +492,11 @@ int Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret)
        pBuckets = PTR(hdr->misc.HashTable);\r
        symtab = PTR(hdr->misc.SymTable);\r
        \r
+//     LOG("Base = %p : pBuckets = %p, symtab = %p\n", Base, pBuckets, symtab);\r
+       \r
+       if(!pBuckets || !symtab)\r
+               return 0;\r
+       \r
        nbuckets = pBuckets[0];\r
        iSymCount = pBuckets[1];\r
        pBuckets = &pBuckets[2];\r
index b2a8660..852b398 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <string.h>
 
 // === CODE ===
 int main(int argc, char *argv[], char **envp)
@@ -11,12 +12,32 @@ int main(int argc, char *argv[], char **envp)
         int    i;
         int    appArgc;
        char    **appArgv;
-       char    *appPath;
+       char    *appPath = NULL;
         int    (*appMain)(int, char *[], char **);
        void    *base;
        
+        int    syscall_handle = -1;
+       
        for( i = 1; i < argc; i ++ )
        {
+               if(strcmp(argv[i], "--key") == 0) {
+                       syscall_handle = atoi(argv[++i]);
+                       continue ;
+               }
+               
+               if(strcmp(argv[i], "--binary") == 0) {
+                       appPath = argv[++i];
+                       continue ;
+               }
+               
+               if(strcmp(argv[i], "--open") == 0) {
+                       if( acess_open(argv[++i], 6) == -1 ) {  // Read/Write
+                               fprintf(stderr, "Unable to open '%s'\n", argv[i]);
+                               exit(1);
+                       }
+                       continue ;
+               }
+               
                if( argv[i][0] != '-' ) break;
        }
 
@@ -25,7 +46,8 @@ int main(int argc, char *argv[], char **envp)
                return 1;
        }
        
-       appPath = argv[i];
+       if( !appPath )
+               appPath = argv[i];
 
        appArgc = argc - i;
        appArgv = &argv[i];
@@ -47,7 +69,6 @@ int main(int argc, char *argv[], char **envp)
                "push %2;\n\t"
                "jmp *%3;\n\t"
                : : "r" (envp), "r" (appArgv), "r" (appArgc), "r" (appMain) );
-       //return appMain(appArgc, appArgv, envp);
        return -1;
 }
 
index c5e89ef..8655377 100644 (file)
@@ -1,5 +1,15 @@
 /*
  */
+#define DEBUG  0
+
+
+#if DEBUG
+# define DEBUG_S       printf
+#else
+# define DEBUG_S(...)
+# define DONT_INCLUDE_SYSCALL_NAMES
+#endif
+
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
@@ -89,6 +99,7 @@ int _InitSyscalls()
                #endif
                exit(0);
        }
+       giSyscall_ClientID = gSocket;   // A bit of a hack really :(
        #endif
        
        #if 0
@@ -130,7 +141,7 @@ int _InitSyscalls()
        return 0;
 }
 
-int SendRequest(tRequestHeader *Request, int RequestSize)
+int SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize)
 {
        if( gSocket == INVALID_SOCKET )
        {
@@ -153,38 +164,38 @@ int SendRequest(tRequestHeader *Request, int RequestSize)
        {
                 int    i;
                char    *data = (char*)&Request->Params[Request->NParams];
-               printf("Request #%i\n", Request->CallID);
+               DEBUG_S("Request #%i (%s) -", Request->CallID, casSYSCALL_NAMES[Request->CallID]);
                for( i = 0; i < Request->NParams; i ++ )
                {
-                       printf("%i: ", i);
                        switch(Request->Params[i].Type)
                        {
                        case ARG_TYPE_INT32:
-                               printf("INT32 %x", *(uint32_t*)data);
+                               DEBUG_S(" 0x%08x", *(uint32_t*)data);
                                data += sizeof(uint32_t);
                                break;
                        case ARG_TYPE_INT64:
-                               printf("INT64 %llx", *(uint64_t*)data);
+                               DEBUG_S(" 0x%016llx", *(uint64_t*)data);
                                data += sizeof(uint64_t);
                                break;
                        case ARG_TYPE_STRING:
-                               printf("STRING '%s'", (char*)data);
+                               DEBUG_S(" '%s'", (char*)data);
                                data += Request->Params[i].Length;
                                break;
                        case ARG_TYPE_DATA:
-                               printf("DATA %i %p", Request->Params[i].Length, (char*)data);
-                               data += Request->Params[i].Length;
+                               DEBUG_S(" %p:0x%x", (char*)data, Request->Params[i].Length);
+                               if( !(Request->Params[i].Flags & ARG_FLAG_ZEROED) )
+                                       data += Request->Params[i].Length;
                                break;
                        }
-                       printf("\n");
                }
+               DEBUG_S("\n");
        }
        
        // Send it off
        SendData(Request, RequestSize);
        
        // Wait for a response (no timeout)
-       return ReadData(Request, RequestSize, 0);
+       return ReadData(Request, ResponseSize, 0);
 }
 
 void SendData(void *Data, int Length)
@@ -245,7 +256,7 @@ int ReadData(void *Dest, int MaxLength, int Timeout)
                exit(-1);
        }
        
-       printf("%i bytes read from socket\n", ret);
+       DEBUG_S("%i bytes read from socket\n", ret);
        
        return ret;
 }
index b33a80f..f31a633 100644 (file)
@@ -10,6 +10,6 @@
 
 #include "../syscalls.h"
 
-extern int     SendRequest(tRequestHeader *Request, int RequestSize);
+extern int     SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize);
 
 #endif
index 02a59b9..5fbecbd 100644 (file)
@@ -1,5 +1,6 @@
 /*
  */
+#define DONT_INCLUDE_SYSCALL_NAMES 1
 #include "../../Usermode/include/acess/sys.h"
 #include "common.h"
 #include <stdio.h>
@@ -7,12 +8,22 @@
 #include <stdint.h>
 #include <stdarg.h>
 #include <string.h>
+#include <stddef.h>
 #include "request.h"
 #include "../syscalls.h"
 
+#define DEBUG(x...)    printf(x)
+
+#define NATIVE_FILE_MASK       0x40000000
+#define        MAX_FPS 16
+
 // === Types ===
 
 // === IMPORTS ===
+extern int     giSyscall_ClientID;     // Needed for execve
+
+// === GLOBALS ===
+FILE   *gaSyscall_LocalFPs[MAX_FPS];
 
 // === CODE ===
 const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const char *ArgTypes, va_list *Args)
@@ -53,7 +64,6 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
                }
                
                val32 = va_arg(*Args, uint32_t);
-               printf("val32 = 0x%x\n", val32);
                
                Dest->Type = ARG_TYPE_INT32;
                Dest->Length = sizeof(uint32_t);
@@ -71,7 +81,6 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
                }
                
                val64 = va_arg(*Args, uint64_t);
-               printf("val64 = 0x%llx\n", val64);
                
                Dest->Type = ARG_TYPE_INT64;
                Dest->Length = sizeof(uint64_t);
@@ -88,7 +97,6 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
                }
                
                str = va_arg(*Args, char*);
-               printf("str = %p '%s'\n", str, str);
                
                Dest->Type = ARG_TYPE_STRING;
                Dest->Length = strlen(str) + 1;
@@ -104,8 +112,6 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
                len = va_arg(*Args, int);
                str = va_arg(*Args, char*);
                
-               printf("len = %i, str = %p\n", len, str);
-               
                // Save the pointer for later
                if( PtrDest )   *PtrDest = str;
                
@@ -159,6 +165,11 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        uint64_t        retValue;
         int    i;
        
+       // DEBUG!
+//     printf("&tRequestHeader->Params = %i\n", offsetof(tRequestHeader, Params));
+//     printf("&tRequestValue->Flags = %i\n", offsetof(tRequestValue, Flags));
+//     printf("&tRequestValue->Length = %i\n", offsetof(tRequestValue, Length));
+       
        // Get data size
        va_start(args, ArgTypes);
        str = ArgTypes;
@@ -219,7 +230,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        va_end(args);
        
        // Send syscall request
-       if( SendRequest(req, dataLength) < 0 ) {
+       if( SendRequest(req, dataLength, retLength) < 0 ) {
                fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID);
                exit(127);
        }
@@ -227,7 +238,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        // Parse return value
        dataPtr = &req->Params[req->NParams];
        retValue = 0;
-       if( req->NParams > 1 )
+       if( req->NParams >= 1 )
        {
                switch(req->Params[0].Type)
                {
@@ -243,94 +254,242 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        }
        
        // Write changes to buffers
-       va_start(args, ArgTypes);
+       retCount = 0;
        for( i = 1; i < req->NParams; i ++ )
        {
-               memcpy( retPtrs[i-1], dataPtr, req->Params[i].Length );
+               #if 0
+                int     j;
+               printf("Return Data %i: (%i)", i, req->Params[i].Length);
+               for( j = 0; j < req->Params[i].Length; j ++ )
+                       printf(" %02x", ((uint8_t*)dataPtr)[j]);
+               printf("\n");
+               #endif
+               memcpy( retPtrs[retCount++], dataPtr, req->Params[i].Length );
                dataPtr += req->Params[i].Length;
        }
-       va_end(args);
        
        free( req );
+       free( retPtrs );
        
-       return 0;
+       DEBUG(": %llx\n", retValue);
+       
+       return retValue;
 }
 
 // --- VFS Calls
-int open(const char *Path, int Flags) {
+int acess_open(const char *Path, int Flags)
+{
+       if( strncmp(Path, "$$$$", 4) == 0 )
+       {
+                int    ret;
+               for(ret = 0; ret < MAX_FPS && gaSyscall_LocalFPs[ret]; ret ++ ) ;
+               if(ret == MAX_FPS)      return -1;
+               // TODO: Handle directories
+               gaSyscall_LocalFPs[ret] = fopen(&Path[4], "r+");
+               if(!gaSyscall_LocalFPs[ret])    return -1;
+               return ret|NATIVE_FILE_MASK;
+       }
+       DEBUG("open(\"%s\", 0x%x)", Path, Flags);
        return _Syscall(SYS_OPEN, ">s >i", Path, Flags);
 }
 
-void close(int FD) {
+void acess_close(int FD) {
+       if(FD & NATIVE_FILE_MASK) {
+               fclose( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
+               gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] = NULL;
+               return ;
+       }
+       DEBUG("close(%i)", FD);
        _Syscall(SYS_CLOSE, ">i", FD);
 }
 
-int reopen(int FD, const char *Path, int Flags) {
+int acess_reopen(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 read(int FD, size_t Bytes, void *Dest) {
-       return _Syscall(SYS_READ, "<i >i >i <d", FD, Bytes, Bytes, Dest);
+size_t acess_read(int FD, size_t Bytes, void *Dest) {
+       if(FD & NATIVE_FILE_MASK)
+               return fread( Dest, Bytes, 1, gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
+       DEBUG("read(0x%x, 0x%x, *%p)", FD, Bytes, Dest);
+       return _Syscall(SYS_READ, ">i >i <d", FD, Bytes, Bytes, Dest);
 }
 
-size_t write(int FD, size_t Bytes, void *Src) {
+size_t acess_write(int FD, size_t Bytes, void *Src) {
+       if(FD & NATIVE_FILE_MASK)
+               return fwrite( Src, Bytes, 1, gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
+       DEBUG("write(0x%x, 0x%x, %p\"%.*s\")", FD, Bytes, Src, Bytes, (char*)Src);
        return _Syscall(SYS_WRITE, ">i >i >d", FD, Bytes, Bytes, Src);
 }
 
-int seek(int FD, int64_t Ofs, int Dir) {
+int acess_seek(int FD, int64_t Ofs, int Dir) {
+       if(FD & NATIVE_FILE_MASK) {
+               switch(Dir) {
+               case ACESS_SEEK_SET:    Dir = SEEK_SET; break;
+               default:
+               case ACESS_SEEK_CUR:    Dir = SEEK_CUR; break;
+               case ACESS_SEEK_END:    Dir = SEEK_END; break;
+               }
+               return fseek( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)], Ofs, Dir );
+       }
+       DEBUG("seek(0x%x, 0x%llx, %i)", FD, Ofs, Dir);
        return _Syscall(SYS_SEEK, ">i >I >i", FD, Ofs, Dir);
 }
 
-uint64_t tell(int FD) {
+uint64_t acess_tell(int FD) {
+       if(FD & NATIVE_FILE_MASK)
+               return ftell( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
        return _Syscall(SYS_TELL, ">i", FD);
 }
 
-int ioctl(int fd, int id, void *data) {
+int acess_ioctl(int fd, int id, void *data) {
        // NOTE: 1024 byte size is a hack
        return _Syscall(SYS_IOCTL, ">i >i ?d", fd, id, 1024, data);
 }
-int finfo(int fd, t_sysFInfo *info, int maxacls) {
+int acess_finfo(int fd, t_sysFInfo *info, int maxacls) {
        return _Syscall(SYS_FINFO, ">i <d >i",
                fd,
                sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info,
                maxacls);
 }
 
-int readdir(int fd, char *dest) {
+int acess_readdir(int fd, char *dest) {
        return _Syscall(SYS_READDIR, ">i <d", fd, 256, dest);
 }
 
-int _SysOpenChild(int fd, char *name, int flags) {
+int acess__SysOpenChild(int fd, char *name, int flags) {
        return _Syscall(SYS_OPENCHILD, ">i >s >i", fd, name, flags);
 }
 
-int _SysGetACL(int fd, t_sysACL *dest) {
+int acess__SysGetACL(int fd, t_sysACL *dest) {
        return _Syscall(SYS_GETACL, "<i >i <d", fd, sizeof(t_sysACL), dest);
 }
 
-int _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
+int acess__SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
        return _Syscall(SYS_MOUNT, ">s >s >s >s", Device, Directory, Type, Options);
 }
 
 
 // --- Error Handler
-int    _SysSetFaultHandler(int (*Handler)(int)) {
+int    acess__SysSetFaultHandler(int (*Handler)(int)) {
+       printf("TODO: Set fault handler (asked to set to %p)\n", Handler);
        return 0;
 }
 
 // --- Memory Management ---
-uint64_t _SysAllocate(uint vaddr)
+uint64_t acess__SysAllocate(uint vaddr)
 {
        if( AllocateMemory(vaddr, 0x1000) == -1 )       // Allocate a page
                return 0;
+               
        return vaddr;   // Just ignore the need for paddrs :)
 }
 
+// --- Process Management ---
+int acess_clone(int flags, void *stack)
+{
+       extern int fork(void);
+       if(flags & CLONE_VM) {
+                int    ret, newID, kernel_tid=0;
+               printf("fork()");
+               
+               newID = _Syscall(SYS_FORK, "<d", sizeof(int), &kernel_tid);
+               ret = fork();
+               if(ret < 0)     return ret;
+               
+               if(ret == 0)
+               {
+                       giSyscall_ClientID = newID;
+                       return 0;
+               }
+               
+               // TODO: Return the acess TID instead
+               return kernel_tid;
+       }
+       else
+       {
+               fprintf(stderr, "ERROR: Threads currently unsupported\n");
+               exit(-1);
+       }
+}
+
+int acess_execve(char *path, char **argv, char **envp)
+{
+        int    i, argc;
+       
+       printf("acess_execve: (path='%s', argv=%p, envp=%p)\n", path, argv, envp);
+       
+       // Get argument count
+       for( argc = 0; argv[argc]; argc ++ ) ;
+       printf(" acess_execve: argc = %i\n", argc);
+       
+       char    *new_argv[5+argc+1];
+       char    key[11];
+       sprintf(key, "%i", giSyscall_ClientID);
+       new_argv[0] = "ld-acess";       // TODO: Get path to ld-acess executable
+       new_argv[1] = "--key";  // Set socket/client ID for Request.c
+       new_argv[2] = key;
+       new_argv[3] = "--binary";       // Set the binary path (instead of using argv[0])
+       new_argv[4] = path;
+       for( i = 0; i < argc; i ++ )    new_argv[5+i] = argv[i];
+       new_argv[5+i] = NULL;
+       
+       #if 1
+       argc += 5;
+       for( i = 0; i < argc; i ++ )
+               printf("\"%s\" ", new_argv[i]);
+       printf("\n");
+       #endif
+       
+       // Call actual execve
+       return execve("./ld-acess", new_argv, envp);
+}
+
+void acess_sleep(void)
+{
+       _Syscall(SYS_SLEEP, "");
+}
+
+int acess_waittid(int TID, int *ExitStatus)
+{
+       return _Syscall(SYS_WAITTID, ">i <d", TID, sizeof(int), &ExitStatus);
+}
+
+int acess_setuid(int ID)
+{
+       return _Syscall(SYS_SETUID, ">i", ID);
+}
+
+int acess_setgid(int ID)
+{
+       return _Syscall(SYS_SETGID, ">i", ID);
+}
+
+// --- Logging
+void acess__SysDebug(const char *Format, ...)
+{
+       va_list args;
+       
+       va_start(args, Format);
+       
+       printf("[_SysDebug] ");
+       vprintf(Format, args);
+       printf("\n");
+       
+       va_end(args);
+}
+
+void acess__exit(int Status)
+{
+       _Syscall(SYS_EXIT, ">i", Status);
+       exit(Status);
+}
+
 
 // === Symbol List ===
-#define DEFSYM(name)   {#name, name}
+#define DEFSYM(name)   {#name, acess_##name}
 const tSym     caBuiltinSymbols[] = {
-       {"_exit", exit},
+       DEFSYM(_exit),
        
        DEFSYM(open),
        DEFSYM(close),
@@ -346,9 +505,17 @@ const tSym caBuiltinSymbols[] = {
        DEFSYM(_SysGetACL),
        DEFSYM(_SysMount),
        
-       DEFSYM(_SysAllocate),
+       DEFSYM(clone),
+       DEFSYM(execve),
+       DEFSYM(sleep),
+       
+       DEFSYM(waittid),
+       DEFSYM(setuid),
+       DEFSYM(setgid),
        
-       {"_SysSetFaultHandler", _SysSetFaultHandler}
+       DEFSYM(_SysAllocate),
+       DEFSYM(_SysDebug),
+       DEFSYM(_SysSetFaultHandler)
 };
 
 const int      ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]);
index b4d211c..158a6cc 100644 (file)
@@ -17,7 +17,7 @@
 typedef struct sRequestValue {
        /// \see eArgumentTypes
        uint16_t        Type;
-        uint8_t        Flags;
+       uint16_t        Flags;
        uint16_t        Length;
 }      tRequestValue;
 
@@ -31,6 +31,9 @@ typedef struct sRequestHeader {
 
 enum eSyscalls {
        SYS_NULL,
+       
+       SYS_EXIT,
+       
        SYS_OPEN,
        SYS_CLOSE,
        SYS_READ,
@@ -44,9 +47,43 @@ enum eSyscalls {
        SYS_GETACL,
        SYS_MOUNT,
        SYS_REOPEN,
+       
+       SYS_WAITTID,
+       SYS_SETUID,
+       SYS_SETGID,
+       
+       // IPC
+       SYS_SLEEP,
+       SYS_FORK,
+       
        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",
+       
+       // IPC
+       "SYS_SLEEP"
+};
+#endif
+
 enum eArgumentTypes {
        ARG_TYPE_VOID,
        ARG_TYPE_INT32,
index e4b0436..10391b8 100644 (file)
@@ -16,9 +16,8 @@ MAKEDEP               = $(CC) -M
 
 CPPFLAGS       += -I./include -I./arch/$(ARCHDIR)/include -D_MODULE_NAME_=\"Kernel\"
 CPPFLAGS       += -DARCH=$(ARCH) -DARCHDIR=$(ARCHDIR) -DKERNEL_VERSION=$(KERNEL_VERSION) -DBUILD_NUM=$(BUILD_NUM)
-CFLAGS         += -Wall -Werror -fno-stack-protector -fno-builtin -Wstrict-prototypes -g
-CFLAGS      += -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wuninitialized
-ASFLAGS                += -D ARCH=\"$(ARCH)\" -D ARCHDIR=\"$(ARCHDIR)\"
+CFLAGS         += -Wall -Werror -fno-stack-protector -fno-builtin -Wstrict-prototypes -g
+CFLAGS         += -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wuninitialized
 LDFLAGS                += -T arch/$(ARCHDIR)/link.ld -g
 
 ifeq ($(DEBUG_BUILD),yes)
@@ -26,13 +25,19 @@ ifeq ($(DEBUG_BUILD),yes)
        CFLAGS += -g
 endif
 
+ifeq ($(AS_SUFFIX),)
+       AS_SUFFIX = s
+endif
+
 OBJ := $(addprefix arch/$(ARCHDIR)/,$(A_OBJ))
 OBJ += heap.o drvutil.o logging.o debug.o lib.o adt.o time.o
 OBJ += messages.o modules.o syscalls.o system.o threads.o
 OBJ += $(addprefix vfs/fs/, $(addsuffix .o,$(FILESYSTEMS)))
-OBJ += drv/kb.o drv/vterm.o drv/proc.o drv/fifo.o drv/iocache.o drv/dma.o drv/pci.o drv/vga.o
+OBJ += drv/vterm.o drv/proc.o drv/fifo.o drv/iocache.o drv/pci.o drv/vga.o
+#OBJ += drv/kb.o drv/dma.o
 OBJ += binary.o bin/elf.o bin/pe.o
-OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/dir.o vfs/io.o vfs/mount.o vfs/memfile.o vfs/nodecache.o vfs/handle.o vfs/select.o
+OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/dir.o vfs/io.o vfs/mount.o
+OBJ += vfs/memfile.o vfs/nodecache.o vfs/handle.o vfs/select.o
 OBJ += vfs/fs/root.o vfs/fs/devfs.o
 OBJ += $(addprefix drv/, $(addsuffix .o,$(DRIVERS)))
 OBJ := $(addsuffix .$(ARCH), $(OBJ))
@@ -44,7 +49,7 @@ DEPFILES  = $(filter %.o.$(ARCH),$(OBJ))
 DEPFILES := $(DEPFILES:%.o.$(ARCH)=%.d.$(ARCH))
 
 SRCFILES  = $(OBJ:%.o.$(ARCH)=%.c)
-SRCFILES := $(SRCFILES:%.ao.$(ARCH)=%.asm)
+SRCFILES := $(SRCFILES:%.ao.$(ARCH)=%.$(AS_SUFFIX))
 
 .PHONY: all clean install apidoc
 
@@ -54,7 +59,10 @@ clean:
        @$(RM) $(BIN) ../Acess2.$(ARCH).gz $(BIN).dsm ../Map.$(ARCH).txt LineCounts.$(ARCH).txt $(OBJ) $(DEPFILES)
 
 install: $(BIN) 
-       gzip -c $(BIN) > ../Acess2.$(ARCH).gz
+       cp $(BIN) $(BIN)_
+       $(STRIP) $(BIN)_
+       gzip -c $(BIN)_ > ../Acess2.$(ARCH).gz
+       $(RM) $(BIN)_
        $(xCP) ../Acess2.$(ARCH).gz $(DISTROOT)
 
 apidoc:
@@ -67,9 +75,9 @@ $(BIN): $(OBJ) $(MODS) arch/$(ARCHDIR)/link.ld Makefile
        @wc -l $(SRCFILES) include/*.h > LineCounts.$(ARCH).txt
        @echo BUILD_NUM = $$(( $(BUILD_NUM) + 1 )) > Makefile.BuildNum.$(ARCH)
        $(POSTBUILD)
-       @$(STRIP) $(BIN)
+#      $(STRIP) $(BIN)
 
-%.ao.$(ARCH): %.asm Makefile
+%.ao.$(ARCH): %.$(AS_SUFFIX) Makefile
        @echo --- AS -o $@
        @$(AS) $(ASFLAGS) $< -o $@
 
@@ -83,7 +91,7 @@ $(BIN): $(OBJ) $(MODS) arch/$(ARCHDIR)/link.ld Makefile
 #      endif
 
 %.xo.$(ARCH):
-       @make -C $* all
+       @BUILDTYPE=static make -C $* all
 
 include/syscalls.h include/syscalls.inc.asm:   syscalls.lst Makefile GenSyscalls.pl
        perl GenSyscalls.pl
diff --git a/Kernel/arch/arm7/Makefile b/Kernel/arch/arm7/Makefile
new file mode 100644 (file)
index 0000000..edee279
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# Acess2 Kernel
+# arm7 Architecture Makefile
+# arch/arm7/Makefile
+
+CPPFLAGS       =
+CFLAGS         =
+ASFLAGS                =
+
+ifeq ($(ARCH),integrator-cp)
+       MMU_PRESENT=1
+else
+       MMU_PRESENT=1
+endif
+
+
+
+#ASFLAGS += -D USE_MP=$(USE_MP) -D USE_PAE=$(USE_PAE)
+CPPFLAGS += -DMMU_PRESENT=$(MMU_PRESENT)
+
+A_OBJ  = start.ao main.o
diff --git a/Kernel/arch/arm7/include/arch.h b/Kernel/arch/arm7/include/arch.h
new file mode 100644 (file)
index 0000000..528880b
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Acess2
+ * ARM7 Architecture Header
+ */
+#ifndef _ARCH_H_
+#define _ARCH_H_
+
+// === CONSTANTS ===
+#define INVLPTR        ((void*)-1)
+#define BITS   32
+
+// === TYPES ===
+typedef unsigned int   Uint;
+typedef unsigned char  Uint8;
+typedef unsigned short Uint16;
+typedef unsigned long  Uint32;
+typedef unsigned long long     Uint64;
+typedef signed int     Sint;
+typedef signed char    Sint8;
+typedef signed short   Sint16;
+typedef signed long    Sint32;
+typedef signed long long       Sint64;
+
+typedef int    size_t;
+typedef char   BOOL;
+
+typedef Uint32 tVAddr;
+typedef Uint32 tPAddr;
+
+#include <lock.h>
+
+// --- Debug
+extern void    Debug_PutCharDebug(char Ch);
+extern void    Debug_PutStringDebug(const char *String);
+
+
+#endif
diff --git a/Kernel/arch/arm7/include/lock.h b/Kernel/arch/arm7/include/lock.h
new file mode 100644 (file)
index 0000000..9b289d1
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Acess2
+ * ARM7 Architecture
+ *
+ * lock.h - Hardware level spinlocks
+ */
+#ifndef _LOCK_H_
+#define _LOCK_H_
+
+// === CODE ===
+struct sShortSpinlock {
+        int    Lock;
+};
+
+// --- Spinlocks ---
+static inline int IS_LOCKED(struct sShortSpinlock *Lock)
+{
+       return !!Lock->Lock;
+}
+
+static inline int CPU_HAS_LOCK(struct sShortSpinlock *Lock)
+{
+       // TODO: Handle multiple CPUs
+       return !!Lock->Lock;
+}
+
+static inline int SHORTLOCK(struct sShortSpinlock *Lock)
+{
+       // Shamelessly copied from linux (/arch/arm/include/asm/spinlock.h) until I can fix stuff
+       Uint    tmp;
+       __asm__ __volatile__ (
+       "1:     ldrex   %0, [%1]\n"
+       "       teq     %0, #0\n"
+       "       strexeq %0, %2, [%1]\n" // Magic? TODO: Look up
+       "       teqeq   %0, #0\n"
+       "       bne     1b"
+               : "=&r" (tmp)   // Temp
+               : "r" (&Lock->Lock), "r" (1)
+               : "cc"  // Condition codes clobbered
+               );
+       return 1;
+}
+
+static inline void SHORTREL(struct sShortSpinlock *Lock)
+{
+       Lock->Lock = 0;
+}
+
+#endif
+
diff --git a/Kernel/arch/arm7/include/mm_virt.h b/Kernel/arch/arm7/include/mm_virt.h
new file mode 100644 (file)
index 0000000..ed6f3af
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Acess2
+ * ARM7 Virtual Memory Manager Header
+ */
+#ifndef _MM_VIRT_H_
+#define _MM_VIRT_H_
+
+#define KERNEL_BASE    0x80000000      // 2GiB
+
+// Page Blocks are 12-bits wide (12 address bits used)
+// Hence, the table is 16KiB large (and must be so aligned)
+// and each block addresses 1MiB of data
+
+#define MM_KHEAP_BASE  0x80800000      // 8MiB of kernel code
+#define MM_KHEAP_MAX   0xC0000000      // 1GiB of kernel heap
+
+#define MM_FRACTAL     0xFFE00000      // 2nd last block
+
+#endif
diff --git a/Kernel/arch/arm7/include/proc.h b/Kernel/arch/arm7/include/proc.h
new file mode 100644 (file)
index 0000000..62d2398
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Acess2
+ * ARM7 Architecture
+ *
+ * proc.h - Arch-Dependent Process Management
+ */
+#ifndef _PROC_H_
+#define _PROC_H_
+
+#define MAX_CPUS       4
+
+// === STRUCTURES ===
+typedef struct {
+       Uint32  IP, LR, SP;
+       Uint32  UserIP, UserSP;
+} tTaskState;
+
+typedef struct {
+       Uint32  Base;
+} tMemoryState;
+
+typedef struct {
+       union {
+               Uint32  Num;
+               Uint32  Error;
+       };
+       union {
+               Uint32  Arg1;
+               Uint32  Return;
+       };
+       union {
+               Uint32  Arg2;
+               Uint32  RetHi;
+       };
+       Uint32  Arg3;
+       Uint32  Arg4;
+       Uint32  Arg5;
+       Uint32  Arg6;   // R6
+       Uint32  Unused[13-6];
+       Uint32  StackPointer;   // R13
+       Uint32  _lr;
+       Uint32  _ip;
+} tSyscallRegs;
+
+// === MACROS ===
+#define HALT() __asm__ __volatile__ ("nop")
+
+// === PROTOTYPES ===
+extern void    Proc_Start(void);
+extern tTID    Proc_Clone(Uint *Errno, int Flags);
+
+#endif
+
diff --git a/Kernel/arch/arm7/lib.c b/Kernel/arch/arm7/lib.c
new file mode 100644 (file)
index 0000000..1679577
--- /dev/null
@@ -0,0 +1,8 @@
+/*
+ * Acess2 ARM7 Port
+ *
+ * lib.c - Library Functions
+ */
+#include <acess.h>
+
+// === CODE ===
diff --git a/Kernel/arch/arm7/main.c b/Kernel/arch/arm7/main.c
new file mode 100644 (file)
index 0000000..891501d
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Acess2
+ *
+ * ARM7 Entrypoint
+ * arch/arm7/main.c
+ */
+
+// === IMPORTS ===
+extern void    Interrupts_Setup(void);
+extern void    MM_SetupPhys(void);
+
+// === PROTOTYPES ===
+ int   kmain(void);
+
+// === CODE ===
+int kmain(void)
+{
+       Interrupts_Setup();
+       
+       MM_SetupPhys();
+       
+       //TODO: 
+       for(;;);
+}
diff --git a/Kernel/arch/arm7/start.s b/Kernel/arch/arm7/start.s
new file mode 100644 (file)
index 0000000..1597ba1
--- /dev/null
@@ -0,0 +1,18 @@
+interrupt_vector_table:
+       b . @ Reset
+       b .
+       b . @ SWI instruction
+       b . 
+       b .
+       b .
+       b .
+       b .
+
+.comm stack, 0x10000   @ ; 64KiB Stack
+
+.globl _start
+_start:
+       ldr sp, =stack+0x10000  @ Set up stack
+       bl main
+1:     b 1b    @ Infinite loop
+
index 41a10bc..aa5d8e2 100644 (file)
@@ -3,11 +3,7 @@
 # i386 Architecture Makefile
 # arch/i386/Makefile
 
-# Assuming build machine is 32-bit ELF
-#CC = gcc
-#AS = nasm
-#LD = ld
-#OBJDUMP = objdump
+AS_SUFFIX = asm
 
 CPPFLAGS       =
 CFLAGS         =
@@ -26,6 +22,7 @@ else ifeq ($(ARCH),i586)
        USE_PAE=1
 endif
 
+#ASFLAGS               += -D ARCH=\"$(ARCH)\" -D ARCHDIR=\"$(ARCHDIR)\"
 ASFLAGS += -D USE_MP=$(USE_MP) -D USE_PAE=$(USE_PAE)
 CPPFLAGS += -DUSE_MP=$(USE_MP) -DUSE_PAE=$(USE_PAE)
 
index f6cc14e..dc064f5 100644 (file)
@@ -210,7 +210,7 @@ DEF_SYSCALL 0xAC    ; Acess System Call
 [extern SchedulerBase]
 ; AP's Timer Interrupt
 Isr0xEE:
-       push 0
+       push 0  ; Line up with interrupt number
        xchg bx, bx     ; MAGIC BREAK
        jmp SchedulerBase
 ; Spurious Interrupt
@@ -227,7 +227,8 @@ Isr0xEF:
 [extern SchedulerBase]
 [extern SetAPICTimerCount]
 Isr240:
-       push 0
+       push 0  ; Line up with Argument in errors
+       push 0  ; CPU Number
        ;xchg bx, bx    ; MAGIC BREAK
 Isr240.jmp:
        %if USE_MP
@@ -287,6 +288,18 @@ SyscallCommon:
        call SyscallHandler
        add esp, 4
        
+       ; Pass changes to TF on to the user
+       ; EFLAGS is stored at ESP[4+8+2+2]
+       ; 4 Segment Registers
+       ; 8 GPRs
+       ; 2 Error Code / Interrupt ID
+       ; 2 CS/EIP
+       pushf
+       pop eax
+       and eax, 0x100  ; 0x100 = Trace Flag
+       and WORD [esp+(4+8+2+2)*4], ~0x100      ; Clear
+       or DWORD [esp+(4+8+2+2)*4], eax ; Set for user
+       
        pop gs
        pop fs
        pop es
@@ -300,6 +313,8 @@ SyscallCommon:
 ; ------------
 [extern IRQ_Handler]
 [global IRQCommon]
+[global IRQCommon_handled]
+IRQCommon_handled equ IRQCommon.handled
 IRQCommon:
        pusha
        push ds
@@ -315,6 +330,7 @@ IRQCommon:
        
        push esp
        call IRQ_Handler
+.handled:
        add esp, 4
        
        pop gs
index 1e0278b..22ad1a3 100644 (file)
@@ -60,6 +60,18 @@ void ErrorHandler(tRegs *Regs)
        
        __asm__ __volatile__ ("cli");
        
+       // Debug exception (used for single-stepping)
+       if(Regs->int_num == 1)
+       {
+               static Uint32   lastEIP = 0;
+               tThread *thread = Proc_GetCurThread();
+               if( Regs->eip == lastEIP )
+                       return;
+               Log("%p(%i %s) IP=%08x", thread, thread->TID, thread->ThreadName, Regs->eip);
+               lastEIP = Regs->eip;
+               return ;
+       }
+       
        // Page Fault
        if(Regs->int_num == 14)
        {
index 8d8a14a..66d7a79 100644 (file)
@@ -123,9 +123,13 @@ typedef struct {
 
 typedef struct {
        Uint    EIP, ESP, EBP;
+       Uint32  UserCS, UserEIP;
 } tTaskState;
 
 // === FUNCTIONS ===
+extern void    Debug_PutCharDebug(char ch);
+extern void    Debug_PutStringDebug(const char *String);
+
 extern int     IS_LOCKED(struct sShortSpinlock *Lock);
 extern int     CPU_HAS_LOCK(struct sShortSpinlock *Lock);
 extern void    SHORTLOCK(struct sShortSpinlock *Lock);
index 2b04b75..e31c76d 100644 (file)
@@ -5,7 +5,7 @@
 #ifndef _PROC_H
 #define _PROC_H
 
-#include <threads.h>
+#include <threads_int.h>
 
 // === TYPES ==
 typedef struct sTSS {
index 5fa9d12..969332b 100644 (file)
@@ -3,21 +3,29 @@
  * lib.c
  */
 #include <acess.h>
-#include <threads.h>
+#include <threads_int.h>
 
 #define TRACE_LOCKS    0
 
+#define DEBUG_TO_E9    1
+#define DEBUG_TO_SERIAL        1
+#define        SERIAL_PORT     0x3F8
+#define        GDB_SERIAL_PORT 0x2F8
+
+// === IMPRORTS ===
 #if TRACE_LOCKS
 extern struct sShortSpinlock   glDebug_Lock;
 #endif
-
-// === IMPRORTS ===
 extern int     GetCPUNum(void);
 
 // === PROTOTYPES ==
 Uint64 __udivdi3(Uint64 Num, Uint64 Den);
 Uint64 __umoddi3(Uint64 Num, Uint64 Den);
 
+// === GLOBALS ===
+ int   gbDebug_SerialSetup = 0;
+ int   gbGDB_SerialSetup = 0;
+
 // === CODE ===
 /**
  * \brief Determine if a short spinlock is locked
@@ -158,6 +166,69 @@ void SHORTREL(struct sShortSpinlock *Lock)
        #endif
 }
 
+// === DEBUG IO ===
+#if USE_GDB_STUB
+int putDebugChar(char ch)
+{
+       if(!gbGDB_SerialSetup) {
+               outb(GDB_SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+               outb(GDB_SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+               outb(GDB_SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
+               outb(GDB_SERIAL_PORT + 1, 0x00);    //  (base is         (hi byte)
+               outb(GDB_SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit (8N1)
+               outb(GDB_SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+               outb(GDB_SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+               gbDebug_SerialSetup = 1;
+       }
+       while( (inb(GDB_SERIAL_PORT + 5) & 0x20) == 0 );
+       outb(GDB_SERIAL_PORT, ch);
+       return 0;
+}
+int getDebugChar(void)
+{
+       if(!gbGDB_SerialSetup) {
+               outb(GDB_SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+               outb(GDB_SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+               outb(GDB_SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
+               outb(GDB_SERIAL_PORT + 1, 0x00);    //                   (hi byte)
+               outb(GDB_SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
+               outb(GDB_SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+               outb(GDB_SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+               gbDebug_SerialSetup = 1;
+       }
+       while( (inb(GDB_SERIAL_PORT + 5) & 1) == 0)     ;
+       return inb(GDB_SERIAL_PORT);
+}
+#endif /* USE_GDB_STUB */
+
+void Debug_PutCharDebug(char ch)
+{
+       #if DEBUG_TO_E9
+       __asm__ __volatile__ ( "outb %%al, $0xe9" :: "a"(((Uint8)ch)) );
+       #endif
+       
+       #if DEBUG_TO_SERIAL
+       if(!gbDebug_SerialSetup) {
+               outb(SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+               outb(SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+               outb(SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
+               outb(SERIAL_PORT + 1, 0x00);    //                   (hi byte)
+               outb(SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
+               outb(SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+               outb(SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+               gbDebug_SerialSetup = 1;
+       }
+       while( (inb(SERIAL_PORT + 5) & 0x20) == 0 );
+       outb(SERIAL_PORT, ch);
+       #endif
+}
+
+void Debug_PutStringDebug(const char *String)
+{
+       while(*String)
+               Debug_PutCharDebug(*String++);
+}
+
 // === IO Commands ===
 void outb(Uint16 Port, Uint8 Data)
 {
index 87dcd61..944b24d 100644 (file)
@@ -74,6 +74,10 @@ SchedulerBase:
        push fs
        push gs
        
+       pushf
+       and BYTE [esp+1], 0xFE  ; Clear Trap Flag
+       popf
+       
        mov eax, dr0
        push eax        ; Debug Register 0, Current Thread
        
@@ -121,7 +125,7 @@ scheduler_return:   ; Used by some hackery in Proc_DumpThreadCPUState
        pop ds
        
        popa
-       add esp, 4      ; CPU ID
+       add esp, 4*2    ; CPU ID + Dummy error code
        ; No Error code / int num
        iret
 
@@ -142,9 +146,10 @@ SpawnTask:
        ; In child, so now set up stack frame
        mov ebx, [esp+4]        ; Child Function
        mov edx, [esp+8]        ; Argument
-       ; Child
+       ; Child Function
        push edx        ; Argument
        call ebx        ; Function
+       ; Kill thread once done
        push eax        ; Exit Code
        push   0        ; Kill this thread
        call Threads_Exit       ; Kill Thread
@@ -237,7 +242,7 @@ Proc_ReturnToUser:
 .justKillIt:
        xor eax, eax
        xor ebx, ebx
-       dec ebx
+       dec ebx ; EBX = -1
        int 0xAC
 
 [global GetCPUNum]
@@ -249,6 +254,15 @@ GetCPUNum: ; TODO: Store in debug registers
        mov eax, dr1
        ret
 
+[extern GetEIP]
+[global GetEIP_Sched]
+[global GetEIP_Sched_ret]
+GetEIP_Sched_ret equ GetEIP_Sched.ret
+GetEIP_Sched:
+       call GetEIP
+GetEIP_Sched.ret:
+       ret
+
 ; Usermode code exported by the kernel
 [section .usertext]
 ; Export a place for the user to jump to to call a syscall
index a85b0ca..b677dfd 100644 (file)
@@ -13,7 +13,7 @@
 #endif
 
 // === FLAGS ===
-#define DEBUG_TRACE_SWITCH     0
+#define DEBUG_TRACE_SWITCH     1
 #define DEBUG_DISABLE_DOUBLEFAULT      1
 
 // === CONSTANTS ===
@@ -40,6 +40,7 @@ extern tIDT   gIDT[];
 extern void APWait(void);      // 16-bit AP pause code
 extern void APStartup(void);   // 16-bit AP startup code
 extern Uint    GetEIP(void);   // start.asm
+extern Uint    GetEIP_Sched(void);     // proc.asm
 extern int     GetCPUNum(void);        // start.asm
 extern Uint32  gaInitPageDir[1024];    // start.asm
 extern char    Kernel_Stack_Top[];
@@ -51,6 +52,8 @@ extern void   Isr8(void);     // Double Fault
 extern void    Proc_ReturnToUser(tVAddr Handler, Uint Argument, tVAddr KernelStack);
 extern void    scheduler_return;       // Return address in SchedulerBase
 extern void    IRQCommon;      // Common IRQ handler code
+extern void    IRQCommon_handled;      // IRQCommon call return location
+extern void    GetEIP_Sched_ret;       // GetEIP call return location
 
 // === PROTOTYPES ===
 void   ArchThreads_Init(void);
@@ -289,7 +292,6 @@ void ArchThreads_Init(void)
        #else
        giNumCPUs = 1;
        gTSSs = &gTSS0;
-       MM_FinishVirtualInit();
        #endif
        
        #if !DEBUG_DISABLE_DOUBLEFAULT
@@ -621,7 +623,7 @@ int Proc_Clone(Uint *Err, Uint Flags)
        newThread->SavedState.EBP = ebp;
        eip = GetEIP();
        if(eip == SWITCH_MAGIC) {
-               __asm__ __volatile__ ("mov %0, %%db0" : : "r" (newThread) );
+               //__asm__ __volatile__ ("mov %0, %%db0" : : "r" (newThread) );
                #if USE_MP
                // ACK the interrupt
                if( GetCPUNum() )
@@ -674,7 +676,7 @@ int Proc_SpawnWorker(void)
        new->SavedState.EBP = ebp;
        eip = GetEIP();
        if(eip == SWITCH_MAGIC) {
-               __asm__ __volatile__ ("mov %0, %%db0" : : "r"(new));
+               //__asm__ __volatile__ ("mov %0, %%db0" : : "r"(new));
                #if USE_MP
                // ACK the interrupt
                if(GetCPUNum())
@@ -855,11 +857,40 @@ void Proc_CallFaultHandler(tThread *Thread)
 
 void Proc_DumpThreadCPUState(tThread *Thread)
 {
-       Uint32  *stack = (void *)Thread->SavedState.EBP;        // EBP = ESP after call and PUSH
-       
        if( Thread->CurCPU > -1 )
        {
-               Log("  Currently running");
+                int    maxBacktraceDistance = 6;
+               tRegs   *regs = NULL;
+               Uint32  *stack;
+               
+               if( Thread->CurCPU != GetCPUNum() ) {
+                       Log("  Currently running");
+                       return ;
+               }
+               
+               // Backtrace to find the IRQ entrypoint
+               // - This will usually only be called by an IRQ, so this should
+               //   work
+               __asm__ __volatile__ ("mov %%ebp, %0" : "=r" (stack));
+               while( maxBacktraceDistance -- )
+               {
+                       // [ebp] = oldEbp
+                       // [ebp+4] = retaddr
+                       
+                       if( stack[1] == (tVAddr)&IRQCommon_handled ) {
+                               regs = (void*)stack[2];
+                               break;
+                       }
+                       
+                       stack = (void*)stack[0];
+               }
+               
+               if( !regs ) {
+                       Log("  Unable to find IRQ Entry");
+                       return ;
+               }
+               
+               Log("  at %04x:%08x", regs->cs, regs->eip);
                return ;
        }
        
@@ -870,25 +901,25 @@ void Proc_DumpThreadCPUState(tThread *Thread)
        
        if( diffFromClone > 0 && diffFromClone < 512 )  // When I last checked, GetEIP was at .+0x183
        {
-               // Just spawned full thread
                Log("  Creating full thread");
                return ;
        }
        
        if( diffFromSpawn > 0 && diffFromSpawn < 512 )  // When I last checked, GetEIP was at .+0x99
        {
-               // Just spawned worker thread
                Log("  Creating worker thread");
                return ;
        }
        
        if( diffFromScheduler > 0 && diffFromScheduler < 256 )  // When I last checked, GetEIP was at .+0x60
        #else
-       if( stack[1] == (Uint32)&IRQCommon + 25 )
+       Uint32  data[3];
+       MM_ReadFromAddrSpace(Thread->MemState.CR3, Thread->SavedState.EBP, data, 12);
+       if( data[1] == (Uint32)&IRQCommon + 25 )
        {
-               tRegs   *regs = (void *) stack[2];
+               tRegs   *regs = (void *) data[2];
                Log("  oldebp = 0x%08x, ret = 0x%08x, regs = 0x%x",
-                       stack[0], stack[1], stack[2]
+                       data[0], data[1], data[2]
                        );
                // [EBP] = old EBP
                // [EBP+0x04] = Return Addr
@@ -901,19 +932,11 @@ void Proc_DumpThreadCPUState(tThread *Thread)
        #endif
        {
                // Scheduled out
-               tRegs   *regs = (void *) &stack[4];
-               Log("  oldebp = 0x%08x, ret = 0x%08x, cpu = %i, thread = 0x%x",
-                       stack[0], stack[1], stack[2], stack[3]);
-               // [EBP] = old EBP
-               // [EBP+0x04] = Return Addr
-               // [EBP+0x08] = Arg 1 (CPU Number)
-               // [EBP+0x0C] = Arg 2 (Thread)
-               // [EBP+0x10] = GS (start of tRegs)
-               Log("  At %02x:%08x", regs->cs, regs->eip);
+               Log("  At %04x:%08x", Thread->SavedState.UserCS, Thread->SavedState.UserEIP);
                return ;
        }
        
-       Log("  Just created");
+       Log("  Just created (unknow %p)", Thread->SavedState.EIP);
 }
 
 /**
@@ -935,8 +958,13 @@ void Proc_Scheduler(int CPU)
        thread = gCurrentThread;
        #endif
        
+       // NOTE:
+       // 2011-04-05
+       // Bug may be caused by DR0 not being maintained somewhere, hence 
+       // login is getting loaded with the idle state.
        if( thread )
        {
+               tRegs   *regs;
                // Reduce remaining quantum and continue timeslice if non-zero
                if( thread->Remaining-- )
                        return;
@@ -953,11 +981,34 @@ void Proc_Scheduler(int CPU)
                thread->SavedState.ESP = esp;
                thread->SavedState.EBP = ebp;
                thread->SavedState.EIP = eip;
+               
+               // TODO: Make this more stable somehow
+               regs = (tRegs*)(ebp+(2+2)*4);   // EBP,Ret + CPU,CurThread
+               thread->SavedState.UserCS = regs->cs;
+               thread->SavedState.UserEIP = regs->eip;
+               
+               if(thread->bInstrTrace) {
+                       regs->eflags |= 0x100;  // Set TF
+                       Log("%p De-scheduled", thread);
+               }
+               else
+                       regs->eflags &= ~0x100; // Clear TF
        }
        
        // Get next thread to run
        thread = Threads_GetNextToRun(CPU, thread);
        
+       
+       #if DEBUG_TRACE_SWITCH
+       if(thread) {
+               Log("Switching to task %i, CR3 = 0x%x, EIP = %p",
+                       thread->TID,
+                       thread->MemState.CR3,
+                       thread->SavedState.EIP
+                       );
+       }
+       #endif
+       
        // No avaliable tasks, just go into low power mode (idle thread)
        if(thread == NULL) {
                #if USE_MP
@@ -975,14 +1026,6 @@ void Proc_Scheduler(int CPU)
        gCurrentThread = thread;
        #endif
        
-       #if DEBUG_TRACE_SWITCH
-       Log("Switching to task %i, CR3 = 0x%x, EIP = %p",
-               thread->TID,
-               thread->MemState.CR3,
-               thread->SavedState.EIP
-               );
-       #endif
-       
        #if USE_MP      // MP Debug
 //     Log("CPU = %i, Thread %p", CPU, thread);
        #endif
@@ -997,18 +1040,26 @@ void Proc_Scheduler(int CPU)
        }
        #endif
        
+       if( thread->bInstrTrace ) {
+               Log("%p Scheduled", thread);
+       }
+       
        #if USE_PAE
        # error "Todo: Implement PAE Address space switching"
        #else
+       // Set thread pointer
+       __asm__ __volatile__("mov %0, %%db0\n\t" : : "r"(thread) );
        // Switch threads
        __asm__ __volatile__ (
                "mov %4, %%cr3\n\t"     // Set address space
                "mov %1, %%esp\n\t"     // Restore ESP
                "mov %2, %%ebp\n\t"     // and EBP
+               "or %5, 72(%%ebp)\n\t"  // or trace flag to eflags (2+2+4+8+2)*4
                "jmp *%3" : :   // And return to where we saved state (Proc_Clone or Proc_Scheduler)
                "a"(SWITCH_MAGIC), "b"(thread->SavedState.ESP),
                "d"(thread->SavedState.EBP), "c"(thread->SavedState.EIP),
-               "r"(thread->MemState.CR3)
+               "r"(thread->MemState.CR3),
+               "r"(thread->bInstrTrace&&thread->SavedState.EIP==(Uint)&GetEIP_Sched_ret?0x100:0)
                );
        #endif
        for(;;);        // Shouldn't reach here
index 4be4130..8c7d9a6 100644 (file)
@@ -96,7 +96,7 @@ start:
        jmp .hlt
 
 ; 
-; Multiprocessing AP Startup Code (Must be within 0x10FFF0)
+; Multiprocessing AP Startup Code (Must be within 0 - 0x10FFF0)
 ;
 %if USE_MP
 [extern gGDT]
@@ -123,12 +123,15 @@ APWait:
 [global APStartup]
 APStartup:
        ;xchg bx, bx    ; MAGIC BREAK!
+       ; Load initial GDT
        mov ax, 0xFFFF
        mov ds, ax
        lgdt [DWORD ds:lGDTPtr-KERNEL_BASE-0xFFFF0]
+       ; Enable PMode in CR0
        mov eax, cr0
        or al, 1
        mov cr0, eax
+       ; Jump into PMode
        jmp 08h:DWORD .ProtectedMode-KERNEL_BASE
 [bits 32]
 .ProtectedMode:
@@ -228,7 +231,7 @@ CallWithArgArray:
 [section .initpd]
 [global gaInitPageDir]
 [global gaInitPageTable]
-align 0x1000
+align 4096
 gaInitPageDir:
        dd      gaInitPageTable-KERNEL_BASE+3   ; 0x000 - Low kernel
        times 0x300-0x000-1     dd      0
@@ -236,7 +239,7 @@ gaInitPageDir:
        times 0x3F0-0x300-1     dd      0
        dd      gaInitPageDir-KERNEL_BASE+3     ; 0xFC0 - Fractal
        times 0x400-0x3F0-1     dd      0
-align 0x1000
+align 4096
 gaInitPageTable:
        %assign i 0
        %rep 1024
@@ -244,7 +247,7 @@ gaInitPageTable:
        %assign i i+1
        %endrep
 [global Kernel_Stack_Top]
-ALIGN 0x1000
+ALIGN 4096
        times 1024      dd      0
 Kernel_Stack_Top:
 gInitAPStacks:
index 906b726..1b0246b 100644 (file)
@@ -5,6 +5,8 @@
 
 MAX_CPUS := 4
 
+AS_SUFFIX = asm
+
 CPPFLAGS       := -DMAX_CPUS=$(MAX_CPUS) -D USE_MP=0
 CFLAGS         := $(KERNEL_CFLAGS) -mno-sse -mno-mmx
 ASFLAGS                := -f elf64 -D MAX_CPUS=$(MAX_CPUS) -D USE_MP=0
index e43bd97..c2c622e 100644 (file)
@@ -101,5 +101,8 @@ extern int  CPU_HAS_LOCK(struct sShortSpinlock *Lock);
 extern void    SHORTLOCK(struct sShortSpinlock *Lock);
 extern void    SHORTREL(struct sShortSpinlock *Lock);
 
+extern void    Debug_PutCharDebug(char ch);
+extern void    Debug_PutStringDebug(const char *Str);
+
 #endif
 
index da9955c..75d544b 100644 (file)
@@ -3,10 +3,23 @@
 #include <acess.h>
 #include <arch.h>
 
+#define DEBUG_TO_E9    1
+#define DEBUG_TO_SERIAL        1
+#define        SERIAL_PORT     0x3F8
+#define        GDB_SERIAL_PORT 0x2F8
+
+
 // === IMPORTS ===
 extern int     GetCPUNum(void);
 extern void    *Proc_GetCurThread(void);
 
+// === GLOBALS ===
+ int   gbDebug_SerialSetup = 0;
+ int   gbGDB_SerialSetup = 0;
+
+// === PROTOTYPEs ===
+ int   putDebugChar(char ch);
+
 // === CODE ===
 /**
  * \brief Determine if a short spinlock is locked
@@ -131,6 +144,70 @@ void SHORTREL(struct sShortSpinlock *Lock)
        #endif
 }
 
+// === DEBUG IO ===
+#if USE_GDB_STUB
+int putDebugChar(char ch)
+{
+       if(!gbGDB_SerialSetup) {
+               outb(GDB_SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+               outb(GDB_SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+               outb(GDB_SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
+               outb(GDB_SERIAL_PORT + 1, 0x00);    //  (base is         (hi byte)
+               outb(GDB_SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit (8N1)
+               outb(GDB_SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+               outb(GDB_SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+               gbDebug_SerialSetup = 1;
+       }
+       while( (inb(GDB_SERIAL_PORT + 5) & 0x20) == 0 );
+       outb(GDB_SERIAL_PORT, ch);
+       return 0;
+}
+int getDebugChar(void)
+{
+       if(!gbGDB_SerialSetup) {
+               outb(GDB_SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+               outb(GDB_SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+               outb(GDB_SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
+               outb(GDB_SERIAL_PORT + 1, 0x00);    //                   (hi byte)
+               outb(GDB_SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
+               outb(GDB_SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+               outb(GDB_SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+               gbDebug_SerialSetup = 1;
+       }
+       while( (inb(GDB_SERIAL_PORT + 5) & 1) == 0)     ;
+       return inb(GDB_SERIAL_PORT);
+}
+#endif
+
+void Debug_PutCharDebug(char ch)
+{
+       #if DEBUG_TO_E9
+       __asm__ __volatile__ ( "outb %%al, $0xe9" :: "a"(((Uint8)ch)) );
+       #endif
+       
+       #if DEBUG_TO_SERIAL
+       if(!gbDebug_SerialSetup) {
+               outb(SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+               outb(SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+               outb(SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
+               outb(SERIAL_PORT + 1, 0x00);    //                   (hi byte)
+               outb(SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
+               outb(SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+               outb(SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+               gbDebug_SerialSetup = 1;
+       }
+       while( (inb(SERIAL_PORT + 5) & 0x20) == 0 );
+       outb(SERIAL_PORT, ch);
+       #endif
+}
+
+void Debug_PutStringDebug(const char *String)
+{
+       while(*String)
+               Debug_PutCharDebug(*String++);
+}
+
+// === PORT IO ===
 void outb(Uint16 Port, Uint8 Data)
 {
        __asm__ __volatile__ ("outb %%al, %%dx"::"d"(Port),"a"(Data));
index 062b138..670beb9 100644 (file)
@@ -32,7 +32,7 @@ void  MM_InitPhys_Multiboot(tMBoot_Info *MBoot);
 
 // === GLOBALS ===
 tMutex glPhysicalPages;
-Uint64 *gaSuperBitmap = (void*)MM_PAGE_SUPBMP; // 1 bit = 64 Pages, 16 MiB Per Word
+Uint64 *gaSuperBitmap = (void*)MM_PAGE_SUPBMP; // 1 bit = 64 Pages, 16 MiB per Word
 Uint64 *gaMainBitmap = (void*)MM_PAGE_BITMAP;  // 1 bit = 1 Page, 256 KiB per Word
 Uint64 *gaMultiBitmap = (void*)MM_PAGE_DBLBMP; // Each bit means that the page is being used multiple times
 Uint32 *gaiPageReferences = (void*)MM_PAGE_COUNTS;     // Reference Counts
index 105a59a..99fa7e6 100644 (file)
@@ -5,6 +5,7 @@
 #include <acess.h>
 #include <proc.h>
 #include <threads.h>
+#include <threads_int.h>
 #include <desctab.h>
 #include <mm_virt.h>
 #include <errno.h>
@@ -62,6 +63,7 @@ void  Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **
 void   Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP);
  int   Proc_Demote(Uint *Err, int Dest, tRegs *Regs);
 void   Proc_CallFaultHandler(tThread *Thread);
+void   Proc_DumpThreadCPUState(tThread *Thread);
 void   Proc_Scheduler(int CPU);
 
 // === GLOBALS ===
@@ -738,6 +740,10 @@ void Proc_CallFaultHandler(tThread *Thread)
        for(;;);
 }
 
+void Proc_DumpThreadCPUState(tThread *Thread)
+{
+}
+
 /**
  * \fn void Proc_Scheduler(int CPU)
  * \brief Swap current thread and clears dead threads
index f59704a..6e7a000 100644 (file)
@@ -7,10 +7,6 @@
 #include <acess.h>
 #include <stdarg.h>
 
-#define DEBUG_TO_E9    1
-#define DEBUG_TO_SERIAL        1
-#define        SERIAL_PORT     0x3F8
-#define        GDB_SERIAL_PORT 0x2F8
 #define        DEBUG_MAX_LINE_LEN      256
 
 #define        LOCK_DEBUG_OUTPUT       1
@@ -21,8 +17,6 @@ extern void   KernelPanic_SetMode(void);
 extern void    KernelPanic_PutChar(char Ch);
 
 // === PROTOTYPES ===
- int   putDebugChar(char ch);
- int   getDebugChar(void);
 static void    Debug_Putchar(char ch);
 static void    Debug_Puts(int DbgOnly, const char *Str);
 void   Debug_DbgOnlyFmt(const char *format, va_list args);
@@ -33,8 +27,6 @@ void  Debug_SetKTerminal(const char *File);
 // === GLOBALS ===
  int   gDebug_Level = 0;
  int   giDebug_KTerm = -1;
- int   gbDebug_SerialSetup = 0;
- int   gbGDB_SerialSetup = 0;
  int   gbDebug_IsKPanic = 0;
 volatile int   gbInPutChar = 0;
 #if LOCK_DEBUG_OUTPUT
@@ -42,60 +34,6 @@ tShortSpinlock       glDebug_Lock;
 #endif
 
 // === CODE ===
-int putDebugChar(char ch)
-{
-       if(!gbGDB_SerialSetup) {
-               outb(GDB_SERIAL_PORT + 1, 0x00);    // Disable all interrupts
-               outb(GDB_SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
-               outb(GDB_SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
-               outb(GDB_SERIAL_PORT + 1, 0x00);    //  (base is         (hi byte)
-               outb(GDB_SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit (8N1)
-               outb(GDB_SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
-               outb(GDB_SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
-               gbDebug_SerialSetup = 1;
-       }
-       while( (inb(GDB_SERIAL_PORT + 5) & 0x20) == 0 );
-       outb(GDB_SERIAL_PORT, ch);
-       return 0;
-}
-int getDebugChar(void)
-{
-       if(!gbGDB_SerialSetup) {
-               outb(GDB_SERIAL_PORT + 1, 0x00);    // Disable all interrupts
-               outb(GDB_SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
-               outb(GDB_SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
-               outb(GDB_SERIAL_PORT + 1, 0x00);    //                   (hi byte)
-               outb(GDB_SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
-               outb(GDB_SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
-               outb(GDB_SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
-               gbDebug_SerialSetup = 1;
-       }
-       while( (inb(GDB_SERIAL_PORT + 5) & 1) == 0)     ;
-       return inb(GDB_SERIAL_PORT);
-}
-
-static void Debug_PutCharDebug(char ch)
-{
-       #if DEBUG_TO_E9
-       __asm__ __volatile__ ( "outb %%al, $0xe9" :: "a"(((Uint8)ch)) );
-       #endif
-       
-       #if DEBUG_TO_SERIAL
-       if(!gbDebug_SerialSetup) {
-               outb(SERIAL_PORT + 1, 0x00);    // Disable all interrupts
-               outb(SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
-               outb(SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
-               outb(SERIAL_PORT + 1, 0x00);    //                   (hi byte)
-               outb(SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
-               outb(SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
-               outb(SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
-               gbDebug_SerialSetup = 1;
-       }
-       while( (inb(SERIAL_PORT + 5) & 0x20) == 0 );
-       outb(SERIAL_PORT, ch);
-       #endif
-}
-
 static void Debug_Putchar(char ch)
 {      
        Debug_PutCharDebug(ch);
@@ -114,18 +52,18 @@ static void Debug_Putchar(char ch)
 static void Debug_Puts(int UseKTerm, const char *Str)
 {
         int    len = 0;
-       while( *Str )
-       {
-               Debug_PutCharDebug( *Str );
-               
-               if( gbDebug_IsKPanic )
-                       KernelPanic_PutChar(*Str);
-               len ++;
-               Str ++;
-       }
        
-       Str -= len;
+       Debug_PutStringDebug(Str);
+       
+       if( gbDebug_IsKPanic )
+       {               
+               for( len = 0; Str[len]; len ++ )
+                       KernelPanic_PutChar( Str[len] );
+       }
+       else
+               for( len = 0; Str[len]; len ++ );
        
+       // Output to the kernel terminal
        if( UseKTerm && !gbDebug_IsKPanic && giDebug_KTerm != -1)
        {
                if(gbInPutChar) return ;
@@ -196,7 +134,7 @@ void LogF(const char *Fmt, ...)
 }
 /**
  * \fn void Debug(const char *Msg, ...)
- * \brief Print only to the debug channel
+ * \brief Print only to the debug channel (not KTerm)
  */
 void Debug(const char *Fmt, ...)
 {
@@ -277,9 +215,10 @@ void Panic(const char *Fmt, ...)
 
        Threads_Dump();
 
-       __asm__ __volatile__ ("xchg %bx, %bx");
-       __asm__ __volatile__ ("cli;\n\thlt");
-       for(;;) __asm__ __volatile__ ("hlt");
+//     __asm__ __volatile__ ("xchg %bx, %bx");
+//     __asm__ __volatile__ ("cli;\n\thlt");
+//     for(;;) __asm__ __volatile__ ("hlt");
+       for(;;) ;
 }
 
 void Debug_SetKTerminal(const char *File)
diff --git a/Kernel/drv/dma.c b/Kernel/drv/dma.c
deleted file mode 100644 (file)
index dd8e88f..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*\r
- * AcessOS 1.0\r
- * DMA Driver\r
- */\r
-#include <acess.h>\r
-#include <modules.h>\r
-\r
-#define DMA_SIZE       (0x2400)\r
-#define DMA_ADDRESS(c) ((c)*DMA_SIZE+0x500)    //Save Space for IDT and BDA\r
-\r
-#define LOWB(x)        ((x)&0xFF)\r
-#define HIB(x) (((x)>>8)&0xFF)\r
-#define HIW(x) (((x)>>16)&0xFFFF)\r
-\r
-// === TYPES ===\r
-typedef struct\r
-{\r
-        int    mode;\r
-       char    *address;\r
-} t_dmaChannel;\r
-\r
-// === PROTOTYPES ===\r
- int   DMA_Install(char **Arguments);\r
-void   DMA_SetChannel(int Channel, int length, int read);\r
- int   DMA_ReadData(int channel, int count, void *buffer);\r
- int   DMA_WriteData(int channel, int count, const void *buffer);\r
-\r
-// === CONSTANTS ===\r
-const Uint8 cMASKPORT [8] = { 0x0A, 0x0A, 0x0A, 0x0A, 0xD4, 0xD4, 0xD4, 0xD4 };\r
-const Uint8 cMODEPORT [8] = { 0x0B, 0x0B, 0x0B, 0x0B, 0xD6, 0xD6, 0xD6, 0xD6 };\r
-const Uint8 cCLEARPORT[8] = { 0x0C, 0x0C, 0x0C, 0x0C, 0xD8, 0xD8, 0xD8, 0xD8 };\r
-const Uint8 cPAGEPORT [8] = { 0x87, 0x83, 0x81, 0x82, 0x8F, 0x8B, 0x89, 0x8A };\r
-const Uint8 cADDRPORT [8] = { 0x00, 0x02, 0x04, 0x06, 0xC0, 0xC4, 0xC8, 0xCC };\r
-const Uint8 cCOUNTPORT[8] = { 0x01, 0x03, 0x05, 0x07, 0xC2, 0xC6, 0xCA, 0xCE };\r
-\r
-// === GLOBALS ===\r
-MODULE_DEFINE(0, 0x0100, ISADMA, DMA_Install, NULL, NULL);\r
-char   *dma_addresses[8];\r
-t_dmaChannel   dma_channels[8];\r
-\r
-// === CODE ===\r
-/**\r
- * \brief Initialise DMA channels\r
- * \param Arguments    Arguments passed at boot time\r
- */\r
-int DMA_Install(char **Arguments)\r
-{\r
-       Uint    i;\r
-       for(i=8;i--;)\r
-       {\r
-               outb( cMASKPORT[i], 0x04 | (i & 0x3) ); // mask channel\r
-               outb( cCLEARPORT[i], 0x00 );\r
-               outb( cMODEPORT[i], 0x48 | (i & 0x3) ); //Read Flag\r
-               outb( 0xd8, 0xff);      //Reset Flip-Flop\r
-               outb( cADDRPORT[i], LOWB(DMA_ADDRESS(i)) );     // send address\r
-               outb( cADDRPORT[i], HIB(DMA_ADDRESS(i)) );      // send address\r
-               outb( 0xd8, 0xff);      //Reset Flip-Flop\r
-               outb( cCOUNTPORT[i], LOWB(DMA_SIZE) );      // send size\r
-               outb( cCOUNTPORT[i], HIB(DMA_SIZE) );       // send size\r
-               outb( cPAGEPORT[i], LOWB(HIW(DMA_ADDRESS(i))) );        // send page\r
-               outb( cMASKPORT[i], i & 0x3 );              // unmask channel\r
-               \r
-               dma_channels[i].mode = 0;\r
-               dma_addresses[i] = (char*)DMA_ADDRESS(i);\r
-               dma_addresses[i] += KERNEL_BASE;\r
-       }\r
-       return MODULE_ERR_OK;\r
-}\r
-\r
-/**\r
- * \fn void DMA_SetChannel(int Channel, int length, int read)\r
- * \brief Set DMA Channel Length and RW\r
- */\r
-void DMA_SetChannel(int Channel, int length, int read)\r
-{\r
-       Uint    chan = Channel & 7;\r
-       read = !!read;\r
-       if(length > DMA_SIZE)   length = DMA_SIZE;\r
-       length --;      //Adjust for DMA\r
-       //__asm__ __volatile__ ("cli");\r
-       outb( cMASKPORT[chan], 0x04 | (chan & 0x3) );           // mask channel\r
-       outb( cCLEARPORT[chan], 0x00 );\r
-       outb( cMODEPORT[chan], (0x44 + (!read)*4) | (chan & 0x3) );\r
-       outb( cADDRPORT[chan], LOWB(DMA_ADDRESS(chan)) );               // send address\r
-       outb( cADDRPORT[chan], HIB(DMA_ADDRESS(chan)) );                // send address\r
-       outb( cPAGEPORT[chan], HIW(DMA_ADDRESS(chan)) );                // send page\r
-       outb( cCOUNTPORT[chan], LOWB(length) );      // send size\r
-       outb( cCOUNTPORT[chan], HIB(length) );       // send size\r
-       outb( cMASKPORT[chan], chan & 0x3 );              // unmask channel\r
-       dma_addresses[chan] = (char*)DMA_ADDRESS(chan);\r
-       dma_addresses[chan] += KERNEL_BASE;\r
-       //__asm__ __volatile__ ("sti");\r
-}\r
-\r
-/**\r
- * \fn void DMA_ReadData(int channel, int count, void *buffer)\r
- * \brief Read data from a DMA buffer\r
- */\r
-int DMA_ReadData(int channel, int count, void *buffer)\r
-{\r
-       if(channel < 0 || channel > 7)\r
-               return -1;\r
-       if(count < 0 || count > DMA_SIZE)\r
-               return -2;\r
-       //LogF("memcpy(*0x%x, dma_channels[channel].address, count)\n", buffer\r
-       memcpy(buffer, dma_addresses[channel], count);\r
-       return 0;\r
-}\r
-\r
-/**\r
- * \fn void DMA_WriteData(int channel, int count, void *buffer)\r
- * \brief Write data to a DMA buffer\r
- */\r
-int DMA_WriteData(int channel, int count, const void *buffer)\r
-{\r
-       if(channel < 0 || channel > 7)\r
-               return -1;\r
-       if(count < 0 || count > DMA_SIZE)\r
-               return -2;\r
-       \r
-       memcpy(dma_addresses[channel], buffer, count);\r
-       \r
-       return 0;\r
-}\r
diff --git a/Kernel/drv/kb.c b/Kernel/drv/kb.c
deleted file mode 100644 (file)
index 07e07f5..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Acess2
- * PS2 Keyboard Driver
- */
-#include <acess.h>
-#include <modules.h>
-#include <fs_devfs.h>
-#include <tpl_drv_common.h>
-#include <tpl_drv_keyboard.h>
-#include "kb_kbdus.h"
-
-// === CONSTANTS ===
-#define        KB_BUFFER_SIZE  1024
-#define        USE_KERNEL_MAGIC        1
-
-// === IMPORTS ===
-void   Threads_Dump(void);
-void   Heap_Stats(void);
-
-// === PROTOTYPES ===
- int   KB_Install(char **Arguments);
-void   KB_IRQHandler(int IRQNum);
-void   KB_AddBuffer(char ch);
-Uint64 KB_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Dest);
-void   KB_UpdateLEDs(void);
- int   KB_IOCtl(tVFS_Node *Node, int Id, void *Data);
-
-// === GLOBALS ===
-MODULE_DEFINE(0, 0x0100, PS2Keyboard, KB_Install, NULL, NULL);
-tDevFS_Driver  gKB_DevInfo = {
-       NULL, "PS2Keyboard",
-       {
-       .NumACLs = 0,
-       .Size = 0,
-       //.Read = KB_Read,
-       .IOCtl = KB_IOCtl
-       }
-};
-tKeybardCallback       gKB_Callback = NULL;
-Uint32 **gpKB_Map = gpKBDUS;
-Uint8  gbaKB_States[3][256];
- int   gbKB_ShiftState = 0;
- int   gbKB_CapsState = 0;
- int   gbKB_KeyUp = 0;
- int   giKB_KeyLayer = 0;
-#if USE_KERNEL_MAGIC
- int   gbKB_MagicState = 0;
- int   giKB_MagicAddress = 0;
- int   giKB_MagicAddressPos = 0;
-#endif
-//Uint64       giKB_ReadBase = 0;
-//Uint32       gaKB_Buffer[KB_BUFFER_SIZE];    //!< Keyboard Ring Buffer
-//volatile int giKB_InsertPoint = 0;   //!< Writing location marker
-//volatile int giKB_ReadPoint = 0;     //!< Reading location marker
-//volatile int giKB_InUse = 0;         //!< Lock marker
-
-// === CODE ===
-/**
- * \brief Install the keyboard driver
- */
-int KB_Install(char **Arguments)
-{
-       Uint8   temp;
-       
-       // Attempt to get around a strange bug in Bochs/Qemu by toggling
-       // the controller on and off
-       temp = inb(0x61);
-       outb(0x61, temp | 0x80);
-       outb(0x61, temp & 0x7F);
-       inb(0x60);      // Clear keyboard buffer
-       
-       IRQ_AddHandler(1, KB_IRQHandler);
-       DevFS_AddDevice( &gKB_DevInfo );
-       //Log("KB_Install: Installed");
-       return MODULE_ERR_OK;
-}
-
-/**
- * \brief Called on a keyboard IRQ
- * \param IRQNum       IRQ number (unused)
- */
-void KB_IRQHandler(int IRQNum)
-{
-       Uint8   scancode;
-       Uint32  ch;
-       // int  keyNum;
-
-       // Check port 0x64 to tell if this is from the aux port
-       //if( inb(0x64) & 0x20 )        return;
-
-       scancode = inb(0x60); // Read from the keyboard's data buffer
-       //Log_Debug("Keyboard", "scancode = %02x", scancode);
-
-       // Ignore ACKs
-       if(scancode == 0xFA) {
-               // Oh man! This is anarchic (I'm leaving it here to represent
-               // the mess that Acess once was)
-               //kb_lastChar = KB_ACK;
-               return;
-       }
-
-       // Layer +1
-       if(scancode == 0xE0) {
-               giKB_KeyLayer = 1;
-               return;
-       }
-       // Layer +2
-       if(scancode == 0xE1) {
-               giKB_KeyLayer = 2;
-               return;
-       }
-
-       #if KB_ALT_SCANCODES
-       if(scancode == 0xF0)
-       {
-               gbKB_KeyUp = 1;
-               return;
-       }
-       #else
-       if(scancode & 0x80)
-       {
-               scancode &= 0x7F;
-               gbKB_KeyUp = 1;
-       }
-       #endif
-
-       // Translate
-       ch = gpKB_Map[giKB_KeyLayer][scancode];
-       //keyNum = giKB_KeyLayer * 256 + scancode;
-       // Check for unknown key
-       if(!ch && !gbKB_KeyUp)
-               Log_Warning("Keyboard", "UNK %i %x", giKB_KeyLayer, scancode);
-
-       // Key Up?
-       if (gbKB_KeyUp)
-       {
-               gbKB_KeyUp = 0;
-               gbaKB_States[giKB_KeyLayer][scancode] = 0;      // Unset key state flag
-
-               #if USE_KERNEL_MAGIC
-               if(ch == KEY_LCTRL)     gbKB_MagicState &= ~1;
-               if(ch == KEY_LALT)      gbKB_MagicState &= ~2;
-               #endif
-
-               if(ch == KEY_LSHIFT)    gbKB_ShiftState &= ~1;
-               if(ch == KEY_RSHIFT)    gbKB_ShiftState &= ~2;
-
-               // Call callback
-               if(ch != 0 && gKB_Callback)
-                       gKB_Callback( ch & 0x80000000 );
-
-               // Reset Layer
-               giKB_KeyLayer = 0;
-               return;
-       }
-
-       // Set the bit relating to the key
-       gbaKB_States[giKB_KeyLayer][scancode] = 1;
-       // Set shift key bits
-       if(ch == KEY_LSHIFT)    gbKB_ShiftState |= 1;
-       if(ch == KEY_RSHIFT)    gbKB_ShiftState |= 2;
-
-       // Check for Caps Lock
-       if(ch == KEY_CAPSLOCK) {
-               gbKB_CapsState = !gbKB_CapsState;
-               KB_UpdateLEDs();
-       }
-
-       // Reset Layer
-       giKB_KeyLayer = 0;
-
-       // Ignore Non-Printable Characters
-       if(ch == 0)             return;
-
-       // --- Check for Kernel Magic Combos
-       #if USE_KERNEL_MAGIC
-       if(ch == KEY_LCTRL) {
-               gbKB_MagicState |= 1;
-               //Log_Log("Keyboard", "Kernel Magic LCTRL Down\n");
-       }
-       if(ch == KEY_LALT) {
-               gbKB_MagicState |= 2;
-               //Log_Log("Keyboard", "Kernel Magic LALT Down\n");
-       }
-       if(gbKB_MagicState == 3)
-       {
-               switch(ch)
-               {
-               case '0':       case '1':       case '2':       case '3':
-               case '4':       case '5':       case '6':       case '7':
-               case '8':       case '9':       case 'a':       case 'b':
-               case 'c':       case 'd':       case 'e':       case 'f':
-                       {
-                       char    str[2] = {ch,0};
-                       if(giKB_MagicAddressPos == BITS/4)      break;
-                       giKB_MagicAddress |= atoi(str) << giKB_MagicAddressPos;
-                       giKB_MagicAddressPos ++;
-                       }
-                       break;
-               
-               // Thread List Dump
-               case 'p':       Threads_Dump(); return;
-               // Heap Statistics
-               case 'h':       Heap_Stats();   return;
-               // Dump Structure
-               case 's':       return;
-               }
-       }
-       #endif
-
-       // Is shift pressed
-       // - Darn ugly hacks !!x means (bool)x
-       if( !!gbKB_ShiftState ^ gbKB_CapsState)
-       {
-               switch(ch)
-               {
-               case 0: break;
-               case '`':       ch = '~';       break;
-               case '1':       ch = '!';       break;
-               case '2':       ch = '@';       break;
-               case '3':       ch = '#';       break;
-               case '4':       ch = '$';       break;
-               case '5':       ch = '%';       break;
-               case '6':       ch = '^';       break;
-               case '7':       ch = '&';       break;
-               case '8':       ch = '*';       break;
-               case '9':       ch = '(';       break;
-               case '0':       ch = ')';       break;
-               case '-':       ch = '_';       break;
-               case '=':       ch = '+';       break;
-               case '[':       ch = '{';       break;
-               case ']':       ch = '}';       break;
-               case '\\':      ch = '|';       break;
-               case ';':       ch = ':';       break;
-               case '\'':      ch = '"';       break;
-               case ',':       ch = '<';       break;
-               case '.':       ch = '>';       break;
-               case '/':       ch = '?';       break;
-               default:
-                       if('a' <= ch && ch <= 'z')
-                               ch -= 0x20;
-                       break;
-               }
-       }
-
-       if(gKB_Callback && ch != 0)     gKB_Callback(ch);
-}
-
-/**
- * \fn void KB_UpdateLEDs(void)
- * \brief Updates the status of the keyboard LEDs
- */
-void KB_UpdateLEDs(void)
-{
-       Uint8   leds;
-
-       leds = (gbKB_CapsState ? 4 : 0);
-
-       while( inb(0x64) & 2 ); // Wait for bit 2 to unset
-       outb(0x60, 0xED);       // Send update command
-
-       while( inb(0x64) & 2 ); // Wait for bit 2 to unset
-       outb(0x60, leds);
-}
-
-/**
- * \fn int KB_IOCtl(tVFS_Node *Node, int Id, void *Data)
- * \brief Calls an IOCtl Command
- */
-int KB_IOCtl(tVFS_Node *Node, int Id, void *Data)
-{
-       switch(Id)
-       {
-       case DRV_IOCTL_TYPE:    return DRV_TYPE_KEYBOARD;
-       case DRV_IOCTL_IDENT:   memcpy(Data, "KB\0\0", 4);      return 1;
-       case DRV_IOCTL_VERSION: return 0x100;
-       case DRV_IOCTL_LOOKUP:  return 0;
-
-       // Sets the Keyboard Callback
-       case KB_IOCTL_SETCALLBACK:
-               // Sanity Check
-               if((Uint)Data < KERNEL_BASE)    return 0;
-               // Can only be set once
-               if(gKB_Callback != NULL)        return 0;
-               // Set Callback
-               gKB_Callback = Data;
-               return 1;
-
-       default:
-               return 0;
-       }
-}
diff --git a/Kernel/drv/kb_kbdus.h b/Kernel/drv/kb_kbdus.h
deleted file mode 100644 (file)
index 441b19a..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-\r
-#ifndef _KBDUS_H\r
-#define _KBDUS_H\r
-\r
-// - BASE (NO PREFIX)\r
-Uint32 gpKBDUS1[256] = {\r
-/*00*/ 0,  KEY_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t',\r
-/*10*/ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', KEY_LCTRL, 'a', 's',\r
-/*20*/ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`', KEY_LSHIFT,'\\', 'z', 'x', 'c', 'v',\r
-/*30*/ 'b', 'n', 'm', ',', '.', '/', KEY_RSHIFT, KEY_KPSTAR,\r
-                       KEY_LALT, ' ', KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,\r
-/*40*/ KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_KPHOME,\r
-                       KEY_KPUP, KEY_KPPGUP, KEY_KPMINUS, KEY_KPLEFT, KEY_KP5, KEY_KPRIGHT, KEY_KPPLUS, KEY_KPEND,\r
-/*50*/ KEY_KPDOWN, KEY_KPPGDN, KEY_KPINS, KEY_KPDEL, 0, 0, 0, KEY_F11,\r
-                       KEY_F12, 0, 0, 0, 0, 0, 0, 0,\r
-/*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*A0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*B0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*C0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*D0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*E0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*F0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
-};\r
-// - 0xE0 Prefixed\r
-Uint32 gpKBDUS2[256] = {\r
-//     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\r
-/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0-F\r
-/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_KPENTER, KEY_RCTRL, 0, 0,\r
-/*20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*30*/ 0, 0, 0, 0, 0, KEY_KPSLASH, 0, 0, KEY_RALT, 0, 0, 0, 0, 0, 0, 0,\r
-/*40*/ 0, 0, 0, 0, 0, 0, 0, KEY_HOME,\r
-                       KEY_UP, KEY_PGUP, 0, KEY_LEFT, 0, KEY_RIGHT, 0, KEY_END,\r
-/*50*/ KEY_DOWN, KEY_PGDOWN, KEY_INS, KEY_DEL, 0, 0, 0, 0,\r
-                       0, 0, KEY_WIN, 0, 0, KEY_MENU, 0, 0,\r
-/*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*A0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*B0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*C0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*D0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*E0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*F0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
-};\r
-// - 0xE1 Prefixed\r
-Uint32 gpKBDUS3[256] = {\r
-//     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\r
-/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0-F\r
-/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_PAUSE, 0, 0,\r
-/*20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*30*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*A0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*B0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*C0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*D0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*E0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-/*F0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
-};\r
-\r
-\r
-Uint32 *gpKBDUS[3] = { gpKBDUS1, gpKBDUS2, gpKBDUS3 };\r
-\r
-#endif\r
index c0ce6ed..0d1ae52 100644 (file)
@@ -155,10 +155,10 @@ int SysFS_RegisterFile(const char *Path, const char *Data, int Length)
                        child->Node.ReadDir = SysFS_Comm_ReadDir;
                        child->Node.FindDir = SysFS_Comm_FindDir;
                        if( !prev ) {
-                               //if(ent)
+                               if(ent)
                                        ent->Node.ImplPtr = child;
-                               //else
-                               //      gSysFS_DriverInfo.RootNode.ImplPtr = child;
+                               else
+                                       gSysFS_DriverInfo.RootNode.ImplPtr = child;
                                // ^^^ Impossible (There is already /Version)
                        }
                        else
@@ -184,7 +184,7 @@ int SysFS_RegisterFile(const char *Path, const char *Data, int Length)
                child = ent->Node.ImplPtr;
        else
                child = gSysFS_DriverInfo.RootNode.ImplPtr;
-       for( child = ent->Node.ImplPtr; child; prev = child, child = child->Next )
+       for( ; child; child = child->Next )
        {
                if( strcmp( &Path[start], child->Name ) == 0 )
                        break;
@@ -283,7 +283,10 @@ int SysFS_RemoveFile(int ID)
        parent = file->Parent;
        
        // Remove from file list
-       prev->ListNext = file->ListNext;
+       if(prev)
+               prev->ListNext = file->ListNext;
+       else
+               gSysFS_FileList = file->ListNext;
        file->Node.Size = 0;
        file->Node.ImplPtr = NULL;
        
index 31e7a50..9e1055e 100644 (file)
@@ -11,7 +11,7 @@
 #include <errno.h>
 #include <semaphore.h>
 
-#define        USE_CTRL_ALT    0
+#define        USE_CTRL_ALT    1
 
 // === CONSTANTS ===
 #define VERSION        ((0<<8)|(50))
@@ -57,7 +57,7 @@ typedef struct {
         int    InputRead;      //!< Input buffer read position
         int    InputWrite;     //!< Input buffer write position
        char    InputBuffer[MAX_INPUT_CHARS8];
-       tSemaphore      InputSemaphore;
+//     tSemaphore      InputSemaphore;
        
        tVT_Char        *Text;
        Uint32          *Buffer;
@@ -160,10 +160,12 @@ int VT_Install(char **Arguments)
                        Log_Debug("VTerm", "Argument '%s'", arg);
                        
                        if( strcmp(opt, "Video") == 0 ) {
-                               gsVT_OutputDevice = strdup(val);
+                               if( !gsVT_OutputDevice && Modules_InitialiseBuiltin( val ) == 0 )
+                                       gsVT_OutputDevice = strdup(val);
                        }
                        else if( strcmp(opt, "Input") == 0 ) {
-                               gsVT_InputDevice = strdup(val);
+                               if( !gsVT_InputDevice && Modules_InitialiseBuiltin( val ) == 0 )
+                                       gsVT_InputDevice = strdup(val);
                        }
                        else if( strcmp(opt, "Width") == 0 ) {
                                giVT_RealWidth = atoi( val );
@@ -177,9 +179,6 @@ int VT_Install(char **Arguments)
                }
        }
        
-       if(gsVT_OutputDevice)   Modules_InitialiseBuiltin( gsVT_OutputDevice );
-       if(gsVT_InputDevice)    Modules_InitialiseBuiltin( gsVT_InputDevice );
-       
        // Apply Defaults
        if(!gsVT_OutputDevice)  gsVT_OutputDevice = strdup(DEFAULT_OUTPUT);
        if(!gsVT_InputDevice)   gsVT_InputDevice = strdup(DEFAULT_INPUT);
@@ -223,7 +222,7 @@ int VT_Install(char **Arguments)
                gVT_Terminals[i].Node.Read = VT_Read;
                gVT_Terminals[i].Node.Write = VT_Write;
                gVT_Terminals[i].Node.IOCtl = VT_Terminal_IOCtl;
-               Semaphore_Init(&gVT_Terminals[i].InputSemaphore, 0, MAX_INPUT_CHARS8, "VTerm", gVT_Terminals[i].Name);
+//             Semaphore_Init(&gVT_Terminals[i].InputSemaphore, 0, MAX_INPUT_CHARS8, "VTerm", gVT_Terminals[i].Name);
        }
        
        // Add to DevFS
@@ -313,6 +312,9 @@ void VT_SetResolution(int Width, int Height)
                {
                        if( gVT_Terminals[i].Mode != TERM_MODE_TEXT )   continue;
                        
+                       gVT_Terminals[i].TextWidth = giVT_RealWidth/giVT_CharWidth;
+                       gVT_Terminals[i].TextHeight = giVT_RealHeight/giVT_CharHeight;
+                       
                        gVT_Terminals[i].Text = realloc(
                                gVT_Terminals[i].Text,
                                newBufSize*sizeof(tVT_Char)
@@ -421,6 +423,8 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
         int    pos = 0;
         int    avail;
        tVTerm  *term = &gVT_Terminals[ Node->Inode ];
+       Uint32  *codepoint_buf = Buffer;
+       Uint32  *codepoint_in;
        
        Mutex_Acquire( &term->ReadingLock );
        
@@ -457,10 +461,12 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                if(avail > Length - pos)
                        avail = Length/4 - pos;
                
+               codepoint_in = (void*)term->InputBuffer;
+               codepoint_buf = Buffer;
                
                while( avail -- )
                {
-                       ((Uint32*)Buffer)[pos] = ((Uint32*)term->InputBuffer)[term->InputRead];
+                       codepoint_buf[pos] = codepoint_in[term->InputRead];
                        pos ++;
                        term->InputRead ++;
                        term->InputRead %= MAX_INPUT_CHARS32;
@@ -735,7 +741,7 @@ void VT_KBCallBack(Uint32 Codepoint)
                #else
                case KEY_LALT:  gbVT_AltDown &= ~1;     break;
                case KEY_RALT:  gbVT_AltDown &= ~2;     break;
-               case KEY_LCTRL: gbVT_CtrlDown &= ~1     break;
+               case KEY_LCTRL: gbVT_CtrlDown &= ~1;    break;
                case KEY_RCTRL: gbVT_CtrlDown &= ~2;    break;
                #endif
                }
@@ -856,7 +862,8 @@ void VT_KBCallBack(Uint32 Codepoint)
        else
        {
                // Encode the raw UTF-32 Key
-               ((Uint32*)term->InputBuffer)[ term->InputWrite ] = Codepoint;
+               Uint32  *raw_in = (void*)term->InputBuffer;
+               raw_in[ term->InputWrite ] = Codepoint;
                term->InputWrite ++;
                term->InputWrite %= MAX_INPUT_CHARS32;
                if(term->InputRead == term->InputWrite) {
@@ -1101,6 +1108,9 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
        default:
                Term->Text[ Term->WritePos ].Ch = Ch;
                Term->Text[ Term->WritePos ].Colour = Term->CurColour;
+               // Update the line before wrapping
+               if( (Term->WritePos + 1) % Term->TextWidth == 0 )
+                       VT_int_UpdateScreen( Term, 0 );
                Term->WritePos ++;
                break;
        }
@@ -1146,7 +1156,7 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
        {
                //Debug("Term->WritePos (%i) >= %i",
                //      Term->WritePos,
-               //      Term->ViewPos + Term->Width*Term->Height
+               //      Term->ViewPos + Term->TextWidth*Term->TextHeight
                //      );
                //Debug("Scrolling screen only");
                
@@ -1161,6 +1171,8 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
                //Debug("Term->ViewPos = %i", Term->ViewPos);
                VT_int_ScrollFramebuffer( Term );
                VT_int_UpdateScreen( Term, 0 );
+               
+               //VT_int_UpdateScreen( Term, 1 );       // HACK!
        }
        
        //LEAVE('-');
index bac7894..a96e222 100644 (file)
@@ -57,7 +57,7 @@ Uint64 DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
                        break;
                
                case VIDEO_2DOP_BLIT:
-                       if(rem < 16)    return Length-rem;
+                       if(rem < 12)    return Length-rem;
                        
                        if(!Handlers->Blit) {
                                Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver"
@@ -73,7 +73,7 @@ Uint64 DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
                                );
                        
                        rem -= 16;
-                       stream = (void*)((tVAddr)stream + 16);
+                       stream = (void*)((tVAddr)stream + 12);
                        break;
                
                }
index c440b18..07a3aad 100644 (file)
@@ -664,8 +664,8 @@ void Heap_Stats(void)
                
                // Print the block info?
                #if 1
-               Log_Debug("Heap", "%p - 0x%x (%i) Owned by %s:%i",
-                       head, head->Size, head->ValidSize, head->File, head->Line);
+               Log_Debug("Heap", "%p (0x%x) - 0x%x (%i) Owned by %s:%i",
+                       head->Data, MM_GetPhysAddr((tVAddr)&head->Data), head->Size, head->ValidSize, head->File, head->Line);
                #endif
        }
 
index a2d406b..79c5062 100644 (file)
@@ -22,15 +22,6 @@ typedef Uint tGID;
 typedef Sint64 tTimestamp;
 typedef Sint64 tTime;
 typedef struct sShortSpinlock  tShortSpinlock;
-typedef struct sMutex  tMutex;
-
-struct sMutex {
-       tShortSpinlock  Protector;      //!< Protector for the lock strucure
-       const char      *Name;  //!< Human-readable name
-       struct sThread  *volatile Owner;        //!< Owner of the lock (set upon getting the lock)
-       struct sThread  *Waiting;       //!< Waiting threads
-       struct sThread  *LastWaiting;   //!< Waiting threads
-};
 
 // --- Helper Macros ---
 /**
@@ -337,8 +328,7 @@ extern char *strncpy(char *__dest, const char *__src, size_t max);
 extern int     strcmp(const char *__str1, const char *__str2);
 extern int     strncmp(const char *Str1, const char *Str2, size_t num);
 extern int     strucmp(const char *Str1, const char *Str2);
-//extern char  *strdup(const char *Str);
-#define strdup(Str)    _strdup(_MODULE_NAME_"/"__FILE__, __LINE__, (Str))
+// strdup macro is defined in heap.h
 extern char    *_strdup(const char *File, int Line, const char *Str);
 extern char    **str_split(const char *__str, char __ch);
 extern char    *strchr(const char *__s, int __c);
@@ -428,9 +418,6 @@ extern tGID Threads_GetGID(void);
 extern int     SpawnTask(tThreadFunction Function, void *Arg);
 extern Uint    *Threads_GetCfgPtr(int Id);
 extern int     Threads_SetName(const char *NewName);
-extern int     Mutex_Acquire(tMutex *Mutex);
-extern void    Mutex_Release(tMutex *Mutex);
-extern int     Mutex_IsLocked(tMutex *Mutex);
 /**
  * \}
  */
@@ -441,5 +428,6 @@ extern int  DivUp(int num, int dem);
 #include <binary_ext.h>
 #include <vfs_ext.h>
 #include <adt.h>
+#include <mutex.h>
 
 #endif
index 28d33c0..b058e8b 100644 (file)
@@ -20,4 +20,6 @@ extern void   Heap_Validate(void);
 #define        free(ptr)       Heap_Deallocate((ptr))
 #define IsHeap(ptr)    Heap_IsHeapAddr((ptr))
 
+#define strdup(Str)    _strdup(_MODULE_NAME_"/"__FILE__, __LINE__, (Str))
+
 #endif
diff --git a/Kernel/include/mutex.h b/Kernel/include/mutex.h
new file mode 100644 (file)
index 0000000..326dbd2
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Acess2 Kernel
+ * mutex.h
+ * - Mutual Exclusion syncronisation primitive
+ */
+#ifndef _MUTEX_H
+#define _MUTEX_H
+
+#include <acess.h>
+
+typedef struct sMutex  tMutex;
+
+struct sMutex
+{
+       tShortSpinlock  Protector;      //!< Protector for the lock strucure
+       const char      *Name;  //!< Human-readable name
+       struct sThread  *volatile Owner;        //!< Owner of the lock (set upon getting the lock)
+       struct sThread  *Waiting;       //!< Waiting threads
+       struct sThread  *LastWaiting;   //!< Waiting threads
+};
+
+/**
+ * \brief Acquire a heavy mutex
+ * \param Mutex        Mutex to acquire
+ * \return zero on success, -1 if terminated
+ * 
+ * This type of mutex checks if the mutex is avaliable, and acquires it
+ * if it is. Otherwise, the current thread is added to the mutex's wait
+ * queue and the thread suspends. When the holder of the mutex completes,
+ * the oldest thread (top thread) on the queue is given the lock and
+ * restarted.
+ */
+extern int     Mutex_Acquire(tMutex *Mutex);
+
+/**
+ * \brief Release a held mutex
+ * \param Mutex        Mutex to release
+ * \note Releasing a non-held mutex has no effect
+ */
+extern void    Mutex_Release(tMutex *Mutex);
+
+/**
+ * \brief Is this mutex locked?
+ * \param Mutex        Mutex pointer
+ */
+extern int     Mutex_IsLocked(tMutex *Mutex);
+
+#endif
index 68fb955..d138cf0 100644 (file)
@@ -7,93 +7,6 @@
 #include <signal.h>
 #include <proc.h>
 
-/**
- * \brief IPC Message
- */
-typedef struct sMessage
-{
-       struct sMessage *Next;  //!< Next message in thread's inbox
-       tTID    Source; //!< Source thread ID
-       Uint    Length; //!< Length of message data in bytes
-       Uint8   Data[]; //!< Message data
-} tMsg;
-
-/**
- * \brief Core threading structure
- * 
- */
-typedef struct sThread
-{
-       // --- threads.c's
-       /**
-        * \brief Next thread in current list
-        * \note Required to be first for linked list hacks to work
-        */
-       struct sThread  *Next;
-       struct sThread  *GlobalNext;    //!< Next thread in global list
-       struct sThread  *GlobalPrev;    //!< Previous thread in global list
-       tShortSpinlock  IsLocked;       //!< Thread's spinlock
-       volatile int    Status;         //!< Thread Status
-       void    *WaitPointer;   //!< What (Mutex/Thread/other) is the thread waiting on
-        int    RetStatus;      //!< Return Status
-       
-       Uint    TID;    //!< Thread ID
-       Uint    TGID;   //!< Thread Group (Process)
-       struct sThread  *Parent;        //!< Parent Thread
-       Uint    UID, GID;       //!< User and Group
-       char    *ThreadName;    //!< Name of thread
-       
-       // --- arch/proc.c's responsibility
-       //! Kernel Stack Base
-       tVAddr  KernelStack;
-       
-       //! Memory Manager State
-       tMemoryState    MemState;
-       
-       //! State on task switch
-       tTaskState      SavedState;
-       
-       // --- threads.c's
-        int    CurFaultNum;    //!< Current fault number, 0: none
-       tVAddr  FaultHandler;   //!< Fault Handler
-       
-       tMsg * volatile Messages;       //!< Message Queue
-       tMsg    *LastMessage;   //!< Last Message (speeds up insertion)
-       
-        int    Quantum, Remaining;     //!< Quantum Size and remaining timesteps
-        int    Priority;       //!< Priority - 0: Realtime, higher means less time
-       
-       Uint    Config[NUM_CFG_ENTRIES];        //!< Per-process configuration
-       
-       volatile int    CurCPU;
-} tThread;
-
-
-enum {
-       THREAD_STAT_NULL,       // Invalid process
-       THREAD_STAT_ACTIVE,     // Running and schedulable process
-       THREAD_STAT_SLEEPING,   // Message Sleep
-       THREAD_STAT_MUTEXSLEEP, // Mutex Sleep
-       THREAD_STAT_SEMAPHORESLEEP,     // Semaphore Sleep
-       THREAD_STAT_WAITING,    // ??? (Waiting for a thread)
-       THREAD_STAT_PREINIT,    // Being created
-       THREAD_STAT_ZOMBIE,     // Died/Killed, but parent not informed
-       THREAD_STAT_DEAD,       // Awaiting burial (free)
-       THREAD_STAT_BURIED      // If it's still on the list here, something's wrong
-};
-static const char * const casTHREAD_STAT[] = {
-       "THREAD_STAT_NULL",
-       "THREAD_STAT_ACTIVE",
-       "THREAD_STAT_SLEEPING",
-       "THREAD_STAT_MUTEXSLEEP",
-       "THREAD_STAT_SEMAPHORESLEEP",
-       "THREAD_STAT_WAITING",
-       "THREAD_STAT_PREINIT",
-       "THREAD_STAT_ZOMBIE",
-       "THREAD_STAT_DEAD",
-       "THREAD_STAT_BURIED"
-};
-
 enum eFaultNumbers
 {
        FAULT_MISC,
@@ -106,29 +19,13 @@ enum eFaultNumbers
 
 #define GETMSG_IGNORE  ((void*)-1)
 
-// === GLOBALS ===
-extern BOOL    gaThreads_NoTaskSwitch[MAX_CPUS];
-
 // === FUNCTIONS ===
-extern tThread *Proc_GetCurThread(void);
-
-extern tThread *Threads_GetThread(Uint TID);
-extern void    Threads_SetPriority(tThread *Thread, int Pri);
-extern int     Threads_Wake(tThread *Thread);
-extern void    Threads_Kill(tThread *Thread, int Status);
-extern void    Threads_AddActive(tThread *Thread);
-extern tThread *Threads_RemActive(void);
-extern tThread *Threads_GetNextToRun(int CPU, tThread *Last);
-
 extern void    Threads_SetFaultHandler(Uint Handler);
 
 extern int     Threads_SetUID(Uint *Errno, tUID ID);
 extern int     Threads_SetGID(Uint *Errno, tUID ID);
 extern int     Threads_WaitTID(int TID, int *Status);
 
-extern tThread *Threads_CloneTCB(Uint *Err, Uint Flags);
-extern tThread *Threads_CloneThreadZero(void);
-
 extern int     Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data);
 extern int     Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer);
 
diff --git a/Kernel/include/threads_int.h b/Kernel/include/threads_int.h
new file mode 100644 (file)
index 0000000..f5c7b1b
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Internal Threading header
+ * - Only for use by stuff that needs access to the thread type.
+ */
+#ifndef _THREADS_INT_H_
+#define _THREADS_INT_H_
+
+#include <threads.h>
+#include <proc.h>
+
+/**
+ * \brief IPC Message
+ */
+typedef struct sMessage
+{
+       struct sMessage *Next;  //!< Next message in thread's inbox
+       tTID    Source; //!< Source thread ID
+       Uint    Length; //!< Length of message data in bytes
+       Uint8   Data[]; //!< Message data
+} tMsg;
+
+/**
+ * \brief Core threading structure
+ * 
+ */
+typedef struct sThread
+{
+       // --- threads.c's
+       /**
+        * \brief Next thread in current list
+        * \note Required to be first for linked list hacks to work
+        */
+       struct sThread  *Next;
+       struct sThread  *GlobalNext;    //!< Next thread in global list
+       struct sThread  *GlobalPrev;    //!< Previous thread in global list
+       tShortSpinlock  IsLocked;       //!< Thread's spinlock
+       volatile int    Status;         //!< Thread Status
+       void    *WaitPointer;   //!< What (Mutex/Thread/other) is the thread waiting on
+        int    RetStatus;      //!< Return Status
+       
+       Uint    TID;    //!< Thread ID
+       Uint    TGID;   //!< Thread Group (Process)
+       struct sThread  *Parent;        //!< Parent Thread
+       Uint    UID, GID;       //!< User and Group
+       char    *ThreadName;    //!< Name of thread
+       
+       // --- arch/proc.c's responsibility
+       //! Kernel Stack Base
+       tVAddr  KernelStack;
+       
+       //! Memory Manager State
+       tMemoryState    MemState;
+       
+       //! State on task switch
+       tTaskState      SavedState;
+       
+       // --- threads.c's
+        int    CurFaultNum;    //!< Current fault number, 0: none
+       tVAddr  FaultHandler;   //!< Fault Handler
+       
+       tMsg * volatile Messages;       //!< Message Queue
+       tMsg    *LastMessage;   //!< Last Message (speeds up insertion)
+       
+        int    Quantum, Remaining;     //!< Quantum Size and remaining timesteps
+        int    Priority;       //!< Priority - 0: Realtime, higher means less time
+       
+       Uint    Config[NUM_CFG_ENTRIES];        //!< Per-process configuration
+       
+       volatile int    CurCPU;
+       
+        int    bInstrTrace;
+} tThread;
+
+
+enum {
+       THREAD_STAT_NULL,       // Invalid process
+       THREAD_STAT_ACTIVE,     // Running and schedulable process
+       THREAD_STAT_SLEEPING,   // Message Sleep
+       THREAD_STAT_MUTEXSLEEP, // Mutex Sleep
+       THREAD_STAT_SEMAPHORESLEEP,     // Semaphore Sleep
+       THREAD_STAT_WAITING,    // ??? (Waiting for a thread)
+       THREAD_STAT_PREINIT,    // Being created
+       THREAD_STAT_ZOMBIE,     // Died/Killed, but parent not informed
+       THREAD_STAT_DEAD,       // Awaiting burial (free)
+       THREAD_STAT_BURIED      // If it's still on the list here, something's wrong
+};
+static const char * const casTHREAD_STAT[] = {
+       "THREAD_STAT_NULL",
+       "THREAD_STAT_ACTIVE",
+       "THREAD_STAT_SLEEPING",
+       "THREAD_STAT_MUTEXSLEEP",
+       "THREAD_STAT_SEMAPHORESLEEP",
+       "THREAD_STAT_WAITING",
+       "THREAD_STAT_PREINIT",
+       "THREAD_STAT_ZOMBIE",
+       "THREAD_STAT_DEAD",
+       "THREAD_STAT_BURIED"
+};
+
+// === GLOBALS ===
+extern BOOL    gaThreads_NoTaskSwitch[MAX_CPUS];
+
+// === FUNCTIONS ===
+extern tThread *Proc_GetCurThread(void);
+
+extern tThread *Threads_GetThread(Uint TID);
+extern void    Threads_SetPriority(tThread *Thread, int Pri);
+extern int     Threads_Wake(tThread *Thread);
+extern void    Threads_Kill(tThread *Thread, int Status);
+extern void    Threads_AddActive(tThread *Thread);
+extern tThread *Threads_RemActive(void);
+extern tThread *Threads_GetNextToRun(int CPU, tThread *Last);
+
+extern tThread *Threads_CloneTCB(Uint *Err, Uint Flags);
+extern tThread *Threads_CloneThreadZero(void);
+
+#endif
index 03e225b..45b5dfa 100644 (file)
@@ -4,6 +4,7 @@
  */
 #include <acess.h>
 #include <threads.h>
+#include <threads_int.h>
 #include <errno.h>
 
 // === IMPORTS ===
index b2923f7..1dc1149 100644 (file)
@@ -28,8 +28,8 @@ EXPORT(Module_RegisterLoader);
 extern int     UDI_LoadDriver(void *Base);
 #endif
 extern void    StartupPrint(const char *Str);
-extern void    gKernelModules;
-extern void    gKernelModulesEnd;
+extern tModule gKernelModules;
+extern tModule gKernelModulesEnd;
 
 // === GLOBALS ===
  int   giNumBuiltinModules = 0;
index b483830..ecddf94 100644 (file)
@@ -5,6 +5,7 @@
  */
 #include <acess.h>
 #include <threads.h>
+#include <threads_int.h>
 #include <errno.h>
 #include <semaphore.h>
 
@@ -59,6 +60,7 @@ void  Threads_Sleep(void);
 void   Threads_AddActive(tThread *Thread);
 tThread        *Threads_RemActive(void);
 #endif
+void   Threads_ToggleTrace(int TID);
 void   Threads_Fault(int Num);
 void   Threads_SegFault(tVAddr Addr);
 #if 0
@@ -71,7 +73,6 @@ tGID  Threads_GetGID(void);
 #endif
 void   Threads_Dump(void);
 void   Threads_DumpActive(void);
-
 #if 0
  int   Mutex_Acquire(tMutex *Mutex);
 void   Mutex_Release(tMutex *Mutex);
@@ -122,6 +123,9 @@ void Threads_Init(void)
 {
        ArchThreads_Init();
        
+       Log_Debug("Threads", "Offsets of tThread");
+       Log_Debug("Threads", ".Priority = %i", offsetof(tThread, Priority));
+       
        // Create Initial Task
        #if SCHEDULER_TYPE == SCHED_RR_PRI
        gaActiveThreads[gThreadZero.Priority] = &gThreadZero;
@@ -184,6 +188,7 @@ void Threads_SetPriority(tThread *Thread, int Pri)
        if(Thread == NULL)      Thread = Proc_GetCurThread();
        // Bounds checking
        // - If < 0, set to lowest priority
+       // - Minumum priority is actualy a high number, 0 is highest
        if(Pri < 0)     Pri = MIN_PRIORITY;
        if(Pri > MIN_PRIORITY)  Pri = MIN_PRIORITY;
        
@@ -208,7 +213,9 @@ void Threads_SetPriority(tThread *Thread, int Pri)
                #if SCHEDULER_TYPE == SCHED_LOTTERY
                giFreeTickets -= caiTICKET_COUNTS[Thread->Priority] - caiTICKET_COUNTS[Pri];
                # if DEBUG_TRACE_TICKETS
-               Log("Threads_SetTickets: new giFreeTickets = %i", giFreeTickets);
+               Log("Threads_SetTickets: new giFreeTickets = %i [-%i+%i]",
+                       giFreeTickets,
+                       caiTICKET_COUNTS[Thread->Priority], caiTICKET_COUNTS[Pri]);
                # endif
                #endif
                Thread->Priority = Pri;
@@ -217,6 +224,12 @@ void Threads_SetPriority(tThread *Thread, int Pri)
        else
                Thread->Priority = Pri;
        #endif
+       
+       #if DEBUG_TRACE_STATE
+       Log("Threads_SetPriority: %p(%i %s) pri set %i",
+               Thread, Thread->TID, Thread->ThreadName,
+               Pri);
+       #endif
 }
 
 /**
@@ -233,10 +246,7 @@ tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
        
        // Allocate and duplicate
        new = malloc(sizeof(tThread));
-       if(new == NULL) {
-               *Err = -ENOMEM;
-               return NULL;
-       }
+       if(new == NULL) { *Err = -ENOMEM; return NULL; }
        memcpy(new, cur, sizeof(tThread));
        
        new->CurCPU = -1;
@@ -248,6 +258,7 @@ tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
        // Get Thread ID
        new->TID = giNextTID++;
        new->Parent = cur;
+       new->bInstrTrace = 0;
        
        // Clone Name
        new->ThreadName = strdup(cur->ThreadName);
@@ -334,6 +345,7 @@ tThread *Threads_CloneThreadZero(void)
        // Set State
        new->Remaining = new->Quantum = cur->Quantum;
        new->Priority = cur->Priority;
+       new->bInstrTrace = 0;
        
        // Set Signal Handlers
        new->CurFaultNum = 0;
@@ -772,6 +784,13 @@ int Threads_WakeTID(tTID TID)
        return ret;
 }
 
+void Threads_ToggleTrace(int TID)
+{
+       tThread *thread = Threads_GetThread(TID);
+       if(!thread)     return ;
+       thread->bInstrTrace = !thread->bInstrTrace;
+}
+
 /**
  * \brief Adds a thread to the active queue
  */
@@ -987,6 +1006,8 @@ void Threads_DumpActive(void)
                                Log("  ERROR State (%i) != THREAD_STAT_ACTIVE (%i)", thread->Status, THREAD_STAT_ACTIVE);
                        Log("  Priority %i, Quantum %i", thread->Priority, thread->Quantum);
                        Log("  KStack 0x%x", thread->KernelStack);
+                       if( thread->bInstrTrace )
+                               Log("  Tracing Enabled");
                        Proc_DumpThreadCPUState(thread);
                }
        
@@ -1031,6 +1052,9 @@ void Threads_Dump(void)
                }
                Log("  Priority %i, Quantum %i", thread->Priority, thread->Quantum);
                Log("  KStack 0x%x", thread->KernelStack);
+               if( thread->bInstrTrace )
+                       Log("  Tracing Enabled");
+               Proc_DumpThreadCPUState(thread);
        }
 }
 
@@ -1117,7 +1141,7 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
                }
                #if SCHEDULER_TYPE == SCHED_LOTTERY && DEBUG_TRACE_TICKETS
                else
-                       LogF("Log: CPU%i released %p (%i %s)->Status = %i (Released)\n",
+                       LogF("Log: CPU%i released %p (%i %s)->Status = %i (Released,not in pool)\n",
                                CPU, Last, Last->TID, Last->ThreadName, Last->Status);
                #endif
                Last->CurCPU = -1;
@@ -1255,16 +1279,7 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
        return thread;
 }
 
-/**
- * \brief Acquire a heavy mutex
- * \param Mutex        Mutex to acquire
- * 
- * This type of mutex checks if the mutex is avaliable, and acquires it
- * if it is. Otherwise, the current thread is added to the mutex's wait
- * queue and the thread suspends. When the holder of the mutex completes,
- * the oldest thread (top thread) on the queue is given the lock and
- * restarted.
- */
+// Acquire mutex (see mutex.h for documentation)
 int Mutex_Acquire(tMutex *Mutex)
 {
        tThread *us = Proc_GetCurThread();
@@ -1293,6 +1308,12 @@ int Mutex_Acquire(tMutex *Mutex)
                        Mutex->Waiting = us;
                        Mutex->LastWaiting = us;
                }
+               
+               #if DEBUG_TRACE_STATE
+               Log("%p (%i %s) waiting on mutex %p",
+                       us, us->TID, us->ThreadName, Mutex);
+               #endif
+               
                #if 0
                {
                         int    i = 0;
@@ -1324,11 +1345,7 @@ int Mutex_Acquire(tMutex *Mutex)
        return 0;
 }
 
-/**
- * \brief Release a held mutex
- * \param Mutex        Mutex to release
- * \note Releasing a non-held mutex has no effect
- */
+// Release a mutex
 void Mutex_Release(tMutex *Mutex)
 {
        SHORTLOCK( &Mutex->Protector );
@@ -1361,10 +1378,7 @@ void Mutex_Release(tMutex *Mutex)
        #endif
 }
 
-/**
- * \brief Is this mutex locked?
- * \param Mutex        Mutex pointer
- */
+// Check if a mutex is locked
 int Mutex_IsLocked(tMutex *Mutex)
 {
        return Mutex->Owner != NULL;
@@ -1427,6 +1441,12 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
                        Sem->LastWaiting = us;
                }
                
+               #if DEBUG_TRACE_STATE
+               Log("%p (%i %s) waiting on semaphore %p %s:%s",
+                       us, us->TID, us->ThreadName,
+                       Sem, Sem->ModName, Sem->Name);
+               #endif
+               
                SHORTREL( &glThreadListLock );  
                SHORTREL( &Sem->Protector );
                while(us->Status == THREAD_STAT_SEMAPHORESLEEP) Threads_Yield();
@@ -1458,6 +1478,13 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
                        given = Sem->MaxValue - Sem->Value;
                Sem->Value -= given;
                
+               
+               #if DEBUG_TRACE_STATE
+               Log("%p (%i %s) woken by wait on %p %s:%s",
+                       toWake, toWake->TID, toWake->ThreadName,
+                       Sem, Sem->ModName, Sem->Name);
+               #endif
+               
                // Save the number we gave to the thread's status
                toWake->RetStatus = given;
                
@@ -1514,6 +1541,12 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
                        Sem->LastSignaling = us;
                }
                
+               #if DEBUG_TRACE_STATE
+               Log("%p (%i %s) signaling semaphore %p %s:%s",
+                       us, us->TID, us->ThreadName,
+                       Sem, Sem->ModName, Sem->Name);
+               #endif
+               
                SHORTREL( &glThreadListLock );  
                SHORTREL( &Sem->Protector );
                while(us->Status == THREAD_STAT_SEMAPHORESLEEP) Threads_Yield();
@@ -1542,12 +1575,13 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
        {
                tThread *toWake = Sem->Waiting;
                
+               // Remove thread from list (double ended, so clear LastWaiting if needed)
                Sem->Waiting = Sem->Waiting->Next;
-               // Reset ->LastWaiting to NULL if we have just removed the last waiting thread
                if( Sem->Waiting == NULL )
                        Sem->LastWaiting = NULL;
                
-               // Figure out how much to give
+               // Figure out how much to give to woken thread
+               // - Requested count is stored in ->RetStatus
                if( toWake->RetStatus && Sem->Value > toWake->RetStatus )
                        given = toWake->RetStatus;
                else
@@ -1557,6 +1591,14 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
                // Save the number we gave to the thread's status
                toWake->RetStatus = given;
                
+               if(toWake->bInstrTrace)
+                       Log("%s(%i) given %i from %p", toWake->ThreadName, toWake->TID, given, Sem);
+               #if DEBUG_TRACE_STATE
+               Log("%p (%i %s) woken by signal on %p %s:%s",
+                       toWake, toWake->TID, toWake->ThreadName,
+                       Sem, Sem->ModName, Sem->Name);
+               #endif
+               
                // Wake the sleeper
                SHORTLOCK( &glThreadListLock );
                if( toWake->Status != THREAD_STAT_ACTIVE )
index e9c9f09..4c3c6a2 100644 (file)
@@ -155,7 +155,7 @@ char *Root_ReadDir(tVFS_Node *Node, int Pos)
        
        for( ; child && Pos--; child = child->Next ) ;
        
-       if(Pos) return strdup(child->Name);
+       if(child)       return strdup(child->Name);
        
        return NULL;
 }
index 0820102..600cedc 100644 (file)
@@ -78,7 +78,7 @@ char *VFS_GetAbsPath(const char *Path)
                strcpy(ret, cwd);
                ret[cwdLen] = '/';
                strcpy(&ret[cwdLen+1], Path);
-               //Log("ret = '%s'\n", ret);
+               //Log("ret = '%s'", ret);
        }
        
        // Parse Path
@@ -590,7 +590,7 @@ void VFS_Close(int FD)
        // Get handle
        h = VFS_GetHandle(FD);
        if(h == NULL) {
-               Log_Warning("VFS", "Invalid file handle passed to VFS_Close, 0x%x\n", FD);
+               Log_Warning("VFS", "Invalid file handle passed to VFS_Close, 0x%x", FD);
                return;
        }
        
index 85c7d62..22417c8 100644 (file)
@@ -148,6 +148,7 @@ int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set
        if( !Timeout || *Timeout > 0 )
        {
                ret = Semaphore_Wait(&thread_info->SleepHandle, 1);
+               // TODO: Do something with ret
        }
        
        // Fill output (modify *Handles)
index c5d2c29..f7f5928 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -54,39 +54,39 @@ install:    install-Filesystem $(INSTALL_DYNMODS) $(INSTALL_MODULES) install-Kernel
 
 # Compile Only
 $(ALL_DYNMODS): all-%:
-       @echo === Dynamic Module: $* && BUILDTYPE=dynamic $(SUBMAKE) all -C Modules/$*
+       +@echo === Dynamic Module: $* && BUILDTYPE=dynamic $(SUBMAKE) all -C Modules/$*
 $(ALL_MODULES): all-%:
-       @echo === Module: $* && BUILDTYPE=static $(SUBMAKE) all -C Modules/$*
+       +@echo === Module: $* && BUILDTYPE=static $(SUBMAKE) all -C Modules/$*
 all-Kernel:
-       @echo === Kernel && $(SUBMAKE) all -C Kernel
+       +@echo === Kernel && $(SUBMAKE) all -C Kernel
 $(ALL_USRLIBS): all-%:
-       @echo === User Library: $* && $(SUBMAKE) all -C Usermode/Libraries/$*_src
+       +@echo === User Library: $* && $(SUBMAKE) all -C Usermode/Libraries/$*_src
 $(ALL_USRAPPS): all-%:
-       @echo === User Application: $* && $(SUBMAKE) all -C Usermode/Applications/$*_src
+       +@echo === User Application: $* && $(SUBMAKE) all -C Usermode/Applications/$*_src
 
 # Compile & Install
 $(AI_DYNMODS): allinstall-%:
-       @echo === Dynamic Module: $* && BUILDTYPE=dynamic $(SUBMAKE) all install -C Modules/$*
+       +@echo === Dynamic Module: $* && BUILDTYPE=dynamic $(SUBMAKE) all install -C Modules/$*
 $(AI_MODULES): allinstall-%:
-       @echo === Module: $* && BUILDTYPE=static $(SUBMAKE) all install -C Modules/$*
+       +@echo === Module: $* && BUILDTYPE=static $(SUBMAKE) all install -C Modules/$*
 allinstall-Kernel:
-       @echo === Kernel && $(SUBMAKE) all install -C Kernel
+       +@echo === Kernel && $(SUBMAKE) all install -C Kernel
 $(AI_USRLIBS): allinstall-%:
-       @echo === User Library: $* && $(SUBMAKE) all install -C Usermode/Libraries/$*_src
+       +@echo === User Library: $* && $(SUBMAKE) all install -C Usermode/Libraries/$*_src
 $(AI_USRAPPS): allinstall-%:
-       @echo === User Application: $* && $(SUBMAKE) all install -C Usermode/Applications/$*_src
+       +@echo === User Application: $* && $(SUBMAKE) all install -C Usermode/Applications/$*_src
 
 # Clean up compilation
 $(CLEAN_DYNMODS): clean-%:
-       @BUILDTYPE=dynamic $(SUBMAKE) clean -C Modules/$*
+       +@BUILDTYPE=dynamic $(SUBMAKE) clean -C Modules/$*
 $(CLEAN_MODULES): clean-%:
-       @BUILDTYPE=static $(SUBMAKE) clean -C Modules/$*
+       +@BUILDTYPE=static $(SUBMAKE) clean -C Modules/$*
 clean-Kernel:
-       @$(SUBMAKE) clean -C Kernel
+       +@$(SUBMAKE) clean -C Kernel
 $(CLEAN_USRLIBS): clean-%:
-       @$(SUBMAKE) clean -C Usermode/Libraries/$*_src
+       +@$(SUBMAKE) clean -C Usermode/Libraries/$*_src
 $(CLEAN_USRAPPS): clean-%:
-       @$(SUBMAKE) clean -C Usermode/Applications/$*_src
+       +@$(SUBMAKE) clean -C Usermode/Applications/$*_src
 
 # Install
 $(INSTALL_DYNMODS): install-%:
index ff49c16..4155f5e 100644 (file)
@@ -42,10 +42,12 @@ DRIVERS :=
 MODULES := Storage/ATA Storage/FDD
 MODULES += Network/NE2000
 MODULES += Display/VESA
-#MODULES += Display/BochsGA
+MODULES += Display/BochsGA
 MODULES += Filesystems/Ext2
 MODULES += Filesystems/FAT
 MODULES += Filesystems/NTFS
 MODULES += IPStack
 DYNMODS := USB/Core
 MODULES += Interfaces/UDI
+MODULES += Input/PS2KbMouse
+MODULES += x86/ISADMA
index 3c8309e..b1b2e22 100644 (file)
@@ -184,7 +184,7 @@ Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *Buffer)
                {\r
                        VT_Font_Render(\r
                                chars->Ch,\r
-                               dest + x*giVT_CharWidth, gpBGA_CurrentMode->width,\r
+                               dest + x*giVT_CharWidth, 32, gpBGA_CurrentMode->width*4,\r
                                VT_Colour12to24(chars->BGCol),\r
                                VT_Colour12to24(chars->FGCol)\r
                                );\r
index 0cc9a46..a3aa301 100644 (file)
@@ -52,14 +52,17 @@ struct ext2_super_block_s {
        Uint32  s_blocks_count;         //!< Blocks count\r
        Uint32  s_r_blocks_count;       //!< Reserved blocks count\r
        Uint32  s_free_blocks_count;    //!< Free blocks count\r
+       \r
        Uint32  s_free_inodes_count;    //!< Free inodes count\r
        Uint32  s_first_data_block;     //!< First Data Block\r
        Uint32  s_log_block_size;       //!< Block size\r
        Sint32  s_log_frag_size;        //!< Fragment size\r
+       \r
        Uint32  s_blocks_per_group;     //!< Number Blocks per group\r
        Uint32  s_frags_per_group;      //!< Number Fragments per group\r
        Uint32  s_inodes_per_group;     //!< Number Inodes per group\r
        Uint32  s_mtime;                        //!< Mount time\r
+       \r
        Uint32  s_wtime;                        //!< Write time\r
        Uint16  s_mnt_count;            //!< Mount count\r
        Sint16  s_max_mnt_count;        //!< Maximal mount count\r
@@ -67,10 +70,12 @@ struct ext2_super_block_s {
        Uint16  s_state;                        //!< File system state\r
        Uint16  s_errors;                       //!< Behaviour when detecting errors\r
        Uint16  s_pad;                          //!< Padding\r
+       \r
        Uint32  s_lastcheck;            //!< time of last check\r
        Uint32  s_checkinterval;        //!< max. time between checks\r
        Uint32  s_creator_os;           //!< Formatting OS\r
        Uint32  s_rev_level;            //!< Revision level\r
+       \r
        Uint16  s_def_resuid;           //!< Default uid for reserved blocks\r
        Uint16  s_def_resgid;           //!< Default gid for reserved blocks\r
        Uint32  s_reserved[235];        //!< Padding to the end of the block\r
index d279bf3..9da14f6 100644 (file)
@@ -5,14 +5,36 @@
 #include "ipstack.h"
 #include "firewall.h"
 
+#define MAX_ADDRTYPE   9
+
 // === IMPORTS ===
 
 // === TYPES ===
+typedef struct sKeyValue       tKeyValue;
 typedef struct sFirewallMod    tFirewallMod;
 typedef struct sModuleRule     tModuleRule;
 typedef struct sRule   tRule;
 typedef struct sChain  tChain;
 
+// === STRUCTURES ===
+struct sKeyValue
+{
+       const char      *Key;
+       const char      *Value;
+};
+
+struct sFirewallMod
+{
+       const char      *Name;
+       
+        int    (*Match)(tModuleRule *Rule, int AddrType,
+                               const void *Src, const void *Dest,
+                               Uint8 Type, Uint32 Flags,
+                               size_t Length, const void *Data);
+       
+       tModuleRule     *(*Create)(tKeyValue *Params);
+};
+
 struct sModuleRule
 {
        tModuleRule     *Next;
@@ -29,17 +51,17 @@ struct sRule
         int    PacketCount;    // Number of packets seen
         int    ByteCount;              // Number of bytes seen (IP Payload bytes)
        
-        int    bInvertSource;
-       void    *Source;
-        int    SourceMask;
+        int    bInvertSource;  // Boolean NOT flag on source
+       void    *Source;        // Source address bytes
+        int    SourceMask;     // Source address mask bits
         
-        int    bInvertDest;
-       void    *Dest;
-        int    DestMask;
+        int    bInvertDest;    // Boolean NOT flag on destination
+       void    *Dest;  // Destination address bytes
+        int    DestMask;       // Destination address mask bits
        
-       tModuleRule     *Modules;
+       tModuleRule     *Modules;       // Modules loaded for this rule
        
-       char    Action[];       // Target rule name
+       char    Target[];       // Target rule name
 };
 
 struct sChain
@@ -62,19 +84,45 @@ struct sChain
        );
 
 // === GLOBALS ===
-tChain *gapFirewall_Chains[10];
+tChain *gapFirewall_Chains[MAX_ADDRTYPE+1];
 tChain gFirewall_DROP = {.Name="DROP"};
 tChain gFirewall_ACCEPT = {.Name="ACCEPT"};
 tChain gFirewall_RETURN = {.Name="RETURN"};
 
 // === CODE ===
+/**
+ * \brief Apply a rule to a packet
+ * \return -1 for no match, -2 for RETURN, eFirewallAction otherwise
+ */
 int IPTables_DoRule(
        tRule *Rule, int AddrType,
        const void *Src, const void *Dest,
        Uint8 Type, Uint32 Flags,
        size_t Length, const void *Data)
 {
-       return 0;
+        int    rv;
+       // Check if source doesn't match
+       if( !IPStack_CompareAddress(AddrType, Src, Rule->Source, Rule->SourceMask) == !Rule->bInvertSource )
+               return -1;
+       // Check if destination doesn't match
+       if( !IPStack_CompareAddress(AddrType, Dest, Rule->Dest, Rule->DestMask) == !Rule->bInvertDest )
+               return -1;
+       
+       // TODO: Handle modules (UDP/TCP/etc)
+       tModuleRule *modrule;
+       for( modrule = Rule->Modules; modrule; modrule = modrule->Next )
+       {
+               if( !modrule->Mod->Match )      continue;
+               rv = modrule->Mod->Match(modrule, AddrType, Src, Dest, Type, Flags, Length, Data);
+               if(rv == -1)    return -1;      // no match
+               // TODO: If != 0 maybe, allowing it to ask for a drop?
+       }
+       
+       // Update statistics
+       Rule->PacketCount ++;
+       Rule->ByteCount += Length;
+       
+       return IPTables_TestChain(Rule->Target, AddrType, Src, Dest, Type, Flags, Length, Data);
 }
 
 /**
@@ -93,6 +141,15 @@ int IPTables_TestChain(
        tChain  *chain;
        tRule   *rule;
        
+       if( AddressType >= MAX_ADDRTYPE )       return -1;      // Bad address type
+       
+       // Catch builtin targets
+       if(strcmp(RuleName, "") == 0)   return -1;      // No action
+       if(strcmp(RuleName, "ACCEPT") == 0)     return 0;       // Accept packet
+       if(strcmp(RuleName, "DROP") == 0)       return 1;       // Drop packet
+       if(strcmp(RuleName, "RETURN") == 0)     return -2;      // Return from rule
+       
+       // Find the rule
        for( chain = gapFirewall_Chains[AddressType]; chain; chain = chain->Next )
        {
                if( strcmp(chain->Name, RuleName) == 0 )
@@ -106,6 +163,8 @@ int IPTables_TestChain(
                rv = IPTables_DoRule(rule, AddressType, Src, Dest, Type, Flags, Length, Data);
                if( rv == -1 )
                        continue ;
+               if( rv == -2 )  // -2 = Return from a chain/table, pretend no match
+                       return -1;
                
                return rv;
        }
index b0dff23..2076d5a 100644 (file)
@@ -116,8 +116,8 @@ static const tMacAddr cMAC_BROADCAST = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
 
 extern int     IPStack_AddFile(tSocketFile *File);
 extern int     IPStack_GetAddressSize(int AddressType);
-extern int     IPStack_CompareAddress(int AddressType, void *Address1, void *Address2, int CheckBits);
-extern const char      *IPStack_PrintAddress(int AddressType, void *Address);
+extern int     IPStack_CompareAddress(int AddressType, const void *Address1, const void *Address2, int CheckBits);
+extern const char      *IPStack_PrintAddress(int AddressType, const void *Address);
 
 extern tRoute  *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address);
 
index d728325..ed59923 100644 (file)
@@ -169,7 +169,7 @@ void IPv6_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff
                hdr->HopLimit --;
                
                rt = IPStack_FindRoute(6, NULL, &hdr->Destination);     // Get the route (gets the interface)
-               //to = ARP_Resolve6(rt->Interface, hdr->Destination);   // Resolve address
+               to = ICMP6_ResolveHWAddr(rt->Interface, hdr->Destination);      // Resolve address
                
                // Send packet
                Log_Log("IPv6", "Forwarding packet");
index 6349995..5aa6715 100644 (file)
@@ -26,7 +26,7 @@ extern tRoute *IPStack_AddRoute(const char *Interface, void *Network, int Subnet
 
 // === PROTOTYPES ===
  int   IPStack_Install(char **Arguments);
- int   IPStack_CompareAddress(int AddressType, void *Address1, void *Address2, int CheckBits);
+ int   IPStack_CompareAddress(int AddressType, const void *Address1, const void *Address2, int CheckBits);
 
 // === GLOBALS ===
 MODULE_DEFINE(0, VERSION, IPStack, IPStack_Install, NULL, NULL);
@@ -218,17 +218,17 @@ int IPStack_GetAddressSize(int AddressType)
 /**
  * \brief Compare two IP Addresses masked by CheckBits
  */
-int IPStack_CompareAddress(int AddressType, void *Address1, void *Address2, int CheckBits)
+int IPStack_CompareAddress(int AddressType, const void *Address1, const void *Address2, int CheckBits)
 {
         int    size = IPStack_GetAddressSize(AddressType);
        Uint8   mask;
-       Uint8   *addr1 = Address1, *addr2 = Address2;
+       const Uint8     *addr1 = Address1, *addr2 = Address2;
        
        // Sanity check size
        if( CheckBits < 0 )     CheckBits = 0;
        if( CheckBits > size*8 )        CheckBits = size*8;
        
-       if( CheckBits == 0 )    return 1;       // /0 matches anythin0
+       if( CheckBits == 0 )    return 1;       // /0 matches anything
        
        // Check first bits/8 bytes
        if( memcmp(Address1, Address2, CheckBits/8) != 0 )      return 0;
@@ -244,20 +244,20 @@ int IPStack_CompareAddress(int AddressType, void *Address1, void *Address2, int
        return 0;
 }
 
-const char *IPStack_PrintAddress(int AddressType, void *Address)
+const char *IPStack_PrintAddress(int AddressType, const void *Address)
 {
        switch( AddressType )
        {
        case 4: {
                static char     ret[4*3+3+1];
-               Uint8   *addr = Address;
+               const Uint8     *addr = Address;
                sprintf(ret, "%i.%i.%i.%i", addr[0], addr[1], addr[2], addr[3]);
                return ret;
                }
        
-       case 6: {
+       case 6: {       // TODO: address compression
                static char     ret[8*4+7+1];
-               Uint16  *addr = Address;
+               const Uint16    *addr = Address;
                sprintf(ret, "%x:%x:%x:%x:%x:%x:%x:%x",
                        addr[0], addr[1], addr[2], addr[3],
                        addr[4], addr[5], addr[6], addr[7]
index cedb8ce..83a71b6 100644 (file)
@@ -18,7 +18,7 @@
 #define TCP_RECIEVE_BUFFER_SIZE        0x4000
 
 // === PROTOTYPES ===
-void   TCP_Initialise();
+void   TCP_Initialise(void);
 void   TCP_StartConnection(tTCPConnection *Conn);
 void   TCP_SendPacket(tTCPConnection *Conn, size_t Length, tTCPHeader *Data);
 void   TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer);
@@ -62,7 +62,7 @@ Uint32        gaTCP_PortBitmap[0x800];
  * 
  * Registers the client and server files and the GetPacket callback
  */
-void TCP_Initialise()
+void TCP_Initialise(void)
 {
        IPStack_AddFile(&gTCP_ServerFile);
        IPStack_AddFile(&gTCP_ClientFile);
diff --git a/Modules/Input/PS2KbMouse/Makefile b/Modules/Input/PS2KbMouse/Makefile
new file mode 100644 (file)
index 0000000..e30e472
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = main.o kb.o ps2mouse.o
+NAME = PS2KbMouse
+
+-include ../Makefile.tpl
diff --git a/Modules/Input/PS2KbMouse/kb.c b/Modules/Input/PS2KbMouse/kb.c
new file mode 100644 (file)
index 0000000..507d575
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * Acess2
+ * PS2 Keyboard Driver
+ */
+#include <acess.h>
+#include <modules.h>
+#include <fs_devfs.h>
+#include <tpl_drv_common.h>
+#include <tpl_drv_keyboard.h>
+#include "kb_kbdus.h"
+
+// === CONSTANTS ===
+#define        KB_BUFFER_SIZE  1024
+#define        USE_KERNEL_MAGIC        1
+
+// === IMPORTS ===
+extern void    Threads_ToggleTrace(int TID);
+extern void    Threads_Dump(void);
+extern void    Heap_Stats(void);
+
+// === PROTOTYPES ===
+ int   KB_Install(char **Arguments);
+void   KB_IRQHandler(int IRQNum);
+void   KB_AddBuffer(char ch);
+Uint64 KB_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Dest);
+void   KB_UpdateLEDs(void);
+ int   KB_IOCtl(tVFS_Node *Node, int Id, void *Data);
+
+// === GLOBALS ===
+tDevFS_Driver  gKB_DevInfo = {
+       NULL, "PS2Keyboard",
+       {
+       .NumACLs = 0,
+       .Size = 0,
+       //.Read = KB_Read,
+       .IOCtl = KB_IOCtl
+       }
+};
+tKeybardCallback       gKB_Callback = NULL;
+Uint32 **gpKB_Map = gpKBDUS;
+Uint8  gbaKB_States[3][256];
+ int   gbKB_ShiftState = 0;
+ int   gbKB_CapsState = 0;
+ int   gbKB_KeyUp = 0;
+ int   giKB_KeyLayer = 0;
+#if USE_KERNEL_MAGIC
+ int   gbKB_MagicState = 0;
+ int   giKB_MagicAddress = 0;
+ int   giKB_MagicAddressPos = 0;
+#endif
+
+// === CODE ===
+/**
+ * \brief Install the keyboard driver
+ */
+int KB_Install(char **Arguments)
+{
+       Uint8   temp;
+       
+       // Attempt to get around a strange bug in Bochs/Qemu by toggling
+       // the controller on and off
+       temp = inb(0x61);
+       outb(0x61, temp | 0x80);
+       outb(0x61, temp & 0x7F);
+       inb(0x60);      // Clear keyboard buffer
+       
+       IRQ_AddHandler(1, KB_IRQHandler);
+       DevFS_AddDevice( &gKB_DevInfo );
+       //Log("KB_Install: Installed");
+       return MODULE_ERR_OK;
+}
+
+/**
+ * \brief Called on a keyboard IRQ
+ * \param IRQNum       IRQ number (unused)
+ */
+void KB_IRQHandler(int IRQNum)
+{
+       Uint8   scancode;
+       Uint32  ch;
+       // int  keyNum;
+
+       // Check port 0x64 to tell if this is from the aux port
+       //if( inb(0x64) & 0x20 )        return;
+
+       scancode = inb(0x60); // Read from the keyboard's data buffer
+       //Log_Debug("Keyboard", "scancode = %02x", scancode);
+
+       // Ignore ACKs
+       if(scancode == 0xFA) {
+               // Oh man! This is anarchic (I'm leaving it here to represent
+               // the mess that Acess once was)
+               //kb_lastChar = KB_ACK;
+               return;
+       }
+
+       // Layer +1
+       if(scancode == 0xE0) {
+               giKB_KeyLayer = 1;
+               return;
+       }
+       // Layer +2
+       if(scancode == 0xE1) {
+               giKB_KeyLayer = 2;
+               return;
+       }
+
+       #if KB_ALT_SCANCODES
+       if(scancode == 0xF0)
+       {
+               gbKB_KeyUp = 1;
+               return;
+       }
+       #else
+       if(scancode & 0x80)
+       {
+               scancode &= 0x7F;
+               gbKB_KeyUp = 1;
+       }
+       #endif
+
+       // Translate
+       ch = gpKB_Map[giKB_KeyLayer][scancode];
+       // Check for unknown key
+       if(!ch && !gbKB_KeyUp)
+               Log_Warning("Keyboard", "UNK %i %x", giKB_KeyLayer, scancode);
+
+       // Key Up?
+       if (gbKB_KeyUp)
+       {
+               gbKB_KeyUp = 0;
+               gbaKB_States[giKB_KeyLayer][scancode] = 0;      // Unset key state flag
+
+               #if USE_KERNEL_MAGIC
+               if(ch == KEY_LCTRL)     gbKB_MagicState &= ~1;
+               if(ch == KEY_LALT)      gbKB_MagicState &= ~2;
+               #endif
+
+               if(ch == KEY_LSHIFT)    gbKB_ShiftState &= ~1;
+               if(ch == KEY_RSHIFT)    gbKB_ShiftState &= ~2;
+
+               // Call callback
+               if(ch != 0 && gKB_Callback)
+                       gKB_Callback( ch & 0x80000000 );
+
+               // Reset Layer
+               giKB_KeyLayer = 0;
+               return;
+       }
+
+       // Set the bit relating to the key
+       gbaKB_States[giKB_KeyLayer][scancode] = 1;
+       // Set shift key bits
+       if(ch == KEY_LSHIFT)    gbKB_ShiftState |= 1;
+       if(ch == KEY_RSHIFT)    gbKB_ShiftState |= 2;
+
+       // Check for Caps Lock
+       if(ch == KEY_CAPSLOCK) {
+               gbKB_CapsState = !gbKB_CapsState;
+               KB_UpdateLEDs();
+       }
+
+       // Reset Layer
+       giKB_KeyLayer = 0;
+
+       // Ignore Non-Printable Characters
+       if(ch == 0)             return;
+
+       // --- Check for Kernel Magic Combos
+       #if USE_KERNEL_MAGIC
+       if(ch == KEY_LCTRL) {
+               gbKB_MagicState |= 1;
+               //Log_Log("Keyboard", "Kernel Magic LCTRL Down\n");
+       }
+       if(ch == KEY_LALT) {
+               gbKB_MagicState |= 2;
+               //Log_Log("Keyboard", "Kernel Magic LALT Down\n");
+       }
+       if(gbKB_MagicState == 3)
+       {
+               switch(ch)
+               {
+               case '0':       case '1':       case '2':       case '3':
+               case '4':       case '5':       case '6':       case '7':
+               case '8':       case '9':       case 'a':       case 'b':
+               case 'c':       case 'd':       case 'e':       case 'f':
+                       {
+                       char    str[4] = {'0', 'x', ch, 0};
+                       if(giKB_MagicAddressPos == BITS/4)      return;
+                       giKB_MagicAddress |= atoi(str) << giKB_MagicAddressPos;
+                       giKB_MagicAddressPos ++;
+                       }
+                       return;
+               
+               // Instruction Tracing
+               case 't':
+                       Log("Toggle instruction tracing on %i\n", giKB_MagicAddress);
+                       Threads_ToggleTrace( giKB_MagicAddress );
+                       giKB_MagicAddress = 0;  giKB_MagicAddressPos = 0;
+                       return;
+               
+               // Thread List Dump
+               case 'p':       Threads_Dump(); return;
+               // Heap Statistics
+               case 'h':       Heap_Stats();   return;
+               // Dump Structure
+               case 's':       return;
+               }
+       }
+       #endif
+
+       // Capitals required?
+       if( (gbKB_ShiftState != 0) != (gbKB_CapsState != 0))
+       {
+               // TODO: Move this to the keyboard map header
+               switch(ch)
+               {
+               case 0: break;
+               case '`':       ch = '~';       break;
+               case '1':       ch = '!';       break;
+               case '2':       ch = '@';       break;
+               case '3':       ch = '#';       break;
+               case '4':       ch = '$';       break;
+               case '5':       ch = '%';       break;
+               case '6':       ch = '^';       break;
+               case '7':       ch = '&';       break;
+               case '8':       ch = '*';       break;
+               case '9':       ch = '(';       break;
+               case '0':       ch = ')';       break;
+               case '-':       ch = '_';       break;
+               case '=':       ch = '+';       break;
+               case '[':       ch = '{';       break;
+               case ']':       ch = '}';       break;
+               case '\\':      ch = '|';       break;
+               case ';':       ch = ':';       break;
+               case '\'':      ch = '"';       break;
+               case ',':       ch = '<';       break;
+               case '.':       ch = '>';       break;
+               case '/':       ch = '?';       break;
+               default:
+                       if('a' <= ch && ch <= 'z')
+                               ch -= 0x20;
+                       break;
+               }
+       }
+
+       if(gKB_Callback && ch != 0)     gKB_Callback(ch);
+}
+
+/**
+ * \fn void KB_UpdateLEDs(void)
+ * \brief Updates the status of the keyboard LEDs
+ */
+void KB_UpdateLEDs(void)
+{
+       Uint8   leds;
+
+       leds = (gbKB_CapsState ? 4 : 0);
+
+       while( inb(0x64) & 2 ); // Wait for bit 2 to unset
+       outb(0x60, 0xED);       // Send update command
+
+       while( inb(0x64) & 2 ); // Wait for bit 2 to unset
+       outb(0x60, leds);
+}
+
+/**
+ * \fn int KB_IOCtl(tVFS_Node *Node, int Id, void *Data)
+ * \brief Calls an IOCtl Command
+ */
+int KB_IOCtl(tVFS_Node *Node, int Id, void *Data)
+{
+       switch(Id)
+       {
+       case DRV_IOCTL_TYPE:    return DRV_TYPE_KEYBOARD;
+       case DRV_IOCTL_IDENT:   memcpy(Data, "KB\0\0", 4);      return 1;
+       case DRV_IOCTL_VERSION: return 0x100;
+       case DRV_IOCTL_LOOKUP:  return 0;
+
+       // Sets the Keyboard Callback
+       case KB_IOCTL_SETCALLBACK:
+               // Sanity Check
+               if((Uint)Data < KERNEL_BASE)    return 0;
+               // Can only be set once
+               if(gKB_Callback != NULL)        return 0;
+               // Set Callback
+               gKB_Callback = Data;
+               return 1;
+
+       default:
+               return 0;
+       }
+}
diff --git a/Modules/Input/PS2KbMouse/kb_kbdus.h b/Modules/Input/PS2KbMouse/kb_kbdus.h
new file mode 100644 (file)
index 0000000..441b19a
--- /dev/null
@@ -0,0 +1,73 @@
+\r
+#ifndef _KBDUS_H\r
+#define _KBDUS_H\r
+\r
+// - BASE (NO PREFIX)\r
+Uint32 gpKBDUS1[256] = {\r
+/*00*/ 0,  KEY_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t',\r
+/*10*/ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', KEY_LCTRL, 'a', 's',\r
+/*20*/ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`', KEY_LSHIFT,'\\', 'z', 'x', 'c', 'v',\r
+/*30*/ 'b', 'n', 'm', ',', '.', '/', KEY_RSHIFT, KEY_KPSTAR,\r
+                       KEY_LALT, ' ', KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,\r
+/*40*/ KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_KPHOME,\r
+                       KEY_KPUP, KEY_KPPGUP, KEY_KPMINUS, KEY_KPLEFT, KEY_KP5, KEY_KPRIGHT, KEY_KPPLUS, KEY_KPEND,\r
+/*50*/ KEY_KPDOWN, KEY_KPPGDN, KEY_KPINS, KEY_KPDEL, 0, 0, 0, KEY_F11,\r
+                       KEY_F12, 0, 0, 0, 0, 0, 0, 0,\r
+/*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*A0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*B0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*C0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*D0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*E0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*F0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
+};\r
+// - 0xE0 Prefixed\r
+Uint32 gpKBDUS2[256] = {\r
+//     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\r
+/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0-F\r
+/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_KPENTER, KEY_RCTRL, 0, 0,\r
+/*20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*30*/ 0, 0, 0, 0, 0, KEY_KPSLASH, 0, 0, KEY_RALT, 0, 0, 0, 0, 0, 0, 0,\r
+/*40*/ 0, 0, 0, 0, 0, 0, 0, KEY_HOME,\r
+                       KEY_UP, KEY_PGUP, 0, KEY_LEFT, 0, KEY_RIGHT, 0, KEY_END,\r
+/*50*/ KEY_DOWN, KEY_PGDOWN, KEY_INS, KEY_DEL, 0, 0, 0, 0,\r
+                       0, 0, KEY_WIN, 0, 0, KEY_MENU, 0, 0,\r
+/*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*A0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*B0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*C0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*D0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*E0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*F0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
+};\r
+// - 0xE1 Prefixed\r
+Uint32 gpKBDUS3[256] = {\r
+//     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\r
+/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0-F\r
+/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_PAUSE, 0, 0,\r
+/*20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*30*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*A0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*B0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*C0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*D0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*E0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*F0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
+};\r
+\r
+\r
+Uint32 *gpKBDUS[3] = { gpKBDUS1, gpKBDUS2, gpKBDUS3 };\r
+\r
+#endif\r
diff --git a/Modules/Input/PS2KbMouse/main.c b/Modules/Input/PS2KbMouse/main.c
new file mode 100644 (file)
index 0000000..353befb
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Acess2
+ *
+ * PS/2 Keboard / Mouse Driver
+ */
+#include <acess.h>
+#include <modules.h>
+
+// === IMPORTS ===
+extern int     KB_Install(char **Arguments);
+extern int     Mouse_Install(char **Arguments);
+
+// === PROTOTYPES ===
+ int   PS2_Install(char **Arguments);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, 0x0100, Input_PS2KbMouse, PS2_Install, NULL, NULL);
+MODULE_DEFINE(0, 0x0100, PS2Keyboard, KB_Install, NULL, NULL);
+
+// === CODE ===
+int PS2_Install(char **Arguments)
+{
+//     KB_Install(Arguments);
+//     Mouse_Install(Arguments);
+       return MODULE_ERR_OK;
+}
diff --git a/Modules/Input/PS2KbMouse/ps2mouse.c b/Modules/Input/PS2KbMouse/ps2mouse.c
new file mode 100644 (file)
index 0000000..e87292a
--- /dev/null
@@ -0,0 +1,203 @@
+/*\r
+ * Acess2 Mouse Driver\r
+ */\r
+#define DEBUG  0\r
+#include <acess.h>\r
+#include <modules.h>\r
+#include <vfs.h>\r
+#include <fs_devfs.h>\r
+#include <tpl_drv_common.h>\r
+#include <tpl_drv_joystick.h>\r
+\r
+// == CONSTANTS ==\r
+#define PS2_IO_PORT    0x60\r
+#define MOUSE_BUFFER_SIZE      (sizeof(t_mouse_fsdata))\r
+#define MOUSE_SENS_BASE        5\r
+\r
+// == PROTOTYPES ==\r
+// - Internal -\r
+ int   PS2Mouse_Install(char **Arguments);\r
+void   PS2Mouse_IRQ(int Num);\r
+static void    mouseSendCommand(Uint8 cmd);\r
+static void    enableMouse();\r
+// - Filesystem -\r
+static Uint64  PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);\r
+static int     PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data);\r
+\r
+typedef struct {\r
+       int x, y, buttons, unk;\r
+}      t_mouse_fsdata;\r
+\r
+// == GLOBALS ==\r
+ int   giMouse_Sensitivity = 1;\r
+t_mouse_fsdata gMouse_Data = {0, 0, 0, 0};\r
+ int giMouse_MaxX = 640, giMouse_MaxY = 480;\r
+ int   giMouse_Cycle = 0;      // IRQ Position\r
+Uint8  gaMouse_Bytes[4] = {0,0,0,0};\r
+tDevFS_Driver  gMouse_DriverStruct = {\r
+       NULL, "ps2mouse",\r
+       {\r
+       .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRX,\r
+       .Read = PS2Mouse_Read, .IOCtl = PS2Mouse_IOCtl\r
+       }\r
+};\r
+\r
+// == CODE ==\r
+int Mouse_Install(char **Arguments)\r
+{\r
+       // Initialise Mouse Controller\r
+       IRQ_AddHandler(12, PS2Mouse_IRQ);       // Set IRQ\r
+       giMouse_Cycle = 0;      // Set Current Cycle position\r
+       enableMouse();          // Enable the mouse\r
+       \r
+       DevFS_AddDevice(&gMouse_DriverStruct);\r
+       \r
+       return MODULE_ERR_OK;\r
+}\r
+\r
+/* Handle Mouse Interrupt\r
+ */\r
+void PS2Mouse_IRQ(int Num)\r
+{\r
+       Uint8   flags;\r
+       int     dx, dy;\r
+       //int   log2x, log2y;\r
+       \r
+       gaMouse_Bytes[giMouse_Cycle] = inb(0x60);\r
+       if(giMouse_Cycle == 0 && !(gaMouse_Bytes[giMouse_Cycle] & 0x8))\r
+               return;\r
+       giMouse_Cycle++;\r
+       if(giMouse_Cycle == 3)\r
+               giMouse_Cycle = 0;\r
+       else\r
+               return;\r
+       \r
+       if(giMouse_Cycle > 0)\r
+               return;\r
+       \r
+       // Read Flags\r
+       flags = gaMouse_Bytes[0];\r
+       if(flags & 0xC0)        // X/Y Overflow\r
+               return;\r
+               \r
+       #if DEBUG\r
+       //LogF(" PS2Mouse_Irq: flags = 0x%x\n", flags);\r
+       #endif\r
+       \r
+       // Calculate dX and dY\r
+       dx = (int) ( gaMouse_Bytes[1] | (flags & 0x10 ? ~0x00FF : 0) );\r
+       dy = (int) ( gaMouse_Bytes[2] | (flags & 0x20 ? ~0x00FF : 0) );\r
+       dy = -dy;       // Y is negated\r
+       LOG("RAW dx=%i, dy=%i\n", dx, dy);\r
+       dx = dx*MOUSE_SENS_BASE/giMouse_Sensitivity;\r
+       dy = dy*MOUSE_SENS_BASE/giMouse_Sensitivity;\r
+       \r
+       //__asm__ __volatile__ ("bsr %%eax, %%ecx" : "=c" (log2x) : "a" ((Uint)gaMouse_Bytes[1]));\r
+       //__asm__ __volatile__ ("bsr %%eax, %%ecx" : "=c" (log2y) : "a" ((Uint)gaMouse_Bytes[2]));\r
+       //LogF(" PS2Mouse_Irq: dx=%i, log2x = %i\n", dx, log2x);\r
+       //LogF(" PS2Mouse_Irq: dy=%i, log2y = %i\n", dy, log2y);\r
+       //dx *= log2x;\r
+       //dy *= log2y;\r
+       \r
+       // Set Buttons\r
+       gMouse_Data.buttons = flags & 0x7;      //Buttons (3 only)\r
+       \r
+       // Update X and Y Positions\r
+       gMouse_Data.x += (int)dx;\r
+       gMouse_Data.y += (int)dy;\r
+       \r
+       // Constrain Positions\r
+       if(gMouse_Data.x < 0)   gMouse_Data.x = 0;\r
+       if(gMouse_Data.y < 0)   gMouse_Data.y = 0;\r
+       if(gMouse_Data.x >= giMouse_MaxX)       gMouse_Data.x = giMouse_MaxX-1;\r
+       if(gMouse_Data.y >= giMouse_MaxY)       gMouse_Data.y = giMouse_MaxY-1; \r
+}\r
+\r
+/* Read mouse state (coordinates)\r
+ */\r
+static Uint64 PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
+{\r
+       if(Length < MOUSE_BUFFER_SIZE)\r
+               return -1;\r
+\r
+       memcpy(Buffer, &gMouse_Data, MOUSE_BUFFER_SIZE);\r
+               \r
+       return MOUSE_BUFFER_SIZE;\r
+}\r
+\r
+static const char *csaIOCtls[] = {DRV_IOCTLNAMES, NULL};\r
+/* Handle messages to the device\r
+ */\r
+static int PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data)\r
+{\r
+       struct {\r
+                int    Num;\r
+                int    Value;\r
+       }       *info = Data;\r
+       switch(ID)\r
+       {\r
+       BASE_IOCTLS(DRV_TYPE_JOYSTICK, "PS2Mouse", 0x100, csaIOCtls);\r
+       \r
+       case JOY_IOCTL_GETSETAXISLIMIT:\r
+               if(!info)       return 0;\r
+               switch(info->Num)\r
+               {\r
+               case 0: // X\r
+                       if(info->Value != -1)\r
+                               giMouse_MaxX = info->Value;\r
+                       return giMouse_MaxX;\r
+               case 1: // Y\r
+                       if(info->Value != -1)\r
+                               giMouse_MaxY = info->Value;\r
+                       return giMouse_MaxY;\r
+               }\r
+               return 0;\r
+               \r
+       default:\r
+               return 0;\r
+       }\r
+}\r
+\r
+//== Internal Functions ==\r
+static inline void mouseOut64(Uint8 data)\r
+{\r
+       int timeout=100000;\r
+       while( timeout-- && inb(0x64) & 2 );    // Wait for Flag to clear\r
+       outb(0x64, data);       // Send Command\r
+}\r
+static inline void mouseOut60(Uint8 data)\r
+{\r
+       int timeout=100000;\r
+       while( timeout-- && inb(0x64) & 2 );    // Wait for Flag to clear\r
+       outb(0x60, data);       // Send Command\r
+}\r
+static inline Uint8 mouseIn60()\r
+{\r
+       int timeout=100000;\r
+       while( timeout-- && (inb(0x64) & 1) == 0);      // Wait for Flag to set\r
+       return inb(0x60);\r
+}\r
+static void mouseSendCommand(Uint8 cmd)\r
+{\r
+       mouseOut64(0xD4);\r
+       mouseOut60(cmd);\r
+}\r
+\r
+static void enableMouse()\r
+{\r
+       Uint8   status;\r
+       Log_Log("PS2 Mouse", "Enabling Mouse...");\r
+       \r
+       // Enable AUX PS/2\r
+       mouseOut64(0xA8);\r
+       \r
+       // Enable AUX PS/2 (Compaq Status Byte)\r
+       mouseOut64(0x20);       // Send Command\r
+       status = mouseIn60();   // Get Status\r
+       status &= 0xDF; status |= 0x02; // Alter Flags (Set IRQ12 (2) and Clear Disable Mouse Clock (20))\r
+       mouseOut64(0x60);       // Send Command\r
+       mouseOut60(status);     // Set Status\r
+       \r
+       //mouseSendCommand(0xF6);       // Set Default Settings\r
+       mouseSendCommand(0xF4); // Enable Packets\r
+}\r
index e8cb7b7..fb92d54 100644 (file)
@@ -33,19 +33,22 @@ int UHCI_Initialise()
 {\r
         int    i=0, id=-1;\r
         int    ret;\r
-       Uint16  base;\r
        \r
        ENTER("");\r
        \r
        // Enumerate PCI Bus, getting a maximum of `MAX_CONTROLLERS` devices\r
        while( (id = PCI_GetDeviceByClass(0x0C03, 0xFFFF, id)) >= 0 && i < MAX_CONTROLLERS )\r
        {\r
+               // NOTE: Check "protocol" from PCI?\r
+               \r
                gUHCI_Controllers[i].PciId = id;\r
                // Assign a port range (BAR4, Reserve 32 ports)\r
-               base = PCI_AssignPort( id, 4, 0x20 );\r
-               gUHCI_Controllers[i].IOBase = base;\r
+               //base = PCI_AssignPort( id, 4, 0x20 );\r
+               gUHCI_Controllers[i].IOBase = PCI_GetBAR4(id);\r
+               gUHCI_Controllers[i].IRQNum = PCI_GetIRQ(id);\r
                \r
-               Log("[USB  ] Controller PCI #%i: IO Base = 0x%x", id, base);\r
+               Log("[USB  ] Controller PCI #%i: IO Base = 0x%x, IRQ %i",\r
+                       id, gUHCI_Controllers[i].IOBase, gUHCI_Controllers[i].IRQNum);\r
                \r
                // Initialise Host\r
                ret = UHCI_Int_InitHost(&gUHCI_Controllers[i]);\r
@@ -91,10 +94,14 @@ int UHCI_Int_InitHost(tUHCI_Controller *Host)
 {\r
        ENTER("pHost", Host);\r
        \r
+       outw( Host->IOBase + USBCMD, 4 );       // GRESET\r
+       // TODO: Wait for at least 10ms\r
+       outw( Host->IOBase + USBCMD, 0 );       // GRESET\r
+       \r
        // Allocate Frame List\r
        Host->FrameList = (void *) MM_AllocDMA(1, 32, &Host->PhysFrameList);    // 1 Page, 32-bit\r
        if( !Host->FrameList ) {\r
-               Warning("[UHCI ] Unable to allocate frame list, aborting");\r
+               Log_Warning("UHCI", "Unable to allocate frame list, aborting");\r
                LEAVE('i', -1);\r
                return -1;\r
        }\r
index df7854b..d8ace9f 100644 (file)
@@ -24,6 +24,11 @@ struct sUHCI_Controller
         */
        Uint16  IOBase;
        
+       /**
+        * \brief IRQ Number assigned to the device
+        */
+        int    IRQNum;
+       
        /**
         * \brief Frame list
         * 
diff --git a/Modules/x86/ISADMA/Makefile b/Modules/x86/ISADMA/Makefile
new file mode 100644 (file)
index 0000000..b74c63f
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ := dma.o
+NAME := ISADMA
+
+-include ../Makefile.tpl
diff --git a/Modules/x86/ISADMA/dma.c b/Modules/x86/ISADMA/dma.c
new file mode 100644 (file)
index 0000000..7b388a7
--- /dev/null
@@ -0,0 +1,124 @@
+/*\r
+ * AcessOS 1.0\r
+ * DMA Driver\r
+ */\r
+#include <acess.h>\r
+#include <modules.h>\r
+\r
+#define DMA_SIZE       (0x2400)\r
+#define DMA_ADDRESS(c) ((c)*DMA_SIZE+0x500)    //Save Space for IDT and BDA\r
+\r
+#define LOWB(x)        ((x)&0xFF)\r
+#define HIB(x) (((x)>>8)&0xFF)\r
+#define HIW(x) (((x)>>16)&0xFFFF)\r
+\r
+// === TYPES ===\r
+typedef struct\r
+{\r
+        int    mode;\r
+       char    *address;\r
+} t_dmaChannel;\r
+\r
+// === PROTOTYPES ===\r
+ int   DMA_Install(char **Arguments);\r
+void   DMA_SetChannel(int Channel, int length, int read);\r
+ int   DMA_ReadData(int channel, int count, void *buffer);\r
+ int   DMA_WriteData(int channel, int count, const void *buffer);\r
+\r
+// === CONSTANTS ===\r
+const Uint8 cMASKPORT [8] = { 0x0A, 0x0A, 0x0A, 0x0A, 0xD4, 0xD4, 0xD4, 0xD4 };\r
+const Uint8 cMODEPORT [8] = { 0x0B, 0x0B, 0x0B, 0x0B, 0xD6, 0xD6, 0xD6, 0xD6 };\r
+const Uint8 cCLEARPORT[8] = { 0x0C, 0x0C, 0x0C, 0x0C, 0xD8, 0xD8, 0xD8, 0xD8 };\r
+const Uint8 cPAGEPORT [8] = { 0x87, 0x83, 0x81, 0x82, 0x8F, 0x8B, 0x89, 0x8A };\r
+const Uint8 cADDRPORT [8] = { 0x00, 0x02, 0x04, 0x06, 0xC0, 0xC4, 0xC8, 0xCC };\r
+const Uint8 cCOUNTPORT[8] = { 0x01, 0x03, 0x05, 0x07, 0xC2, 0xC6, 0xCA, 0xCE };\r
+\r
+// === GLOBALS ===\r
+MODULE_DEFINE(0, 0x0100, x86_ISADMA, DMA_Install, NULL, NULL);\r
+char   *dma_addresses[8];\r
+t_dmaChannel   dma_channels[8];\r
+\r
+// === CODE ===\r
+/**\r
+ * \brief Initialise DMA channels\r
+ * \param Arguments    Arguments passed at boot time\r
+ */\r
+int DMA_Install(char **Arguments)\r
+{\r
+       Uint    i;\r
+       for(i=8;i--;)\r
+       {\r
+               outb( cMASKPORT[i], 0x04 | (i & 0x3) ); // mask channel\r
+               outb( cCLEARPORT[i], 0x00 );\r
+               outb( cMODEPORT[i], 0x48 | (i & 0x3) ); //Read Flag\r
+               outb( 0xd8, 0xff);      //Reset Flip-Flop\r
+               outb( cADDRPORT[i], LOWB(DMA_ADDRESS(i)) );     // send address\r
+               outb( cADDRPORT[i], HIB(DMA_ADDRESS(i)) );      // send address\r
+               outb( 0xd8, 0xff);      //Reset Flip-Flop\r
+               outb( cCOUNTPORT[i], LOWB(DMA_SIZE) );      // send size\r
+               outb( cCOUNTPORT[i], HIB(DMA_SIZE) );       // send size\r
+               outb( cPAGEPORT[i], LOWB(HIW(DMA_ADDRESS(i))) );        // send page\r
+               outb( cMASKPORT[i], i & 0x3 );              // unmask channel\r
+               \r
+               dma_channels[i].mode = 0;\r
+               dma_addresses[i] = (char*)DMA_ADDRESS(i);\r
+               dma_addresses[i] += KERNEL_BASE;\r
+       }\r
+       return MODULE_ERR_OK;\r
+}\r
+\r
+/**\r
+ * \fn void DMA_SetChannel(int Channel, int length, int read)\r
+ * \brief Set DMA Channel Length and RW\r
+ */\r
+void DMA_SetChannel(int Channel, int length, int read)\r
+{\r
+       Uint    chan = Channel & 7;\r
+       read = !!read;\r
+       if(length > DMA_SIZE)   length = DMA_SIZE;\r
+       length --;      //Adjust for DMA\r
+       //__asm__ __volatile__ ("cli");\r
+       outb( cMASKPORT[chan], 0x04 | (chan & 0x3) );           // mask channel\r
+       outb( cCLEARPORT[chan], 0x00 );\r
+       outb( cMODEPORT[chan], (0x44 + (!read)*4) | (chan & 0x3) );\r
+       outb( cADDRPORT[chan], LOWB(DMA_ADDRESS(chan)) );               // send address\r
+       outb( cADDRPORT[chan], HIB(DMA_ADDRESS(chan)) );                // send address\r
+       outb( cPAGEPORT[chan], HIW(DMA_ADDRESS(chan)) );                // send page\r
+       outb( cCOUNTPORT[chan], LOWB(length) );      // send size\r
+       outb( cCOUNTPORT[chan], HIB(length) );       // send size\r
+       outb( cMASKPORT[chan], chan & 0x3 );              // unmask channel\r
+       dma_addresses[chan] = (char*)DMA_ADDRESS(chan);\r
+       dma_addresses[chan] += KERNEL_BASE;\r
+       //__asm__ __volatile__ ("sti");\r
+}\r
+\r
+/**\r
+ * \fn void DMA_ReadData(int channel, int count, void *buffer)\r
+ * \brief Read data from a DMA buffer\r
+ */\r
+int DMA_ReadData(int channel, int count, void *buffer)\r
+{\r
+       if(channel < 0 || channel > 7)\r
+               return -1;\r
+       if(count < 0 || count > DMA_SIZE)\r
+               return -2;\r
+       //LogF("memcpy(*0x%x, dma_channels[channel].address, count)\n", buffer\r
+       memcpy(buffer, dma_addresses[channel], count);\r
+       return 0;\r
+}\r
+\r
+/**\r
+ * \fn void DMA_WriteData(int channel, int count, void *buffer)\r
+ * \brief Write data to a DMA buffer\r
+ */\r
+int DMA_WriteData(int channel, int count, const void *buffer)\r
+{\r
+       if(channel < 0 || channel > 7)\r
+               return -1;\r
+       if(count < 0 || count > DMA_SIZE)\r
+               return -2;\r
+       \r
+       memcpy(dma_addresses[channel], buffer, count);\r
+       \r
+       return 0;\r
+}\r
diff --git a/Modules/x86/Makefile.tpl b/Modules/x86/Makefile.tpl
new file mode 100644 (file)
index 0000000..61b234f
--- /dev/null
@@ -0,0 +1,3 @@
+CATEGORY = x86
+
+-include ../../Makefile.tpl
index aa93996..c0eeeec 100644 (file)
@@ -9,13 +9,15 @@
  int   Menubar_HandleMessage(tAxWin_Message *Message);
 
 // === GLOBALS ===
-tAxWin_Handle  ghMenubarWindow;
+tAxWin_Element geConsole;
 
 // === CODE ===
 int main(int argc, char *argv[])
 {
        AxWin_Register("Terminal");
        
+       //geConsole = AxWin_CreateElement();
+       
        AxWin_MessageLoop();
        
        return 0;
index 630b1f4..8d62c67 100644 (file)
@@ -35,31 +35,29 @@ void Interface_Init(void)
        // Set root window to no-border
        WM_SetFlags(NULL, 0);
        
-       // -- Create Sidebar --
+       // -- Create Sidebar (Menu and Window List) --
        gpInterface_Sidebar = WM_CreateElement(NULL, ELETYPE_TOOLBAR, ELEFLAG_VERTICAL, "Sidebar");
        WM_SetSize( gpInterface_Sidebar, giInterface_Width );
        
        // > System Menu Button
        btn = WM_CreateElement(gpInterface_Sidebar, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH, "SystemMenu");
        WM_SetSize(btn, giInterface_Width-4);
-       // TODO: Once image loading is implemented, switch to a logo
-       #if 1
-       //text = WM_CreateElement(btn, ELETYPE_IMAGE, ELEFLAG_SCALE);
+       //text = WM_CreateElement(btn, ELETYPE_IMAGE, ELEFLAG_SCALE, "MenuLogo");
        text = WM_CreateElement(btn, ELETYPE_IMAGE, 0, "MenuLogo");
        //WM_SetText(text, "file:///LogoSmall.sif");
        WM_SetText(text, csLogoSmall);
-       #else
-       text = WM_CreateElement(btn, ELETYPE_TEXT, 0, NULL);
-       WM_SetText(text, "Acess");
-       #endif
+       
        // > Plain <hr/> style spacer
        ele = WM_CreateElement(gpInterface_Sidebar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, "SideBar Spacer Top");
        WM_SetSize(ele, 4);
-       // > Application List
+       
+       // > Application List (Window list on most OSs)
        gpInterface_ProgramList = WM_CreateElement(gpInterface_Sidebar, ELETYPE_BOX, ELEFLAG_VERTICAL, "ProgramList");
+       
        // > Plain <hr/> style spacer
        ele = WM_CreateElement(gpInterface_Sidebar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, "SideBar Spacer Bottom");
        WM_SetSize(ele, 4);
+       
        // > Version/Time
        text = WM_CreateElement(gpInterface_Sidebar, ELETYPE_TEXT, ELEFLAG_NOSTRETCH, "Version String");
        WM_SetSize(text, 20);
index cd4ab90..565697d 100644 (file)
@@ -71,12 +71,12 @@ enum eElementFlags
        /**
         * \brief Element visibility
         * 
-        * If set, the element is not drawn.
+        * If set, the element is not drawn (but still is used for size calculations)
         */
        ELEFLAG_INVISIBLE   = 0x002,
        
        /**
-        * \brief Position an element absulutely
+        * \brief Position an element absulutely (ignored in size calcs)
         */
        ELEFLAG_ABSOLUTEPOS = 0x004,
        
@@ -87,6 +87,9 @@ enum eElementFlags
        
        /**
         * \brief Element "orientation"
+        * 
+        * Vertical means that the children of this element are stacked,
+        * otherwise they list horizontally
         */
        ELEFLAG_VERTICAL    = 0x010,//  ELEFLAG_HORIZONTAL  = 0x000,
        /**
@@ -105,7 +108,7 @@ enum eElementFlags
        /**
         * \brief With (length) size action
         * If this flag is set, the element will only be as large as
-        * is required
+        * is required along it's parent
         */
        ELEFLAG_NOSTRETCH   = 0x080,
        
@@ -115,8 +118,11 @@ enum eElementFlags
        ELEFLAG_ALIGN_CENTER= 0x100,
        /**
         * \brief Right/Bottom alignment
+        * 
+        * If set, the element aligns to the end of avaliable space (instead
+        * of the beginning)
         */
-       ELEFLAG_ALIGN_END = 0x200
+       ELEFLAG_ALIGN_END       = 0x200
 };
 
 /**
@@ -125,15 +131,16 @@ enum eElementTypes
 {
        ELETYPE_NONE,
        
-       ELETYPE_BOX,    //!< Content box
+       ELETYPE_BOX,    //!< Content box (invisible in itself)
        ELETYPE_TABBAR, //!< Tab Bar
        ELETYPE_TOOLBAR,        //!< Tool Bar
        
        ELETYPE_BUTTON, //!< Push Button
+       
        ELETYPE_TEXT,   //!< Text
        ELETYPE_IMAGE,  //!< Image
        
-       ELETYPE_SPACER, //!< Visual Spacer
+       ELETYPE_SPACER, //!< Visual Spacer (horizontal / vertical rule)
        
        MAX_ELETYPES    = 0x100
 };
diff --git a/Usermode/Applications/imageview_src/Makefile b/Usermode/Applications/imageview_src/Makefile
new file mode 100644 (file)
index 0000000..f3abb88
--- /dev/null
@@ -0,0 +1,11 @@
+# Project: imageview
+
+-include ../Makefile.cfg
+
+LDFLAGS += -luri
+
+OBJ := main.o
+BIN := imageview
+
+-include ../Makefile.tpl
+
diff --git a/Usermode/Applications/imageview_src/main.c b/Usermode/Applications/imageview_src/main.c
new file mode 100644 (file)
index 0000000..a998061
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Acess2 Image Viewer
+ * By John Hodge (thePowersGang)
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <acess/sys.h>
+#include <uri.h>
+
+// === PROTOTYPES ===
+ int   main(int argc, char *argv[]);
+void   *SIF_Load(tURIFile *FP, int *Width, int *Height, uint32_t Magic);
+
+// === CONSTANTS ===
+const struct {
+       const char      *Name;
+       uint32_t        Mask;
+       uint32_t        Ident;
+       void    *(*Load)(tURIFile *FP, int *Width, int *Height, uint32_t Magic);
+}      caFileTypes[] = {
+       {"SIF", 0xFFFF, 0x51F0, SIF_Load}
+       };
+#define NUM_FILE_TYPES (sizeof(caFileTypes)/sizeof(caFileTypes[0]))
+
+// === CODE ===
+int main(int argc, char *argv[])
+{
+       char    *imageURI;
+       tURI    *uri;
+       tURIFile        *fp;
+       uint32_t        idDWord = 0;
+        int    i;
+       uint32_t        *buffer;
+        int    w, h;
+        int    termW, termH;
+        int    tmp;
+       
+       // --- Parse Arguments
+       if( argc < 2 ) {
+               fprintf(stderr, "Usage: %s <image>\n", argv[0]);
+               return 0;
+       }
+       imageURI = argv[1];
+       
+       // --- Open File
+       uri = URI_Parse(imageURI);
+       printf("uri = {Proto:'%s',Host:'%s',Port:%i('%s'),Path:'%s'}\n",
+               uri->Proto, uri->Host, uri->PortNum, uri->PortStr, uri->Path);
+       fp = URI_Open(URI_MODE_READ, uri);
+       printf("fp = %p\n", fp);
+       if(!fp) {
+               fprintf(stderr, "ERROR: Unable to open '%s'\nFile unable to open\n", imageURI);
+               return -1;
+       }
+       free(uri);
+       
+       
+       // --- Determine file type
+       i = URI_Read(fp, 4, &idDWord);
+       printf("i = %i\n", i);
+       printf("idDWord = 0x%08lx\n", idDWord);
+       for( i = 0; i < NUM_FILE_TYPES; i++ )
+       {
+               if( (idDWord & caFileTypes[i].Mask) == caFileTypes[i].Ident )
+                       break;
+       }
+       if( i == NUM_FILE_TYPES ) {
+               fprintf(stderr, "ERROR: Unable to open '%s'\nUnknown file type\n", imageURI);
+               return -2;
+       }
+       
+       // --- Load
+       buffer = caFileTypes[i].Load(fp, &w, &h, idDWord);
+       if( !buffer ) {
+               fprintf(stderr, "ERROR: Unable to open '%s'\nParsing failed\n", imageURI);
+               return -3;
+       }
+       
+       printf("w=%i,h=%i\n", w, h);
+       
+       // --- Display
+       termW = ioctl(1, 5, NULL);      termW *= 8;     ioctl(1, 5, &termW);
+       termH = ioctl(1, 6, NULL);      termH *= 16;    ioctl(1, 6, &termH);
+       //printf("termW = %i, termH = %i\n", termW, termH);
+       tmp = 1;        ioctl(1, 4, &tmp);
+       
+       seek(1, 0, SEEK_SET);
+       for( i = 0; i < (h < termH ? h : termH); i++ )
+       {
+               write(1, (w < termW ? w : termW) * 4, buffer + i*w);
+               if(w < termW)
+                       seek(1, (termW-w)*4, SEEK_CUR);
+       }
+       
+       for( ;; );
+       
+       return 0;
+}
+
+// === Simple Image Format Loader ===
+void *SIF_Load(tURIFile *FP, int *Width, int *Height, uint32_t Magic)
+{
+       uint16_t        flags = Magic >> 16;
+       uint16_t        w, h;
+        int    comp = flags & 3;
+        int    ofs, i;
+       uint32_t        *ret;
+       
+       // First 4 bytes were read by main()
+       URI_Read(FP, 2, &w);
+       URI_Read(FP, 2, &h);
+       
+       ret = malloc(w * h * 4);
+       
+       switch(comp)
+       {
+       // Uncompressed 32-bpp data
+       case 0:
+               URI_Read( FP, w * h * 4, ret );
+               *Width = w;
+               *Height = h;
+               return ret;
+       
+       // 1.7.32 RLE
+       // (1 Flag, 7-bit size, 32-bit value)
+       case 1:
+               ofs = 0;
+               while( ofs < w*h )
+               {
+                       uint8_t len;
+                       uint32_t        val;
+                       URI_Read(FP, 1, &len);
+                       if(len & 0x80) {
+                               len &= 0x7F;
+                               URI_Read(FP, len, ret+ofs);
+                               ofs += len;
+                       }
+                       else {
+                               URI_Read(FP, 4, &val);
+                               while(len--)    ret[ofs++] = val;
+                       }
+               }
+               return ret;
+       
+       case 3:
+               // Alpha
+               ofs = 0;
+               while( ofs < w*h )
+               {
+                       uint8_t len, val;
+                       URI_Read(FP, 1, &len);
+                       if(len & 0x80) {
+                               len &= 0x7F;
+                               while(len--) {
+                                       URI_Read(FP, 1, &val);
+                                       ret[ofs++] = (uint32_t)val << 24;
+                               }
+                       }
+                       else {
+                               URI_Read(FP, 1, &val);
+                               while(len--)
+                                       ret[ofs++] = (uint32_t)val << 24;
+                       }
+               }
+               // Red, Green, Blue
+               for( i = 0; i < 4; i++ )
+               {
+                       ofs = 0;
+                       while( ofs < w*h )
+                       {
+                               uint8_t len, val;
+                               URI_Read(FP, 1, &len);
+                               if(len & 0x80) {
+                                       len &= 0x7F;
+                                       while(len--) {
+                                               URI_Read(FP, 1, &val);
+                                               ret[ofs++] |= (uint32_t)val << (24-i*8);
+                                       }
+                               }
+                               else {
+                                       URI_Read(FP, 1, &val);
+                                       while(len--)
+                                               ret[ofs++] |= (uint32_t)val << (24-i*8);
+                               }
+                       }
+               }
+               return ret;
+       
+       default:
+               fprintf(stderr, "Warning: Unknown compression scheme %i for SIF\n", comp);
+               return NULL;
+       }
+       
+}
index d69a4be..4117b02 100644 (file)
@@ -245,7 +245,7 @@ EXPORT int fputc(int c, FILE *fp)
  */\r
 EXPORT int fgetc(FILE *fp)\r
 {\r
-        int    ret = 0;\r
+       char    ret = 0;\r
        if(!fp) return -1;\r
        if(read(fp->FD, 1, &ret) == -1) return -1;\r
        return ret;\r
index 5355838..d84b8f9 100644 (file)
@@ -1,4 +1,7 @@
 /*
+ * SpiderScript Library
+ *
+ * AST Execution
  */
 #include <stdlib.h>
 #include <stdio.h>
@@ -797,12 +800,33 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
                // Perform assignment operation
                if( Node->Assign.Operation != NODETYPE_NOP )
                {
-                       tSpiderValue    *varVal = Variable_GetValue(Block, Node->Assign.Dest);
-                       tSpiderValue    *value;
+                       tSpiderValue    *varVal, *value;
+
+                       varVal = Variable_GetValue(Block, Node->Assign.Dest);
+                       if(varVal == ERRPTR)    return ERRPTR;
+                       #if 0
+                       #else
+                       if(varVal && varVal->ReferenceCount == 2) {
+                               Object_Dereference(varVal);
+//                             printf("pre: (%s) varVal->ReferenceCount = %i\n",
+//                                     Node->Assign.Dest->Variable.Name,
+//                                     varVal->ReferenceCount);
+                       }
+                       #endif
                        value = AST_ExecuteNode_BinOp(Block, Node, Node->Assign.Operation, varVal, ret);
                        if(value == ERRPTR)     return ERRPTR;
+
                        if(ret) Object_Dereference(ret);
+                       #if 0
                        if(varVal)      Object_Dereference(varVal);
+                       #else
+                       if(varVal && varVal->ReferenceCount == 1) {
+                               Object_Reference(varVal);
+//                             printf("post: varVal->ReferenceCount = %i\n", varVal->ReferenceCount);
+                               break;  // If varVal was non-null, it has been updated by _BinOp
+                       }
+                       #endif
+                       // Else, it was NULL, so has to be assigned
                        ret = value;
                }
                
@@ -1386,12 +1410,17 @@ tSpiderValue *AST_ExecuteNode_UniOp(tAST_BlockState *Block, tAST_Node *Node, int
        {
        // Integer Operations
        case SS_DATATYPE_INTEGER:
+               if( Value->ReferenceCount == 1 )
+                       Object_Reference(ret = Value);
+               else
+                       ret = SpiderScript_CreateInteger(0);
                switch(Operation)
                {
-               case NODETYPE_NEGATE:   ret = SpiderScript_CreateInteger( -Value->Integer );    break;
-               case NODETYPE_BWNOT:    ret = SpiderScript_CreateInteger( ~Value->Integer );    break;
+               case NODETYPE_NEGATE:   ret->Integer = -Value->Integer; break;
+               case NODETYPE_BWNOT:    ret->Integer = ~Value->Integer; break;
                default:
                        AST_RuntimeError(Node, "SpiderScript internal error: Exec,UniOP,Integer unknown op %i", Operation);
+                       Object_Dereference(ret);
                        ret = ERRPTR;
                        break;
                }
@@ -1487,6 +1516,11 @@ tSpiderValue *AST_ExecuteNode_BinOp(tAST_BlockState *Block, tAST_Node *Node, int
                case NODETYPE_ADD:      // Concatenate
                        ret = Object_StringConcat(Left, Right);
                        break;
+               // TODO: Support python style 'i = %i' % i ?
+               // Might do it via a function call
+//             case NODETYPE_MODULUS:
+//                     break;
+
                default:
                        AST_RuntimeError(Node, "SpiderScript internal error: Exec,BinOP,String unknown op %i", Operation);
                        ret = ERRPTR;
@@ -1495,23 +1529,28 @@ tSpiderValue *AST_ExecuteNode_BinOp(tAST_BlockState *Block, tAST_Node *Node, int
                break;
        // Integer Operations
        case SS_DATATYPE_INTEGER:
+               if( Left->ReferenceCount == 1 )
+                       Object_Reference(ret = Left);
+               else
+                       ret = SpiderScript_CreateInteger(0);
                switch(Operation)
                {
-               case NODETYPE_ADD:      ret = SpiderScript_CreateInteger( Left->Integer + Right->Integer );     break;
-               case NODETYPE_SUBTRACT: ret = SpiderScript_CreateInteger( Left->Integer - Right->Integer );     break;
-               case NODETYPE_MULTIPLY: ret = SpiderScript_CreateInteger( Left->Integer * Right->Integer );     break;
-               case NODETYPE_DIVIDE:   ret = SpiderScript_CreateInteger( Left->Integer / Right->Integer );     break;
-               case NODETYPE_MODULO:   ret = SpiderScript_CreateInteger( Left->Integer % Right->Integer );     break;
-               case NODETYPE_BWAND:    ret = SpiderScript_CreateInteger( Left->Integer & Right->Integer );     break;
-               case NODETYPE_BWOR:     ret = SpiderScript_CreateInteger( Left->Integer | Right->Integer );     break;
-               case NODETYPE_BWXOR:    ret = SpiderScript_CreateInteger( Left->Integer ^ Right->Integer );     break;
-               case NODETYPE_BITSHIFTLEFT:     ret = SpiderScript_CreateInteger( Left->Integer << Right->Integer );    break;
-               case NODETYPE_BITSHIFTRIGHT:ret = SpiderScript_CreateInteger( Left->Integer >> Right->Integer );        break;
+               case NODETYPE_ADD:      ret->Integer = Left->Integer + Right->Integer;  break;
+               case NODETYPE_SUBTRACT: ret->Integer = Left->Integer - Right->Integer;  break;
+               case NODETYPE_MULTIPLY: ret->Integer = Left->Integer * Right->Integer;  break;
+               case NODETYPE_DIVIDE:   ret->Integer = Left->Integer / Right->Integer;  break;
+               case NODETYPE_MODULO:   ret->Integer = Left->Integer % Right->Integer;  break;
+               case NODETYPE_BWAND:    ret->Integer = Left->Integer & Right->Integer;  break;
+               case NODETYPE_BWOR:     ret->Integer = Left->Integer | Right->Integer;  break;
+               case NODETYPE_BWXOR:    ret->Integer = Left->Integer ^ Right->Integer;  break;
+               case NODETYPE_BITSHIFTLEFT: ret->Integer = Left->Integer << Right->Integer;     break;
+               case NODETYPE_BITSHIFTRIGHT:ret->Integer = Left->Integer >> Right->Integer;     break;
                case NODETYPE_BITROTATELEFT:
-                       ret = SpiderScript_CreateInteger( (Left->Integer << Right->Integer) | (Left->Integer >> (64-Right->Integer)) );
+                       ret->Integer = (Left->Integer << Right->Integer) | (Left->Integer >> (64-Right->Integer));
                        break;
                default:
                        AST_RuntimeError(Node, "SpiderScript internal error: Exec,BinOP,Integer unknown op %i", Operation);
+                       Object_Dereference(ret);
                        ret = ERRPTR;
                        break;
                }
@@ -1519,14 +1558,19 @@ tSpiderValue *AST_ExecuteNode_BinOp(tAST_BlockState *Block, tAST_Node *Node, int
        
        // Real Numbers
        case SS_DATATYPE_REAL:
+               if( Left->ReferenceCount == 1 )
+                       Object_Reference(ret = Left);
+               else
+                       ret = SpiderScript_CreateReal(0);
                switch(Operation)
                {
-               case NODETYPE_ADD:      ret = SpiderScript_CreateReal( Left->Real + Right->Real );      break;
-               case NODETYPE_SUBTRACT: ret = SpiderScript_CreateReal( Left->Real - Right->Real );      break;
-               case NODETYPE_MULTIPLY: ret = SpiderScript_CreateReal( Left->Real * Right->Real );      break;
-               case NODETYPE_DIVIDE:   ret = SpiderScript_CreateReal( Left->Real / Right->Real );      break;
+               case NODETYPE_ADD:      ret->Real = Left->Real + Right->Real;   break;
+               case NODETYPE_SUBTRACT: ret->Real = Left->Real - Right->Real;   break;
+               case NODETYPE_MULTIPLY: ret->Real = Left->Real * Right->Real;   break;
+               case NODETYPE_DIVIDE:   ret->Real = Left->Real / Right->Real;   break;
                default:
                        AST_RuntimeError(Node, "SpiderScript internal error: Exec,BinOP,Real unknown op %i", Operation);
+                       Object_Dereference(ret);
                        ret = ERRPTR;
                        break;
                }
index 35f582d..fd219bc 100644 (file)
@@ -5,7 +5,7 @@
 #define _ACESS_SYS_H_
 
 #include <stdint.h>
-#include <sys/types.h>
+#include "../sys/types.h"
 
 // === CONSTANTS ===
 #ifndef NULL
 # define SEEK_CUR      0
 # define SEEK_END      -1
 #endif
-#define CLONE_VM       0x10
 #define GETMSG_IGNORE  ((void*)-1)
 #define FILEFLAG_DIRECTORY     0x10
 #define FILEFLAG_SYMLINK       0x20
 
 // === TYPES ===
-struct s_sysACL {
-       union {
-               struct {
-                       unsigned        group: 1;
-                       unsigned        id:     31;
-               };
-               uint32_t        object;
-       };
-       union {
-               struct {
-                       unsigned        invert: 1;
-                       unsigned        perms:  31;
-               };
-               uint32_t        rawperms;
-       };
-};
-struct s_sysFInfo {
-       uint    uid, gid;
-       uint    flags;
-       uint64_t        size;
-       uint64_t        atime;
-       uint64_t        mtime;
-       uint64_t        ctime;
-        int    numacls;
-       struct s_sysACL acls[];
-};
-typedef struct s_sysFInfo      t_sysFInfo;
-typedef struct s_sysACL        t_sysACL;
 
 // === VARIABLES ===
 extern int     _errno;
index c7ff8fc..a7857ef 100644 (file)
@@ -3,7 +3,7 @@
 #ifndef _STDTYPES_H_
 #define _STDTYPES_H_
 
-typedef unsigned int   uint;
+//typedef unsigned int uint;
 typedef unsigned char  uint8_t;
 typedef unsigned short uint16_t;
 typedef unsigned long  uint32_t;
index 92e2791..a1ed85b 100644 (file)
@@ -29,6 +29,9 @@ typedef struct {
 
 #define FD_SETSIZE     128
 
+
+#define CLONE_VM       0x10
+
 /**
  * \brief fd_set for select()
  */
@@ -37,6 +40,35 @@ typedef struct
        uint16_t        flags[FD_SETSIZE/16];
 }      fd_set;
 
+struct s_sysACL {
+       union {
+               struct {
+                       unsigned        group: 1;
+                       unsigned        id:     31;
+               };
+               uint32_t        object;
+       };
+       union {
+               struct {
+                       unsigned        invert: 1;
+                       unsigned        perms:  31;
+               };
+               uint32_t        rawperms;
+       };
+};
+struct s_sysFInfo {
+       unsigned int    uid, gid;
+       unsigned int    flags;
+       uint64_t        size;
+       uint64_t        atime;
+       uint64_t        mtime;
+       uint64_t        ctime;
+        int    numacls;
+       struct s_sysACL acls[];
+};
+typedef struct s_sysFInfo      t_sysFInfo;
+typedef struct s_sysACL        t_sysACL;
+
 static inline void FD_ZERO(fd_set *fdsetp) {int i=FD_SETSIZE/16;while(i--)fdsetp->flags[i]=0; }
 static inline void FD_CLR(int fd, fd_set *fdsetp) { fdsetp->flags[fd/16]&=~(1<<(fd%16)); }
 static inline void FD_SET(int fd, fd_set *fdsetp) { fdsetp->flags[fd/16]|=1<<(fd%16); }
@@ -46,4 +78,6 @@ typedef uint32_t      pid_t;
 typedef uint32_t       tid_t;
 typedef  int64_t       time_t;
 
+typedef unsigned int   uint;
+
 #endif

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