diff --git a/sortix/include/sortix/kernel/pci.h b/sortix/include/sortix/kernel/pci.h
new file mode 100644
index 00000000..6867d66f
--- /dev/null
+++ b/sortix/include/sortix/kernel/pci.h
@@ -0,0 +1,75 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
+
+ This file is part of Sortix.
+
+ Sortix is free software: you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation, either version 3 of the License, or (at your option) any later
+ version.
+
+ Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ details.
+
+ You should have received a copy of the GNU General Public License along with
+ Sortix. If not, see .
+
+ pci.h
+ Functions for handling PCI devices.
+
+*******************************************************************************/
+
+#ifndef SORTIX_PCI_H
+#define SORTIX_PCI_H
+
+namespace Sortix {
+
+typedef struct
+{
+ uint16_t deviceid;
+ uint16_t vendorid;
+} pciid_t;
+
+typedef struct
+{
+ uint8_t classid;
+ uint8_t subclassid;
+ uint8_t progif;
+ uint8_t revid;
+} pcitype_t;
+
+// memset(&pcifind, 255, sizeof(pcifind)) and fill out rest.
+typedef struct
+{
+ uint16_t deviceid;
+ uint16_t vendorid;
+ uint8_t classid;
+ uint8_t subclassid;
+ uint8_t progif;
+ uint8_t revid;
+} pcifind_t;
+
+namespace PCI {
+
+void Init();
+uint32_t MakeDevAddr(uint8_t bus, uint8_t slot, uint8_t func);
+void SplitDevAddr(uint32_t devaddr, uint8_t* vals /* bus, slot, func */);
+uint8_t Read8(uint32_t devaddr, uint8_t off); // Host endian
+uint16_t Read16(uint32_t devaddr, uint8_t off); // Host endian
+uint32_t Read32(uint32_t devaddr, uint8_t off); // Host endian
+uint32_t ReadRaw32(uint32_t devaddr, uint8_t off); // PCI endian
+void Write32(uint32_t devaddr, uint8_t off, uint32_t val); // Host endian
+void WriteRaw32(uint32_t devaddr, uint8_t off, uint32_t val); // PCI endian
+pciid_t GetDeviceId(uint32_t devaddr);
+pcitype_t GetDeviceType(uint32_t devaddr);
+uint32_t SearchForDevice(pcifind_t pcifind);
+addr_t ParseDevBar0(uint32_t devaddr);
+
+} // namespace PCI
+} // namespace Sortix
+
+#endif
+
diff --git a/sortix/kernel.cpp b/sortix/kernel.cpp
index 1c623e92..deeddc87 100644
--- a/sortix/kernel.cpp
+++ b/sortix/kernel.cpp
@@ -27,6 +27,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -42,7 +43,7 @@
#include "process.h"
#include "scheduler.h"
#include "syscall.h"
-#include "pci.h"
+#include "ata.h"
#include "com.h"
#include "uart.h"
#include "vgatextbuffer.h"
@@ -218,6 +219,9 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo)
// Search for PCI devices and load their drivers.
PCI::Init();
+ // Initialize ATA devices.
+ ATA::Init();
+
// Alright, now the system's drivers are loaded and initialized. It is
// time to load the initial user-space programs and start execution of
// the actual operating system.
diff --git a/sortix/pci.cpp b/sortix/pci.cpp
index db902ed6..6a2d717d 100644
--- a/sortix/pci.cpp
+++ b/sortix/pci.cpp
@@ -1,6 +1,6 @@
-/******************************************************************************
+/*******************************************************************************
- COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
This file is part of Sortix.
@@ -14,283 +14,180 @@
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
- You should have received a copy of the GNU General Public License along
- with Sortix. If not, see .
+ You should have received a copy of the GNU General Public License along with
+ Sortix. If not, see .
- pci.h
- Handles basic PCI bus stuff.
+ pci.cpp
+ Functions for handling PCI devices.
-******************************************************************************/
+*******************************************************************************/
#include
-#include "cpu.h"
-#include
-#include "pci.h"
-#include
-#include "ata.h"
+#include
+#include
+#include "cpu.h" // TODO: Put this in some
-using namespace Maxsi;
+// TODO: Verify that the endian conversions in this file actually works. I have
+// a sneaking suspicion that they won't work on non-little endian platforms.
-namespace Sortix
+namespace Sortix {
+namespace PCI {
+
+const uint16_t CONFIG_ADDRESS = 0xCF8;
+const uint16_t CONFIG_DATA = 0xCFC;
+
+uint32_t MakeDevAddr(uint8_t bus, uint8_t slot, uint8_t func)
{
- namespace PCI
+ //ASSERT(bus < 1UL<<8UL); // bus is 8 bit anyways.
+ ASSERT(slot < 1UL<<5UL);
+ ASSERT(func < 1UL<<3UL);
+ return func << 8U | slot << 11U | bus << 16U | 1 << 31U;
+}
+
+void SplitDevAddr(uint32_t devaddr, uint8_t* vals /* bus, slot, func */)
+{
+ vals[0] = devaddr >> 16U & ((1UL<<8UL)-1);
+ vals[1] = devaddr >> 11U & ((1UL<<3UL)-1);
+ vals[2] = devaddr >> 8U & ((1UL<<5UL)-1);
+}
+
+uint32_t ReadRaw32(uint32_t devaddr, uint8_t off)
+{
+ CPU::OutPortL(CONFIG_ADDRESS, devaddr + off);
+ return CPU::InPortL(CONFIG_DATA);
+}
+
+void WriteRaw32(uint32_t devaddr, uint8_t off, uint32_t val)
+{
+ CPU::OutPortL(CONFIG_ADDRESS, devaddr + off);
+ CPU::OutPortL(CONFIG_DATA, val);
+}
+
+uint32_t Read32(uint32_t devaddr, uint8_t off)
+{
+ return LittleToHost(ReadRaw32(devaddr, off));
+}
+
+void Write32(uint32_t devaddr, uint8_t off, uint32_t val)
+{
+ WriteRaw32(devaddr, off, HostToLittle(val));
+}
+
+uint16_t Read16(uint32_t devaddr, uint8_t off)
+{
+ ASSERT((off & 0x1) == 0);
+ uint8_t alignedoff = off & ~0x3;
+ union { uint16_t val16[2]; uint32_t val32; };
+ val32 = ReadRaw32(devaddr, alignedoff);
+ uint16_t ret = off & 0x2 ? val16[0] : val16[1];
+ return LittleToHost(ret);
+}
+
+uint8_t Read8(uint32_t devaddr, uint8_t off)
+{
+ uint8_t alignedoff = off & ~0x1;
+ union { uint8_t val8[2]; uint32_t val16; };
+ val16 = HostToLittle(Read16(devaddr, alignedoff));
+ uint8_t ret = off & 0x1 ? val8[0] : val8[1];
+ return ret;
+}
+
+uint32_t CheckDevice(uint8_t bus, uint8_t slot, uint8_t func)
+{
+ return Read32(MakeDevAddr(bus, slot, func), 0x0);
+}
+
+pciid_t GetDeviceId(uint32_t devaddr)
+{
+ pciid_t ret;
+ ret.deviceid = Read16(devaddr, 0x00);
+ ret.vendorid = Read16(devaddr, 0x02);
+ return ret;
+}
+
+pcitype_t GetDeviceType(uint32_t devaddr)
+{
+ pcitype_t ret;
+ ret.classid = Read8(devaddr, 0x08);
+ ret.subclassid = Read8(devaddr, 0x09);
+ ret.progif = Read8(devaddr, 0x0A);
+ ret.revid = Read8(devaddr, 0x0B);
+ return ret;
+}
+
+static bool MatchesSearchCriteria(uint32_t devaddr, pcifind_t pcifind)
+{
+ pciid_t id = GetDeviceId(devaddr);
+ if ( id.vendorid == 0xFFFF && id.deviceid == 0xFFFF )
+ return false;
+ pcitype_t type = GetDeviceType(devaddr);
+ if ( pcifind.vendorid != 0xFFFF && id.vendorid != pcifind.vendorid )
+ return false;
+ if ( pcifind.deviceid != 0xFFFF && id.deviceid != pcifind.deviceid )
+ return false;
+ if ( pcifind.classid != 0xFF && type.classid != pcifind.classid )
+ return false;
+ if ( pcifind.subclassid != 0xFF && type.subclassid != pcifind.subclassid )
+ return false;
+ if ( pcifind.progif != 0xFF && type.progif != pcifind.progif )
+ return false;
+ if ( pcifind.revid != 0xFF && type.revid != pcifind.revid )
+ return false;
+ return true;
+}
+
+static uint32_t SearchForDeviceOnBus(uint8_t bus, pcifind_t pcifind)
+{
+ for ( unsigned slot = 0; slot < 32; slot++ )
{
- const uint16_t Config_Address = 0xCF8;
- const uint16_t Config_Data = 0xCFC;
-
- uint32_t SwapBytes(uint32_t I)
+ unsigned numfuncs = 1;
+ for ( unsigned func = 0; func < numfuncs; func++ )
{
- return (I >> 24) | ((I >> 8) & 0x0000FF00) | ((I << 8) & 0x00FF0000) | (I << 24);
+ uint32_t devaddr = MakeDevAddr(bus, slot, func);
+ if ( MatchesSearchCriteria(devaddr, pcifind) )
+ return devaddr;
+ uint8_t header = Read8(devaddr, 0x0D); // Secondary Bus Number.
+ if ( header & 0x80 ) // Multi function device.
+ numfuncs = 8;
+ if ( (header & 0x7F) == 0x01 ) // PCI to PCI bus.
+ {
+ uint8_t subbusid = Read8(devaddr, 0x1A);
+ uint32_t recret = SearchForDeviceOnBus(subbusid, pcifind);
+ if ( recret )
+ return recret;
+ }
}
+ }
+ return 0;
+}
- const char* ToDeviceDesc(uint32_t ProductInfo, uint32_t DeviceType)
- {
- uint32_t Class = (DeviceType) >> 24;
- uint32_t SubClass = (DeviceType >> 16) & 0xFF;
- uint32_t ProgIF = (DeviceType >> 8) & 0xFF;
- uint32_t RevisionID = (DeviceType) & 0xFF;
+uint32_t SearchForDevice(pcifind_t pcifind)
+{
+ // Search on bus 0 and recurse on other detected busses.
+ return SearchForDeviceOnBus(0, pcifind);
+}
- if ( Class == 0x00 )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "Any device except for VGA-Compatible devices"; }
- if ( SubClass == 0x01 && ProgIF == 0x00 ) { return "VGA-Compatible Device"; }
- }
- if ( Class == 0x01 )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "SCSI Bus Controller"; }
- if ( SubClass == 0x01 ) { return "IDE Controller"; }
- if ( SubClass == 0x02 && ProgIF == 0x00 ) { return "Floppy Disk Controller"; }
- if ( SubClass == 0x03 && ProgIF == 0x00 ) { return "IPI Bus Controller"; }
- if ( SubClass == 0x04 && ProgIF == 0x00 ) { return "RAID Controller"; }
- if ( SubClass == 0x05 && ProgIF == 0x20 ) { return "ATA Controller (Single DMA)"; }
- if ( SubClass == 0x05 && ProgIF == 0x30 ) { return "ATA Controller (Chained DMA)"; }
- if ( SubClass == 0x06 && ProgIF == 0x00 ) { return "Serial ATA (Direct Port Access)"; }
- if ( SubClass == 0x80 && ProgIF == 0x00 ) { return "Other Mass Storage Controller"; }
- }
- if ( Class == 0x02 )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "Ethernet Controller"; }
- if ( SubClass == 0x01 && ProgIF == 0x00 ) { return "Token Ring Controller"; }
- if ( SubClass == 0x02 && ProgIF == 0x00 ) { return "FDDI Controller"; }
- if ( SubClass == 0x03 && ProgIF == 0x00 ) { return "ATM Controller"; }
- if ( SubClass == 0x04 && ProgIF == 0x00 ) { return "ISDN Controller"; }
- if ( SubClass == 0x05 && ProgIF == 0x00 ) { return "WorldFip Controller"; }
- if ( SubClass == 0x05 && ProgIF == 0x00 ) { return "ATA Controller (Chained DMA)"; }
- if ( SubClass == 0x06 ) { return "PICMG 2.14 Multi Computing"; }
- if ( SubClass == 0x80 && ProgIF == 0x00 ) { return "Other Network Controller"; }
- }
- if ( Class == 0x03 )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "VGA-Compatible Controller"; }
- if ( SubClass == 0x00 && ProgIF == 0x01 ) { return "8512-Compatible Controller"; }
- if ( SubClass == 0x01 && ProgIF == 0x00 ) { return "XGA Controller"; }
- if ( SubClass == 0x02 && ProgIF == 0x00 ) { return "3D Controller (Not VGA-Compatible)"; }
- if ( SubClass == 0x80 && ProgIF == 0x00 ) { return "Other Display Controller"; }
- }
- if ( Class == 0x04 )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "Video Device"; }
- if ( SubClass == 0x01 && ProgIF == 0x00 ) { return "Audio Device"; }
- if ( SubClass == 0x02 && ProgIF == 0x00 ) { return "Computer Telephony Device"; }
- if ( SubClass == 0x80 && ProgIF == 0x00 ) { return "Other Multimedia Device"; }
- }
- if ( Class == 0x05 )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "RAM Controller"; }
- if ( SubClass == 0x01 && ProgIF == 0x00 ) { return "Flash Controller"; }
- if ( SubClass == 0x80 && ProgIF == 0x00 ) { return "Other Memory Controller"; }
- }
- if ( Class == 0x06 )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "Host Bridge"; }
- if ( SubClass == 0x01 && ProgIF == 0x00 ) { return "ISA Bridge"; }
- if ( SubClass == 0x02 && ProgIF == 0x00 ) { return "EISA Bridge"; }
- if ( SubClass == 0x03 && ProgIF == 0x00 ) { return "MCA Bridge"; }
- if ( SubClass == 0x04 && ProgIF == 0x00 ) { return "PCI-to-PCI Bridge"; }
- if ( SubClass == 0x04 && ProgIF == 0x01 ) { return "PCI-to-PCI Bridge (Subtractive Decode)"; }
- if ( SubClass == 0x05 && ProgIF == 0x00 ) { return "PCMCIA Bridge"; }
- if ( SubClass == 0x06 && ProgIF == 0x00 ) { return "NuBus Bridge"; }
- if ( SubClass == 0x07 && ProgIF == 0x00 ) { return "CardBus Bridge"; }
- if ( SubClass == 0x08 ) { return "RACEway Bridge"; }
- if ( SubClass == 0x09 && ProgIF == 0x40 ) { return "PCI-to-PCI Bridge (Semi-Transparent, Primary)"; }
- if ( SubClass == 0x09 && ProgIF == 0x80 ) { return "PCI-to-PCI Bridge (Semi-Transparent, Secondary)"; }
- if ( SubClass == 0x0A && ProgIF == 0x00 ) { return "InfiniBrand-to-PCI Host Bridge"; }
- if ( SubClass == 0x80 && ProgIF == 0x00 ) { return "Other Bridge Device"; }
- }
- if ( Class == 0x07 )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "Generic XT-Compatible Serial Controller"; }
- if ( SubClass == 0x00 && ProgIF == 0x01 ) { return "16450-Compatible Serial Controller"; }
- if ( SubClass == 0x00 && ProgIF == 0x02 ) { return "16550-Compatible Serial Controller"; }
- if ( SubClass == 0x00 && ProgIF == 0x03 ) { return "16650-Compatible Serial Controller"; }
- if ( SubClass == 0x00 && ProgIF == 0x04 ) { return "16750-Compatible Serial Controller"; }
- if ( SubClass == 0x00 && ProgIF == 0x05 ) { return "16850-Compatible Serial Controller"; }
- if ( SubClass == 0x00 && ProgIF == 0x06 ) { return "16950-Compatible Serial Controller"; }
- if ( SubClass == 0x01 && ProgIF == 0x00 ) { return "Parallel Port"; }
- if ( SubClass == 0x01 && ProgIF == 0x01 ) { return "Bi-Directional Parallel Port"; }
- if ( SubClass == 0x01 && ProgIF == 0x02 ) { return "ECP 1.X Compliant Parallel Port"; }
- if ( SubClass == 0x01 && ProgIF == 0x03 ) { return "IEEE 1284 Controller"; }
- if ( SubClass == 0x01 && ProgIF == 0xFE ) { return "IEEE 1284 Target Device"; }
- if ( SubClass == 0x02 && ProgIF == 0x00 ) { return "Multiport Serial Controller"; }
- if ( SubClass == 0x03 && ProgIF == 0x00 ) { return "Generic Modem"; }
- if ( SubClass == 0x03 && ProgIF == 0x01 ) { return "Hayes Compatible Modem (16450-Compatible Interface)"; }
- if ( SubClass == 0x03 && ProgIF == 0x02 ) { return "Hayes Compatible Modem (16550-Compatible Interface)"; }
- if ( SubClass == 0x03 && ProgIF == 0x03 ) { return "Hayes Compatible Modem (16650-Compatible Interface)"; }
- if ( SubClass == 0x03 && ProgIF == 0x04 ) { return "Hayes Compatible Modem (16750-Compatible Interface)"; }
- if ( SubClass == 0x04 && ProgIF == 0x00 ) { return "IEEE 488.1/2 (GPIB) Controller"; }
- if ( SubClass == 0x05 && ProgIF == 0x00 ) { return "Smart Card"; }
- if ( SubClass == 0x80 && ProgIF == 0x00 ) { return "Other Communications Device"; }
- }
- if ( Class == 0x08 )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "Generic 8259 PIC"; }
- if ( SubClass == 0x00 && ProgIF == 0x01 ) { return "ISA PIC"; }
- if ( SubClass == 0x00 && ProgIF == 0x02 ) { return "EISA PIC"; }
- if ( SubClass == 0x00 && ProgIF == 0x10 ) { return "I/O APIC Interrupt Controller"; }
- if ( SubClass == 0x00 && ProgIF == 0x20 ) { return "I/O(x) APIC Interrupt Controller"; }
- if ( SubClass == 0x01 && ProgIF == 0x00 ) { return "Generic 8237 DMA Controller"; }
- if ( SubClass == 0x01 && ProgIF == 0x01 ) { return "ISA DMA Controller"; }
- if ( SubClass == 0x01 && ProgIF == 0x02 ) { return "EISA DMA Controller"; }
- if ( SubClass == 0x02 && ProgIF == 0x00 ) { return "Generic 8254 System Timer"; }
- if ( SubClass == 0x02 && ProgIF == 0x01 ) { return "ISA System Timer"; }
- if ( SubClass == 0x02 && ProgIF == 0x02 ) { return "EISA System Timer"; }
- if ( SubClass == 0x03 && ProgIF == 0x00 ) { return "Generic RTC Controller"; }
- if ( SubClass == 0x03 && ProgIF == 0x01 ) { return "ISA RTC Controller"; }
- if ( SubClass == 0x04 && ProgIF == 0x01 ) { return "Generic PCI Hot-Plug Controller"; }
- if ( SubClass == 0x80 && ProgIF == 0x00 ) { return "Other System Peripheral"; }
- }
- if ( Class == 0x09 )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "Keyboard Controller"; }
- if ( SubClass == 0x01 && ProgIF == 0x00 ) { return "Digitizer"; }
- if ( SubClass == 0x02 && ProgIF == 0x00 ) { return "Mouse Controller"; }
- if ( SubClass == 0x03 && ProgIF == 0x00 ) { return "Scanner Controller"; }
- if ( SubClass == 0x04 && ProgIF == 0x00 ) { return "Gameport Controller (Generic)"; }
- if ( SubClass == 0x04 && ProgIF == 0x10 ) { return "Gameport Controller (Legacy)"; }
- if ( SubClass == 0x80 && ProgIF == 0x00 ) { return "Other Input Controller"; }
- }
- if ( Class == 0x0A )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "Generic Docking Station"; }
- if ( SubClass == 0x80 && ProgIF == 0x00 ) { return "Other Docking Station"; }
- }
- if ( Class == 0x0B )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "386 Processor"; }
- if ( SubClass == 0x01 && ProgIF == 0x00 ) { return "486 Processor"; }
- if ( SubClass == 0x02 && ProgIF == 0x00 ) { return "Pentium Processor"; }
- if ( SubClass == 0x10 && ProgIF == 0x00 ) { return "Alpha Processor"; }
- if ( SubClass == 0x20 && ProgIF == 0x00 ) { return "PowerPC Processor"; }
- if ( SubClass == 0x30 && ProgIF == 0x00 ) { return "MIPS Processor"; }
- if ( SubClass == 0x40 && ProgIF == 0x00 ) { return "Co-Processor"; }
- }
- if ( Class == 0x0C )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "IEEE 1394 Controller (FireWire)"; }
- if ( SubClass == 0x00 && ProgIF == 0x10 ) { return "IEEE 1394 Controller (1394 OpenHCI Spec)"; }
- if ( SubClass == 0x01 && ProgIF == 0x00 ) { return "ACCESS.bus"; }
- if ( SubClass == 0x02 && ProgIF == 0x00 ) { return "SSA"; }
- if ( SubClass == 0x03 && ProgIF == 0x00 ) { return "USB (Universal Host Controller Spec)"; }
- if ( SubClass == 0x03 && ProgIF == 0x10 ) { return "USB (Open Host Controller Spec)"; }
- if ( SubClass == 0x03 && ProgIF == 0x20 ) { return "USB2 Host Controller (Intel Enhanced Host Controller Interface)"; }
- if ( SubClass == 0x03 && ProgIF == 0x80 ) { return "USB"; }
- if ( SubClass == 0x03 && ProgIF == 0xFE ) { return "USB (Not Host Controller)"; }
- if ( SubClass == 0x04 && ProgIF == 0x00 ) { return "Fibre Channel"; }
- if ( SubClass == 0x05 && ProgIF == 0x00 ) { return "SMBus"; }
- if ( SubClass == 0x06 && ProgIF == 0x00 ) { return "InfiniBand"; }
- if ( SubClass == 0x07 && ProgIF == 0x00 ) { return "IPMI SMIC Interface"; }
- if ( SubClass == 0x07 && ProgIF == 0x01 ) { return "IPMI Kybd Controller Style Interface"; }
- if ( SubClass == 0x07 && ProgIF == 0x02 ) { return "IPMI Block Transfer Interface"; }
- if ( SubClass == 0x08 && ProgIF == 0x02 ) { return "SERCOS Interface Standard (IEC 61491)"; }
- if ( SubClass == 0x09 && ProgIF == 0x00 ) { return "CANbus"; }
- }
- if ( Class == 0x0E )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "Message FIFO"; }
- if ( SubClass == 0x00 ) { return "I20 Architecture"; }
- }
- if ( Class == 0x0F )
- {
- if ( SubClass == 0x01 && ProgIF == 0x00 ) { return "TV Controller"; }
- if ( SubClass == 0x02 && ProgIF == 0x00 ) { return "Audio Controller"; }
- if ( SubClass == 0x03 && ProgIF == 0x00 ) { return "Voice Controller"; }
- if ( SubClass == 0x04 && ProgIF == 0x00 ) { return "Data Controller"; }
- }
- if ( Class == 0x10 )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "Network and Computing Encryption/Decryption"; }
- if ( SubClass == 0x10 && ProgIF == 0x00 ) { return "Entertainment Encryption/Decryption"; }
- if ( SubClass == 0x80 && ProgIF == 0x00 ) { return "Other Encryption/Decryption"; }
- }
- if ( Class == 0x11 )
- {
- if ( SubClass == 0x00 && ProgIF == 0x00 ) { return "DPIO Modules"; }
- if ( SubClass == 0x01 && ProgIF == 0x00 ) { return "Performance Counters"; }
- if ( SubClass == 0x10 && ProgIF == 0x00 ) { return "Communications Syncrhonization Plus Time and Frequency Test/Measurment"; }
- if ( SubClass == 0x20 && ProgIF == 0x00 ) { return "Management Card"; }
- if ( SubClass == 0x80 && ProgIF == 0x00 ) { return "Other Data Acquisition/Signal Processing Controller"; }
- }
-
- return NULL;
- }
-
- void Init()
- {
- ATA::Init();
-#if 0
- Log::Print("PCI Devices: ");
-
- for ( nat Bus = 0; Bus < 256; Bus++ )
- {
- for ( nat Slot = 0; Slot < 32; Slot++ )
- {
- for ( nat Function = 0; Function < 8; Function++ )
- {
- uint32_t ProductInfo = CheckDevice(Bus, Slot, Function);
-
- if ( ProductInfo == 0xFFFFFFFF ) { continue; }
-
- uint32_t DeviceType = ReadLong(Bus, Slot, Function, 0x08);
-
- const char* DeviceDesc = ToDeviceDesc(ProductInfo, DeviceType);
-
- if ( DeviceDesc != NULL )
- {
- Log::PrintF("%s, ", DeviceDesc);
- }
- else
- {
- Log::PrintF("Unknown PCI Device @ %x:%x.%x (ProductInfo=0x%x, DeviceType=0x%x), ", Bus, Slot, Function, ProductInfo, DeviceType);
- }
- }
- }
- }
-
- Log::Print("\b\b\n");
-#endif
- }
-
- uint32_t ReadLong(uint8_t Bus, uint8_t Slot, uint8_t Function, uint8_t Offset)
- {
- unsigned long LBus = (unsigned long) Bus;
- unsigned long LSlot = (unsigned long) Slot;
- unsigned long LFunc = (unsigned long) Function;
-
- // create configuration address.
- unsigned long Address = (unsigned long) ( (LBus << 16) | (LSlot << 11) | (LFunc << 8) | (Offset & 0xFC) | ((uint32_t) 0x80000000));
-
- // Write out the address.
- CPU::OutPortL(Config_Address, Address);
-
- // Read in the data.
- return CPU::InPortL(Config_Data);
-
- }
-
- uint32_t CheckDevice(uint8_t Bus, uint8_t Slot, uint8_t Function)
- {
- return ReadLong(Bus, Slot, Function, 0);
- }
+// TODO: This is just a hack but will do for now.
+addr_t ParseDevBar0(uint32_t devaddr)
+{
+ uint32_t bar0 = Read32(devaddr, 0x10);
+ if ( bar0 & 0x1 ) // IO Space
+ return bar0 & ~0x7UL;
+ else // Memory Space
+ {
+ //uint32_t type = bar0 >> 1 & 0x3;
+ //uint32_t prefetchable = bar0 >> 3 & 0x1;
+ //if ( type == 0x01 )
+ // // TODO: Support 16-bit addresses here.
+ //if ( type == 0x02 )
+ // // TODO: Support 64-bit addresses here.
+ return bar0 & ~0xFUL;
}
}
+void Init()
+{
+}
+
+} // namespace PCI
+} // namespace Sortix
diff --git a/sortix/pci.h b/sortix/pci.h
deleted file mode 100644
index d545c35f..00000000
--- a/sortix/pci.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/******************************************************************************
-
- COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
-
- This file is part of Sortix.
-
- Sortix is free software: you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation, either version 3 of the License, or (at your option) any later
- version.
-
- Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- details.
-
- You should have received a copy of the GNU General Public License along
- with Sortix. If not, see .
-
- pci.h
- Handles basic PCI bus stuff.
-
-******************************************************************************/
-
-#ifndef SORTIX_PCI_H
-#define SORTIX_PCI_H
-
-namespace Sortix
-{
- namespace PCI
- {
- void Init();
- uint32_t ReadLong(uint8_t Bus, uint8_t Slot, uint8_t Function, uint8_t Offset);
- uint32_t CheckDevice(uint8_t Bus, uint8_t Slot, uint8_t Function = 0);
- }
-}
-
-#endif
-