Kernel - Added a (slightly hacky) virtual PCI interface
authorJohn Hodge <[email protected]>
Thu, 13 Sep 2012 05:29:21 +0000 (13:29 +0800)
committerJohn Hodge <[email protected]>
Thu, 13 Sep 2012 05:29:21 +0000 (13:29 +0800)
- Used to present the Tegra2's USB controllers to the EHCI driver

KernelLand/Kernel/Makefile
KernelLand/Kernel/arch/armv7/Makefile
KernelLand/Kernel/arch/armv7/link.ld
KernelLand/Kernel/arch/armv7/vpci_tegra2.c [new file with mode: 0644]
KernelLand/Kernel/arch/x86/Makefile
KernelLand/Kernel/arch/x86/main.c
KernelLand/Kernel/arch/x86/mboot.c
KernelLand/Kernel/arch/x86/vpci.c [new file with mode: 0644]
KernelLand/Kernel/drv/pci.c
KernelLand/Kernel/drv/vpci.c [new file with mode: 0644]
KernelLand/Kernel/include/virtual_pci.h [new file with mode: 0644]

index 454dd09..a82bbc9 100644 (file)
@@ -57,7 +57,7 @@ OBJ += heap.o logging.o debug.o lib.o libc.o adt.o time.o
 OBJ += drvutil_video.o drvutil_disk.o
 OBJ += messages.o modules.o syscalls.o system.o
 OBJ += threads.o mutex.o semaphore.o workqueue.o events.o rwlock.o
-OBJ += drv/zero-one.o drv/proc.o drv/fifo.o drv/iocache.o drv/pci.o
+OBJ += drv/zero-one.o drv/proc.o drv/fifo.o drv/iocache.o drv/pci.o drv/vpci.o
 OBJ += drv/vterm.o drv/vterm_font.o drv/vterm_vt100.o drv/vterm_output.o drv/vterm_input.o drv/vterm_termbuf.o
 OBJ += binary.o bin/elf.o bin/pe.o
 OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/dir.o vfs/io.o vfs/mount.o
index fad1b55..5429fe6 100644 (file)
@@ -12,6 +12,7 @@ LDFLAGS += `$(CC) --print-libgcc-file-name`
 
 A_OBJ  = start.ao main.o lib.o lib.ao time.o pci.o debug.o
 A_OBJ += mm_phys.o mm_virt.o proc.o proc.ao
+A_OBJ += vpci_$(PLATFORM).o
 
 #main.c: Makefile.BuildNum.$(ARCH)
 
index e45101b..fbd3582 100644 (file)
@@ -29,13 +29,27 @@ SECTIONS
        . += gUsertextPhysStart + _kernel_base - _usertext_vbase;
 
        /DISCARD/           : { *(.ARM.extab.init .ARM.exidx.init)      }
-       .ARM.extab          : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
+       .ARM.extab          : AT( ADDR(.ARM.extab) - _kernel_base)
+       {
+               *(.ARM.extab* .gnu.linkonce.armextab.*)
+       }
        PROVIDE_HIDDEN ( __exidx_start = . );
-       .ARM.exidx          : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+       .ARM.exidx          : AT( ADDR(.ARM.exidx) - _kernel_base)
+       {
+               *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+       }
        PROVIDE_HIDDEN ( __exidx_end = . );
-       .eh_frame_hdr       : { *(.eh_frame_hdr) }
-       .eh_frame           : ONLY_IF_RO { KEEP (*(.eh_frame)) }
-       .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
+       .eh_frame_hdr       : AT( ADDR(.eh_frame_hdr) - _kernel_base) {
+               *(.eh_frame_hdr)
+       }
+       .eh_frame           : AT( ADDR(.eh_frame) - _kernel_base) ONLY_IF_RO
+       {
+               KEEP (*(.eh_frame))
+       }
+       .gcc_except_table   : AT( ADDR(.gcc_except_table) - _kernel_base) ONLY_IF_RO
+       {
+               *(.gcc_except_table .gcc_except_table.*)
+       }
 
        /* 0x4000 (4 pages) alignment needed for root table */
        . = ALIGN(0x4000);
diff --git a/KernelLand/Kernel/arch/armv7/vpci_tegra2.c b/KernelLand/Kernel/arch/armv7/vpci_tegra2.c
new file mode 100644 (file)
index 0000000..d44e9d5
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Acess2 Kernel ARMv7 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * vpci_tegra2.c
+ * - Tegra2 VPCI Definitions
+ */
+#include <virtual_pci.h>
+
+// === PROTOTYPES ===
+
+// === GLOBALS ===
+tVPCI_Device   gaVPCI_Devices[] = {
+       {
+       .Vendor=0x0ACE,.Device=0x1100,
+       .Class = 0x0C032000,    // Serial, USB, ECHI
+       .BARs = {0xC5000000,0,0,0,0,0},
+       .IRQ = 0*32+20,
+       },
+       {
+       .Vendor=0x0ACE,.Device=0x1100,
+       .Class = 0x0C032000,    // Serial, USB, ECHI
+       .BARs = {0xC5004000,0,0,0,0,0},
+       .IRQ = 0*32+21,
+       },
+       {
+       .Vendor=0x0ACE,.Device=0x1100,
+       .Class = 0x0C032000,    // Serial, USB, ECHI
+       .BARs = {0xC5008000,0,0,0,0,0},
+       .IRQ = 4*32+1,
+       }
+};
+int giVPCI_DeviceCount = sizeof(gaVPCI_Devices)/sizeof(gaVPCI_Devices[0]);
+
index c3223d0..7372839 100644 (file)
@@ -23,4 +23,4 @@ CPPFLAGS += -DUSE_MP=$(USE_MP)
 A_OBJ  = start.ao main.o mboot.o lib.o desctab.ao errors.o irq.o
 A_OBJ += mm_phys.o mm_virt.o
 A_OBJ += proc.o proc.ao time.o vm8086.o
-A_OBJ += kpanic.o pci.o
+A_OBJ += kpanic.o pci.o vpci.o
index af9007d..a2932c1 100644 (file)
@@ -54,7 +54,7 @@ int kmain(Uint MbMagic, void *MbInfoPtr)
                gsBootCmdLine = (char*)(mbInfo->CommandLine + KERNEL_BASE);
 
                // Adjust Multiboot structure address
-               mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE );
+               mbInfo = (void*)( (tVAddr)MbInfoPtr + KERNEL_BASE );
 
                nPMemMapEnts = Multiboot_LoadMemoryMap(mbInfo, KERNEL_BASE, pmemmap, MAX_PMEMMAP_ENTS,
                        KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_BASE);
index 5fe4068..897c9bb 100644 (file)
@@ -5,7 +5,7 @@
  * mboot.c
  * - Multiboot Support
  */
-#define DEBUG  0
+#define DEBUG  1
 #include <acess.h>
 #include <mboot.h>
 
@@ -19,26 +19,52 @@ int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *
        ENTER("pMBInfo pMapOffset pMap iMapSize PKStart PKEnd",
                MBInfo, MapOffset, Map, MapSize, KStart, KEnd);
 
-       // Build up memory map
-       nPMemMapEnts = 0;
-       while( ent < last && nPMemMapEnts < MapSize )
+       // Check that the memory map is present
+       if( MBInfo->Flags & (1 << 6) )
        {
-               tPMemMapEnt     *nent = &Map[nPMemMapEnts];
-               nent->Start = ent->Base;
-               nent->Length = ent->Length;
-               switch(ent->Type)
+               // Build up memory map
+               nPMemMapEnts = 0;
+               while( ent < last && nPMemMapEnts < MapSize )
                {
-               case 1:
-                       nent->Type = PMEMTYPE_FREE;
-                       break;
-               default:
-                       nent->Type = PMEMTYPE_RESERVED;
-                       break;
+                       tPMemMapEnt     *nent = &Map[nPMemMapEnts];
+                       if( !MM_GetPhysAddr(ent) )
+                               Log_KernelPanic("MBoot", "MBoot Map entry %i addres bad (%p)",
+                                       nPMemMapEnts, ent);
+       
+                       nent->Start = ent->Base;
+                       nent->Length = ent->Length;
+                       switch(ent->Type)
+                       {
+                       case 1:
+                               nent->Type = PMEMTYPE_FREE;
+                               break;
+                       default:
+                               nent->Type = PMEMTYPE_RESERVED;
+                               break;
+                       }
+                       nent->NUMADomain = 0;
+                       
+                       nPMemMapEnts ++;
+                       ent = (void*)( (tVAddr)ent + ent->Size + 4 );
                }
-               nent->NUMADomain = 0;
-               
-               nPMemMapEnts ++;
-               ent = (void*)( (tVAddr)ent + ent->Size + 4 );
+       }
+       else if( MBInfo->Flags & (1 << 0) )
+       {
+               Log_Warning("MBoot", "No memory map passed, using mem_lower and mem_upper");
+               nPMemMapEnts = 2;
+               Map[0].Start = 0;
+               Map[0].Length = MBInfo->LowMem * 1024;
+               Map[0].Type = PMEMTYPE_FREE;
+               Map[0].NUMADomain = 0;
+
+               Map[1].Start = 0x100000;
+               Map[1].Length = MBInfo->HighMem * 1024;
+               Map[1].Type = PMEMTYPE_FREE;
+               Map[1].NUMADomain = 0;
+       }
+       else
+       {
+               Log_KernelPanic("MBoot", "Multiboot didn't pass memory information");
        }
 
        // Ensure it's valid
@@ -51,19 +77,28 @@ int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *
                KStart, KEnd - KStart
                );
 
-       // Replace modules with PMEMTYPE_USED
-       nPMemMapEnts = PMemMap_MarkRangeUsed(Map, nPMemMapEnts, MapSize,
-               MBInfo->Modules, MBInfo->ModuleCount*sizeof(tMBoot_Module)
-               );
-       tMBoot_Module *mods = (void*)( (tVAddr)MBInfo->Modules + MapOffset);
-       for( int i = 0; i < MBInfo->ModuleCount; i ++ )
+       PMemMap_DumpBlocks(Map, nPMemMapEnts);
+
+       // Check if boot modules were passed
+       if( MBInfo->Flags & (1 << 3) )
        {
-               nPMemMapEnts = PMemMap_MarkRangeUsed(
-                       Map, nPMemMapEnts, MapSize,
-                       mods->Start, mods->End - mods->Start
+               // Replace modules with PMEMTYPE_USED
+               nPMemMapEnts = PMemMap_MarkRangeUsed(Map, nPMemMapEnts, MapSize,
+                       MBInfo->Modules, MBInfo->ModuleCount*sizeof(tMBoot_Module)
                        );
+               LOG("MBInfo->Modules = %x", MBInfo->Modules);
+               tMBoot_Module *mods = (void*)( (tVAddr)MBInfo->Modules + MapOffset);
+               for( int i = 0; i < MBInfo->ModuleCount; i ++ )
+               {
+                       LOG("&mods[%i] = %p", i, &mods[i]);
+                       LOG("mods[i] = {0x%x -> 0x%x}", mods[i].Start, mods[i].End);
+                       nPMemMapEnts = PMemMap_MarkRangeUsed(
+                               Map, nPMemMapEnts, MapSize,
+                               mods[i].Start, mods[i].End - mods[i].Start
+                               );
+               }
        }
-       
+               
        // Debug - Output map
        PMemMap_DumpBlocks(Map, nPMemMapEnts);
 
@@ -73,6 +108,12 @@ int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *
 
 tBootModule *Multiboot_LoadModules(tMBoot_Info *MBInfo, tVAddr MapOffset, int *ModuleCount)
 {
+       if( !(MBInfo->Flags & (1 << 3)) ) {
+               *ModuleCount = 0;
+               Log_Log("Arch", "No multiboot module information passed");
+               return NULL;
+       }
+
        tMBoot_Module   *mods = (void*)( MBInfo->Modules + MapOffset );
        *ModuleCount = MBInfo->ModuleCount;
        tBootModule *ret = malloc( MBInfo->ModuleCount * sizeof(*ret) );
diff --git a/KernelLand/Kernel/arch/x86/vpci.c b/KernelLand/Kernel/arch/x86/vpci.c
new file mode 100644 (file)
index 0000000..0319e6e
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Acess2 Kernel x86 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * vpci.c
+ * - Virtual PCI Bus
+ */
+#include <virtual_pci.h>
+
+// === GLOBALS ===
+ int   giVPCI_DeviceCount = 0;
+tVPCI_Device   gaVPCI_Devices[0];
+
index 702c9cc..2e1ce15 100644 (file)
@@ -1,6 +1,9 @@
 /*\r
- * AcessOS/AcessBasic v0.1\r
- * PCI Bus Driver\r
+ * Acess2 Kernel\r
+ * - By John Hodge (thePowersGang)\r
+ * \r
+ * drv/pci.c\r
+ * - PCI Enumeration and Arbitration\r
  */\r
 #define DEBUG  0\r
 #include <acess.h>\r
@@ -9,9 +12,11 @@
 #include <fs_devfs.h>\r
 #include <drv_pci.h>\r
 #include <drv_pci_int.h>\r
+#include <virtual_pci.h>\r
 \r
 #define USE_PORT_BITMAP        0\r
 #define        LIST_DEVICES    1\r
+#define PCI_MAX_BUSSES 8\r
 \r
 // === STRUCTURES ===\r
 typedef struct sPCIDevice\r
@@ -42,6 +47,7 @@ size_t        PCI_int_ReadDevice(tVFS_Node *node, off_t Offset, size_t Length, void *bu
 // === GLOBALS ===\r
 MODULE_DEFINE(0, 0x0100, PCI, PCI_Install, NULL, NULL);\r
  int   giPCI_BusCount = 1;\r
+Uint8  gaPCI_BusNumbers[PCI_MAX_BUSSES];\r
  int   giPCI_InodeHandle = -1;\r
  int   giPCI_DeviceCount = 0;\r
 tPCIDevice     *gPCI_Devices = NULL;\r
@@ -95,12 +101,18 @@ int PCI_Install(char **Arguments)
        #endif  \r
 \r
        // Scan Bus (Bus 0, Don't fill gPCI_Devices)\r
+       giPCI_DeviceCount = 0;\r
+       giPCI_BusCount = 1;\r
+       gaPCI_BusNumbers[0] = 0;\r
        for( bus = 0; bus < giPCI_BusCount; bus ++ )\r
        {\r
-               ret = PCI_ScanBus(bus, 0);\r
+               ret = PCI_ScanBus(gaPCI_BusNumbers[bus], 0);\r
                if(ret != MODULE_ERR_OK)        return ret;\r
        }\r
-               \r
+       // TODO: PCIe\r
+       // - Add VPCI Devices\r
+       giPCI_DeviceCount += giVPCI_DeviceCount;\r
+       \r
        if(giPCI_DeviceCount == 0) {\r
                Log_Notice("PCI", "No devices were found");\r
                return MODULE_ERR_NOTNEEDED;\r
@@ -123,7 +135,33 @@ int PCI_Install(char **Arguments)
        // Rescan, filling the PCI device array\r
        for( bus = 0; bus < giPCI_BusCount; bus ++ )\r
        {\r
-               PCI_ScanBus(bus, 1);\r
+               PCI_ScanBus(gaPCI_BusNumbers[bus], 1);\r
+       }\r
+       // Insert VPCI Devices\r
+       for( int i = 0; i < giVPCI_DeviceCount; i ++ )\r
+       {\r
+               tPCIDevice      *devinfo = &gPCI_Devices[giPCI_DeviceCount];\r
+               \r
+               devinfo->bus = -1;\r
+               devinfo->slot = i;\r
+               devinfo->fcn = 0;\r
+               devinfo->vendor = gaVPCI_Devices[i].Vendor;\r
+               devinfo->device = gaVPCI_Devices[i].Device;\r
+               devinfo->revision = gaVPCI_Devices[i].Class & 0xFF;\r
+               devinfo->class = gaVPCI_Devices[i].Class >> 8;\r
+               snprintf(devinfo->Name, sizeof(devinfo->Name), "%02x.%02x:%x", 0xFF, i, 0);\r
+\r
+               for(int j = 0; j < 256/4; j ++ )\r
+                       devinfo->ConfigCache[i] = VPCI_Read(&gaVPCI_Devices[i], j*4, 4);\r
+\r
+               memset(&devinfo->Node, 0, sizeof(devinfo->Node));\r
+               devinfo->Node.Inode = giPCI_DeviceCount;\r
+               devinfo->Node.Size = 256;\r
+               devinfo->Node.NumACLs = 1;\r
+               devinfo->Node.ACLs = &gVFS_ACL_EveryoneRO;\r
+               devinfo->Node.Type = &gPCI_DevNodeType;\r
+\r
+               giPCI_DeviceCount ++;\r
        }\r
        \r
        // Complete Driver Structure\r
@@ -158,26 +196,12 @@ int PCI_ScanBus(int BusID, int bFill)
                        if(!PCI_int_EnumDevice(BusID, dev, fcn, &devInfo))\r
                                continue;\r
                        \r
-                       if(devInfo.class == PCI_OC_PCIBRIDGE)\r
-                       {\r
-                               #if LIST_DEVICES\r
-                               if( !bFill )\r
-                                       Log_Log("PCI", "Bridge @ %i,%i:%i (0x%x:0x%x)",\r
-                                               BusID, dev, fcn, devInfo.vendor, devInfo.device);\r
-                               #endif\r
-                               //TODO: Handle PCI-PCI Bridges\r
-                               //PCI_ScanBus(devInfo.???, bFill);\r
-                               giPCI_BusCount ++;\r
-                       }\r
-                       else\r
-                       {\r
-                               #if LIST_DEVICES\r
-                               if( !bFill )\r
-                                       Log_Log("PCI", "Device %i,%i:%i %06x => 0x%04x:0x%04x Rev %i",\r
-                                               BusID, dev, fcn, devInfo.class,\r
-                                               devInfo.vendor, devInfo.device, devInfo.revision);\r
-                               #endif\r
-                       }\r
+                       #if LIST_DEVICES\r
+                       if( !bFill )\r
+                               Log_Log("PCI", "Device %i,%i:%i %06x => 0x%04x:0x%04x Rev %i",\r
+                                       BusID, dev, fcn, devInfo.class,\r
+                                       devInfo.vendor, devInfo.device, devInfo.revision);\r
+                       #endif\r
                        \r
                        if( bFill ) {\r
                                devInfo.Node.Inode = giPCI_DeviceCount;\r
@@ -185,7 +209,28 @@ int PCI_ScanBus(int BusID, int bFill)
                        }\r
                        giPCI_DeviceCount ++;\r
                        \r
-                       // If bit 23 of (soemthing) is set, there are sub-functions\r
+                       switch(devInfo.ConfigCache[3] & 0x007F0000)\r
+                       {\r
+                       case 0x00:      // Normal device\r
+                               break;\r
+                       case 0x01:      // PCI-PCI Bridge\r
+                               {\r
+                               // TODO: Add to list of busses?\r
+                               Uint8   sec = (devInfo.ConfigCache[6] & 0x0000FF00) >> 8;\r
+                               #if LIST_DEVICES\r
+                               if( !bFill ) {\r
+                                       Uint8   pri = (devInfo.ConfigCache[6] & 0x000000FF) >> 0;\r
+                                       Log_Log("PCI", "- PCI-PCI Bridge %02x=>%02x", pri, sec);\r
+                               }\r
+                               #endif\r
+                               gaPCI_BusNumbers[giPCI_BusCount++] = sec;\r
+                               }\r
+                               break;\r
+                       case 0x02:      // PCI-CardBus Bridge\r
+                               break;\r
+                       }\r
+\r
+                       // If bit 8 of the Header Type register is set, there are sub-functions\r
                        if(fcn == 0 && !(devInfo.ConfigCache[3] & 0x00800000) )\r
                                break;\r
                }\r
@@ -212,35 +257,16 @@ int PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
  */\r
 tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename)\r
 {\r
-        int    bus,slot,fcn;\r
         int    i;\r
-       // Validate Filename (Pointer and length)\r
-       if(!filename || strlen(filename) != 7)\r
-               return NULL;\r
-       // Check for spacers\r
-       if(filename[2] != '.' || filename[5] != ':')\r
-               return NULL;\r
-       \r
-       // Get Information\r
-       if(filename[0] < '0' || filename[0] > '9')      return NULL;\r
-       bus = (filename[0] - '0')*10;\r
-       if(filename[1] < '0' || filename[1] > '9')      return NULL;\r
-       bus += filename[1] - '0';\r
-       if(filename[3] < '0' || filename[3] > '9')      return NULL;\r
-       slot = (filename[3] - '0')*10;\r
-       if(filename[4] < '0' || filename[4] > '9')      return NULL;\r
-       slot += filename[4] - '0';\r
-       if(filename[6] < '0' || filename[6] > '9')      return NULL;\r
-       fcn = filename[6] - '0';\r
        \r
        // Find Match\r
        for(i=0;i<giPCI_DeviceCount;i++)\r
        {\r
-               if(gPCI_Devices[i].bus != bus)          continue;\r
-               if(gPCI_Devices[i].slot != slot)        continue;\r
-               if(gPCI_Devices[i].fcn != fcn)  continue;\r
-               \r
-               return &gPCI_Devices[i].Node;\r
+               int cmp = strcmp(gPCI_Devices[i].Name, filename);\r
+               if( cmp > 0 )   // Sorted list\r
+                       break;\r
+               if( cmp == 0 )\r
+                       return &gPCI_Devices[i].Node;\r
        }\r
        \r
        // Error Return\r
@@ -372,6 +398,11 @@ Uint32 PCI_ConfigRead(tPCIDev ID, int Offset, int Size)
        if( Offset & (Size - 1) )       return 0;\r
 \r
        dev = &gPCI_Devices[ID];\r
+       // Detect VPCI devices\r
+       if( dev->bus == -1 ) {\r
+               return VPCI_Read(&gaVPCI_Devices[dev->slot], Offset, Size);\r
+       }\r
+\r
        addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, Offset);\r
 \r
        dword = PCI_CfgReadDWord(addr);\r
@@ -391,10 +422,18 @@ void PCI_ConfigWrite(tPCIDev ID, int Offset, int Size, Uint32 Value)
        tPCIDevice      *dev;\r
        Uint32  dword, addr;\r
         int    shift;\r
+\r
        if( ID < 0 || ID >= giPCI_DeviceCount ) return ;\r
        if( Offset < 0 || Offset > 256 )        return ;\r
-       \r
+\r
        dev = &gPCI_Devices[ID];\r
+\r
+       // Detect VPCI devices\r
+       if( dev->bus == -1 ) {\r
+               VPCI_Write(&gaVPCI_Devices[dev->slot], Offset, Size, Value);\r
+               return ;\r
+       }\r
+\r
        addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, Offset);\r
 \r
        if(Size != 4)\r
@@ -456,16 +495,18 @@ int PCI_int_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info)
        vendor_dev = PCI_CfgReadDWord( addr );\r
        if((vendor_dev & 0xFFFF) == 0xFFFF)     // Invalid Device\r
                return 0;\r
+       \r
+       info->bus = bus;\r
+       info->slot = slot;\r
+       info->fcn = fcn;\r
 \r
+       // Read configuration\r
        info->ConfigCache[0] = vendor_dev;\r
        for( i = 1, addr += 4; i < 256/4; i ++, addr += 4 )\r
        {\r
                info->ConfigCache[i] = PCI_CfgReadDWord(addr);\r
        }       \r
 \r
-       info->bus = bus;\r
-       info->slot = slot;\r
-       info->fcn = fcn;\r
        info->vendor = vendor_dev & 0xFFFF;\r
        info->device = vendor_dev >> 16;\r
        tmp = info->ConfigCache[2];\r
@@ -479,14 +520,7 @@ int PCI_int_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info)
 //     #endif\r
        \r
        // Make node name\r
-       info->Name[0] = '0' + bus/10;\r
-       info->Name[1] = '0' + bus%10;\r
-       info->Name[2] = '.';\r
-       info->Name[3] = '0' + slot/10;\r
-       info->Name[4] = '0' + slot%10;\r
-       info->Name[5] = ':';\r
-       info->Name[6] = '0' + fcn;\r
-       info->Name[7] = '\0';\r
+       snprintf(info->Name, 8, "%02x.%02x:%x", bus, slot, fcn);\r
        \r
        // Create VFS Node\r
        memset( &info->Node, 0, sizeof(tVFS_Node) );\r
diff --git a/KernelLand/Kernel/drv/vpci.c b/KernelLand/Kernel/drv/vpci.c
new file mode 100644 (file)
index 0000000..4fccdb8
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * drv/vpci.c
+ * - Virtual PCI Bus
+ */
+#include <virtual_pci.h>
+
+// === CODE ===
+Uint32 VPCI_Read(tVPCI_Device *Dev, Uint8 Offset, Uint8 Size)
+{
+       Uint32  tmp_dword = 0;
+
+       if( Size > 4 || Size == 3 || Size == 0 )
+               return 0;
+       if( Offset & (Size - 1) )
+               return 0;
+       
+       switch( Offset >> 2 )
+       {
+       case 0: // Vendor[0:15], Device[16:31]
+               tmp_dword = (Dev->Vendor) | (Dev->Device << 16);
+               break;
+       case 2: // Class Code
+               tmp_dword = Dev->Class;
+               break;
+       // 1: Command[0:15], Status[16:31]
+       // 3: Cache Line Size, Latency Timer, Header Type, BIST
+       // 4-9: BARs
+       // 10: Unused (Cardbus CIS Pointer)
+       // 11: Subsystem Vendor ID, Subsystem ID
+       // 12: Expansion ROM Address
+       // 13: Capabilities[0:8], Reserved[9:31]
+       // 14: Reserved
+       // 15: Interrupt Line, Interrupt Pin, Min Grant, Max Latency
+       default:
+               tmp_dword = Dev->Read(Dev->Ptr, Offset >> 2);
+               break;
+       }
+
+       tmp_dword >>= 8*(Offset & 3);
+       switch(Size)
+       {
+       case 4: break;
+       case 2: tmp_dword &= 0xFFFF;    break;
+       case 1: tmp_dword &= 0xFF;
+       }
+
+       return tmp_dword;
+}
+
+void VPCI_Write(tVPCI_Device *Dev, Uint8 Offset, Uint8 Size, Uint32 Data)
+{
+       Uint32  tmp_dword;
+       if( Size > 4 || Size == 3 || Size == 0 )
+               return ;
+       if( Offset & (Size - 1) )
+               return ;
+       
+       switch(Offset >> 2)
+       {
+       case 0: // Vendor / Device IDs
+       case 2: // Class Code
+               // READ ONLY
+               return ;
+       }
+
+       tmp_dword = Dev->Read(Dev->Ptr, Offset>>2);
+       switch(Size)
+       {
+       case 4: tmp_dword = 0;  break;
+       case 2:
+               tmp_dword &= ~(0xFFFF << ((Offset&2)*16));
+               Data |= 0xFFFF;
+               break;
+       case 1:
+               tmp_dword &= ~(0xFF << ((Offset&3)*8));
+               Data |= 0xFF;
+               break;
+       }
+       tmp_dword |= Data << ((Offset&3)*8);
+       Dev->Write(Dev->Ptr, Offset>>2, tmp_dword);
+}
diff --git a/KernelLand/Kernel/include/virtual_pci.h b/KernelLand/Kernel/include/virtual_pci.h
new file mode 100644 (file)
index 0000000..c6408cd
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ * 
+ * virtual_pci.h
+ * - Virtual PCI bus definitions
+ */
+#ifndef _VIRTUAL_PCI_H_
+#define _VIRTUAL_PCI_H_
+#include <acess.h>
+
+typedef struct sVPCI_Device    tVPCI_Device;
+
+struct sVPCI_Device
+{
+       void    *Ptr;
+
+       // Vendor/Device is defined at runtime as 0x0ACE:0x[ARCH][ARCH][IDX][IDX]
+       Uint16  Vendor;
+       Uint16  Device;
+       // Class code (Class, Subclass, Programming Interface, Revision)
+       Uint32  Class;
+       
+       Uint32  BARs[6];
+       Uint8   IRQ;
+       
+       /**
+        * \param Ptr   Value in sVPCI_Device.Ptr
+        * \param Data  Data to write to the specified address
+        */
+       void    (*Write)(void *Ptr, Uint8 DWord, Uint32 Data);
+       Uint32  (*Read)(void *Ptr, Uint8 DWord);
+};
+
+extern int     giVPCI_DeviceCount;
+extern tVPCI_Device    gaVPCI_Devices[];
+
+extern Uint32  VPCI_Read(tVPCI_Device *Dev, Uint8 Offset, Uint8 Size);
+extern void    VPCI_Write(tVPCI_Device *Dev, Uint8 Offset, Uint8 Size, Uint32 Data);
+#endif
+

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