Merge branch 'master' of github.com:thepowersgang/acess2
authorJohn Hodge (sonata) <[email protected]>
Fri, 3 May 2013 03:14:48 +0000 (11:14 +0800)
committerJohn Hodge (sonata) <[email protected]>
Fri, 3 May 2013 03:14:48 +0000 (11:14 +0800)
Conflicts:
KernelLand/Kernel/arch/x86/acpica.c

35 files changed:
BuildConf/x86/default.mk
KernelLand/Kernel/arch/x86/acpica.c
KernelLand/Kernel/arch/x86/mboot.c
KernelLand/Kernel/arch/x86/mm_virt.c
KernelLand/Modules/IPStack/include/adapters_api.h
KernelLand/Modules/IPStack/link.c
KernelLand/Modules/Network/E1000/e1000.c
KernelLand/Modules/Network/E1000/e1000.h
KernelLand/Modules/Network/E1000/e1000_hw.h [new file with mode: 0644]
KernelLand/Modules/Network/PCnetFAST3/pcnet-fast3.c
RunQemu
Tools/GCCProxy/gccproxy.sh
Usermode/Applications/axwin3_src/Interface/main.c
Usermode/Applications/init_src/main.c
Usermode/Filesystem/Conf/inittab
Usermode/Libraries/ld-acess.so_src/arch/syscalls.s.h
Usermode/Libraries/ld-acess.so_src/loadlib.c
Usermode/Libraries/ld-acess.so_src/main.c
Usermode/Libraries/libc.so_src/include_exp/errno.enum.h
Usermode/Libraries/libc.so_src/include_exp/signal.h
Usermode/Libraries/libc.so_src/stdio.c
Usermode/Libraries/libposix.so_src/include_exp/fcntl.h
Usermode/Libraries/libposix.so_src/include_exp/pwd.h
Usermode/Libraries/libposix.so_src/include_exp/sys/ioctl.h [new file with mode: 0644]
Usermode/Libraries/libposix.so_src/include_exp/sys/select.h
Usermode/Libraries/libposix.so_src/include_exp/sys/stat.h
Usermode/Libraries/libposix.so_src/include_exp/sys/wait.h
Usermode/Libraries/libposix.so_src/include_exp/termios.h
Usermode/Libraries/libposix.so_src/include_exp/unistd.h
Usermode/Libraries/libposix.so_src/unistd.c
Usermode/Libraries/libpsocket.so_src/getaddrinfo.c
Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h
Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h
Usermode/Libraries/libpsocket.so_src/include_exp/netinet/ip.h [new file with mode: 0644]
Usermode/Libraries/libpsocket.so_src/include_exp/sys/socket.h

index f4423eb..bbe5d2f 100644 (file)
@@ -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
index a7a0883..1534789 100644 (file)
@@ -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;
 }
 
index 7403f38..08331a1 100644 (file)
@@ -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;
index e04b4ae..13562f2 100644 (file)
@@ -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;
 }
index 7872998..60e7eb4 100644 (file)
@@ -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)
 
index c4f716f..d92504b 100644 (file)
@@ -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],
index b225d3d..644d694 100644 (file)
@@ -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)
 #include <modules.h>
 #include <drv_pci.h>
 #include <IPStack/include/adapters_api.h>
+#include <timers.h>    // 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);
 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;
 }
index d8b864f..2a0eb8e 100644 (file)
@@ -8,6 +8,45 @@
 #ifndef _E1000_H_
 #define _E1000_H_
 
+#include "e1000_hw.h"
+
+#include <semaphore.h>
+#include <mutex.h>
+#include <IPStack/include/buffer.h>
+
+#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 (file)
index 0000000..cd182eb
--- /dev/null
@@ -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
+
index 06c783a..7105b02 100644 (file)
@@ -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 db5306a..c34d963 100755 (executable)
--- 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
index 477c476..0dd6864 100755 (executable)
@@ -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
 
index a098614..5f323e4 100644 (file)
@@ -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");
index 3d96028..87eccde 100644 (file)
@@ -258,7 +258,7 @@ int ProcessInittab(const char *Path)
                        // stty <devpath> [78][NOE][012][bB]<baud> <command...>
                        char    path_seg[32+1];
                        char    modespec[4+6+1];
-                       if( fscanf(fp, "%32s %6s ", path_seg, modespec) != 2 ) {
+                       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);
 }
 
index cf07584..98b7bbe 100644 (file)
@@ -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
index 78d34bf..c7a7215 100644 (file)
@@ -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*
index dcacd8a..5307301 100644 (file)
@@ -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;
index 985f9c8..e379a70 100644 (file)
@@ -12,7 +12,6 @@ void  *DoRelocate(void *base, char **envp, const char *Filename);
 \r
 // === Imports ===\r
 extern char    gLinkedBase[];\r
-extern tLoadedLib      gLoadedLibraries[];\r
 char   **gEnvP;\r
 extern int     memcmp(const void *m1, const void *m2, size_t size);\r
  \r
@@ -41,10 +40,6 @@ void *SoMain(void *base, int argc, char **argv, char **envp)
                for(;;);\r
        }\r
 \r
-       gLoadedLibraries[0].Base = &gLinkedBase;\r
-       // 'libld-acess.so' because that is what applications link against\r
-       gLoadedLibraries[0].Name = "/Acess/Libs/libld-acess.so";\r
-       \r
        // Otherwise do relocations\r
        //ret = DoRelocate( base, envp, "Executable" );\r
        ret = DoRelocate( base, NULL, "Executable" );\r
index 090b06b..67ca351 100644 (file)
@@ -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
index bf03c7f..da6d78f 100644 (file)
@@ -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
index 8f7ede0..d03231c 100644 (file)
@@ -389,6 +389,11 @@ size_t _fwrite_unbuffered(FILE *fp, size_t size, size_t num, const void *data)
        while( num -- )\r
        {\r
                bytes = _SysWrite(fp->FD, data, size);\r
+               if( bytes == (size_t)-1 ) {\r
+                       // Oops.\r
+                       // TODO: Set error flag\r
+                       break;\r
+               }\r
                if( bytes != size ) {\r
                        _SysDebug("_fwrite_unbuffered: Oops, rollback %i/%i bytes!", bytes, size);\r
                        _SysSeek(fp->FD, -bytes, SEEK_CUR);\r
index ded9ba1..daababb 100644 (file)
@@ -9,15 +9,15 @@
 #ifndef _FCNTL_H_
 #define _FCNTL_H_
 
-#include <sys/sys.h>
+//#include <sys/sys.h>
 
 // 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
 
index 66b157f..ae4bf07 100644 (file)
@@ -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 (file)
index 0000000..16cdd40
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * ioctl.h
+ * - IOCtl hacks
+ */
+#ifndef _LIBPOSIX__IOCTL_H_
+#define _LIBPOSIX__IOCTL_H_
+
+
+
+#endif
+
index c33ccb1..cf2f1aa 100644 (file)
@@ -9,6 +9,7 @@
 #define _SYS__SELECT_H_
 
 #include <acess/fd_set.h>
+#include <sys/time.h>
 
 extern int select(int nfds, fd_set *readfds, fd_set *writefds, struct timeval *timeout);
 // TODO: pselect?
index 3e9f430..c574928 100644 (file)
@@ -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 */
index d37f5e5..73e83f2 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef _LIBPOSIX__SYS__WAIT_H_
 #define _LIBPOSIX__SYS__WAIT_H_
 
+#include <sys/types.h>
+
 // POSIX, waitpid()
 #define        WNOHANG 0x01
 #define WUNTRACED      0x02
index e29ff4c..a200f2c 100644 (file)
@@ -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
 };
 
index a2f397c..ea107a9 100644 (file)
@@ -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
 
index c1d4908..68c4e52 100644 (file)
 #include <stdarg.h>
 
 // === 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);
+}
+
index 57120f0..c26ce32 100644 (file)
@@ -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)
index e9cf788..0968181 100644 (file)
@@ -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);
index 33e7865..3a289eb 100644 (file)
@@ -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 (file)
index 0000000..433b16d
--- /dev/null
@@ -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
+
index 4d2a1c2..70eafd1 100644 (file)
@@ -9,7 +9,9 @@
 #define _SYS_SOCKETS_H_
 
 #include <sys/types.h>
+#ifndef size_t
 #include <stddef.h>    // size_t
+#endif
 #include <stdint.h>    // 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
 

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