OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [tools/] [src/] [librw11/] [Rw11RdmaDisk.cpp] - Rev 38

Compare with Previous | Blame | View Log

// $Id: Rw11RdmaDisk.cpp 648 2015-02-20 20:16:21Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, or at your option any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for complete details.
// 
// Revision History: 
// Date         Rev Version  Comment
// 2015-01-04   628   1.0    Initial version
// ---------------------------------------------------------------------------
 
/*!
  \file
  \version $Id: Rw11RdmaDisk.cpp 648 2015-02-20 20:16:21Z mueller $
  \brief   Implemenation of Rw11RdmaDisk.
*/
 
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/Rexception.hpp"
 
#include "Rw11RdmaDisk.hpp"
 
using namespace std;
 
/*!
  \class Retro::Rw11RdmaDisk
  \brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11RdmaDisk::Rw11RdmaDisk(Rw11Cntl* pcntl, const precb_t& precb, 
                           const postcb_t& postcb)
  : Rw11Rdma(pcntl, precb, postcb),
    fBuf(),
    fpUnit(nullptr),
    fNWord(0),
    fNBlock(0),
    fLba()
{
  fStats.Define(kStatNWritePadded, "NWritePadded" , "padded disk write");
  fStats.Define(kStatNWChkFail,    "NWChkFail"    , "write check failed");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11RdmaDisk::~Rw11RdmaDisk()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::QueueDiskRead(uint32_t addr, size_t size, uint16_t mode, 
                                 uint32_t lba, Rw11UnitDisk* punit)
{
  SetupDisk(size, lba, punit, kFuncRead);
  QueueWMem(addr, fBuf.data(), size, mode);
  return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::QueueDiskWrite(uint32_t addr,size_t size, uint16_t mode,
                                  uint32_t lba, Rw11UnitDisk* punit)
{
  SetupDisk(size, lba, punit, kFuncWrite);
  QueueRMem(addr, fBuf.data(), size, mode);
  return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::QueueDiskWriteCheck(uint32_t addr, size_t size, 
                                       uint16_t mode, uint32_t lba, 
                                       Rw11UnitDisk* punit)
{
  SetupDisk(size, lba, punit, kFuncWriteCheck);
  QueueRMem(addr, fBuf.data(), size, mode);
  return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
size_t Rw11RdmaDisk::WriteCheck(size_t nwdone)
{
  if (nwdone == 0) return 0;
 
  size_t bszwrd = fpUnit->BlockSize()/2;    // block size in words
  size_t nblk   = (nwdone+bszwrd-1)/bszwrd;
  size_t dsize  = nblk*bszwrd;
 
  std::vector<uint16_t>  dbuf(dsize);
  RerrMsg emsg;
  bool rc = fpUnit->VirtRead(fLba, nblk,
                             reinterpret_cast<uint8_t*>(dbuf.data()), emsg);
  if (!rc) throw Rexception("Rw11RdmaDisk::WriteCheck()", 
                            "VirtRead() failed: ", emsg);
 
  uint16_t* pdsk = dbuf.data();
  uint16_t* pmem = fBuf.data();
  for (size_t i=0; i<nwdone; i++) {
    if (*pdsk++ != *pmem++) {
      fStats.Inc(kStatNWChkFail);
      return i;
    }
  }
 
  return nwdone;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::Dump(std::ostream& os, int ind, const char* text) const
{
  RosFill bl(ind);
  os << bl << (text?text:"--") << "Rw11RdmaDisk @ " << this << endl;
  os << bl << "  fBuf.size()      " << RosPrintf(fBuf.size(),"d",5) << endl;
  os << bl << "  fpUnit:          " << fpUnit << endl;
  os << bl << "  fNWord:          " << RosPrintf(fNWord,"d",5) << endl;
  os << bl << "  fNBlock:         " << RosPrintf(fNBlock,"d",5) << endl;
  os << bl << "  fLba:            " << RosPrintf(fLba,"d",8) << endl;
  os << bl << "  fFunc:           " << fFunc << endl;
 
  Rw11Rdma::Dump(os, ind, " ^");
  return;
} 
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::SetupDisk(size_t size, uint32_t lba, Rw11UnitDisk* punit, 
                             Rw11RdmaDisk::func func)
{
  fpUnit = punit;
  size_t bszwrd = fpUnit->BlockSize()/2;    // block size in words
 
  fNWord  = size;
  fNBlock = (fNWord+bszwrd-1)/bszwrd;
  fLba    = lba;
  fFunc   = func;
 
  size_t tsize = fNBlock*bszwrd;
  if (fBuf.size() < tsize) fBuf.resize(tsize);
 
  return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::PreRdmaHook()
{
  if (fFunc != kFuncRead) return;          // quit unless read request
 
  RerrMsg emsg;
  bool rc = fpUnit->VirtRead(fLba, fNBlock,
                             reinterpret_cast<uint8_t*>(fBuf.data()), emsg);
  if (!rc) throw Rexception("Rw11RdmaDisk::PreRdmaHook()", 
                            "VirtRead() failed: ", emsg);
  return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::PostRdmaHook(size_t nwdone)
{
  if (nwdone == 0) return;                  // quit if rdma failed early
  if (fFunc != kFuncWrite) return;          // quit unless write request
 
  size_t bszwrd = fpUnit->BlockSize()/2;    // block size in words
  size_t nblock = (nwdone+bszwrd-1)/bszwrd;
  size_t npad   = nblock*bszwrd - nwdone;
 
  // if an incomplete block was read, pad it with hex dead
  if (npad) {
    fStats.Inc(kStatNWritePadded);
    uint16_t* p = fBuf.data()+nwdone;
    for (size_t i=0; i<npad; i++) *p++ = 0xdead;
  }
 
  RerrMsg emsg;
  bool rc = fpUnit->VirtWrite(fLba, nblock, 
                              reinterpret_cast<uint8_t*>(fBuf.data()), emsg);
  if (!rc) throw Rexception("Rw11RdmaDisk::PostRdmaHook()", 
                            "VirtWrite() failed: ", emsg);
  return;
}
 
 
} // end namespace Retro
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.