From: John Hodge Date: Thu, 25 Feb 2010 11:44:14 +0000 (+0800) Subject: Working on UDP, removed debug from some code, fixed ARP setting hwtype to 0x100 ... X-Git-Tag: rel0.06~297 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=b3fa9a08edcbc459bd8e9df73186e292470ebfc3;p=tpg%2Facess2.git Working on UDP, removed debug from some code, fixed ARP setting hwtype to 0x100 (should be 1) - Other Misc changes --- diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index da45617b..e082886e 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 1438 +BUILD_NUM = 1447 diff --git a/Kernel/arch/x86/irq.c b/Kernel/arch/x86/irq.c index c9fa7265..9e0647f2 100644 --- a/Kernel/arch/x86/irq.c +++ b/Kernel/arch/x86/irq.c @@ -21,18 +21,18 @@ tIRQ_Callback gIRQ_Handlers[16][MAX_CALLBACKS_PER_IRQ]; void IRQ_Handler(tRegs *Regs) { int i; - + Regs->int_num -= 0xF0; // Adjust - + //Log("IRQ_Handler: (Regs={int_num:%i})", Regs->int_num); - + for( i = 0; i < MAX_CALLBACKS_PER_IRQ; i++ ) { //Log(" IRQ_Handler: Call %p", gIRQ_Handlers[Regs->int_num][i]); if( gIRQ_Handlers[Regs->int_num][i] ) gIRQ_Handlers[Regs->int_num][i](Regs->int_num); } - + //Log(" IRQ_Handler: Resetting"); if(Regs->int_num >= 8) outb(0xA0, 0x20); // ACK IRQ (Secondary PIC) @@ -49,10 +49,12 @@ int IRQ_AddHandler( int Num, void (*Callback)(int) ) for( i = 0; i < MAX_CALLBACKS_PER_IRQ; i++ ) { if( gIRQ_Handlers[Num][i] == NULL ) { + Log("IRQ_AddHandler: Added IRQ%i Cb#%i %p", Num, i, Callback); gIRQ_Handlers[Num][i] = Callback; return 1; } } - + + Warning("IRQ_AddHandler - No free callbacks on IRQ%i", Num); return 0; } diff --git a/Kernel/debug.c b/Kernel/debug.c index 8404fc1d..857ab596 100644 --- a/Kernel/debug.c +++ b/Kernel/debug.c @@ -56,22 +56,22 @@ static void E9(char ch) { if(giDebug_KTerm != -1) VFS_Write(giDebug_KTerm, 1, &ch); - + #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, 0x03); // Set divisor to 3 (lo byte) 38400 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 + outb(SERIAL_PORT + 1, 0x00); // Disable all interrupts + outb(SERIAL_PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) + outb(SERIAL_PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 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 - + #if DEBUG_TO_E9 __asm__ __volatile__ ( "outb %%al, $0xe9" :: "a"(((Uint8)ch)) ); #endif @@ -90,7 +90,7 @@ void E9_Fmt(const char *format, va_list *args) char *p = NULL; int isLongLong = 0; Uint64 arg; - + while((c = *format++) != 0) { // Non control character @@ -98,15 +98,15 @@ void E9_Fmt(const char *format, va_list *args) E9(c); continue; } - + c = *format++; - + // Literal % if(c == '%') { E9('%'); continue; } - + // Pointer if(c == 'p') { Uint ptr = va_arg(*args, Uint); @@ -115,17 +115,17 @@ void E9_Fmt(const char *format, va_list *args) itoa(p, ptr, 16, BITS/4, '0'); goto printString; } - + // Get Argument arg = va_arg(*args, Uint); - + // Padding if(c == '0') { pad = '0'; c = *format++; } else pad = ' '; - + // Minimum length minSize = 1; if('1' <= c && c <= '9') @@ -138,7 +138,7 @@ void E9_Fmt(const char *format, va_list *args) c = *format++; } } - + // Long (default) isLongLong = 0; if(c == 'l') { @@ -151,7 +151,7 @@ void E9_Fmt(const char *format, va_list *args) isLongLong = 1; } } - + p = tmpBuf; switch (c) { case 'd': @@ -179,14 +179,14 @@ void E9_Fmt(const char *format, va_list *args) if(arg) E9_Str("True"); else E9_Str("False"); break; - + case 's': p = (char*)(Uint)arg; printString: if(!p) p = "(null)"; while(*p) E9(*p++); break; - + // Single Character / Array case 'c': if(minSize == 1) { @@ -197,7 +197,7 @@ void E9_Fmt(const char *format, va_list *args) if(!p) goto printString; while(minSize--) E9(*p++); break; - + default: E9(arg); break; } } @@ -218,11 +218,11 @@ void LogV(char *Fmt, va_list Args) void LogF(char *Fmt, ...) { va_list args; - + va_start(args, Fmt); - + E9_Fmt(Fmt, &args); - + va_end(args); } /** @@ -231,7 +231,7 @@ void LogF(char *Fmt, ...) void Log(char *Fmt, ...) { va_list args; - + E9_Str("Log: "); va_start(args, Fmt); E9_Fmt(Fmt, &args); @@ -255,9 +255,9 @@ void Panic(char *Fmt, ...) E9_Fmt(Fmt, &args); va_end(args); E9('\n'); - + Threads_Dump(); - + __asm__ __volatile__ ("xchg %bx, %bx"); __asm__ __volatile__ ("cli;\n\thlt"); for(;;) __asm__ __volatile__ ("hlt"); @@ -276,13 +276,13 @@ void Debug_Enter(char *FuncName, char *ArgTypes, ...) va_list args; int i = gDebug_Level ++; int pos; - + va_start(args, ArgTypes); - + while(i--) E9(' '); - + E9_Str(FuncName); E9_Str(": ("); - + while(*ArgTypes) { pos = strpos(ArgTypes, ' '); @@ -307,11 +307,11 @@ void Debug_Enter(char *FuncName, char *ArgTypes, ...) if(pos != -1) { E9(','); E9(' '); } - + if(pos == -1) break; ArgTypes = &ArgTypes[pos+1]; } - + va_end(args); E9(')'); E9('\n'); } @@ -320,14 +320,14 @@ void Debug_Log(char *FuncName, char *Fmt, ...) { va_list args; int i = gDebug_Level; - + va_start(args, Fmt); - + while(i--) E9(' '); - + E9_Str(FuncName); E9_Str(": "); E9_Fmt(Fmt, &args); - + va_end(args); E9('\n'); } @@ -336,24 +336,24 @@ void Debug_Leave(char *FuncName, char RetType, ...) { va_list args; int i = --gDebug_Level; - + va_start(args, RetType); - + if( i == -1 ) { gDebug_Level = 0; i = 0; } // Indenting while(i--) E9(' '); - + E9_Str(FuncName); E9_Str(": RETURN"); - + // No Return if(RetType == '-') { E9('\n'); return; } - + E9(' '); switch(RetType) { @@ -367,7 +367,7 @@ void Debug_Leave(char *FuncName, char RetType, ...) case 'X': E9_Fmt("0x%llx", &args); break; } E9('\n'); - + va_end(args); } @@ -377,7 +377,7 @@ void Debug_HexDump(char *Header, void *Data, Uint Length) Uint pos = 0; E9_Str(Header); LogF(" (Hexdump of %p)\n", Data); - + while(Length >= 16) { Log("%04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", @@ -389,7 +389,7 @@ void Debug_HexDump(char *Header, void *Data, Uint Length) cdat += 16; pos += 16; } - + LogF("Log: %04x: ", pos); while(Length) { diff --git a/Kernel/drv/kb.c b/Kernel/drv/kb.c index b5428b5b..a546153d 100644 --- a/Kernel/drv/kb.c +++ b/Kernel/drv/kb.c @@ -58,6 +58,7 @@ int KB_Install(char **Arguments) { IRQ_AddHandler(1, KB_IRQHandler); DevFS_AddDevice( &gKB_DevInfo ); + //Log("KB_Install: Installed"); return 1; } @@ -72,17 +73,19 @@ void KB_IRQHandler() // int keyNum; //if( inportb(0x64) & 0x20 ) return; - + scancode = inb(0x60); // Read from the keyboard's data buffer + Log("KB_IRQHandler: scancode = 0x%02x", scancode); + // Ignore ACKs if(scancode == 0xFA) { // Oh man! This is anachic (I'm leaving it here to represent the - // mess that acess once was + // mess that Acess once was) //kb_lastChar = KB_ACK; return; } - + // Layer +1 if(scancode == 0xE0) { giKB_KeyLayer = 1; @@ -93,7 +96,7 @@ void KB_IRQHandler() giKB_KeyLayer = 2; return; } - + #if KB_ALT_SCANCODES if(scancode == 0xF0) { @@ -107,32 +110,32 @@ void KB_IRQHandler() gbKB_KeyUp = 1; } #endif - + // Translate ch = gpKB_Map[giKB_KeyLayer][scancode]; //keyNum = giKB_KeyLayer * 256 + scancode; // Check for unknown key if(!ch && !gbKB_KeyUp) Warning("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; @@ -143,19 +146,19 @@ void KB_IRQHandler() // 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; @@ -169,7 +172,7 @@ void KB_IRQHandler() } } #endif - + // Is shift pressed // - Darn ugly hacks !(!x) means (bool)x if( !(!gbKB_ShiftState) ^ gbKB_CapsState) @@ -204,7 +207,7 @@ void KB_IRQHandler() break; } } - + if(gKB_Callback && ch != 0) gKB_Callback(ch); } @@ -215,12 +218,12 @@ void KB_IRQHandler() void KB_UpdateLEDs() { 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); } @@ -237,7 +240,7 @@ int KB_IOCtl(tVFS_Node *Node, int Id, void *Data) 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 @@ -247,7 +250,7 @@ int KB_IOCtl(tVFS_Node *Node, int Id, void *Data) // Set Callback gKB_Callback = Data; return 1; - + default: return 0; } diff --git a/Kernel/heap.c b/Kernel/heap.c index f42d59f8..61f7881e 100644 --- a/Kernel/heap.c +++ b/Kernel/heap.c @@ -30,7 +30,7 @@ void free(void *Ptr); void Heap_Dump(); // === GLOBALS === - int giHeapSpinlock; + int glHeap; void *gHeapStart; void *gHeapEnd; @@ -140,7 +140,7 @@ void *malloc(size_t Bytes) Bytes = (Bytes + sizeof(tHeapHead) + sizeof(tHeapFoot) + BLOCK_SIZE-1) & ~(BLOCK_SIZE-1); // Lock Heap - LOCK(&giHeapSpinlock); + LOCK(&glHeap); // Traverse Heap for( head = gHeapStart; @@ -154,6 +154,7 @@ void *malloc(size_t Bytes) Warning("Size of heap address %p is invalid not aligned (0x%x)", head, head->Size); Heap_Dump(); #endif + RELEASE(&glHeap); return NULL; } @@ -165,7 +166,7 @@ void *malloc(size_t Bytes) Warning("Magic of heap address %p is invalid (0x%x)", head, head->Magic); Heap_Dump(); #endif - RELEASE(&giHeapSpinlock); // Release spinlock + RELEASE(&glHeap); // Release spinlock return NULL; } @@ -175,7 +176,7 @@ void *malloc(size_t Bytes) // Perfect fit if(head->Size == Bytes) { head->Magic = MAGIC_USED; - RELEASE(&giHeapSpinlock); // Release spinlock + RELEASE(&glHeap); // Release spinlock #if DEBUG_TRACE LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0)); #endif @@ -202,12 +203,12 @@ void *malloc(size_t Bytes) best = Heap_Extend( Bytes ); // Check for errors if(!best) { - RELEASE(&giHeapSpinlock); // Release spinlock + RELEASE(&glHeap); // Release spinlock return NULL; } // Check size if(best->Size == Bytes) { - RELEASE(&giHeapSpinlock); // Release spinlock + RELEASE(&glHeap); // Release spinlock #if DEBUG_TRACE LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0)); #endif @@ -228,7 +229,7 @@ void *malloc(size_t Bytes) best->Size = Bytes; // Update size in old header best->Magic = MAGIC_USED; // Mark block as used - RELEASE(&giHeapSpinlock); // Release spinlock + RELEASE(&glHeap); // Release spinlock #if DEBUG_TRACE LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0)); #endif @@ -285,7 +286,7 @@ void free(void *Ptr) } // Lock - LOCK( &giHeapSpinlock ); + LOCK( &glHeap ); // Mark as free head->Magic = MAGIC_FREE; @@ -293,7 +294,7 @@ void free(void *Ptr) Heap_Merge( head ); // Release - RELEASE( &giHeapSpinlock ); + RELEASE( &glHeap ); } /** diff --git a/Kernel/include/tpl_drv_common.h b/Kernel/include/tpl_drv_common.h index 31edb9cf..f281c0ee 100644 --- a/Kernel/include/tpl_drv_common.h +++ b/Kernel/include/tpl_drv_common.h @@ -82,6 +82,19 @@ enum eTplDrv_IOCtl { //! These are the official lookup names of the core calls #define DRV_IOCTLNAMES "type", "ident", "version", "lookup" +#define BASE_IOCTLS(_type, _ident, _version, _ioctls) \ + case DRV_IOCTL_TYPE: LEAVE('i', (_type)); return (_type);\ + case DRV_IOCTL_IDENT: {\ + int tmp = ModUtil_SetIdent(Data, (_ident));\ + LEAVE('i', tmp); return tmp;\ + }\ + case DRV_IOCTL_VERSION: LEAVE('x', (_version)); return (_version);\ + case DRV_IOCTL_LOOKUP:{\ + int tmp = ModUtil_LookupString( (char**)(_ioctls), (char*)Data );\ + LEAVE('i', tmp);\ + return tmp;\ + } + /** * \enum eTplDrv_Type * \brief Driver Types returned by DRV_IOCTL_TYPE diff --git a/Modules/IPStack/arp.c b/Modules/IPStack/arp.c index 3f919399..2b246cd5 100644 --- a/Modules/IPStack/arp.c +++ b/Modules/IPStack/arp.c @@ -16,7 +16,7 @@ extern tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broad // === PROTOTYPES === int ARP_Initialise(); - int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address); +tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address); void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer); // === GLOBALS === @@ -64,6 +64,7 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address) { int lastID; int i; + struct sArpRequest4 req; ENTER("pInterface xAddress", Interface, Address); @@ -87,37 +88,12 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address) RELEASE( &glARP_Cache4 ); lastID = giARP_LastUpdateID; - ARP_int_Resolve4(Interface, Address); - for(;;) - { - while(lastID == giARP_LastUpdateID) Threads_Yield(); - lastID = giARP_LastUpdateID; - - LOCK( &glARP_Cache4 ); - for( i = 0; i < giARP_Cache4Space; i++ ) - { - if(gaARP_Cache4[i].IP.L != Address.L) continue; - - RELEASE( &glARP_Cache4 ); - return gaARP_Cache4[i].MAC; - } - RELEASE( &glARP_Cache4 ); - } -} - -/** - * \fn int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address) - * \brief Request the network to resolve an IPv4 Address - * \return Boolean Success - */ -int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address) -{ - struct sArpRequest4 req; + // Create request Log("[ARP4 ] Asking for address %i.%i.%i.%i", Address.B[0], Address.B[1], Address.B[2], Address.B[3] ); - req.HWType = htons(0x100); // Ethernet + req.HWType = htons(1); // Ethernet req.Type = htons(0x0800); req.HWSize = 6; req.SWSize = 4; @@ -127,9 +103,25 @@ int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address) req.DestMac = cMAC_BROADCAST; req.DestIP = Address; + // Send Request Link_SendPacket(Interface->Adapter, 0x0806, req.DestMac, sizeof(struct sArpRequest4), &req); - return 0; + // Wait for a reply + for(;;) + { + while(lastID == giARP_LastUpdateID) Threads_Yield(); + lastID = giARP_LastUpdateID; + + LOCK( &glARP_Cache4 ); + for( i = 0; i < giARP_Cache4Space; i++ ) + { + if(gaARP_Cache4[i].IP.L != Address.L) continue; + + RELEASE( &glARP_Cache4 ); + return gaARP_Cache4[i].MAC; + } + RELEASE( &glARP_Cache4 ); + } } /** diff --git a/Modules/IPStack/tcp.c b/Modules/IPStack/tcp.c index dd94b923..9225ffaf 100644 --- a/Modules/IPStack/tcp.c +++ b/Modules/IPStack/tcp.c @@ -12,6 +12,7 @@ // === PROTOTYPES === void TCP_Initialise(); 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); void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Header); Uint16 TCP_GetUnusedPort(); @@ -61,16 +62,16 @@ void TCP_Initialise() void TCP_StartConnection(tTCPConnection *Conn) { tTCPHeader hdr; - - hdr->SourcePort = Conn->LocalPort; - hdr->DestPort = Conn->RemotePort; + + hdr.SourcePort = Conn->LocalPort; + hdr.DestPort = Conn->RemotePort; Conn->NextSequenceSend = rand(); - hdr->SequenceNumber = Conn->NextSequenceSend; - hdr->DataOffset = (sizeof(tTCPHeader)+3)/4; - hdr->Flags = TCP_FLAG_SYN; - hdr->WindowSize = 0; // TODO - hdr->Checksum = 0; // TODO - hdr->UrgentPointer = 0; + hdr.SequenceNumber = Conn->NextSequenceSend; + hdr.DataOffset = (sizeof(tTCPHeader)+3)/4; + hdr.Flags = TCP_FLAG_SYN; + hdr.WindowSize = 0; // TODO + hdr.Checksum = 0; // TODO + hdr.UrgentPointer = 0; // SEND PACKET TCP_SendPacket( Conn, sizeof(tTCPHeader), &hdr ); return ; @@ -86,19 +87,19 @@ void TCP_SendPacket( tTCPConnection *Conn, size_t Length, tTCPHeader *Data ) { size_t buflen; Uint32 *buf; - switch( Conn->Interface.Type ) + switch( Conn->Interface->Type ) { - case 4: + case 4: // Append IPv4 Pseudo Header buflen = 4 + 4 + 4 + ((Length+1)&1); buf = malloc( buflen ); - buf[0] = Conn->Interface.IP4.Address.L; + buf[0] = Conn->Interface->IP4.Address.L; buf[1] = Conn->RemoteIP.v4.L; buf[2] = (htons(Length)<<16) | (6<<8) | 0; Data->Checksum = 0; - memcpy( &buf[3], Data, buflen ); + memcpy( &buf[3], Data, Length ); Data->Checksum = IPv4_Checksum( buf, buflen ); free(buf); - IPv4_SendPacket(Conn->Interface, Conn->RemoteIP.v4, IP4PROT_TCP, 0, sizeof(tTCPHeader), &hdr); + IPv4_SendPacket(Conn->Interface, Conn->RemoteIP.v4, IP4PROT_TCP, 0, buflen, buf); break; } } @@ -112,7 +113,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe tTCPHeader *hdr = Buffer; tTCPListener *srv; tTCPConnection *conn; - + Log("[TCP ] sizeof(tTCPHeader) = %i", sizeof(tTCPHeader)); Log("[TCP ] DestPort = %i", ntohs(hdr->DestPort)); Log("[TCP ] DestPort = %i", ntohs(hdr->DestPort)); @@ -132,7 +133,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe Log("[TCP ] WindowSize = %i", htons(hdr->WindowSize)); Log("[TCP ] Checksum = 0x%x", htons(hdr->Checksum)); Log("[TCP ] UrgentPointer = 0x%x", htons(hdr->UrgentPointer)); - + // Check Servers { for( srv = gTCP_Listeners; srv; srv = srv->Next ) @@ -143,53 +144,53 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe if(srv->Interface && srv->Interface != Interface) continue; // Check the destination port if(srv->Port != hdr->DestPort) continue; - + // Is this in an established connection? for( conn = srv->Connections; conn; conn = conn->Next ) { // Check that it is coming in on the same interface if(conn->Interface != Interface) continue; - + // Check Source Port if(conn->RemotePort != hdr->SourcePort) continue; - + // Check Source IP if(conn->Interface->Type == 6 && !IP6_EQU(conn->RemoteIP.v6, *(tIPv6*)Address)) continue; if(conn->Interface->Type == 4 && !IP4_EQU(conn->RemoteIP.v4, *(tIPv4*)Address)) continue; - + // We have a response! - TCP_INT_HandleConnectionPacket(conn, hdr) - + TCP_INT_HandleConnectionPacket(conn, hdr); + return; } - + // Open a new connection (well, check that it's a SYN) //TODO - + break; } } - - + + // Check Open Connections { for( conn = gTCP_OutbountCons; conn; conn = conn->Next ) { // Check that it is coming in on the same interface if(conn->Interface != Interface) continue; - + // Check Source Port if(conn->RemotePort != hdr->SourcePort) continue; - + // Check Source IP if(conn->Interface->Type == 6 && !IP6_EQU(conn->RemoteIP.v6, *(tIPv6*)Address)) continue; if(conn->Interface->Type == 4 && !IP4_EQU(conn->RemoteIP.v4, *(tIPv4*)Address)) continue; - - TCP_INT_HandleConnectionPacket(conn, hdr) + + TCP_INT_HandleConnectionPacket(conn, hdr); } } } @@ -199,7 +200,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe */ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Header) { - + } /** @@ -209,7 +210,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head Uint16 TCP_GetUnusedPort() { Uint16 ret; - + // Get Next outbound port ret = giTCP_NextOutPort++; while( gaTCP_PortBitmap[ret/32] & (1 << (ret%32)) ) @@ -220,10 +221,10 @@ Uint16 TCP_GetUnusedPort() ret = giTCP_NextOutPort = TCP_MIN_DYNPORT; } } - + // Mark the new port as used gaTCP_PortBitmap[ret/32] |= 1 << (ret%32); - + return ret; } @@ -236,10 +237,10 @@ int TCP_AllocatePort(Uint16 Port) // Check if the port has already been allocated if( gaTCP_PortBitmap[Port/32] & (1 << (Port%32)) ) return 0; - + // Allocate gaTCP_PortBitmap[Port/32] |= 1 << (Port%32); - + return 1; } @@ -252,10 +253,10 @@ int TCP_DeallocatePort(Uint16 Port) // Check if the port has already been allocated if( !(gaTCP_PortBitmap[Port/32] & (1 << (Port%32))) ) return 0; - + // Allocate gaTCP_PortBitmap[Port/32] &= ~(1 << (Port%32)); - + return 1; } @@ -263,7 +264,7 @@ int TCP_DeallocatePort(Uint16 Port) tVFS_Node *TCP_Server_Init(tInterface *Interface) { tTCPListener *srv = malloc( sizeof(tTCPListener) ); - + srv->Interface = Interface; srv->Port = 0; srv->NextID = 0; @@ -276,12 +277,12 @@ tVFS_Node *TCP_Server_Init(tInterface *Interface) srv->Node.FindDir = TCP_Server_FindDir; srv->Node.IOCtl = TCP_Server_IOCtl; srv->Node.Close = TCP_Server_Close; - + LOCK(&glTCP_Listeners); srv->Next = gTCP_Listeners; gTCP_Listeners = srv; RELEASE(&glTCP_Listeners); - + return &srv->Node; } @@ -296,14 +297,14 @@ char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos) tTCPListener *srv = Node->ImplPtr; tTCPConnection *conn; char *ret; - + while( srv->NewConnections == NULL ) Threads_Yield(); - + conn = srv->NewConnections; srv->NewConnections = conn->Next; - + ret = malloc(9); - itoa(ret, conn->ImplInt, 16, '0', 8); + itoa(ret, Node->ImplInt, 16, '0', 8); return ret; } @@ -320,27 +321,27 @@ tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, char *Name) int TCP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data) { tTCPListener *srv = Node->ImplPtr; - + switch(ID) { case 4: // Get/Set Port if(!Data) // Get Port return srv->Port; - + if(srv->Port) // Wait, you can't CHANGE the port return -1; - + if(!CheckMem(Data, sizeof(Uint16))) // Sanity check return -1; - + // Permissions check if(Threads_GetUID() != 0 && *(Uint16*)Data != 0 && *(Uint16*)Data < 1024) return -1; - + // TODO: Check if a port is in use - + // Set Port srv->Port = *(Uint16*)Data; if(srv->Port == 0) // Allocate a random port @@ -361,13 +362,13 @@ void TCP_Server_Close(tVFS_Node *Node) tVFS_Node *TCP_Client_Init(tInterface *Interface) { tTCPConnection *conn = malloc( sizeof(tTCPConnection) ); - + conn->State = TCP_ST_CLOSED; conn->Interface = Interface; conn->LocalPort = 0; conn->RemotePort = 0; memset( &conn->RemoteIP, 0, sizeof(conn->RemoteIP) ); - + conn->Node.ImplPtr = conn; conn->Node.NumACLs = 1; conn->Node.ACLs = &gVFS_ACL_EveryoneRW; @@ -375,12 +376,12 @@ tVFS_Node *TCP_Client_Init(tInterface *Interface) conn->Node.Write = TCP_Client_Write; conn->Node.IOCtl = TCP_Client_IOCtl; conn->Node.Close = TCP_Client_Close; - + LOCK(&glTCP_OutbountCons); conn->Next = gTCP_OutbountCons; gTCP_OutbountCons = conn; RELEASE(&glTCP_OutbountCons); - + return &conn->Node; } @@ -394,10 +395,13 @@ Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buf return 0; } +/** + * \brief Control a client socket + */ int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data) { tTCPConnection *conn = Node->ImplPtr; - + switch(ID) { case 4: // Get/Set local port @@ -407,20 +411,20 @@ int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data) return -1; if(!CheckMem(Data, sizeof(Uint16))) return -1; - + if(Threads_GetUID() != 0 && *(Uint16*)Data < 1024) return -1; - + conn->LocalPort = *(Uint16*)Data; return 0; - + case 5: // Get/Set remote port if(!Data) return conn->RemotePort; if(conn->State != TCP_ST_CLOSED) return -1; if(!CheckMem(Data, sizeof(Uint16))) return -1; conn->RemotePort = *(Uint16*)Data; return 0; - + case 6: // Set Remote IP if( conn->State != TCP_ST_CLOSED ) return -1; @@ -435,17 +439,17 @@ int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data) conn->RemoteIP.v6 = *(tIPv6*)Data; } return 0; - + case 7: // Connect if(conn->LocalPort == -1) conn->LocalPort = TCP_GetUnusedPort(); if(conn->RemotePort == -1) return 0; - + TCP_StartConnection(conn); return 1; } - + return 0; } diff --git a/Modules/IPStack/tcp.h b/Modules/IPStack/tcp.h index ed517db8..fd04f7b7 100644 --- a/Modules/IPStack/tcp.h +++ b/Modules/IPStack/tcp.h @@ -68,7 +68,7 @@ struct sTCPListener int NextID; //!< Name of the next connection tSpinlock lConnections; //!< Spinlock for connections tTCPConnection *Connections; //!< Connections (linked list) - volatile tTCPConnection *NewConnections; + tTCPConnection *volatile NewConnections; }; struct sTCPConnection diff --git a/Modules/IPStack/udp.c b/Modules/IPStack/udp.c index 194c62b2..f014c557 100644 --- a/Modules/IPStack/udp.c +++ b/Modules/IPStack/udp.c @@ -3,19 +3,38 @@ * - UDP Handling */ #include "ipstack.h" +#include #include "udp.h" +#define UDP_ALLOC_BASE 0xC000 + // === PROTOTYPES === void UDP_Initialise(); void UDP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer); -// --- Channel +// --- Listening Server +tVFS_Node *UDP_Server_Init(tInterface *Interface); +char *UDP_Server_ReadDir(tVFS_Node *Node, int ID); +tVFS_Node UDP_Server_FindDir(tVFS_Node *Node, char *Name); + int UDP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data); +void UDP_Server_Close(tVFS_Node *Node); +// --- Client Channels tVFS_Node *UDP_Channel_Init(tInterface *Interface); Uint64 UDP_Channel_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); Uint64 UDP_Channel_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); int UDP_Channel_IOCtl(tVFS_Node *Node, int ID, void *Data); void UDP_Channel_Close(tVFS_Node *Node); +// --- Helpers +Uint16 UDP_int_AllocatePort(); + int UDP_int_MarkPortAsUsed(Uint16 Port); +void UDP_int_FreePort(Uint16 Port); // === GLOBALS === +tSpinlock glUDP_Channels; +tUDPChannel *gpUDP_Channels; +tSpinlock glUDP_Ports; +Uint32 gUDP_Ports[0x10000/32]; +//tSocketFile gUDP_ServerFile = {NULL, "udps", UDP_Server_Init}; +tSocketFile gUDP_ClientFile = {NULL, "udpc", UDP_Channel_Init}; // === CODE === /** @@ -24,6 +43,7 @@ void UDP_Channel_Close(tVFS_Node *Node); */ void UDP_Initialise() { + IPStack_AddFile(&gUDP_ClientFile); IPv4_RegisterCallback(IP4PROT_UDP, UDP_GetPacket); } @@ -34,9 +54,318 @@ void UDP_Initialise() void UDP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer) { tUDPHeader *hdr = Buffer; + tUDPChannel *chan; + tUDPPacket *pack; + int len; Log("[UDP ] hdr->SourcePort = %i", ntohs(hdr->SourcePort)); Log("[UDP ] hdr->DestPort = %i", ntohs(hdr->DestPort)); Log("[UDP ] hdr->Length = %i", ntohs(hdr->Length)); Log("[UDP ] hdr->Checksum = 0x%x", ntohs(hdr->Checksum)); + + // Check registered connections + LOCK(&glUDP_Channels); + for(chan = gpUDP_Channels; + chan; + chan = chan->Next) + { + if(chan->Interface != Interface) continue; + if(chan->LocalPort != ntohs(hdr->DestPort)) continue; + if(chan->RemotePort != ntohs(hdr->SourcePort)) continue; + + if(Interface->Type == 4) { + if(IP4_EQU(chan->RemoteAddr.v4, *(tIPv4*)Address)) continue; + } + else if(Interface->Type == 6) { + if(IP6_EQU(chan->RemoteAddr.v6, *(tIPv6*)Address)) continue; + } + else { + Warning("[UDP ] Address type %i unknown", Interface->Type); + RELEASE(&glUDP_Channels); + return ; + } + + // Create the cached packet + len = ntohs(hdr->Length); + pack = malloc(sizeof(tUDPPacket) + len); + pack->Next = NULL; + pack->Length = len; + memcpy(pack->Data, hdr->Data, len); + + // Add the packet to the channel's queue + LOCK(&chan->lQueue); + if(chan->Queue) + chan->QueueEnd->Next = pack; + else + chan->QueueEnd = chan->Queue = pack; + RELEASE(&chan->lQueue); + RELEASE(&glUDP_Channels); + return ; + } + + // TODO: Server/Listener + + RELEASE(&glUDP_Channels); +} + +/** + * \brief Send a packet + * \param Channel Channel to send the packet from + * \param Data Packet data + * \param Length Length in bytes of packet data + */ +void UDP_SendPacket(tUDPChannel *Channel, void *Data, size_t Length) +{ + tUDPHeader *hdr; + + switch(Channel->Interface->Type) + { + case 4: + // Create the packet + hdr = malloc(sizeof(tUDPHeader)+Length); + hdr->SourcePort = htons( Channel->LocalPort ); + hdr->DestPort = htons( Channel->RemotePort ); + hdr->Length = htons( Length ); + hdr->Checksum = 0; // Checksum can be zero on IPv4 + memcpy(hdr->Data, Data, Length); + // Pass on the the IPv4 Layer + IPv4_SendPacket(Channel->Interface, Channel->RemoteAddr.v4, IP4PROT_UDP, 0, sizeof(tUDPHeader)+Length, hdr); + // Free allocated packet + free(hdr); + break; + } +} + +// --- Client Channels +tVFS_Node *UDP_Channel_Init(tInterface *Interface) +{ + tUDPChannel *new; + new = calloc( sizeof(tUDPChannel), 1 ); + new->Interface = Interface; + new->Node.ImplPtr = new; + new->Node.NumACLs = 1; + new->Node.ACLs = &gVFS_ACL_EveryoneRW; + new->Node.Read = UDP_Channel_Read; + new->Node.Write = UDP_Channel_Write; + new->Node.IOCtl = UDP_Channel_IOCtl; + new->Node.Close = UDP_Channel_Close; + + LOCK(&glUDP_Channels); + new->Next = gpUDP_Channels; + gpUDP_Channels = new; + RELEASE(&glUDP_Channels); + + return &new->Node; +} + +/** + * \brief Read from the channel file (wait for a packet) + */ +Uint64 UDP_Channel_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +{ + tUDPChannel *chan = Node->ImplPtr; + tUDPPacket *pack; + + if(chan->LocalPort == 0) return 0; + if(chan->RemotePort == 0) return 0; + + while(chan->Queue == NULL) Threads_Yield(); + + for(;;) + { + LOCK(&chan->lQueue); + if(chan->Queue == NULL) { + RELEASE(&chan->lQueue); + continue; + } + pack = chan->Queue; + chan->Queue = pack->Next; + if(!chan->Queue) chan->QueueEnd = NULL; + RELEASE(&chan->lQueue); + break; + } + + // Clip length to packet length + if(Length > pack->Length) Length = pack->Length; + // Copy packet data from cache + memcpy(Buffer, pack->Data, Length); + // Free cached packet + free(pack); + + return Length; +} + +/** + * \brief Write to the channel file (send a packet) + */ +Uint64 UDP_Channel_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +{ + tUDPChannel *chan = Node->ImplPtr; + if(chan->RemotePort == 0) return 0; + + UDP_SendPacket(chan, Buffer, (size_t)Length); + + return 0; +} + +/** + * \brief Names for channel IOCtl Calls + */ +static const char *casIOCtls_Channel[] = { + DRV_IOCTLNAMES, + "getset_localport", + "getset_remoteport", + "set_remoteaddr", + NULL + }; +/** + * \brief Channel IOCtls + */ +int UDP_Channel_IOCtl(tVFS_Node *Node, int ID, void *Data) +{ + tUDPChannel *chan = Node->ImplPtr; + ENTER("pNode iID pData", Node, ID, Data); + switch(ID) + { + BASE_IOCTLS(DRV_TYPE_MISC, "UDP Channel", 0x100, casIOCtls_Channel); + + case 4: // getset_localport (returns bool success) + if(!Data) LEAVE_RET('i', chan->LocalPort); + if(!CheckMem( Data, sizeof(Uint16) ) ) { + LOG("Invalid pointer %p", Data); + LEAVE_RET('i', -1); + } + // Set port + chan->LocalPort = *(Uint16*)Data; + // Permissions check (Ports lower than 1024 are root-only) + if(chan->LocalPort != 0 && chan->LocalPort < 1024) { + if( Threads_GetUID() != 0 ) { + LOG("Attempt by non-superuser to listen on port %i", chan->LocalPort); + chan->LocalPort = 0; + LEAVE_RET('i', -1); + } + } + // Allocate a random port if requested + if( chan->LocalPort == 0 ) + chan->LocalPort = UDP_int_AllocatePort(); + else + { + // Else, mark the requested port as used + if( UDP_int_MarkPortAsUsed(chan->LocalPort) == 0 ) { + LOG("Port %i us currently in use", chan->LocalPort); + chan->LocalPort = 0; + LEAVE_RET('i', 0); + } + LEAVE_RET('i', 1); + } + LEAVE_RET('i', 1); + + case 5: // getset_remoteport (returns bool success) + if(!Data) LEAVE_RET('i', chan->RemotePort); + if(!CheckMem( Data, sizeof(Uint16) ) ) { + LOG("Invalid pointer %p", Data); + LEAVE_RET('i', -1); + } + chan->RemotePort = *(Uint16*)Data; + return 1; + + case 6: // set_remoteaddr (returns bool success) + switch(chan->Interface->Type) + { + case 4: + if(!CheckMem(Data, sizeof(tIPv4))) { + LOG("Invalid pointer %p", Data); + LEAVE_RET('i', -1); + } + chan->RemoteAddr.v4 = *(tIPv4*)Data; + break; + } + break; + } + LEAVE_RET('i', 0); +} + +/** + * \brief Close and destroy an open channel + */ +void UDP_Channel_Close(tVFS_Node *Node) +{ + tUDPChannel *chan = Node->ImplPtr; + tUDPChannel *prev; + + // Remove from the main list first + LOCK(&glUDP_Channels); + if(gpUDP_Channels == chan) + gpUDP_Channels = gpUDP_Channels->Next; + else + { + for(prev = gpUDP_Channels; + prev->Next && prev->Next != chan; + prev = prev->Next); + if(!prev->Next) + Warning("[UDP ] Bookeeping Fail, channel %p is not in main list", chan); + else + prev->Next = prev->Next->Next; + } + RELEASE(&glUDP_Channels); + + // Clear Queue + LOCK(&chan->lQueue); + while(chan->Queue) + { + tUDPPacket *tmp; + tmp = chan->Queue; + chan->Queue = tmp->Next; + free(tmp); + } + RELEASE(&chan->lQueue); + + // Free channel structure + free(chan); +} + +/** + * \return Port Number on success, or zero on failure + */ +Uint16 UDP_int_AllocatePort() +{ + int i; + LOCK(&glUDP_Ports); + // Fast Search + for( i = UDP_ALLOC_BASE; i < 0x10000; i += 32 ) + if( gUDP_Ports[i/32] != 0xFFFFFFFF ) + break; + if(i == 0x10000) return 0; + for( ;; i++ ) + { + if( !(gUDP_Ports[i/32] & (1 << (i%32))) ) + return i; + } + RELEASE(&glUDP_Ports); +} + +/** + * \brief Allocate a specific port + * \return Boolean Success + */ +int UDP_int_MarkPortAsUsed(Uint16 Port) +{ + LOCK(&glUDP_Ports); + if( gUDP_Ports[Port/32] & (1 << (Port%32)) ) { + return 0; + RELEASE(&glUDP_Ports); + } + gUDP_Ports[Port/32] |= 1 << (Port%32); + RELEASE(&glUDP_Ports); + return 1; +} + +/** + * \brief Free an allocated port + */ +void UDP_int_FreePort(Uint16 Port) +{ + LOCK(&glUDP_Ports); + gUDP_Ports[Port/32] &= ~(1 << (Port%32)); + RELEASE(&glUDP_Ports); } diff --git a/Modules/IPStack/udp.h b/Modules/IPStack/udp.h index be2ff64e..36c36e15 100644 --- a/Modules/IPStack/udp.h +++ b/Modules/IPStack/udp.h @@ -9,6 +9,8 @@ #include "ipv4.h" typedef struct sUDPHeader tUDPHeader; +typedef struct sUDPPacket tUDPPacket; +typedef struct sUDPChannel tUDPChannel; struct sUDPHeader { @@ -19,4 +21,27 @@ struct sUDPHeader Uint8 Data[]; }; +struct sUDPPacket +{ + struct sUDPPacket *Next; + size_t Length; + Uint8 Data[]; +}; + +struct sUDPChannel +{ + struct sUDPChannel *Next; + tInterface *Interface; + Uint16 LocalPort; + union { + tIPv4 v4; + tIPv6 v6; + } RemoteAddr; + Uint16 RemotePort; + tVFS_Node Node; + tSpinlock lQueue; + tUDPPacket * volatile Queue; + tUDPPacket *QueueEnd; +}; + #endif diff --git a/Modules/Storage/ATA/main.c b/Modules/Storage/ATA/main.c index 41f08738..1ba124b5 100644 --- a/Modules/Storage/ATA/main.c +++ b/Modules/Storage/ATA/main.c @@ -2,7 +2,7 @@ * Acess2 IDE Harddisk Driver * - main.c */ -#define DEBUG 0 +#define DEBUG 1 #include #include #include @@ -110,17 +110,17 @@ tPRDT_Ent gATA_PRDTs[2] = { int ATA_Install() { int ret; - + ret = ATA_SetupIO(); if(ret != 1) return ret; - + ATA_SetupPartitions(); - + ATA_SetupVFS(); - + if( DevFS_AddDevice( &gATA_DriverInfo ) == 0 ) return MODULE_INIT_FAILURE; - + return MODULE_INIT_SUCCESS; } @@ -132,9 +132,9 @@ int ATA_SetupIO() { int ent; tPAddr addr; - + ENTER(""); - + // Get IDE Controller's PCI Entry ent = PCI_GetDeviceByClass(0x0101, 0xFFFF, -1); LOG("ent = %i", ent); @@ -156,25 +156,25 @@ int ATA_SetupIO() // Bit 0 is left set as a flag to other functions LOG("gATA_BusMasterBase = 0x%x", gATA_BusMasterBase & ~1); } - + IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri ); IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec ); - + gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( (Uint)&gATA_Buffers[0] ); gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( (Uint)&gATA_Buffers[1] ); - + LOG("gATA_PRDTs = {PBufAddr: 0x%x, PBufAddr: 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr); - + addr = MM_GetPhysAddr( (Uint)&gATA_PRDTs[0] ); LOG("addr = 0x%x", addr); ATA_int_BusMasterWriteDWord(4, addr); addr = MM_GetPhysAddr( (Uint)&gATA_PRDTs[1] ); LOG("addr = 0x%x", addr); ATA_int_BusMasterWriteDWord(12, addr); - + outb(IDE_PRI_BASE+1, 1); outb(IDE_SEC_BASE+1, 1); - + LEAVE('i', MODULE_INIT_SUCCESS); return MODULE_INIT_SUCCESS; } @@ -201,7 +201,7 @@ void ATA_SetupPartitions() void ATA_SetupVFS() { int i, j, k; - + // Count number of nodes needed giATA_NumNodes = 0; for( i = 0; i < MAX_ATA_DISKS; i++ ) @@ -210,10 +210,10 @@ void ATA_SetupVFS() giATA_NumNodes ++; giATA_NumNodes += gATA_Disks[i].NumPartitions; } - + // Allocate Node space gATA_Nodes = malloc( giATA_NumNodes * sizeof(void*) ); - + // Set nodes k = 0; for( i = 0; i < MAX_ATA_DISKS; i++ ) @@ -223,7 +223,7 @@ void ATA_SetupVFS() for( j = 0; j < gATA_Disks[i].NumPartitions; j ++ ) gATA_Nodes[ k++ ] = &gATA_Disks[i].Partitions[j].Node; } - + gATA_DriverInfo.RootNode.Size = giATA_NumNodes; } @@ -239,19 +239,19 @@ int ATA_ScanDisk(int Disk) Uint8 val; int i; tVFS_Node *node; - + ENTER("iDisk", Disk); - + base = ATA_GetBasePort( Disk ); - + LOG("base = 0x%x", base); - + // Send Disk Selector if(Disk == 1 || Disk == 3) outb(base+6, 0xB0); else outb(base+6, 0xA0); - + // Send IDENTIFY outb(base+7, 0xEC); val = inb(base+7); // Read status @@ -259,27 +259,27 @@ int ATA_ScanDisk(int Disk) LEAVE('i', 0); return 0; // Disk does not exist } - + // Poll until BSY clears and DRQ sets or ERR is set while( ((val & 0x80) || !(val & 0x08)) && !(val & 1)) val = inb(base+7); - + if(val & 1) { LEAVE('i', 0); return 0; // Error occured, so return false } - + // Read Data for(i=0;i<256;i++) buf[i] = inw(base); - + // Populate Disk Structure if(identify->Sectors48 != 0) gATA_Disks[ Disk ].Sectors = identify->Sectors48; else gATA_Disks[ Disk ].Sectors = identify->Sectors28; - - + + LOG("gATA_Disks[ Disk ].Sectors = 0x%x", gATA_Disks[ Disk ].Sectors); - + if( gATA_Disks[ Disk ].Sectors / (2048*1024) ) Log("Disk %i: 0x%llx Sectors (%i GiB)", Disk, gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / (2048*1024)); @@ -289,21 +289,21 @@ int ATA_ScanDisk(int Disk) else Log("Disk %i: 0x%llx Sectors (%i KiB)", Disk, gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / 2); - + // Create Name gATA_Disks[ Disk ].Name[0] = 'A'+Disk; gATA_Disks[ Disk ].Name[1] = '\0'; - + // Get pointer to vfs node and populate it node = &gATA_Disks[ Disk ].Node; node->Size = gATA_Disks[Disk].Sectors * SECTOR_SIZE; node->NumACLs = 0; // Means Superuser only can access it node->Inode = (Disk << 8) | 0xFF; node->ImplPtr = gATA_Disks[ Disk ].Name; - + node->ATime = node->MTime = node->CTime = now(); - + node->Read = ATA_ReadFS; node->Write = ATA_WriteFS; node->IOCtl = ATA_IOCtl; @@ -313,13 +313,13 @@ int ATA_ScanDisk(int Disk) LOG("Reading MBR"); // Read Boot Sector ATA_ReadDMA( Disk, 0, 1, mbr ); - + // Check for a GPT table if(mbr->Parts[0].SystemID == 0xEE) ATA_ParseGPT(Disk); else // No? Just parse the MBR ATA_ParseMBR(Disk); - + LEAVE('i', 0); return 1; } @@ -345,7 +345,7 @@ void ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start Part->Node.NumACLs = 0; // Only root can read/write raw block devices Part->Node.Inode = (Disk << 8) | Num; Part->Node.ImplPtr = Part->Name; - + Part->Node.Read = ATA_ReadFS; Part->Node.Write = ATA_WriteFS; Part->Node.IOCtl = ATA_IOCtl; @@ -401,7 +401,7 @@ tVFS_Node *ATA_FindDir(tVFS_Node *Node, char *Name) return NULL; return &gATA_Disks[Name[0]-'A'].Node; } - + // Partitions if(Name[1] < '0' || '9' < Name[1]) return NULL; if(Name[2] == '\0') { // <= 9 @@ -412,12 +412,12 @@ tVFS_Node *ATA_FindDir(tVFS_Node *Node, char *Name) // > 9 if('0' > Name[2] || '9' < Name[2]) return NULL; if(Name[3] != '\0') return NULL; - + part = (Name[1] - '0') * 10; part += Name[2] - '0'; part --; return &gATA_Disks[Name[0]-'A'].Partitions[part].Node; - + } /** @@ -427,7 +427,7 @@ Uint64 ATA_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) { int disk = Node->Inode >> 8; int part = Node->Inode & 0xFF; - + // Raw Disk Access if(part == 0xFF) { @@ -445,7 +445,7 @@ Uint64 ATA_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) Length = gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE - Offset; Offset += gATA_Disks[disk].Partitions[part].Start * SECTOR_SIZE; } - + //Log("ATA_ReadFS: (Node=%p, Offset=0x%llx, Length=0x%llx, Buffer=%p)", Node, Offset, Length, Buffer); return DrvUtil_ReadBlock(Offset, Length, Buffer, ATA_ReadRaw, SECTOR_SIZE, disk); } @@ -457,7 +457,7 @@ Uint64 ATA_WriteFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) { int disk = Node->Inode >> 8; int part = Node->Inode & 0xFF; - + // Raw Disk Access if(part == 0xFF) { @@ -475,7 +475,7 @@ Uint64 ATA_WriteFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) Length = gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE - Offset; Offset += gATA_Disks[disk].Partitions[part].Start * SECTOR_SIZE; } - + Log("ATA_WriteFS: (Node=%p, Offset=0x%llx, Length=0x%llx, Buffer=%p)", Node, Offset, Length, Buffer); Debug_HexDump("ATA_WriteFS", Buffer, Length); return DrvUtil_WriteBlock(Offset, Length, Buffer, ATA_ReadRaw, ATA_WriteRaw, SECTOR_SIZE, disk); @@ -503,7 +503,7 @@ Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk) int ret; Uint offset; Uint done = 0; - + // Pass straight on to ATA_ReadDMAPage if we can if(Count <= MAX_DMA_SECTORS) { @@ -511,7 +511,7 @@ Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk) if(ret == 0) return 0; return Count; } - + // Else we will have to break up the transfer offset = 0; while(Count > MAX_DMA_SECTORS) @@ -524,7 +524,7 @@ Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk) Count -= MAX_DMA_SECTORS; offset += MAX_DMA_SECTORS*SECTOR_SIZE; } - + ret = ATA_ReadDMA(Disk, Address+offset, Count, Buffer+offset); if(ret != 1) return 0; return done+Count; @@ -538,7 +538,7 @@ Uint ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk) int ret; Uint offset; Uint done = 0; - + // Pass straight on to ATA_WriteDMA if we can if(Count <= MAX_DMA_SECTORS) { @@ -546,7 +546,7 @@ Uint ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk) if(ret == 0) return 0; return Count; } - + // Else we will have to break up the transfer offset = 0; while(Count > MAX_DMA_SECTORS) @@ -559,7 +559,7 @@ Uint ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk) Count -= MAX_DMA_SECTORS; offset += MAX_DMA_SECTORS*SECTOR_SIZE; } - + ret = ATA_WriteDMA(Disk, Address+offset, Count, Buffer+offset); if(ret != 1) return 0; return done+Count; @@ -573,9 +573,9 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) int cont = (Disk>>1)&1; // Controller ID int disk = Disk & 1; Uint16 base; - + ENTER("iDisk XAddress iCount pBuffer", Disk, Address, Count, Buffer); - + // Check if the count is small enough if(Count > MAX_DMA_SECTORS) { Warning("Passed too many sectors for a bulk DMA read (%i > %i)", @@ -583,19 +583,19 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) LEAVE('i'); return 0; } - + // Get exclusive access to the disk controller LOCK( &giaATA_ControllerLock[ cont ] ); - + // Set Size gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE; - + // Get Port Base base = ATA_GetBasePort(Disk); - + // Reset IRQ Flag gaATA_IRQs[cont] = 0; - + // Set up transfer outb(base+0x01, 0x00); if( Address > 0x0FFFFFFF ) // Use LBA48 @@ -610,12 +610,12 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) { outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); //Disk,Magic,High addr } - + outb(base+0x02, (Uint8) Count); // Sector Count outb(base+0x03, (Uint8) Address); // Low Addr outb(base+0x04, (Uint8) (Address >> 8)); // Middle Addr outb(base+0x05, (Uint8) (Address >> 16)); // High Addr - + LOG("Starting Transfer"); #if START_BEFORE_CMD // Start transfer @@ -632,7 +632,7 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) // Start transfer ATA_int_BusMasterWriteByte( cont << 3, 9 ); // Read and start #endif - + // Wait for transfer to complete //ATA_int_BusMasterWriteByte( (cont << 3) + 2, 0x4 ); while( gaATA_IRQs[cont] == 0 ) { @@ -640,18 +640,18 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) //LOG("val = 0x%02x", val); Threads_Yield(); } - + // Complete Transfer ATA_int_BusMasterWriteByte( cont << 3, 0 ); // Write and stop - + LOG("Transfer Completed & Acknowledged"); - + // Copy to destination buffer memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE ); - + // Release controller lock RELEASE( &giaATA_ControllerLock[ cont ] ); - + LEAVE('i', 1); return 1; } @@ -664,19 +664,19 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) int cont = (Disk>>1)&1; // Controller ID int disk = Disk & 1; Uint16 base; - + // Check if the count is small enough if(Count > MAX_DMA_SECTORS) return 0; - + // Get exclusive access to the disk controller LOCK( &giaATA_ControllerLock[ cont ] ); - + // Set Size gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE; - + // Get Port Base base = ATA_GetBasePort(Disk); - + // Set up transfer outb(base+0x01, 0x00); if( Address > 0x0FFFFFFF ) // Use LBA48 @@ -691,7 +691,7 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) { outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); //Disk,Magic,High addr } - + outb(base+0x02, (Uint8) Count); // Sector Count outb(base+0x03, (Uint8) Address); // Low Addr outb(base+0x04, (Uint8) (Address >> 8)); // Middle Addr @@ -700,25 +700,25 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) outb(base+0x07, HDD_DMA_W48); // Write Command (LBA48) else outb(base+0x07, HDD_DMA_W28); // Write Command (LBA28) - + // Reset IRQ Flag gaATA_IRQs[cont] = 0; - + // Copy to output buffer memcpy( gATA_Buffers[cont], Buffer, Count*SECTOR_SIZE ); - + // Start transfer ATA_int_BusMasterWriteByte( cont << 3, 1 ); // Write and start - + // Wait for transfer to complete while( gaATA_IRQs[cont] == 0 ) Threads_Yield(); - + // Complete Transfer ATA_int_BusMasterWriteByte( cont << 3, 0 ); // Write and stop - + // Release controller lock RELEASE( &giaATA_ControllerLock[ cont ] ); - + return 1; } @@ -728,7 +728,7 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) void ATA_IRQHandlerPri(int unused) { Uint8 val; - + // IRQ bit set for Primary Controller val = ATA_int_BusMasterReadByte( 0x2 ); LOG("IRQ val = 0x%x", val); @@ -748,6 +748,7 @@ void ATA_IRQHandlerSec(int unused) Uint8 val; // IRQ bit set for Secondary Controller val = ATA_int_BusMasterReadByte( 0xA ); + LOG("IRQ val = 0x%x", val); if(val & 4) { LOG("IRQ hit (val = 0x%x)", val); ATA_int_BusMasterWriteByte( 0xA, 4 ); @@ -785,7 +786,7 @@ void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value) */ void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value) { - + if( gATA_BusMasterBase & 1 ) outd( (gATA_BusMasterBase & ~1) + Ofs, Value ); else diff --git a/Usermode/Applications/axwin2_src/WM/main.c b/Usermode/Applications/axwin2_src/WM/main.c index 13039a3a..7d26b399 100644 --- a/Usermode/Applications/axwin2_src/WM/main.c +++ b/Usermode/Applications/axwin2_src/WM/main.c @@ -38,7 +38,8 @@ int main(int argc, char *argv[]) // Main Loop for(;;) { - yield(); + Messages_PollIPC(); + //yield(); } return 0; } diff --git a/Usermode/Applications/axwin2_src/WM/messages.c b/Usermode/Applications/axwin2_src/WM/messages.c index bf2d2b89..0147e5ff 100644 --- a/Usermode/Applications/axwin2_src/WM/messages.c +++ b/Usermode/Applications/axwin2_src/WM/messages.c @@ -22,13 +22,13 @@ void Messages_Handle(tAxWin_Message *Msg, tMessages_Handle_Callback *Respond, in void Messages_PollIPC() { int len; - int tid = 0; + pid_t tid = 0; char staticBuf[STATICBUF_SIZE]; tAxWin_Message *msg; // Wait for a message - while( (len = SysGetMessage(&tid, NULL)) ) - yield(); + while( (len = SysGetMessage(&tid, NULL)) == 0 ) + sleep(); // Allocate the space for it if( len <= STATICBUF_SIZE ) diff --git a/Usermode/Applications/ifconfig_src/main.c b/Usermode/Applications/ifconfig_src/main.c index 7f8746b3..eb8fa19d 100644 --- a/Usermode/Applications/ifconfig_src/main.c +++ b/Usermode/Applications/ifconfig_src/main.c @@ -61,7 +61,6 @@ void DumpInterfaces(int DumpAll) while( readdir(dp, filename) ) { if(filename[0] == '.') continue; - if(filename[0] != 'i' || filename[1] != 'p') continue; fd = open(path, OPENFLAG_READ); if(fd == -1) { @@ -142,7 +141,7 @@ int DoAutoConfig( char *Device ) tmp = AddInterface(Device); if( tmp < 0 ) return tmp; - sprintf(path, IPSTACK_ROOT"/ip%i", tmp); + sprintf(path, IPSTACK_ROOT"/%i", tmp); fd = open(path, OPENFLAG_READ); if( fd == -1 ) { diff --git a/Usermode/Libraries/Makefile.cfg b/Usermode/Libraries/Makefile.cfg index e4a4aaca..abd8c812 100644 --- a/Usermode/Libraries/Makefile.cfg +++ b/Usermode/Libraries/Makefile.cfg @@ -6,6 +6,6 @@ MAKEDEP = $(CC) -M ASFLAGS = -felf -CPPFLAGS = -I../../include/ +CPPFLAGS = -I$(ACESSDIR)/Usermode/include/ CFLAGS = -Wall -fPIC -fno-builtin -fno-stack-protector $(CPPFLAGS) LDFLAGS = -nostdlib -shared -I/Acess/Libs/ld-acess.so -e SoMain -x -L.. -lacess diff --git a/Usermode/include/acess/sys.h b/Usermode/include/acess/sys.h index 7f4d7dbf..c034b77f 100644 --- a/Usermode/include/acess/sys.h +++ b/Usermode/include/acess/sys.h @@ -7,11 +7,15 @@ #include // === CONSTANTS === +#ifndef NULL +# define NULL ((void*)0) +#endif + #define OPENFLAG_EXEC 0x01 #define OPENFLAG_READ 0x02 #define OPENFLAG_WRITE 0x04 #define OPENFLAG_NOLINK 0x40 -#define OPENFLAG_CREATE 0x40 +#define OPENFLAG_CREATE 0x80 #ifndef SEEK_CUR # define SEEK_SET 1 # define SEEK_CUR 0 @@ -23,6 +27,8 @@ #define FILEFLAG_SYMLINK 0x20 // === TYPES === +typedef uint pid_t; + struct s_sysACL { union { struct { @@ -90,8 +96,8 @@ extern int _SysGetACL(int fd, t_sysACL *dest); extern int _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options); // --- IPC --- -extern int SysSendMessage(int dest, int length, void *Data); -extern int SysGetMessage(int *src, void *Data); +extern int SysSendMessage(pid_t dest, uint length, void *Data); +extern int SysGetMessage(pid_t *src, void *Data); // --- MEMORY --- uint64_t _SysGetPhys(uint vaddr); diff --git a/Usermode/include/axwin/messages.h b/Usermode/include/axwin/messages.h index c11b8644..e4ed1fe2 100644 --- a/Usermode/include/axwin/messages.h +++ b/Usermode/include/axwin/messages.h @@ -6,6 +6,8 @@ #ifndef _AXWIN_MESSAGES_H #define _AXWIN_MESSAGES_H +#include + typedef struct sAxWin_Message tAxWin_Message; /** @@ -16,7 +18,7 @@ enum eAxWin_Messages // Server Requests MSG_SREQ_PING, // - Windows - MSG_SREQ_NEWWINDOW, + MSG_SREQ_NEWWINDOW, // (short x, y, w, h, uint32_t flags) MSG_SREQ_GETFLAGS, MSG_SREQ_SETFLAGS, MSG_SREQ_GETRECT, MSG_SREQ_SETRECT, // - Drawing @@ -29,19 +31,54 @@ enum eAxWin_Messages // Server Responses MSG_SRSP_PONG, + MSG_SRSP_WINDOW, // Returns the new window ID MSG_SRSP_IMG, // Returns the image ID NUM_MSG }; +// --- Server Requests (Requests from the client of the server) /** - * \brief New Window Request structure + * \brief Server Request - Ping (Get Server Version) */ -struct sAxWin_Req_NewWindow +struct sAxWin_SReq_Ping { - }; +/** + * \brief Server Request - New Window + * \see eAxWin_Messages.MSG_SREQ_NEWWINDOW + */ +struct sAxWin_SReq_NewWindow +{ + uint16_t X, Y, W, H; + uint32_t Flags; +}; + + +// --- Server Responses +/** + * \brief Server Response - Pong + * \see eAxWin_Messages.MSG_SRSP_PONG + */ +struct sAxWin_SRsp_Pong +{ + uint8_t Major; + uint8_t Minor; + uint16_t Build; +}; + +/** + * \brief Server Response - New Window + * \see eAxWin_Messages.MSG_SRSP_NEWWINDOW + */ +struct sAxWin_SRsp_NewWindow +{ + uint32_t Handle; +}; + + +// === Core Message Structure /** * \brief Overarching Message Structure * \note sizeof(tAxWin_Message) is never valid @@ -50,6 +87,15 @@ struct sAxWin_Message { uint16_t ID; uint16_t Size; //!< Size in DWORDS + union + { + struct sAxWin_SReq_Ping SReq_Pong; + struct sAxWin_SReq_NewWindow SReq_NewWindow; + + // Server Responses + struct sAxWin_SRsp_Pong SRsp_Pong; + struct sAxWin_SRsp_NewWindow SRsp_Window; + }; }; #endif