w11 - cpp 0.794
Backend server for Rlink and w11
Loading...
Searching...
No Matches
Rw11CntlRK11.cpp
Go to the documentation of this file.
1// $Id: Rw11CntlRK11.cpp 1186 2019-07-12 17:49:59Z mueller $
2// SPDX-License-Identifier: GPL-3.0-or-later
3// Copyright 2013-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4// Other credits:
5// the boot code is from the simh project and Copyright Robert M Supnik
6//
7// Revision History:
8// Date Rev Version Comment
9// 2019-04-19 1133 2.0.12 use ExecWibr()
10// 2019-04-14 1131 2.0.11 proper unit init, call UnitSetupAll() in Start()
11// 2019-02-23 1114 2.0.10 use std::bind instead of lambda
12// 2018-12-19 1090 2.0.9 use RosPrintf(bool)
13// 2018-12-15 1082 2.0.8 use std::bind or lambda instead of boost::bind
14// 2018-12-09 1080 2.0.7 use HasVirt(); Virt() returns ref
15// 2018-10-28 1062 2.0.6 replace boost/foreach
16// 2017-04-02 865 2.0.5 Dump(): add detail arg
17// 2017-03-03 858 2.0.4 use cntl name as message prefix
18// 2017-02-26 857 2.0.3 use kCPAH_M_UBM22
19// 2015-06-04 686 2.0.2 check for spurious lams
20// 2015-02-17 647 2.0.1 use Nwrd2Nblk(); BUGFIX: revise RdmaPostExecCB()
21// 2015-01-04 628 2.0 use Rw11RdmaDisk
22// 2014-12-30 625 1.2 adopt to Rlink V4 attn logic
23// 2014-12-25 621 1.1 adopt to 4k word ibus window
24// 2014-06-14 562 1.0.1 Add stats
25// 2013-04-20 508 1.0 Initial version
26// 2013-02-10 485 0.1 First draft
27// ---------------------------------------------------------------------------
28
33#include <functional>
34
35#include "librtools/RosFill.hpp"
39#include "librtools/RlogMsg.hpp"
40
41#include "Rw11CntlRK11.hpp"
42using namespace std::placeholders;
43
44using namespace std;
45
51// all method definitions in namespace Retro
52namespace Retro {
53
54//------------------------------------------+-----------------------------------
55// constants definitions
56
57const uint16_t Rw11CntlRK11::kIbaddr;
58const int Rw11CntlRK11::kLam;
59
60const uint16_t Rw11CntlRK11::kRKDS;
61const uint16_t Rw11CntlRK11::kRKER;
62const uint16_t Rw11CntlRK11::kRKCS;
63const uint16_t Rw11CntlRK11::kRKWC;
64const uint16_t Rw11CntlRK11::kRKBA;
65const uint16_t Rw11CntlRK11::kRKDA;
66const uint16_t Rw11CntlRK11::kRKMR;
67
68const uint16_t Rw11CntlRK11::kProbeOff;
71
72const uint16_t Rw11CntlRK11::kRKDS_M_ID;
73const uint16_t Rw11CntlRK11::kRKDS_V_ID;
74const uint16_t Rw11CntlRK11::kRKDS_B_ID;
75const uint16_t Rw11CntlRK11::kRKDS_M_HDEN;
76const uint16_t Rw11CntlRK11::kRKDS_M_DRU;
77const uint16_t Rw11CntlRK11::kRKDS_M_SIN;
78const uint16_t Rw11CntlRK11::kRKDS_M_SOK;
79const uint16_t Rw11CntlRK11::kRKDS_M_DRY;
80const uint16_t Rw11CntlRK11::kRKDS_M_ADRY;
81const uint16_t Rw11CntlRK11::kRKDS_M_WPS;
82const uint16_t Rw11CntlRK11::kRKDS_B_SC;
83
84const uint16_t Rw11CntlRK11::kRKER_M_DRE;
85const uint16_t Rw11CntlRK11::kRKER_M_OVR;
86const uint16_t Rw11CntlRK11::kRKER_M_WLO;
87const uint16_t Rw11CntlRK11::kRKER_M_PGE;
88const uint16_t Rw11CntlRK11::kRKER_M_NXM;
89const uint16_t Rw11CntlRK11::kRKER_M_NXD;
90const uint16_t Rw11CntlRK11::kRKER_M_NXC;
91const uint16_t Rw11CntlRK11::kRKER_M_NXS;
92const uint16_t Rw11CntlRK11::kRKER_M_CSE;
93const uint16_t Rw11CntlRK11::kRKER_M_WCE;
94
95const uint16_t Rw11CntlRK11::kRKCS_M_MAINT;
96const uint16_t Rw11CntlRK11::kRKCS_M_IBA;
97const uint16_t Rw11CntlRK11::kRKCS_M_FMT;
98const uint16_t Rw11CntlRK11::kRKCS_M_RWA;
99const uint16_t Rw11CntlRK11::kRKCS_M_SSE;
100const uint16_t Rw11CntlRK11::kRKCS_M_RDY;
101const uint16_t Rw11CntlRK11::kRKCS_M_MEX;
102const uint16_t Rw11CntlRK11::kRKCS_V_MEX;
103const uint16_t Rw11CntlRK11::kRKCS_B_MEX;
104const uint16_t Rw11CntlRK11::kRKCS_V_FUNC;
105const uint16_t Rw11CntlRK11::kRKCS_B_FUNC;
106const uint16_t Rw11CntlRK11::kRKCS_M_GO;
107
108const uint16_t Rw11CntlRK11::kFUNC_CRESET;
109const uint16_t Rw11CntlRK11::kFUNC_WRITE;
110const uint16_t Rw11CntlRK11::kFUNC_READ;
111const uint16_t Rw11CntlRK11::kFUNC_WCHK;
112const uint16_t Rw11CntlRK11::kFUNC_SEEK;
113const uint16_t Rw11CntlRK11::kFUNC_RCHK;
114const uint16_t Rw11CntlRK11::kFUNC_DRESET;
115const uint16_t Rw11CntlRK11::kFUNC_WLOCK;
116
117const uint16_t Rw11CntlRK11::kRKDA_M_DRSEL;
118const uint16_t Rw11CntlRK11::kRKDA_V_DRSEL;
119const uint16_t Rw11CntlRK11::kRKDA_B_DRSEL;
120const uint16_t Rw11CntlRK11::kRKDA_M_CYL;
121const uint16_t Rw11CntlRK11::kRKDA_V_CYL;
122const uint16_t Rw11CntlRK11::kRKDA_B_CYL;
123const uint16_t Rw11CntlRK11::kRKDA_M_SUR;
124const uint16_t Rw11CntlRK11::kRKDA_V_SUR;
125const uint16_t Rw11CntlRK11::kRKDA_B_SUR;
126const uint16_t Rw11CntlRK11::kRKDA_B_SC;
127
128const uint16_t Rw11CntlRK11::kRKMR_M_RID;
129const uint16_t Rw11CntlRK11::kRKMR_V_RID;
130const uint16_t Rw11CntlRK11::kRKMR_M_CRDONE;
131const uint16_t Rw11CntlRK11::kRKMR_M_SBCLR;
132const uint16_t Rw11CntlRK11::kRKMR_M_CRESET;
133const uint16_t Rw11CntlRK11::kRKMR_M_FDONE;
134
135//------------------------------------------+-----------------------------------
137
139 : Rw11CntlBase<Rw11UnitRK11,8>("rk11"),
140 fPC_rkwc(0),
141 fPC_rkba(0),
142 fPC_rkda(0),
143 fPC_rkmr(0),
144 fPC_rkcs(0),
145 fRd_rkcs(0),
146 fRd_rkda(0),
147 fRd_addr(0),
148 fRd_lba(0),
149 fRd_nwrd(0),
150 fRd_fu(0),
151 fRd_ovr(false),
152 fRdma(this,
153 std::bind(&Rw11CntlRK11::RdmaPreExecCB, this, _1, _2, _3, _4),
154 std::bind(&Rw11CntlRK11::RdmaPostExecCB, this, _1, _2, _3, _4))
155{
156 // must be here because Units have a back-ptr (not available at Rw11CntlBase)
157 for (size_t i=0; i<NUnit(); i++) {
158 fspUnit[i].reset(new Rw11UnitRK11(this, i));
159 }
160
161 fStats.Define(kStatNFuncCreset , "NFuncCreset" , "func CRESET");
162 fStats.Define(kStatNFuncWrite , "NFuncWrite" , "func WRITE");
163 fStats.Define(kStatNFuncRead , "NFuncRead" , "func READ");
164 fStats.Define(kStatNFuncWchk , "NFuncWchk" , "func WCHK");
165 fStats.Define(kStatNFuncSeek , "NFuncSeek" , "func SEEK");
166 fStats.Define(kStatNFuncRchk , "NFuncRchk" , "func RCHK");
167 fStats.Define(kStatNFuncDreset , "NFuncDreset" , "func DRESET");
168 fStats.Define(kStatNFuncWlock , "NFuncWlock " , "func WLOCK");
169}
170
171//------------------------------------------+-----------------------------------
173
175{}
176
177//------------------------------------------+-----------------------------------
179
180void Rw11CntlRK11::Config(const std::string& name, uint16_t base, int lam)
181{
182 ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
183 return;
184}
185
186//------------------------------------------+-----------------------------------
188
190{
191 if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
192 throw Rexception("Rw11CntlRK11::Start",
193 "Bad state: started, no lam, not enable, not found");
194
195 // add device register address ibus and rbus mappings
196 // done here because now Cntl bound to Cpu and Cntl probed
197 Cpu().AllIAddrMapInsert(Name()+".ds", Base() + kRKDS);
198 Cpu().AllIAddrMapInsert(Name()+".er", Base() + kRKER);
199 Cpu().AllIAddrMapInsert(Name()+".cs", Base() + kRKCS);
200 Cpu().AllIAddrMapInsert(Name()+".wc", Base() + kRKWC);
201 Cpu().AllIAddrMapInsert(Name()+".ba", Base() + kRKBA);
202 Cpu().AllIAddrMapInsert(Name()+".da", Base() + kRKDA);
203 Cpu().AllIAddrMapInsert(Name()+".mr", Base() + kRKMR);
204
205 // ensure unit status is initialized
206 UnitSetupAll();
207
208 // setup primary info clist
214 fPC_rkmr = Cpu().AddRibr(fPrimClist, fBase+kRKMR); // read to monitor CRDONE
216
217 // add attn handler
219 uint16_t(1)<<fLam, this);
220
221 fStarted = true;
222 return;
223}
224
225//------------------------------------------+-----------------------------------
227
229{
230 Rw11UnitRK11& unit = *fspUnit[ind];
231
232 uint16_t rkds = ind<<kRKDS_V_ID;
233 if (unit.HasVirt()) { // file attached
234 rkds |= kRKDS_M_HDEN; // always high density
235 rkds |= kRKDS_M_SOK; // always sector counter OK ?FIXME?
236 rkds |= kRKDS_M_DRY; // drive available
237 rkds |= kRKDS_M_ADRY; // access available
238 if (unit.WProt()) // in case write protected
239 rkds |= kRKDS_M_WPS;
240 }
241 unit.SetRkds(rkds);
242 Cpu().ExecWibr(fBase+kRKDS, rkds);
243
244 return;
245}
246
247//------------------------------------------+-----------------------------------
249
250bool Rw11CntlRK11::BootCode(size_t unit, std::vector<uint16_t>& code,
251 uint16_t& aload, uint16_t& astart)
252{
253 uint16_t kBOOT_START = 02000;
254 uint16_t bootcode[] = { // rk11 boot loader - from simh pdp11_rk.c (v3.9)
255 0042113, // "KD"
256 0012706, kBOOT_START, // MOV #boot_start, SP
257 0012700, uint16_t(unit), // MOV #unit, R0 ; unit number
258 0010003, // MOV R0, R3
259 0000303, // SWAB R3
260 0006303, // ASL R3
261 0006303, // ASL R3
262 0006303, // ASL R3
263 0006303, // ASL R3
264 0006303, // ASL R3
265 0012701, 0177412, // MOV #RKDA, R1 ; rkda
266 0010311, // MOV R3, (R1) ; load da
267 0005041, // CLR -(R1) ; clear ba
268 0012741, 0177000, // MOV #-256.*2, -(R1) ; load wc
269 0012741, 0000005, // MOV #READ+GO, -(R1) ; read & go
270 0005002, // CLR R2
271 0005003, // CLR R3
272 0012704, uint16_t(kBOOT_START+020), // MOV #START+20, R4 ; ?? unclear ??
273 0005005, // CLR R5
274 0105711, // TSTB (R1)
275 0100376, // BPL .-4
276 0105011, // CLRB (R1)
277 0005007 // CLR PC (5007)
278 };
279
280 code.clear();
281 code.insert(code.end(), std::begin(bootcode), std::end(bootcode));
282 aload = kBOOT_START;
283 astart = kBOOT_START+2;
284 return true;
285}
286
287//------------------------------------------+-----------------------------------
289
290void Rw11CntlRK11::Dump(std::ostream& os, int ind, const char* text,
291 int detail) const
292{
293 RosFill bl(ind);
294 os << bl << (text?text:"--") << "Rw11CntlRK11 @ " << this << endl;
295 os << bl << " fPC_rkwc: " << fPC_rkwc << endl;
296 os << bl << " fPC_rkba: " << fPC_rkba << endl;
297 os << bl << " fPC_rkda: " << fPC_rkda << endl;
298 os << bl << " fPC_rkmr: " << fPC_rkmr << endl;
299 os << bl << " fPC_rkcs: " << fPC_rkcs << endl;
300 os << bl << " fRd_rkcs: " << fRd_rkcs << endl;
301 os << bl << " fRd_rkda: " << fRd_rkda << endl;
302 os << bl << " fRd_addr: " << fRd_addr << endl;
303 os << bl << " fRd_lba: " << fRd_lba << endl;
304 os << bl << " fRd_nwrd: " << fRd_nwrd << endl;
305 os << bl << " fRd_fu: " << fRd_fu << endl;
306 os << bl << " fRd_ovr: " << RosPrintf(fRd_ovr) << endl;
307 fRdma.Dump(os, ind+2, "fRdma: ", detail);
308 Rw11CntlBase<Rw11UnitRK11,8>::Dump(os, ind, " ^", detail);
309 return;
310}
311
312//------------------------------------------+-----------------------------------
314
316{
319
320 uint16_t rkwc = fPrimClist[fPC_rkwc].Data();
321 uint16_t rkba = fPrimClist[fPC_rkba].Data();
322 uint16_t rkda = fPrimClist[fPC_rkda].Data();
323 //uint16_t rkmr = fPrimClist[fPC_rkmr].Data();
324 uint16_t rkcs = fPrimClist[fPC_rkcs].Data();
325
326 uint16_t se = rkda & kRKDA_B_SC;
327 uint16_t hd = (rkda>>kRKDA_V_SUR) & kRKDA_B_SUR;
328 uint16_t cy = (rkda>>kRKDA_V_CYL) & kRKDA_B_CYL;
329 uint16_t dr = (rkda>>kRKDA_V_DRSEL) & kRKDA_B_DRSEL;
330
331 bool go = rkcs & kRKCS_M_GO;
332 uint16_t fu = (rkcs>>kRKCS_V_FUNC) & kRKCS_B_FUNC;
333 uint16_t mex = (rkcs>>kRKCS_V_MEX) & kRKCS_B_MEX;
334 uint32_t addr = uint32_t(mex)<<16 | uint32_t(rkba);
335
336 // Note: apparently are operands first promoted to 32 bit -> mask after ~ !
337 uint32_t nwrd = (~uint32_t(rkwc)&0xffff) + 1; // transfer size in words
338
339 if (!go) {
340 RlogMsg lmsg(LogFile());
341 lmsg << "-I " << Name() << ":"
342 << " cs=" << RosPrintBvi(rkcs,8)
343 << " go=0, spurious attn, dropped";
344 return 0;
345 }
346
347 // all 8 units are always available, but check anyway
348 if (dr > NUnit())
349 throw Rexception("Rw11CntlRK11::AttnHandler","Bad state: dr > NUnit()");
350
351 Rw11UnitRK11& unit = *fspUnit[dr];
352 Rw11Cpu& cpu = Cpu();
353 RlinkCommandList clist;
354
355 uint32_t lba = unit.Chs2Lba(cy,hd,se);
356 uint32_t nblk = unit.Nwrd2Nblk(nwrd);
357
358 uint16_t rker = 0;
359 uint16_t rkds = unit.Rkds();
360
361 if (fTraceLevel>0) {
362 RlogMsg lmsg(LogFile());
363 static const char* fumnemo[8] = {"cr","w ","r ","wc","sk","rc","dr","wl"};
364
365 lmsg << "-I " << Name() << ":"
366 << " cs=" << RosPrintBvi(rkcs,8)
367 << " da=" << RosPrintBvi(rkda,8)
368 << " ad=" << RosPrintBvi(addr,8,18)
369 << " fu=" << fumnemo[fu&0x7]
370 << " pa=" << dr
371 << "," << RosPrintf(cy,"d",3)
372 << "," << hd
373 << "," << RosPrintf(se,"d",2)
374 << " la,nw=" << RosPrintf(lba,"d",4)
375 << "," << RosPrintf(nwrd,"d",5);
376 }
377
378 // check for spurious interrupts (either RDY=1 or RDY=0 and rdma busy)
379 if ((rkcs & kRKCS_M_RDY) || fRdma.IsActive()) {
380 RlogMsg lmsg(LogFile());
381 lmsg << "-E " << Name() << ": err"
382 << " cr=" << RosPrintBvi(rkcs,8)
383 << " spurious lam: "
384 << (fRdma.IsActive() ? "RDY=0 and Rdma busy" : "RDY=1");
385 return 0;
386 }
387
388 // check for general abort conditions
389 if (fu != kFUNC_CRESET && // function not control reset
390 (!unit.HasVirt())) { // and drive not attached
391 rker = kRKER_M_NXD; // --> abort with NXD error
392
393 } else if (fu != kFUNC_WRITE && // function neither write
394 fu != kFUNC_READ && // nor read
395 (rkcs & (kRKCS_M_FMT|kRKCS_M_RWA))) { // and FMT or RWA set
396 rker = kRKER_M_PGE; // --> abort with PGE error
397 } else if (rkcs & kRKCS_M_RWA) { // RWA not supported
398 rker = kRKER_M_DRE; // --> abort with DRE error
399 }
400
401 if (rker) {
402 cpu.AddWibr(clist, fBase+kRKER, rker);
403 if (fu == kFUNC_SEEK || fu == kFUNC_DRESET)
404 cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_SBCLR | (1u<<dr));
405 cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
406 LogRker(rker);
407 Server().Exec(clist);
408 return 0;
409 }
410
411 // check for overrun (read/write beyond cylinder 203)
412 // if found, truncate request length
413 bool ovr = lba + nblk > unit.NBlock();
414 if (ovr) nwrd = (unit.NBlock()-lba) * (unit.BlockSize()/2);
415
416 // remember request parameters for call back
417 fRd_rkcs = rkcs;
418 fRd_rkda = rkda;
419 fRd_addr = addr;
420 fRd_lba = lba;
421 fRd_nwrd = nwrd;
422 fRd_ovr = ovr;
423 fRd_fu = fu;
424
425 // now handle the functions
426 if (fu == kFUNC_CRESET) { // Control reset -----------------
428 cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_CRESET);
429
430 } else if (fu == kFUNC_WRITE) { // Write -------------------------
431 // Note: WRITE+FMT is just WRITE
433 if (se >= unit.NSector()) rker |= kRKER_M_NXS;
434 if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
435 if (unit.WProt()) rker |= kRKER_M_WLO;
436 if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE; // IBA not supported
437 if (rker) {
438 AddErrorExit(clist, rker);
439 } else {
440 fRdma.QueueDiskWrite(addr, nwrd, Rw11Cpu::kCPAH_M_UBM22, lba, &unit);
441 }
442
443 } else if (fu == kFUNC_READ) { // Read --------------------------
445 if (se >= unit.NSector()) rker |= kRKER_M_NXS;
446 if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
447 if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE; // IBA not supported
448 if (rker) {
449 AddErrorExit(clist, rker);
450 } else {
451 fRdma.QueueDiskRead(addr, nwrd, Rw11Cpu::kCPAH_M_UBM22, lba, &unit);
452 }
453
454 } else if (fu == kFUNC_WCHK) { // Write Check -------------------
456 if (se >= unit.NSector()) rker |= kRKER_M_NXS;
457 if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
458 if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE; // IBA not supported
459 if (rker) {
460 AddErrorExit(clist, rker);
461 } else {
462 fRdma.QueueDiskWriteCheck(addr, nwrd, Rw11Cpu::kCPAH_M_UBM22, lba, &unit);
463 }
464
465 } else if (fu == kFUNC_SEEK) { // Seek --------------------------
467 if (se >= unit.NSector()) rker |= kRKER_M_NXS;
468 if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
469 if (rker) {
470 cpu.AddWibr(clist, fBase+kRKER, rker);
471 cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_SBCLR | (1u<<dr));
472 cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
473 LogRker(rker);
474 } else {
475 cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
476 rkds &= ~kRKDS_B_SC; // replace current sector number
477 rkds |= se;
478 unit.SetRkds(rkds);
479 cpu.AddWibr(clist, fBase+kRKDS, rkds);
480 cpu.AddWibr(clist, fBase+kRKMR, 1u<<dr); // issue seek done
481 }
482
483 } else if (fu == kFUNC_RCHK) { // Read Check --------------------
485 if (se >= unit.NSector()) rker |= kRKER_M_NXS;
486 if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
487 if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE; // IBA not supported
488 if (rker) {
489 AddErrorExit(clist, rker);
490 } else {
491 AddNormalExit(clist, nwrd, 0); // no action, virt disks don't err
492 }
493
494 } else if (fu == kFUNC_DRESET) { // Drive Reset -------------------
496 cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
497 cpu.AddWibr(clist, fBase+kRKMR, 1u<<dr); // issue seek done
498
499 } else if (fu == kFUNC_WLOCK) { // Write Lock --------------------
501 rkds |= kRKDS_M_WPS; // set RKDS write protect flag
502 unit.SetRkds(rkds);
503 unit.SetWProt(true);
504 cpu.AddWibr(clist, fBase+kRKDS, rkds);
505 cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
506 }
507
508 if (clist.Size()) { // if handled directly
509 Server().Exec(clist); // doit
510 }
511 return 0;
512}
513
514//------------------------------------------+-----------------------------------
516
517void Rw11CntlRK11::RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext,
518 RlinkCommandList& clist)
519{
520 // if last chunk and not doing WCHK add a labo and normal exit csr update
521 if (stat == Rw11Rdma::kStatusBusyLast && fRd_fu != kFUNC_WCHK) {
522 clist.AddLabo();
523 AddNormalExit(clist, nwdone+nwnext, 0);
524 }
525 return;
526}
527
528//------------------------------------------+-----------------------------------
530
531void Rw11CntlRK11::RdmaPostExecCB(int stat, size_t ndone,
532 RlinkCommandList& clist, size_t ncmd)
533{
534 if (stat == Rw11Rdma::kStatusBusy) return;
535
536 uint16_t rker = 0;
537
538 // handle write check
539 if (fRd_fu == kFUNC_WCHK) {
540 size_t nwcok = fRdma.WriteCheck(ndone);
541 if (nwcok != ndone) { // if mismatch found
542 rker |= kRKER_M_WCE; // set error flag
543 if (fRd_rkcs & kRKCS_M_SSE) { // if 'stop-on-soft' requested
544 ndone = nwcok; // truncate word count
545 }
546 }
547 }
548
549 // handle Rdma aborts
550 if (stat == Rw11Rdma::kStatusFailRdma) rker |= kRKER_M_NXM;
551
552 // check for fused csr updates
553 if (clist.Size() > ncmd) {
554 uint8_t ccode = clist[ncmd].Command();
555 uint16_t cdata = clist[ncmd].Data();
556 if (ccode != RlinkCommand::kCmdLabo || (rker != 0 && cdata == 0))
557 throw Rexception("Rw11CntlRK11::RdmaPostExecCB",
558 "Bad state: Labo not found or missed abort");
559 if (cdata == 0) return;
560 }
561
562 // finally to RK11 register update
563 RlinkCommandList clist1;
564 AddNormalExit(clist1, ndone, rker);
565 Server().Exec(clist1);
566
567 return;
568}
569
570//------------------------------------------+-----------------------------------
572
573void Rw11CntlRK11::LogRker(uint16_t rker)
574{
575 RlogMsg lmsg(LogFile());
576 lmsg << "-E " << Name() << ": er=" << RosPrintBvi(rker,8) << " ERROR ABORT";
577}
578
579//------------------------------------------+-----------------------------------
581
583{
584 Rw11Cpu& cpu = Cpu();
585 cpu.AddWibr(clist, fBase+kRKER, rker);
586 cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
587 LogRker(rker);
588 return;
589}
590
591//------------------------------------------+-----------------------------------
593
595 uint16_t rker)
596{
597 Rw11Cpu& cpu = Cpu();
598 uint16_t dr = (fRd_rkda>>kRKDA_V_DRSEL) & kRKDA_B_DRSEL;
599 Rw11UnitRK11& unit = *fspUnit[dr];
600
601 size_t nblk = unit.Nwrd2Nblk(ndone);
602
603 uint32_t addr = fRd_addr + 2*ndone;
604 size_t lba = fRd_lba + nblk;
605 uint32_t nrest = fRd_nwrd - ndone;
606
607 uint16_t ba = addr & 0177776; // get lower 16 bits
608 uint16_t mex = (addr>>16) & 03; // get upper 2 bits
609 uint16_t cs = (fRd_rkcs & ~kRKCS_M_MEX) | (mex << kRKCS_V_MEX);
610 uint16_t se;
611 uint16_t hd;
612 uint16_t cy;
613 unit.Lba2Chs(lba, cy,hd,se);
614 uint16_t da = (fRd_rkda & kRKDA_M_DRSEL) | (cy<<kRKDA_V_CYL) |
615 (hd<<kRKDA_V_SUR) | se;
616
617 if (fRd_ovr) rker |= kRKER_M_OVR;
618
619 if (rker) {
620 cpu.AddWibr(clist, fBase+kRKER, rker);
621 LogRker(rker);
622 }
623 cpu.AddWibr(clist, fBase+kRKWC, uint16_t((-nrest)&0177777));
624 cpu.AddWibr(clist, fBase+kRKBA, ba);
625 cpu.AddWibr(clist, fBase+kRKDA, da);
626 if (cs != fRd_rkcs)
627 cpu.AddWibr(clist, fBase+kRKCS, cs);
628 cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
629
630 return;
631}
632
633
634} // end namespace Retro
FIXME_docs.
Definition: Rexception.hpp:29
size_t AddAttn()
FIXME_docs.
size_t Size() const
FIXME_docs.
size_t AddLabo()
FIXME_docs.
static const uint8_t kCmdLabo
command code list abort
void AddAttnHandler(attnhdl_t &&attnhdl, uint16_t mask, void *cdata=nullptr)
FIXME_docs.
void GetAttnInfo(AttnArgs &args, RlinkCommandList &clist)
FIXME_docs.
bool Exec(RlinkCommandList &clist, RerrMsg &emsg)
FIXME_docs.
Definition: RlinkServer.ipp:60
FIXME_docs.
Definition: RlogMsg.hpp:24
I/O appicator to generate fill characters.
Definition: RosFill.hpp:24
void Inc(size_t ind, double val=1.)
FIXME_docs.
Definition: Rstats.ipp:29
void Define(size_t ind, const std::string &name, const std::string &text)
FIXME_docs.
Definition: Rstats.cpp:72
Implemenation (inline) of Rw11CntlBase.
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
virtual size_t NUnit() const
FIXME_docs.
std::shared_ptr< Rw11UnitRK11 > fspUnit[NU]
static const uint16_t kRKDA_M_SUR
static const uint16_t kFUNC_CRESET
static const uint16_t kRKER_M_CSE
static const uint16_t kRKER_M_OVR
static const bool kProbeInt
probe int active
bool fRd_ovr
Rdma: overrun condition found.
void Config(const std::string &name, uint16_t base, int lam)
FIXME_docs.
static const uint16_t kRKDS_M_WPS
WPS: write protect.
static const uint16_t kRKDS_M_ID
ID: drive number.
static const uint16_t kRKMR_V_RID
static const uint16_t kRKMR_M_SBCLR
Rw11CntlRK11()
Default constructor.
static const uint16_t kRKCS_M_MAINT
uint16_t fRd_fu
Rdma: request fu code.
static const uint16_t kRKDS_M_DRY
DRY: drive ready.
static const uint16_t kRKER_M_WCE
virtual void UnitSetup(size_t ind)
FIXME_docs.
static const uint16_t kFUNC_WLOCK
static const uint16_t kRKER_M_NXC
static const uint16_t kRKBA
RKBA reg offset.
static const uint16_t kRKDS_B_ID
static const uint16_t kFUNC_RCHK
size_t fPC_rkwc
PrimClist: rkwc index.
static const uint16_t kRKER_M_PGE
void RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext, RlinkCommandList &clist)
FIXME_docs.
static const uint16_t kRKDA_B_SC
static const uint16_t kRKMR
RKMR reg offset.
void LogRker(uint16_t rker)
FIXME_docs.
static const uint16_t kRKDA
RKDA reg offset.
static const uint16_t kRKDA_V_SUR
static const uint16_t kRKDS_M_SIN
SIN: seek incomplete.
void RdmaPostExecCB(int stat, size_t ndone, RlinkCommandList &clist, size_t ncmd)
FIXME_docs.
static const uint16_t kRKCS_M_FMT
static const uint16_t kRKMR_M_CRESET
static const bool kProbeRem
probr rem active
static const uint16_t kRKWC
RKWC reg offset.
size_t fPC_rkmr
PrimClist: rkmr index.
static const uint16_t kRKDS_M_ADRY
ADRY: access ready.
@ kStatNFuncWlock
func WLOCK
@ kStatNFuncDreset
func DRESET
@ kStatNFuncWrite
func WRITE
@ kStatNFuncRead
func READ
@ kStatNFuncRchk
func RCHK
@ kStatNFuncCreset
func CRESET
@ kStatNFuncSeek
func SEEK
@ kStatNFuncWchk
func WCHK
static const uint16_t kRKMR_M_CRDONE
static const int kLam
RK11 default lam.
static const uint16_t kRKDA_M_CYL
static const uint16_t kRKER_M_DRE
static const uint16_t kRKDS_M_DRU
DRU: drive unsafe.
static const uint16_t kRKDS_V_ID
static const uint16_t kRKCS_M_IBA
static const uint16_t kRKDS_M_HDEN
HDEN: high density drv.
static const uint16_t kRKMR_M_RID
size_t fPC_rkba
PrimClist: rkba index.
uint32_t fRd_addr
Rdma: current addr.
static const uint16_t kRKCS_V_MEX
int AttnHandler(RlinkServer::AttnArgs &args)
FIXME_docs.
static const uint16_t kRKCS_B_FUNC
static const uint16_t kRKCS_M_MEX
uint32_t fRd_nwrd
Rdma: current nwrd.
static const uint16_t kRKCS_B_MEX
static const uint16_t kRKDA_B_CYL
static const uint16_t kRKDA_V_DRSEL
static const uint16_t kRKCS_M_RDY
static const uint16_t kRKDA_V_CYL
static const uint16_t kRKCS
RKCS reg offset.
~Rw11CntlRK11()
Destructor.
static const uint16_t kRKER
RKER reg offset.
virtual bool BootCode(size_t unit, std::vector< uint16_t > &code, uint16_t &aload, uint16_t &astart)
FIXME_docs.
static const uint16_t kFUNC_READ
virtual void Start()
FIXME_docs.
static const uint16_t kRKER_M_NXD
void AddNormalExit(RlinkCommandList &clist, size_t ndone, uint16_t rker=0)
FIXME_docs.
static const uint16_t kFUNC_SEEK
uint32_t fRd_lba
Rdma: current lba.
uint16_t fRd_rkcs
Rdma: request rkcs.
static const uint16_t kFUNC_DRESET
static const uint16_t kRKDA_B_SUR
static const uint16_t kRKER_M_WLO
static const uint16_t kRKDA_M_DRSEL
static const uint16_t kFUNC_WRITE
static const uint16_t kProbeOff
probe address offset (rkcs)
void AddErrorExit(RlinkCommandList &clist, uint16_t rker)
FIXME_docs.
static const uint16_t kRKCS_M_RWA
static const uint16_t kRKCS_V_FUNC
static const uint16_t kIbaddr
RK11 default address.
uint16_t fRd_rkda
Rdma: request rkda.
static const uint16_t kRKCS_M_GO
static const uint16_t kRKER_M_NXM
static const uint16_t kRKDA_B_DRSEL
static const uint16_t kRKDS
RKDS reg offset.
static const uint16_t kRKDS_B_SC
SC: sector counter.
static const uint16_t kRKMR_M_FDONE
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
static const uint16_t kRKCS_M_SSE
size_t fPC_rkda
PrimClist: rkda index.
static const uint16_t kFUNC_WCHK
static const uint16_t kRKER_M_NXS
static const uint16_t kRKDS_M_SOK
SOK: sector counter OK.
Rw11RdmaDisk fRdma
Rdma controller.
size_t fPC_rkcs
PrimClist: rkcs index.
int fLam
attn bit number (-1 of none)
Definition: Rw11Cntl.hpp:110
uint32_t fTraceLevel
trace level; 0=off;1=cntl
Definition: Rw11Cntl.hpp:114
RlinkCommandList fPrimClist
clist for attn primary info
Definition: Rw11Cntl.hpp:115
uint16_t Base() const
FIXME_docs.
Definition: Rw11Cntl.ipp:88
Rstats fStats
statistics
Definition: Rw11Cntl.hpp:116
Rw11Probe fProbe
controller probe context
Definition: Rw11Cntl.hpp:113
Rw11Cpu & Cpu() const
FIXME_docs.
Definition: Rw11Cntl.ipp:32
void ConfigCntl(const std::string &name, uint16_t base, int lam, uint16_t probeoff, bool probeint, bool proberem)
FIXME_docs.
Definition: Rw11Cntl.cpp:156
bool fStarted
true if Start() called
Definition: Rw11Cntl.hpp:112
bool fEnable
enable flag
Definition: Rw11Cntl.hpp:111
RlinkServer & Server() const
FIXME_docs.
Definition: Rw11Cntl.ipp:48
const std::string & Name() const
FIXME_docs.
Definition: Rw11Cntl.ipp:80
RlogFile & LogFile() const
FIXME_docs.
Definition: Rw11Cntl.ipp:64
virtual void UnitSetupAll()
FIXME_docs.
Definition: Rw11Cntl.cpp:113
uint16_t fBase
controller base address
Definition: Rw11Cntl.hpp:109
FIXME_docs.
Definition: Rw11Cpu.hpp:66
void AllIAddrMapInsert(const std::string &name, uint16_t ibaddr)
FIXME_docs.
Definition: Rw11Cpu.cpp:902
void ExecWibr(uint16_t ibaddr0, uint16_t data0, uint16_t ibaddr1=0, uint16_t data1=0, uint16_t ibaddr2=0, uint16_t data2=0)
FIXME_docs.
Definition: Rw11Cpu.cpp:491
int AddWibr(RlinkCommandList &clist, uint16_t ibaddr, uint16_t data)
FIXME_docs.
Definition: Rw11Cpu.cpp:365
int AddRibr(RlinkCommandList &clist, uint16_t ibaddr)
FIXME_docs.
Definition: Rw11Cpu.cpp:354
static const uint16_t kCPAH_M_UBM22
ubmap+22bit
Definition: Rw11Cpu.hpp:228
void QueueDiskWrite(uint32_t addr, size_t size, uint16_t mode, uint32_t lba, Rw11UnitDisk *punit)
FIXME_docs.
void QueueDiskWriteCheck(uint32_t addr, size_t size, uint16_t mode, uint32_t lba, Rw11UnitDisk *punit)
FIXME_docs.
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
size_t WriteCheck(size_t nwdone)
FIXME_docs.
void QueueDiskRead(uint32_t addr, size_t size, uint16_t mode, uint32_t lba, Rw11UnitDisk *punit)
FIXME_docs.
bool IsActive() const
FIXME_docs.
Definition: Rw11Rdma.ipp:77
@ kStatusBusyLast
last chunk to come
Definition: Rw11Rdma.hpp:85
@ kStatusFailRdma
last rdma transfer failed
Definition: Rw11Rdma.hpp:86
@ kStatusBusy
more chunks to come
Definition: Rw11Rdma.hpp:84
size_t NCylinder() const
FIXME_docs.
void SetWProt(bool wprot)
FIXME_docs.
bool WProt() const
FIXME_docs.
uint32_t Chs2Lba(uint16_t cy, uint16_t hd, uint16_t se)
FIXME_docs.
size_t NBlock() const
FIXME_docs.
size_t NSector() const
FIXME_docs.
size_t BlockSize() const
FIXME_docs.
void Lba2Chs(uint32_t lba, uint16_t &cy, uint16_t &hd, uint16_t &se)
FIXME_docs.
uint32_t Nwrd2Nblk(uint32_t nwrd)
FIXME_docs.
void SetRkds(uint16_t rkds)
FIXME_docs.
uint16_t Rkds() const
FIXME_docs.
bool HasVirt() const
FIXME_docs.
RosPrintfS< bool > RosPrintf(bool value, const char *form=0, int width=0, int prec=0)
Creates a print object for the formatted output of a bool value.
Definition: RosPrintf.ipp:38
Declaration of class ReventLoop.
Definition: ReventLoop.cpp:47
bool Found() const
FIXME_docs.
Definition: Rw11Probe.cpp:52