gem5  v22.1.0.0
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 
29 #include "dev/lupio/lupio_blk.hh"
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 
50 namespace gem5
51 {
52 
53 LupioBLK::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 
70 void
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 
87 uint64_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 
133 void
134 LupioBLK::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 
171 void
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
183  reqLen = nblk * SECTOR_SIZE;
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 
206 Tick
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 
222 Tick
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:186
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)
Definition: dma_device.hh:214
void dmaRead(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
Definition: dma_device.hh:228
DmaDeviceParams Params
Definition: dma_device.hh:209
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:294
Addr getAddr() const
Definition: packet.hh:805
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:1059
unsigned getSize() const
Definition: packet.hh:815
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)
Definition: addr_range.hh:815
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:178
#define gem5_assert(cond,...)
The assert macro will function like a normal assert, but will use panic instead of straight abort().
Definition: logging.hh:318
#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< 5 > r
Definition: pagetable.hh:60
Bitfield< 63 > val
Definition: misc.hh:776
Bitfield< 3 > addr
Definition: types.hh:84
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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:49

Generated on Wed Dec 21 2022 10:22:33 for gem5 by doxygen 1.9.1