From: John Hodge (sonata) Date: Fri, 3 May 2013 03:14:48 +0000 (+0800) Subject: Merge branch 'master' of github.com:thepowersgang/acess2 X-Git-Tag: rel0.15~484^2~11 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=b806b8f55067584cb90fe20277235369a1111c66;hp=001546477549f71fd1af08e13c60e0a39397532a;p=tpg%2Facess2.git Merge branch 'master' of github.com:thepowersgang/acess2 Conflicts: KernelLand/Kernel/arch/x86/acpica.c --- diff --git a/BuildConf/x86/default.mk b/BuildConf/x86/default.mk index f4423eb8..bbe5d2f2 100644 --- a/BuildConf/x86/default.mk +++ b/BuildConf/x86/default.mk @@ -3,6 +3,7 @@ MODULES += Storage/ATA MODULES += Storage/FDDv2 MODULES += Network/NE2000 Network/RTL8139 MODULES += Network/VIARhineII +MODULES += Network/PCnetFAST3 MODULES += Network/E1000 MODULES += Display/VESA MODULES += Display/BochsGA diff --git a/KernelLand/Kernel/arch/x86/acpica.c b/KernelLand/Kernel/arch/x86/acpica.c index a7a0883d..15347892 100644 --- a/KernelLand/Kernel/arch/x86/acpica.c +++ b/KernelLand/Kernel/arch/x86/acpica.c @@ -170,11 +170,15 @@ ACPI_STATUS AcpiOsDeleteCache(ACPI_CACHE_T *Cache) ACPI_STATUS AcpiOsPurgeCache(ACPI_CACHE_T *Cache) { - if( Cache == NULL ) + ENTER("pCache", Cache); + if( Cache == NULL ) { + LEAVE('i', AE_BAD_PARAMETER); return AE_BAD_PARAMETER; + } memset(Cache->ObjectStates, 0, sizeof(char)*Cache->nObj); + LEAVE('i', AE_OK); return AE_OK; } @@ -192,7 +196,8 @@ void *AcpiOsAcquireObject(ACPI_CACHE_T *Cache) } } - Log_Debug("ACPICA", "AcpiOsAcquireObject: %i objects used in cache '%s'", Cache->nObj, Cache->Name); + Log_Debug("ACPICA", "AcpiOsAcquireObject: All %i objects used in '%s'", + Cache->nObj, Cache->Name); LEAVE('n'); return NULL; @@ -202,6 +207,7 @@ ACPI_STATUS AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object) { if( Cache == NULL || Object == NULL ) return AE_BAD_PARAMETER; + ENTER("pCache pObject", Cache, Object); tVAddr delta = (tVAddr)Object - (tVAddr)Cache->First; delta /= Cache->ObjectSize; @@ -212,6 +218,7 @@ ACPI_STATUS AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object) Cache->ObjectStates[delta] = 0; + LEAVE('i', AE_OK); return AE_OK; } diff --git a/KernelLand/Kernel/arch/x86/mboot.c b/KernelLand/Kernel/arch/x86/mboot.c index 7403f387..08331a10 100644 --- a/KernelLand/Kernel/arch/x86/mboot.c +++ b/KernelLand/Kernel/arch/x86/mboot.c @@ -13,8 +13,6 @@ int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *Map, const int MapSize, tPAddr KStart, tPAddr KEnd) { int nPMemMapEnts = 0; - tMBoot_MMapEnt *ent = (void*)((tVAddr)MBInfo->MMapAddr + MapOffset); - tMBoot_MMapEnt *last = (void*)((tVAddr)ent + MBInfo->MMapLength); ENTER("pMBInfo pMapOffset pMap iMapSize PKStart PKEnd", MBInfo, MapOffset, Map, MapSize, KStart, KEnd); @@ -22,6 +20,8 @@ int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt * // Check that the memory map is present if( MBInfo->Flags & (1 << 6) ) { + tMBoot_MMapEnt *ent = (void*)((tVAddr)MBInfo->MMapAddr + MapOffset); + tMBoot_MMapEnt *last = (void*)((tVAddr)ent + MBInfo->MMapLength); // Build up memory map nPMemMapEnts = 0; while( ent < last && nPMemMapEnts < MapSize ) @@ -48,10 +48,16 @@ int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt * nPMemMapEnts ++; ent = (void*)( (tVAddr)ent + ent->Size + 4 ); } + if( ent < last ) + { + Log_Warning("MBoot", "Memory map has >%i entries, internal version is truncated", + MapSize); + } } else if( MBInfo->Flags & (1 << 0) ) { Log_Warning("MBoot", "No memory map passed, using mem_lower and mem_upper"); + ASSERT(MapSize >= 2); nPMemMapEnts = 2; Map[0].Start = 0; Map[0].Length = MBInfo->LowMem * 1024; diff --git a/KernelLand/Kernel/arch/x86/mm_virt.c b/KernelLand/Kernel/arch/x86/mm_virt.c index e04b4ae7..13562f28 100644 --- a/KernelLand/Kernel/arch/x86/mm_virt.c +++ b/KernelLand/Kernel/arch/x86/mm_virt.c @@ -1080,7 +1080,7 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr) MaxBits = PHYS_BITS; // Sanity Check - if(MaxBits < 12 || !PhysAddr) { + if(MaxBits < 12) { LEAVE('i', 0); return 0; } @@ -1089,11 +1089,11 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr) if(Pages == 1 && MaxBits >= PHYS_BITS) { phys = MM_AllocPhys(); + if( PhysAddr ) + *PhysAddr = phys; if( !phys ) { - *PhysAddr = 0; LEAVE_RET('i', 0); } - *PhysAddr = phys; ret = MM_MapHWPages(phys, 1); if(ret == 0) { MM_DerefPhys(phys); @@ -1122,7 +1122,8 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr) return 0; } - *PhysAddr = phys; + if( PhysAddr ) + *PhysAddr = phys; LEAVE('x', ret); return ret; } diff --git a/KernelLand/Modules/IPStack/include/adapters_api.h b/KernelLand/Modules/IPStack/include/adapters_api.h index 78729986..60e7eb44 100644 --- a/KernelLand/Modules/IPStack/include/adapters_api.h +++ b/KernelLand/Modules/IPStack/include/adapters_api.h @@ -20,7 +20,7 @@ enum eIPStack_AdapterTypes // Checksum offloading #define ADAPTERFLAG_OFFLOAD_MAC (1 << 0) #define ADAPTERFLAG_OFFLOAD_IP4 (1 << 1) -#define ADAPTERFLAG_OFFLOAD_IP6 (1 << 2) +#define ADAPTERFLAG_OFFLOAD_80211q (1 << 2) #define ADAPTERFLAG_OFFLOAD_TCP (1 << 3) #define ADAPTERFLAG_OFFLOAD_UDP (1 << 4) diff --git a/KernelLand/Modules/IPStack/link.c b/KernelLand/Modules/IPStack/link.c index c4f716f0..d92504b7 100644 --- a/KernelLand/Modules/IPStack/link.c +++ b/KernelLand/Modules/IPStack/link.c @@ -82,23 +82,27 @@ void Link_RegisterType(Uint16 Type, tPacketCallback Callback) void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, tIPStackBuffer *Buffer) { int length = IPStack_Buffer_GetLength(Buffer); - int ofs = 4 - (length & 3); + int ofs = (4 - (length & 3)) & 3; Uint8 buf[sizeof(tEthernetHeader) + ofs + 4]; + Uint32 *checksum = (void*)(buf + sizeof(tEthernetHeader) + ofs); tEthernetHeader *hdr = (void*)buf; - if( ofs == 4 ) ofs = 0; - Log_Log("Net Link", "Sending %i bytes to %02x:%02x:%02x:%02x:%02x:%02x (Type 0x%x)", length, To.B[0], To.B[1], To.B[2], To.B[3], To.B[4], To.B[5], Type); hdr->Dest = To; memcpy(&hdr->Src, Adapter->HWAddr, 6); // TODO: Remove hard coded 6 hdr->Type = htons(Type); - *(Uint32*)(buf + sizeof(tEthernetHeader) + ofs) = 0; + memset(hdr, 0, ofs+4); // zero padding and checksum - IPStack_Buffer_AppendSubBuffer(Buffer, sizeof(tEthernetHeader), ofs + 4, hdr, NULL, NULL); - - *(Uint32*)(buf + sizeof(tEthernetHeader) + ofs) = htonl( Link_CalculateCRC(Buffer) ); + if( (Adapter->Type->Flags & ADAPTERFLAG_OFFLOAD_MAC) ) + IPStack_Buffer_AppendSubBuffer(Buffer, sizeof(tEthernetHeader), ofs, hdr, NULL, NULL); + else + { + IPStack_Buffer_AppendSubBuffer(Buffer, sizeof(tEthernetHeader), ofs + 4, hdr, NULL, NULL); + *checksum = htonl( Link_CalculateCRC(Buffer) ); + Log_Debug("Net Link", "Non-Offloaded: 0x%x, 0x%x", *checksum, ntohl(*checksum)); + } Log_Log("Net Link", " from %02x:%02x:%02x:%02x:%02x:%02x", hdr->Src.B[0], hdr->Src.B[1], hdr->Src.B[2], diff --git a/KernelLand/Modules/Network/E1000/e1000.c b/KernelLand/Modules/Network/E1000/e1000.c index b225d3dd..644d6940 100644 --- a/KernelLand/Modules/Network/E1000/e1000.c +++ b/KernelLand/Modules/Network/E1000/e1000.c @@ -3,7 +3,7 @@ * - By John Hodge (thePowersGang) * * e1000.c - * - Intel E1000 Network Card Driver (core) + * - Intel 8254x Network Card Driver (core) */ #define DEBUG 1 #define VERSION VER2(0,1) @@ -12,6 +12,19 @@ #include #include #include +#include // Time_Delay + +const struct sSupportedCard { + Uint16 Vendor, Device; +} caSupportedCards[] = { + {0x8086, 0x100E}, // 82540EM-A Desktop + {0x8086, 0x1010}, // 82546EB-A1 Copper Dual Port + {0x8086, 0x1012}, // 82546EB-A1 Fiber + {0x8086, 0x1019}, // 82547[EG]I Copper + {0x8086, 0x101A}, // 82547EI Mobile + {0x8086, 0x101D}, // 82546EB-A1 Copper Quad Port +}; +const int ciNumSupportedCards = sizeof(caSupportedCards)/sizeof(caSupportedCards[0]); // === PROTOTYPES === int E1000_Install(char **Arguments); @@ -19,25 +32,81 @@ tIPStackBuffer *E1000_WaitForPacket(void *Ptr); int E1000_SendPacket(void *Ptr, tIPStackBuffer *Buffer); void E1000_IRQHandler(int Num, void *Ptr); + int E1000_int_InitialiseCard(tCard *Card); +Uint16 E1000_int_ReadEEPROM(tCard *Card, Uint8 WordIdx); // === GLOBALS === MODULE_DEFINE(0, VERSION, E1000, E1000_Install, E1000_Cleanup, NULL); tIPStack_AdapterType gE1000_AdapterType = { .Name = "E1000", - .Type = 0, // TODO: Differentiate differnet wire protos and speeds - .Flags = 0, // TODO: IP checksum offloading, MAC checksum offloading etc + .Type = ADAPTERTYPE_ETHERNET_1G, // TODO: Differentiate differnet wire protos and speeds + .Flags = ADAPTERFLAG_OFFLOAD_MAC, // TODO: IP/TCP/UDP checksum offloading .SendPacket = E1000_SendPacket, .WaitForPacket = E1000_WaitForPacket }; +tCard *gaE1000_Cards; // === CODE === int E1000_Install(char **Arguments) { - for( int id = -1; (id = PCI_GetDevice(0x8086, 0x100E, id)) != -1; ) + int card_count = 0; + for( int modelidx = 0; modelidx < ciNumSupportedCards; modelidx ++ ) { - + const struct sSupportedCard *cardtype = &caSupportedCards[modelidx]; + card_count += PCI_CountDevices(cardtype->Vendor, cardtype->Device); + } + LOG("card_count = %i", card_count); + if( card_count == 0 ) { + LOG("Zero cards located"); + return MODULE_ERR_NOTNEEDED; + } + + // Allocate card array + gaE1000_Cards = calloc(sizeof(tCard), card_count); + if( !gaE1000_Cards ) { + return MODULE_ERR_MALLOC; + } + + // Initialise cards + int card_idx = 0; + for( int modelidx = 0; modelidx < ciNumSupportedCards; modelidx ++ ) + { + const struct sSupportedCard *cardtype = &caSupportedCards[modelidx]; + for( int id = -1, i = 0; (id = PCI_GetDevice(cardtype->Vendor, cardtype->Device, i)) != -1; i ++ ) + { + tCard *card = &gaE1000_Cards[card_idx++]; + Uint32 mmiobase = PCI_GetBAR(id, 0); + if( mmiobase & (1|8) ) { + Log_Warning("E1000", "Dev %i: BAR0 should be non-prefetchable memory", id); + continue; + } + const int addrsize = (mmiobase>>1) & 3; + if( addrsize == 0 ) { + // Standard 32-bit + card->MMIOBasePhys = mmiobase & ~0xF; + } + else if( addrsize == 2 ) { + // 64-bit + card->MMIOBasePhys = (mmiobase & ~0xF) | ((Uint64)PCI_GetBAR(id, 1)<<32); + } + else { + Log_Warning("E1000", "Dev %i: Unknown memory address size %i", id, (mmiobase>>1)&3); + continue; + } + + card->IRQ = PCI_GetIRQ(id); + IRQ_AddHandler(card->IRQ, E1000_IRQHandler, card); + + Log_Debug("E1000", "Card %i: %P IRQ %i", card_idx, card->MMIOBasePhys, card->IRQ); + + if( E1000_int_InitialiseCard(card) ) { + return MODULE_ERR_MALLOC; + } + + card->IPStackHandle = IPStack_Adapter_Add(&gE1000_AdapterType, card, card->MacAddr); + } } - return MODULE_ERR_NOTNEEDED; + return MODULE_ERR_OK; } int E1000_Cleanup(void) @@ -45,16 +114,349 @@ int E1000_Cleanup(void) return 0; } +void E1000_int_ReleaseRXD(void *Arg, size_t HeadLen, size_t FootLen, const void *Data) +{ + tCard **cardptr = Arg; + tCard *Card = *cardptr; + int rxd = (Arg - (void*)Card->RXDescs) / sizeof(tRXDesc); + + Card->RXDescs[rxd].Status = 0; + Mutex_Acquire(&Card->lRXDescs); + if( rxd == REG32(Card, REG_RDT) ) { + while( rxd != Card->FirstUnseenRXD && !(Card->RXDescs[rxd].Status & RXD_STS_DD) ) { + rxd ++; + if( rxd == NUM_RX_DESC ) + rxd = 0; + } + REG32(Card, REG_RDT) = rxd; + LOG("Updated RDT=%i", rxd); + } + Mutex_Release(&Card->lRXDescs); +} + tIPStackBuffer *E1000_WaitForPacket(void *Ptr) { - return NULL; + tCard *Card = Ptr; + + if( Semaphore_Wait(&Card->AvailPackets, 1) != 1 ) + return NULL; + + ENTER("pPtr", Ptr); + + Mutex_Acquire(&Card->lRXDescs); + int first_rxd = Card->FirstUnseenRXD; + int last_rxd = first_rxd; + int nDesc = 1; + while( last_rxd != Card->LastUnseenRXD ) { + if( !(Card->RXDescs[last_rxd].Status & RXD_STS_DD) ) + break; // Oops, should ahve found an EOP first + if( Card->RXDescs[last_rxd].Status & RXD_STS_EOP ) + break; + nDesc ++; + last_rxd = (last_rxd + 1) % NUM_RX_DESC; + } + Card->FirstUnseenRXD = (last_rxd + 1) % NUM_RX_DESC; + Mutex_Release(&Card->lRXDescs); + + LOG("nDesc = %i, first_rxd = %i", nDesc, first_rxd); + tIPStackBuffer *ret = IPStack_Buffer_CreateBuffer(nDesc); + int rxd = first_rxd; + for( int i = 0; i < nDesc; i ++ ) + { + IPStack_Buffer_AppendSubBuffer(ret, 0, Card->RXDescs[rxd].Length, Card->RXBuffers[rxd], + E1000_int_ReleaseRXD, &Card->RXBackHandles[rxd]); + } + + LEAVE('p', ret); + return ret; } int E1000_SendPacket(void *Ptr, tIPStackBuffer *Buffer) { - return -1; + tCard *Card = Ptr; + + ENTER("pPtr pBuffer", Ptr, Buffer); + + int nDesc = 0; + size_t len; + const void *ptr; + // Count sub-buffers (including splitting cross-page entries) + int idx = -1; + while( (idx = IPStack_Buffer_GetBuffer(Buffer, idx, &len, &ptr)) != -1 ) + { + if( len > PAGE_SIZE ) { + LOG("len=%i > PAGE_SIZE", len); + LEAVE('i', EINVAL); + return EINVAL; + } + if( MM_GetPhysAddr(ptr) + len-1 != MM_GetPhysAddr((char*)ptr + len-1) ) { + LOG("Buffer %p+%i spans non-contig physical pages", ptr, len); + nDesc ++; + } + nDesc ++; + } + + // Request set of TX descriptors + int rv = Semaphore_Wait(&Card->FreeTxDescs, nDesc); + if(rv != nDesc) { + LEAVE('i', EINTR); + return EINTR; + } + Mutex_Acquire(&Card->lTXDescs); + int first_txd = Card->FirstFreeTXD; + Card->FirstFreeTXD = (first_txd + nDesc) % NUM_TX_DESC; + int last_txd = (first_txd + nDesc-1) % NUM_TX_DESC; + + LOG("first_txd = %i, last_txd = %i", first_txd, last_txd); + + // Populate buffers + idx = -1; + int txd = first_txd; + while( (idx = IPStack_Buffer_GetBuffer(Buffer, idx, &len, &ptr)) != -1 ) + { + if( MM_GetPhysAddr(ptr) + len-1 != MM_GetPhysAddr((char*)ptr + len-1) ) + { + size_t remlen = PAGE_SIZE - ((tVAddr)ptr & (PAGE_SIZE-1)); + // Split in two + // - First Page + Card->TXDescs[txd].Buffer = MM_GetPhysAddr(ptr); + Card->TXDescs[txd].Length = remlen; + Card->TXDescs[txd].CMD = TXD_CMD_RS; + txd = (txd + 1) % NUM_TX_DESC; + // - Second page + Card->TXDescs[txd].Buffer = MM_GetPhysAddr((char*)ptr + remlen); + Card->TXDescs[txd].Length = len - remlen; + Card->TXDescs[txd].CMD = TXD_CMD_RS; + } + else + { + // Single + Card->TXDescs[txd].Buffer = MM_GetPhysAddr(ptr); + Card->TXDescs[txd].Length = len; + Card->TXDescs[txd].CMD = TXD_CMD_RS; + } + txd = (txd + 1) % NUM_TX_DESC; + } + Card->TXDescs[last_txd].CMD |= TXD_CMD_EOP|TXD_CMD_IDE|TXD_CMD_IFCS; + Card->TXSrcBuffers[last_txd] = Buffer; + + // Trigger TX + IPStack_Buffer_LockBuffer(Buffer); + REG32(Card, REG_TDT) = Card->FirstFreeTXD; + Mutex_Release(&Card->lTXDescs); + LOG("Waiting for TX"); + + // Wait for completion (lock will block, then release straight away) + IPStack_Buffer_LockBuffer(Buffer); + IPStack_Buffer_UnlockBuffer(Buffer); + + // TODO: Check status bits + + LEAVE('i', 0); + return 0; } void E1000_IRQHandler(int Num, void *Ptr) { + tCard *Card = Ptr; + + Uint32 icr = REG32(Card, REG_ICR); + if( icr == 0 ) + return ; + LOG("icr = %x", icr); + + // Transmit descriptor written + if( (icr & ICR_TXDW) || (icr & ICR_TXQE) ) + { + int nReleased = 0; + // Walk descriptors looking for the first non-complete descriptor + LOG("TX %i:%i", Card->LastFreeTXD, Card->FirstFreeTXD); + while( Card->LastFreeTXD != Card->FirstFreeTXD && (Card->TXDescs[Card->LastFreeTXD].Status & TXD_STS_DD) ) + { + nReleased ++; + if( Card->TXSrcBuffers[Card->LastFreeTXD] ) { + IPStack_Buffer_UnlockBuffer( Card->TXSrcBuffers[Card->LastFreeTXD] ); + Card->TXSrcBuffers[Card->LastFreeTXD] = NULL; + } + Card->LastFreeTXD ++; + if(Card->LastFreeTXD == NUM_TX_DESC) + Card->LastFreeTXD = 0; + } + Semaphore_Signal(&Card->FreeTxDescs, nReleased); + LOG("nReleased = %i", nReleased); + } + + if( icr & ICR_LSC ) + { + // Link status change + LOG("LSC"); + // TODO: Detect link drop/raise and poke IPStack + } + + // Pending packet (s) + if( icr & ICR_RXT0 ) + { + int nPackets = 0; + LOG("RX %i:%i", Card->LastUnseenRXD, Card->FirstUnseenRXD); + while( (Card->RXDescs[Card->LastUnseenRXD].Status & RXD_STS_DD) ) + { + if( Card->RXDescs[Card->LastUnseenRXD].Status & RXD_STS_EOP ) + nPackets ++; + Card->LastUnseenRXD ++; + if( Card->LastUnseenRXD == NUM_RX_DESC ) + Card->LastUnseenRXD = 0; + + if( Card->LastUnseenRXD == Card->FirstUnseenRXD ) + break; + } + Semaphore_Signal(&Card->AvailPackets, nPackets); + LOG("nPackets = %i", nPackets); + } + + icr &= ~(ICR_RXT0|ICR_LSC|ICR_TXQE|ICR_TXDW); + if( icr ) + Log_Warning("E1000", "Unhandled ICR bits 0x%x", icr); +} + +// TODO: Move this function into Kernel/drvutil.c +/** + * \brief Allocate a set of buffers in hardware mapped space + * + * Allocates \a NumBufs buffers using shared pages (if \a BufSize is less than a page) or + * as a set of contiugious allocations. + */ +int DrvUtil_AllocBuffers(void **Buffers, int NumBufs, int PhysBits, size_t BufSize) +{ + if( BufSize >= PAGE_SIZE ) + { + const int pages_per_buf = BufSize / PAGE_SIZE; + ASSERT(pages_per_buf * PAGE_SIZE == BufSize); + for( int i = 0; i < NumBufs; i ++ ) { + Buffers[i] = (void*)MM_AllocDMA(pages_per_buf, PhysBits, NULL); + if( !Buffers[i] ) return 1; + } + } + else + { + size_t ofs = 0; + const int bufs_per_page = PAGE_SIZE / BufSize; + ASSERT(bufs_per_page * BufSize == PAGE_SIZE); + void *page; + for( int i = 0; i < NumBufs; i ++ ) + { + if( ofs == 0 ) { + page = (void*)MM_AllocDMA(1, PhysBits, NULL); + if( !page ) return 1; + } + Buffers[i] = (char*)page + ofs; + ofs += BufSize; + if( ofs >= PAGE_SIZE ) + ofs = 0; + } + } + return 0; +} + +int E1000_int_InitialiseCard(tCard *Card) +{ + ENTER("pCard", Card); + + // Map required structures + Card->MMIOBase = (void*)MM_MapHWPages( Card->MMIOBasePhys, 7 ); + if( !Card->MMIOBase ) { + Log_Error("E1000", "%p: Failed to map MMIO Space (7 pages)", Card); + LEAVE('i', 1); + return 1; + } + + // --- Read MAC address from EEPROM --- + { + Uint16 macword; + macword = E1000_int_ReadEEPROM(Card, 0); + Card->MacAddr[0] = macword & 0xFF; + Card->MacAddr[1] = macword >> 8; + macword = E1000_int_ReadEEPROM(Card, 1); + Card->MacAddr[2] = macword & 0xFF; + Card->MacAddr[3] = macword >> 8; + macword = E1000_int_ReadEEPROM(Card, 2); + Card->MacAddr[4] = macword & 0xFF; + Card->MacAddr[5] = macword >> 8; + } + Log_Log("E1000", "%p: MAC Address %02x:%02x:%02x:%02x:%02x:%02x", + Card, + Card->MacAddr[0], Card->MacAddr[1], + Card->MacAddr[2], Card->MacAddr[3], + Card->MacAddr[4], Card->MacAddr[5]); + + // --- Prepare for RX --- + LOG("RX Preparation"); + Card->RXDescs = (void*)MM_AllocDMA(1, 64, NULL); + if( !Card->RXDescs ) { + LEAVE('i', 2); + return 2; + } + if( DrvUtil_AllocBuffers(Card->RXBuffers, NUM_RX_DESC, 64, RX_DESC_BSIZE) ) { + LEAVE('i', 3); + return 3; + } + for( int i = 0; i < NUM_RX_DESC; i ++ ) + { + Card->RXDescs[i].Buffer = MM_GetPhysAddr(Card->RXBuffers[i]); + Card->RXDescs[i].Status = 0; // Clear RXD_STS_DD, gives it to the card + Card->RXBackHandles[i] = Card; + } + + REG64(Card, REG_RDBAL) = MM_GetPhysAddr((void*)Card->RXDescs); + REG32(Card, REG_RDLEN) = NUM_RX_DESC * 16; + REG32(Card, REG_RDH) = 0; + REG32(Card, REG_RDT) = NUM_RX_DESC; + // Hardware size, Multicast promisc, Accept broadcast, Interrupt at 1/4 Rx descs free + REG32(Card, REG_RCTL) = RX_DESC_BSIZEHW | RCTL_MPE | RCTL_BAM | RCTL_RDMTS_1_4; + Card->FirstUnseenRXD = 0; + Card->LastUnseenRXD = 0; + + // --- Prepare for TX --- + LOG("TX Preparation"); + Card->TXDescs = (void*)MM_AllocDMA(1, 64, NULL); + if( !Card->RXDescs ) { + LEAVE('i', 4); + return 4; + } + for( int i = 0; i < NUM_TX_DESC; i ++ ) + { + Card->TXDescs[i].Buffer = 0; + Card->TXDescs[i].CMD = 0; + } + REG64(Card, REG_TDBAL) = MM_GetPhysAddr((void*)Card->TXDescs); + REG32(Card, REG_TDLEN) = NUM_TX_DESC * 16; + REG32(Card, REG_TDH) = 0; + REG32(Card, REG_TDT) = 0; + // Enable, pad short packets + REG32(Card, REG_TCTL) = TCTL_EN | TCTL_PSP | (0x0F << TCTL_CT_ofs) | (0x40 << TCTL_COLD_ofs); + Card->FirstFreeTXD = 0; + + // -- Prepare Semaphores + Semaphore_Init(&Card->FreeTxDescs, NUM_TX_DESC, NUM_TX_DESC, "E1000", "TXDescs"); + Semaphore_Init(&Card->AvailPackets, 0, NUM_RX_DESC, "E1000", "RXDescs"); + + // --- Prepare for full operation --- + LOG("Starting card"); + REG32(Card, REG_CTRL) = CTRL_SLU|CTRL_ASDE; // Link up, auto speed detection + REG32(Card, REG_IMS) = 0x1F6DC; // Interrupt mask + (void)REG32(Card, REG_ICR); // Discard pending interrupts + REG32(Card, REG_RCTL) |= RCTL_EN; + LEAVE('i', 0); + return 0; +} + +Uint16 E1000_int_ReadEEPROM(tCard *Card, Uint8 WordIdx) +{ + REG32(Card, REG_EERD) = ((Uint32)WordIdx << 8) | 1; + Uint32 tmp; + while( !((tmp = REG32(Card, REG_EERD)) & (1 << 4)) ) { + // TODO: use something like Time_MicroDelay instead + Time_Delay(1); + } + + return tmp >> 16; } diff --git a/KernelLand/Modules/Network/E1000/e1000.h b/KernelLand/Modules/Network/E1000/e1000.h index d8b864ff..2a0eb8e3 100644 --- a/KernelLand/Modules/Network/E1000/e1000.h +++ b/KernelLand/Modules/Network/E1000/e1000.h @@ -8,6 +8,45 @@ #ifndef _E1000_H_ #define _E1000_H_ +#include "e1000_hw.h" + +#include +#include +#include + +#define NUM_TX_DESC (PAGE_SIZE/sizeof(struct sTXDesc)) +#define NUM_RX_DESC (PAGE_SIZE/sizeof(struct sRXDesc)) + +#define RX_DESC_BSIZE 4096 +#define RX_DESC_BSIZEHW RCTL_BSIZE_4096 + +typedef struct sCard +{ + tPAddr MMIOBasePhys; + int IRQ; + Uint16 IOBase; + volatile void *MMIOBase; + + tMutex lRXDescs; + int FirstUnseenRXD; + int LastUnseenRXD; + void *RXBuffers[NUM_RX_DESC]; + volatile tRXDesc *RXDescs; + tSemaphore AvailPackets; + struct sCard *RXBackHandles[NUM_RX_DESC]; // Pointers to this struct, offset used to select desc + + tMutex lTXDescs; + int FirstFreeTXD; + int LastFreeTXD; + volatile tTXDesc *TXDescs; + tSemaphore FreeTxDescs; + + tIPStackBuffer *TXSrcBuffers[NUM_TX_DESC]; + + Uint8 MacAddr[6]; + + void *IPStackHandle; +} tCard; #endif diff --git a/KernelLand/Modules/Network/E1000/e1000_hw.h b/KernelLand/Modules/Network/E1000/e1000_hw.h new file mode 100644 index 00000000..cd182ebf --- /dev/null +++ b/KernelLand/Modules/Network/E1000/e1000_hw.h @@ -0,0 +1,249 @@ +/* + * Acess2 E1000 Network Driver + * - By John Hodge (thePowersGang) + * + * e1000_hw.h + * - Hardware Definitions + */ +#ifndef _E1000_HW_H_ +#define _E1000_HW_H_ + +typedef struct sRXDesc tRXDesc; +typedef struct sTXDesc tTXDesc; + +#define RXD_STS_PIF (1<<7) // Passed inexact filter (multicast, probably) +#define RXD_STS_IPCS (1<<6) // IP Checksum was calculated +#define RXD_STS_TCPCS (1<<5) // TCP Checksum was calculated +#define RXD_STS_RSV (1<<4) // reserved +#define RXD_STS_VP (1<<3) // Packet was 802.1q tagged +#define RXD_STS_IXSM (1<<2) // Ignore IPCS/TCPS +#define RXD_STS_EOP (1<<1) // Last descriptor in apcket +#define RXD_STS_DD (1<<0) // Descriptor Done, buffer data is now valid + +#define RXD_ERR_RXE (1<<7) // RX Error +#define RXD_ERR_IPE (1<<6) // IP Checksum Error +#define RXD_ERR_TCPE (1<<5) // TCP/UDP Checksum Error +#define RXD_ERR_CXE (1<<4) // Carrier Extension Error (GMII cards [82544GC/EI] only) +#define RXD_ERR_SEQ (1<<2) // Sequence Error (aka Framing Error) +#define RXD_ERR_SE (1<<1) // Symbol error (TBI mode) +#define RXD_ERR_CE (1<<0) // CRC Error / Alignmnet Error + +struct sRXDesc +{ + Uint64 Buffer; + Uint16 Length; + Uint16 Checksum; + Uint8 Status; + Uint8 Errors; + Uint16 Special; +} PACKED; + +#define TXD_CMD_IDE (1<<7) // Interrupt delay enable +#define TXD_CMD_VLE (1<<6) // VLAN Packet enable +#define TXD_CMD_DEXT (1<<5) // Use extended descriptor format (TODO) +#define TXD_CMD_RPS (1<<4) // GC/EI Report Packet Set +#define TXD_CMD_RS (1<<3) // Report Status +#define TXD_CMD_IC (1<<2) // Insert checksum at indicated offset +#define TXD_CMD_IFCS (1<<1) // Insert frame check sum +#define TXD_CMD_EOP (1<<0) // End of packet + +#define TXD_STS_TU (1<<3) // [GC/EI] Transmit Underrun +#define TXD_STS_LC (1<<2) // Late collision +#define TXD_STS_EC (1<<1) // Excess collisions +#define TXD_STS_DD (1<<0) // Descriptor Done + +struct sTXDesc +{ + Uint64 Buffer; + Uint16 Length; + Uint8 CSO; // TCP Checksum offset + Uint8 CMD; + Uint8 Status; + Uint8 CSS; // TCP Checksum start + Uint16 Special; +} PACKED; + +#define TXCD_CMD_IDE (1<<(24+7)) // Interrupt Delay +#define TXCD_CMD_DEXT (1<<(24+5)) // Descriptor Extension (Must be one) +#define TXCD_CMD_RS (1<<(24+3)) // Report Status +#define TXCD_CMD_TSE (1<<(24+2)) // TCP Segmentation Enable +#define TXCD_CMD_IP (1<<(24+1)) // IP version (1=IPv4, 0=IPv6) +#define TXCD_CMD_TCP (1<<(24+0)) // Packet Type (1=TCP, 0=Other) + +#define TXCD_STS_DD (1<<0) // Descriptor Done + +struct sTXCtxDesc +{ + Uint8 IPCSS; // IP Checksum Start + Uint8 IPCSO; // IP Checksum Offset + Uint16 IPCSE; // IP Checksum Ending (last byte) + Uint8 TUCSS; // TCP/UDP Checksum Start + Uint8 TUCSO; // TCP/UDP Checksum Offset + Uint16 TUCSE; // TCP/UDP Checksum Ending + Uint32 CmdLen; // [0:19] Length, [20:23] DTYP (0), [24:31] TUCMD + Uint8 Status; + Uint8 HdrLen; // Header length + Uint16 MSS; // Maximum segment size +} PACKED; + +#define TXDD_CMD_IDE (1<<(24+7)) // Interrupt Delay +#define TXDD_CMD_VLE (1<<(24+6)) // VLAN Enable +#define TXDD_CMD_DEXT (1<<(24+5)) // Descriptor Extension +#define TXDD_CMD_RPS (1<<(24+4)) // [GC/EI] Report Packet Sent +#define TXDD_CMD_RS (1<<(24+3)) // Report Status +#define TXDD_CMD_TSE (1<<(24+2)) // TCP Segmentation Enable +#define TXDD_CMD_IFCS (1<<(24+1)) // Insert FCS +#define TXDD_CMD_EOP (1<<(24+0)) // End of packet + +#define TXDD_STS_TU (1<<3) // [GC/EI] Transmit Underrun +#define TXDD_STS_LC (1<<2) // Late collision +#define TXDD_STS_EC (1<<1) // Excess collisions +#define TXDD_STS_DD (1<<0) // Descriptor Done + +#define TXDD_POPTS_TXSM (1<<1) // Insert TCP/UDP Checksum +#define TXDD_POPTS_IXSM (1<<0) // Insert IP Checksum + +struct sTXDataDesc +{ + Uint64 Buffer; + Uint32 CmdLen; // [0:19] Length, [20:23] DTYP (1), [24:31] DCMD + Uint8 Status; + Uint8 POpts; // Packet option field + Uint16 Special; +}; + +#define REG32(card,ofs) (((volatile Uint32*)card->MMIOBase)[ofs/4]) +#define REG64(card,ofs) (((volatile Uint64*)card->MMIOBase)[ofs/8]) + +enum eRegs +{ + REG_CTRL = 0x000, + REG_STATUS = 0x008, + REG_EECD = 0x010, + REG_EERD = 0x014, + REG_CTRL_EXT = 0x018, + REG_FLA = 0x01C, + REG_MDIC = 0x020, + REG_FCAL = 0x028, // 64-bit value + REG_FCAH = 0x02C, + REG_FCT = 0x030, + + REG_ICR = 0x0C0, // Interrupt cause read + REG_ITR = 0x0C4, // Interrupt throttling + REG_ICS = 0x0C8, // Interrupt cause set + REG_IMS = 0x0D0, // Interrupt mask set/read + REG_IMC = 0x0D8, // Interrupt mask clear + + REG_TXCW = 0x178, // N/A for 82540EP/EM, 82541xx and 82547GI/EI + REG_RXCW = 0x180, // ^^ + REG_LEDCTL = 0xE00, + + REG_RCTL = 0x100, + REG_RDBAL = 0x2800, + REG_RDLEN = 0x2808, + REG_RDH = 0x2810, + REG_RDT = 0x2818, + REG_RDTR = 0x2820, + REG_RXDCTL = 0x2820, // Receive Descriptor Control + + REG_TCTL = 0x400, + REG_TDBAL = 0x3800, + REG_TDLEN = 0x3808, + REG_TDH = 0x3810, + REG_TDT = 0x3818, + REG_TDIV = 0x3820, // Transmit Interrupt Delay Value + REG_TXDCTL = 0x3828, // Transmit Descriptor Control + + REG_MTA0 = 0x5200, // 128 entries + REG_RA0 = 0x5400, // 16 entries of ? + REG_VFTA0 = 0x6500, // 128 entries +}; + +#define CTRL_FD (1 << 0) // Full-Duplex +#define CTRL_LRST (1 << 3) // Link Reset +#define CTRL_ASDE (1 << 5) // Auto-Speed Detection Enable +#define CTRL_SLU (1 << 6) // Set link up +// TODO: CTRL_* +#define CTRL_SDP0_DATA (1 << 18) // Software Programmable IO #0 (Data) +#define CTRL_SDP1_DATA (1 << 19) // Software Programmable IO #1 (Data) +// TODO: CTRL_* +#define CTRL_RST (1 << 26) // Software reset (cleared by hw once complete) +#define CTRL_RFCE (1 << 27) // Receive Flow Control Enable +#define CTRL_TFCE (1 << 28) // Transmit Flow Control Enable +#define CTRL_VME (1 << 30) // VLAN Mode Enable +#define CTRL_PHY_RST (1 << 31) // PHY Reset (3uS) + +#define ICR_TXDW (1 << 0) // Transmit Descriptor Written Back +#define ICR_TXQE (1 << 1) // Transmit Queue Empty +#define ICR_LSC (1 << 2) // Link Status Change +#define ICR_RXSEQ (1 << 3) // Receive Sequence Error (Framing Error) +#define ICR_RXDMT0 (1 << 4) // Receive Descriptor Minimum Threshold Reached (need more RX descs) +#define ICR_XRO (1 << 6) // Receiver overrun +#define ICR_RXT0 (1 << 7) // Receiver Timer Interrupt +#define ICR_MDAC (1 << 9) // MDI/O Access Complete +#define ICR_RXCFG (1 << 10) // Receiving /C/ ordered sets +#define ICR_PHYINT (1 << 12) // PHY Interrupt +#define ICR_GPI_SDP6 (1 << 13) // GP Interrupt SDP6/SDP2 +#define ICR_GPI_SDP7 (1 << 14) // GP Interrupt SDP7/SDP3 +#define ICR_TXD_LOW (1 << 15) // Transmit Descriptor Low Threshold hit +#define ICR_SRPD (1 << 16) // Small Receive Packet Detected + +#define RCTL_EN (1 << 1) // Receiver Enable +#define RCTL_SBP (1 << 2) // Store Bad Packets +#define RCTL_UPE (1 << 3) // Unicast Promiscuous Enabled +#define RCTL_MPE (1 << 4) // Multicast Promiscuous Enabled +#define RCTL_LPE (1 << 5) // Long Packet Reception Enable +#define RCTL_LBM (3 << 6) // Loopback mode +enum { + RCTL_LBM_NONE = 0 << 6, // - No Loopback + RCTL_LBM_UD1 = 1 << 6, // - Undefined + RCTL_LBM_UD2 = 2 << 6, // - Undefined + RCTL_LBM_PHY = 3 << 6, // - PHY or external SerDes loopback +}; +#define RCTL_RDMTS (3 << 8) // Receive Descriptor Minimum Threshold Size +enum { + RCTL_RDMTS_1_2 = 0 << 8, // - 1/2 RDLEN free + RCTL_RDMTS_1_4 = 1 << 8, // - 1/4 RDLEN free + RCTL_RDMTS_1_8 = 2 << 8, // - 1/8 RDLEN free + RCTL_RDMTS_RSVD = 3 << 8, // - Reserved +}; +#define RCTL_MO (3 << 12) // Multicast Offset +enum { + RCTL_MO_36 = 0 << 12, // bits [47:36] of multicast address + RCTL_MO_35 = 1 << 12, // bits [46:35] of multicast address + RCTL_MO_34 = 2 << 12, // bits [45:34] of multicast address + RCTL_MO_32 = 3 << 12, // bits [43:32] of multicast address +}; +#define RCTL_BAM (1 << 15) // Broadcast Accept Mode +#define RCTL_BSIZE (1 << 16) // Receive Buffer Size +enum { + RCTL_BSIZE_2048 = (0 << 16), // - 2048 bytes + RCTL_BSIZE_1024 = (1 << 16), // - 1024 bytes + RCTL_BSIZE_512 = (2 << 16), // - 512 bytes + RCTL_BSIZE_256 = (3 << 16), // - 256 bytes + + RCTL_BSIZE_RSVD = (0 << 16)|(1 << 25), // - Reserved + RCTL_BSIZE_16K = (1 << 16)|(1 << 25), // - 16384 bytes + RCTL_BSIZE_8192 = (2 << 16)|(1 << 25), // - 8192 bytes + RCTL_BSIZE_4096 = (3 << 16)|(1 << 25), // - 4096 bytes +}; +#define RCTL_VFE (1 << 18) // VLAN Filter Enable +#define RCTL_CFIEN (1 << 19) // Canoical Form Indicator Enable +#define RCTL_CFI (1 << 20) // Value to check the CFI for [Valid if CFIEN] +#define RCTL_DPF (1 << 22) // Discard Pause Frames +#define RCTL_PMCF (1 << 23) // Pass MAC Control Frames +#define RCTL_BSEX (1 << 25) // Buffer Size Extension (multply BSIZE by 16, used in BSIZE enum) +#define RCTL_SECRC (1 << 26) // Strip Ethernet CRC + +#define TCTL_EN (1 << 1) // Transmit Enable +#define TCTL_PSP (1 << 3) // Pad Short Packets +#define TCTL_CT (255 << 4) // Collision Threshold +#define TCTL_CT_ofs 4 +#define TCTL_COLD (1023 << 12) // Collision Distance +#define TCTL_COLD_ofs 12 +#define TCTL_SWXOFF (1 << 22) // Software XOFF Transmission +#define TCTL_RTLC (1 << 24) // Retransmit on Late Collision +#define TCTL_NRTU (1 << 25) // No retransmit on underrun [82544GC/EI] + +#endif + diff --git a/KernelLand/Modules/Network/PCnetFAST3/pcnet-fast3.c b/KernelLand/Modules/Network/PCnetFAST3/pcnet-fast3.c index 06c783a2..7105b02f 100644 --- a/KernelLand/Modules/Network/PCnetFAST3/pcnet-fast3.c +++ b/KernelLand/Modules/Network/PCnetFAST3/pcnet-fast3.c @@ -70,8 +70,9 @@ static void _WriteBCR(tCard *Card, Uint8 Reg, Uint16 Value); MODULE_DEFINE(0, VERSION, Network_PCnetFAST3, PCnet3_Install, PCnet3_Cleanup, "IPStack", NULL); tIPStack_AdapterType gPCnet3_AdapterType = { .Name = "PCnet-FAST III", - .Type = 0, // TODO: Differentiate differnet wire protos and speeds - .Flags = 0, // TODO: IP checksum offloading, MAC checksum offloading etc + .Type = ADAPTERTYPE_ETHERNET_100M, + //.Flags = ADAPTERFLAG_OFFLOAD_MAC, + .Flags = 0, .SendPacket = PCnet3_SendPacket, .WaitForPacket = PCnet3_WaitForPacket }; @@ -134,18 +135,6 @@ int PCnet3_Install(char **Options) outd(card->IOBase + REG_RDP, 0); // Get MAC address - #if 0 - Uint16 macword; - //macword = _ReadCSR(card, CSR_MAC0); - card->MacAddr[0] = macword & 0xFF; - card->MacAddr[1] = macword >> 8; - //macword = _ReadCSR(card, CSR_MAC1); - card->MacAddr[2] = macword & 0xFF; - card->MacAddr[3] = macword >> 8; - //macword = _ReadCSR(card, CSR_MAC2); - card->MacAddr[4] = macword & 0xFF; - card->MacAddr[5] = macword >> 8; - #else Uint32 macword; macword = ind(card->IOBase + REG_APROM0); card->MacAddr[0] = macword & 0xFF; @@ -155,17 +144,13 @@ int PCnet3_Install(char **Options) macword = ind(card->IOBase + REG_APROM4); card->MacAddr[4] = macword & 0xFF; card->MacAddr[5] = macword >> 8; - #endif // Install IRQ Handler IRQ_AddHandler(card->IRQ, PCnet3_IRQHandler, card); - // Soft reset (read from RESET) + // Initialise the card state PCnet3_int_InitCard(card); - - Semaphore_Init(&card->ReadSemaphore, 0, 0, "PCnet3", "CardRead"); - // Register card->IPStackHandle = IPStack_Adapter_Add(&gPCnet3_AdapterType, card, card->MacAddr); @@ -235,6 +220,15 @@ tIPStackBuffer *PCnet3_WaitForPacket(void *Ptr) return ret; } +int PCnet3_int_FillTD(tTxDesc_3 *td, Uint32 BufAddr, Uint32 Len, int bBounced) +{ + td->Flags0 = 0; + td->Flags1 = 0xF000 | (4096 - (Len & 0xFFF)); + td->Buffer = BufAddr; + td->_avail = bBounced; + return 0; +} + int PCnet3_SendPacket(void *Ptr, tIPStackBuffer *Buffer) { tCard *card = Ptr; @@ -259,7 +253,7 @@ int PCnet3_SendPacket(void *Ptr, tIPStackBuffer *Buffer) ; // will be bounce-buffered else #endif - if( MM_GetPhysAddr(sbuf_ptr)+sbuf_len != MM_GetPhysAddr(sbuf_ptr+sbuf_len) ) + if( MM_GetPhysAddr(sbuf_ptr)+sbuf_len-1 != MM_GetPhysAddr(sbuf_ptr+sbuf_len-1) ) { // Split nDesc ++; @@ -298,10 +292,7 @@ int PCnet3_SendPacket(void *Ptr, tIPStackBuffer *Buffer) void *bounce_virt = MM_AllocDMA(1, 32, &bounce_phys); memcpy(bounce_virt, sbuf_ptr, sbuf_len); // Copy to bounce buffer - td->Flags0 = 0; - td->Flags1 = 0xF000 | sbuf_len; - td->Buffer = bounce_phys; - td->_avail = 1; + PCnet3_int_FillTD(td, bounce_phys, sbuf_len, 1); LOG("%i: Bounce buffer %P+%i (orig %P,%P) - %p", idx, bounce_phys, sbuf_len, start_phys, end_phys, td); } @@ -314,15 +305,11 @@ int PCnet3_SendPacket(void *Ptr, tIPStackBuffer *Buffer) assert( !(td2->Flags1 & TXDESC_FLG1_OWN) ); td_idx = (td_idx + 1) % TLEN; - td->Flags0 = 0; - td->Flags1 = 0xF000 | page1_maxsize; - td->Buffer = start_phys; - td->_avail = 0; + PCnet3_int_FillTD(td, start_phys, page1_maxsize, 0); - td2->Flags0 = 0; - td2->Flags1 = 0xF000 | (sbuf_len - page1_maxsize); - td2->Buffer = end_phys - (sbuf_len-page1_maxsize-1); - td2->_avail = 0; + size_t page2_size = sbuf_len - page1_maxsize; + PCnet3_int_FillTD(td2, end_phys - (page2_size-1), page2_size, 0); + // - Explicitly set OWN on td2 because it's never the first, and `td` gets set below td2->Flags1 |= TXDESC_FLG1_OWN; LOG("%i: Split (%P,%P)+%i - %p,%p", @@ -330,16 +317,13 @@ int PCnet3_SendPacket(void *Ptr, tIPStackBuffer *Buffer) } else { - td->Flags0 = 0; - td->Flags1 = 0xF000 | sbuf_len; - td->Buffer = start_phys; - td->_avail = 0; + PCnet3_int_FillTD(td, start_phys, sbuf_len, 0); LOG("%i: Straight %P+%i - %p", idx, td->Buffer, sbuf_len, td); } // On every descriptor except the first, set OWN // - OWN set later once all are filled - if( (td_idx+TLEN-1)%TLEN != first_desc ) + if( td != &card->TxQueue[first_desc] ) td->Flags1 |= TXDESC_FLG1_OWN; } @@ -476,7 +460,8 @@ void PCnet3_IRQHandler(int Num, void *Ptr) if( status & CSR_STATUS_IDON ) { Log_Debug("PCnet3", "Card %p initialisation done", card); - } + LOG("CSR15 reads as 0x%x", _ReadCSR(card, 15)); + } // ERR set? if( status & 0xBC00 ) diff --git a/RunQemu b/RunQemu index db5306a8..c34d963a 100755 --- a/RunQemu +++ b/RunQemu @@ -13,6 +13,8 @@ QEMU_PARAMS=$QEMU_PARAMS" -net nic" _NETTYPE="user" +_EVAL=eval + while [ $# -ne 0 ]; do case $1 in -gdb) @@ -47,6 +49,9 @@ while [ $# -ne 0 ]; do shift QEMU_PARAMS=$QEMU_PARAMS" "$1 ;; + -n) + _EVAL=echo + ;; -fwd) _NETTYPE=$_NETTYPE",hostfwd=tcp::10023-10.0.2.10:23" ;; @@ -80,13 +85,13 @@ fi # qemu-system-x86_64 $QEMU_PARAMS -serial stdio | tee QemuLog.txt #echo $QEMU $BOOTOPT $QEMU_PARAMS if [ "x$_NOGRAPHIC" = "xyes" ] ; then - eval $QEMU $BOOTOPT $QEMU_PARAMS -nographic | tee QemuLog.txt + $_EVAL $QEMU $BOOTOPT $QEMU_PARAMS -nographic | tee QemuLog.txt exit fi if [ "x$_NOTEE" = "xyes" ] ; then - eval $QEMU $BOOTOPT $QEMU_PARAMS -serial stdio + $_EVAL $QEMU $BOOTOPT $QEMU_PARAMS -serial stdio exit fi -eval $QEMU $BOOTOPT $QEMU_PARAMS -serial stdio | tee QemuLog.txt +$_EVAL $QEMU $BOOTOPT $QEMU_PARAMS -serial stdio | tee QemuLog.txt diff --git a/Tools/GCCProxy/gccproxy.sh b/Tools/GCCProxy/gccproxy.sh index 477c4766..0dd68644 100755 --- a/Tools/GCCProxy/gccproxy.sh +++ b/Tools/GCCProxy/gccproxy.sh @@ -78,6 +78,8 @@ run() { return $? } +_ldflags="-lposix -lpsocket "$_ldflags + cfgfile=`mktemp` make --no-print-directory -f $BASEDIR/getconfig.mk ARCH=x86 TYPE=$_linktype > $cfgfile . $cfgfile @@ -104,6 +106,6 @@ elif echo " $_miscargs" | grep '\.c' >/dev/null; then rm $tmpout exit $_rv else - run $_LD$_ldflags $_miscargs $_outfile $LDFLAGS $_libs + run $_LD $_ldflags $_miscargs $_outfile $LDFLAGS $LIBGCC_PATH $_libs fi diff --git a/Usermode/Applications/axwin3_src/Interface/main.c b/Usermode/Applications/axwin3_src/Interface/main.c index a0986147..5f323e46 100644 --- a/Usermode/Applications/axwin3_src/Interface/main.c +++ b/Usermode/Applications/axwin3_src/Interface/main.c @@ -22,6 +22,7 @@ void create_run_dialog(void); void mainmenu_run_dialog(void *unused); void mainmenu_app_terminal(void *unused); void mainmenu_app_textedit(void *unused); +void update_time(void); // === GLOBALS === tHWND gSidebar; @@ -29,6 +30,7 @@ tAxWin3_Widget *gSidebarRoot; tHWND gSystemMenu; tHWND gRunDialog; tAxWin3_Widget *gRunInput; +tAxWin3_Widget *gTimeDisplay; int giScreenWidth; int giScreenHeight; char **gEnvion; @@ -97,9 +99,10 @@ void create_sidebar(void) ELEFLAG_VERTICAL|ELEFLAG_ALIGN_CENTER|ELEFLAG_NOSTRETCH, "Version/Time" ); - txt = AxWin3_Widget_AddWidget(ele, ELETYPE_TEXT, ELEFLAG_NOSTRETCH, "Version String"); - AxWin3_Widget_SetSize(txt, 20); - AxWin3_Widget_SetText(txt, "3.0"); + gTimeDisplay = AxWin3_Widget_AddWidget(ele, ELETYPE_TEXT, ELEFLAG_NOSTRETCH, "Time"); + AxWin3_Widget_SetSize(gTimeDisplay, 20); + //AxWin3_Widget_SetText(gTimeDisplay, "--:--"); + update_time(); // Turn off decorations AxWin3_DecorateWindow(gSidebar, 0); @@ -109,6 +112,13 @@ void create_sidebar(void) } +void update_time(void) +{ + char tmpbuf[2+1+2+1] = "--:--"; + //strftime(tmpbuf, sizeof(tmpbuf), "%H:%M", NULL); + AxWin3_Widget_SetText(gTimeDisplay, tmpbuf); +} + void mainmenu_app_textedit(void *unused) { // _SysDebug("TODO: Launch text editor"); diff --git a/Usermode/Applications/init_src/main.c b/Usermode/Applications/init_src/main.c index 3d960282..87eccde4 100644 --- a/Usermode/Applications/init_src/main.c +++ b/Usermode/Applications/init_src/main.c @@ -258,7 +258,7 @@ int ProcessInittab(const char *Path) // stty [78][NOE][012][bB] char path_seg[32+1]; char modespec[4+6+1]; - if( fscanf(fp, "%32s %6s ", path_seg, modespec) != 2 ) { + if( fscanf(fp, "%32s %10s ", path_seg, modespec) != 2 ) { goto lineError; } char **command = ReadCommand(fp); @@ -271,8 +271,14 @@ int ProcessInittab(const char *Path) // - Runs a daemon (respawning) that logs to the specified files // - Will append a header whenever the daemon starts char *stdout_path = ReadQuotedString(fp); + if( !stdout_path ) + goto lineError; char *stderr_path = ReadQuotedString(fp); + if( !stderr_path ) + goto lineError; char **command = ReadCommand(fp); + if( !command ) + goto lineError; AddDaemon(stdout_path, stderr_path, command); } @@ -368,8 +374,9 @@ int AddSerialTerminal(const char *DevPathSegment, const char *ModeStr, char **Co int baud; // Parse mode string - if( sscanf(ModeStr, "%1[78]%1[NOE]%1[012]%*1[bB]%d", &dbit, &parity, &sbit, &baud) != 5 ) { + if( sscanf(ModeStr, "%1[78]%1[NOE]%1[012]%*1[bB]%d", &dbit, &parity, &sbit, &baud) != 4 ) { // Oops? + _SysDebug("Serial mode string is invalid ('%s')", ModeStr); return -1; } @@ -436,6 +443,11 @@ int SpawnSTerm(tInitProgram *Program) int in = _SysOpen(Program->TypeInfo.STerm.Path, OPENFLAG_READ); int out = _SysOpen(Program->TypeInfo.STerm.Path, OPENFLAG_WRITE); + if(in == -1 || out == -1 ) { + _SysDebug("Unable to open serial '%s' for '%s'", Program->TypeInfo.STerm.Path, Program->Command); + return -1; + } + #if 0 if( _SysIOCtl(in, 0, NULL) != DRV_TYPE_SERIAL ) { @@ -462,6 +474,13 @@ int SpawnDaemon(tInitProgram *Program) return -2; } + // Log spawn header + { + char buffer[101]; + size_t len = snprintf(buffer, 100, "[%i] init spawning '%s'\n", _SysTimestamp(), Program->Command); + _SysWrite(out, buffer, len); + } + return SpawnCommand(in, out, err, Program->Command); } diff --git a/Usermode/Filesystem/Conf/inittab b/Usermode/Filesystem/Conf/inittab index cf075847..98b7bbef 100644 --- a/Usermode/Filesystem/Conf/inittab +++ b/Usermode/Filesystem/Conf/inittab @@ -1,8 +1,10 @@ exec /Acess/SBin/dhcpc +daemon /Devices/null /Devices/null /Acess/SBin/telnetd + ktty 0 /Acess/SBin/login ktty 1 /Acess/SBin/login -stty serial/0 /Acess/SBin/login +stty serial/0 8N1b115200 /Acess/SBin/login # vim: ft=text diff --git a/Usermode/Libraries/ld-acess.so_src/arch/syscalls.s.h b/Usermode/Libraries/ld-acess.so_src/arch/syscalls.s.h index 78d34bf7..c7a7215c 100644 --- a/Usermode/Libraries/ld-acess.so_src/arch/syscalls.s.h +++ b/Usermode/Libraries/ld-acess.so_src/arch/syscalls.s.h @@ -42,6 +42,7 @@ SYSCALL3(_SysSetMemFlags, SYS_SETFLAGS) // uint32_t SysSetMemFlags(uint addr, ui SYSCALL2(_SysOpen, SYS_OPEN) // char*, int SYSCALL3(_SysOpenChild, SYS_OPENCHILD) // int, char*, int SYSCALL3(_SysReopen, SYS_REOPEN) // int, char*, int +SYSCALL2(_SysCopyFD, SYS_COPYFD) // int, int SYSCALL1(_SysClose, SYS_CLOSE) // int SYSCALL3(_SysRead, SYS_READ) // int, uint, void* SYSCALL3(_SysWrite, SYS_WRITE) // int, uint, void* diff --git a/Usermode/Libraries/ld-acess.so_src/loadlib.c b/Usermode/Libraries/ld-acess.so_src/loadlib.c index dcacd8a8..53073019 100644 --- a/Usermode/Libraries/ld-acess.so_src/loadlib.c +++ b/Usermode/Libraries/ld-acess.so_src/loadlib.c @@ -24,6 +24,7 @@ extern const struct { } caLocalExports[]; extern const int ciNumLocalExports; extern char **gEnvP; +extern char gLinkedBase[]; // === GLOABLS === tLoadedLib gLoadedLibraries[MAX_LOADED_LIBRARIES]; @@ -108,6 +109,15 @@ void *IsFileLoaded(const char *file) { int i; DEBUGS("IsFileLoaded: (file='%s')", file); + + // Applications link against either libld-acess.so or ld-acess.so + if( strcmp(file, "/Acess/Libs/libld-acess.so") == 0 + || strcmp(file, "/Acess/Libs/ld-acess.so") == 0 ) + { + DEBUGS("IsFileLoaded: Found local (%p)", &gLinkedBase); + return &gLinkedBase; + } + for( i = 0; i < MAX_LOADED_LIBRARIES; i++ ) { if(gLoadedLibraries[i].Base == 0) break; // Last entry has Base set to NULL @@ -217,7 +227,7 @@ int GetSymbol(const char *name, void **Value, size_t *Size) } // Entry 0 is ld-acess, ignore it - for(i = 1; i < MAX_LOADED_LIBRARIES; i ++) + for(i = 0; i < MAX_LOADED_LIBRARIES; i ++) { if(gLoadedLibraries[i].Base == 0) break; diff --git a/Usermode/Libraries/ld-acess.so_src/main.c b/Usermode/Libraries/ld-acess.so_src/main.c index 985f9c8c..e379a70a 100644 --- a/Usermode/Libraries/ld-acess.so_src/main.c +++ b/Usermode/Libraries/ld-acess.so_src/main.c @@ -12,7 +12,6 @@ void *DoRelocate(void *base, char **envp, const char *Filename); // === Imports === extern char gLinkedBase[]; -extern tLoadedLib gLoadedLibraries[]; char **gEnvP; extern int memcmp(const void *m1, const void *m2, size_t size); @@ -41,10 +40,6 @@ void *SoMain(void *base, int argc, char **argv, char **envp) for(;;); } - gLoadedLibraries[0].Base = &gLinkedBase; - // 'libld-acess.so' because that is what applications link against - gLoadedLibraries[0].Name = "/Acess/Libs/libld-acess.so"; - // Otherwise do relocations //ret = DoRelocate( base, envp, "Executable" ); ret = DoRelocate( base, NULL, "Executable" ); diff --git a/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h b/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h index 090b06bf..67ca3519 100644 --- a/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h +++ b/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h @@ -3,6 +3,7 @@ enum { EOK, ENOSYS, // Invalid Instruction EINVAL, // Invalid Paramater + EBADF, // Bad FD ENOMEM, // No free memory EACCES, // Not permitted EBUSY, // Resource is busy @@ -16,6 +17,11 @@ enum { ENOTDIR, // Not a directory EIO, // IO Error EINTR, // Operation interrupted (signal) + ENODEV, // ??? + EADDRNOTAVAIL, // ? + EINPROGRESS, // ? + + EAGAIN, // Try again EALREADY, // Operation was a NOP EINTERNAL, // Internal Error diff --git a/Usermode/Libraries/libc.so_src/include_exp/signal.h b/Usermode/Libraries/libc.so_src/include_exp/signal.h index bf03c7f1..da6d78fd 100644 --- a/Usermode/Libraries/libc.so_src/include_exp/signal.h +++ b/Usermode/Libraries/libc.so_src/include_exp/signal.h @@ -13,11 +13,25 @@ typedef void (*sighandler_t)(int); #define SIG_DFL ((void*)0) #define SIG_ERR ((void*)-1) +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 #define SIGABRT 6 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGSEGV 11 +//#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGUSR1 16 +#define SIGUSR2 17 #define SIGPIPE 1001 #define SIGCHLD 1002 +extern sighandler_t signal(int signum, sighandler_t handler); + extern int raise(int sig); #endif diff --git a/Usermode/Libraries/libc.so_src/stdio.c b/Usermode/Libraries/libc.so_src/stdio.c index 8f7ede00..d03231c3 100644 --- a/Usermode/Libraries/libc.so_src/stdio.c +++ b/Usermode/Libraries/libc.so_src/stdio.c @@ -389,6 +389,11 @@ size_t _fwrite_unbuffered(FILE *fp, size_t size, size_t num, const void *data) while( num -- ) { bytes = _SysWrite(fp->FD, data, size); + if( bytes == (size_t)-1 ) { + // Oops. + // TODO: Set error flag + break; + } if( bytes != size ) { _SysDebug("_fwrite_unbuffered: Oops, rollback %i/%i bytes!", bytes, size); _SysSeek(fp->FD, -bytes, SEEK_CUR); diff --git a/Usermode/Libraries/libposix.so_src/include_exp/fcntl.h b/Usermode/Libraries/libposix.so_src/include_exp/fcntl.h index ded9ba1e..daababb4 100644 --- a/Usermode/Libraries/libposix.so_src/include_exp/fcntl.h +++ b/Usermode/Libraries/libposix.so_src/include_exp/fcntl.h @@ -9,15 +9,15 @@ #ifndef _FCNTL_H_ #define _FCNTL_H_ -#include +//#include // Hacks to handle different behaviors in Acess // Open doesn't take a chmod -#define open(_1,_2,...) open(_1, _2) +//#define open(_1,_2,...) open(_1, _2) // Close returns void -#define close(_1) (close(_1),0) +//#define close(_1) (close(_1),0) // Acess doesn't implement lseek #define lseek(_1,_2,_3) (seek(_1,_2,_3),tell(_1)) @@ -27,7 +27,7 @@ enum e_fcntl_cmds F_SETFL }; -int fcntl(int fd, int cmd, ...) { return -1; } +static inline int fcntl(int fd __attribute__((unused)), int cmd __attribute__((unused)), ...) { return -1; } #endif diff --git a/Usermode/Libraries/libposix.so_src/include_exp/pwd.h b/Usermode/Libraries/libposix.so_src/include_exp/pwd.h index 66b157f9..ae4bf077 100644 --- a/Usermode/Libraries/libposix.so_src/include_exp/pwd.h +++ b/Usermode/Libraries/libposix.so_src/include_exp/pwd.h @@ -17,6 +17,7 @@ struct passwd gid_t pw_gid; char *pw_dir; char *pw_shell; + char *pw_passwd; }; extern struct passwd *getpwnam(const char *); diff --git a/Usermode/Libraries/libposix.so_src/include_exp/sys/ioctl.h b/Usermode/Libraries/libposix.so_src/include_exp/sys/ioctl.h new file mode 100644 index 00000000..16cdd40a --- /dev/null +++ b/Usermode/Libraries/libposix.so_src/include_exp/sys/ioctl.h @@ -0,0 +1,14 @@ +/* + * Acess2 POSIX Emulation + * - By John Hodge (thePowersGang) + * + * ioctl.h + * - IOCtl hacks + */ +#ifndef _LIBPOSIX__IOCTL_H_ +#define _LIBPOSIX__IOCTL_H_ + + + +#endif + diff --git a/Usermode/Libraries/libposix.so_src/include_exp/sys/select.h b/Usermode/Libraries/libposix.so_src/include_exp/sys/select.h index c33ccb13..cf2f1aaf 100644 --- a/Usermode/Libraries/libposix.so_src/include_exp/sys/select.h +++ b/Usermode/Libraries/libposix.so_src/include_exp/sys/select.h @@ -9,6 +9,7 @@ #define _SYS__SELECT_H_ #include +#include extern int select(int nfds, fd_set *readfds, fd_set *writefds, struct timeval *timeout); // TODO: pselect? diff --git a/Usermode/Libraries/libposix.so_src/include_exp/sys/stat.h b/Usermode/Libraries/libposix.so_src/include_exp/sys/stat.h index 3e9f4303..c5749281 100644 --- a/Usermode/Libraries/libposix.so_src/include_exp/sys/stat.h +++ b/Usermode/Libraries/libposix.so_src/include_exp/sys/stat.h @@ -18,8 +18,12 @@ typedef uint64_t blkcnt_t; typedef unsigned int nlink_t; typedef uint32_t mode_t; +#ifndef uid_t typedef uint32_t uid_t; +#endif +#ifndef gid_t typedef uint32_t gid_t; +#endif #define S_IFMT 0170000 /* type of file */ #define S_IFDIR 0040000 /* directory */ diff --git a/Usermode/Libraries/libposix.so_src/include_exp/sys/wait.h b/Usermode/Libraries/libposix.so_src/include_exp/sys/wait.h index d37f5e5d..73e83f2a 100644 --- a/Usermode/Libraries/libposix.so_src/include_exp/sys/wait.h +++ b/Usermode/Libraries/libposix.so_src/include_exp/sys/wait.h @@ -8,6 +8,8 @@ #ifndef _LIBPOSIX__SYS__WAIT_H_ #define _LIBPOSIX__SYS__WAIT_H_ +#include + // POSIX, waitpid() #define WNOHANG 0x01 #define WUNTRACED 0x02 diff --git a/Usermode/Libraries/libposix.so_src/include_exp/termios.h b/Usermode/Libraries/libposix.so_src/include_exp/termios.h index e29ff4cf..a200f2c4 100644 --- a/Usermode/Libraries/libposix.so_src/include_exp/termios.h +++ b/Usermode/Libraries/libposix.so_src/include_exp/termios.h @@ -12,18 +12,113 @@ typedef unsigned char cc_t; typedef unsigned long speed_t; typedef unsigned short tcflag_t; -enum { +// c_iflag +#define IGNBRK (1 << 0) +#define BRKINT (1 << 1) +#define IGNPAR (1 << 2) // Ignore parity failures +#define PARMRK (1 << 3) // Mark parity failures with FFh 00h +#define INPCK (1 << 4) // Enable input parity checks +#define ISTRIP (1 << 5) // strip 8th bit +#define INLCR (1 << 6) // Translate input newline into CR +#define IGNCR (1 << 7) // Ignore input CR +#define ICRNL (1 << 8) // Translate input CR into NL +// (Linux) IUCLC // Map upper to lower case +#define IXON (1 <<10) // Enable input XON/XOFF +#define IXANY (1 <<11) // Any character will restart input +#define IXOFF IXON +// (Linux) IMAXBEL +// (Linux) IUTF8 + +// c_oflag +#define OPOST (1 << 0) // Output processing +// (Linux) OLCUC +#define ONLCR (1 << 2) // (XSI) NL->CR +#define OCRNL (1 << 3) // CR->NL +#define ONOCR (1 << 4) // Don't output CR at column 0 +#define ONLRET (1 << 5) // Don't output CR +#define OFILL (1 << 6) // Send fill chars for a delay, instead of timing +// (Linux) OFDEL +#define NLDLY (1 << 8) // Newline delay mask (NL0/NL1) +#define NL0 (0 << 8) +#define NL1 (1 << 8) +#define NCDLY (3 << 9) // Carriage return delay mask (CR0-CR3) +#define CR0 (0 << 9) +#define CR1 (1 << 9) +#define CR2 (2 << 9) +#define CR3 (3 << 9) +#define TABDLY (3 << 11) // Horizontal tab delay mask +#define TAB0 (0 << 11) +#define TAB1 (1 << 11) +#define TAB2 (2 << 11) +#define TAB3 (3 << 11) +#define BSDLY (1 << 13) // Backspace delay +#define BS0 (0 << 13) +#define BS1 (1 << 13) +#define VTDLY (1 << 14) // Vertical tab delay +#define VT0 (0 << 14) +#define VT1 (1 << 14) +#define FFDLY (1 << 15) // Form feed delay +#define FF0 (0 << 15) +#define VFF1 (1 << 15) + +// c_cflag +#define CBAUD (037 << 0) // Baud speed +#define CSIZE (3 << 5) // Character size mask +#define CS5 (0 << 5) +#define CS6 (1 << 5) +#define CS7 (2 << 5) +#define CS8 (3 << 5) +#define CSTOPB (1 << 7) // 1/2 stop bits +#define CREAD (1 << 8) // Enable receiver +#define PARENB (1 << 9) // Enable parity generation / checking +#define PARODD (1 << 10) // Odd parity +#define HUPCL (1 << 11) // Hang up on close +#define CLOCAL (1 << 12) // Ignore modem control lines +// LOBLK +// CIBAUD +// CMSPAR +// CRTSCTS + +// c_lflag +#define ISIG (1 << 0) // Generate signals for INTR, QUIT, SUSP and DSUSP +#define ICANON (1 << 1) // Input canonical mode +// XCASE +#define ECHO (1 << 3) // Echo input characters +#define ECHOE (1 << 4) // Enable ERASE and WERASE on echoed input [ICANON] +#define ECHOK (1 << 5) // Enable KILL char on echoed input [ICANON] +#define ECHONL (1 << 6) // Echo NL even if ECHO is unset [ICANON] +#define ECHOCTL (1 << 7) // (non-POSIX) If ECHO set specials are echoed as val+0x40 (BS=^H) +// ECHOPRT +#define ECHOKE (1 << 9) // (non-POSIX) KILL implimented by sequential erase [ICANON] +// DEFECHO +// FLUSHO +#define NOFLSH (1 << 11) // Disable flush of IO when generating INT, QUIT and SUSP +#define TOSTOP (1 << 12) // ? +// PENDIN +#define IEXTEN (1 << 14) + +// - Indexes for c_cc +enum +{ + VDISCARD, + VDSUSP, VEOF, VEOL, + VEOL2, VERASE, VINTR, VKILL, + VLNEXT, VMIN, VQUIT, + // VREPRINT, // (non-POSIX) VSTART, + // VSTATUS, // (non-POSIX) VSTOP, VSUSP, + // VSWITCH, // (non-POSIX) VTIME, + VWERASE, NCCS }; diff --git a/Usermode/Libraries/libposix.so_src/include_exp/unistd.h b/Usermode/Libraries/libposix.so_src/include_exp/unistd.h index a2f397cc..ea107a9d 100644 --- a/Usermode/Libraries/libposix.so_src/include_exp/unistd.h +++ b/Usermode/Libraries/libposix.so_src/include_exp/unistd.h @@ -43,5 +43,7 @@ extern ssize_t read(int fd, void *buf, size_t count); extern int fork(void); extern int execv(const char *b, char *v[]); +extern int dup2(int oldfd, int newfd); + #endif diff --git a/Usermode/Libraries/libposix.so_src/unistd.c b/Usermode/Libraries/libposix.so_src/unistd.c index c1d4908d..68c4e522 100644 --- a/Usermode/Libraries/libposix.so_src/unistd.c +++ b/Usermode/Libraries/libposix.so_src/unistd.c @@ -10,6 +10,11 @@ #include // === CODE === +int unlink(const char *pathname) +{ + return _SysUnlink(pathname); +} + int open(const char *path, int openmode, ...) { mode_t create_mode = 0; @@ -60,6 +65,16 @@ ssize_t read(int fd, void *buf, size_t count) return _SysRead(fd, buf, count); } +int seek(int fd, int whence, off_t dest) +{ + return _SysSeek(fd, whence, dest); +} + +off_t tell(int fd) +{ + return _SysTell(fd); +} + int fork(void) { return _SysClone(CLONE_VM, 0); @@ -69,3 +84,10 @@ int execv(const char *b, char *v[]) { return _SysExecVE(b, v, NULL); } + +int dup2(int oldfd, int newfd) +{ + // NOTE: Acess's CopyFD doesn't cause offset sharing + return _SysCopyFD(oldfd, newfd); +} + diff --git a/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c b/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c index 57120f0d..c26ce321 100644 --- a/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c +++ b/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c @@ -126,6 +126,45 @@ void freeaddrinfo(struct addrinfo *res) } +int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) +{ + // Determine hostname + if( host ) + { + if( hostlen == 0 ) + return EAI_OVERFLOW; + host[0] = '\0'; + if( !(flags & NI_NUMERICHOST) ) + { + // Handle NI_NOFQDN + } + // Numeric hostname or the hostname was unresolvable + if( host[0] == '\0' ) + { + if( (flags & NI_NAMEREQD) ) + return EAI_NONAME; + } + } + + // Determine service name + if( serv ) + { + if( servlen == 0 ) + return EAI_OVERFLOW; + serv[0] = '\0'; + if( !(flags & NI_NUMERICSERV) ) + { + // Handle NI_DGRAM + } + if( serv[0] == '\0' ) + { + + } + } + return EAI_SUCCESS; +} + + const char *gai_strerror(int errnum) { switch(errnum) diff --git a/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h b/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h index e9cf7883..09681812 100644 --- a/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h +++ b/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h @@ -8,6 +8,12 @@ #define AI_ADDRCONFIG 0x004 #define AI_NUMERICHOST 0x008 +#define NI_NAMEREQD (1<<0) +#define NI_DGRAM (1<<1) +#define NI_NOFQDN (1<<2) +#define NI_NUMERICHOST (1<<3) +#define NI_NUMERICSERV (1<<4) + enum { EAI_SUCCESS, @@ -22,7 +28,8 @@ enum EAI_NODATA, EAI_NONAME, EAI_SERVICE, - EAI_SYSTEM + EAI_SYSTEM, + EAI_OVERFLOW }; struct addrinfo @@ -37,6 +44,7 @@ struct addrinfo struct addrinfo *ai_next; }; +extern int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); extern int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); extern void freeaddrinfo(struct addrinfo *res); const char *gai_strerror(int errorcode); diff --git a/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h b/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h index 33e78659..3a289ebf 100644 --- a/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h +++ b/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h @@ -1,3 +1,10 @@ +/* + * Acess2 POSIX Sockets Emulation + * - By John Hodge (thePowersGang) + * + * netinet/in.h + * - ?Addressing? + */ #ifndef _LIBPSOCKET__NETINET__IN_H_ #define _LIBPSOCKET__NETINET__IN_H_ diff --git a/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/ip.h b/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/ip.h new file mode 100644 index 00000000..433b16db --- /dev/null +++ b/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/ip.h @@ -0,0 +1,12 @@ +/* + * Acess2 POSIX Sockets Emulation + * - By John Hodge (thePowersGang) + * + * netinet/ip.h + * - ??? + */ +#ifndef _LIBPSOCKET__NETINET__IP_H_ +#define _LIBPSOCKET__NETINET__IP_H_ + +#endif + diff --git a/Usermode/Libraries/libpsocket.so_src/include_exp/sys/socket.h b/Usermode/Libraries/libpsocket.so_src/include_exp/sys/socket.h index 4d2a1c23..70eafd18 100644 --- a/Usermode/Libraries/libpsocket.so_src/include_exp/sys/socket.h +++ b/Usermode/Libraries/libpsocket.so_src/include_exp/sys/socket.h @@ -9,7 +9,9 @@ #define _SYS_SOCKETS_H_ #include +#ifndef size_t #include // size_t +#endif #include // uint32_t typedef uint32_t socklen_t; @@ -93,7 +95,16 @@ enum enum { SO_REUSEADDR, - SO_LINGER + SO_LINGER, + SO_ERROR +}; + +// shutdown how +enum +{ + SHUT_RD, + SHUT_WR, + SHUT_RDWR }; /** @@ -102,6 +113,11 @@ enum */ extern int socket(int domain, int type, int protocol); +/** + * + */ +extern int shutdown(int socket, int how); + /** * \brief Bind a socket to an address */ @@ -133,5 +149,12 @@ extern int getsockopt(int socket, int level, int option_name, void *option_value extern int getsockname(int socket, struct sockaddr *addr, socklen_t *addrlen); extern int getpeername(int socket, struct sockaddr *addr, socklen_t *addrlen); +extern struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type); +extern void sethostent(int stayopen); +extern void endhostent(void); +extern void herror(const char *s); +extern const char *hstrerror(int err); +extern struct hostent *gethostent(void); + #endif