chunk_generator.hh revision 2632:1bb2f91485ea
1955SN/A/* 2955SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan 39812Sandreas.hansson@arm.com * All rights reserved. 49812Sandreas.hansson@arm.com * 59812Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 69812Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 79812Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 89812Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 99812Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 109812Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 119812Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 129812Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 139812Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 149812Sandreas.hansson@arm.com * this software without specific prior written permission. 157816Ssteve.reinhardt@amd.com * 165871Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171762SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27955SN/A */ 28955SN/A 29955SN/A#ifndef __BASE__CHUNK_GENERATOR_HH__ 30955SN/A#define __BASE__CHUNK_GENERATOR_HH__ 31955SN/A 32955SN/A/** 33955SN/A * @file 34955SN/A * Declaration and inline definition of ChunkGenerator object. 35955SN/A */ 36955SN/A 37955SN/A#include <algorithm> 38955SN/A#include "base/intmath.hh" 39955SN/A#include "arch/isa_traits.hh" // for Addr 40955SN/A 41955SN/A/** 422665Ssaidi@eecs.umich.edu * This class takes an arbitrary memory region (address/length pair) 432665Ssaidi@eecs.umich.edu * and generates a series of appropriately (e.g. block- or page-) 445863Snate@binkert.org * aligned chunks covering the same region. 45955SN/A * 46955SN/A * Example usage: 47955SN/A 48955SN/A\code 49955SN/A for (ChunkGenerator gen(addr, size, chunkSize); !gen.done(); gen.next()) { 508878Ssteve.reinhardt@amd.com doSomethingChunky(gen.addr(), gen.size()); 512632Sstever@eecs.umich.edu } 528878Ssteve.reinhardt@amd.com\endcode 532632Sstever@eecs.umich.edu */ 54955SN/Aclass ChunkGenerator 558878Ssteve.reinhardt@amd.com{ 562632Sstever@eecs.umich.edu private: 572761Sstever@eecs.umich.edu /** The starting address of the current chunk. */ 582632Sstever@eecs.umich.edu Addr curAddr; 592632Sstever@eecs.umich.edu /** The starting address of the next chunk (after the current one). */ 602632Sstever@eecs.umich.edu Addr nextAddr; 612761Sstever@eecs.umich.edu /** The size of the current chunk (in bytes). */ 622761Sstever@eecs.umich.edu int curSize; 632761Sstever@eecs.umich.edu /** The number of bytes remaining in the region after the current chunk. */ 648878Ssteve.reinhardt@amd.com int sizeLeft; 658878Ssteve.reinhardt@amd.com /** The start address so we can calculate offset in writing block. */ 662761Sstever@eecs.umich.edu const Addr startAddr; 672761Sstever@eecs.umich.edu /** The maximum chunk size, e.g., the cache block size or page size. */ 682761Sstever@eecs.umich.edu const int chunkSize; 692761Sstever@eecs.umich.edu 702761Sstever@eecs.umich.edu public: 718878Ssteve.reinhardt@amd.com /** 728878Ssteve.reinhardt@amd.com * Constructor. 732632Sstever@eecs.umich.edu * @param startAddr The starting address of the region. 742632Sstever@eecs.umich.edu * @param totalSize The total size of the region. 758878Ssteve.reinhardt@amd.com * @param _chunkSize The size/alignment of chunks into which 768878Ssteve.reinhardt@amd.com * the region should be decomposed. 772632Sstever@eecs.umich.edu */ 78955SN/A ChunkGenerator(Addr _startAddr, int totalSize, int _chunkSize) 79955SN/A : startAddr(_startAddr), chunkSize(_chunkSize) 80955SN/A { 815863Snate@binkert.org // chunkSize must be a power of two 825863Snate@binkert.org assert(chunkSize == 0 || isPowerOf2(chunkSize)); 835863Snate@binkert.org 845863Snate@binkert.org // set up initial chunk. 855863Snate@binkert.org curAddr = startAddr; 865863Snate@binkert.org 875863Snate@binkert.org if (chunkSize == 0) //Special Case, if we see 0, assume no chuncking 885863Snate@binkert.org { 895863Snate@binkert.org nextAddr = startAddr + totalSize; 905863Snate@binkert.org } 915863Snate@binkert.org else 928878Ssteve.reinhardt@amd.com { 935863Snate@binkert.org // nextAddr should be *next* chunk start 945863Snate@binkert.org nextAddr = roundUp(startAddr, chunkSize); 955863Snate@binkert.org if (curAddr == nextAddr) { 969812Sandreas.hansson@arm.com // ... even if startAddr is already chunk-aligned 979812Sandreas.hansson@arm.com nextAddr += chunkSize; 985863Snate@binkert.org } 999812Sandreas.hansson@arm.com } 1005863Snate@binkert.org 1015863Snate@binkert.org // how many bytes are left between curAddr and the end of this chunk? 1025863Snate@binkert.org int left_in_chunk = nextAddr - curAddr; 1039812Sandreas.hansson@arm.com curSize = std::min(totalSize, left_in_chunk); 1049812Sandreas.hansson@arm.com sizeLeft = totalSize - curSize; 1055863Snate@binkert.org } 1065863Snate@binkert.org 1078878Ssteve.reinhardt@amd.com /** Return starting address of current chunk. */ 1085863Snate@binkert.org Addr addr() { return curAddr; } 1095863Snate@binkert.org /** Return size in bytes of current chunk. */ 1105863Snate@binkert.org int size() { return curSize; } 1116654Snate@binkert.org 112955SN/A /** Number of bytes we have already chunked up. */ 1135396Ssaidi@eecs.umich.edu int complete() { return curAddr - startAddr; } 1145863Snate@binkert.org /** 1155863Snate@binkert.org * Are we done? That is, did the last call to next() advance 1164202Sbinkertn@umich.edu * past the end of the region? 1175863Snate@binkert.org * @return True if yes, false if more to go. 1185863Snate@binkert.org */ 1195863Snate@binkert.org bool done() { return (curSize == 0); } 1205863Snate@binkert.org 121955SN/A /** 1226654Snate@binkert.org * Advance generator to next chunk. 1235273Sstever@gmail.com * @return True if successful, false if unsuccessful 1245871Snate@binkert.org * (because we were at the last chunk). 1255273Sstever@gmail.com */ 1266655Snate@binkert.org bool next() 1278878Ssteve.reinhardt@amd.com { 1286655Snate@binkert.org if (sizeLeft == 0) { 1296655Snate@binkert.org curSize = 0; 1309219Spower.jg@gmail.com return false; 1316655Snate@binkert.org } 1325871Snate@binkert.org 1336654Snate@binkert.org curAddr = nextAddr; 1348947Sandreas.hansson@arm.com curSize = std::min(sizeLeft, chunkSize); 1355396Ssaidi@eecs.umich.edu sizeLeft -= curSize; 1368120Sgblack@eecs.umich.edu nextAddr += curSize; 1378120Sgblack@eecs.umich.edu return true; 1388120Sgblack@eecs.umich.edu } 1398120Sgblack@eecs.umich.edu}; 1408120Sgblack@eecs.umich.edu 1418120Sgblack@eecs.umich.edu#endif // __BASE__CHUNK_GENERATOR_HH__ 1428120Sgblack@eecs.umich.edu