Adding several modules to the Tree, plus some files that escaped earlier
authorJohn Hodge <[email protected]>
Tue, 10 Nov 2009 05:21:38 +0000 (13:21 +0800)
committerJohn Hodge <[email protected]>
Tue, 10 Nov 2009 05:21:38 +0000 (13:21 +0800)
- Added the in-progress IP Stack
- Added the in-progress USB Stack
- Added module's linker script
- Added tpl_drv_terminal.h (Terminal Emulator defintions)
- Added libreadline (my own version)
- Added Usermode/stddef.h

24 files changed:
Kernel/include/tpl_drv_terminal.h [new file with mode: 0644]
Modules/IPStack/Makefile [new file with mode: 0644]
Modules/IPStack/arp.c [new file with mode: 0644]
Modules/IPStack/arp.h [new file with mode: 0644]
Modules/IPStack/icmp.c [new file with mode: 0644]
Modules/IPStack/icmp.h [new file with mode: 0644]
Modules/IPStack/ipstack.h [new file with mode: 0644]
Modules/IPStack/ipv4.c [new file with mode: 0644]
Modules/IPStack/ipv4.h [new file with mode: 0644]
Modules/IPStack/ipv6.c [new file with mode: 0644]
Modules/IPStack/ipv6.h [new file with mode: 0644]
Modules/IPStack/link.c [new file with mode: 0644]
Modules/IPStack/link.h [new file with mode: 0644]
Modules/IPStack/main.c [new file with mode: 0644]
Modules/IPStack/tcp.c [new file with mode: 0644]
Modules/IPStack/tcp.h [new file with mode: 0644]
Modules/USB/Makefile [new file with mode: 0644]
Modules/USB/main.c [new file with mode: 0644]
Modules/USB/uhci.c [new file with mode: 0644]
Modules/USB/uhci.h [new file with mode: 0644]
Modules/USB/usb.h [new file with mode: 0644]
Modules/link.ld [new file with mode: 0644]
Usermode/Libraries/libreadline.so_src/main.c [new file with mode: 0644]
Usermode/include/stddef.h [new file with mode: 0644]

diff --git a/Kernel/include/tpl_drv_terminal.h b/Kernel/include/tpl_drv_terminal.h
new file mode 100644 (file)
index 0000000..639d181
--- /dev/null
@@ -0,0 +1,104 @@
+/**\r
+ * \file tpl_drv_terminal.h\r
+ * \brief Terminal Driver Interface Definitions\r
+*/\r
+#ifndef _TPL_TERMINAL_H\r
+#define _TPL_TERMINAL_H\r
+\r
+#include <tpl_drv_common.h>\r
+\r
+/**\r
+ * \enum eTplTerminal_IOCtl\r
+ * \brief Common Terminal IOCtl Calls\r
+ * \extends eTplDrv_IOCtl\r
+ */\r
+enum eTplTerminal_IOCtl {\r
+       /**\r
+        * ioctl(..., int *mode)\r
+        * \brief Get/Set the current video mode type\r
+        * see ::eTplTerminal_Modes\r
+        * \note If the mode is set the mode is changed at this call\r
+       */\r
+       TERM_IOCTL_MODETYPE = 4,\r
+       \r
+       /**\r
+        * ioctl(..., int *width)\r
+        * \brief Get/set the display width\r
+        * \param width Pointer to an integer containing the new width\r
+        * \return Current width\r
+        * \r
+        * Set `width` to NULL to just return the current width\r
+        */\r
+       TERM_IOCTL_WIDTH,\r
+       \r
+       /**\r
+        * ioctl(..., int *height)\r
+        * \brief Get/set the display height\r
+        * \param height        Pointer to an integer containing the new height\r
+        * \return Current height\r
+        * \r
+        * Set \a height to NULL to just return the current height\r
+        */\r
+       TERM_IOCTL_HEIGHT,\r
+       \r
+       /**\r
+        * ioctl(..., tTerm_IOCtl_Mode *info)\r
+        * \brief Queries the current driver about it's modes\r
+        * \param info  A pointer to a ::tTerm_IOCtl_Mode with .ID set to the mode index\r
+        * \return Number of modes\r
+        * \r
+        * \a info can be NULL\r
+        */\r
+       TERM_IOCTL_QUERYMODE\r
+};\r
+\r
+typedef struct sTerm_IOCtl_Mode        tTerm_IOCtl_Mode;\r
+\r
+/**\r
+ * \brief Virtual Terminal Mode\r
+ * Describes a VTerm mode to the caller of ::TERM_IOCTL_QUERYMODE\r
+ */\r
+struct sTerm_IOCtl_Mode\r
+{\r
+       short   ID;             //!< Zero Based index of mode\r
+       short   DriverID;       //!< Driver's ID number (from ::tVideo_IOCtl_Mode)\r
+       Uint16  Height; //!< Height\r
+       Uint16  Width;  //!< Width\r
+       Uint8   Depth;  //!< Bits per cell\r
+       struct {\r
+               unsigned bText: 1;      //!< Text Mode marker\r
+               unsigned unused:        7;\r
+       };\r
+};\r
+\r
+/**\r
+ * \brief Terminal Modes\r
+ */\r
+enum eTplTerminal_Modes {\r
+       /**\r
+        * \brief UTF-8 Text Mode\r
+        * Any writes to the terminal file are treated as UTF-8 encoded\r
+        * strings and reads will also return UTF-8 strings.\r
+        */\r
+       TERM_MODE_TEXT,\r
+       \r
+       /**\r
+        * \brief 32bpp Framebuffer\r
+        * Writes to the terminal file will write to the framebuffer.\r
+        * Reads will return UTF-32 characters\r
+        */\r
+       TERM_MODE_FB,\r
+       \r
+       /**\r
+        * \brief OpenGL 2D/3D\r
+        * Writes to the terminal file will send 3D commands\r
+        * Reads will return UTF-32 characters\r
+        * \note May or may not stay in the spec\r
+        */\r
+       TERM_MODE_OPENGL,\r
+       \r
+       NUM_TERM_MODES\r
+};\r
+\r
+\r
+#endif\r
diff --git a/Modules/IPStack/Makefile b/Modules/IPStack/Makefile
new file mode 100644 (file)
index 0000000..6226f4f
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = main.o link.o arp.o ipv4.o ipv6.o
+NAME = IPStack
+
+-include ../Makefile.tpl
diff --git a/Modules/IPStack/arp.c b/Modules/IPStack/arp.c
new file mode 100644 (file)
index 0000000..cc194e9
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Acess2 IP Stack
+ * - Address Resolution Protocol
+ */
+#include "ipstack.h"
+#include "arp.h"
+#include "link.h"
+
+#define        ARP_CACHE_SIZE  64
+
+// === IMPORTS ===
+extern tInterface      *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast);
+extern tInterface      *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broadcast);
+
+// === PROTOTYPES ===
+ int   ARP_Initialise();
+ int   ARP_int_Resolve4(tInterface *Interface, tIPv4 Address);
+void   ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer);
+
+// === GLOBALS ===
+struct sARP_Cache {
+       tMacAddr        MAC;
+       tIPv4   IP4;
+       tIPv6   IP6;
+       Sint64  LastUpdate;
+}      *gaARP_Cache;
+ int   giARP_CacheSpace;
+
+// === CODE ===
+/**
+ * \fn int ARP_Initialise()
+ * \brief Initalise the ARP section
+ */
+int ARP_Initialise()
+{
+       gaARP_Cache = malloc( ARP_CACHE_SIZE * sizeof(*gaARP_Cache) );
+       memset( gaARP_Cache, 0, ARP_CACHE_SIZE * sizeof(*gaARP_Cache) );
+       giARP_CacheSpace = ARP_CACHE_SIZE;
+       
+       Link_RegisterType(0x0806, ARP_int_GetPacket);
+       return 1;
+}
+
+/**
+ * \fn int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address)
+ * \brief Request the network to resolve an IPv4 Address
+ * \return Boolean Success
+ */
+int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address)
+{
+       struct sArpRequest4     req;
+       
+       req.HWType = htons(0x100);      // Ethernet
+       req.Type   = htons(0x0800);
+       req.HWSize = 6;
+       req.SWSize = 4;
+       req.Request = htons(1);
+       req.SourceMac = Interface->Adapter->MacAddr;
+       req.SourceIP = Interface->IP4.Address;
+       req.DestMac = cMAC_BROADCAST;
+       req.DestIP = Address;
+       
+       Link_SendPacket(Interface->Adapter, 0x0806, req.DestMac, sizeof(struct sArpRequest4), &req);
+       
+       return 0;
+}
+
+/**
+ * \fn void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer)
+ * \brief Called when an ARP packet is recieved
+ */
+void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer)
+{
+        int    i, free = -1;
+        int    oldest = 0;
+       tArpRequest4    *req4 = Buffer;
+       tArpRequest6    *req6 = Buffer;
+       tInterface      *iface;
+       
+       // Sanity Check Packet
+       if( Length < sizeof(tArpRequest4) ) {
+               Log("[ARP  ] Recieved undersized packet");
+               return ;
+       }
+       if( ntohs(req4->Type) != 0x0800 ) {
+               Log("[ARP  ] Recieved a packet with a bad type 0x%x", ntohs(req4->Type));
+               return ;
+       }
+       if( req4->HWSize != 6 ) {
+               Log("[ARP  ] Recieved a packet with HWSize != 6 (%i)", req4->HWSize);
+               return;
+       }
+       if( !MAC_EQU(req4->SourceMac, From) ) {
+               Log("[ARP  ] ARP spoofing detected", req4->HWSize);
+               return;
+       }
+       
+       switch( req4->Request )
+       {
+       case 1: // You want my IP?
+               // Check what type of IP it is
+               switch( req4->SWSize )
+               {
+               case 4:
+                       iface = IPv4_GetInterface(Adapter, req4->DestIP, 0);
+                       if( iface )
+                       {
+                               IP4_SET(req4->DestIP, req4->SourceIP);
+                               req4->DestMac = req4->SourceMac;
+                               req4->SourceIP = iface->IP4.Address;
+                               req4->SourceMac = Adapter->MacAddr;
+                               req4->Request = htons(2);
+                               Link_SendPacket(Adapter, 0x0806, req4->DestMac, sizeof(tArpRequest4), req4);
+                       }
+                       break;
+               case 6:
+                       if( Length < sizeof(tArpRequest6) ) {
+                               Log("[ARP  ] Recieved undersized packet (IPv6)");
+                               return ;
+                       }
+                       iface = IPv6_GetInterface(Adapter, req6->DestIP, 0);
+                       if( iface )
+                       {
+                               req6->DestIP = req6->SourceIP;
+                               req6->DestMac = req6->SourceMac;
+                               req6->SourceIP = iface->IP6.Address;
+                               req6->SourceMac = Adapter->MacAddr;
+                               req6->Request = htons(2);
+                               Link_SendPacket(Adapter, 0x0806, req6->DestMac, sizeof(tArpRequest6), req6);
+                       }
+                       break;
+               default:
+                       Log("[ARP  ] Unknown Protocol Address size (%i)", req4->SWSize);
+                       return ;
+               }
+               
+               break;
+       
+       case 2: // Ooh! A response!
+               // Find an entry for the MAC address in the cache
+               for( i = giARP_CacheSpace; i--; )
+               {
+                       if(gaARP_Cache[oldest].LastUpdate > gaARP_Cache[i].LastUpdate) {
+                               oldest = i;
+                       }
+                       if( MAC_EQU(gaARP_Cache[i].MAC, From) ) break;
+                       if( gaARP_Cache[i].LastUpdate == 0 && free==-1 )        free = i;
+               }
+               if(i + 1 == 0) {
+                       if(free != -1)
+                               i = free;
+                       else
+                               i = oldest;
+               }
+               
+               // Check what type of IP it is
+               switch( req4->SWSize )
+               {
+               case 4:
+                       gaARP_Cache[i].IP4 = req4->SourceIP;
+                       break;
+               case 6:
+                       if( Length < sizeof(tArpRequest6) ) {
+                               Log("[ARP  ] Recieved undersized packet (IPv6)");
+                               return ;
+                       }
+                       gaARP_Cache[i].IP6 = req6->SourceIP;
+                       break;
+               default:
+                       Log("[ARP  ] Unknown Protocol Address size (%i)", req4->SWSize);
+                       return ;
+               }
+               
+               gaARP_Cache[i].LastUpdate = now();
+               break;
+       }
+}
diff --git a/Modules/IPStack/arp.h b/Modules/IPStack/arp.h
new file mode 100644 (file)
index 0000000..64f07c3
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Acess2 IP Stack
+ * - Common Header
+ */
+#ifndef _ARP_H_
+#define _ARP_H_
+
+#include "ipstack.h"
+
+typedef struct sArpRequest4    tArpRequest4;
+typedef struct sArpRequest6    tArpRequest6;
+
+struct sArpRequest4 {
+       Uint16  HWType;
+       Uint16  Type;
+       Uint8   HWSize, SWSize;
+       Uint16  Request;
+       tMacAddr        SourceMac;
+       tIPv4   SourceIP;
+       tMacAddr        DestMac;
+       tIPv4   DestIP;
+};
+
+struct sArpRequest6 {
+       Uint16  HWType;
+       Uint16  Type;
+       Uint8   HWSize, SWSize;
+       Uint16  Request;
+       tMacAddr        SourceMac;
+       tIPv6   SourceIP;
+       tMacAddr        DestMac;
+       tIPv6   DestIP;
+};
+
+#endif
diff --git a/Modules/IPStack/icmp.c b/Modules/IPStack/icmp.c
new file mode 100644 (file)
index 0000000..bd9c05f
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Acess2 IP Stack
+ * - ICMP Handling
+ */
+#include "ipstack.h"
+#include "icmp.h"
+
+// === PROTOTYPES ===
+void   ICMP_Initialise();
+void   ICMP_GetPacket(tInterface *Interface, int Length, void *Buffer);
+
+// === GLOBALS ===
+
+// === CODE ===
+/**
+ * \fn void ICMP_Initialise()
+ * \brief Initialise the ICMP Layer
+ */
+void ICMP_Initialise()
+{
+       
+}
+
+/**
+ * \fn void ICMP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer)
+ * \brief Handles a packet from the IP Layer
+ */
+void ICMP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer)
+{
+       tICMPHeader     *hdr = Buffer;
+       
+}
diff --git a/Modules/IPStack/icmp.h b/Modules/IPStack/icmp.h
new file mode 100644 (file)
index 0000000..73a641f
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Acess2 IP Stack
+ * - ICMP Handling
+ */
+#ifndef _ICMP_H_
+#define _ICMP_H_
+
+// === TYPEDEFS ===
+typedef struct sICMPHeader     tICMPHeader;
+
+// === STRUCTURES ===
+struct sICMPHeader
+{
+       Uint8   Type;
+       Uint8   Code;
+       Uint16  Checksum;
+       Uint16  ID;
+       Uint16  Sequence;
+};
+
+#endif
diff --git a/Modules/IPStack/ipstack.h b/Modules/IPStack/ipstack.h
new file mode 100644 (file)
index 0000000..8b846ab
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Acess2 IP Stack
+ * - Common Header
+ */
+#ifndef _IPSTACK_H_
+#define _IPSTACK_H_
+
+#include <common.h>
+#include <vfs.h>
+
+typedef union uIPv4    tIPv4;
+typedef union uIPv6    tIPv6;
+typedef struct sMacAddr        tMacAddr;
+typedef struct sAdapter        tAdapter;
+typedef struct sInterface      tInterface;
+
+typedef void   (*tIPCallback)(tInterface *Interface, void *Address, int Length, void *Buffer);
+
+union uIPv4 {
+       Uint32  L;
+       Uint8   B[4];
+};
+
+union uIPv6 {
+       Uint32  L[4];
+       Uint8   B[16];
+};
+
+struct sMacAddr {
+       Uint8   B[6];
+};
+
+struct sInterface {
+       struct sInterface       *Next;
+       tVFS_Node       Node;
+       tAdapter        *Adapter;
+        int    Type;   // 4 for IPv4 and 6 for IPv6
+       union {
+               struct  {
+                       tIPv6   Address;
+                        int    SubnetBits;
+               }       IP6;
+               
+               struct {
+                       tIPv4   Address;
+                       tIPv4   Gateway;
+                        int    SubnetBits;
+               }       IP4;
+       };
+};
+
+/**
+ * \brief Represents a network adapter
+ */
+struct sAdapter {
+       struct sAdapter *Next;
+       char    *Device;
+        int    DeviceFD;
+       
+       tMacAddr        MacAddr;
+       
+       tInterface      *Interfaces;
+};
+
+static const tMacAddr cMAC_BROADCAST = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
+
+#define MAC_SET(t,v)   memcpy(&(t),&(v),sizeof(tMacAddr))
+#define IP4_SET(t,v)   (t).L = (v).L;
+#define IP6_SET(t,v)   memcpy(&(t),&(v),sizeof(tIPv6))
+
+#define MAC_EQU(a,b)   memcmp(&(a),&(b),sizeof(tMacAddr))
+#define IP4_EQU(a,b)   ((a).L==(b).L)
+#define IP6_EQU(a,b)   memcmp(&(a),&(b),sizeof(tIPv6))
+
+// === FUNCTIONS ===
+#define htonb(v)       (v)
+#define htons(in)      BigEndian16(in)
+#define htonl(in)      BigEndian32(in)
+#define ntonb(v)       (v)
+#define ntohs(in)      BigEndian16(in)
+#define ntohl(in)      BigEndian16(in)
+
+#endif
diff --git a/Modules/IPStack/ipv4.c b/Modules/IPStack/ipv4.c
new file mode 100644 (file)
index 0000000..d57b124
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Acess2 IP Stack
+ * - IPv4 Protcol Handling
+ */
+#include "ipstack.h"
+#include "link.h"
+#include "ipv4.h"
+
+// === PROTOTYPES ===
+ int   IPv4_Initialise();
+void   IPv4_int_GetPacket(tAdapter *Interface, tMacAddr From, int Length, void *Buffer);
+tInterface     *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast);
+Uint32 IPv4_Netmask(int FixedBits);
+
+// === GLOBALS ===
+tIPCallback    gaIPv4_Callbacks[256];
+
+// === CODE ===
+/**
+ * \fn int IPv4_Initialise()
+ */
+int IPv4_Initialise()
+{
+       Link_RegisterType(IPV4_ETHERNET_ID, IPv4_int_GetPacket);
+       return 1;
+}
+
+/**
+ * \fn void IPv4_int_GetPacket(tInterface *Adapter, tMacAddr From, int Length, void *Buffer)
+ * \brief Process an IPv4 Packet
+ */
+void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer)
+{
+       tIPv4Header     *hdr = Buffer;
+       tInterface      *iface;
+       char    *data;
+        int    dataLength;
+       if(Length < sizeof(tIPv4Header))        return;
+       
+       // Check that the version IS IPv4
+       if(hdr->Version != 4)   return;
+       
+       // Check Header checksum
+       //TODO
+       
+       // Check Packet length
+       if(hdr->TotalLength > Length)   return;
+       
+       // Get Interface (allowing broadcasts)
+       iface = IPv4_GetInterface(Adapter, hdr->Source, 1);
+       if(!iface)      return; // Not for us? Well, let's ignore it
+       
+       // Defragment
+       //TODO
+       
+       dataLength = hdr->TotalLength - sizeof(tIPv4Header);
+       data = &hdr->Options[0];
+       
+       // Send it on
+       gaIPv4_Callbacks[hdr->Protocol] (iface, &hdr->Source, dataLength, data);
+}
+
+/**
+ * \fn tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address)
+ * \brief Searches an adapter for a matching address
+ */
+tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast)
+{
+       tInterface      *iface = NULL;
+       Uint32  netmask;
+       
+       for( iface = Adapter->Interfaces; iface; iface = iface->Next)
+       {
+               if( iface->Type != 4 )  continue;
+               if( IP4_EQU(Address, iface->IP4.Address) )
+                       return iface;
+               
+               if( !Broadcast )        continue;
+               
+               // Check for broadcast
+               netmask = IPv4_Netmask(iface->IP4.SubnetBits);
+               if( (Address.L & netmask) == (iface->IP4.Address.L & netmask)
+                && (Address.L & ~netmask) == (0xFFFFFFFF & ~netmask) )
+                       return iface;
+       }
+       return NULL;
+}
+
+/**
+ * \brief Convert a network prefix to a netmask
+ * 
+ * For example /24 will become 255.255.255.0
+ */
+Uint32 IPv4_Netmask(int FixedBits)
+{
+       Uint32  ret = 0xFFFFFFFF;
+       ret >>= (32-FixedBits);
+       ret <<= (32-FixedBits);
+       return ret;
+}
diff --git a/Modules/IPStack/ipv4.h b/Modules/IPStack/ipv4.h
new file mode 100644 (file)
index 0000000..67b3dc8
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Acess2 IP Stack
+ * - IPv4 Definitions
+ */
+#ifndef _IPV4_H_
+#define _IPV4_H_
+
+#include "ipstack.h"
+
+typedef struct sIPv4Header     tIPv4Header;
+
+struct sIPv4Header
+{
+       struct {
+               unsigned Version:       4;      // = 4
+               unsigned HeaderLength:  4;      // in 4-byte chunks
+       };
+       Uint8   DiffServices;   // Differentiated Services
+       Uint16  TotalLength;
+       Uint16  Identifcation;
+       
+       struct {
+               unsigned Reserved:      1;
+               unsigned DontFragment:  1;
+               unsigned MoreFragments: 1;
+               unsigned FragOffLow:    5;
+       };
+       Uint8   FragOffHi;      // Number of 8-byte blocks from the original start
+       
+       Uint8   TTL;    // Max number of hops effectively
+       Uint8   Protocol;
+       Uint16  HeaderChecksum; // One's Complement Sum of the entire header must equal zero
+       
+       tIPv4   Source;
+       tIPv4   Destination;
+       
+       Uint8   Options[];
+};
+
+#define IP4PROT_ICMP   1
+#define IP4PROT_TCP    6
+#define IP4PROT_UDP    17
+
+#define IPV4_ETHERNET_ID       0x0800
+
+#endif
diff --git a/Modules/IPStack/ipv6.c b/Modules/IPStack/ipv6.c
new file mode 100644 (file)
index 0000000..31aedcb
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Acess2 IP Stack
+ * - IPv6 Protcol Handling
+ */
+#include "ipstack.h"
+#include "link.h"
+#include "ipv6.h"
+
+// === IMPORTS ===
+extern Uint32  IPv4_Netmask(int FixedBits);
+
+// === PROTOTYPES ===
+ int   IPv6_Initialise();
+void   IPv6_int_GetPacket(tAdapter *Interface, tMacAddr From, int Length, void *Buffer);
+tInterface     *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broadcast);
+
+// === CODE ===
+/**
+ * \fn int IPv6_Initialise()
+ */
+int IPv6_Initialise()
+{
+       Link_RegisterType(IPV6_ETHERNET_ID, IPv6_int_GetPacket);
+       return 1;
+}
+
+/**
+ * \fn void IPv6_int_GetPacket(tInterface *Interface, tMacAddr From, int Length, void *Buffer)
+ * \brief Process an IPv6 Packet
+ */
+void IPv6_int_GetPacket(tAdapter *Interface, tMacAddr From, int Length, void *Buffer)
+{
+       tIPv6Header     *hdr = Buffer;
+       if(Length < sizeof(tIPv6Header))        return;
+       
+       if(hdr->Version != 6)   return;
+}
+
+/**
+ * \fn tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address)
+ * \brief Searches an adapter for a matching address
+ */
+tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broadcast)
+{
+        int    i, j;
+       tInterface      *iface = NULL;
+       Uint32  netmask;
+       
+       for( iface = Adapter->Interfaces; iface; iface = iface->Next)
+       {
+               // Skip non-IPv6 Interfaces
+               if( iface->Type != 6 )  continue;
+               
+               // If the address is a perfect match, return this interface
+               if( IP6_EQU(Address, iface->IP6.Address) )      return iface;
+               
+               // Check if we want to match broadcast addresses
+               if( !Broadcast )        continue;
+               
+               // Check for broadcast
+               if( iface->IP6.SubnetBits > 32 && Address.L[0] != iface->IP6.Address.L[0] )
+                       continue;
+               if( iface->IP6.SubnetBits > 64 && Address.L[1] != iface->IP6.Address.L[1] )
+                       continue;
+               if( iface->IP6.SubnetBits > 96 && Address.L[2] != iface->IP6.Address.L[2] )
+                       continue;
+               
+               j = iface->IP6.SubnetBits / 32;
+               i = iface->IP6.SubnetBits % 32;
+               netmask = IPv4_Netmask( iface->IP6.SubnetBits % 32 );
+               
+               // Check the last bit of the netmask
+               if( (Address.L[j] >> i) != (iface->IP6.Address.L[j] >> i) )     continue;
+               
+               // Check that the host portion is one
+               if( (Address.L[j] & ~netmask) != (0xFFFFFFFF & ~netmask) )      continue;
+               if( j >= 2 && Address.L[3] != 0xFFFFFFFF)       continue;
+               if( j >= 1 && Address.L[2] != 0xFFFFFFFF)       continue;
+               if( j >= 0 && Address.L[1] != 0xFFFFFFFF)       continue;
+               
+               return iface;
+       }
+       return NULL;
+}
diff --git a/Modules/IPStack/ipv6.h b/Modules/IPStack/ipv6.h
new file mode 100644 (file)
index 0000000..a98561d
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Acess2 IP Stack
+ * - IPv6 Definitions
+ */
+#ifndef _IPV6_H_
+#define _IPV6_H_
+
+#include "ipstack.h"
+
+typedef struct sIPv6Header     tIPv6Header;
+
+struct sIPv6Header
+{
+       struct {
+               unsigned Version:       4;
+               unsigned TrafficClass:  8;
+               unsigned FlowLabel:     20;
+       };
+       Uint16  PayloadLength;
+       Uint8   NextHeader;     // Type of payload data
+       Uint8   HopLimit;
+       tIPv6   Source;
+       tIPv6   Destination;
+};
+
+#define IPV6_ETHERNET_ID       0x86DD
+
+#endif
diff --git a/Modules/IPStack/link.c b/Modules/IPStack/link.c
new file mode 100644 (file)
index 0000000..fb21984
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Acess2 IP Stack
+ * - Link/Media Layer Interface
+ */
+#include "ipstack.h"
+#include "link.h"
+
+// === CONSTANTS ===
+#define        MAX_PACKET_SIZE 2048
+
+// === GLOBALS ===
+ int   giRegisteredTypes = 0;
+struct {
+       Uint16  Type;
+       tPacketCallback Callback;
+}      *gaRegisteredTypes;
+
+// === CODE ===
+/**
+ * \fn void Link_RegisterType(Uint16 Type, tPacketCallback Callback)
+ * \brief Registers a callback for a specific packet type
+ */
+void Link_RegisterType(Uint16 Type, tPacketCallback Callback)
+{
+        int    i;
+       void    *tmp;
+       for( i = giRegisteredTypes; i -- ; )
+       {
+               if(gaRegisteredTypes[i].Type == Type) {
+                       Warning("[NET  ] Attempt to register 0x%x twice", Type);
+                       return ;
+               }
+               // Ooh! Free slot!
+               if(gaRegisteredTypes[i].Callback == NULL)       break;
+       }
+       
+       if(i + 1 == 0)
+       {
+               tmp = realloc(gaRegisteredTypes, (giRegisteredTypes+1)*sizeof(*gaRegisteredTypes));
+               if(!tmp)        Panic("[NET  ] Out of heap space!");
+               i = giRegisteredTypes;
+               giRegisteredTypes ++;
+               gaRegisteredTypes = tmp;
+       }
+       
+       gaRegisteredTypes[i].Callback = Callback;
+       gaRegisteredTypes[i].Type = Type;
+}
+
+/**
+ * \fn void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, int Length, void *Buffer)
+ * \brief Formats and sends a packet on the specified interface
+ */
+void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, int Length, void *Buffer)
+{
+        int    bufSize = sizeof(tEthernetHeader) + Length;
+       Uint8   buf[bufSize];
+       tEthernetHeader *hdr = (void*)buf;
+       
+       hdr->Dest = To;
+       hdr->Src = Adapter->MacAddr;
+       hdr->Type = htons(Type);
+       
+       memcpy(hdr->Data, Buffer, Length);
+       
+       VFS_Write(Adapter->DeviceFD, bufSize, buf);
+}
+
+/**
+ * \fn void Link_WatchDevice(tAdapter *Adapter)
+ * \brief Spawns a worker thread to watch the specified adapter
+ */
+void Link_WatchDevice(tAdapter *Adapter)
+{
+        int    tid = Proc_SpawnWorker();       // Create a new worker thread
+       
+       if(tid < 0) {
+               Panic("[NET  ] Unable to create watcher thread for '%s'", Adapter->Device);
+       }
+       
+       if(tid > 0) {
+               Log("[NET  ] Watching '%s' using tid %i", Adapter->Device, tid);
+               return ;
+       }
+       
+       // Child Thread
+       while(Adapter->DeviceFD != -1)
+       {
+               Uint8   buf[MAX_PACKET_SIZE];
+               tEthernetHeader *hdr = (void*)buf;
+                int    ret, i;
+               
+               // Wait for a packet
+               ret = VFS_Read(Adapter->DeviceFD, MAX_PACKET_SIZE, buf);
+               if(ret == -1)   break;
+               
+               if(ret <= sizeof(tEthernetHeader)) {
+                       Log("[NET  ] Recieved an undersized packet");
+                       continue;
+               }
+               
+               // Check if there is a registered callback for this packet type
+               for( i = giRegisteredTypes; i--; )
+               {
+                       if(gaRegisteredTypes[i].Type == hdr->Type)      continue;
+               }
+               // No? Ignore it
+               if( i + 1 == 0 )        continue;
+               
+               // Call the callback
+               gaRegisteredTypes[i].Callback(
+                       Adapter,
+                       hdr->Src,
+                       ret - sizeof(tEthernetHeader),
+                       hdr->Data
+                       );
+       }
+}
diff --git a/Modules/IPStack/link.h b/Modules/IPStack/link.h
new file mode 100644 (file)
index 0000000..c662f14
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Acess2 IP Stack
+ * - Link/Media Layer Header
+ */
+#ifndef _LINK_H_
+#define _LINK_H_
+
+// === EXTERNAL ===
+typedef void (*tPacketCallback)(tAdapter *Interface, tMacAddr From, int Length, void *Buffer);
+
+extern void    Link_RegisterType(Uint16 Type, tPacketCallback Callback);
+extern void    Link_SendPacket(tAdapter *Interface, Uint16 Type, tMacAddr To, int Length, void *Buffer);
+
+// === INTERNAL ===
+typedef struct sEthernetHeader tEthernetHeader;
+typedef struct sEthernetFooter tEthernetFooter;
+struct sEthernetHeader {
+       tMacAddr        Dest;
+       tMacAddr        Src;
+       Uint16  Type;
+       Uint8   Data[];
+};
+
+struct sEthernetFooter {
+       //Uint32        CRC;
+};
+
+#endif
diff --git a/Modules/IPStack/main.c b/Modules/IPStack/main.c
new file mode 100644 (file)
index 0000000..aaeeb9a
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Acess2 IP Stack
+ * - Address Resolution Protocol
+ */
+#include "ipstack.h"
+#include <modules.h>
+#include <fs_devfs.h>
+
+// === IMPORTS ===
+ int   ARP_Initialise();
+
+// === PROTOTYPES ===
+ int   IPStack_Install(char **Arguments);
+char   *IPStack_ReadDir(tVFS_Node *Node, int Pos);
+tVFS_Node      *IPStack_FindDir(tVFS_Node *Node, char *Name);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, 0x000A, IPStack, IPStack_Install, NULL);
+tDevFS_Driver  gIP_DriverInfo = {
+       NULL, "ip",
+       {
+       .NumACLs = 1,
+       .ACLs = &gVFS_ACL_EveryoneRX,
+       .Flags = VFS_FFLAG_DIRECTORY,
+       .ReadDir = IPStack_ReadDir,
+       .FindDir = IPStack_FindDir
+       }
+};
+ int   giIP_NumInterfaces;
+tInterface     *gIP_Interfaces = NULL;
+
+// === CODE ===
+/**
+ * \fn int IPStack_Install(char **Arguments)
+ * \brief Intialise the relevant parts of the stack and register with DevFS
+ */
+int IPStack_Install(char **Arguments)
+{
+        int    i = 0;
+       
+       // Install Handlers
+       ARP_Initialise();
+       
+       // Parse module arguments
+       for( i = 0; Arguments[i]; i++ )
+       {
+               //if(strcmp(Arguments[i], "Device") == '=') {
+               //      
+               //}
+       }
+       
+       return 1;
+}
+
+/**
+ * \brief Read from the IP Stack's Device Directory
+ */
+char *IPStack_ReadDir(tVFS_Node *Node, int Pos)
+{
+       tInterface      *iface;
+       char    name[5] = "ip0\0\0";
+       
+       // Create the name
+       if(Pos < 10)
+               name[2] = '0' + Pos;
+       else {
+               name[2] = '0' + Pos/10;
+               name[3] = '0' + Pos%10;
+       }
+       
+       // Traverse the list
+       for( iface = gIP_Interfaces; iface && Pos--; iface = iface->Next ) ;
+       
+       // Did we run off the end?
+       if(!iface)      return NULL;
+       
+       // Return the pre-generated name
+       return strdup(name);
+}
+
+/**
+ * \brief Get the node of an interface
+ */
+tVFS_Node *IPStack_FindDir(tVFS_Node *Node, char *Name)
+{
+       return NULL;
+}
diff --git a/Modules/IPStack/tcp.c b/Modules/IPStack/tcp.c
new file mode 100644 (file)
index 0000000..b8c1758
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Acess2 IP Stack
+ * - TCP Handling
+ */
+#include "ipstack.h"
+#include "tcp.h"
+
+#define TCP_MIN_DYNPORT        0x1000
+
+// === PROTOTYPES ===
+void   TCP_Initialise();
+void   *TCP_Open(tInterface *Interface, Uint16 LocalPort, void *Address, Uint16 Port);
+void   TCP_GetPacket(tInterface *Interface, int Length, void *Buffer);
+Uint16 TCP_GetUnusedPort();
+ int   TCP_AllocatePort(Uint16 Port);
+ int   TCP_DeallocatePort(Uint16 Port);
+
+// === GLOBALS ===
+ int   giTCP_NumHalfopen = 0;
+tTCPListener   *gTCP_Listeners;
+tTCPConnection *gTCP_OutbountCons;
+Uint32 gaTCP_PortBitmap[0x800];
+ int   giTCP_NextOutPort = TCP_MIN_DYNPORT;
+
+// === CODE ===
+/**
+ * \fn void TCP_Initialise()
+ * \brief Initialise the TCP Layer
+ */
+void TCP_Initialise()
+{
+       
+}
+
+/**
+ * \fn void *TCP_Open(tInterface *Interface, Uint16 LocalPort, void *Address, Uint16 Port)
+ * \brief Open a connection to another host using TCP
+ */
+void *TCP_Open(tInterface *Interface, Uint16 LocalPort, void *Address, Uint16 Port)
+{
+       tTCPConnection  *ret = malloc( sizeof(tTCPConnection) );
+       
+       ret->State = TCP_ST_CLOSED;
+       if(LocalPort == 0)
+               ret->LocalPort = TCP_GetUnusedPort();
+       else
+               ret->LocalPort = LocalPort;
+       ret->RemotePort = Port;
+       
+       ret->LocalInterface = Interface;
+       
+       if(Interface->Type == 6)
+               ret->RemoteIP.v6 = *(tIPv6*)Address;
+       else
+               ret->RemoteIP.v4 = *(tIPv4*)Address;
+       
+       // SEND PACKET
+       
+       return ret;
+}
+
+/**
+ * \fn void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer)
+ * \brief Handles a packet from the IP Layer
+ */
+void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer)
+{
+       tTCPHeader      *hdr = Buffer;
+       tTCPListener    *srv;
+       tTCPConnection  *conn;
+       
+       // Check Servers
+       {
+               for( srv = gTCP_Listeners; srv; srv = srv->Next )
+               {
+                       // Check the interface
+                       if(srv->Interface && srv->Interface != Interface)       continue;
+                       // Check the destination port
+                       if(srv->Port != hdr->DestPort)  continue;
+                       
+                       // Is this in an established connection?
+                       for( conn = srv->Connections; conn; conn = conn->Next )
+                       {
+                               // Check that it is coming in on the same interface
+                               if(conn->Interface != Interface)        continue;
+                               
+                               // Check Source Port
+                               if(conn->RemotePort != hdr->SourcePort) continue;
+                               
+                               // Check Source IP
+                               if(conn->Interface->Type == 6 && !IP6_EQU(conn->RemoteIP.v6, *(tIPv6*)Address))
+                                       continue;
+                               if(conn->Interface->Type == 4 && !IP4_EQU(conn->RemoteIP.v4, *(tIPv4*)Address))
+                                       continue;
+                               
+                               // We have a response!
+                               //TODO
+                               
+                               return;
+                       }
+                       
+                       // Open a new connection
+                       //TODO
+                       
+                       break;
+               }
+       }
+       
+       
+       // Check Open Connections
+       {
+               for( conn = gTCP_OutbountCons; conn; conn = conn->Next )
+               {
+                       // TODO
+               }
+       }
+}
+
+/**
+ * \fn Uint16 TCP_GetUnusedPort()
+ * \brief Gets an unused port and allocates it
+ */
+Uint16 TCP_GetUnusedPort()
+{
+       Uint16  ret;
+       
+       // Get Next outbound port
+       ret = giTCP_NextOutPort++;
+       while( gaTCP_PortBitmap[ret/32] & (1 << (ret%32)) )
+       {
+               ret ++;
+               giTCP_NextOutPort++;
+               if(giTCP_NextOutPort == 0x10000) {
+                       ret = giTCP_NextOutPort = TCP_MIN_DYNPORT;
+               }
+       }
+       
+       // Mark the new port as used
+       gaTCP_PortBitmap[ret/32] |= 1 << (ret%32);
+       
+       return ret;
+}
+
+/**
+ * \fn int TCP_AllocatePort(Uint16 Port)
+ * \brief Marks a port as used
+ */
+int TCP_AllocatePort(Uint16 Port)
+{
+       // Check if the port has already been allocated
+       if( gaTCP_PortBitmap[Port/32] & (1 << (Port%32)) )
+               return 0;
+       
+       // Allocate
+       gaTCP_PortBitmap[Port/32] |= 1 << (Port%32);
+       
+       return 1;
+}
+
+/**
+ * \fn int TCP_DeallocatePort(Uint16 Port)
+ * \brief Marks a port as unused
+ */
+int TCP_DeallocatePort(Uint16 Port)
+{
+       // Check if the port has already been allocated
+       if( !(gaTCP_PortBitmap[Port/32] & (1 << (Port%32))) )
+               return 0;
+       
+       // Allocate
+       gaTCP_PortBitmap[Port/32] &= ~(1 << (Port%32));
+       
+       return 1;
+}
+
diff --git a/Modules/IPStack/tcp.h b/Modules/IPStack/tcp.h
new file mode 100644 (file)
index 0000000..fb515ac
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Acess2 IP Stack
+ * - TCP Definitions
+ */
+#ifndef _TCP_H_
+#define _TCP_H_
+
+#include "ipstack.h"
+
+typedef struct sTCPHeader      tTCPHeader;
+typedef struct sTCPListener    tTCPListener;
+typedef struct sTCPConnection  tTCPConnection;
+
+struct sTCPHeader
+{
+       Uint16  SourcePort;
+       Uint16  DestPort;
+       Uint32  SequenceNumber;
+       Uint32  AcknowlegementNumber;
+       struct {
+               unsigned DataOffset: 4; // Size of the header in 32-bit words
+               unsigned Reserved:      4;
+       };
+       struct {
+               unsigned CWR:   1;      // Congestion Window Reduced
+               unsigned ECE:   1;      // ECN-Echo
+               unsigned URG:   1;      // Urgent pointer is significant
+               unsigned ACK:   1;      // Acknowlegement field is significant
+               unsigned PSH:   1;      // Push Function
+               unsigned RST:   1;      // Reset Connection
+               unsigned SYN:   1;      // Synchronise Sequence Numbers
+               unsigned FIN:   1;      // Last packet
+       } Flags;
+       Uint16  WindowSize;
+       
+       Uint16  Checksum;
+       Uint16  UrgentPointer;
+       
+       Uint8   Options[];
+};
+
+struct sTCPListener
+{
+       struct sTCPListener     *Next;
+       Uint16  Port;
+       tInterface      *Interface;
+       tTCPConnection  *Connections;
+};
+
+struct sTCPConnection
+{
+       struct sTCPConnection   *Next;
+        int    State;
+       Uint16  LocalPort;
+       Uint16  RemotePort;
+       
+       tInterface      *LocalInterface;
+       union {
+               tIPv4   v4;
+               tIPv6   v6;
+       } RemoteIP;     // Type is determined by LocalInterface->Type
+};
+
+enum eTCPConnectionState
+{
+       TCP_ST_CLOSED,
+       TCP_ST_HALFOPEN,
+       TCP_ST_OPEN
+};
+
+#endif
diff --git a/Modules/USB/Makefile b/Modules/USB/Makefile
new file mode 100644 (file)
index 0000000..b4f400a
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = main.o uhci.o
+NAME = USB
+
+-include ../Makefile.tpl
diff --git a/Modules/USB/main.c b/Modules/USB/main.c
new file mode 100644 (file)
index 0000000..0bdcc24
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Acess2
+ * USB Stack
+ */
+#define VERSION        ( (0<<8)| 5 )
+#define DEBUG  1
+#include <common.h>
+#include <vfs.h>
+#include <fs_devfs.h>
+#include <modules.h>
+#include "usb.h"
+
+// === IMPORTS ===
+ int   UHCI_Initialise();
+
+// === PROTOTYPES ===
+ int   USB_Install(char **Arguments);
+void   USB_Cleanup();
+char   *USB_ReadDir(tVFS_Node *Node, int Pos);
+tVFS_Node      *USB_FindDir(tVFS_Node *Node, char *Name);
+ int   USB_IOCtl(tVFS_Node *Node, int Id, void *Data);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, VERSION, USB, USB_Install, NULL, NULL);
+tDevFS_Driver  gUSB_DrvInfo = {
+       NULL, "usb", {
+               .NumACLs = 1,
+               .ACLs = &gVFS_ACL_EveryoneRX,
+               .Flags = VFS_FFLAG_DIRECTORY,
+               .ReadDir = USB_ReadDir,
+               .FindDir = USB_FindDir,
+               .IOCtl = USB_IOCtl
+       }
+};
+tUSBDevice     *gUSB_Devices = NULL;
+tUSBHost       *gUSB_Hosts = NULL;
+
+// === CODE ===
+/**
+ * \fn int ModuleLoad()
+ * \brief Called once module is loaded
+ */
+int USB_Install(char **Arguments)
+{
+       UHCI_Initialise();
+       Warning("[USB  ] Not Complete - Devel Only");
+       return 0;
+}
+
+/**
+ * \fn void USB_Cleanup()
+ * \brief Called just before module is unloaded
+ */
+void USB_Cleanup()
+{
+}
+
+/**
+ * \fn char *USB_ReadDir(tVFS_Node *Node, int Pos)
+ * \brief Read from the USB root
+ */
+char *USB_ReadDir(tVFS_Node *Node, int Pos)
+{
+       return NULL;
+}
+
+/**
+ * \fn tVFS_Node *USB_FindDir(tVFS_Node *Node, char *Name)
+ * \brief Locate an entry in the USB root
+ */
+tVFS_Node *USB_FindDir(tVFS_Node *Node, char *Name)
+{
+       return NULL;
+}
+
+/**
+ * \fn int USB_IOCtl(tVFS_Node *Node, int Id, void *Data)
+ * \brief Handles IOCtl Calls to the USB driver
+ */
+int USB_IOCtl(tVFS_Node *Node, int Id, void *Data)
+{
+       return 0;
+}
diff --git a/Modules/USB/uhci.c b/Modules/USB/uhci.c
new file mode 100644 (file)
index 0000000..65037ef
--- /dev/null
@@ -0,0 +1,119 @@
+/*\r
+ * Acess 2 USB Stack\r
+ * Universal Host Controller Interface\r
+ */\r
+#define DEBUG  1\r
+#include <common.h>\r
+#include <vfs.h>\r
+#include <drv_pci.h>\r
+#include "usb.h"\r
+#include "uhci.h"\r
+\r
+// === CONSTANTS ===\r
+#define        MAX_CONTROLLERS 4\r
+#define NUM_TDs        1024\r
+\r
+// === PROTOTYPES ===\r
+ int   UHCI_Initialise();\r
+void   UHCI_Cleanup();\r
+ int   UHCI_IOCtl(tVFS_Node *node, int id, void *data);\r
+ int   UHCI_Int_InitHost(tUHCI_Controller *Host);\r
+\r
+// === GLOBALS ===
+//Uint gaFrameList[1024];\r
+tUHCI_TD       gaUHCI_TDPool[NUM_TDs];\r
+tUHCI_Controller       gUHCI_Controllers[MAX_CONTROLLERS];\r
+\r
+// === CODE ===\r
+/**\r
+ * \fn int UHCI_Initialise()\r
+ * \brief Called to initialise the UHCI Driver\r
+ */\r
+int UHCI_Initialise()\r
+{\r
+        int    i=0, id=-1;\r
+        int    ret;\r
+       Uint16  base;\r
+       \r
+       ENTER("");\r
+       \r
+       // Enumerate PCI Bus, getting a maximum of `MAX_CONTROLLERS` devices\r
+       while( (id = PCI_GetDeviceByClass(0x0C03, 0xFFFF, id)) >= 0 && i < MAX_CONTROLLERS )\r
+       {\r
+               gUHCI_Controllers[i].PciId = id;\r
+               // Assign a port range (BAR4, Reserve 32 ports)\r
+               base = PCI_AssignPort( id, 4, 0x20 );\r
+               gUHCI_Controllers[i].IOBase = base;\r
+               \r
+               LOG("Controller PCI #%i: IO Base = 0x%x", id, base);\r
+               \r
+               // Initialise Host\r
+               ret = UHCI_Int_InitHost(&gUHCI_Controllers[i]);\r
+               // Detect an error\r
+               if(ret != 0) {\r
+                       LEAVE('i', ret);\r
+                       return ret;\r
+               }\r
+               \r
+               i ++;\r
+       }\r
+       if(i == MAX_CONTROLLERS) {\r
+               Warning("[UHCI ] Over "EXPAND_STR(MAX_CONTROLLERS)" UHCI controllers detected, ignoring rest");\r
+       }\r
+       LEAVE('i', 0);\r
+       return 0;\r
+}\r
+\r
+/**\r
+ * \fn void UHCI_Cleanup()\r
+ * \brief Called just before module is unloaded\r
+ */\r
+void UHCI_Cleanup()\r
+{\r
+}
+
+/**
+ * \fn int UHCI_IOCtl(tVFS_Node *Node, int ID, void *Data)
+ */
+int UHCI_IOCtl(tVFS_Node *Node, int ID, void *Data)
+{
+       return 0;
+}\r
+\r
+// === INTERNAL FUNCTIONS ===\r
+/**\r
+ * \fn int UHCI_Int_InitHost(tUCHI_Controller *Host)\r
+ * \brief Initialises a UHCI host controller\r
+ * \param Host Pointer - Host to initialise\r
+ */\r
+int UHCI_Int_InitHost(tUHCI_Controller *Host)\r
+{\r
+       ENTER("pHost", Host);\r
+       \r
+       // Allocate Frame List\r
+       Host->FrameList = (void *) MM_AllocDMA(1, 32, &Host->PhysFrameList);    // 1 Page, 32-bit\r
+       if( !Host->FrameList ) {\r
+               Warning("[UHCI ] Unable to allocate frame list, aborting");\r
+               LEAVE('i', -1);\r
+               return -1;\r
+       }\r
+       LOG("Allocated frame list 0x%x (0x%x)", Host->FrameList, Host->PhysFrameList);\r
+       memsetd( Host->FrameList, 1, 1024 );    // Clear List (Disabling all entries)\r
+       \r
+       //! \todo Properly fill frame list\r
+       \r
+       // Set frame length to 1 ms\r
+       outb( Host->IOBase + SOFMOD, 64 );\r
+       \r
+       // Set Frame List Address\r
+       outd( Host->IOBase + FLBASEADD, Host->PhysFrameList );\r
+       \r
+       // Set Frame Number\r
+       outw( Host->IOBase + FRNUM, 0 );\r
+       \r
+       // Enable Interrupts\r
+       //PCI_WriteWord( Host->PciId, 0xC0, 0x2000 );\r
+       \r
+       LEAVE('i', 0);\r
+       return 0;\r
+}\r
diff --git a/Modules/USB/uhci.h b/Modules/USB/uhci.h
new file mode 100644 (file)
index 0000000..df7854b
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * AcessOS Version 1
+ * USB Stack
+ * - Universal Host Controller Interface
+ */
+#ifndef _UHCI_H_
+#define _UHCI_H_
+
+// === TYPES ===
+typedef struct sUHCI_Controller        tUHCI_Controller;
+typedef struct sUHCI_TD        tUHCI_TD;
+typedef struct sUHCI_QH        tUHCI_QH;
+
+// === STRUCTURES ===
+struct sUHCI_Controller
+{
+       /**
+        * \brief PCI Device ID
+        */
+       Uint16  PciId;
+       
+       /**
+        * \brief IO Base Address
+        */
+       Uint16  IOBase;
+       
+       /**
+        * \brief Frame list
+        * 
+        * 31:4 - Frame Pointer
+        * 3:2 - Reserved
+        * 1 - QH/TD Selector
+        * 0 - Terminate (Empty Pointer)
+        */
+       Uint32  *FrameList;
+       
+       /**
+        * \brief Physical Address of the Frame List
+        */
+       tPAddr  PhysFrameList;
+};
+
+struct sUHCI_TD
+{
+       /**
+        * \brief Next Entry in list
+        * 
+        * 31:4 - Address
+        * 3 - Reserved
+        * 2 - Depth/Breadth Select
+        * 1 - QH/TD Select
+        * 0 - Terminate (Last in List)
+        */
+       Uint32  Link;
+       
+       /**
+        * \brief Control and Status Field
+        * 
+        * 31:30 - Reserved
+        * 29 - Short Packet Detect (Input Only)
+        * 28:27 - Number of Errors Allowed
+        * 26 - Low Speed Device (Communicating with a low speed device)
+        * 25 - Isynchonious Select
+        * 24 - Interrupt on Completion (IOC)
+        * 23:16 - Status
+        *     23 - Active
+        *     22 - Stalled
+        *     21 - Data Buffer Error
+        *     20 - Babble Detected
+        *     19 - NAK Detected
+        *     18 - CRC/Timout Error
+        *     17 - Bitstuff Error
+        *     16 - Reserved
+        * 15:11 - Reserved
+        * 10:0 - Actual Length (Number of bytes transfered)
+        */
+       Uint32  Control;
+       
+       /**
+        * \brief Packet Header
+        * 
+        * 31:21 - Maximum Length (0=1, Max 0x4FF, 0x7FF=0)
+        * 20 - Reserved
+        * 19 - Data Toggle
+        * 18:15 - Endpoint
+        * 14:8 - Device Address
+        * 7:0 - PID (Packet Identifcation) - Only 96, E1, 2D allowed
+        */
+       Uint32  Token;
+       
+       /**
+        * \brief Pointer to the data to send
+        */
+       Uint32  BufferPointer;
+};
+
+struct sUHCI_QH
+{
+       /**
+        * \brief Next Entry in list
+        * 
+        * 31:4 - Address
+        * 3:2 - Reserved
+        * 1 - QH/TD Select
+        * 0 - Terminate (Last in List)
+        */
+       Uint32  Next;
+
+       
+       /**
+        * \brief Next Entry in list
+        * 
+        * 31:4 - Address
+        * 3:2 - Reserved
+        * 1 - QH/TD Select
+        * 0 - Terminate (Last in List)
+        */
+       Uint32  Child;
+};
+
+// === ENUMERATIONS ===
+enum eUHCI_IOPorts {
+       /**
+        * \brief USB Command Register
+        * 
+        * 15:8 - Reserved
+        * 7 - Maximum Packet Size selector (1: 64 bytes, 0: 32 bytes)
+        * 6 - Configure Flag (No Hardware Effect)
+        * 5 - Software Debug (Don't think it will be needed)
+        * 4 - Force Global Resume
+        * 3 - Enter Global Suspend Mode
+        * 2 - Global Reset (Resets all devices on the bus)
+        * 1 - Host Controller Reset (Reset just the controller)
+        * 0 - Run/Stop
+        */
+       USBCMD  = 0x00,
+       /**
+        * \brief USB Status Register
+        * 
+        * 15:6 - Reserved
+        * 5 - HC Halted, set to 1 when USBCMD:RS is set to 0
+        * 4 - Host Controller Process Error (Errors related to the bus)
+        * 3 - Host System Error (Errors related to the OS/PCI Bus)
+        * 2 - Resume Detect (Set if a RESUME command is sent to the Controller)
+        * 1 - USB Error Interrupt
+        * 0 - USB Interrupts (Set if a transaction with the IOC bit set is completed)
+        */
+       USBSTS  = 0x02,
+       /**
+        * \brief USB Interrupt Enable Register
+        * 
+        * 15:4 - Reserved
+        * 3 - Short Packet Interrupt Enable
+        * 2 - Interrupt on Complete (IOC) Enable
+        * 1 - Resume Interrupt Enable
+        * 0 - Timout / CRC Error Interrupt Enable
+        */
+       USBINTR = 0x04,
+       /**
+        * \brief Frame Number (Index into the Frame List)
+        * 
+        * 15:11 - Reserved
+        * 10:0 - Index (Incremented each approx 1ms)
+        */
+       FRNUM   = 0x06,
+       /**
+        * \brief Frame List Base Address
+        * 
+        * 31:12 - Pysical Address >> 12
+        * 11:0 - Reserved (Set to Zero)
+        */
+       FLBASEADD = 0x08,       // 32-bit
+       /**
+        * \brief Start-of-frame Modify Register
+        * \note 8-bits only
+        * 
+        * Sets the size of a frame
+        * Frequency = (11936+n)/12000 kHz
+        * 
+        * 7 - Reserved
+        * 6:0 -
+        */
+       SOFMOD = 0x0C,  // 8bit
+       /**
+        * \brief Port Status and Controll Register (Port 1)
+        * 
+        * 15:13 - Reserved
+        * 12 - Suspend
+        * 11:10 - Reserved
+        * 9 - Port Reset
+        * 8 - Low Speed Device Attached
+        * 5:4 - Line Status
+        * 3 - Port Enable/Disable Change - Used for detecting device removal
+        * 2 - Port Enable/Disable
+        * 1 - Connect Status Change
+        * 0 - Current Connect Status
+        */
+       PORTSC1 = 0x10,
+       /**
+        * \brief Port Status and Controll Register (Port 2)
+        * 
+        * See ::PORTSC1
+        */
+       PORTSC2 = 0x12
+};
+
+#endif
diff --git a/Modules/USB/usb.h b/Modules/USB/usb.h
new file mode 100644 (file)
index 0000000..3e503ec
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * AcessOS Version 1
+ * USB Stack
+ */
+#ifndef _USB_H_
+#define _USB_H_
+
+// === TYPES ===
+typedef struct sUSBHost        tUSBHost;
+typedef struct sUSBDevice      tUSBDevice;
+
+// === STRUCTURES ===
+/**
+ * \brief Defines a USB Host Controller
+ */
+struct sUSBHost
+{
+       Uint16  IOBase;
+       
+        int    (*SendPacket)(int ID, int Length, void *Data);
+};
+
+/**
+ * \brief Defines a single device on the USB Bus
+ */
+struct sUSBDevice
+{
+       tUSBHost        *Host;
+};
+
+#endif
diff --git a/Modules/link.ld b/Modules/link.ld
new file mode 100644 (file)
index 0000000..503f63d
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Acess2 Kernel Modules
+ * Linker Script
+ */
+
+ENTRY(ModuleEntry)
+OUTPUT_FORMAT(elf32-i386)
+
+SECTIONS 
+{
+       . = 0 + SIZEOF_HEADERS;
+       
+       .text : AT(ADDR(.text)) {
+               textzero = .;
+               *(.text)
+       }
+       
+       .rodata ALIGN(0x1000): AT(ADDR(.rodata)) {
+               *(.rodata)
+               *(.rdata)
+               DriverInfo = .;
+               *(KMODULES)
+       }
+       
+       .data ALIGN (0x1000) : AT(ADDR(.data)) {
+               *(.data)
+       }
+
+       .bss : AT(ADDR(.bss)) {
+               _sbss = .;
+               *(COMMON)
+               *(.bss)
+               _ebss = .;
+       }
+}
diff --git a/Usermode/Libraries/libreadline.so_src/main.c b/Usermode/Libraries/libreadline.so_src/main.c
new file mode 100644 (file)
index 0000000..e145bc0
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Acess2 Library Suite
+ * - Readline
+ * 
+ * Text mode entry with history
+ */
+#include <readline.h>
+#include <stdlib.h>
+
+// === GLOBALS ===
+
+// === CODE ===
+char *Readline(tReadline *Info)
+{
+       char    *ret;
+        int    len, pos, space = 1023;
+       char    ch;
+        int    scrollbackPos = Info->NumHistory;
+        
+       // Preset Variables
+       ret = malloc( space+1 );
+       if(!ret)        return NULL;
+       len = 0;        pos = 0;
+               
+       // Read In Command Line
+       do {
+               read(_stdin, 1, &ch);   // Read Character from stdin (read is a blocking call)
+               
+               if(ch == '\n')  break;
+               
+               switch(ch)
+               {
+               // Control characters
+               case '\x1B':
+                       read(_stdin, 1, &ch);   // Read control character
+                       switch(ch)
+                       {
+                       //case 'D':     if(pos) pos--;  break;
+                       //case 'C':     if(pos<len)     pos++;  break;
+                       case '[':
+                               read(_stdin, 1, &ch);   // Read control character
+                               switch(ch)
+                               {
+                               case 'A':       // Up
+                                       {
+                                                int    oldLen = len;
+                                               if( scrollbackPos <= 0 )        break;
+                                               
+                                               free(ret);
+                                               ret = strdup( Info->History[--scrollbackPos] );
+                                               
+                                               len = strlen(ret);
+                                               while(pos--)    write(_stdout, 3, "\x1B[D");
+                                               write(_stdout, len, ret);       pos = len;
+                                               while(pos++ < oldLen)   write(_stdout, 1, " ");
+                                       }
+                                       break;
+                               case 'B':       // Down
+                                       {
+                                                int    oldLen = len;
+                                               if( scrollbackPos >= Info->NumHistory ) break;
+                                               
+                                               free(ret);
+                                               ret = strdup( Info->History[scrollbackPos++] );
+                                               
+                                               len = strlen(ret);
+                                               while(pos--)    write(_stdout, 3, "\x1B[D");
+                                               write(_stdout, len, ret);       pos = len;
+                                               while(pos++ < oldLen)   write(_stdout, 1, " ");
+                                       }
+                                       break;
+                               case 'D':       // Left
+                                       if(pos == 0)    break;
+                                       pos --;
+                                       write(_stdout, 3, "\x1B[D");
+                                       break;
+                               case 'C':       // Right
+                                       if(pos == len)  break;
+                                       pos++;
+                                       write(_stdout, 3, "\x1B[C");
+                                       break;
+                               }
+                       }
+                       break;
+               
+               // Backspace
+               case '\b':
+                       if(len <= 0)            break;  // Protect against underflows
+                       write(_stdout, 1, &ch);
+                       if(pos == len) {        // Simple case of end of string
+                               len --;
+                               pos--;
+                       }
+                       else {
+                               char    buf[7] = "\x1B[000D";
+                               buf[2] += ((len-pos+1)/100) % 10;
+                               buf[3] += ((len-pos+1)/10) % 10;
+                               buf[4] += (len-pos+1) % 10;
+                               write(_stdout, len-pos, &ret[pos]);     // Move Text
+                               ch = ' ';       write(_stdout, 1, &ch); ch = '\b';      // Clear deleted character
+                               write(_stdout, 7, buf); // Update Cursor
+                               // Alter Buffer
+                               memmove(&ret[pos-1], &ret[pos], len-pos);
+                               pos --;
+                               len --;
+                       }
+                       break;
+               
+               // Tab
+               case '\t':
+                       //TODO: Implement Tab-Completion
+                       //Currently just ignore tabs
+                       break;
+               
+               default:                
+                       // Expand Buffer
+                       if(len+1 > space) {
+                               space += 256;
+                               ret = realloc(ret, space+1);
+                               if(!ret)        return NULL;
+                       }
+                       
+                       // Editing inside the buffer
+                       if(pos != len) {
+                               char    buf[7] = "\x1B[000D";
+                               buf[2] += ((len-pos)/100) % 10;
+                               buf[3] += ((len-pos)/10) % 10;
+                               buf[4] += (len-pos) % 10;
+                               write(_stdout, 1, &ch); // Print new character
+                               write(_stdout, len-pos, &ret[pos]);     // Move Text
+                               write(_stdout, 7, buf); // Update Cursor
+                               memmove( &ret[pos+1], &ret[pos], len-pos );
+                       }
+                       else {
+                               write(_stdout, 1, &ch);
+                       }
+                       ret[pos++] = ch;
+                       len ++;
+                       break;
+               }
+       } while(ch != '\n');
+       
+       // Cap String
+       ret[len] = '\0';
+       printf("\n");
+       
+       // Return length
+       //if(Length)    *Length = len;
+       
+       // Add to history
+       if( strcmp( Info->History[ Info->NumHistory-1 ], ret) != 0 )
+       {
+               void    *tmp;
+               Info->NumHistory ++;
+               tmp = realloc( Info->History, Info->NumHistory * sizeof(char*) );
+               if(tmp != NULL)
+               {
+                       Info->History = tmp;
+                       Info->History[ Info->NumHistory-1 ] = strdup(ret);
+               }
+       }
+       
+       return ret;
+}
diff --git a/Usermode/include/stddef.h b/Usermode/include/stddef.h
new file mode 100644 (file)
index 0000000..88e19f6
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * AcessOS LibC
+ * stddef.h
+ */
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+// === CONSTANTS ===
+#ifndef NULL
+# define NULL  ((void*)0)
+#endif
+
+// === TYPES ===
+#ifndef size_t
+typedef unsigned int   size_t;
+#endif
+
+#endif

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