From 02cbaac1233be9c5228973a787431fa5e0aa178e Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 22 Jan 2011 20:59:13 +0800 Subject: [PATCH] Lots of work on the AcessNative kernel - Fixed some bugs (and possibly introduced some) in the main kernel - Cleaned up a heap of other stuff in AcessNative/ld-acess - Fixed a bug in the TCP code that could cause a deadlock --- AcessNative/acesskernel_src/Makefile | 9 +- AcessNative/acesskernel_src/helpers.c | 4 +- AcessNative/acesskernel_src/include/arch.h | 2 +- AcessNative/acesskernel_src/include/heap.h | 2 + AcessNative/acesskernel_src/keyboard.c | 68 +++++ AcessNative/acesskernel_src/main.c | 40 ++- AcessNative/acesskernel_src/syscalls.c | 131 +++++++++ AcessNative/acesskernel_src/threads.c | 12 +- AcessNative/acesskernel_src/ui.h | 24 ++ AcessNative/acesskernel_src/ui_sdl.c | 191 +++++++++++++ AcessNative/acesskernel_src/video.c | 298 +++++++++++++++++++++ AcessNative/ld-acess_src/binary.c | 9 +- AcessNative/ld-acess_src/elf.c | 7 +- AcessNative/ld-acess_src/main.c | 4 + AcessNative/ld-acess_src/memory.c | 2 +- AcessNative/ld-acess_src/request.c | 68 ++++- AcessNative/ld-acess_src/syscalls.c | 76 ++++-- AcessNative/syscalls.h | 15 +- Kernel/arch/x86/lib.c | 10 + Kernel/drv/vterm.c | 26 +- Kernel/include/tpl_drv_keyboard.h | 2 + Kernel/include/tpl_drv_video.h | 1 + Modules/IPStack/tcp.c | 2 +- Usermode/Libraries/crt0.o_src/crt0.asm | 6 +- 24 files changed, 953 insertions(+), 56 deletions(-) create mode 100644 AcessNative/acesskernel_src/syscalls.c create mode 100644 AcessNative/acesskernel_src/ui.h create mode 100644 AcessNative/acesskernel_src/ui_sdl.c diff --git a/AcessNative/acesskernel_src/Makefile b/AcessNative/acesskernel_src/Makefile index 4ff36c95..71782a9a 100644 --- a/AcessNative/acesskernel_src/Makefile +++ b/AcessNative/acesskernel_src/Makefile @@ -7,19 +7,20 @@ endif KERNEL_SRC = ../../Kernel/ -KERNEL_OBJ := logging.o adt.o lib.o +KERNEL_OBJ := logging.o adt.o lib.o drvutil.o 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 KERNEL_OBJ += vfs/fs/root.o vfs/fs/devfs.o KERNEL_OBJ += drv/vterm.o drv/fifo.o drv/proc.o -OBJ := main.o helpers.o threads.o video.o keyboard.o mouse.o nativefs.o vfs_handle.o +OBJ := main.o helpers.o threads.o syscalls.o +OBJ += video.o keyboard.o mouse.o nativefs.o vfs_handle.o ui_sdl.o OBJ += $(addprefix $(KERNEL_SRC),$(KERNEL_OBJ)) OBJ := $(addsuffix .$(PLATFORM),$(OBJ)) CPPFLAGS += -I include/ -I $(KERNEL_SRC)include/ -CFLAGS += -Wall -LDFLAGS += -lSDL -lSDLmain +CFLAGS += -Wall -g +LDFLAGS += -lSDL -lSDLmain -g ifeq ($(PLATFORM),win) BIN := ../AcessKernel.exe diff --git a/AcessNative/acesskernel_src/helpers.c b/AcessNative/acesskernel_src/helpers.c index 2209b05f..ef5f1db1 100644 --- a/AcessNative/acesskernel_src/helpers.c +++ b/AcessNative/acesskernel_src/helpers.c @@ -53,9 +53,9 @@ void Debug_SetKTerminal(const char *Path) // Ignored, kernel debug goes to stdout } -void *Heap_Allocate(int Count, const char *File, int Line) +void *Heap_Allocate(const char *File, int Line, int ByteCount) { - return malloc(Count); + return malloc(ByteCount); } tPAddr MM_GetPhysAddr(tVAddr VAddr) diff --git a/AcessNative/acesskernel_src/include/arch.h b/AcessNative/acesskernel_src/include/arch.h index d67b6734..8f0eb796 100644 --- a/AcessNative/acesskernel_src/include/arch.h +++ b/AcessNative/acesskernel_src/include/arch.h @@ -6,7 +6,7 @@ #include #include #include - +#undef CLONE_VM #define _MODULE_NAME_ "NativeKernel" #define BITS (sizeof(intptr_t)*8) diff --git a/AcessNative/acesskernel_src/include/heap.h b/AcessNative/acesskernel_src/include/heap.h index 20525597..9315142e 100644 --- a/AcessNative/acesskernel_src/include/heap.h +++ b/AcessNative/acesskernel_src/include/heap.h @@ -4,5 +4,7 @@ #define _HEAP_H_ // NOP (stdlib.h defines the heap functions) +// Heap_Allocate is used in _strdup +extern void *Heap_Allocate(const char *File, int Line, int ByteCount); #endif diff --git a/AcessNative/acesskernel_src/keyboard.c b/AcessNative/acesskernel_src/keyboard.c index e69de29b..76894831 100644 --- a/AcessNative/acesskernel_src/keyboard.c +++ b/AcessNative/acesskernel_src/keyboard.c @@ -0,0 +1,68 @@ +/* + * Acess2 Native Kernel + * + * Keyboard Driver + */ +#include +#include +#include +#include +#include +#include "ui.h" + +// === PROTOTYPES === + int NativeKeyboard_Install(char **Arguments); + int NativeKeyboard_IOCtl(tVFS_Node *Node, int Id, void *Data); + +// === GLOBALS === +MODULE_DEFINE(0, 0x0100, NativeKeyboard, NativeKeyboard_Install, NULL, NULL); +tDevFS_Driver gKB_DevInfo = { + NULL, "NativeKeyboard", + { + .NumACLs = 0, + .Size = 0, + .IOCtl = NativeKeyboard_IOCtl + } +}; + +// === CODE === +/** + * \brief Install the keyboard driver + */ +int NativeKeyboard_Install(char **Arguments) +{ + DevFS_AddDevice( &gKB_DevInfo ); + return MODULE_ERR_OK; +} + +static const char * const csaIOCTL_NAMES[] = { + DRV_IOCTLNAMES, + DRV_KEYBAORD_IOCTLNAMES, + NULL +}; + +/** + * \fn int KB_IOCtl(tVFS_Node *Node, int Id, void *Data) + * \brief Calls an IOCtl Command + */ +int NativeKeyboard_IOCtl(tVFS_Node *Node, int Id, void *Data) +{ + switch(Id) + { + BASE_IOCTLS(DRV_TYPE_KEYBOARD, "NativeKeyboard", 0x10000, csaIOCTL_NAMES); + + // Sets the Keyboard Callback + case KB_IOCTL_SETCALLBACK: + // Sanity Check + if(Threads_GetUID() != 0) + return 0; + // Can only be set once + if(gUI_KeyboardCallback != NULL) return 0; + // Set Callback + gUI_KeyboardCallback = Data; + return 1; + + default: + return 0; + } +} diff --git a/AcessNative/acesskernel_src/main.c b/AcessNative/acesskernel_src/main.c index 09e09dc4..7de6bf95 100644 --- a/AcessNative/acesskernel_src/main.c +++ b/AcessNative/acesskernel_src/main.c @@ -6,10 +6,48 @@ */ #include #include -#include +// === IMPORTS === +extern int UI_Initialise(int Width, int Height); +extern int VFS_Init(void); +extern int Video_Install(char **Arguments); +extern int NativeKeyboard_Install(char **Arguments); +extern int VT_Install(char **Arguments); + +// === CODE === int main(int argc, char *argv[]) { + // Parse command line settings + + // Start UI subsystem + UI_Initialise(640, 480); + + // Initialise VFS + VFS_Init(); + // - Start IO Drivers + Video_Install(NULL); + NativeKeyboard_Install(NULL); + // - Start VTerm + { + char *args[] = { + "Video=NativeVideo", + "Input=NativeKeyboard", + NULL + }; + VT_Install(args); + } + + // Start syscall server + for( ;; ) + { + UI_Redraw(); + } + return 0; } +void AcessNative_Exit(void) +{ + // TODO: Close client applications too + exit(0); +} diff --git a/AcessNative/acesskernel_src/syscalls.c b/AcessNative/acesskernel_src/syscalls.c new file mode 100644 index 00000000..db790770 --- /dev/null +++ b/AcessNative/acesskernel_src/syscalls.c @@ -0,0 +1,131 @@ +/* + * Acess2 Native Kernel + * - Acess kernel emulation on another OS using SDL and UDP + * + * Syscall Server + */ +#include +#include "../syscalls.h" + +// === TYPES === +typedef int (*tSyscallHandler)(const char *Format, void *Args); + +// === MACROS === +#define SYSCALL3(_name, _call, _fmtstr, _t1, _t2, _t3) int _name(const char *fmt,void*args){\ + _t1 a1;_t2 a2;_t3 a3;\ + if(strcmp(fmt,_fmtstr)!=0)return 0;\ + a1 = *(_t1*)args;args+=sizeof(_t1);\ + a2 = *(_t2*)args;args+=sizeof(_t2);\ + a3 = *(_t3*)args;args+=sizeof(_t3);\ + return _call(a1,a2,a3);\ +} + +#define SYSCALL2(_name, _call, _fmtstr, _t1, _t2) int _name(const char *fmt,void*args){\ + _t1 a1;_t2 a2;\ + if(strcmp(fmt,_fmtstr)!=0)return 0;\ + a1 = *(_t1*)args;args+=sizeof(_t1);\ + a2 = *(_t2*)args;args+=sizeof(_t2);\ + return _call(a1,a2);\ +} + +#define SYSCALL1V(_name, _call, _fmtstr, _t1) int _name(const char *fmt, void*args){\ + _t1 a1;\ + if(strcmp(fmt,_fmtstr)!=0)return 0;\ + a1 = *(_t1*)args;args+=sizeof(_t1);\ + _call(a1);\ + return 0;\ +} + +// === CODE === +int Syscall_Null(const char *Format, void *Args) +{ + return 0; +} + +SYSCALL2(Syscall_Open, VFS_Open, "di", const char *, int); +SYSCALL1V(Syscall_Close, VFS_Close, "i", int); +SYSCALL3(Syscall_Read, VFS_Read, "iid", int, int, void *); +SYSCALL3(Syscall_Write, VFS_Write, "iid", int, int, const void *); + + +const tSyscallHandler caSyscalls[] = { + Syscall_Null, + Syscall_Open, + Syscall_Close, + Syscall_Read, + Syscall_Write +}; +const int ciNumSyscalls = sizeof(caSyscalls)/sizeof(caSyscalls[0]); +/** + * \brief Recieve a syscall structure from the server code + */ +tRequestHeader *SyscallRecieve(tRequestHeader *Request) +{ + char formatString[Request->NParams+1]; + char *inData = (char*)&Request->Params[Request->NParams+Request->NReturn]; + int argListLen = 0; + int i, retVal; + + if( Request->CallID > ciNumSyscalls ) { + return NULL; + } + + // Get size of argument list + for( i = 0; i < Request->NParams; i ++ ) + { + switch(Request->Params[i].Type) + { + case ARG_TYPE_VOID: + formatString[i] = '-'; + break; + case ARG_TYPE_INT32: + formatString[i] = 'i'; + argListLen += sizeof(Uint32); + break; + case ARG_TYPE_INT64: + formatString[i] = 'I'; + argListLen += sizeof(Uint64); + break; + case ARG_TYPE_DATA: + formatString[i] = 'd'; + argListLen += sizeof(void*); + break; + default: + return NULL; // ERROR! + } + } + + { + char argListData[argListLen]; + argListLen = 0; + // Build argument list + for( i = 0; i < Request->NParams; i ++ ) + { + switch(Request->Params[i].Type) + { + case ARG_TYPE_VOID: + break; + case ARG_TYPE_INT32: + *(Uint32*)&argListData[argListLen] = *(Uint32*)inData; + argListLen += sizeof(Uint32); + inData += sizeof(Uint32); + break; + case ARG_TYPE_INT64: + *(Uint64*)&argListData[argListLen] = *(Uint64*)inData; + argListLen += sizeof(Uint64); + inData += sizeof(Uint64); + break; + case ARG_TYPE_DATA: + case ARG_TYPE_STRING: + *(void**)&argListData[argListLen] = *(void**)inData; + argListLen += sizeof(void*); + inData += sizeof(void*); + break; + } + } + + retVal = caSyscalls[Request->CallID](formatString, argListData); + } + + return NULL; +} diff --git a/AcessNative/acesskernel_src/threads.c b/AcessNative/acesskernel_src/threads.c index 5f29f760..7b66624f 100644 --- a/AcessNative/acesskernel_src/threads.c +++ b/AcessNative/acesskernel_src/threads.c @@ -44,8 +44,12 @@ typedef struct sThread } tThread; // === GLOBALS === -tThread *gpThreads; -__thread tThread *gpCurrentThread; +tThread gThread_Zero = { + State: 1, + ThreadName: "ThreadZero" +}; +tThread *gpThreads = &gThread_Zero; +__thread tThread *gpCurrentThread = &gThread_Zero; // === CODE === tThread *Threads_GetThread(int TID) @@ -66,6 +70,10 @@ tPID Threads_GetPID() { return gpCurrentThread->PID; } Uint *Threads_GetCfgPtr(int Index) { + if( Index < 0 || Index >= NUM_CFG_ENTRIES ) + return NULL; + if( !gpCurrentThread ) + return NULL; return &gpCurrentThread->Config[Index]; } diff --git a/AcessNative/acesskernel_src/ui.h b/AcessNative/acesskernel_src/ui.h new file mode 100644 index 00000000..24298b91 --- /dev/null +++ b/AcessNative/acesskernel_src/ui.h @@ -0,0 +1,24 @@ +/* + * Acess2 + * AcessNative Kernel + * + * ui.h - User Interface common header + */ +#ifndef _UI_H_ +#define _UI_H_ + +extern const int giUI_Width; +extern const int giUI_Height; +extern const int giUI_Pitch; +extern const Uint32 * const gUI_Framebuffer; + +extern void UI_SetWindowDims(int Width, int Height); +extern void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap); +extern void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H); +extern void UI_FillBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 Value); +extern void UI_Redraw(void); + +typedef void (*tUI_KeybardCallback)(Uint32 Key); +extern tUI_KeybardCallback gUI_KeyboardCallback; + +#endif diff --git a/AcessNative/acesskernel_src/ui_sdl.c b/AcessNative/acesskernel_src/ui_sdl.c new file mode 100644 index 00000000..97856f96 --- /dev/null +++ b/AcessNative/acesskernel_src/ui_sdl.c @@ -0,0 +1,191 @@ +/* + * Acess2 Native Kernel + * + * SDL User Interface + */ +#include +#define const +#include "ui.h" +#undef const +#include + +// === IMPORTS === +extern void AcessNative_Exit(void); + +// === PROTOTYPES === + int UI_Initialise(int MaxWidth, int MaxHeight); + int UI_MainThread(void *Unused); +void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap); +void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H); +void UI_FillBitmap(int X, int Y, int W, int H, Uint32 Value); +void UI_Redraw(void); + +// === GLOBALS === +SDL_Surface *gScreen; +SDL_Thread *gInputThread; + int giUI_Width = 0; + int giUI_Height = 0; + int giUI_Pitch = 0; +tUI_KeybardCallback gUI_KeyboardCallback; +Uint32 gUI_Keymap[2][SDLK_LAST]; // Upper/Lower case + +// === FUNCTIONS === +int UI_Initialise(int MaxWidth, int MaxHeight) +{ + // Changed when the video mode is set + giUI_Width = MaxWidth; + giUI_Height = MaxHeight; + + // Start main thread + gInputThread = SDL_CreateThread(UI_MainThread, NULL); + + return 0; +} + +Uint32 UI_GetAcessKeyFromSDL(SDLKey Sym, Uint16 Unicode) +{ + Uint8 *keystate = SDL_GetKeyState(NULL); + int shiftState = 0; + Uint32 ret = 0; + + if( keystate[SDLK_RSHIFT] || keystate[SDLK_LSHIFT] ) + shiftState = 1; + + // Fast return + if( gUI_Keymap[shiftState][Sym] ) + return gUI_Keymap[shiftState][Sym]; + + // How nice of you, a unicode value + if( Unicode ) + { + ret = Unicode; + } + // Ok, we need to do work :( + else + { + switch(Sym) + { + case SDLK_UP: ret = KEY_UP; break; + case SDLK_DOWN: ret = KEY_DOWN; break; + case SDLK_LEFT: ret = KEY_LEFT; break; + case SDLK_RIGHT:ret = KEY_RIGHT;break; + case SDLK_CAPSLOCK: ret = KEY_CAPSLOCK; break; + case SDLK_F1: ret = KEY_F1; break; + case SDLK_F2: ret = KEY_F2; break; + case SDLK_F3: ret = KEY_F3; break; + case SDLK_F4: ret = KEY_F4; break; + case SDLK_F5: ret = KEY_F5; break; + case SDLK_F6: ret = KEY_F6; break; + case SDLK_F7: ret = KEY_F7; break; + case SDLK_F8: ret = KEY_F8; break; + case SDLK_F9: ret = KEY_F9; break; + case SDLK_F10: ret = KEY_F10; break; + case SDLK_F11: ret = KEY_F11; break; + case SDLK_F12: ret = KEY_F12; break; + default: + printf("Unhandled key code %i\n", Sym); + break; + } + } + + gUI_Keymap[shiftState][Sym] = ret; + return ret; +} + +int UI_MainThread(void *Unused) +{ + SDL_Event event; + Uint32 acess_sym; + + SDL_Init(SDL_INIT_VIDEO); + + // Set up video + gScreen = SDL_SetVideoMode(giUI_Width, giUI_Height, 32, 0); + if( !gScreen ) { + fprintf(stderr, "Couldn't set %ix%i video mode: %s\n", giUI_Width, giUI_Height, SDL_GetError()); + SDL_Quit(); + exit(2); + } + SDL_WM_SetCaption("Acess2", "Acess2"); + + giUI_Width = gScreen->w; + giUI_Height = gScreen->h; + giUI_Pitch = gScreen->pitch; + + SDL_EnableUNICODE(1); + + for( ;; ) + { + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + case SDL_QUIT: + AcessNative_Exit(); + return 0; + + case SDL_KEYDOWN: + acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym, + event.key.keysym.unicode); + + if( gUI_KeyboardCallback ) + gUI_KeyboardCallback(acess_sym); + break; + + case SDL_KEYUP: + acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym, + event.key.keysym.unicode); + + //if( gUI_KeyboardCallback ) + // gUI_KeyboardCallback(0x80000000|acess_sym); + break; + + default: + break; + } + } + } +} + +void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap) +{ + SDL_Surface *tmp; + SDL_Rect dstRect; + + 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; + + SDL_BlitSurface(tmp, NULL, gScreen, &dstRect); + + SDL_FreeSurface(tmp); +} + +void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H) +{ + SDL_Rect srcRect; + SDL_Rect dstRect; + + srcRect.x = SrcX; srcRect.y = SrcY; + srcRect.w = W; srcRect.h = H; + dstRect.x = DstX; dstRect.y = DstY; + + SDL_BlitSurface(gScreen, &srcRect, gScreen, &dstRect); +} + +void UI_FillBitmap(int X, int Y, int W, int H, Uint32 Value) +{ + SDL_Rect dstRect; + + dstRect.x = X; dstRect.y = Y; + dstRect.w = W; dstRect.h = H; + + SDL_FillRect(gScreen, &dstRect, Value); +} + +void UI_Redraw(void) +{ + // No-Op, we're not using double buffering +} diff --git a/AcessNative/acesskernel_src/video.c b/AcessNative/acesskernel_src/video.c index e69de29b..4645b956 100644 --- a/AcessNative/acesskernel_src/video.c +++ b/AcessNative/acesskernel_src/video.c @@ -0,0 +1,298 @@ +/* + * Acess2 Native Kernel + * + * Video Driver + */ +#define VERSION ((0<<8)|10) +#include +#include +#include +#include +#include +#include "ui.h" + +// === PROTOTYPES === + int Video_Install(char **Arguments); +Uint64 Video_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); +Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); + int Video_IOCtl(tVFS_Node *Node, int ID, void *Data); +// --- 2D Acceleration Functions -- +void Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour); +void Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H); + +// === GLOBALS === +//MODULE_DEFINE(0, VERSION, NativeVideo, Video_Install, NULL, NULL); +tDevFS_Driver gVideo_DriverStruct = { + NULL, "NativeVideo", + { + .Read = Video_Read, + .Write = Video_Write, + .IOCtl = Video_IOCtl + } +}; + int giVideo_DriverID; + int giVideo_CurrentFormat; +// --- 2D Video Stream Handlers --- +tDrvUtil_Video_2DHandlers gVideo_2DFunctions = { + NULL, + Video_2D_Fill, + Video_2D_Blit +}; + +// === CODE === +int Video_Install(char **Arguments) +{ + // Install Device + giVideo_DriverID = DevFS_AddDevice( &gVideo_DriverStruct ); + if(giVideo_DriverID == -1) + return MODULE_ERR_MISC; + + return MODULE_ERR_OK; +} + +/** + * \brief Read from framebuffer (unimplemented) + */ +Uint64 Video_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +{ + return 0; +} + +/** + * \brief Write to the framebuffer + */ +Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +{ + int i; + ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); + + if(Buffer == NULL) { + LEAVE('i', 0); + return 0; + } + // Text Mode + switch( giVideo_CurrentFormat ) + { + case VIDEO_BUFFMT_TEXT: + { + tVT_Char *chars = Buffer; + // int pitch = giUI_Pitch; + int widthInChars = giUI_Width/giVT_CharWidth; + int heightInChars = giUI_Height/giVT_CharHeight; + int x, y; + Uint32 tmpBuf[giVT_CharHeight*giVT_CharWidth]; + + Length /= sizeof(tVT_Char); + Offset /= sizeof(tVT_Char); + + x = Offset % widthInChars; + y = Offset / widthInChars; + + // Sanity Check + if( Offset > (Uint64)(heightInChars*widthInChars) ) { + LEAVE('i', 0); + return 0; + } + if(y >= heightInChars) { + LEAVE('i', 0); + return 0; + } + + // Clip to screen size + if( (int)Offset + (int)Length > heightInChars*widthInChars ) { + Log_Debug("Video", "%i + %i > %i*%i (%i)", + (int)Offset, (int)Length, heightInChars, widthInChars, heightInChars*widthInChars); + Length = heightInChars*widthInChars - Offset; + Log_Notice("Video", "Clipping write size to %i characters", (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 + ); + + chars ++; + x ++; + if( x >= widthInChars ) { + x = 0; + y ++; + //dest += pitch*giVT_CharHeight; + } + } + Length *= sizeof(tVT_Char); + } + break; + + case VIDEO_BUFFMT_FRAMEBUFFER: + { + int startX, startY; + + if(giUI_Pitch*giUI_Height < Offset+Length) + { + Log_Warning("Video", "Video_Write - Framebuffer Overflow"); + LEAVE('i', 0); + return 0; + } + + LOG("buffer = %p", Buffer); + LOG("Updating Framebuffer (%p to %p)", destBuf, destBuf + (Uint)Length); + + startX = Offset % giUI_Width; + startY = Offset / giUI_Width; + + if( Length + startX < giUI_Width ) + { + // Single line + UI_BlitBitmap( + startX, startY, + Length, 1, + Buffer); + } + else + { + // First scanline (partial or full) + UI_BlitBitmap( + startX, startY, + giUI_Width - startX, 1, + Buffer); + + Length -= giUI_Width - startX; + Buffer += giUI_Width - startX; + + // Middle Scanlines + for( i = 0; i < Length / giUI_Height; i ++ ) + { + UI_BlitBitmap( + 0, startY + i, + giUI_Width, 1, + Buffer); + Buffer += giUI_Width; + } + + // Final scanline (partial) + if( Length % giUI_Height ) + { + UI_BlitBitmap( + 0, startY + i, + Length % giUI_Height, 1, + Buffer); + } + } + } + break; + + case VIDEO_BUFFMT_2DSTREAM: + Length = DrvUtil_Video_2DStream( + NULL, // Single framebuffer, so Ent is unused + Buffer, Length, &gVideo_2DFunctions, sizeof(gVideo_2DFunctions) + ); + break; + + default: + LEAVE('i', -1); + return -1; + } + + // Tell the UI to blit + UI_Redraw(); + + LEAVE('X', Length); + return Length; +} + +const char * const csaVIDEO_IOCTLS[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL}; +/** + * \brief Handle messages to the device + */ +int Video_IOCtl(tVFS_Node *Node, int ID, void *Data) +{ + int ret; + tVideo_IOCtl_Mode *mode = Data; + switch(ID) + { + BASE_IOCTLS(DRV_TYPE_VIDEO, "NativeVideo", VERSION, csaVIDEO_IOCTLS); + + // Video mode control + // - We cheat, and only have one mode + case VIDEO_IOCTL_GETSETMODE: + return 0; + case VIDEO_IOCTL_FINDMODE: + case VIDEO_IOCTL_MODEINFO: + mode->id = 0; + mode->width = giUI_Width; + mode->height = giUI_Height; + mode->bpp = 32; + mode->flags = 0; + return 0; + + // Buffer mode + case VIDEO_IOCTL_SETBUFFORMAT: + ret = giVideo_CurrentFormat; + if(Data) { + giVideo_CurrentFormat = *(int*)Data; + } + return ret; + + #if 0 + case VIDEO_IOCTL_SETCURSOR: // Set cursor position + #if !BLINKING_CURSOR + if(giVesaCursorX > 0) + Vesa_FlipCursor(Node); + #endif + giVesaCursorX = ((tVideo_IOCtl_Pos*)Data)->x; + giVesaCursorY = ((tVideo_IOCtl_Pos*)Data)->y; + //Log_Debug("VESA", "Cursor position (%i,%i)", giVesaCursorX, giVesaCursorY); + if( + giVesaCursorX < 0 || giVesaCursorY < 0 + || giVesaCursorX >= gpVesaCurMode->width/giVT_CharWidth + || giVesaCursorY >= gpVesaCurMode->height/giVT_CharHeight) + { + #if BLINKING_CURSOR + if(giVesaCursorTimer != -1) { + Time_RemoveTimer(giVesaCursorTimer); + giVesaCursorTimer = -1; + } + #endif + giVesaCursorX = -1; + giVesaCursorY = -1; + } + else { + #if BLINKING_CURSOR + // Log_Debug("VESA", "Updating timer %i?", giVesaCursorTimer); + if(giVesaCursorTimer == -1) + giVesaCursorTimer = Time_CreateTimer(VESA_CURSOR_PERIOD, Vesa_FlipCursor, Node); + #else + Vesa_FlipCursor(Node); + #endif + } + //Log_Debug("VESA", "Cursor position (%i,%i) Timer %i", giVesaCursorX, giVesaCursorY, giVesaCursorTimer); + return 0; + #endif + + case VIDEO_IOCTL_REQLFB: // Request Linear Framebuffer + return 0; + } + return 0; +} + +// --- 2D Acceleration Functions -- +void Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour) +{ + UI_FillBitmap(X, Y, W, H, Colour); +} + +void Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H) +{ + UI_BlitFramebuffer(DstX, DstY, SrcX, SrcY, W, H); +} diff --git a/AcessNative/ld-acess_src/binary.c b/AcessNative/ld-acess_src/binary.c index b8f6e71b..0ce9fac9 100644 --- a/AcessNative/ld-acess_src/binary.c +++ b/AcessNative/ld-acess_src/binary.c @@ -147,7 +147,6 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint) fread(&dword, 1, 4, fp); fseek(fp, 0, SEEK_SET); - printf("dword = %08x\n", dword); if( memcmp(&dword, "\x7F""ELF", 4) == 0 ) { fmt = &gElf_FormatDef; @@ -211,8 +210,8 @@ int Binary_GetSymbol(const char *SymbolName, uintptr_t *Value) int i; tBinary *bin; - printf("Binary_GetSymbol: (SymbolName='%s', Value=%p)\n", - SymbolName, Value); + //printf("Binary_GetSymbol: (SymbolName='%s', Value=%p)\n", + // SymbolName, Value); // Search builtins // - Placed first to override smartarses that define their own versions @@ -229,12 +228,12 @@ int Binary_GetSymbol(const char *SymbolName, uintptr_t *Value) for(bin = gLoadedBinaries; bin; bin = bin->Next) { if( !bin->Ready ) continue; - printf(" Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path); + //printf(" Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path); if( bin->Format->GetSymbol(bin->Base, (char*)SymbolName, Value) ) return 1; } - printf("Binary_GetSymbol: RETURN 0, not found\n"); + //printf("Binary_GetSymbol: RETURN 0, not found\n"); return 0; } diff --git a/AcessNative/ld-acess_src/elf.c b/AcessNative/ld-acess_src/elf.c index 3ab5a504..a79b591f 100644 --- a/AcessNative/ld-acess_src/elf.c +++ b/AcessNative/ld-acess_src/elf.c @@ -42,7 +42,7 @@ void *Elf_Load(FILE *FP) Elf32_Phdr *phtab; int i, j; int iPageCount; - uint32_t max, base = -1; + uint32_t max, base; uint32_t addr; uint32_t baseDiff = 0; @@ -100,6 +100,8 @@ void *Elf_Load(FILE *FP) //ret->Interpreter = NULL; // Prescan for base and size + max = 0; + base = 0xFFFFFFFF; for( i = 0; i < hdr.phentcount; i ++) { if( phtab[i].Type != PT_LOAD ) @@ -157,6 +159,9 @@ void *Elf_Load(FILE *FP) addr = phtab[i].VAddr + baseDiff; if( AllocateMemory( addr, phtab[i].MemSize ) ) { + fprintf(stderr, "Elf_Load: Unable to map memory at %x (0x%x bytes)\n", + addr, phtab[i].MemSize); + free( phtab ); return NULL; } diff --git a/AcessNative/ld-acess_src/main.c b/AcessNative/ld-acess_src/main.c index e310a84a..b2a8660e 100644 --- a/AcessNative/ld-acess_src/main.c +++ b/AcessNative/ld-acess_src/main.c @@ -37,6 +37,10 @@ int main(int argc, char *argv[], char **envp) printf("base = %p\n", base); if( !base ) return 127; + printf("==============================\n"); + for(i = 0; i < appArgc; i ++) + printf("\"%s\" ", appArgv[i]); + printf("\n"); __asm__ __volatile__ ( "push %0;\n\t" "push %1;\n\t" diff --git a/AcessNative/ld-acess_src/memory.c b/AcessNative/ld-acess_src/memory.c index 627f9024..072d3266 100644 --- a/AcessNative/ld-acess_src/memory.c +++ b/AcessNative/ld-acess_src/memory.c @@ -42,7 +42,7 @@ uintptr_t FindFreeRange(size_t ByteCount, int MaxBits) #else uintptr_t base, ofs, size; uintptr_t end = -1; - const int PAGE_SIZE = 0x1000; + static const int PAGE_SIZE = 0x1000; size = (ByteCount + PAGE_SIZE - 1) / PAGE_SIZE; size *= PAGE_SIZE; diff --git a/AcessNative/ld-acess_src/request.c b/AcessNative/ld-acess_src/request.c index f9526b3a..df6e5c55 100644 --- a/AcessNative/ld-acess_src/request.c +++ b/AcessNative/ld-acess_src/request.c @@ -43,8 +43,10 @@ int _InitSyscalls() } #endif + // Open TCP Connection + gSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Open UDP Connection - gSocket = socket(AF_INET, SOCK_DGRAM, 0); + //gSocket = socket(AF_INET, SOCK_DGRAM, 0); if (gSocket == INVALID_SOCKET) { fprintf(stderr, "Could not create socket.\n"); @@ -66,6 +68,20 @@ int _InitSyscalls() client.sin_port = htons(0); client.sin_addr.s_addr = htonl(0x7F00001); + if( connect(gSocket, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0 ) + { + fprintf(stderr, "Cannot connect to server (localhost:%i)\n", SERVER_PORT); + perror("_InitSyscalls"); + #if __WIN32__ + closesocket(gSocket); + WSACleanup(); + #else + close(gSocket); + #endif + exit(0); + } + + #if 0 // Bind if( bind(gSocket, (struct sockaddr *)&client, sizeof(struct sockaddr_in)) == -1 ) { @@ -78,6 +94,8 @@ int _InitSyscalls() #endif exit(0); } + #endif + return 0; } @@ -89,6 +107,11 @@ int SendRequest(int RequestID, int NumOutput, tOutValue **Output, int NumInput, int requestLen; int i; + if( gSocket == INVALID_SOCKET ) + { + _InitSyscalls(); + } + // See ../syscalls.h for details of request format requestLen = sizeof(tRequestHeader) + (NumOutput + NumInput) * sizeof(tRequestValue); @@ -115,13 +138,17 @@ int SendRequest(int RequestID, int NumOutput, tOutValue **Output, int NumInput, case 'i': value->Type = ARG_TYPE_INT32; break; case 'I': value->Type = ARG_TYPE_INT64; break; case 'd': value->Type = ARG_TYPE_DATA; break; + case 's': value->Type = ARG_TYPE_DATA; break; default: + fprintf(stderr, __FILE__" SendRequest: Unknown output type '%c'\n", + Output[i]->Type); return -1; } value->Length = Output[i]->Length; memcpy(data, Output[i]->Data, Output[i]->Length); + value ++; data += Output[i]->Length; } @@ -134,18 +161,53 @@ int SendRequest(int RequestID, int NumOutput, tOutValue **Output, int NumInput, case 'I': value->Type = ARG_TYPE_INT64; break; case 'd': value->Type = ARG_TYPE_DATA; break; default: + fprintf(stderr, " SendRequest: Unknown input type '%c'\n", + Input[i]->Type); return -1; } value->Length = Input[i]->Length; + value ++; + } + #if 0 + printf("value = %p\n", value); + { + for(i=0;iNParams != NumInput ) { + fprintf(stderr, "SendRequest: Unexpected number of values retured (%i, exp %i)\n", + request->NParams, NumInput + ); + free( request ); + return -1; + } + + // Free memory + free( request ); return 0; } diff --git a/AcessNative/ld-acess_src/syscalls.c b/AcessNative/ld-acess_src/syscalls.c index ec4af017..9bdde9b2 100644 --- a/AcessNative/ld-acess_src/syscalls.c +++ b/AcessNative/ld-acess_src/syscalls.c @@ -8,6 +8,7 @@ #include #include #include "request.h" +#include "../syscalls.h" // === Types === @@ -152,25 +153,29 @@ const char *ReadEntry(tOutValue **OutDest, tInValue **InDest, * ?d: Bi-directional buffer (Preceded by valid size), buffer contents * are returned */ -int _Syscall(const char *ArgTypes, ...) +void _Syscall(int SyscallID, const char *ArgTypes, ...) { va_list args; - int outCount = 0; - int inCount = 0; + int outCount; + int inCount; const char *str; - tOutValue **output; tInValue **input; // Get data size va_start(args, ArgTypes); str = ArgTypes; + outCount = 0; + inCount = 0; while(*str) { int dir; str = ReadEntry(NULL, NULL, &dir, str, args); - if( !str ) break; + if( !str ) { + fprintf(stderr, "syscalls.c: ReadEntry failed (SyscallID = %i)\n", SyscallID); + exit(127); + } // Out! if( dir & 1 ) outCount ++; @@ -184,13 +189,12 @@ int _Syscall(const char *ArgTypes, ...) output = malloc( outCount*sizeof(tOutValue*) ); input = malloc( inCount*sizeof(tInValue*) ); - // - re-zero so they can be used as indicies - outCount = 0; - inCount = 0; - // Fill `output` and `input` va_start(args, ArgTypes); str = ArgTypes; + // - re-zero so they can be used as indicies + outCount = 0; + inCount = 0; while(*str) { tOutValue *outParam; @@ -208,66 +212,90 @@ int _Syscall(const char *ArgTypes, ...) va_end(args); // Send syscall request - + if( SendRequest(SyscallID, outCount, output, inCount, input) ) { + fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID); + exit(127); + } // Clean up while(outCount--) free(output[outCount]); free(output); while(inCount--) free(input[inCount]); free(input); - - return 0; } // --- VFS Calls int open(const char *Path, int Flags) { - return _Syscall(">s >i", Path, Flags); + int ret = 0; + _Syscall(SYS_OPEN, "s >i", &ret, Path, Flags); + return ret; } void close(int FD) { - _Syscall(">i", FD); + _Syscall(SYS_CLOSE, ">i", FD); } size_t read(int FD, size_t Bytes, void *Dest) { - return _Syscall(">i >i i >i i >i >d", FD, Bytes, Bytes, Src); + int ret = 0; + _Syscall(SYS_WRITE, "i >i >d", &ret, FD, Bytes, Bytes, Src); + return ret; } int seek(int FD, int64_t Ofs, int Dir) { - return _Syscall(">i >I >i", FD, Ofs, Dir); + int ret = 0; + _Syscall(SYS_SEEK, "i >I >i", &ret, FD, Ofs, Dir); + return ret; } uint64_t tell(int FD) { uint64_t ret; - _Syscall("i", &ret, FD); + _Syscall(SYS_TELL, "i", &ret, FD); return ret; } int ioctl(int fd, int id, void *data) { + int ret = 0; // NOTE: 1024 byte size is a hack - return _Syscall(">i >i ?d", fd, id, 1024, data); + _Syscall(SYS_IOCTL, "i >i ?d", &ret, fd, id, 1024, data); + return ret; } int finfo(int fd, t_sysFInfo *info, int maxacls) { - return _Syscall(">i i", fd, maxacls*sizeof(t_sysFInfo), info, maxacls); + int ret = 0; + _Syscall(SYS_FINFO, "i i", + &ret, fd, + sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info, + maxacls); + return ret; } int readdir(int fd, char *dest) { - return _Syscall(">i i i >s >i", fd, name, flags); + int ret = 0; + _Syscall(SYS_OPENCHILD, "i >s >i", &ret, fd, name, flags); + return ret; } int _SysGetACL(int fd, t_sysACL *dest) { - return _Syscall(">i i s >s >s >s", Device, Directory, Type, Options); + int ret = 0; + _Syscall(SYS_MOUNT, "s >s >s >s", &ret, Device, Directory, Type, Options); + return ret; } diff --git a/AcessNative/syscalls.h b/AcessNative/syscalls.h index e298c94d..5081a53d 100644 --- a/AcessNative/syscalls.h +++ b/AcessNative/syscalls.h @@ -29,13 +29,26 @@ typedef struct sRequestHeader { enum eSyscalls { SYS_NULL, - SYS_OPEN + SYS_OPEN, + SYS_CLOSE, + SYS_READ, + SYS_WRITE, + SYS_SEEK, + SYS_TELL, + SYS_IOCTL, + SYS_FINFO, + SYS_READDIR, + SYS_OPENCHILD, + SYS_GETACL, + SYS_MOUNT, + N_SYSCALLS }; enum eArgumentTypes { ARG_TYPE_VOID, ARG_TYPE_INT32, ARG_TYPE_INT64, + ARG_TYPE_STRING, ARG_TYPE_DATA }; diff --git a/Kernel/arch/x86/lib.c b/Kernel/arch/x86/lib.c index 86117ccb..2160805c 100644 --- a/Kernel/arch/x86/lib.c +++ b/Kernel/arch/x86/lib.c @@ -5,6 +5,8 @@ #include #include +#define TRACE_LOCKS 1 + extern int GetCPUNum(void); // === CODE === @@ -103,6 +105,10 @@ void SHORTLOCK(struct sShortSpinlock *Lock) __ASM__("cli"); Lock->IF = IF; #endif + + #if TRACE_LOCKS + Log_Log("LOCK", "%p locked by %p\n", Lock, __builtin_return_address(0)); + #endif } /** * \brief Release a short lock @@ -110,6 +116,10 @@ void SHORTLOCK(struct sShortSpinlock *Lock) */ void SHORTREL(struct sShortSpinlock *Lock) { + #if TRACE_LOCKS + Log_Log("LOCK", "%p released by %p\n", Lock, __builtin_return_address(0)); + #endif + #if STACKED_LOCKS if( Lock->Depth ) { Lock->Depth --; diff --git a/Kernel/drv/vterm.c b/Kernel/drv/vterm.c index 252f2924..52c3a944 100644 --- a/Kernel/drv/vterm.c +++ b/Kernel/drv/vterm.c @@ -140,13 +140,21 @@ int VT_Install(char **Arguments) // Scan Arguments if(Arguments) { - char **args = Arguments; - char *arg, *opt, *val; - for( ; (arg = *args); args++ ) + char **args; + const char *arg; + for(args = Arguments; (arg = *args); args++ ) { + char data[strlen(arg)+1]; + char *opt = data; + char *val; + + val = strchr(arg, '='); + strcpy(data, arg); + if( val ) { + data[ val - arg ] = '\0'; + val ++; + } Log_Debug("VTerm", "Argument '%s'", arg); - opt = arg; - val = arg + strpos(arg, '='); *val++ = '\0'; if( strcmp(opt, "Video") == 0 ) { gsVT_OutputDevice = val; @@ -197,6 +205,7 @@ int VT_Install(char **Arguments) gVT_Terminals[i].CurColour = DEFAULT_COLOUR; gVT_Terminals[i].WritePos = 0; gVT_Terminals[i].ViewPos = 0; + gVT_Terminals[i].ReadingThread = -1; // Initialise VT_int_ChangeMode( &gVT_Terminals[i], @@ -233,7 +242,7 @@ int VT_Install(char **Arguments) void VT_InitOutput() { giVT_OutputDevHandle = VFS_Open(gsVT_OutputDevice, VFS_OPENFLAG_WRITE); - if(giVT_InputDevHandle == -1) { + if(giVT_OutputDevHandle == -1) { Log_Warning("VTerm", "Oh F**k, I can't open the video device '%s'", gsVT_OutputDevice); return ; } @@ -249,7 +258,10 @@ void VT_InitOutput() void VT_InitInput() { giVT_InputDevHandle = VFS_Open(gsVT_InputDevice, VFS_OPENFLAG_READ); - if(giVT_InputDevHandle == -1) return ; + if(giVT_InputDevHandle == -1) { + Log_Warning("VTerm", "Can't open the input device '%s'", gsVT_InputDevice); + return ; + } VFS_IOCtl(giVT_InputDevHandle, KB_IOCTL_SETCALLBACK, VT_KBCallBack); } diff --git a/Kernel/include/tpl_drv_keyboard.h b/Kernel/include/tpl_drv_keyboard.h index 8f4c1585..c93c147e 100644 --- a/Kernel/include/tpl_drv_keyboard.h +++ b/Kernel/include/tpl_drv_keyboard.h @@ -57,6 +57,8 @@ enum eTplKeyboard_IOCtl { KB_IOCTL_SETCALLBACK }; +#define DRV_KEYBAORD_IOCTLNAMES "getset_repeat_rate", "getset_repeat_delay", "set_callback" + /** * \brief Callback type for KB_IOCTL_SETCALLBACK * \param Key Unicode character code for the pressed key (with bit 31 diff --git a/Kernel/include/tpl_drv_video.h b/Kernel/include/tpl_drv_video.h index 1c00c5ed..bf67e598 100644 --- a/Kernel/include/tpl_drv_video.h +++ b/Kernel/include/tpl_drv_video.h @@ -102,6 +102,7 @@ enum eTplVideo_IOCtl { */ VIDEO_IOCTL_REQLFB }; +#define DRV_VIDEO_IOCTLNAMES "getset_mode", "find+mode", "mode_info", "set_buf_format", "set_cursor", "request_framebuffer" /** * \brief Mode Structure used in IOCtl Calls diff --git a/Modules/IPStack/tcp.c b/Modules/IPStack/tcp.c index 37415036..e42e940c 100644 --- a/Modules/IPStack/tcp.c +++ b/Modules/IPStack/tcp.c @@ -231,7 +231,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe srv->ConnectionsTail = conn; if(!srv->NewConnections) srv->NewConnections = conn; - SHORTLOCK(&srv->lConnections); + SHORTREL(&srv->lConnections); // Send the SYN ACK hdr->Flags |= TCP_FLAG_ACK; diff --git a/Usermode/Libraries/crt0.o_src/crt0.asm b/Usermode/Libraries/crt0.o_src/crt0.asm index 07db9de2..b923d184 100644 --- a/Usermode/Libraries/crt0.o_src/crt0.asm +++ b/Usermode/Libraries/crt0.o_src/crt0.asm @@ -10,10 +10,10 @@ [global _start] [global start] [extern main] +[extern _exit] _start: start: call main - mov eax, ebx ; Set Argument 1 to Return Value - xor eax, eax ; Set EAX to SYS_EXIT (0) - int 0xAC + push eax + call _exit jmp $ ; This should never be reached -- 2.20.1