Have bus use the BadAddress device to handle bad addresses. The O3 CPU should be able to boot into Linux with caches on after this change.
src/mem/bus.cc: src/mem/bus.hh: Bus now will be setup with a default responder, unless the user overrides it. This default responder should return BadAddress if no matching port is found. src/python/m5/objects/Bus.py: Bus now has a default responder for FS mode if the user doesn't override it. It returns BadAddress if no matching port is found. src/python/m5/objects/Tsunami.py: Add bad address device. Also record when the user has specified their own default responder. --HG-- extra : convert_revision : 59070477ae313ee711b2d59baa2369c9a91c5b85
This commit is contained in:
parent
c3485a6548
commit
45363ea658
|
@ -42,13 +42,14 @@
|
||||||
Port *
|
Port *
|
||||||
Bus::getPort(const std::string &if_name, int idx)
|
Bus::getPort(const std::string &if_name, int idx)
|
||||||
{
|
{
|
||||||
if (if_name == "default")
|
if (if_name == "default") {
|
||||||
if (defaultPort == NULL) {
|
if (defaultPort == NULL) {
|
||||||
defaultPort = new BusPort(csprintf("%s-default",name()), this,
|
defaultPort = new BusPort(csprintf("%s-default",name()), this,
|
||||||
defaultId);
|
defaultId);
|
||||||
return defaultPort;
|
return defaultPort;
|
||||||
} else
|
} else
|
||||||
fatal("Default port already set\n");
|
fatal("Default port already set\n");
|
||||||
|
}
|
||||||
|
|
||||||
// if_name ignored? forced to be empty?
|
// if_name ignored? forced to be empty?
|
||||||
int id = interfaces.size();
|
int id = interfaces.size();
|
||||||
|
@ -269,7 +270,16 @@ Bus::findPort(Addr addr, int id)
|
||||||
return defaultPort;
|
return defaultPort;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic("Unable to find destination for addr: %#llx", addr);
|
|
||||||
|
if (responderSet) {
|
||||||
|
panic("Unable to find destination for addr (user set default "
|
||||||
|
"responder): %#llx", addr);
|
||||||
|
} else {
|
||||||
|
DPRINTF(Bus, "Unable to find destination for addr: %#llx, will use "
|
||||||
|
"default port", addr);
|
||||||
|
|
||||||
|
return defaultPort;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -392,12 +402,15 @@ Bus::recvStatusChange(Port::Status status, int id)
|
||||||
|
|
||||||
if (id == defaultId) {
|
if (id == defaultId) {
|
||||||
defaultRange.clear();
|
defaultRange.clear();
|
||||||
defaultPort->getPeerAddressRanges(ranges, snoops);
|
// Only try to update these ranges if the user set a default responder.
|
||||||
assert(snoops.size() == 0);
|
if (responderSet) {
|
||||||
for(iter = ranges.begin(); iter != ranges.end(); iter++) {
|
defaultPort->getPeerAddressRanges(ranges, snoops);
|
||||||
defaultRange.push_back(*iter);
|
assert(snoops.size() == 0);
|
||||||
DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n",
|
for(iter = ranges.begin(); iter != ranges.end(); iter++) {
|
||||||
iter->start, iter->end);
|
defaultRange.push_back(*iter);
|
||||||
|
DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n",
|
||||||
|
iter->start, iter->end);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -503,18 +516,20 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus)
|
||||||
Param<int> bus_id;
|
Param<int> bus_id;
|
||||||
Param<int> clock;
|
Param<int> clock;
|
||||||
Param<int> width;
|
Param<int> width;
|
||||||
|
Param<bool> responder_set;
|
||||||
|
|
||||||
END_DECLARE_SIM_OBJECT_PARAMS(Bus)
|
END_DECLARE_SIM_OBJECT_PARAMS(Bus)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(Bus)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(Bus)
|
||||||
INIT_PARAM(bus_id, "a globally unique bus id"),
|
INIT_PARAM(bus_id, "a globally unique bus id"),
|
||||||
INIT_PARAM(clock, "bus clock speed"),
|
INIT_PARAM(clock, "bus clock speed"),
|
||||||
INIT_PARAM(width, "width of the bus (bits)")
|
INIT_PARAM(width, "width of the bus (bits)"),
|
||||||
|
INIT_PARAM(responder_set, "Is a default responder set by the user")
|
||||||
END_INIT_SIM_OBJECT_PARAMS(Bus)
|
END_INIT_SIM_OBJECT_PARAMS(Bus)
|
||||||
|
|
||||||
CREATE_SIM_OBJECT(Bus)
|
CREATE_SIM_OBJECT(Bus)
|
||||||
{
|
{
|
||||||
return new Bus(getInstanceName(), bus_id, clock, width);
|
return new Bus(getInstanceName(), bus_id, clock, width, responder_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_SIM_OBJECT("Bus", Bus)
|
REGISTER_SIM_OBJECT("Bus", Bus)
|
||||||
|
|
|
@ -240,6 +240,9 @@ class Bus : public MemObject
|
||||||
/** Port that handles requests that don't match any of the interfaces.*/
|
/** Port that handles requests that don't match any of the interfaces.*/
|
||||||
BusPort *defaultPort;
|
BusPort *defaultPort;
|
||||||
|
|
||||||
|
/** Has the user specified their own default responder? */
|
||||||
|
bool responderSet;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** A function used to return the port associated with this bus object. */
|
/** A function used to return the port associated with this bus object. */
|
||||||
|
@ -247,9 +250,11 @@ class Bus : public MemObject
|
||||||
|
|
||||||
virtual void init();
|
virtual void init();
|
||||||
|
|
||||||
Bus(const std::string &n, int bus_id, int _clock, int _width)
|
Bus(const std::string &n, int bus_id, int _clock, int _width,
|
||||||
|
bool responder_set)
|
||||||
: MemObject(n), busId(bus_id), clock(_clock), width(_width),
|
: MemObject(n), busId(bus_id), clock(_clock), width(_width),
|
||||||
tickNextIdle(0), busIdle(this), inRetry(false), defaultPort(NULL)
|
tickNextIdle(0), busIdle(this), inRetry(false), defaultPort(NULL),
|
||||||
|
responderSet(responder_set)
|
||||||
{
|
{
|
||||||
//Both the width and clock period must be positive
|
//Both the width and clock period must be positive
|
||||||
if (width <= 0)
|
if (width <= 0)
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
|
from m5 import build_env
|
||||||
from m5.params import *
|
from m5.params import *
|
||||||
|
from m5.proxy import *
|
||||||
from MemObject import MemObject
|
from MemObject import MemObject
|
||||||
|
from Tsunami import BadAddr
|
||||||
|
|
||||||
class Bus(MemObject):
|
class Bus(MemObject):
|
||||||
type = 'Bus'
|
type = 'Bus'
|
||||||
port = VectorPort("vector port for connecting devices")
|
port = VectorPort("vector port for connecting devices")
|
||||||
default = Port("Default port for requests that aren't handeled by a device.")
|
|
||||||
bus_id = Param.Int(0, "blah")
|
bus_id = Param.Int(0, "blah")
|
||||||
clock = Param.Clock("1GHz", "bus clock speed")
|
clock = Param.Clock("1GHz", "bus clock speed")
|
||||||
width = Param.Int(64, "bus width (bytes)")
|
width = Param.Int(64, "bus width (bytes)")
|
||||||
|
responder_set = Param.Bool(False, "Did the user specify a default responder.")
|
||||||
|
if build_env['FULL_SYSTEM']:
|
||||||
|
default = Port(Self.responder.pio, "Default port for requests that aren't handled by a device.")
|
||||||
|
responder = BadAddr(pio_addr=0x0, pio_latency="1ps")
|
||||||
|
else:
|
||||||
|
default = Port("Default port for requests that aren't handled by a device.")
|
||||||
|
|
|
@ -15,6 +15,9 @@ class IsaFake(BasicPioDevice):
|
||||||
type = 'IsaFake'
|
type = 'IsaFake'
|
||||||
pio_size = Param.Addr(0x8, "Size of address range")
|
pio_size = Param.Addr(0x8, "Size of address range")
|
||||||
|
|
||||||
|
class BadAddr(BasicPioDevice):
|
||||||
|
type = 'BadAddr'
|
||||||
|
|
||||||
class TsunamiIO(BasicPioDevice):
|
class TsunamiIO(BasicPioDevice):
|
||||||
type = 'TsunamiIO'
|
type = 'TsunamiIO'
|
||||||
time = Param.UInt64(1136073600,
|
time = Param.UInt64(1136073600,
|
||||||
|
@ -70,6 +73,7 @@ class Tsunami(Platform):
|
||||||
self.cchip.pio = bus.port
|
self.cchip.pio = bus.port
|
||||||
self.pchip.pio = bus.port
|
self.pchip.pio = bus.port
|
||||||
self.pciconfig.pio = bus.default
|
self.pciconfig.pio = bus.default
|
||||||
|
bus.responder_set = True
|
||||||
self.fake_sm_chip.pio = bus.port
|
self.fake_sm_chip.pio = bus.port
|
||||||
self.fake_uart1.pio = bus.port
|
self.fake_uart1.pio = bus.port
|
||||||
self.fake_uart2.pio = bus.port
|
self.fake_uart2.pio = bus.port
|
||||||
|
|
Loading…
Reference in a new issue