w11 - cpp 0.794
Backend server for Rlink and w11
Loading...
Searching...
No Matches
Rw11CntlRHRP.cpp
Go to the documentation of this file.
1// $Id: Rw11CntlRHRP.cpp 1186 2019-07-12 17:49:59Z mueller $
2// SPDX-License-Identifier: GPL-3.0-or-later
3// Copyright 2015-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 1.0.12 use ExecWibr()
10// 2019-04-14 1131 1.0.11 proper unit init, call UnitSetupAll() in Start()
11// 2019-02-23 1114 1.0.10 use std::bind instead of lambda
12// 2018-12-19 1090 1.0.9 use RosPrintf(bool)
13// 2018-12-15 1082 1.0.8 use std::bind or lambda instead of boost::bind
14// 2018-12-09 1080 1.0.7 use HasVirt(); Virt() returns ref
15// 2018-10-28 1062 1.0.6 replace boost/foreach
16// 2017-04-02 865 1.0.5 Dump(): add detail arg
17// 2017-03-03 858 1.0.4 use cntl name as message prefix
18// 2015-12-28 720 1.0.3 use octal for er1= printouts
19// 2015-06-04 686 1.0.2 check for spurious lams
20// 2015-05-24 684 1.0.1 fixed rpcs2 update for wcheck and nem aborts
21// 2015-05-14 680 1.0 Initial version
22// 2015-03-21 659 0.1 First draft
23// ---------------------------------------------------------------------------
24
29#include <functional>
30
31#include "librtools/RosFill.hpp"
35#include "librtools/RlogMsg.hpp"
36
37#include "Rw11CntlRHRP.hpp"
38
39using namespace std;
40using namespace std::placeholders;
41
47// all method definitions in namespace Retro
48namespace Retro {
49
50//------------------------------------------+-----------------------------------
51// constants definitions
52
53const uint16_t Rw11CntlRHRP::kIbaddr;
54const int Rw11CntlRHRP::kLam;
55
56const uint16_t Rw11CntlRHRP::kRPCS1;
57const uint16_t Rw11CntlRHRP::kRPWC;
58const uint16_t Rw11CntlRHRP::kRPBA;
59const uint16_t Rw11CntlRHRP::kRPDA;
60const uint16_t Rw11CntlRHRP::kRPCS2;
61const uint16_t Rw11CntlRHRP::kRPDS;
62const uint16_t Rw11CntlRHRP::kRPER1;
63const uint16_t Rw11CntlRHRP::kRPAS;
64const uint16_t Rw11CntlRHRP::kRPLA;
65const uint16_t Rw11CntlRHRP::kRPDB;
66const uint16_t Rw11CntlRHRP::kRPMR1;
67const uint16_t Rw11CntlRHRP::kRPDT;
68const uint16_t Rw11CntlRHRP::kRPSN;
69const uint16_t Rw11CntlRHRP::kRPOF;
70const uint16_t Rw11CntlRHRP::kRPDC;
71const uint16_t Rw11CntlRHRP::kRxM13;
72const uint16_t Rw11CntlRHRP::kRxM14;
73const uint16_t Rw11CntlRHRP::kRxM15;
74const uint16_t Rw11CntlRHRP::kRPEC1;
75const uint16_t Rw11CntlRHRP::kRPEC2;
76const uint16_t Rw11CntlRHRP::kRPBAE;
77const uint16_t Rw11CntlRHRP::kRPCS3;
78
79const uint16_t Rw11CntlRHRP::kProbeOff;
82
83const uint16_t Rw11CntlRHRP::kRPCS1_M_SC;
84const uint16_t Rw11CntlRHRP::kRPCS1_M_TRE;
85const uint16_t Rw11CntlRHRP::kRPCS1_M_DVA;
86const uint16_t Rw11CntlRHRP::kRPCS1_M_BAE;
87const uint16_t Rw11CntlRHRP::kRPCS1_V_BAE;
88const uint16_t Rw11CntlRHRP::kRPCS1_B_BAE;
89const uint16_t Rw11CntlRHRP::kRPCS1_M_RDY;
90const uint16_t Rw11CntlRHRP::kRPCS1_M_IE;
91const uint16_t Rw11CntlRHRP::kRPCS1_V_FUNC;
92const uint16_t Rw11CntlRHRP::kRPCS1_B_FUNC;
93const uint16_t Rw11CntlRHRP::kRPCS1_M_GO;
94
95const uint16_t Rw11CntlRHRP::kFUNC_WCD;
96const uint16_t Rw11CntlRHRP::kFUNC_WCHD;
97const uint16_t Rw11CntlRHRP::kFUNC_WRITE;
98const uint16_t Rw11CntlRHRP::kFUNC_WHD;
99const uint16_t Rw11CntlRHRP::kFUNC_READ;
100const uint16_t Rw11CntlRHRP::kFUNC_RHD;
101
102const uint16_t Rw11CntlRHRP::kRFUNC_WUNIT;
103const uint16_t Rw11CntlRHRP::kRFUNC_CUNIT;
104const uint16_t Rw11CntlRHRP::kRFUNC_DONE;
105const uint16_t Rw11CntlRHRP::kRFUNC_WIDLY;
106
107const uint16_t Rw11CntlRHRP::kRPCS1_V_RUNIT;
108const uint16_t Rw11CntlRHRP::kRPCS1_B_RUNIT;
109const uint16_t Rw11CntlRHRP::kRPCS1_M_RATA;
110const uint16_t Rw11CntlRHRP::kRPCS1_V_RIDLY;
111const uint16_t Rw11CntlRHRP::kRPCS1_B_RIDLY;
112
113const uint16_t Rw11CntlRHRP::kRPDA_V_TA;
114const uint16_t Rw11CntlRHRP::kRPDA_B_TA;
115const uint16_t Rw11CntlRHRP::kRPDA_B_SA;
116
117const uint16_t Rw11CntlRHRP::kRPCS2_M_RWCO;
118const uint16_t Rw11CntlRHRP::kRPCS2_M_WCE;
119const uint16_t Rw11CntlRHRP::kRPCS2_M_NED;
120const uint16_t Rw11CntlRHRP::kRPCS2_M_NEM;
121const uint16_t Rw11CntlRHRP::kRPCS2_M_PGE;
122const uint16_t Rw11CntlRHRP::kRPCS2_M_MXF;
123const uint16_t Rw11CntlRHRP::kRPCS2_M_OR;
124const uint16_t Rw11CntlRHRP::kRPCS2_M_IR;
125const uint16_t Rw11CntlRHRP::kRPCS2_M_CLR;
126const uint16_t Rw11CntlRHRP::kRPCS2_M_PAT;
127const uint16_t Rw11CntlRHRP::kRPCS2_M_BAI;
128const uint16_t Rw11CntlRHRP::kRPCS2_M_UNIT2;
129const uint16_t Rw11CntlRHRP::kRPCS2_B_UNIT;
130
131const uint16_t Rw11CntlRHRP::kRPDS_M_ATA;
132const uint16_t Rw11CntlRHRP::kRPDS_M_ERP;
133const uint16_t Rw11CntlRHRP::kRPDS_M_MOL;
134const uint16_t Rw11CntlRHRP::kRPDS_M_WRL;
135const uint16_t Rw11CntlRHRP::kRPDS_M_LBT;
136const uint16_t Rw11CntlRHRP::kRPDS_M_DPR;
137const uint16_t Rw11CntlRHRP::kRPDS_M_DRY;
138const uint16_t Rw11CntlRHRP::kRPDS_M_VV;
139const uint16_t Rw11CntlRHRP::kRPDS_M_OM ;
140
141const uint16_t Rw11CntlRHRP::kRPER1_M_UNS;
142const uint16_t Rw11CntlRHRP::kRPER1_M_WLE;
143const uint16_t Rw11CntlRHRP::kRPER1_M_IAE;
144const uint16_t Rw11CntlRHRP::kRPER1_M_AOE;
145const uint16_t Rw11CntlRHRP::kRPER1_M_RMR;
146const uint16_t Rw11CntlRHRP::kRPER1_M_ILF;
147
148const uint16_t Rw11CntlRHRP::kRPDC_B_CA;
149
150const uint16_t Rw11CntlRHRP::kRPCS3_M_IE;
155
156//------------------------------------------+-----------------------------------
158
160 : Rw11CntlBase<Rw11UnitRHRP,4>("rhrp"),
161 fPC_rpcs1(0),
162 fPC_rpcs2(0),
163 fPC_rpcs3(0),
164 fPC_rpwc(0),
165 fPC_rpba(0),
166 fPC_rpbae(0),
167 fPC_cunit(0),
168 fPC_rpds(0),
169 fPC_rpda(0),
170 fPC_rpdc(0),
171 fRd_rpcs1(0),
172 fRd_rpcs2(0),
173 fRd_rpcs3(0),
174 fRd_rpwc(0),
175 fRd_rpba(0),
176 fRd_rpbae(0),
177 fRd_rpds(0),
178 fRd_rpda(0),
179 fRd_rpdc(0),
180 fRd_addr(0),
181 fRd_lba(0),
182 fRd_nwrd(0),
183 fRd_fu(0),
184 fRd_ovr(false),
185 fRdma(this,
186 std::bind(&Rw11CntlRHRP::RdmaPreExecCB, this, _1, _2, _3, _4),
187 std::bind(&Rw11CntlRHRP::RdmaPostExecCB, this, _1, _2, _3, _4))
188{
189 // must be here because Units have a back-ptr (not available at Rw11CntlBase)
190 for (size_t i=0; i<NUnit(); i++) {
191 fspUnit[i].reset(new Rw11UnitRHRP(this, i));
192 }
193
194 fStats.Define(kStatNFuncWchk , "NFuncWchk" , "func WCHK");
195 fStats.Define(kStatNFuncWrite , "NFuncWrite" , "func WRITE");
196 fStats.Define(kStatNFuncRead , "NFuncRead" , "func READ");
197 fStats.Define(kStatNFuncSear , "NFuncSear" , "func SEARCH (loc)");
198 fStats.Define(kStatNFuncPack , "NFuncPack" , "func PACK ACK (loc)");
199 fStats.Define(kStatNFuncPore , "NFuncPore" , "func PORT REL (loc)");
200 fStats.Define(kStatNFuncSeek , "NFuncSeek" , "func SEEK (loc)");
201}
202
203//------------------------------------------+-----------------------------------
205
207{}
208
209//------------------------------------------+-----------------------------------
211
212void Rw11CntlRHRP::Config(const std::string& name, uint16_t base, int lam)
213{
214 ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
215 return;
216}
217
218//------------------------------------------+-----------------------------------
220
222{
223 if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
224 throw Rexception("Rw11CntlRHRP::Start",
225 "Bad state: started, no lam, not enable, not found");
226
227 // add device register address ibus and rbus mappings
228 // done here because now Cntl bound to Cpu and Cntl probed
229 Cpu().AllIAddrMapInsert(Name()+".cs1", Base() + kRPCS1);
230 Cpu().AllIAddrMapInsert(Name()+".wc", Base() + kRPWC);
231 Cpu().AllIAddrMapInsert(Name()+".ba", Base() + kRPBA);
232 Cpu().AllIAddrMapInsert(Name()+".da", Base() + kRPDA);
233 Cpu().AllIAddrMapInsert(Name()+".cs2", Base() + kRPCS2);
234 Cpu().AllIAddrMapInsert(Name()+".ds", Base() + kRPDS);
235 Cpu().AllIAddrMapInsert(Name()+".er1", Base() + kRPER1);
236 Cpu().AllIAddrMapInsert(Name()+".as", Base() + kRPAS);
237 Cpu().AllIAddrMapInsert(Name()+".la", Base() + kRPLA);
238 Cpu().AllIAddrMapInsert(Name()+".db", Base() + kRPDB);
239 Cpu().AllIAddrMapInsert(Name()+".mr1", Base() + kRPMR1);
240 Cpu().AllIAddrMapInsert(Name()+".dt", Base() + kRPDT);
241 Cpu().AllIAddrMapInsert(Name()+".sn", Base() + kRPSN);
242 Cpu().AllIAddrMapInsert(Name()+".of", Base() + kRPOF);
243 Cpu().AllIAddrMapInsert(Name()+".dc", Base() + kRPDC);
244 Cpu().AllIAddrMapInsert(Name()+".m13", Base() + kRxM13);
245 Cpu().AllIAddrMapInsert(Name()+".m14", Base() + kRxM14);
246 Cpu().AllIAddrMapInsert(Name()+".m15", Base() + kRxM15);
247 Cpu().AllIAddrMapInsert(Name()+".ec1", Base() + kRPEC1);
248 Cpu().AllIAddrMapInsert(Name()+".ec2", Base() + kRPEC2);
249 Cpu().AllIAddrMapInsert(Name()+".bae", Base() + kRPBAE);
250 Cpu().AllIAddrMapInsert(Name()+".cs3", Base() + kRPCS3);
251
252 // ensure unit status is initialized
253 UnitSetupAll();
254
255 // setup primary info clist
264
267
271
272 // add attn handler
274 uint16_t(1)<<fLam, this);
275
276 fStarted = true;
277 return;
278}
279
280//------------------------------------------+-----------------------------------
282
284{
285 Rw11UnitRHRP& unit = *fspUnit[ind];
286
287 // only two mayor drive states are used
288 // power medium wlock : ds flags
289 // off --- --- : dpr=0 mol=0 wrl=0 (disabled, type=off)
290 // on off --- : dpr=1 mol=0 wrl=0 (enabled, no file attached)
291 // on on no : dpr=1 mol=1 wrl=0 (file attached)
292 // on on yes : dpr=1 mol=1 wrl=1 (file attached + wlock)
293
294 uint16_t rpds = 0;
295
296 if (unit.Type() != "off") { // is enabled
297 rpds |= kRPDS_M_DPR;
298 if (unit.HasVirt()) { // file attached
299 rpds |= kRPDS_M_MOL; // -> set MOL
300 rpds |= kRPDS_M_ERP; // -> clear ER1 via ERP=1
301 if (unit.WProt()) rpds |= kRPDS_M_WRL; // in case write protected
302 }
303 if ((unit.Rpds() ^ rpds) & kRPDS_M_MOL) { // mol state change ?
304 rpds |= kRPDS_M_ATA; // cause attentions
305 rpds |= kRPDS_M_VV; // reset volume valid
306 }
307 }
308
309 unit.SetRpds(rpds); // remember new DS
310 Cpu().ExecWibr(fBase+kRPCS1, (ind << kRPCS1_V_RUNIT) | // setup unit
312 fBase+kRPDT, unit.Rpdt(), // setup DT
313 fBase+kRPDS, rpds); // setup DS
314
315 return;
316}
317
318//------------------------------------------+-----------------------------------
320
321bool Rw11CntlRHRP::BootCode(size_t unit, std::vector<uint16_t>& code,
322 uint16_t& aload, uint16_t& astart)
323{
324 uint16_t kBOOT_START = 02000;
325 uint16_t bootcode[] = { // rh/rp boot loader - from simh pdp11_rp.c (v3.9)
326 0042102, // "BD"
327 0012706, kBOOT_START, // mov #boot_start, sp
328 0012700, uint16_t(unit), // mov #unit, r0
329 0012701, 0176700, // mov #RPCS1, r1
330 0012761, 0000040, 0000010, // mov #CS2_CLR, 10(r1) ; reset
331 0010061, 0000010, // mov r0, 10(r1) ; set unit
332 0012711, 0000021, // mov #RIP+GO, (r1) ; pack ack
333 0012761, 0010000, 0000032, // mov #FMT16B, 32(r1) ; 16b mode
334 0012761, 0177000, 0000002, // mov #-512., 2(r1) ; set wc
335 0005061, 0000004, // clr 4(r1) ; clr ba
336 0005061, 0000006, // clr 6(r1) ; clr da
337 0005061, 0000034, // clr 34(r1) ; clr cyl
338 0012711, 0000071, // mov #READ+GO, (r1) ; read
339 0105711, // tstb (r1) ; wait
340 0100376, // bpl .-2
341 0005002, // clr R2
342 0005003, // clr R3
343 0012704, uint16_t(kBOOT_START+020), // mov #start+020, r4
344 0005005, // clr R5
345 0105011, // clrb (r1)
346 0005007 // clr PC
347 };
348
349 code.clear();
350 code.insert(code.end(), std::begin(bootcode), std::end(bootcode));
351 aload = kBOOT_START;
352 astart = kBOOT_START+2;
353 return true;
354}
355
356//------------------------------------------+-----------------------------------
358
359void Rw11CntlRHRP::Dump(std::ostream& os, int ind, const char* text,
360 int detail) const
361{
362 RosFill bl(ind);
363 os << bl << (text?text:"--") << "Rw11CntlRHRP @ " << this << endl;
364 os << bl << " fPC_rpcs1: " << RosPrintf(fPC_rpcs1,"d",6) << endl;
365 os << bl << " fPC_rpcs2: " << RosPrintf(fPC_rpcs2,"d",6) << endl;
366 os << bl << " fPC_rpcs3: " << RosPrintf(fPC_rpcs3,"d",6) << endl;
367 os << bl << " fPC_rpwc: " << RosPrintf(fPC_rpwc,"d",6) << endl;
368 os << bl << " fPC_rpba: " << RosPrintf(fPC_rpba,"d",6) << endl;
369 os << bl << " fPC_rpbae: " << RosPrintf(fPC_rpbae,"d",6) << endl;
370 os << bl << " fPC_cunit: " << RosPrintf(fPC_cunit,"d",6) << endl;
371 os << bl << " fPC_rpds: " << RosPrintf(fPC_rpds,"d",6) << endl;
372 os << bl << " fPC_rpda: " << RosPrintf(fPC_rpda,"d",6) << endl;
373 os << bl << " fPC_rpdc: " << RosPrintf(fPC_rpdc,"d",6) << endl;
374 os << bl << " fRd_rpcs1: " << RosPrintBvi(fRd_rpcs1) << endl;
375 os << bl << " fRd_rpcs2: " << RosPrintBvi(fRd_rpcs2) << endl;
376 os << bl << " fRd_rpcs3: " << RosPrintBvi(fRd_rpcs3) << endl;
377 os << bl << " fRd_rpwc: " << RosPrintBvi(fRd_rpwc) << endl;
378 os << bl << " fRd_rpba: " << RosPrintBvi(fRd_rpba) << endl;
379 os << bl << " fRd_rpbae: " << RosPrintBvi(fRd_rpbae) << endl;
380 os << bl << " fRd_rpds: " << RosPrintBvi(fRd_rpds) << endl;
381 os << bl << " fRd_rpda: " << RosPrintBvi(fRd_rpda) << endl;
382 os << bl << " fRd_rpdc: " << RosPrintBvi(fRd_rpdc) << endl;
383 os << bl << " fRd_addr: " << RosPrintBvi(fRd_addr,8,22) << endl;
384 os << bl << " fRd_lba: " << RosPrintf(fRd_lba,"d",6) << endl;
385 os << bl << " fRd_nwrd: " << RosPrintf(fRd_nwrd,"d",6) << endl;
386 os << bl << " fRd_fu: " << RosPrintf(fRd_fu,"d",6) << endl;
387 os << bl << " fRd_ovr: " << RosPrintf(fRd_ovr) << endl;
388 fRdma.Dump(os, ind+2, "fRdma: ", detail);
389 Rw11CntlBase<Rw11UnitRHRP,4>::Dump(os, ind, " ^", detail);
390 return;
391}
392
393//------------------------------------------+-----------------------------------
395
397{
400
401 uint16_t rpcs1 = fPrimClist[fPC_rpcs1].Data();
402 uint16_t rpcs2 = fPrimClist[fPC_rpcs2].Data();
403 uint16_t rpcs3 = fPrimClist[fPC_rpcs3].Data();
404 uint16_t rpwc = fPrimClist[fPC_rpwc ].Data();
405 uint16_t rpba = fPrimClist[fPC_rpba ].Data();
406 uint16_t rpbae = fPrimClist[fPC_rpbae].Data();
407 uint16_t rpds = fPrimClist[fPC_rpds ].Data();
408 uint16_t rpda = fPrimClist[fPC_rpda ].Data();
409 uint16_t rpdc = fPrimClist[fPC_rpdc ].Data();
410
411 uint16_t unum = rpcs2 & kRPCS2_B_UNIT;
412 uint16_t fu = (rpcs1>>kRPCS1_V_FUNC) & kRPCS1_B_FUNC;
413
414 uint32_t addr = uint32_t(rpbae)<<16 | uint32_t(rpba);
415
416 uint16_t sa = rpda & kRPDA_B_SA;
417 uint16_t ta = (rpda>>kRPDA_V_TA) & kRPDA_B_TA;
418 uint16_t ca = rpdc & kRPDC_B_CA;
419
420 uint32_t nwrd = (~uint32_t(rpwc)&0xffff) + 1; // transfer size in words
421
422 // all 4 units are always available, but check anyway
423 if (unum >= NUnit())
424 throw Rexception("Rw11CntlRHRP::AttnHandler","Bad state: unum >= NUnit()");
425
426 Rw11UnitRHRP& unit = *fspUnit[unum];
427 //Rw11Cpu& cpu = Cpu();
428 RlinkCommandList clist;
429
430 uint32_t lba = unit.Chs2Lba(ca,ta,sa);
431 uint32_t nblk = unit.Nwrd2Nblk(nwrd);
432
433 if (fTraceLevel>0) {
434 RlogMsg lmsg(LogFile());
435 static const char* fumnemo[32] =
436 {"00 ","01 ","02 ","03 ","04 ","05 ","06 ","07 ", // 00---
437 "10 ","11 ","12 ","13 ","14 ","15 ","16 ","17 ", // 01---
438 "20 ","21 ","22 ","23 ","wc ","wch","26 ","27 ", // 10---
439 "wr ","wrh","32 ","33 ","rd ","rdh","36 ","37 "}; // 11---
440 lmsg << "-I " << Name() << ":"
441 << " fu=" << fumnemo[fu&037]
442 << " cs=" << RosPrintBvi(rpcs1,8)
443 << "," << RosPrintBvi(rpcs2,8)
444 << " ad=" << RosPrintBvi(addr,8,22)
445 << " pa=" << unum
446 << "," << RosPrintf(ca,"d",3)
447 << "," << RosPrintf(ta,"d",2)
448 << "," << RosPrintf(sa,"d",2)
449 << " la,nw=" << RosPrintf(lba,"d",6)
450 << ",";
451 if (nwrd==65536) lmsg << " (0)"; else lmsg << RosPrintf(nwrd,"d",5);
452 }
453
454 // handle cs3 done flags, just count them
459
460 // check for spurious interrupts (either RDY=1 or RDY=0 and rdma busy)
461 if ((rpcs1 & kRPCS1_M_RDY) || fRdma.IsActive()) {
462 RlogMsg lmsg(LogFile());
463 lmsg << "-E RHRP err "
464 << " cs=" << RosPrintBvi(rpcs1,8)
465 << " spurious lam: "
466 << (fRdma.IsActive() ? "RDY=0 and Rdma busy" : "RDY=1");
467 return 0;
468 }
469
470 // check for overrun (read/write beyond last track
471 // if found, truncate request length
472 bool ovr = lba + nblk > unit.NBlock();
473 if (ovr) nwrd = (unit.NBlock()-lba) * (unit.BlockSize()/2);
474
475 // remember request parameters for call back and error exit handling
476
477 fRd_rpcs1 = rpcs1;
478 fRd_rpcs2 = rpcs2;
479 fRd_rpcs3 = rpcs3;
480 fRd_rpwc = rpwc;
481 fRd_rpba = rpba;
482 fRd_rpbae = rpbae;
483 fRd_rpds = rpds;
484 fRd_rpda = rpda;
485 fRd_rpdc = rpdc;
486 fRd_addr = addr;
487 fRd_lba = lba;
488 fRd_nwrd = nwrd;
489 fRd_fu = fu;
490 fRd_ovr = ovr;
491
492 // check for general abort conditions
493 // note: only 'data transfer' functions handled via backend
494 // SEEK and others are done in ibdr_rhrp autonomously
495
496 // not attached --> signal drive unsave status
497 if (! unit.HasVirt()) { // not attached
498 AddErrorExit(clist, kRPER1_M_UNS); // signal UNS (drive unsafe)
499 Server().Exec(clist); // doit
500 return 0;
501 }
502
503 // invalid disk address
504 if (ca > unit.NCylinder() || ta > unit.NHead() || sa > unit.NSector()) {
505 AddErrorExit(clist, kRPER1_M_IAE); // signal IAE (invalid address err)
506 Server().Exec(clist); // doit
507 return 0;
508 }
509
510 // now handle the functions
511 if (fu == kFUNC_WRITE) { // Write -------------------------
513 if (unit.WProt()) { // write on write locked drive ?
514 AddErrorExit(clist, kRPER1_M_WLE); // signal WLE (write lock error)
515 } else {
516 fRdma.QueueDiskWrite(addr, nwrd, Rw11Cpu::kCPAH_M_22BIT, lba, &unit);
517 }
518
519 } else if (fu == kFUNC_WCD) { // Write Check -------------------
521 fRdma.QueueDiskWriteCheck(addr, nwrd, Rw11Cpu::kCPAH_M_22BIT, lba, &unit);
522
523 } else if (fu == kFUNC_READ ) { // Read --------------------------
525 fRdma.QueueDiskRead(addr, nwrd, Rw11Cpu::kCPAH_M_22BIT, lba, &unit);
526
527 } else {
528 // FIXME: handle other special functions (currently simply error out !!)
529 AddErrorExit(clist, kRPER1_M_ILF); // signal ILF (invalid function)
530 Server().Exec(clist); // doit
531 return 0;
532 }
533
534 if (clist.Size()) { // if handled directly
535 Server().Exec(clist); // doit
536 }
537
538 return 0;
539}
540
541//------------------------------------------+-----------------------------------
543
544void Rw11CntlRHRP::RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext,
545 RlinkCommandList& clist)
546{
547 // if last chunk and not doing WCD add a labo and normal exit csr update
548 if (stat == Rw11Rdma::kStatusBusyLast && fRd_fu != kFUNC_WCD) {
549 clist.AddLabo();
550 AddNormalExit(clist, nwdone+nwnext, 0, 0);
551 }
552 return;
553}
554
555//------------------------------------------+-----------------------------------
557
558void Rw11CntlRHRP::RdmaPostExecCB(int stat, size_t ndone,
559 RlinkCommandList& clist, size_t ncmd)
560{
561 if (stat == Rw11Rdma::kStatusBusy) return;
562
563 uint16_t rper1 = 0;
564 uint16_t rpcs2 = 0;
565
566 if (fRd_fu == kFUNC_WCD) {
567 size_t nwcok = fRdma.WriteCheck(ndone);
568 if (nwcok != ndone) { // if mismatch found
569 rpcs2 |= kRPCS2_M_WCE;
570 if (ndone & 0x1) rpcs2 |= kRPCS2_M_RWCO; // failed in odd word !
571 ndone = nwcok; // truncate word count
572 }
573 }
574
575 // handle Rdma aborts
576 if (stat == Rw11Rdma::kStatusFailRdma) rpcs2 |= kRPCS2_M_NEM;
577
578 // check for fused csr updates
579 if (clist.Size() > ncmd) {
580 uint8_t ccode = clist[ncmd].Command();
581 uint16_t cdata = clist[ncmd].Data();
582 /* coverity[deadcode] */ /* unused until rper1 is really set */
583 if (ccode != RlinkCommand::kCmdLabo || (rper1 != 0 && cdata == 0))
584 throw Rexception("Rw11CntlRHRP::RdmaPostExecCB",
585 "Bad state: Labo not found or missed abort");
586 if (cdata == 0) return;
587 }
588
589 // finally to RHRP register update
590 RlinkCommandList clist1;
591 AddNormalExit(clist1, ndone, rper1, rpcs2);
592 Server().Exec(clist1);
593 return;
594}
595
596//------------------------------------------+-----------------------------------
598
600{
601 Rw11Cpu& cpu = Cpu();
602
604 cpu.AddWibr(clist, fBase+kRPER1, rper1);
605
606 // use ATA termination ! Comes late, but should be ok
608
609 if (fTraceLevel>1) {
610 RlogMsg lmsg(LogFile());
611 lmsg << "-I " << Name() << ": err "
612 << " cs1=" << RosPrintBvi(fRd_rpcs1,8)
613 << " er1=" << RosPrintBvi(rper1,8);
614 }
615
616 return;
617}
618
619//------------------------------------------+-----------------------------------
621
623 uint16_t rper1, uint16_t rpcs2)
624{
625 Rw11Cpu& cpu = Cpu();
626 uint16_t unum = fRd_rpcs2 & kRPCS2_B_UNIT;
627 Rw11UnitRHRP& unit = *fspUnit[unum];
628
629 size_t nblk = unit.Nwrd2Nblk(ndone);
630 uint32_t addr = fRd_addr + 2*ndone;
631 size_t lba = fRd_lba + nblk;
632
633 uint16_t ba = addr & 0177776; // get lower 16 bits
634 uint16_t bae = (addr>>16) & 077; // get upper 6 bits
635
636 uint16_t sa;
637 uint16_t ta;
638 uint16_t ca;
639 unit.Lba2Chs(lba, ca,ta,sa);
640 uint16_t da = (ta<<kRPDA_V_TA) | sa;
641 uint16_t wc = fRd_rpwc + uint16_t(ndone);
642
643 if (fRd_ovr) rper1 |= kRPER1_M_AOE;
644
645 cpu.AddWibr(clist, fBase+kRPWC, wc);
646 cpu.AddWibr(clist, fBase+kRPBA, ba);
647 cpu.AddWibr(clist, fBase+kRPBAE, bae);
648
650 cpu.AddWibr(clist, fBase+kRPDA, da);
651 cpu.AddWibr(clist, fBase+kRPDC, ca);
652
653 if (rper1) cpu.AddWibr(clist, fBase+kRPER1, rper1);
654 if (rpcs2) cpu.AddWibr(clist, fBase+kRPER1, rpcs2);
655
657
658 if (fTraceLevel>1) {
659 RlogMsg lmsg(LogFile());
660 if (rper1 || rpcs2) {
661 lmsg << "-I " << Name() << ": err "
662 << " er1=" << RosPrintBvi(rper1,8)
663 << " cs2=" << RosPrintBvi(rpcs2,8,8)
664 << endl;
665 }
666 lmsg << "-I " << Name() << (rper1==0 ? ": ok " : ": err ")
667 << " we=" << RosPrintBvi(wc,8) << "," << RosPrintBvi(rper1,8)
668 << " ad=" << RosPrintBvi(addr,8,22)
669 << " pa=" << unum
670 << "," << RosPrintf(ca,"d",3)
671 << "," << RosPrintf(ta,"d",2)
672 << "," << RosPrintf(sa,"d",2)
673 << " ca,da=" << RosPrintBvi(ca,8,10) << "," << RosPrintBvi(da,8);
674 }
675
676 return;
677}
678
679
680} // 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< Rw11UnitRHRP > fspUnit[NU]
static const uint16_t kRPCS1_B_BAE
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
func: read
uint16_t fRd_rpdc
Rdma: request rpdc.
static const uint16_t kRPCS1_M_TRE
static const uint16_t kRPCS1_V_RIDLY
static const uint16_t kProbeOff
probe address offset (rxcs2)
static const uint16_t kRPCS1_B_RIDLY
static const uint16_t kRPCS1_V_RUNIT
static const uint16_t kRPCS1_B_FUNC
static const uint16_t kRFUNC_WIDLY
rfunc: write idly
static const uint16_t kRPDA
RPDA reg offset.
static const uint16_t kRPDS_M_DPR
static const uint16_t kRPCS3_M_RSEEKDONE
static const uint16_t kRPDS_M_LBT
size_t fPC_rpcs3
PrimClist: rpcs3 index.
static const uint16_t kRPCS1_M_SC
uint16_t fRd_rpcs3
Rdma: request rpcs3.
static const bool kProbeRem
probr rem active
static const uint16_t kRPCS2_M_UNIT2
static const uint16_t kRPCS2_M_WCE
static const uint16_t kRPCS1_M_RATA
size_t fPC_rpba
PrimClist: rpba index.
static const uint16_t kRPDT
RPDT reg offset.
static const uint16_t kRPDS_M_ATA
static const uint16_t kRPDS_M_MOL
void RdmaPostExecCB(int stat, size_t ndone, RlinkCommandList &clist, size_t ncmd)
FIXME_docs.
static const uint16_t kRPDC
RPDC reg offset.
static const uint16_t kRPCS3_M_IE
static const uint16_t kRPBAE
RPBAE reg offset.
bool fRd_ovr
Rdma: overrun condition found.
static const uint16_t kRPCS1
RPCS1 reg offset.
static const uint16_t kRPER1_M_WLE
static const uint16_t kRPCS2_M_NEM
static const uint16_t kRPER1_M_ILF
static const uint16_t kRPER1_M_AOE
static const uint16_t kRPCS3
RPCS3 reg offset.
static const uint16_t kRPEC1
RPEC1 reg offset.
static const uint16_t kFUNC_WHD
func: write head&data
static const uint16_t kRPDC_B_CA
uint16_t fRd_rpda
Rdma: request rpda.
size_t fPC_cunit
PrimClist: copy unit.
static const uint16_t kRPDA_V_TA
static const uint16_t kFUNC_WRITE
func: write
static const int kLam
RHRP default lam.
static const uint16_t kRPCS1_M_RDY
static const uint16_t kRPCS1_V_BAE
static const uint16_t kRPDA_B_TA
virtual void Start()
FIXME_docs.
static const uint16_t kRPDS_M_DRY
static const uint16_t kRFUNC_DONE
rfunc: done (set rdy)
static const uint16_t kRPBA
RPBA reg offset.
static const uint16_t kRPCS2_B_UNIT
static const uint16_t kRPCS1_B_RUNIT
static const uint16_t kFUNC_WCHD
func: write chk head&data
static const uint16_t kRPCS2_M_PAT
static const uint16_t kRPCS2_M_OR
static const uint16_t kRFUNC_WUNIT
rfunc: write runit
~Rw11CntlRHRP()
Destructor.
static const bool kProbeInt
probe int active
static const uint16_t kRPDA_B_SA
uint16_t fRd_rpwc
Rdma: request rpwc.
static const uint16_t kRPMR1
RPMR1 reg offset.
static const uint16_t kRPCS2_M_NED
static const uint16_t kRPWC
RPWC reg offset.
static const uint16_t kRPCS3_M_RSEARDONE
static const uint16_t kRPLA
RPLA reg offset.
static const uint16_t kRPDS_M_VV
static const uint16_t kRxM14
MB reg 14 reg offset.
Rw11RdmaDisk fRdma
Rdma controller.
uint32_t fRd_nwrd
Rdma: current nwrd.
static const uint16_t kRPSN
RPSN reg offset.
void AddNormalExit(RlinkCommandList &clist, size_t ndone, uint16_t rper1=0, uint16_t rpcs2=0)
FIXME_docs.
static const uint16_t kRPCS2_M_RWCO
uint16_t fRd_fu
Rdma: request fu code.
static const uint16_t kRPER1_M_IAE
Rw11CntlRHRP()
Default constructor.
static const uint16_t kRPCS2_M_MXF
static const uint16_t kRPER1_M_RMR
uint16_t fRd_rpcs1
Rdma: request rpcs1.
static const uint16_t kRPDB
RPDB reg offset.
static const uint16_t kRPCS1_M_DVA
void Config(const std::string &name, uint16_t base, int lam)
FIXME_docs.
uint16_t fRd_rpbae
Rdma: request rpbae.
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
static const uint16_t kRPCS2_M_PGE
static const uint16_t kRPCS1_M_IE
size_t fPC_rpda
PrimClist: rpda index.
static const uint16_t kFUNC_RHD
func: read head&data
static const uint16_t kRFUNC_CUNIT
rfunc: copy funit->runit
uint16_t fRd_rpcs2
Rdma: request rpcs2.
static const uint16_t kIbaddr
RHRP default address.
static const uint16_t kRPDS_M_ERP
size_t fPC_rpcs1
PrimClist: rpcs1 index.
uint16_t fRd_rpds
Rdma: request rpds.
static const uint16_t kRPCS3_M_RPOREDONE
static const uint16_t kRxM15
MB reg 15 reg offset.
static const uint16_t kRPCS2_M_IR
static const uint16_t kRPCS1_V_FUNC
static const uint16_t kRPER1_M_UNS
static const uint16_t kRPCS1_M_GO
void AddErrorExit(RlinkCommandList &clist, uint16_t rper1)
FIXME_docs.
virtual void UnitSetup(size_t ind)
FIXME_docs.
static const uint16_t kRPCS2_M_CLR
static const uint16_t kRPDS
RPDS reg offset.
uint32_t fRd_addr
Rdma: current addr.
static const uint16_t kRPEC2
RPEC2 reg offset.
size_t fPC_rpcs2
PrimClist: rpcs2 index.
static const uint16_t kRPDS_M_OM
static const uint16_t kRPCS1_M_BAE
static const uint16_t kRPAS
RPAS reg offset.
static const uint16_t kRPCS3_M_RPACKDONE
size_t fPC_rpds
PrimClist: rpds index.
static const uint16_t kRPCS2_M_BAI
size_t fPC_rpbae
PrimClist: rpbae index.
static const uint16_t kRPOF
RPOF reg offset.
size_t fPC_rpwc
PrimClist: rpwc index.
void RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext, RlinkCommandList &clist)
FIXME_docs.
uint32_t fRd_lba
Rdma: current lba.
size_t fPC_rpdc
PrimClist: rpdc index.
static const uint16_t kFUNC_WCD
func: write chk data
static const uint16_t kRPCS2
RPCS2 reg offset.
static const uint16_t kRxM13
MB reg 13 reg offset.
static const uint16_t kRPER1
RPER1 reg offset.
static const uint16_t kRPDS_M_WRL
int AttnHandler(RlinkServer::AttnArgs &args)
FIXME_docs.
uint16_t fRd_rpba
Rdma: request rpba.
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
static const uint16_t kCPAH_M_22BIT
ena 22bit addressing
Definition: Rw11Cpu.hpp:226
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
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.
bool WProt() const
FIXME_docs.
size_t NHead() const
FIXME_docs.
const std::string & Type() 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 SetRpds(uint16_t rpds)
FIXME_docs.
uint16_t Rpds() const
FIXME_docs.
uint16_t Rpdt() 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