w11 - cpp 0.794
Backend server for Rlink and w11
Loading...
Searching...
No Matches
Rw11CntlLP11.cpp
Go to the documentation of this file.
1// $Id: Rw11CntlLP11.cpp 1185 2019-07-12 17:29:12Z 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//
5// Revision History:
6// Date Rev Version Comment
7// 2019-05-30 1155 1.3.5 size->fuse rename
8// 2019-04-27 1140 1.3.4 use RtraceTools::
9// 2019-04-19 1133 1.3.3 use ExecWibr()
10// 2019-04-14 1131 1.3.2 remove SetOnline(), use UnitSetup()
11// 2019-04-07 1127 1.3.1 add fQueBusy, queue protection; fix logic;
12// Start(): ensure unit offline; better tracing
13// 2019-03-17 1123 1.3 add lp11_buf readout
14// 2019-02-23 1114 1.2.6 use std::bind instead of lambda
15// 2018-12-15 1082 1.2.5 use lambda instead of boost::bind
16// 2018-12-09 1080 1.2.4 use HasVirt()
17// 2017-04-02 865 1.2.3 Dump(): add detail arg
18// 2017-03-03 858 1.2.2 use cntl name as message prefix
19// 2017-02-25 855 1.2.1 shorten ctor code
20// 2014-12-30 625 1.2 adopt to Rlink V4 attn logic
21// 2014-12-25 621 1.1 adopt to 4k word ibus window
22// 2013-05-04 515 1.0 Initial version
23// 2013-05-01 513 0.1 First draft
24// ---------------------------------------------------------------------------
25
30#include <functional>
31#include <algorithm>
32
33#include "librtools/RosFill.hpp"
37#include "librtools/RlogMsg.hpp"
38
39#include "RtraceTools.hpp"
40#include "Rw11CntlLP11.hpp"
41
42using namespace std;
43using namespace std::placeholders;
44
50// all method definitions in namespace Retro
51namespace Retro {
52
53//------------------------------------------+-----------------------------------
54// constants definitions
55
56const uint16_t Rw11CntlLP11::kIbaddr;
57const int Rw11CntlLP11::kLam;
58
59const uint16_t Rw11CntlLP11::kCSR;
60const uint16_t Rw11CntlLP11::kBUF;
61
62const uint16_t Rw11CntlLP11::kProbeOff;
65
66const uint16_t Rw11CntlLP11::kFifoMaxSize;
67
68const uint16_t Rw11CntlLP11::kCSR_M_ERROR;
69const uint16_t Rw11CntlLP11::kCSR_V_RLIM;
70const uint16_t Rw11CntlLP11::kCSR_B_RLIM;
71const uint16_t Rw11CntlLP11::kCSR_V_TYPE;
72const uint16_t Rw11CntlLP11::kCSR_B_TYPE;
73const uint16_t Rw11CntlLP11::kBUF_M_VAL;
74const uint16_t Rw11CntlLP11::kBUF_V_FUSE;
75const uint16_t Rw11CntlLP11::kBUF_B_FUSE;
76const uint16_t Rw11CntlLP11::kBUF_M_DATA;
77
78//------------------------------------------+-----------------------------------
80
82 : Rw11CntlBase<Rw11UnitLP11,1>("lp11"),
83 fPC_buf(0),
84 fRlim(0),
85 fItype(0),
86 fFsize(0),
87 fRblkSize(4),
88 fQueBusy(false)
89{
90 // must be here because Units have a back-ptr (not available at Rw11CntlBase)
91 fspUnit[0].reset(new Rw11UnitLP11(this, 0)); // single unit controller
92
93 fStats.Define(kStatNQue , "NQue" , "rblk queued");
94 fStats.Define(kStatNNull , "NNull" , "null char send");
95 fStats.Define(kStatNChar , "NChar" , "char send (non-null)");
96 fStats.Define(kStatNLine , "NLine" , "lines send");
97 fStats.Define(kStatNPage , "NPage" , "pages send");
98}
99
100//------------------------------------------+-----------------------------------
102
104{}
105
106//------------------------------------------+-----------------------------------
108
109void Rw11CntlLP11::Config(const std::string& name, uint16_t base, int lam)
110{
111 ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
112 return;
113}
114
115//------------------------------------------+-----------------------------------
117
119{
120 if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
121 throw Rexception("Rw11CntlLP11::Start",
122 "Bad state: started, no lam, not enable, not found");
123
124 // add device register address ibus and rbus mappings
125 // done here because now Cntl bound to Cpu and Cntl probed
126 Cpu().AllIAddrMapInsert(Name()+".csr", Base() + kCSR);
127 Cpu().AllIAddrMapInsert(Name()+".buf", Base() + kBUF);
128
129 // detect device type
131 fFsize = (1<<fItype) - 1;
132
133 // ensure unit status is initialized (online, rlim,...)
134 UnitSetupAll();
135
136 // setup primary info clist
139 if (!Buffered()) {
141 } else {
145 }
146
147 // add attn handler
149 uint16_t(1)<<fLam, this);
150
151 fStarted = true;
152 return;
153}
154
155//------------------------------------------+-----------------------------------
157
159{
160 Rw11UnitLP11& unit = *fspUnit[ind];
161 bool online = unit.HasVirt() && ! unit.Virt().Error();
162 uint16_t csr = (online ? 0 : kCSR_M_ERROR) | // err field
163 ((fRlim & kCSR_B_RLIM) << kCSR_V_RLIM); // rlim field
164 Cpu().ExecWibr(fBase+kCSR, csr);
165 return;
166}
167
168//------------------------------------------+-----------------------------------
170
171void Rw11CntlLP11::SetRlim(uint16_t rlim)
172{
173 if (rlim > kCSR_B_RLIM)
174 throw Rexception("Rw11CntlLP11::SetRlim","Bad args: rlim too large");
175
176 fRlim = rlim;
177 UnitSetup(0);
178 return;
179}
180
181//------------------------------------------+-----------------------------------
183
184void Rw11CntlLP11::Dump(std::ostream& os, int ind, const char* text,
185 int detail) const
186{
187 RosFill bl(ind);
188 os << bl << (text?text:"--") << "Rw11CntlLP11 @ " << this << endl;
189 os << bl << " fPC_buf: " << fPC_buf << endl;
190 os << bl << " fRlim: " << RosPrintf(fRlim,"d",3) << endl;
191 os << bl << " fItype: " << RosPrintf(fItype,"d",3) << endl;
192 os << bl << " fFsize: " << RosPrintf(fFsize,"d",3) << endl;
193 os << bl << " fRblkSize: " << RosPrintf(fRblkSize,"d",3) << endl;
194 os << bl << " fQueBusy: " << RosPrintf(fQueBusy) << endl;
195
196 Rw11CntlBase<Rw11UnitLP11,1>::Dump(os, ind, " ^", detail);
197 return;
198}
199
200//------------------------------------------+-----------------------------------
202
204{
207
208 if (!Buffered()) { // un-buffered iface -------------
210 } else { // buffered iface ----------------
212 }
213
214 return 0;
215}
216
217//------------------------------------------+-----------------------------------
219
221{
222 bool val = buf & kBUF_M_VAL;
223 uint8_t ochr = buf & kBUF_M_DATA;
224
225 if (val) WriteChar(ochr);
226
227 if (fTraceLevel>0) {
228 RlogMsg lmsg(LogFile());
229 lmsg << "-I " << Name() << ":"
230 << " buf=" << RosPrintBvi(buf,8)
231 << " val=" << val;
232 if (val) {
233 lmsg << " char=" << RosPrintBvi(ochr,8) << " ";
234 RtraceTools::TraceChar(lmsg, ochr);
235 }
236 }
237
238 return;
239}
240
241
242//------------------------------------------+-----------------------------------
244
245void Rw11CntlLP11::WriteChar(uint8_t ochr)
246{
247 if (ochr == 0) { // count NULL char
249 return;
250 }
251
253 RerrMsg emsg;
254 bool rc = fspUnit[0]->VirtWrite(&ochr, 1, emsg);
255 if (!rc) {
256 RlogMsg lmsg(LogFile());
257 lmsg << emsg;
258 UnitSetup(0);
259 }
260 if (ochr == '\f') { // ^L = FF = FormFeed seen ?
262 rc = fspUnit[0]->VirtFlush(emsg);
263 } else if (ochr == '\n') { // ^J = LF = LineFeed seen ?
265 }
266 return;
267}
268
269//------------------------------------------+-----------------------------------
271void Rw11CntlLP11::ProcessBuf(const RlinkCommand& cmd, bool prim)
272{
273 const uint16_t* pbuf = cmd.BlockPointer();
274 size_t done = cmd.BlockDone();
275
276 if (fQueBusy && prim) {
277 RlogMsg lmsg(LogFile());
278 lmsg << "-E " << Name()
279 << ": prim=1 call and queue busy";
280 }
281
282 uint16_t fbeg = 0;
283 uint16_t fend = 0;
284 uint16_t fdel = 0;
285 uint16_t fumin = 0;
286 uint16_t fumax = 0;
287
288 if (done > 0) {
289 fbeg = (pbuf[0] >>kBUF_V_FUSE) & kBUF_B_FUSE;
290 fend = (pbuf[done-1]>>kBUF_V_FUSE) & kBUF_B_FUSE;
291 fdel = fbeg-fend+1;
292 fumin = kFifoMaxSize;
293 }
294
295 for (size_t i=0; i < done; i++) {
296 uint8_t ochr = pbuf[i] & kBUF_M_DATA;
297 uint16_t fuse = (pbuf[i]>>kBUF_V_FUSE) & kBUF_B_FUSE;
298 fumin = min(fumin,fuse);
299 fumax = max(fumax,fuse);
300 WriteChar(ochr);
301 }
302
303 // determine next chunk size from highest fifo 'fuse' field, at least 4
304 fRblkSize = max(uint16_t(4), max(uint16_t(done),fumax));
305
306 // queue further reads when fifo not emptied
307 // check for 'fuse==1' not seen in current read
308 if (fumin > 1) { // if fumin>1 no fuse==1 seen
309 if (fQueBusy) {
310 RlogMsg lmsg(LogFile());
311 lmsg << "-E " << Name()
312 << ": queue attempt while queue busy, prim=" << prim;
313 } else {
315 fQueBusy = true;
317 }
318 }
319
320 if (fTraceLevel > 0) {
321 RlogMsg lmsg(LogFile());
322 lmsg << "-I " << Name() << ":"
323 << " pr,si,do=" << prim
324 << "," << RosPrintf(cmd.BlockSize(),"d",3)
325 << "," << RosPrintf(done,"d",3)
326 << " fifo=" << RosPrintf(fbeg,"d",3)
327 << "," << RosPrintf(fend,"d",3)
328 << ";" << RosPrintf(fdel,"d",3)
329 << "," << RosPrintf(done-fdel,"d",3)
330 << ";" << RosPrintf(fumax,"d",3)
331 << "," << RosPrintf(fumin,"d",3)
332 << " que=" << fQueBusy;
333
334 if (fTraceLevel > 1) RtraceTools::TraceBuffer(lmsg, pbuf,
335 done, fTraceLevel);
336 }
337
338
339 // re-sizing the prim rblk invalidates pbuf -> so must be done last
340 if (prim) { // if primary list
341 fPrimClist[fPC_buf].SetBlockRead(fRblkSize); // setup size for next attn
342 }
343
344 return;
345}
346
347//------------------------------------------+-----------------------------------
350{
351 fQueBusy = false;
352 RlinkCommandList clist;
353 Cpu().AddRbibr(clist, fBase+kBUF, fRblkSize);
354 clist[0].SetExpectStatus(0, RlinkCommand::kStat_M_RbTout |
356 Server().Exec(clist);
357 ProcessBuf(clist[0], false);
358 return 0;
359}
360
361} // end namespace Retro
FIXME_docs.
Definition: RerrMsg.hpp:25
FIXME_docs.
Definition: Rexception.hpp:29
size_t AddAttn()
FIXME_docs.
static const uint8_t kStat_M_RbNak
stat: rbnak flag set
static const uint8_t kStat_M_RbTout
stat: rbtout flag set
size_t BlockSize() const
FIXME_docs.
size_t BlockDone() const
FIXME_docs.
uint16_t * BlockPointer()
FIXME_docs.
void AddAttnHandler(attnhdl_t &&attnhdl, uint16_t mask, void *cdata=nullptr)
FIXME_docs.
void QueueAction(actnhdl_t &&actnhdl)
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.
std::shared_ptr< Rw11UnitLP11 > fspUnit[NU]
static const uint16_t kBUF_B_FUSE
buf.fuse bit mask
virtual void Start()
FIXME_docs.
uint16_t fItype
interface type
static const uint16_t kBUF_M_DATA
buf data mask
static const uint16_t kCSR
CSR reg offset.
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
void SetRlim(uint16_t rlim)
FIXME_docs.
static const uint16_t kBUF_M_VAL
buf.val mask
uint16_t fRlim
interrupt rate limit
static const int kLam
LP11 default lam.
virtual void UnitSetup(size_t ind)
FIXME_docs.
bool Buffered() const
FIXME_docs.
uint16_t fRblkSize
rblk chunk size
static const uint16_t kIbaddr
LP11 default address.
bool fQueBusy
rcv queue busy
int AttnHandler(RlinkServer::AttnArgs &args)
FIXME_docs.
static const uint16_t kCSR_V_RLIM
csr.rlim shift
void Config(const std::string &name, uint16_t base, int lam)
FIXME_docs.
static const bool kProbeRem
probr rem active
static const bool kProbeInt
probe int active
static const uint16_t kCSR_M_ERROR
csr.err mask
static const uint16_t kCSR_B_TYPE
csr.type bit mask
uint16_t fFsize
fifo size
void WriteChar(uint8_t ochr)
FIXME_docs.
Rw11CntlLP11()
Default constructor.
~Rw11CntlLP11()
Destructor.
static const uint16_t kFifoMaxSize
maximal fifo size
static const uint16_t kProbeOff
probe address offset (rcsr)
void ProcessBuf(const RlinkCommand &cmd, bool prim)
FIXME_docs.
static const uint16_t kBUF
BUF reg offset.
static const uint16_t kCSR_B_RLIM
csr.rlim bit mask
size_t fPC_buf
PrimClist: buf index.
static const uint16_t kCSR_V_TYPE
csr.type shift
void ProcessUnbuf(uint16_t buf)
FIXME_docs.
static const uint16_t kBUF_V_FUSE
buf.fuse shift
int RcvHandler()
FIXME_docs.
@ kStatNPage
send pages
@ kStatNNull
send null char
@ kStatNQue
queue rblk
@ kStatNLine
send lines
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
void AllIAddrMapInsert(const std::string &name, uint16_t ibaddr)
FIXME_docs.
Definition: Rw11Cpu.cpp:902
int AddRbibr(RlinkCommandList &clist, uint16_t ibaddr, size_t size)
FIXME_docs.
Definition: Rw11Cpu.cpp:375
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 AddRibr(RlinkCommandList &clist, uint16_t ibaddr)
FIXME_docs.
Definition: Rw11Cpu.cpp:354
TV & Virt()
FIXME_docs.
bool HasVirt() const
FIXME_docs.
bool Error() 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
void TraceBuffer(RlogMsg &lmsg, const uint16_t *pbuf, size_t done, uint32_t level)
FIXME_docs.
Definition: RtraceTools.cpp:34
void TraceChar(RlogMsg &lmsg, uint8_t chr)
FIXME_docs.
Declaration of class ReventLoop.
Definition: ReventLoop.cpp:47
bool Found() const
FIXME_docs.
Definition: Rw11Probe.cpp:52
uint16_t DataRem() const
FIXME_docs.
Definition: Rw11Probe.ipp:28