PCI Basics

Added PCI enumeration and structures. Kind of.
alentours-dev
q3k 2012-10-28 12:24:43 +01:00
parent 2612fe8bc4
commit 5eb8f32864
8 changed files with 203 additions and 8 deletions

View File

@ -73,6 +73,13 @@ TIER1OBJ := $(patsubst %.asm,%.nao,$(TIER1OBJ))
TIER1 := $(foreach i, $(TIER1OBJ), obj/$(i))
Tier1: $(TIER1)
ALENTOURSSRC := $(shell find src/Alentours -mindepth 1 -maxdepth 3 -name "*.cpp")
ALENTOURSSRC += $(shell find src/Alentours -mindepth 1 -maxdepth 3 -name "*.asm")
ALENTOURSOBJ := $(patsubst %.cpp,%.xo,$(ALENTOURSSRC))
ALENTOURSOBJ := $(patsubst %.asm,%.nao,$(ALENTOURSOBJ))
ALENTOURS := $(foreach i, $(ALENTOURSOBJ), obj/$(i))
Alentours: $(ALENTOURS)
src/Lua/liblua.a:
@echo "[i] Building Lua..."
@make -C src/Lua
@ -80,9 +87,9 @@ src/Lua/liblua.a:
LUA := src/Lua/liblua.a
Lua: $(LUA)
kernel.bin: version-gen Tier0 Tier1 Lua
kernel.bin: version-gen Tier0 Tier1 Lua Alentours
@echo "[i] Linking kernel.bin..."
@$(LD) -T src/kernel.ld -o kernel.bin $(TIER0) $(TIER1) -Lsrc/Lua -llua
@$(LD) -T src/kernel.ld -o kernel.bin $(TIER0) $(TIER1) $(ALENTOURS) -Lsrc/Lua -llua
hdd.img: kernel.bin
@echo "[i] Creating HDD image..."

View File

@ -0,0 +1,74 @@
#ifndef __PCI_H__
#define __PCI_H__
// ports for PCI config on IA-32(e)
#define PCI_CONFIG_ADDRESS 0xCF8
#define PCI_CONFIG_DATA 0xCFC
#include "types.h"
#include "Tier1/Util/CVector.h"
namespace Alentours
{
// structure representing the configuration register internals
typedef struct
{
u8 Zero : 2;
u8 Register : 6;
u8 Function : 3;
u8 Device : 5;
u8 Bus : 8;
u8 Reserved : 7;
u8 Enable : 1;
} __attribute__((packed)) TPCIConfigAddressFields;
typedef union
{
TPCIConfigAddressFields Fields;
u32 Value;
} TPCIConfigAddress;
typedef struct
{
u16 VendorID;
u16 ProductID;
u16 Command;
u16 Code;
u8 Revision;
u8 ProgInterface;
u8 Subclass;
u8 Class;
u8 CacheLineSize;
u8 LatencyTimer;
u8 HeaderType : 7;
u8 MultiFunction : 1;
u8 BIST;
} __attribute__((packed)) TPCIHeaderCommon;
class CPCIDevice
{
private:
u16 m_Bus, m_Device;
TPCIHeaderCommon m_Header;
public:
CPCIDevice(u16 Bus, u16 Device);
u32 ConfigRead(u16 Function, u16 Offset);
};
class CPCIManager
{
private:
static cb::CVector<CPCIDevice> m_Devices;
static u8 DevicePresent(u16 Bus, u16 Device);
static u32 ConfigRead(u16 Bus, u16 Device, u16 Function, u16 Offset);
public:
static void Initialize(void);
static u32 GetDeviceCount(void);
static CPCIDevice *GetDeviceByIndex(void);
static CPCIDevice *GetDeviceByAddress(u16 Bus, u16 Device);
static void GetDeviceByIDPair(cb::CVector<CPCIDevice> &Devices, u16 Vendor, u16 Device);
static void GetAllDevices(cb::CVector<CPCIDevice> &Devices);
};
};
#endif

View File

@ -21,6 +21,7 @@ void kputi(s32 Number);
void kprintf(const s8 *Format, ...);
void kdump(u8 *bData, u32 Length);
void kprint_hex(u64 Number);
void kprint_hex_16(u16 Number);
void kstdio_set_globals(u8 line, u8 cur_x, u8 cur_y);
s32 kmemcmp(const u8 *MemA, const u8 *MemB, u32 Length);

View File

@ -0,0 +1,92 @@
#include "Alentours/PCI.h"
extern "C" {
#include "Tier0/kstdio.h"
}
using namespace Alentours;
u32 CPCIManager::ConfigRead(u16 Bus, u16 Device, u16 Function, u16 Offset)
{
TPCIConfigAddress Address;
Address.Fields.Zero = 0;
Address.Fields.Register = Offset >> 2;
Address.Fields.Function = Function;
Address.Fields.Device = Device;
Address.Fields.Bus = Bus;
Address.Fields.Reserved = 0;
Address.Fields.Enable = 1;
koutl(PCI_CONFIG_ADDRESS, Address.Value);
return kinl(PCI_CONFIG_DATA);
}
u8 CPCIManager::DevicePresent(u16 Bus, u16 Device)
{
// try to get the VID & PID pair - if all 1's, then no device is present
u32 Value = CPCIManager::ConfigRead(Bus, Device, 0, 0);
return (Value != 0xFFFFFFFF);
}
void CPCIManager::Initialize(void)
{
for (u16 BusID = 0; BusID < 256; BusID++)
{
for (u8 DeviceID = 0; DeviceID < 32; DeviceID++)
{
u8 Present = DevicePresent(BusID, DeviceID);
if (Present)
{
CPCIDevice Device(BusID, DeviceID);
m_Devices.Push(Device);
}
}
}
}
u32 CPCIDevice::ConfigRead(u16 Function, u16 Offset)
{
TPCIConfigAddress Address;
Address.Fields.Zero = 0;
Address.Fields.Register = Offset >> 2;
Address.Fields.Function = Function;
Address.Fields.Device = m_Device;
Address.Fields.Bus = m_Bus;
Address.Fields.Reserved = 0;
Address.Fields.Enable = 1;
koutl(PCI_CONFIG_ADDRESS, Address.Value);
return kinl(PCI_CONFIG_DATA);
}
CPCIDevice::CPCIDevice(u16 Bus, u16 Device)
{
m_Bus = Bus;
m_Device = Device;
kprintf("PCI device [%i:%i]\n", Bus, Device);
for (u8 i = 0; i < sizeof(m_Header); i += 4)
{
u32 Value = ConfigRead(0, i);
((u32 *)&m_Header)[i/4] = Value;
}
kprintf(" VID: %h, PID: %h\n", m_Header.VendorID, m_Header.ProductID);
kprintf(" Type: ");
switch (m_Header.HeaderType)
{
case 0x00:
kprintf("Generic Device\n");
break;
case 0x01:
kprintf("PCI-PCI Bridge\n");
break;
case 0x02:
kprintf("CardBus Bridge\n");
break;
default:
kprintf("Unknown.\n");
break;
}
}
cb::CVector<CPCIDevice> CPCIManager::m_Devices;

View File

@ -27,7 +27,7 @@ void __cxa_pure_virtual()
kprintf("[e] A pure virtual call happened. WTF?\n");
}
int __cxa_atexit(void (*f)(void *), void *objptr, void *dso)
int __cxa_atexit(void (*f)(void *), void *arg, void *__dso_handle)
{
// Do nothing, for now.
return 0;
@ -37,3 +37,5 @@ void __cxa_finalize(void *f)
{
// -- " -- " --
}
void *__dso_handle = 0;

View File

@ -123,9 +123,17 @@ void kprintf(const s8 *szFormat, ...)
}
case 'X':
case 'x':
; u64 bData = va_arg(ap, u64);
kprint_hex(bData);
break;
{
u64 bData = va_arg(ap, u64);
kprint_hex(bData);
break;
}
case 'h':
{
u16 bData = va_arg(ap, u32);
kprint_hex_16(bData);
break;
}
default:
kprintf("printf: Unknown escape character %c!\n", szFormat[Offset + 1]);
}
@ -212,6 +220,16 @@ void kprint_hex(u64 Number)
}
}
void kprint_hex_16(u16 Number)
{
for (s8 i = 1; i >= 0; i--)
{
u8 Byte = (Number >> (i << 3)) & 0xFF; //switch i bytes to the right and mask as byte
kdump_nibble((Byte >> 4) & 0x0F); //high nibble
kdump_nibble(Byte & 0x0F); //low nibble
}
}
void kdump(u8 *bData, u32 Length)
{
for (u32 i = 0; i < Length; i++)

View File

@ -6,6 +6,7 @@
#include "Tier1/Util/CVector.h"
#include "Tier1/Util/CLinearList.h"
//#include "Tier1/CTimer.h"
#include "Alentours/PCI.h"
using namespace cb;
@ -43,7 +44,7 @@ void CKernel::Start(void)
}
m_Logger = new CLogger();
Alentours::CPCIManager::Initialize();
/*CTask *KernelTask = CreateKernelTask();
kprintf("[i] Kernel task has TID %i.\n", KernelTask->GetPID());
CScheduler::AddTask(KernelTask);

View File

@ -13,7 +13,7 @@ SECTIONS
{
_code = .;
*(.text)
*(.text.startup)
*(.text.*)
*(.rodata*)
. = ALIGN(8);