gem5 v24.0.0.0
Loading...
Searching...
No Matches
lupio_blk.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 The Regents of the University of California
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
30
31#include "debug/LupioBLK.hh"
32#include "dev/dma_device.hh"
33#include "mem/packet_access.hh"
34#include "params/LupioBLK.hh"
35
36/* Shared fields for CTRL and STAT registers */
37#define LUPIO_BLK_TYPE 0x2
38
39/* Specific fields for CTRL */
40#define LUPIO_BLK_IRQE 0x1
41
42/* Specific fields for STAT */
43#define LUPIO_BLK_BUSY 0x1
44#define LUPIO_BLK_ERRR 0x4
45
46/* Fixed sector size of 512 bytes */
47#define SECTOR_BITS 9
48#define SECTOR_SIZE (1ULL << SECTOR_BITS)
49
50namespace gem5
51{
52
53LupioBLK::LupioBLK(const Params &params) :
54 DmaDevice(params),
55 platform(params.platform),
56 dmaEvent([this]{ dmaEventDone(); }, name()),
57 pioAddr(params.pio_addr),
58 pioSize(params.pio_size),
59 image(*params.image),
60 lupioBLKIntID(params.int_id)
61{
62 static_assert(SECTOR_SIZE == SectorSize, "Sector size of disk image must"
63 " match LupIO device\n");
64 nbBlocks = image.size();
65 gem5_assert(isPowerOf2(nbBlocks));
66 gem5_assert(ceilLog2(nbBlocks) <= 32, "Max number of blocks is 2^32\n");
67 DPRINTF(LupioBLK, "LupioBLK initalized\n");
68}
69
70void
72{
73 int64_t _offset = lba;
74
75 if (writeOp) {
76 for (int i = 0; i < reqLen; i += SECTOR_SIZE, _offset++) {
77 image.write(&reqData[i], _offset);
78 }
79 }
80
81 delete[] reqData;
82 busy = false;
83 DPRINTF(LupioBLK, "Done with DMA event\n");
84 platform->postPciInt(lupioBLKIntID);
85}
86
87uint64_t
89{
90 uint64_t r = 0;
91
92 switch (addr >> 2) {
93 case LUPIO_BLK_CONF:
94 r = SECTOR_BITS << 16 // log2(512B / block)
96 DPRINTF(LupioBLK, "Read LUPIO_BLK_CONF: %d\n", r);
97 break;
98 case LUPIO_BLK_NBLK:
99 r = nblk;
100 DPRINTF(LupioBLK, "Read LUPIO_BLK_NBLK: %d\n", r);
101 break;
102 case LUPIO_BLK_BLKA:
103 r = lba;
104 DPRINTF(LupioBLK, "Read LUPIO_BLK_BLKA: %d\n", r);
105 break;
106 case LUPIO_BLK_MEMA:
107 r = mem;
108 DPRINTF(LupioBLK, "Read LUPIO_BLK_MEMA: %d\n", r);
109 break;
110
111 case LUPIO_BLK_STAT:
112 r = busy;
113 if (writeOp) {
114 r |= LUPIO_BLK_TYPE; // Write command
115 }
116 if (err) {
117 r |= LUPIO_BLK_ERRR; // Error
118 }
119 DPRINTF(LupioBLK, "Read LUPIO_BLK_STAT: %d\n", r);
120
121 // Acknowledge IRQ
122 platform->clearPciInt(lupioBLKIntID);
123 break;
124
125 default:
126 panic("Unexpected read to the LupioBLK device at address"
127 " %#llx!\n", addr);
128 break;
129 }
130 return r;
131}
132
133void
134LupioBLK::lupioBLKWrite(const uint8_t addr, uint64_t val64)
135{
136 uint32_t val = val64;
137
138 switch (addr >> 2) {
139 case LUPIO_BLK_NBLK:
140 nblk = val;
141 DPRINTF(LupioBLK, "Write LUPIO_BLK_NBLK: %d\n", nblk);
142 break;
143 case LUPIO_BLK_BLKA:
144 lba = val;
145 DPRINTF(LupioBLK, "Write LUPIO_BLK_BLKA: %d\n", lba);
146 break;
147 case LUPIO_BLK_MEMA:
148 mem = val;
149 DPRINTF(LupioBLK, "Write LUPIO_BLK_MEMA: %d\n", mem);
150 break;
151
152 case LUPIO_BLK_CTRL:
153 // Perform command
154 if (!busy) {
155 err = false;
157 lupioBLKCmd();
158 } else {
159 panic("Attempting to write to LupioBLK device while transfer"
160 " is ongoing!\n");
161 }
162 break;
163
164 default:
165 panic("Unexpected write to the LupioBLK device at address"
166 " %#llx!\n", addr);
167 break;
168 }
169}
170
171void
173{
174 // Check parameters
175 if ((uint64_t)lba + nblk > nbBlocks) {
176 panic("Bad LBA range\n");
177 }
178
179 // Block device is busy when a transfer occurs
180 busy = true;
181
182 // Perform transfer
184 reqData = new uint8_t[reqLen];
185 int64_t _offset = lba;
186
187 if (!writeOp) {
188 // Read command (block -> mem)
189 for (int i = 0; i < reqLen; i += SECTOR_SIZE, _offset++) {
190 image.read(&reqData[i], _offset);
191 }
193 } else {
194 // Write command (mem -> block)
196 }
197}
198
201{
202 AddrRangeList ranges = { RangeSize(pioAddr, pioSize) };
203 return ranges;
204}
205
206Tick
208{
209 Addr addr = pkt->getAddr() - pioAddr;
210
212 "Read request - addr: %#x, size: %#x\n", addr, pkt->getSize());
213
214 uint64_t read_request = lupioBLKRead(addr);
215 DPRINTF(LupioBLK, "Packet Read: %d\n", read_request);
216 pkt->setUintX(read_request, byteOrder);
217 pkt->makeResponse();
218
219 return pioDelay;
220}
221
222Tick
224{
225 Addr daddr = pkt->getAddr() - pioAddr;
226
227 DPRINTF(LupioBLK, "Write register %#x value %#x\n", daddr,
228 pkt->getUintX(byteOrder));
229
230 lupioBLKWrite(daddr, pkt->getUintX(byteOrder));
231 DPRINTF(LupioBLK, "Packet Write Value: %d\n", pkt->getUintX(byteOrder));
232
233 pkt->makeResponse();
234
235 return pioDelay;
236}
237} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
virtual std::streampos write(const uint8_t *data, std::streampos offset)=0
virtual std::streampos read(uint8_t *data, std::streampos offset) const =0
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
void dmaRead(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
DmaDeviceParams Params
LupioBLK: A virtual block device which aims to provide a disk-like interface for second-level storage...
Definition lupio_blk.hh:51
uint32_t lba
Definition lupio_blk.hh:83
void dmaEventDone()
Definition lupio_blk.cc:71
void lupioBLKCmd(void)
Function to initiate and direct the transfer of data by the DMA device.
Definition lupio_blk.cc:172
uint32_t nblk
Definition lupio_blk.hh:82
AddrRangeList getAddrRanges() const override
Implement BasicPioDevice virtual functions.
Definition lupio_blk.cc:200
uint64_t nbBlocks
Definition lupio_blk.hh:81
uint8_t * reqData
Definition lupio_blk.hh:79
void lupioBLKWrite(const uint8_t addr, uint64_t val64)
Function to write to registers containing data pertaining to block transfers.
Definition lupio_blk.cc:134
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition lupio_blk.cc:223
LupioBLK(const Params &params)
Definition lupio_blk.cc:53
const ByteOrder byteOrder
Definition lupio_blk.hh:53
uint64_t lupioBLKRead(const uint8_t addr)
Function to return data pertaining to blocks being transferred.
Definition lupio_blk.cc:88
DiskImage & image
Definition lupio_blk.hh:59
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition lupio_blk.cc:207
Platform * platform
Definition lupio_blk.hh:54
EventFunctionWrapper dmaEvent
Definition lupio_blk.hh:55
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
Addr getAddr() const
Definition packet.hh:807
void setUintX(uint64_t w, ByteOrder endian)
Set the value in the word w after truncating it to the length of the packet and then byteswapping it ...
Definition packet.cc:361
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
Definition packet.hh:1062
unsigned getSize() const
Definition packet.hh:817
uint64_t getUintX(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness and zero-extended to 64 bits.
Definition packet.cc:352
#define SectorSize
Definition disk_image.hh:44
AddrRange RangeSize(Addr start, Addr size)
static constexpr std::enable_if_t< std::is_integral_v< T >, int > floorLog2(T x)
Definition intmath.hh:59
static constexpr int ceilLog2(const T &n)
Definition intmath.hh:84
static constexpr bool isPowerOf2(const T &n)
Definition intmath.hh:98
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define gem5_assert(cond,...)
The assert macro will function like a normal assert, but will use panic instead of straight abort().
Definition logging.hh:317
#define LUPIO_BLK_ERRR
Definition lupio_blk.cc:44
#define SECTOR_SIZE
Definition lupio_blk.cc:48
#define LUPIO_BLK_TYPE
Definition lupio_blk.cc:37
#define SECTOR_BITS
Definition lupio_blk.cc:47
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 63 > val
Definition misc.hh:804
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
uint64_t Tick
Tick count type.
Definition types.hh:58
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:24:03 for gem5 by doxygen 1.11.0