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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [tools/] [src/] [librw11/] [Rw11CntlRK11.cpp] - Diff between revs 28 and 29

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 28 Rev 29
Line 1... Line 1...
// $Id: Rw11CntlRK11.cpp 628 2015-01-04 16:22:09Z mueller $
// $Id: Rw11CntlRK11.cpp 647 2015-02-17 22:35:36Z mueller $
//
//
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
// Other credits: 
// Other credits: 
//   the boot code is from the simh project and Copyright Robert M Supnik
//   the boot code is from the simh project and Copyright Robert M Supnik
// 
// 
Line 13... Line 13...
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for complete details.
// for complete details.
// 
// 
// Revision History: 
// Revision History: 
// Date         Rev Version  Comment
// Date         Rev Version  Comment
 
// 2015-02-17   647   2.0.1  use Nwrd2Nblk(); BUGFIX: revise RdmaPostExecCB()
// 2015-01-04   628   2.0    use Rw11RdmaDisk
// 2015-01-04   628   2.0    use Rw11RdmaDisk
// 2014-12-30   625   1.2    adopt to Rlink V4 attn logic
// 2014-12-30   625   1.2    adopt to Rlink V4 attn logic
// 2014-12-25   621   1.1    adopt to 4k word ibus window
// 2014-12-25   621   1.1    adopt to 4k word ibus window
// 2014-06-14   562   1.0.1  Add stats
// 2014-06-14   562   1.0.1  Add stats
// 2013-04-20   508   1.0    Initial version
// 2013-04-20   508   1.0    Initial version
// 2013-02-10   485   0.1    First draft
// 2013-02-10   485   0.1    First draft
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
 
 
/*!
/*!
  \file
  \file
  \version $Id: Rw11CntlRK11.cpp 628 2015-01-04 16:22:09Z mueller $
  \version $Id: Rw11CntlRK11.cpp 647 2015-02-17 22:35:36Z mueller $
  \brief   Implemenation of Rw11CntlRK11.
  \brief   Implemenation of Rw11CntlRK11.
*/
*/
 
 
#include "boost/bind.hpp"
#include "boost/bind.hpp"
#include "boost/foreach.hpp"
#include "boost/foreach.hpp"
Line 100... Line 101...
const uint16_t Rw11CntlRK11::kRKCS_M_MEX;
const uint16_t Rw11CntlRK11::kRKCS_M_MEX;
const uint16_t Rw11CntlRK11::kRKCS_V_MEX;
const uint16_t Rw11CntlRK11::kRKCS_V_MEX;
const uint16_t Rw11CntlRK11::kRKCS_B_MEX;
const uint16_t Rw11CntlRK11::kRKCS_B_MEX;
const uint16_t Rw11CntlRK11::kRKCS_V_FUNC;
const uint16_t Rw11CntlRK11::kRKCS_V_FUNC;
const uint16_t Rw11CntlRK11::kRKCS_B_FUNC;
const uint16_t Rw11CntlRK11::kRKCS_B_FUNC;
const uint16_t Rw11CntlRK11::kRKCS_CRESET;
 
const uint16_t Rw11CntlRK11::kRKCS_WRITE;
 
const uint16_t Rw11CntlRK11::kRKCS_READ;
 
const uint16_t Rw11CntlRK11::kRKCS_WCHK;
 
const uint16_t Rw11CntlRK11::kRKCS_SEEK;
 
const uint16_t Rw11CntlRK11::kRKCS_RCHK;
 
const uint16_t Rw11CntlRK11::kRKCS_DRESET;
 
const uint16_t Rw11CntlRK11::kRKCS_WLOCK;
 
const uint16_t Rw11CntlRK11::kRKCS_M_GO;
const uint16_t Rw11CntlRK11::kRKCS_M_GO;
 
 
 
const uint16_t Rw11CntlRK11::kFUNC_CRESET;
 
const uint16_t Rw11CntlRK11::kFUNC_WRITE;
 
const uint16_t Rw11CntlRK11::kFUNC_READ;
 
const uint16_t Rw11CntlRK11::kFUNC_WCHK;
 
const uint16_t Rw11CntlRK11::kFUNC_SEEK;
 
const uint16_t Rw11CntlRK11::kFUNC_RCHK;
 
const uint16_t Rw11CntlRK11::kFUNC_DRESET;
 
const uint16_t Rw11CntlRK11::kFUNC_WLOCK;
 
 
const uint16_t Rw11CntlRK11::kRKDA_M_DRSEL;
const uint16_t Rw11CntlRK11::kRKDA_M_DRSEL;
const uint16_t Rw11CntlRK11::kRKDA_V_DRSEL;
const uint16_t Rw11CntlRK11::kRKDA_V_DRSEL;
const uint16_t Rw11CntlRK11::kRKDA_B_DRSEL;
const uint16_t Rw11CntlRK11::kRKDA_B_DRSEL;
const uint16_t Rw11CntlRK11::kRKDA_M_CYL;
const uint16_t Rw11CntlRK11::kRKDA_M_CYL;
const uint16_t Rw11CntlRK11::kRKDA_V_CYL;
const uint16_t Rw11CntlRK11::kRKDA_V_CYL;
Line 146... Line 148...
    fRd_lba(0),
    fRd_lba(0),
    fRd_nwrd(0),
    fRd_nwrd(0),
    fRd_fu(0),
    fRd_fu(0),
    fRd_ovr(false),
    fRd_ovr(false),
    fRdma(this,
    fRdma(this,
          boost::bind(&Rw11CntlRK11::RdmaPreExecCB,  this, _1, _2, _3),
          boost::bind(&Rw11CntlRK11::RdmaPreExecCB,  this, _1, _2, _3, _4),
          boost::bind(&Rw11CntlRK11::RdmaPostExecCB, this, _1, _2, _3, _4))
          boost::bind(&Rw11CntlRK11::RdmaPostExecCB, this, _1, _2, _3, _4))
{
{
  // must be here because Units have a back-ptr (not available at Rw11CntlBase)
  // must be here because Units have a back-ptr (not available at Rw11CntlBase)
  for (size_t i=0; i<NUnit(); i++) {
  for (size_t i=0; i<NUnit(); i++) {
    fspUnit[i].reset(new Rw11UnitRK11(this, i));
    fspUnit[i].reset(new Rw11UnitRK11(this, i));
Line 347... Line 349...
  Rw11UnitRK11& unit = *fspUnit[dr];
  Rw11UnitRK11& unit = *fspUnit[dr];
  Rw11Cpu& cpu = Cpu();
  Rw11Cpu& cpu = Cpu();
  RlinkCommandList clist;
  RlinkCommandList clist;
 
 
  uint32_t lba  = unit.Chs2Lba(cy,hd,se);
  uint32_t lba  = unit.Chs2Lba(cy,hd,se);
  uint32_t nblk = (2*nwrd+unit.BlockSize()-1)/unit.BlockSize();
  uint32_t nblk = unit.Nwrd2Nblk(nwrd);
 
 
  uint16_t rker = 0;
  uint16_t rker = 0;
  uint16_t rkds = unit.Rkds();
  uint16_t rkds = unit.Rkds();
 
 
  if (fTraceLevel>0) {
  if (fTraceLevel>0) {
Line 369... Line 371...
         << " lba,nw=" << RosPrintf(lba,"d",4)
         << " lba,nw=" << RosPrintf(lba,"d",4)
         << "," << RosPrintf(nwrd,"d",5);
         << "," << RosPrintf(nwrd,"d",5);
  }
  }
 
 
  // check for general abort conditions
  // check for general abort conditions
  if (fu != kRKCS_CRESET &&                 // function not control reset
  if (fu != kFUNC_CRESET &&                 // function not control reset
      (!unit.Virt())) {                     //   and drive not attached
      (!unit.Virt())) {                     //   and drive not attached
    rker = kRKER_M_NXD;                     //   --> abort with NXD error
    rker = kRKER_M_NXD;                     //   --> abort with NXD error
 
 
  } else if (fu != kRKCS_WRITE &&           // function neither write
  } else if (fu != kFUNC_WRITE &&           // function neither write
             fu != kRKCS_READ &&            //   nor read
             fu != kFUNC_READ &&            //   nor read
             (rkcs & (kRKCS_M_FMT|kRKCS_M_RWA))) { // and FMT or RWA set 
             (rkcs & (kRKCS_M_FMT|kRKCS_M_RWA))) { // and FMT or RWA set 
    rker = kRKER_M_PGE;                     //   --> abort with PGE error
    rker = kRKER_M_PGE;                     //   --> abort with PGE error
  } else if (rkcs & kRKCS_M_RWA) {          // RWA not supported
  } else if (rkcs & kRKCS_M_RWA) {          // RWA not supported
    rker = kRKER_M_DRE;                     //   --> abort with DRE error
    rker = kRKER_M_DRE;                     //   --> abort with DRE error
  }
  }
 
 
  if (rker) {
  if (rker) {
    cpu.AddWibr(clist, fBase+kRKER, rker);
    cpu.AddWibr(clist, fBase+kRKER, rker);
    if (fu == kRKCS_SEEK || fu == kRKCS_DRESET)
    if (fu == kFUNC_SEEK || fu == kFUNC_DRESET)
      cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_SBCLR | (1u<<dr));
      cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_SBCLR | (1u<<dr));
    cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
    cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
    LogRker(rker);
    LogRker(rker);
    Server().Exec(clist);
    Server().Exec(clist);
    return 0;
    return 0;
  }
  }
 
 
  // check for overrun (read/write beyond cylinder 203
  // check for overrun (read/write beyond cylinder 203)
  // if found, truncate request length
  // if found, truncate request length
  bool ovr = lba + nblk > unit.NBlock();
  bool ovr = lba + nblk > unit.NBlock();
  if (ovr) nwrd = (unit.NBlock()-lba) * (unit.BlockSize()/2);
  if (ovr) nwrd = (unit.NBlock()-lba) * (unit.BlockSize()/2);
 
 
  // remember request parameters for call back
  // remember request parameters for call back
Line 406... Line 408...
  fRd_nwrd  = nwrd;
  fRd_nwrd  = nwrd;
  fRd_ovr   = ovr;
  fRd_ovr   = ovr;
  fRd_fu    = fu;
  fRd_fu    = fu;
 
 
  // now handle the functions
  // now handle the functions
  if (fu == kRKCS_CRESET) {                 // Control reset -----------------
  if (fu == kFUNC_CRESET) {                 // Control reset -----------------
    fStats.Inc(kStatNFuncCreset);
    fStats.Inc(kStatNFuncCreset);
    cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_CRESET);
    cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_CRESET);
 
 
  } else if (fu == kRKCS_WRITE) {           // Write -------------------------
  } else if (fu == kFUNC_WRITE) {           // Write -------------------------
                                            //   Note: WRITE+FMT is just WRITE
                                            //   Note: WRITE+FMT is just WRITE
    fStats.Inc(kStatNFuncWrite);
    fStats.Inc(kStatNFuncWrite);
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
    if (unit.WProt())           rker |= kRKER_M_WLO;
    if (unit.WProt())           rker |= kRKER_M_WLO;
Line 425... Line 427...
      fRdma.QueueDiskWrite(addr, nwrd,
      fRdma.QueueDiskWrite(addr, nwrd,
                           Rw11Cpu::kCp_ah_m_22bit|Rw11Cpu::kCp_ah_m_ubmap,
                           Rw11Cpu::kCp_ah_m_22bit|Rw11Cpu::kCp_ah_m_ubmap,
                           lba, &unit);
                           lba, &unit);
    }
    }
 
 
  } else if (fu == kRKCS_READ) {            // Read --------------------------
  } else if (fu == kFUNC_READ) {            // Read --------------------------
    fStats.Inc(kStatNFuncRead);
    fStats.Inc(kStatNFuncRead);
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
    if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE;  // IBA not supported
    if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE;  // IBA not supported
    if (rker) {
    if (rker) {
Line 438... Line 440...
      fRdma.QueueDiskRead(addr, nwrd,
      fRdma.QueueDiskRead(addr, nwrd,
                          Rw11Cpu::kCp_ah_m_22bit|Rw11Cpu::kCp_ah_m_ubmap,
                          Rw11Cpu::kCp_ah_m_22bit|Rw11Cpu::kCp_ah_m_ubmap,
                          lba, &unit);
                          lba, &unit);
    }
    }
 
 
  } else if (fu == kRKCS_WCHK) {            // Write Check -------------------
  } else if (fu == kFUNC_WCHK) {            // Write Check -------------------
    fStats.Inc(kStatNFuncWchk);
    fStats.Inc(kStatNFuncWchk);
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
    if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE;  // IBA not supported
    if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE;  // IBA not supported
    if (rker) {
    if (rker) {
Line 451... Line 453...
      fRdma.QueueDiskWriteCheck(addr, nwrd,
      fRdma.QueueDiskWriteCheck(addr, nwrd,
                                Rw11Cpu::kCp_ah_m_22bit|Rw11Cpu::kCp_ah_m_ubmap,
                                Rw11Cpu::kCp_ah_m_22bit|Rw11Cpu::kCp_ah_m_ubmap,
                                lba, &unit);
                                lba, &unit);
    }
    }
 
 
  } else if (fu == kRKCS_SEEK) {            // Seek --------------------------
  } else if (fu == kFUNC_SEEK) {            // Seek --------------------------
    fStats.Inc(kStatNFuncSeek);
    fStats.Inc(kStatNFuncSeek);
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
    if (rker) {
    if (rker) {
      cpu.AddWibr(clist, fBase+kRKER, rker);
      cpu.AddWibr(clist, fBase+kRKER, rker);
Line 469... Line 471...
      unit.SetRkds(rkds);
      unit.SetRkds(rkds);
      cpu.AddWibr(clist, fBase+kRKDS, rkds);
      cpu.AddWibr(clist, fBase+kRKDS, rkds);
      cpu.AddWibr(clist, fBase+kRKMR, 1u<<dr); // issue seek done
      cpu.AddWibr(clist, fBase+kRKMR, 1u<<dr); // issue seek done
    }
    }
 
 
  } else if (fu == kRKCS_RCHK) {            // Read Check --------------------
  } else if (fu == kFUNC_RCHK) {            // Read Check --------------------
    fStats.Inc(kStatNFuncRchk);
    fStats.Inc(kStatNFuncRchk);
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
    if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE;  // IBA not supported
    if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE;  // IBA not supported
    if (rker) {
    if (rker) {
      AddErrorExit(clist, rker);
      AddErrorExit(clist, rker);
    } else {
    } else {
      AddNormalExit(clist, nwrd, 0);        // no action, virt disks don't err
      AddNormalExit(clist, nwrd, 0);        // no action, virt disks don't err
    }
    }
 
 
  } else if (fu == kRKCS_DRESET) {          // Drive Reset -------------------
  } else if (fu == kFUNC_DRESET) {          // Drive Reset -------------------
    fStats.Inc(kStatNFuncDreset);
    fStats.Inc(kStatNFuncDreset);
    cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
    cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
    cpu.AddWibr(clist, fBase+kRKMR, 1u<<dr);   // issue seek done
    cpu.AddWibr(clist, fBase+kRKMR, 1u<<dr);   // issue seek done
 
 
  } else if (fu == kRKCS_WLOCK) {           // Write Lock --------------------
  } else if (fu == kFUNC_WLOCK) {           // Write Lock --------------------
    fStats.Inc(kStatNFuncWlock);
    fStats.Inc(kStatNFuncWlock);
    rkds |= kRKDS_M_WPS;                    // set RKDS write protect flag
    rkds |= kRKDS_M_WPS;                    // set RKDS write protect flag
    unit.SetRkds(rkds);
    unit.SetRkds(rkds);
    unit.SetWProt(true);
    unit.SetWProt(true);
    cpu.AddWibr(clist, fBase+kRKDS, rkds);
    cpu.AddWibr(clist, fBase+kRKDS, rkds);
Line 503... Line 505...
}
}
 
 
//------------------------------------------+-----------------------------------
//------------------------------------------+-----------------------------------
//! FIXME_docs
//! FIXME_docs
 
 
void Rw11CntlRK11::RdmaPreExecCB(int stat, size_t nword,
void Rw11CntlRK11::RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext,
                                 RlinkCommandList& clist)
                                 RlinkCommandList& clist)
{
{
  // if last chunk and not doing WCHK add a labo and normal exit csr update
  // if last chunk and not doing WCHK add a labo and normal exit csr update
  if (stat == Rw11Rdma::kStatusBusyLast && fRd_fu != kRKCS_WCHK) {
  if (stat == Rw11Rdma::kStatusBusyLast && fRd_fu != kFUNC_WCHK) {
    clist.AddLabo();
    clist.AddLabo();
    AddNormalExit(clist, nword, 0);
    AddNormalExit(clist, nwdone+nwnext, 0);
  }
  }
  return;
  return;
}
}
 
 
//------------------------------------------+-----------------------------------
//------------------------------------------+-----------------------------------
Line 525... Line 527...
  if (stat == Rw11Rdma::kStatusBusy) return;
  if (stat == Rw11Rdma::kStatusBusy) return;
 
 
  uint16_t rker = 0;
  uint16_t rker = 0;
 
 
  // handle write check
  // handle write check
  if (fRd_fu == kRKCS_WCHK) {
  if (fRd_fu == kFUNC_WCHK) {
    size_t nwcok = fRdma.WriteCheck(ndone);
    size_t nwcok = fRdma.WriteCheck(ndone);
    if (nwcok != ndone) {                   // if mismatch found
    if (nwcok != ndone) {                   // if mismatch found
      rker |= kRKER_M_WCE;                  // set error flag
      rker |= kRKER_M_WCE;                  // set error flag
      if (fRd_rkcs & kRKCS_M_SSE) {         // if 'stop-on-soft' requested
      if (fRd_rkcs & kRKCS_M_SSE) {         // if 'stop-on-soft' requested
        ndone = nwcok;                      // truncate word count
        ndone = nwcok;                      // truncate word count
Line 586... Line 588...
                                 uint16_t rker)
                                 uint16_t rker)
{
{
  Rw11Cpu& cpu  = Cpu();
  Rw11Cpu& cpu  = Cpu();
  uint16_t dr   = (fRd_rkda>>kRKDA_V_DRSEL) & kRKDA_B_DRSEL;
  uint16_t dr   = (fRd_rkda>>kRKDA_V_DRSEL) & kRKDA_B_DRSEL;
  Rw11UnitRK11& unit = *fspUnit[dr];
  Rw11UnitRK11& unit = *fspUnit[dr];
  size_t bszwrd = unit.BlockSize()/2;         // block size in words
 
 
 
  size_t nblk   = (ndone+bszwrd-1)/bszwrd;
  size_t nblk   = unit.Nwrd2Nblk(ndone);
 
 
  uint32_t addr = fRd_addr + 2*ndone;
  uint32_t addr = fRd_addr + 2*ndone;
  size_t   lba  = fRd_lba  + nblk;
  size_t   lba  = fRd_lba  + nblk;
  uint32_t nrest = fRd_nwrd - ndone;
  uint32_t nrest = fRd_nwrd - ndone;
 
 

powered by: WebSVN 2.1.0

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