Added code so that BAR writes will result in an updated memory mapping

dev/pcidev.cc:
dev/pcidev.hh:
    BAR changes should now change the mmu mapping

--HG--
extra : convert_revision : 2d5c60ef076ab0588a25def1ecd9dbb90c9144d7
This commit is contained in:
Ali Saidi 2004-02-04 19:56:24 -05:00
parent aaaa782165
commit 69e1e10f5d
2 changed files with 25 additions and 6 deletions

View file

@ -52,9 +52,10 @@ using namespace std;
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)
@ -93,6 +94,8 @@ PciDev::ReadConfig(int offset, int size, uint8_t *data)
void
PciDev::WriteConfig(int offset, int size, uint32_t data)
{
uint32_t barnum;
union {
uint8_t byte_value;
uint16_t half_value;
@ -103,6 +106,8 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
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) {
@ -146,11 +151,13 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
// 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);
}
@ -159,6 +166,16 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
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) |

View file

@ -35,16 +35,17 @@
#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;
@ -57,6 +58,7 @@ class PciDev : public MMapDevice
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);