summaryrefslogtreecommitdiff
path: root/src/mem/cache/miss/blocking_buffer.hh
blob: 39a06a3779afb53db1a2070ab17f0f855d3e7d33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/*
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Erik Hallnor
 */

/**
 * @file
 * Declaration of a simple buffer for a blocking cache.
 */

#ifndef __BLOCKING_BUFFER_HH__
#define __BLOCKING_BUFFER_HH__

#include <vector>

#include "mem/cache/miss/mshr.hh"
#include "base/statistics.hh"

class BaseCache;
class BasePrefetcher;

/**
 * Miss and writeback storage for a blocking cache.
 */
class BlockingBuffer
{
protected:
    /** Miss storage. */
    MSHR miss;
    /** WB storage. */
    MSHR wb;

    //Params

    /** Allocate on write misses. */
    const bool writeAllocate;

    /** Pointer to the parent cache. */
    BaseCache* cache;

    BasePrefetcher* prefetcher;

    /** Block size of the parent cache. */
    int blkSize;

    // Statistics
    /**
     * @addtogroup CacheStatistics
     * @{
     */
    /** Number of blocks written back per thread. */
    Stats::Vector<> writebacks;

    /**
     * @}
     */

public:
    /**
     * Builds and initializes this buffer.
     * @param write_allocate If true, treat write misses the same as reads.
     */
    BlockingBuffer(bool write_allocate)
        : writeAllocate(write_allocate)
    {
    }

    /**
     * Register statistics for this object.
     * @param name The name of the parent cache.
     */
    void regStats(const std::string &name);

    /**
     * Called by the parent cache to set the back pointer.
     * @param _cache A pointer to the parent cache.
     */
    void setCache(BaseCache *_cache);

    void setPrefetcher(BasePrefetcher *_prefetcher);

    /**
     * Handle a cache miss properly. Requests the bus and marks the cache as
     * blocked.
     * @param req The request that missed in the cache.
     * @param blk_size The block size of the cache.
     * @param time The time the miss is detected.
     */
    void handleMiss(Packet * &pkt, int blk_size, Tick time);

    /**
     * Fetch the block for the given address and buffer the given target.
     * @param addr The address to fetch.
     * @param asid The address space of the address.
     * @param blk_size The block size of the cache.
     * @param time The time the miss is detected.
     * @param target The target for the fetch.
     */
    MSHR* fetchBlock(Addr addr, int asid, int blk_size, Tick time,
                     Packet * &target)
    {
        fatal("Unimplemented");
    }

    /**
     * Selects a outstanding request to service.
     * @return The request to service, NULL if none found.
     */
    Packet * getPacket();

    /**
     * Set the command to the given bus command.
     * @param req The request to update.
     * @param cmd The bus command to use.
     */
    void setBusCmd(Packet * &pkt, Packet::Command cmd);

    /**
     * Restore the original command in case of a bus transmission error.
     * @param req The request to reset.
     */
    void restoreOrigCmd(Packet * &pkt);

    /**
     * Marks a request as in service (sent on the bus). This can have side
     * effect since storage for no response commands is deallocated once they
     * are successfully sent.
     * @param req The request that was sent on the bus.
     */
    void markInService(Packet * &pkt);

    /**
     * Frees the resources of the request and unblock the cache.
     * @param req The request that has been satisfied.
     * @param time The time when the request is satisfied.
     */
    void handleResponse(Packet * &pkt, Tick time);

    /**
     * Removes all outstanding requests for a given thread number. If a request
     * has been sent to the bus, this function removes all of its targets.
     * @param req->getThreadNum()ber The thread number of the requests to squash.
     */
    void squash(int threadNum);

    /**
     * Return the current number of outstanding misses.
     * @return the number of outstanding misses.
     */
    int getMisses()
    {
        return miss.getNumTargets();
    }

    /**
     * Searches for the supplied address in the miss "queue".
     * @param addr The address to look for.
     * @param asid The address space id.
     * @return A pointer to miss if it matches.
     */
    MSHR* findMSHR(Addr addr, int asid)
    {
        if (miss.addr == addr && miss.pkt)
            return &miss;
        return NULL;
    }

    /**
     * Searches for the supplied address in the write buffer.
     * @param addr The address to look for.
     * @param asid The address space id.
     * @param writes List of pointers to the matching writes.
     * @return True if there is a matching write.
     */
    bool findWrites(Addr addr, int asid, std::vector<MSHR*>& writes)
    {
        if (wb.addr == addr && wb.pkt) {
            writes.push_back(&wb);
            return true;
        }
        return false;
    }



    /**
     * Perform a writeback of dirty data to the given address.
     * @param addr The address to write to.
     * @param asid The address space id.
     * @param size The number of bytes to write.
     * @param data The data to write, can be NULL.
     * @param compressed True if the data is compressed.
     */
    void doWriteback(Addr addr, int asid,
                     int size, uint8_t *data, bool compressed);

    /**
     * Perform a writeback request.
     * @param req The writeback request.
     */
    void doWriteback(Packet * &pkt);

    /**
     * Returns true if there are outstanding requests.
     * @return True if there are outstanding requests.
     */
    bool havePending()
    {
        return !miss.inService || !wb.inService;
    }

    /**
     * Add a target to the given MSHR. This assumes it is in the miss queue.
     * @param mshr The mshr to add a target to.
     * @param req The target to add.
     */
    void addTarget(MSHR *mshr, Packet * &pkt)
    {
        fatal("Shouldn't call this on a blocking buffer.");
    }

    /**
     * Dummy implmentation.
     */
    MSHR* allocateTargetList(Addr addr, int asid)
    {
        fatal("Unimplemented");
    }
};

#endif // __BLOCKING_BUFFER_HH__