PciDev::PciDev(const string &name, PCIConfigAll *cf, uint32_t bus,
uint32_t dev, uint32_t func)
- : MMapDevice(name), ConfigSpace(cf), Bus(bus), Device(dev), Function(func)
+ : MMapDevice(name), ConfigSpace(cf), Bus(bus), Device(dev), Function(func), MMU(mmu)
{
memset(config.data, 0, sizeof(config.data));
+ memset(BARAddrs, 0, sizeof(Addr) * 6);
// Setup pointer in config space to point to this entry
if(cf->devices[dev][func] != NULL)
void
PciDev::WriteConfig(int offset, int size, uint32_t data)
{
+ uint32_t barnum;
+
union {
uint8_t byte_value;
uint16_t half_value;
DPRINTF(PCIDEV, "write device: %#x function: %#x register: %#x size: %#x data: %#x\n",
Device, Function, offset, size, word_value);
+ barnum = (offset - PCI0_BASE_ADDR0) >> 2;
+
switch (size) {
case sizeof(uint8_t): // 1-byte access
switch (offset) {
// This is I/O Space, bottom two bits are read only
if(config.data[offset] & 0x1) {
*(uint32_t *)&config.data[offset] =
- ~(BARSize[offset-PCI0_BASE_ADDR0] - 1) | (config.data[offset] & 0x3);
+ ~(BARSize[barnum] - 1) |
+ (config.data[offset] & 0x3);
} else {
// This is memory space, bottom four bits are read only
*(uint32_t *)&config.data[offset] =
- ~(BARSize[(offset-PCI0_BASE_ADDR0)>>2] - 1) | (config.data[offset] & 0xF);
+ ~(BARSize[barnum] - 1) |
+ (config.data[offset] & 0xF);
}
if(config.data[offset] & 0x1) {
*(uint32_t *)&config.data[offset] = (word_value & ~0x3) |
(config.data[offset] & 0x3);
+ if (word_value) {
+ // It's never been set
+ if (BARAddr[barnum] == 0)
+ AddMapping(word_value, BARSize[barnum]-1, MMU);
+ else
+ UpdateMapping(BARAddr[barnum], BARSize[barnum]-1,
+ word_value, BARSize[barnum]-1, MMU);
+ BARAddr[barnum] = word_value;
+ }
+
} else {
// This is memory space, bottom four bits are read only
*(uint32_t *)&config.data[offset] = (word_value & ~0xF) |
#include "mem/functional_mem/mmap_device.hh"
#include "dev/pcireg.h"
+
class PCIConfigAll;
-/*
- * PCI device configuration device.
+/**
+ * PCI device, base implemnation is only config space.
* Each device is connected to a PCIConfigSpace device
* which returns -1 for everything but the pcidevs that
* register with it. This object registers with the PCIConfig space
* object.
*/
-class PciDev : public MMapDevice
+class PciDev : public MmapDevice
{
private:
uint32_t Bus;
PCIConfigAll *ConfigSpace;
PCIConfig config;
uint32_t BARSize[6];
+ Addr BARAddrs[6];
virtual void WriteConfig(int offset, int size, uint32_t data);
virtual void ReadConfig(int offset, int size, uint8_t *data);