13898Ssaidi@eecs.umich.edu/*
23898Ssaidi@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan
33898Ssaidi@eecs.umich.edu * All rights reserved.
43898Ssaidi@eecs.umich.edu *
53898Ssaidi@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
63898Ssaidi@eecs.umich.edu * modification, are permitted provided that the following conditions are
73898Ssaidi@eecs.umich.edu * met: redistributions of source code must retain the above copyright
83898Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
93898Ssaidi@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
103898Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
113898Ssaidi@eecs.umich.edu * documentation and/or other materials provided with the distribution;
123898Ssaidi@eecs.umich.edu * neither the name of the copyright holders nor the names of its
133898Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from
143898Ssaidi@eecs.umich.edu * this software without specific prior written permission.
153898Ssaidi@eecs.umich.edu *
163898Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173898Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183898Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193898Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203898Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213898Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223898Ssaidi@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233898Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243898Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253898Ssaidi@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263898Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273898Ssaidi@eecs.umich.edu *
283898Ssaidi@eecs.umich.edu * Authors: Ali Saidi
293898Ssaidi@eecs.umich.edu */
303898Ssaidi@eecs.umich.edu
313898Ssaidi@eecs.umich.edu/** @file
323898Ssaidi@eecs.umich.edu * This device acts as a disk similar to the memory mapped disk device
333898Ssaidi@eecs.umich.edu * in legion. Any access is translated to an offset in the disk image.
343898Ssaidi@eecs.umich.edu */
353898Ssaidi@eecs.umich.edu
3611793Sbrandon.potter@amd.com#include "dev/sparc/mm_disk.hh"
3711793Sbrandon.potter@amd.com
383918Ssaidi@eecs.umich.edu#include <cstring>
393918Ssaidi@eecs.umich.edu
403898Ssaidi@eecs.umich.edu#include "base/trace.hh"
418232Snate@binkert.org#include "debug/IdeDisk.hh"
423898Ssaidi@eecs.umich.edu#include "dev/platform.hh"
438229Snate@binkert.org#include "mem/packet_access.hh"
443898Ssaidi@eecs.umich.edu#include "mem/port.hh"
453898Ssaidi@eecs.umich.edu#include "sim/byteswap.hh"
463898Ssaidi@eecs.umich.edu#include "sim/system.hh"
473898Ssaidi@eecs.umich.edu
484762Snate@binkert.orgMmDisk::MmDisk(const Params *p)
499808Sstever@gmail.com    : BasicPioDevice(p, p->image->size() * SectorSize),
509808Sstever@gmail.com      image(p->image), curSector((off_t)-1), dirty(false)
513898Ssaidi@eecs.umich.edu{
524011Ssaidi@eecs.umich.edu    std::memset(&diskData, 0, SectorSize);
533898Ssaidi@eecs.umich.edu}
543898Ssaidi@eecs.umich.edu
553898Ssaidi@eecs.umich.eduTick
563898Ssaidi@eecs.umich.eduMmDisk::read(PacketPtr pkt)
573898Ssaidi@eecs.umich.edu{
583898Ssaidi@eecs.umich.edu    Addr accessAddr;
593898Ssaidi@eecs.umich.edu    off_t sector;
604011Ssaidi@eecs.umich.edu    uint16_t d16;
614011Ssaidi@eecs.umich.edu    uint32_t d32;
624011Ssaidi@eecs.umich.edu    uint64_t d64;
633898Ssaidi@eecs.umich.edu
643898Ssaidi@eecs.umich.edu    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
653898Ssaidi@eecs.umich.edu    accessAddr = pkt->getAddr() - pioAddr;
663898Ssaidi@eecs.umich.edu
673898Ssaidi@eecs.umich.edu    sector = accessAddr / SectorSize;
683898Ssaidi@eecs.umich.edu
693898Ssaidi@eecs.umich.edu    if (sector != curSector) {
704011Ssaidi@eecs.umich.edu        if (dirty) {
718641Snate@binkert.org#ifndef NDEBUG
728641Snate@binkert.org            off_t bytes_written =
738641Snate@binkert.org#endif
748641Snate@binkert.org                image->write(diskData, curSector);
758641Snate@binkert.org            assert(bytes_written == SectorSize);
764011Ssaidi@eecs.umich.edu        }
778641Snate@binkert.org#ifndef NDEBUG
788641Snate@binkert.org        off_t bytes_read =
798641Snate@binkert.org#endif
808641Snate@binkert.org            image->read(diskData, sector);
814011Ssaidi@eecs.umich.edu        assert(bytes_read == SectorSize);
823898Ssaidi@eecs.umich.edu        curSector = sector;
833898Ssaidi@eecs.umich.edu    }
843898Ssaidi@eecs.umich.edu    switch (pkt->getSize()) {
853898Ssaidi@eecs.umich.edu      case sizeof(uint8_t):
8613231Sgabeblack@google.com        pkt->setRaw(diskData[accessAddr % SectorSize]);
8713231Sgabeblack@google.com        DPRINTF(IdeDisk, "reading byte %#x value= %#x\n",
8813231Sgabeblack@google.com                accessAddr, diskData[accessAddr % SectorSize]);
893898Ssaidi@eecs.umich.edu        break;
903898Ssaidi@eecs.umich.edu      case sizeof(uint16_t):
914011Ssaidi@eecs.umich.edu        memcpy(&d16, diskData + (accessAddr % SectorSize), 2);
9213231Sgabeblack@google.com        pkt->setRaw(d16);
934011Ssaidi@eecs.umich.edu        DPRINTF(IdeDisk, "reading word %#x value= %#x\n", accessAddr, d16);
943898Ssaidi@eecs.umich.edu        break;
953898Ssaidi@eecs.umich.edu      case sizeof(uint32_t):
964011Ssaidi@eecs.umich.edu        memcpy(&d32, diskData + (accessAddr % SectorSize), 4);
9713231Sgabeblack@google.com        pkt->setRaw(d32);
984011Ssaidi@eecs.umich.edu        DPRINTF(IdeDisk, "reading dword %#x value= %#x\n", accessAddr, d32);
993898Ssaidi@eecs.umich.edu        break;
1003898Ssaidi@eecs.umich.edu      case sizeof(uint64_t):
1014011Ssaidi@eecs.umich.edu        memcpy(&d64, diskData + (accessAddr % SectorSize), 8);
10213231Sgabeblack@google.com        pkt->setRaw(d64);
1034011Ssaidi@eecs.umich.edu        DPRINTF(IdeDisk, "reading qword %#x value= %#x\n", accessAddr, d64);
1043898Ssaidi@eecs.umich.edu        break;
1053898Ssaidi@eecs.umich.edu      default:
1063898Ssaidi@eecs.umich.edu        panic("Invalid access size\n");
1073898Ssaidi@eecs.umich.edu    }
1083898Ssaidi@eecs.umich.edu
1094870Sstever@eecs.umich.edu    pkt->makeAtomicResponse();
1103898Ssaidi@eecs.umich.edu    return pioDelay;
1113898Ssaidi@eecs.umich.edu}
1123898Ssaidi@eecs.umich.edu
1133898Ssaidi@eecs.umich.eduTick
1143898Ssaidi@eecs.umich.eduMmDisk::write(PacketPtr pkt)
1153898Ssaidi@eecs.umich.edu{
1164011Ssaidi@eecs.umich.edu    Addr accessAddr;
1174011Ssaidi@eecs.umich.edu    off_t sector;
1184011Ssaidi@eecs.umich.edu    uint16_t d16;
1194011Ssaidi@eecs.umich.edu    uint32_t d32;
1204011Ssaidi@eecs.umich.edu    uint64_t d64;
1214011Ssaidi@eecs.umich.edu
1224011Ssaidi@eecs.umich.edu    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
1234011Ssaidi@eecs.umich.edu    accessAddr = pkt->getAddr() - pioAddr;
1244011Ssaidi@eecs.umich.edu
1254011Ssaidi@eecs.umich.edu    sector = accessAddr / SectorSize;
1264011Ssaidi@eecs.umich.edu
1274011Ssaidi@eecs.umich.edu    if (sector != curSector) {
1284011Ssaidi@eecs.umich.edu        if (dirty) {
1298641Snate@binkert.org#ifndef NDEBUG
1308641Snate@binkert.org            off_t bytes_written =
1318641Snate@binkert.org#endif
1328641Snate@binkert.org                image->write(diskData, curSector);
1338641Snate@binkert.org            assert(bytes_written == SectorSize);
1344011Ssaidi@eecs.umich.edu        }
1358641Snate@binkert.org#ifndef NDEBUG
1368641Snate@binkert.org        off_t bytes_read =
1378641Snate@binkert.org#endif
1388641Snate@binkert.org            image->read(diskData,  sector);
1394011Ssaidi@eecs.umich.edu        assert(bytes_read == SectorSize);
1404011Ssaidi@eecs.umich.edu        curSector = sector;
1414011Ssaidi@eecs.umich.edu    }
1424011Ssaidi@eecs.umich.edu    dirty = true;
1434011Ssaidi@eecs.umich.edu
1444011Ssaidi@eecs.umich.edu    switch (pkt->getSize()) {
1454011Ssaidi@eecs.umich.edu      case sizeof(uint8_t):
14613231Sgabeblack@google.com        diskData[accessAddr % SectorSize] = htobe(pkt->getRaw<uint8_t>());
14713231Sgabeblack@google.com        DPRINTF(IdeDisk, "writing byte %#x value= %#x\n",
14813231Sgabeblack@google.com                accessAddr, diskData[accessAddr % SectorSize]);
1494011Ssaidi@eecs.umich.edu        break;
1504011Ssaidi@eecs.umich.edu      case sizeof(uint16_t):
15113231Sgabeblack@google.com        d16 = pkt->getRaw<uint16_t>();
1524011Ssaidi@eecs.umich.edu        memcpy(diskData + (accessAddr % SectorSize), &d16, 2);
1534011Ssaidi@eecs.umich.edu        DPRINTF(IdeDisk, "writing word %#x value= %#x\n", accessAddr, d16);
1544011Ssaidi@eecs.umich.edu        break;
1554011Ssaidi@eecs.umich.edu      case sizeof(uint32_t):
15613231Sgabeblack@google.com        d32 = pkt->getRaw<uint32_t>();
1574011Ssaidi@eecs.umich.edu        memcpy(diskData + (accessAddr % SectorSize), &d32, 4);
1584011Ssaidi@eecs.umich.edu        DPRINTF(IdeDisk, "writing dword %#x value= %#x\n", accessAddr, d32);
1594011Ssaidi@eecs.umich.edu        break;
1604011Ssaidi@eecs.umich.edu      case sizeof(uint64_t):
16113231Sgabeblack@google.com        d64 = pkt->getRaw<uint64_t>();
1624011Ssaidi@eecs.umich.edu        memcpy(diskData + (accessAddr % SectorSize), &d64, 8);
1634011Ssaidi@eecs.umich.edu        DPRINTF(IdeDisk, "writing qword %#x value= %#x\n", accessAddr, d64);
1644011Ssaidi@eecs.umich.edu        break;
1654011Ssaidi@eecs.umich.edu      default:
1664011Ssaidi@eecs.umich.edu        panic("Invalid access size\n");
1674011Ssaidi@eecs.umich.edu    }
1684011Ssaidi@eecs.umich.edu
1694870Sstever@eecs.umich.edu    pkt->makeAtomicResponse();
1704011Ssaidi@eecs.umich.edu    return pioDelay;
1713898Ssaidi@eecs.umich.edu}
1723898Ssaidi@eecs.umich.edu
1734011Ssaidi@eecs.umich.eduvoid
17410905Sandreas.sandberg@arm.comMmDisk::serialize(CheckpointOut &cp) const
1754011Ssaidi@eecs.umich.edu{
1764011Ssaidi@eecs.umich.edu    // just write any dirty changes to the cow layer it will take care of
1774011Ssaidi@eecs.umich.edu    // serialization
1784011Ssaidi@eecs.umich.edu    if (dirty) {
1798641Snate@binkert.org#ifndef NDEBUG
1808641Snate@binkert.org        int bytes_read =
1818641Snate@binkert.org#endif
1828641Snate@binkert.org            image->write(diskData, curSector);
1834011Ssaidi@eecs.umich.edu        assert(bytes_read == SectorSize);
1844011Ssaidi@eecs.umich.edu    }
18512544Skhalique913@gmail.com    ClockedObject::serialize(cp);
1864011Ssaidi@eecs.umich.edu}
1874011Ssaidi@eecs.umich.edu
1884762Snate@binkert.orgMmDisk *
1894762Snate@binkert.orgMmDiskParams::create()
1903898Ssaidi@eecs.umich.edu{
1914762Snate@binkert.org    return new MmDisk(this);
1923898Ssaidi@eecs.umich.edu}
193