From 92585d60c9c5c34272cb356362bab638d15bcac0 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 20 Jan 2015 08:11:55 -0500 Subject: mem: Move DRAM interleaving check to init This patch fixes a bug where the DRAM controller tried to access the system cacheline size before the system pointer was initialised. It also fixes a bug where the granularity is 0 (no interleaving). --- src/mem/dram_ctrl.cc | 81 ++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/src/mem/dram_ctrl.cc b/src/mem/dram_ctrl.cc index 44ac3d512..e52f03588 100644 --- a/src/mem/dram_ctrl.cc +++ b/src/mem/dram_ctrl.cc @@ -69,7 +69,7 @@ DRAMCtrl::DRAMCtrl(const DRAMCtrlParams* p) : burstSize((devicesPerRank * burstLength * deviceBusWidth) / 8), rowBufferSize(devicesPerRank * deviceRowBufferSize), columnsPerRowBuffer(rowBufferSize / burstSize), - columnsPerStripe(range.granularity() / burstSize), + columnsPerStripe(range.interleaved() ? range.granularity() / burstSize : 1), ranksPerChannel(p->ranks_per_channel), bankGroupsPerRank(p->bank_groups_per_rank), bankGroupArch(p->bank_groups_per_rank > 0), @@ -153,45 +153,6 @@ DRAMCtrl::DRAMCtrl(const DRAMCtrlParams* p) : rowsPerBank = capacity / (rowBufferSize * banksPerRank * ranksPerChannel); - // a bit of sanity checks on the interleaving - if (range.interleaved()) { - if (channels != range.stripes()) - fatal("%s has %d interleaved address stripes but %d channel(s)\n", - name(), range.stripes(), channels); - - if (addrMapping == Enums::RoRaBaChCo) { - if (rowBufferSize != range.granularity()) { - fatal("Channel interleaving of %s doesn't match RoRaBaChCo " - "address map\n", name()); - } - } else if (addrMapping == Enums::RoRaBaCoCh || - addrMapping == Enums::RoCoRaBaCh) { - // for the interleavings with channel bits in the bottom, - // if the system uses a channel striping granularity that - // is larger than the DRAM burst size, then map the - // sequential accesses within a stripe to a number of - // columns in the DRAM, effectively placing some of the - // lower-order column bits as the least-significant bits - // of the address (above the ones denoting the burst size) - assert(columnsPerStripe >= 1); - - // channel striping has to be done at a granularity that - // is equal or larger to a cache line - if (system()->cacheLineSize() > range.granularity()) { - fatal("Channel interleaving of %s must be at least as large " - "as the cache line size\n", name()); - } - - // ...and equal or smaller than the row-buffer size - if (rowBufferSize < range.granularity()) { - fatal("Channel interleaving of %s must be at most as large " - "as the row-buffer size\n", name()); - } - // this is essentially the check above, so just to be sure - assert(columnsPerStripe <= columnsPerRowBuffer); - } - } - // some basic sanity checks if (tREFI <= tRP || tREFI <= tRFC) { fatal("tREFI (%d) must be larger than tRP (%d) and tRFC (%d)\n", @@ -239,6 +200,46 @@ DRAMCtrl::init() } else { port.sendRangeChange(); } + + // a bit of sanity checks on the interleaving, save it for here to + // ensure that the system pointer is initialised + if (range.interleaved()) { + if (channels != range.stripes()) + fatal("%s has %d interleaved address stripes but %d channel(s)\n", + name(), range.stripes(), channels); + + if (addrMapping == Enums::RoRaBaChCo) { + if (rowBufferSize != range.granularity()) { + fatal("Channel interleaving of %s doesn't match RoRaBaChCo " + "address map\n", name()); + } + } else if (addrMapping == Enums::RoRaBaCoCh || + addrMapping == Enums::RoCoRaBaCh) { + // for the interleavings with channel bits in the bottom, + // if the system uses a channel striping granularity that + // is larger than the DRAM burst size, then map the + // sequential accesses within a stripe to a number of + // columns in the DRAM, effectively placing some of the + // lower-order column bits as the least-significant bits + // of the address (above the ones denoting the burst size) + assert(columnsPerStripe >= 1); + + // channel striping has to be done at a granularity that + // is equal or larger to a cache line + if (system()->cacheLineSize() > range.granularity()) { + fatal("Channel interleaving of %s must be at least as large " + "as the cache line size\n", name()); + } + + // ...and equal or smaller than the row-buffer size + if (rowBufferSize < range.granularity()) { + fatal("Channel interleaving of %s must be at most as large " + "as the row-buffer size\n", name()); + } + // this is essentially the check above, so just to be sure + assert(columnsPerStripe <= columnsPerRowBuffer); + } + } } void -- cgit v1.2.3