FirewireLowUtil.Mod 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098
  1. MODULE FirewireLowUtil; (** AUTHOR "VIP"; PURPOSE "IEEE 1394 Generic Driver Utilities"; *)
  2. IMPORT SYSTEM, KernelLog;
  3. CONST
  4. (* 1394 in ASCII *)
  5. BusIDNumber* = 31333934H;
  6. (* CSR Registers *)
  7. CSRBaseLow* = {28..31};
  8. CSRBaseHigh* = {0..15};
  9. CSRConfigRom*= {10};
  10. (* root directory entries *)
  11. ConfigRomLogicalUnitNumber*= 14H;
  12. ConfigRomVendorID*= 03H;
  13. ConfigRomModelID*= 17H;
  14. ConfigRomNodeCapabilities*= 0CH;
  15. ConfigRomUnitDirectory*= 0D1H;
  16. ConfigRomLogicalUnitDirectory*= 0D4H;
  17. ConfigRomSpecifierID*= 12H;
  18. ConfigRomUnitSWVersion*= 13H;
  19. ConfigRomDescriptorLeaf*= 81H;
  20. ConfigRomDescriptorDirectory*= 0C1H;
  21. (* offsets *)
  22. CSRTopologyMapStart* = 01000H;
  23. CSRTopologyMapEnd = 1400H;
  24. CSRSpeedMapStart = 2000H;
  25. CSRSpeedMapEnd = 3000H;
  26. (* Packet constants *)
  27. QUEUED* = 0;
  28. PENDING* = 1;
  29. COMPLETE* = 2;
  30. INCOMING* = 3;
  31. UNUSED* = 4;
  32. maxBlock = 10;
  33. REQU = 0; RESP = 1;
  34. (* Response codes *)
  35. respComplete*= 0;
  36. respConflictError=4;
  37. respDataError=5;
  38. respTypeError=6;
  39. respAddressError*=7;
  40. (* Extended transaction codes *)
  41. MaskSwap= 0001H;
  42. CompareSwap= 0002H;
  43. FetchAdd= 0003H;
  44. LittleAdd = 0004H;
  45. BoundedAdd = 0005H;
  46. WrapAdd = 0006H;
  47. (* Event and ack codes *)
  48. EvtNoStatus*= 0H; (* No event status *)
  49. EvtReserved1*= 1H;
  50. EvtLongPacket*= 2H; (* The received data length was greater than the buffer's data length *)
  51. EvtMissingAck*= 3H; (* A subaction gap was detected before an ack arrived or the received ack had a parity error *)
  52. EvtUnderrun*= 4H; (* Underrun on the corresponding FIFO. The packet was truncated *)
  53. EvtOverrun*= 5H; (* A receive FIFO overflowed during the reception of an isochronous packet *)
  54. EvtDescriptorRead*= 6H;
  55. EvtDataRead*= 7H;
  56. EvtDataWrite*= 8H;
  57. EvtBusReset*= 9H;
  58. EvtTimeout*= 0AH;
  59. EvtTcodeErr*= 0BH;
  60. EvtReserved2*= 0CH;
  61. EvtReserved3*= 0DH;
  62. EvtUnknown*= 0EH;
  63. EvtFlushed*= 0FH;
  64. EvtReserved4*= 10H;
  65. AckComplete*= 11H;
  66. AckPending*= 12H;
  67. EvtReserved5*= 13H;
  68. AckBusyX*= 14H;
  69. AckBusyA*= 15H;
  70. AckBusyB*= 16H;
  71. EvtReserved6*= 17H;
  72. EvtReserved7*= 18H;
  73. EvtReserved8*= 19H;
  74. EvtReserved9*= 1AH;
  75. AckTardy*= 1BH;
  76. EvtReserved10*= 1CH;
  77. AckDataError*= 1DH;
  78. AckTypeError*= 1EH;
  79. EvtReserved11*= 1FH;
  80. AckError*= -1;
  81. (* tcodes *)
  82. QWriteATReq* = 0H;
  83. BWriteATReq* = 1H;
  84. NoDataWATReq* = 4H;
  85. BReadATReq* = 5H;
  86. LockATReq* = 9H;
  87. StreamATReq* = 0AH;
  88. PhyATReq* = 0EH;
  89. NoDataWATRes* = 2H;
  90. QReadATRes* = 6H;
  91. BReadATRes* = 7H;
  92. LockATRes* = 0BH;
  93. QWriteARReq* = 0H;
  94. BWriteARReq* = 1H;
  95. NoDataQRARReq* = 4H;
  96. BReadARReq* = 5H;
  97. LockARReq* = 9H;
  98. PhyARReq* = 0EH;
  99. NoDataWARRes* = 2H;
  100. QReadARRes* = 6H;
  101. BReadARRes* = 7H;
  102. LockARRes* = 0BH;
  103. ITCode* = 0AH;
  104. IRCode* = 0AH;
  105. CycleStartCode* = 8H;
  106. Version*= 0H;
  107. MaxPhysRespRetries*= {10}; (* eight retries *)
  108. MaxATReqRetries*= {1}; (* two retries *)
  109. MaxATRespRetries*= {5}; (* two retries *)
  110. BufSize*= 4096;
  111. (* contest type *)
  112. ISO*= 0;
  113. REQ*= 1;
  114. RES*= 2;
  115. (* packet type *)
  116. async* = {};
  117. iso* = {0};
  118. raw* = {1};
  119. IntMask* = 088H;
  120. CIntMask*= 08CH;
  121. SelfIDCount* = 068H;
  122. SelfIDBuffer* = 064H;
  123. HCControl* = 050H;
  124. IntEvent* = 080H;
  125. CIntEvent* = 084H;
  126. PhyControl* = 0ECH;
  127. LinkControl* = 0E0H;
  128. CLinkControl* = 0E4H;
  129. softReset* = 16;
  130. NodeID* = 0E8H;
  131. BusID* = 01CH;
  132. ConfigRomMap* = 034H;
  133. ARReqComPtr* = 1CCH;
  134. ARResComPtr* = 1ECH;
  135. ATResComPtr* = 1ACH;
  136. ATReqComPtr* = 18CH;
  137. isoRecvIntMaskSet* = 0A8H;
  138. isoRecvIntMaskClear* = 0ACH;
  139. isoXmitIntMaskSet* = 098H;
  140. isoXmitIntMaskClear* = 09CH;
  141. IRComPtr* = 40CH;
  142. ITComPtr* = 20CH;
  143. BusOptions* = 020H;
  144. postedWriteEnable = 18;
  145. isochXmitCntCtrlClear* = 204H;
  146. isochXmitCntCtrlSet* = 200H;
  147. isochRecvCntCtrlSet* = 400H;
  148. isochRecvCntCtrlClear* = 404H;
  149. isochRecvContMatch* = 410H;
  150. isochRecvIntEvntClear* = 0A4H;
  151. isochRecvIntEvntSet* = 0A0H;
  152. isochRecvIntMaskClear* = 0ACH;
  153. isochRecvIntMaskSet* = 0A8H;
  154. isochXmitIntEvntSet* = 090H;
  155. isochXmitIntEvntClear* = 094H;
  156. isochXmitIntMaskSet* = 098H;
  157. isochXmitIntMaskClear* = 09CH;
  158. IRmultiChanMaskLoClear* = 07CH;
  159. IRmultiChanMaskLoSet* = 078H;
  160. IRmultiChanMaskHiClear* = 074H;
  161. IRmultiChanMaskHiSet* = 070H;
  162. ARReqContCtrlSet* = 1C0H;
  163. ARReqContCtrlClear* = 1C4H;
  164. ARResContCtrlSet* = 1E0H;
  165. ARResContCtrlClear* = 1E4H;
  166. ATReqContCtrlSet* = 180H;
  167. ATReqContCtrlClear* = 184H;
  168. ATResContCtrlSet* = 1A0H;
  169. ATResContCtrlClear* = 1A4H;
  170. ARFilterHISet* = 100H;
  171. ARFilterHIClaer* = 104H;
  172. ARFilterLowSet* = 108H;
  173. ARFilterLowClear* = 10CH;
  174. PRFilterHiSet*= 110H;
  175. PRFilterHiClear*= 114H;
  176. PRFilterLowSet*= 118H;
  177. PRFilterLowClear*= 11CH;
  178. PhyUpperBound*= 120H;
  179. ATRetries* = 008H;
  180. isochCycleTimer* = 0F0H;
  181. CSRData*= 00CH;
  182. CSRCompare*= 010H;
  183. CSRControl*= 014H;
  184. TYPE
  185. FIFONode*= POINTER TO NodeDesc;
  186. (** Data structure used only by lists *)
  187. NodeDesc*= RECORD
  188. packet: OHCIPacket;
  189. pListMember*: POINTER TO ListMember; (* used only by List *)
  190. next: FIFONode;
  191. END;
  192. (** FIFO list pointer *)
  193. FIFO = RECORD
  194. first, last: FIFONode
  195. END;
  196. (** FIFO list *)
  197. FIFOList= OBJECT
  198. PROCEDURE Enqueue*(VAR q: FIFO; n: FIFONode);
  199. BEGIN
  200. n.next:= NIL;
  201. IF q.first # NIL THEN q.last.next := n ELSE q.first := n END;
  202. q.last := n;
  203. END Enqueue;
  204. PROCEDURE DequeuedNode*(VAR q: FIFO): FIFONode;
  205. VAR n: FIFONode;
  206. BEGIN
  207. n := q.first;
  208. IF n # NIL THEN q.first := n.next END;
  209. RETURN n
  210. END DequeuedNode;
  211. END FIFOList;
  212. (** FIFO list for packets *)
  213. PacketFIFO*= OBJECT
  214. VAR q,usedQ: FIFO; list,usedList: FIFOList; bufSize: LONGINT;
  215. PROCEDURE GetPacket*():OHCIPacket;
  216. VAR n:FIFONode; packet: OHCIPacket;
  217. BEGIN {EXCLUSIVE}
  218. n:=list.DequeuedNode(q); (* Print(debug,"Dequeuning node"); *)
  219. IF n = NIL THEN KernelLog.String("Allocating new buffer!"); KernelLog.Ln();
  220. NEW(n); NEW(packet,0,bufSize); n.packet:= packet;
  221. END;
  222. usedList.Enqueue(usedQ,n);
  223. (* Print(debug,"Returning address!");
  224. KernelLog.Int(n.bufAddr,2); *)
  225. RETURN n.packet
  226. END GetPacket;
  227. PROCEDURE ReleasePacket*(packet: OHCIPacket);
  228. VAR n: FIFONode;
  229. BEGIN {EXCLUSIVE}
  230. n:= usedList.DequeuedNode(usedQ);
  231. n.packet:= packet;
  232. list.Enqueue(q,n);
  233. END ReleasePacket;
  234. PROCEDURE &Init*(numOfPacket :LONGINT);
  235. VAR n: FIFONode;i: LONGINT; packet: OHCIPacket;
  236. BEGIN {EXCLUSIVE}
  237. bufSize:= GetMaxPcktSize();
  238. NEW(list);NEW(usedList);
  239. IF numOfPacket > 0 THEN
  240. FOR i:= 0 TO numOfPacket-1 DO
  241. NEW(n);
  242. NEW(packet,0,bufSize);
  243. n.packet:= packet;
  244. list.Enqueue(q,n)
  245. END
  246. END
  247. END Init;
  248. END PacketFIFO;
  249. (** Used to hold addresses that must be checked before being accessed *)
  250. AddressChecker*= OBJECT
  251. VAR index: LONGINT; addrs: ARRAY 100 OF LONGINT;
  252. PROCEDURE Add*(adr: LONGINT);
  253. BEGIN
  254. addrs[index]:= adr;
  255. index:= index MOD 100;
  256. END Add;
  257. PROCEDURE Find*(adr: LONGINT): BOOLEAN;
  258. VAR i: LONGINT; found: BOOLEAN;
  259. BEGIN
  260. found:= FALSE;
  261. WHILE ~found & (i # 100) DO
  262. IF addrs[i] = adr THEN found:= TRUE END;
  263. INC(i);
  264. END;
  265. END Find;
  266. PROCEDURE &Init*;
  267. BEGIN
  268. index:= 0;
  269. END Init;
  270. END AddressChecker;
  271. CharBuffer*= POINTER TO ARRAY OF CHAR;
  272. (** Data structure that represents a unit directory *)
  273. UnitDirectory*= OBJECT
  274. VAR
  275. addrHigh*: SET;
  276. addrLow*: SET;
  277. vendorID*: LONGINT;
  278. vendorNameSize*: LONGINT;
  279. modelID*: LONGINT;
  280. modelNameSize*: LONGINT;
  281. specifierID*: LONGINT;
  282. version*: LONGINT;
  283. ID*: LONGINT;
  284. length: LONGINT;
  285. udEntries*: POINTER TO ARRAY OF SET;
  286. hasLogicalUnitDir*: BOOLEAN;
  287. luns*: ARRAY 10 OF UnitDirectory;
  288. PROCEDURE GetLength*():LONGINT;
  289. BEGIN
  290. RETURN length
  291. END GetLength;
  292. PROCEDURE &Init*(length: LONGINT);
  293. VAR i: LONGINT;
  294. BEGIN
  295. hasLogicalUnitDir:= FALSE;
  296. SELF.length:= length;
  297. NEW(udEntries,length);
  298. FOR i:= 0 TO 9 DO
  299. luns[i]:= NIL;
  300. END
  301. END Init;
  302. END UnitDirectory;
  303. (** Data structure for the global user id *)
  304. GUID*= RECORD
  305. low*: SET;
  306. high*: SET;
  307. END;
  308. (** Bus options *)
  309. BusOpt*= RECORD
  310. irmc*: BOOLEAN;
  311. cmc*: BOOLEAN;
  312. isc*: BOOLEAN;
  313. bmc*: BOOLEAN;
  314. pmc*: BOOLEAN;
  315. cycClkAcc*: LONGINT;
  316. maxRec*: LONGINT;
  317. generation*: LONGINT;
  318. linkSpd*: LONGINT;
  319. END;
  320. (** 1394 Node *)
  321. Node*= OBJECT
  322. VAR
  323. capabilities*: SET;
  324. phyID*: SET;
  325. linkAct: BOOLEAN;
  326. phySpeed: SET;
  327. delay: SET;
  328. contender: BOOLEAN;
  329. pwrClass: SET;
  330. portStatus: ARRAY 16 OF SET;
  331. guid*: GUID;
  332. vendorID*: LONGINT;
  333. generation*: LONGINT;
  334. probe*: BOOLEAN;
  335. busOptions*: BusOpt;
  336. uds*: ARRAY 10 OF UnitDirectory; (* should be enough *)
  337. PROCEDURE Update*(busOptions: SET; physicalID: SET; generation: LONGINT);
  338. BEGIN
  339. IF physicalID # phyID THEN
  340. KernelLog.String("The physicalID has changed "); KernelLog.Ln();
  341. phyID:= physicalID
  342. END;
  343. IF SELF.busOptions.generation # generation THEN
  344. UpdateBusOpt(busOptions);
  345. probe:= TRUE
  346. END;
  347. SELF.generation:= generation;
  348. END Update;
  349. (* Updates the bus options *)
  350. PROCEDURE UpdateBusOpt(busOpt: SET);
  351. BEGIN
  352. IF 31 IN busOpt THEN busOptions.irmc:= TRUE ELSE busOptions.irmc:= FALSE END;
  353. IF 30 IN busOpt THEN busOptions.cmc:= TRUE ELSE busOptions.cmc:= FALSE END;
  354. IF 29 IN busOpt THEN busOptions.isc:= TRUE ELSE busOptions.isc:= FALSE END;
  355. IF 28 IN busOpt THEN busOptions.bmc:= TRUE ELSE busOptions.bmc:= FALSE END;
  356. IF 27 IN busOpt THEN busOptions.pmc:= TRUE ELSE busOptions.pmc:= FALSE END;
  357. busOptions.cycClkAcc:= SYSTEM.VAL(LONGINT,LSH(busOpt,-16)*{0..7});
  358. busOptions.maxRec:= LSH(SYSTEM.VAL(LONGINT,LSH(busOpt,-12)*{0..3})+1,1);
  359. busOptions.generation:= SYSTEM.VAL(LONGINT,LSH(busOpt,-4)*{0..3});
  360. busOptions.linkSpd:= SYSTEM.VAL(LONGINT,busOpt*{0..2});
  361. END UpdateBusOpt;
  362. PROCEDURE &Init*(guid: GUID; busOptions: SET; physicalID: SET; generation: LONGINT);
  363. VAR i: LONGINT;
  364. BEGIN
  365. SELF.guid:= guid; phyID:= physicalID; SELF.generation:= generation;
  366. vendorID:= SYSTEM.VAL(LONGINT,LSH(guid.high,-8)); probe:= TRUE; UpdateBusOpt(busOptions);
  367. FOR i:= 0 TO 9 DO
  368. uds[i]:= NIL;
  369. END;
  370. END Init;
  371. END Node;
  372. (** Is used to distribute the transaction labels *)
  373. LabelPool*= OBJECT
  374. VAR freeLabel: LONGINT;
  375. freeLabelField: ARRAY 64 OF BOOLEAN;
  376. PROCEDURE GetTransLabel*():SET;
  377. VAR i: LONGINT; found: BOOLEAN;
  378. BEGIN {EXCLUSIVE}
  379. IF freeLabel = 0 THEN KernelLog.String("Awating free label!"); KernelLog.Ln();
  380. AWAIT(freeLabel > 0);
  381. END;
  382. (* search a free label *)
  383. (* KernelLog.String("Looking for a free label:: GetTransLabel "); KernelLog.Ln(); *)
  384. found:= FALSE; i:= 0;
  385. WHILE ~found DO
  386. IF freeLabelField[i] THEN found:= TRUE; DEC(freeLabel);
  387. freeLabelField[i]:= FALSE
  388. ELSE INC(i)
  389. END
  390. END;
  391. (* KernelLog.String("Returning transaction label: "); KernelLog.Int(i,2); KernelLog.Ln(); *)
  392. RETURN ConvertToSet(i);
  393. END GetTransLabel;
  394. PROCEDURE FreeTransLabel*(lab: SET);
  395. VAR label: LONGINT;
  396. BEGIN {EXCLUSIVE} label:= SYSTEM.VAL(LONGINT,lab);
  397. freeLabelField[label]:= TRUE; (* KernelLog.String("Freeing transaction label"); KernelLog.Ln(); *)
  398. INC(freeLabel)
  399. END FreeTransLabel;
  400. PROCEDURE &Init*(freeLabel: LONGINT);
  401. VAR i: LONGINT;
  402. BEGIN SELF.freeLabel:= freeLabel;
  403. FOR i:= 0 TO freeLabel-1 DO
  404. freeLabelField[i]:=TRUE;
  405. END
  406. END Init;
  407. END LabelPool;
  408. (** Data structure used in lists *)
  409. ListMember*=RECORD
  410. next*: POINTER TO ListMember;
  411. data*: OHCIPacket;
  412. END;
  413. (** Another kind of FIFO list *)
  414. List*= OBJECT
  415. VAR head*: POINTER TO ListMember; last*: POINTER TO ListMember; usedList*,list*: FIFOList;
  416. usedQ*,q*: FIFO;
  417. PROCEDURE AddPacket*(data: OHCIPacket);
  418. VAR temp: POINTER TO ListMember; n: FIFONode;
  419. BEGIN
  420. n:= list.DequeuedNode(q);
  421. IF n = NIL THEN NEW(temp); KernelLog.String("Run out of nodes in list!"); KernelLog.Ln(); ELSE temp:= n.pListMember; n.pListMember:= NIL; usedList.Enqueue(usedQ,n);
  422. END;
  423. last.next:= temp; temp.data:= data;
  424. last:= temp; last.next:= NIL;
  425. END AddPacket;
  426. PROCEDURE GetPacket*(VAR packet:OHCIPacket):BOOLEAN;
  427. VAR error: BOOLEAN;
  428. BEGIN
  429. error:= FALSE;
  430. IF (head.next # NIL) THEN
  431. packet:= head.next.data;
  432. ELSE error:= TRUE END;
  433. RETURN error
  434. END GetPacket;
  435. PROCEDURE DelPacket*(VAR packet: OHCIPacket):BOOLEAN;
  436. VAR error: BOOLEAN; n: FIFONode;
  437. BEGIN
  438. error:= FALSE;
  439. IF (head.next # NIL) THEN
  440. packet:= head.next.data;
  441. IF last = head.next THEN last:= head END;
  442. n:= usedList.DequeuedNode(usedQ);
  443. n.pListMember:= head.next;
  444. list.Enqueue(q,n);
  445. head.next:= head.next.next;
  446. ELSE error:= TRUE END;
  447. RETURN error
  448. END DelPacket;
  449. PROCEDURE &Init*(numOfPacket: LONGINT);
  450. VAR n: FIFONode; i: LONGINT;
  451. BEGIN
  452. NEW(head); head.next:= NIL; last:= head; NEW(usedList); NEW(list);
  453. IF numOfPacket > 0 THEN
  454. FOR i:= 0 TO numOfPacket-1 DO
  455. NEW(n);
  456. NEW(n.pListMember);
  457. list.Enqueue(q,n);
  458. END
  459. END
  460. END Init;
  461. END List;
  462. (** Data structure to represent self identification information of each node on the bus *)
  463. SelfID*= OBJECT (* 1394-1995 *)
  464. VAR
  465. packetIdentifier*: SET;
  466. physicalID*: SET;
  467. extended*: BOOLEAN;
  468. linkActive*: SET;
  469. gapCount*: SET;
  470. sp*: SET;
  471. del*: SET;
  472. c*: SET;
  473. pwr*: SET;
  474. p0*: SET;
  475. p1*: SET;
  476. p2*: SET;
  477. i*: SET;
  478. m*: SET;
  479. PROCEDURE &Init*(packetZero: SET);
  480. BEGIN
  481. packetIdentifier:= LSH(packetZero * {30,31},-30);
  482. physicalID:= LSH(packetZero * {24..29},-24);
  483. IF 23 IN packetZero THEN extended:= TRUE ELSE extended:= FALSE END;
  484. linkActive:= LSH(packetZero * {22},-22);
  485. gapCount:= LSH(packetZero * {16..21},-16);
  486. sp:= LSH(packetZero * {14,15},-14);
  487. del:= LSH(packetZero * {12,13},-12);
  488. c:= LSH(packetZero * {11},-11);
  489. pwr:= LSH(packetZero * {8..10},-8);
  490. p0:= LSH(packetZero * {6,7},-6);
  491. p1:= LSH(packetZero * {4,5},-4);
  492. p2:= LSH(packetZero * {2,3},-2);
  493. i:= LSH(packetZero * {1},-1);
  494. m:= packetZero * {0};
  495. END Init;
  496. END SelfID;
  497. (** Data structure used to hold extended selfidentification information *)
  498. ExtSelfID*= OBJECT(SelfID) (* 1394-1995 *)
  499. VAR
  500. seq*: SET;
  501. pa*: SET;
  502. pb*: SET;
  503. pc*: SET;
  504. pd*: SET;
  505. pe*: SET;
  506. pf*: SET;
  507. pg*: SET;
  508. ph*: SET;
  509. PROCEDURE &Init*(packetZero: SET);
  510. BEGIN
  511. packetIdentifier:= LSH(packetZero * {30,31},-30);
  512. physicalID:= LSH(packetZero * {24..29},-24);
  513. IF 23 IN packetZero THEN extended:= TRUE ELSE extended:= FALSE END;
  514. seq:= LSH(packetZero * {20..22},-20);
  515. pa:= LSH(packetZero * {16,17},-16);
  516. pb:= LSH(packetZero * {14,15},-14);
  517. pa:= LSH(packetZero * {12,13},-12);
  518. pa:= LSH(packetZero * {10,11},-10);
  519. pa:= LSH(packetZero * {8,9},-8);
  520. pa:= LSH(packetZero * {6,7},-6);
  521. pa:= LSH(packetZero * {4,5},-4);
  522. pa:= LSH(packetZero * {2,3},-2);
  523. m:= packetZero * {0};
  524. END Init;
  525. END ExtSelfID;
  526. (** Holds OHCI informatin and status *)
  527. OHCIDesc*= RECORD
  528. SelfIDErrors*: LONGINT;
  529. SelfIDBufferAdr*: SET;
  530. ptrToSelfIDBuf*: CharBuffer;
  531. ConfigRomBufferAdr*: SET;
  532. ptrToConfigRomBuf*: CharBuffer;
  533. MaxPacketSize*: LONGINT;
  534. ARDescNum*: LONGINT;
  535. ATDescNum*: LONGINT;
  536. IRDescNum*: LONGINT;
  537. ITDescNum*: LONGINT;
  538. IMDesc*: InputMoreDesc;
  539. inBusReset*: BOOLEAN;
  540. ARController*: ADMAController;
  541. ATController*: ADMAController;
  542. IRController*: IRDMAController;
  543. ITController*: ITDMAController;
  544. Nodes*: ARRAY 63 OF Node;
  545. IsRoot*: BOOLEAN;
  546. ExstRegMap*: BOOLEAN;
  547. IsIRM*: BOOLEAN;
  548. IsBM*: BOOLEAN;
  549. nodeID*: LONGINT;
  550. TopologyMap*: ARRAY 256 OF SelfID;
  551. SpeedMap*: ARRAY 64,64 OF LONGINT;
  552. numOfNodes*: LONGINT;
  553. labeler*: LabelPool;
  554. selfIDComplete*: BOOLEAN;
  555. adrCheck*: AddressChecker;
  556. packetFIFO*: PacketFIFO;
  557. tempBuffer*: POINTER TO ARRAY OF CHAR;
  558. END ;
  559. (** Represents an OHCI packet *)
  560. OHCIPacket*= OBJECT
  561. VAR
  562. host*: OHCIDesc;
  563. nodeID*: SET;
  564. type*: SET;
  565. header*: POINTER TO ARRAY OF SET; (* data from the response packet *)
  566. data*: POINTER TO ARRAY OF SET; (* holds data from the response packet if it's a read,from the request packet if it's a write/lock packet *)
  567. headerSize*: LONGINT;
  568. dataSize*: LONGINT;
  569. tCode*: SET;
  570. speed*: SET;
  571. ack*: SET;
  572. pending*: BOOLEAN;
  573. respExpected*: BOOLEAN;
  574. tLabel*: SET;
  575. generation*: LONGINT;
  576. state*: LONGINT;
  577. block*: Block; (* only needed when sending *)
  578. size*: LONGINT;
  579. name*: ARRAY 5 OF CHAR;
  580. blockBufferAddr*: ADDRESS;
  581. ptrToBlckBufAddr*: CharBuffer;
  582. PROCEDURE &Init*(hSize,dSize: LONGINT);
  583. BEGIN
  584. blockBufferAddr:= AllocATReqBuf(ptrToBlckBufAddr);
  585. headerSize:= hSize; dataSize:= dSize; size:= 0;
  586. IF headerSize = 0 THEN (* using embedded header *)
  587. headerSize:= 4*5 END;
  588. NEW(header,headerSize DIV 4); NEW(data,dataSize DIV 4);
  589. generation:= -1; state:= UNUSED;
  590. END Init;
  591. END OHCIPacket;
  592. (** Represents a descriptor block *)
  593. Block* = RECORD
  594. descNum*: LONGINT;
  595. start*: ADDRESS;
  596. end*: ADDRESS; (* Points to first quadlet of last descriptor *)
  597. END;
  598. (** Represents a context program *)
  599. Program* = OBJECT
  600. VAR blockBuffer*: BlockBuffer; bufferAddr*: ADDRESS; j,blockNum: LONGINT; hasNext,result: BOOLEAN;
  601. branchAddressPtr, branchAddress: ADDRESS; nextAddr*: ADDRESS; packetOffset*: LONGINT; curDesc*: SET;
  602. ptrToBuf*: CharBuffer; oldPtrToBlck,ptrToBlck: CharBuffer;
  603. PROCEDURE SetBranchAddress*(address,ptr: ADDRESS;newPtrToBlck: CharBuffer);
  604. BEGIN
  605. oldPtrToBlck:= ptrToBlck;
  606. ptrToBlck:= newPtrToBlck;
  607. (* set branchAddress in precedent block *)
  608. IF branchAddressPtr # 0 THEN
  609. branchAddress:= address; SYSTEM.PUT32(branchAddressPtr,branchAddress) END;
  610. (* update branchAddress pointer to this block and set Z to zero because this is the last block*)
  611. branchAddressPtr:= ptr; SYSTEM.PUT32(branchAddressPtr,{})
  612. END SetBranchAddress;
  613. (* Used to set the program buffer address *)
  614. PROCEDURE SetBufferAddr*(addr: ADDRESS);
  615. BEGIN
  616. bufferAddr:= addr;
  617. (* nextAddr and curDesc represent basically the same thing *)
  618. nextAddr:= addr; (* just to initialize *)
  619. curDesc:= SYSTEM.VAL(SET,bufferAddr); (* just to initialize *)
  620. END SetBufferAddr;
  621. PROCEDURE GetBufferAddr*():ADDRESS;
  622. BEGIN
  623. RETURN bufferAddr;
  624. END GetBufferAddr;
  625. (* Block buffer holds free blocks, if there is no block left then one has to wait *)
  626. PROCEDURE GetFreeBlocks*():LONGINT;
  627. BEGIN
  628. RETURN blockBuffer.GetFreeBlocks()
  629. END GetFreeBlocks;
  630. PROCEDURE &Init*;
  631. BEGIN
  632. NEW(blockBuffer,maxBlock); branchAddressPtr:= 0;ptrToBlck:= NIL;
  633. hasNext:= FALSE; j:= 0; blockNum:= 0; packetOffset:= 0;
  634. END Init;
  635. END Program;
  636. Packet* = ARRAY BufSize OF CHAR;
  637. (** Represents a DMA context *)
  638. Contest* = OBJECT
  639. VAR
  640. type*: LONGINT;
  641. prgr*: Program;
  642. procBuffer*: PacketBuffer; (* received packets *)
  643. cmdPtr*: LONGINT;
  644. ctrlSet*: LONGINT;
  645. ctrlClear*: LONGINT;
  646. name*: ARRAY 20 OF CHAR;
  647. listAwaiting*: List; (* packets awaiting an ack or a response after being sent from list inserted*)
  648. listPending*: List; (* packets to send *)
  649. listInserted*: List; (* sent packets coming from list pending*)
  650. tempBuffer*: ARRAY 1 OF SET;
  651. ptrToTmpBuf*: ARRAY 1 OF CharBuffer;
  652. buffers*: BufferBuffer;
  653. PROCEDURE &Init*(pcktNum,bufferNum: LONGINT);
  654. BEGIN
  655. NEW(listPending,100); NEW(listInserted,100); NEW(listAwaiting,100);
  656. NEW(procBuffer,pcktNum);
  657. NEW(prgr); NEW(buffers,bufferNum);
  658. END Init;
  659. END Contest;
  660. (** The isochronous receive context *)
  661. IRContest* =OBJECT(Contest)
  662. VAR match*: LONGINT;
  663. END IRContest;
  664. (** The isochronous transmit controller*)
  665. ITDMAController*= OBJECT
  666. VAR contests: POINTER TO ARRAY OF Contest; contest: Contest; i,j,avITCont: LONGINT; hasNext*:BOOLEAN;
  667. PROCEDURE GetNextContest*():Contest;
  668. BEGIN
  669. contest:= contests[j];
  670. INC(j);
  671. IF ~(j < avITCont) THEN hasNext:= FALSE; j:= 0 END;
  672. RETURN contest;
  673. END GetNextContest;
  674. PROCEDURE ResetIterator*;
  675. BEGIN
  676. IF avITCont > 0 THEN hasNext:= TRUE END
  677. END ResetIterator;
  678. PROCEDURE &Init*(contNum,pcktNum,bufferNum: LONGINT);
  679. BEGIN
  680. NEW(contests,contNum);
  681. FOR i:= 0 TO contNum-1 DO NEW(contest,pcktNum,contNum*bufferNum);
  682. contests[i]:= contest;
  683. END;
  684. j:= 0; avITCont:= contNum; IF avITCont > 0 THEN hasNext:= TRUE END
  685. END Init;
  686. END ITDMAController;
  687. (** The asynchronous controller *)
  688. ADMAController* = OBJECT
  689. VAR contests: POINTER TO ARRAY OF Contest; contest: Contest;
  690. PROCEDURE GetReqContest*(): Contest;
  691. BEGIN
  692. RETURN contests[REQU];
  693. END GetReqContest;
  694. PROCEDURE GetResContest*(): Contest;
  695. BEGIN
  696. RETURN contests[RESP];
  697. END GetResContest;
  698. PROCEDURE &Init*(pcktNum, bufferNum :LONGINT);
  699. BEGIN
  700. NEW(contests,2);
  701. NEW(contest,pcktNum,bufferNum);
  702. contests[REQU]:= contest;
  703. NEW(contest,pcktNum,bufferNum);
  704. contests[RESP]:= contest;
  705. END Init;
  706. END ADMAController;
  707. (** The isochronous controller *)
  708. IRDMAController*= OBJECT
  709. VAR contests: POINTER TO ARRAY OF IRContest; contest: IRContest; i,j,avIRCont*: LONGINT; hasNext*:BOOLEAN;
  710. PROCEDURE GetNextContest*():IRContest;
  711. BEGIN
  712. contest:= contests[j];
  713. INC(j);
  714. IF ~(j < avIRCont) THEN hasNext:= FALSE; j:= 0 END;
  715. RETURN contest;
  716. END GetNextContest;
  717. PROCEDURE GetContest*(n: LONGINT):IRContest;
  718. BEGIN
  719. RETURN contests[n]
  720. END GetContest;
  721. PROCEDURE ResetIterator*;
  722. BEGIN
  723. IF avIRCont > 0 THEN hasNext:= TRUE END
  724. END ResetIterator;
  725. PROCEDURE &Init*(contNum,pcktNum,bufferNum :LONGINT);
  726. BEGIN
  727. NEW(contests,contNum);
  728. FOR i:=0 TO contNum-1 DO NEW(contest,pcktNum,contNum*bufferNum);
  729. contests[i]:= contest
  730. END;
  731. j:= 0; avIRCont:= contNum; IF avIRCont > 0 THEN hasNext:= TRUE END
  732. END Init;
  733. END IRDMAController;
  734. (** This is a ring buffer for generic buffers *)
  735. BufferBuffer* = OBJECT
  736. VAR head, num: LONGINT; buffer: POINTER TO ARRAY OF SET;
  737. ptrToBuf: POINTER TO ARRAY OF CharBuffer;
  738. PROCEDURE FreeBuffer*(x: SET);
  739. BEGIN {EXCLUSIVE}
  740. AWAIT(num # LEN(buffer));
  741. buffer[(head+num) MOD LEN(buffer)] := x;
  742. INC(num)
  743. END FreeBuffer;
  744. PROCEDURE GetBuffer*(): SET;
  745. VAR x: SET;
  746. BEGIN {EXCLUSIVE}
  747. AWAIT(num # 0);
  748. x := buffer[head];
  749. head := (head+1) MOD LEN(buffer);
  750. DEC(num);
  751. RETURN x
  752. END GetBuffer;
  753. PROCEDURE &Init*(n: LONGINT);
  754. BEGIN
  755. head := 0; num := n; NEW(buffer, n); NEW(ptrToBuf, n);
  756. AllocPcktBuf(n,buffer^,ptrToBuf^);
  757. END Init;
  758. END BufferBuffer;
  759. (** This is a ring buffer for packet buffers *)
  760. PacketBuffer* = OBJECT
  761. VAR head, num: LONGINT; buffer: POINTER TO ARRAY OF Packet;
  762. PROCEDURE Append*(x: Packet);
  763. BEGIN {EXCLUSIVE}
  764. AWAIT(num # LEN(buffer));
  765. buffer[(head+num) MOD LEN(buffer)] := x;
  766. INC(num)
  767. END Append;
  768. PROCEDURE Remove*(): Packet;
  769. VAR x: Packet;
  770. BEGIN {EXCLUSIVE}
  771. AWAIT(num # 0);
  772. x := buffer[head];
  773. head := (head+1) MOD LEN(buffer);
  774. DEC(num);
  775. RETURN x
  776. END Remove;
  777. PROCEDURE GetPckt*(): Packet;
  778. VAR x: Packet;
  779. BEGIN {EXCLUSIVE}
  780. AWAIT(num # 0);
  781. x := buffer[head];
  782. RETURN x
  783. END GetPckt;
  784. PROCEDURE &Init*(n: LONGINT);
  785. BEGIN
  786. head := 0; num := 0; NEW(buffer, n)
  787. END Init;
  788. END PacketBuffer;
  789. (** This is a ring buffer for block buffers *)
  790. BlockBuffer* = OBJECT
  791. VAR head, (* free places in the fifo *) num*: LONGINT; buffer: POINTER TO ARRAY OF Block;
  792. PROCEDURE Append*(x: Block);
  793. BEGIN {EXCLUSIVE}
  794. AWAIT(num # LEN(buffer));
  795. buffer[(head+num) MOD LEN(buffer)] := x;
  796. INC(num);
  797. END Append;
  798. PROCEDURE Remove*(): Block;
  799. VAR x: Block;
  800. BEGIN {EXCLUSIVE}
  801. AWAIT(num # 0);
  802. x := buffer[head];
  803. head := (head+1) MOD LEN(buffer);
  804. DEC(num);
  805. RETURN x
  806. END Remove;
  807. PROCEDURE GetBlock*():Block;
  808. VAR x: Block;
  809. BEGIN {EXCLUSIVE}
  810. AWAIT(num # 0);
  811. x := buffer[head];
  812. RETURN x;
  813. END GetBlock;
  814. PROCEDURE GetFreeBlocks*():LONGINT;
  815. BEGIN {EXCLUSIVE}
  816. RETURN num
  817. END GetFreeBlocks;
  818. PROCEDURE &Init*(n: LONGINT);
  819. BEGIN
  820. head := 0; num := 0; NEW(buffer, n)
  821. END Init;
  822. END BlockBuffer;
  823. (** A generic descriptor *)
  824. GeneralDesc*= RECORD
  825. control*: SET;
  826. address*: SET;
  827. branchAddress*: SET;
  828. status*: SET;
  829. data*: ARRAY 4 OF SET;
  830. END;
  831. (** Data structure for an input more descriptor *)
  832. InputMoreDesc* = RECORD
  833. cmd*: SET;
  834. s*: SET;
  835. key*: SET;
  836. i*: SET;
  837. b*: SET;
  838. w*:SET;
  839. reqCount*: SET;
  840. dataAddress*: SET;
  841. branchAddress*: SET;
  842. Z*: SET;
  843. xferStatus*: SET;
  844. resCount*: SET;
  845. END;
  846. (** Data structure for an input last descriptor *)
  847. InputLastDesc* = RECORD
  848. cmd*: SET;
  849. s*: SET;
  850. key*: SET;
  851. i*: SET;
  852. b*: SET;
  853. w*:SET;
  854. reqCount*: SET;
  855. dataAddress*: SET;
  856. branchAddress*: SET;
  857. Z*: SET;
  858. xferStatus*: SET;
  859. resCount*: SET;
  860. END;
  861. (** Data structure for an output more descriptor *)
  862. OutputMore*= RECORD
  863. cmd*: SET;
  864. key*: SET;
  865. b*: SET;
  866. resCount*: SET;
  867. reqCount*: SET;
  868. dataAddress*: SET;
  869. END;
  870. (** Data structure for an output more immediate descriptor *)
  871. OutputMoreImmediate*= RECORD
  872. cmd*: SET;
  873. key*: SET;
  874. i*: SET;
  875. b*: SET;
  876. reqCount*: SET;
  877. skipAddress*: SET;
  878. Z*: SET;
  879. timeStamp*: SET;
  880. firstQuadlet*: SET;
  881. secondQuadlet*: SET;
  882. thirdQuadlet*: SET;
  883. fourthQuadlet*: SET;
  884. END;
  885. (** Data structure for an output last descriptor *)
  886. OutputLast*= RECORD
  887. cmd*: SET;
  888. s*: SET;
  889. key*: SET;
  890. p*: SET;
  891. i*: SET;
  892. b*: SET;
  893. reqCount*: SET;
  894. dataAddress*: SET;
  895. brachAddress*: SET;
  896. Z*: SET;
  897. xferStatus*: SET;
  898. timeStamp*: SET;
  899. END;
  900. (** Data structure for an output last immediate descriptor *)
  901. OutputLastImmediate*= RECORD
  902. cmd*: SET;
  903. s*: SET;
  904. key*: SET;
  905. p*: SET;
  906. i*: SET;
  907. b*: SET;
  908. reqCount*: SET;
  909. brachAddress*: SET;
  910. Z*: SET;
  911. xferStatus*: SET;
  912. timeStamp*: SET;
  913. firstQuadlet*: SET;
  914. secondQuadlet*: SET;
  915. thirdQuadlet*: SET;
  916. fourthQuadlet*: SET;
  917. END;
  918. (** Data structure for a store value descriptor *)
  919. StoreValueDesc*= RECORD
  920. cmd*: SET;
  921. key*: SET;
  922. i*: SET;
  923. storeDoublet*: SET;
  924. dataAddress*: SET;
  925. skipAddress*: SET;
  926. Z*: SET;
  927. END;
  928. (** Data structure for a dual buffer descriptor *)
  929. DualBufferDesc* = RECORD
  930. s*: SET;
  931. key*: SET;
  932. i*: SET;
  933. b*: SET;
  934. w*: SET;
  935. firstSize*: SET;
  936. firstReqCount*: SET;
  937. secondReqCount*: SET;
  938. brachAddress*: SET;
  939. Z*: SET;
  940. firstBuffer*: SET;
  941. secondBuffer*: SET;
  942. END;
  943. VAR avIRCont, avITCont: LONGINT; base: LONGINT;
  944. (** Returns the bus id *)
  945. PROCEDURE GetBusID*():SET;
  946. BEGIN
  947. RETURN LSH(ReadReg(NodeID)*{6..15},-6);
  948. END GetBusID;
  949. (** Returns the generation counter *)
  950. PROCEDURE GetGeneration*():LONGINT;
  951. VAR reg: SET;
  952. BEGIN
  953. reg:= ReadReg(SelfIDCount);
  954. reg:= LSH(reg,-16)*{0..7};
  955. RETURN SYSTEM.VAL(LONGINT,reg);
  956. END GetGeneration;
  957. (** Computes the packet length *)
  958. PROCEDURE PacketLength*(context: Contest):LONGINT;
  959. VAR bufferAddr: SET; bufSize, resCount, packetSize, packetOffset: LONGINT; nextBlock, curBlock: LONGINT;
  960. BEGIN
  961. (* KernelLog.String("Entering PacketLength"); KernelLog.Ln(); *)
  962. curBlock:= SYSTEM.VAL(LONGINT,context.prgr.curDesc);
  963. packetOffset:= context.prgr.packetOffset;
  964. bufferAddr:= SYSTEM.VAL(SET,SYSTEM.GET32(curBlock + 4));
  965. bufSize:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(curBlock))*{0..15});
  966. resCount:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(curBlock + 12))*{0..15});
  967. (* remember that packet cannot cross more than one buffer boundary *)
  968. IF resCount > 0 THEN (* Packet is not split *)
  969. (* KernelLog.String("Packet is not split::PacketLength"); KernelLog.Ln(); *)
  970. packetSize:= bufSize - packetOffset - resCount;
  971. ELSE (* packet is split or exactly filled the buffer *)
  972. (* KernelLog.String("Packet is split or exactly fills the buffer!::PacketLength"); KernelLog.Ln(); *)
  973. packetSize:= bufSize - packetOffset;
  974. nextBlock:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(curBlock+8))*{4..31});
  975. bufSize:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(nextBlock))*{0..15});
  976. resCount:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(nextBlock + 12))*{0..15});
  977. ASSERT(resCount > 0); (* This should never happen *)
  978. packetSize:= packetSize+ bufSize - resCount;
  979. END;
  980. (* KernelLog.String("Leaving PacketLength"); KernelLog.Ln(); *)
  981. ASSERT(packetSize > 0);
  982. RETURN packetSize;
  983. (* remember that we always need at least one free descriptor to handle next incoming packet *)
  984. END PacketLength;
  985. (** This function maps tCodes to packetSizes in bytes *)
  986. PROCEDURE TCodeToSize*(tCode: SET):LONGINT;
  987. VAR tCodeSize: ARRAY 16 OF LONGINT;
  988. BEGIN
  989. tCodeSize[0]:= 20;
  990. tCodeSize[1]:= 0;
  991. tCodeSize[2]:= 16;
  992. tCodeSize[3]:= -1;
  993. tCodeSize[4]:= 16;
  994. tCodeSize[5]:= 20;
  995. tCodeSize[6]:= 20;
  996. tCodeSize[7]:= 0;
  997. tCodeSize[8]:= -1;
  998. tCodeSize[9]:= 0;
  999. tCodeSize[10]:= -1;
  1000. tCodeSize[11]:= 0;
  1001. tCodeSize[12]:= -1;
  1002. tCodeSize[13]:= -1;
  1003. tCodeSize[14]:= 16;
  1004. tCodeSize[15]:= -1;
  1005. RETURN tCodeSize[SYSTEM.VAL(LONGINT,tCode)];
  1006. END TCodeToSize;
  1007. (** Writes to register *)
  1008. PROCEDURE WriteReg*(reg: LONGINT; val: SET);
  1009. BEGIN
  1010. SYSTEM.PUT32(base + reg, val);
  1011. END WriteReg;
  1012. (** Reads from a register *)
  1013. PROCEDURE ReadReg*(reg: LONGINT):SET;
  1014. BEGIN
  1015. RETURN SYSTEM.VAL(SET, SYSTEM.GET32(base + reg));
  1016. END ReadReg;
  1017. (** Starts a context *)
  1018. PROCEDURE StartContest*(contest: Contest):BOOLEAN;
  1019. CONST isValid= 31; nodeNumber= {0..5};
  1020. BEGIN
  1021. (* check if node id is valid *)
  1022. IF ~(isValid IN ReadReg(NodeID)) THEN KernelLog.String("Node id is not valid"); KernelLog.Ln();
  1023. RETURN FALSE
  1024. END;
  1025. (* check if node id is not equal 63 *)
  1026. IF ConvertToSet(63) = (ReadReg(NodeID)*nodeNumber) THEN KernelLog.String("Node id is 63");
  1027. KernelLog.Ln(); RETURN FALSE
  1028. END;
  1029. (* run the contest*)
  1030. (* KernelLog.String("Running contest "); KernelLog.String(contest.name); KernelLog.Ln(); *)
  1031. WriteReg(contest.ctrlSet,{15}); RETURN TRUE;
  1032. END StartContest;
  1033. (* isoRecvIntMask *)
  1034. (** Checks how much isochronous transmit contexts are availble *)
  1035. PROCEDURE CheckAvailableIT*;
  1036. VAR reg: SET; i,av: LONGINT;
  1037. BEGIN
  1038. reg:= {0..31};
  1039. SYSTEM.PUT32(base + isoXmitIntMaskSet,reg);
  1040. reg:= SYSTEM.VAL(SET, SYSTEM.GET32(base + isoXmitIntMaskSet));
  1041. FOR i:= 0 TO 31 DO
  1042. IF i IN reg THEN INC(av);
  1043. END
  1044. END;
  1045. (* KernelLog.String("There are ");KernelLog.Int(av,2);
  1046. KernelLog.String(" available isoXmit contexts"); KernelLog.Ln(); *)
  1047. avITCont:= av;
  1048. END CheckAvailableIT;
  1049. (** Checks how much isochronous receive contexts are availble *)
  1050. PROCEDURE CheckAvailableIR*;
  1051. VAR reg: SET; i,av: LONGINT;
  1052. BEGIN
  1053. reg:= {0..31};
  1054. SYSTEM.PUT32(base + isoRecvIntMaskSet,reg);
  1055. reg:= SYSTEM.VAL(SET, SYSTEM.GET32(base + isoRecvIntMaskSet));
  1056. FOR i:= 0 TO 31 DO
  1057. IF i IN reg THEN INC(av);
  1058. END
  1059. END;
  1060. (* KernelLog.String("There are ");KernelLog.Int(av,2);
  1061. KernelLog.String(" available isoRecv contexts"); KernelLog.Ln(); *)
  1062. avIRCont:= av;
  1063. END CheckAvailableIR;
  1064. (** Returns the availble number of isochronous receive contexts *)
  1065. PROCEDURE GetAvailableIRCont*():LONGINT;
  1066. BEGIN
  1067. RETURN avIRCont;
  1068. END GetAvailableIRCont;
  1069. (** Returns the availble number of isochronous transmit contexts *)
  1070. PROCEDURE GetAvailableITCont*():LONGINT;
  1071. BEGIN
  1072. RETURN avITCont;
  1073. END GetAvailableITCont;
  1074. (** Sets the isochronous receive context match register *)
  1075. PROCEDURE SetIsochRecvContMatch*(s: SET);
  1076. VAR reg: SET;
  1077. BEGIN
  1078. reg:= SYSTEM.VAL(SET,SYSTEM.GET32(base+isochRecvContMatch));
  1079. reg:= reg + s;
  1080. SYSTEM.PUT32(base+isochRecvContMatch,reg);
  1081. END SetIsochRecvContMatch;
  1082. (** Allocates a buffer for the asynchronous transmit context *)
  1083. PROCEDURE AllocATReqBuf*(VAR ptrToBfr: CharBuffer):ADDRESS;
  1084. VAR buffer: CharBuffer; adr: ADDRESS;
  1085. BEGIN
  1086. (* Allocating a 128 byte address + 16 byte padding *)
  1087. NEW(buffer, 144);
  1088. (* find a 16 byte aligned address *)
  1089. adr:= ADDRESSOF(buffer[0]);
  1090. DEC(adr, adr MOD 16);
  1091. INC(adr, 16);
  1092. ptrToBfr:= buffer;
  1093. RETURN adr;
  1094. END AllocATReqBuf;
  1095. (** Allocates a buffer for the asynchronous receive context *)
  1096. PROCEDURE AllocATResBuf*(VAR ptrToBfr: CharBuffer):ADDRESS;
  1097. VAR buffer: CharBuffer; adr: ADDRESS;
  1098. BEGIN
  1099. (* Allocating a 128 byte address + 16 byte padding *)
  1100. NEW(buffer, 144);
  1101. (* find a 16 byte aligned address *)
  1102. adr:= ADDRESSOF(buffer[0]);
  1103. DEC(adr, adr MOD 16);
  1104. INC(adr, 16);
  1105. ptrToBfr:= buffer;
  1106. RETURN adr;
  1107. END AllocATResBuf;
  1108. (** Allocates a buffer for the isochronous transmit context *)
  1109. PROCEDURE AllocITBuf*(VAR ptrToBfr: CharBuffer;descNum: LONGINT):ADDRESS;
  1110. VAR buffer: CharBuffer; adr: ADDRESS;
  1111. BEGIN
  1112. (* Allocating buffer for the isochronous context *)
  1113. NEW(buffer, 16*descNum+16);
  1114. (* Find a 16 byte aligned address *)
  1115. adr:= ADDRESSOF(buffer[0]);
  1116. DEC(adr, adr MOD 16);
  1117. INC(adr, 16);
  1118. ptrToBfr:= buffer;
  1119. RETURN adr;
  1120. END AllocITBuf;
  1121. (** Allocates a buffer for the isochronous receive context *)
  1122. PROCEDURE AllocIRBuf*(VAR ptrToBfr: CharBuffer;descNum: LONGINT):ADDRESS;
  1123. VAR buffer: CharBuffer; adr: ADDRESS;
  1124. BEGIN
  1125. (* Allocating buffer for the isochronous context *)
  1126. NEW(buffer, 16*descNum+16);
  1127. (* Find a 16 byte aligned address *)
  1128. adr:= ADDRESSOF(buffer[0]);
  1129. DEC(adr, adr MOD 16);
  1130. INC(adr, 16);
  1131. ptrToBfr:= buffer;
  1132. RETURN adr
  1133. END AllocIRBuf;
  1134. (** Allocates a buffer for the asynchronous receive request context *)
  1135. PROCEDURE AllocARReqBuf*(VAR ptrToBfr: CharBuffer):ADDRESS;
  1136. VAR buffer: CharBuffer; adr: ADDRESS;
  1137. BEGIN
  1138. (* Allocating a 80 byte address *)
  1139. NEW(buffer, 80);
  1140. (* find a 16 byte aligned address *)
  1141. adr:= ADDRESSOF(buffer[0]);
  1142. DEC(adr, adr MOD 16);
  1143. INC(adr, 16);
  1144. ptrToBfr:= buffer;
  1145. RETURN adr;
  1146. END AllocARReqBuf;
  1147. (** Allocates a buffer for the asynchronous receive response context *)
  1148. PROCEDURE AllocARResBuf*(VAR ptrToBfr: CharBuffer):ADDRESS;
  1149. VAR buffer: CharBuffer; adr: ADDRESS;
  1150. BEGIN
  1151. (* Allocating a 80 byte address *)
  1152. NEW(buffer, 80);
  1153. (* find a 16 byte aligned address *)
  1154. adr:= ADDRESSOF(buffer[0]);
  1155. DEC(adr, adr MOD 16);
  1156. INC(adr, 16);
  1157. ptrToBfr:= buffer;
  1158. RETURN adr;
  1159. END AllocARResBuf;
  1160. (** Sets the isochronous receive command pointer *)
  1161. PROCEDURE SetIRComPtr*(VAR ptrToBuf: CharBuffer);
  1162. VAR buffer: CharBuffer; adr: ADDRESS; s: SET; i: LONGINT;
  1163. BEGIN
  1164. FOR i:= 0 TO avIRCont-1 DO
  1165. (* Allocating a 80 byte address *)
  1166. NEW(buffer, 80);
  1167. (* find a 16 byte aligned address *)
  1168. adr:= ADDRESSOF(buffer[0]);
  1169. DEC(adr, adr MOD 16);
  1170. INC(adr, 16);
  1171. s:= SYSTEM.VAL(SET,adr);
  1172. (* Setting the address *)
  1173. SYSTEM.PUT32(base + IRComPtr + 32*i, s);
  1174. ptrToBuf:= buffer;
  1175. END
  1176. END SetIRComPtr;
  1177. (** Sets the isochronous transmit command pointer *)
  1178. PROCEDURE SetITComPtr*(VAR ptrToBuf: CharBuffer);
  1179. VAR buffer: CharBuffer; adr: ADDRESS; s: SET; i: LONGINT;
  1180. BEGIN
  1181. FOR i:= 0 TO avITCont-1 DO
  1182. (* Allocating a 80 byte address *)
  1183. NEW(buffer, 80);
  1184. (* find a 16 byte aligned address *)
  1185. adr:= ADDRESSOF(buffer[0]);
  1186. DEC(adr, adr MOD 16);
  1187. INC(adr, 16);
  1188. s:= SYSTEM.VAL(SET,adr);
  1189. (* Setting the address *)
  1190. SYSTEM.PUT32(base + ITComPtr + 16*i, s);
  1191. ptrToBuf:= buffer;
  1192. END
  1193. END SetITComPtr;
  1194. (* Int Mask *)
  1195. (** Clears the interrupt mask *)
  1196. PROCEDURE ClearIntMaskAll*;
  1197. VAR s,s2:SET; i: LONGINT;
  1198. BEGIN
  1199. (* KernelLog.String("Entering ClearIntMaskAll");
  1200. KernelLog.Ln(); *)
  1201. CheckIntMask();
  1202. s := ReadReg(IntMask);
  1203. i := 0;
  1204. WHILE i < 32 DO
  1205. s2 := {};
  1206. IF ~(i IN {10,11,12,13,14,28,30,31}) & (i IN s) THEN
  1207. INCL(s2,i);
  1208. WriteReg(CIntMask,s2);
  1209. END;
  1210. INC(i);
  1211. END;
  1212. CheckIntMask();
  1213. (* KernelLog.String("Leaving ClearIntMaskAll");
  1214. KernelLog.Ln(); *)
  1215. END ClearIntMaskAll;
  1216. (** Prints the interrupt mask register *)
  1217. PROCEDURE CheckIntMask*;
  1218. VAR reg:SET;
  1219. BEGIN
  1220. reg := ReadReg(IntMask);
  1221. (* KernelLog.String("Checking IntMask");
  1222. KernelLog.Ln;
  1223. PrintSet(reg); *)
  1224. END CheckIntMask;
  1225. (* HCControl *)
  1226. (** Sets HCControl register fields *)
  1227. PROCEDURE SetHCControl*(reg:SET);
  1228. VAR reg2: SET;
  1229. BEGIN
  1230. reg2:= ReadReg(HCControl);
  1231. reg:= reg + reg2;
  1232. SYSTEM.PUT32(base+HCControl,reg);
  1233. END SetHCControl;
  1234. (* IntEvent *)
  1235. PROCEDURE SoftInterrupt*; (* not used *)
  1236. CONST softInterrupt= 29;
  1237. VAR reg:SET;
  1238. BEGIN
  1239. INCL(reg,softInterrupt);
  1240. SYSTEM.PUT32(base + IntEvent,reg);
  1241. END SoftInterrupt;
  1242. (** Clears all occured interrupt event *)
  1243. PROCEDURE ClearIntEventAll*;
  1244. VAR s,s2:SET; i: LONGINT;
  1245. BEGIN
  1246. (* KernelLog.String("Entering ClearIntEventAll");
  1247. KernelLog.Ln(); *)
  1248. CheckIntEvent();
  1249. s := ReadReg(IntEvent);
  1250. i := 0;
  1251. WHILE i < 32 DO
  1252. s2 := {};
  1253. IF ~(i IN {10,11,12,13,14,28,30,31}) & (i IN s) THEN
  1254. INCL(s2,i);
  1255. WriteReg(CIntEvent,s2);
  1256. END;
  1257. INC(i);
  1258. END;
  1259. CheckIntEvent();
  1260. (* KernelLog.String("Leaving ClearIntEventAll");
  1261. KernelLog.Ln(); *)
  1262. END ClearIntEventAll;
  1263. (** Checks the HCControl register *)
  1264. PROCEDURE CheckHCControl;
  1265. VAR reg: SET;
  1266. BEGIN
  1267. reg:= ReadReg(HCControl);
  1268. KernelLog.String("Checking HCControl");
  1269. KernelLog.Ln;
  1270. PrintSet(reg);
  1271. END CheckHCControl;
  1272. (** Checks the int event register *)
  1273. PROCEDURE CheckIntEvent*;
  1274. VAR reg:SET;
  1275. BEGIN
  1276. reg := ReadReg(IntEvent);
  1277. (* KernelLog.String("Checking IntEvent");
  1278. KernelLog.Ln;
  1279. PrintSet(reg); *)
  1280. END CheckIntEvent;
  1281. (* Context Control *)
  1282. (** Stops a context *)
  1283. PROCEDURE StopContext*(reg: LONGINT);
  1284. CONST run= {15}; active= 10;
  1285. VAR s: SET;
  1286. BEGIN
  1287. SYSTEM.PUT32(base + reg,run);
  1288. s:= SYSTEM.VAL(SET, SYSTEM.GET32(base + reg));
  1289. WHILE active IN s DO
  1290. s:= SYSTEM.VAL(SET, SYSTEM.GET32(base + reg));
  1291. END;
  1292. (* KernelLog.String("Stopped context"); KernelLog.Ln();
  1293. PrintSet(ReadReg(reg)); *)
  1294. END StopContext;
  1295. (* PhyControl *)
  1296. (** Sets the physical control register to write data to regAddr *)
  1297. PROCEDURE SetPhyControl*(regAddr:SET; data: SET);
  1298. CONST rdReg = 15; rdData = {16..23}; IBR = 6; wrReg = 14; rdDone = 31;
  1299. VAR phyReg: SET; done: BOOLEAN; dataRead: SET; offset: LONGINT; i: LONGINT;
  1300. BEGIN
  1301. (* KernelLog.String("Setting the phy control register"); KernelLog.Ln(); *)
  1302. phyReg:= ReadReg(PhyControl);
  1303. (* Set register address *)
  1304. phyReg:= phyReg + regAddr;
  1305. (* Initiate read request *)
  1306. INCL(phyReg,rdReg);
  1307. (* Write the register back *)
  1308. SYSTEM.PUT32(base+PhyControl,phyReg);
  1309. done:= FALSE;
  1310. (* wait until register is read *)
  1311. WHILE ~done DO
  1312. (* KernelLog.String("I'm waiting");
  1313. KernelLog.Ln(); *)
  1314. phyReg := ReadReg(PhyControl);
  1315. IF rdDone IN phyReg THEN done := TRUE;
  1316. END
  1317. END;
  1318. (* masking out ridden Data *)
  1319. dataRead := phyReg*rdData;
  1320. (* eliminate offset *)
  1321. offset := 16;
  1322. i := 16;
  1323. WHILE i<24 DO
  1324. IF i IN dataRead THEN EXCL(dataRead,i);INCL(dataRead,(i-offset));
  1325. END;
  1326. INC(i)
  1327. END;
  1328. (* setting bit *)
  1329. dataRead:= dataRead + data;
  1330. (* to be sure read out one more time *)
  1331. phyReg := ReadReg(PhyControl);
  1332. (* set register address although could still be set *)
  1333. phyReg:= phyReg + regAddr;
  1334. (* write to wrData the data that has to be written *)
  1335. phyReg := phyReg+dataRead;
  1336. (*initiate write request*)
  1337. (* set "write request" bit *)
  1338. SYSTEM.PUT32(base+PhyControl,phyReg);
  1339. INCL(phyReg,wrReg);
  1340. SYSTEM.PUT32(base+PhyControl,phyReg);
  1341. done := FALSE;
  1342. (* wait until register is written *)
  1343. WHILE ~done DO
  1344. (* KernelLog.String("I'm waiting");
  1345. KernelLog.Ln(); *)
  1346. phyReg := ReadReg(PhyControl);
  1347. IF ~(wrReg IN phyReg) THEN done := TRUE;
  1348. END
  1349. END;
  1350. END SetPhyControl;
  1351. (** Converts a value to a set *)
  1352. PROCEDURE ConvertToSet*(l: ADDRESS):SET;
  1353. BEGIN
  1354. RETURN SYSTEM.VAL(SET,l)
  1355. END ConvertToSet;
  1356. (** Does the same as LSH but only for sets, better use LSH *)
  1357. PROCEDURE DelOffset*(reg:SET;offset:LONGINT):SET;
  1358. VAR i: LONGINT;
  1359. BEGIN
  1360. i := 0;
  1361. WHILE i<32 DO
  1362. IF i IN reg THEN
  1363. EXCL(reg,i); INCL(reg,(i-offset))
  1364. END;
  1365. INC(i);
  1366. END;
  1367. RETURN reg;
  1368. END DelOffset;
  1369. (** Basically does what system.move does *)
  1370. PROCEDURE AllocPacket*(dataAddr: ARRAY OF SET; dataSize: SIZE;adr: ADDRESS):SET;
  1371. VAR i,j: SIZE; address: SET;
  1372. BEGIN
  1373. (* dataSize is in bytes *)
  1374. address:= SYSTEM.VAL(SET,adr);
  1375. j:= 0; i:= 0;
  1376. WHILE i< (dataSize-1) DO
  1377. SYSTEM.PUT32(SYSTEM.VAL(LONGINT,address)+i,dataAddr[j]);
  1378. INC(i,4); INC(j);
  1379. END;
  1380. RETURN address
  1381. END AllocPacket;
  1382. (** Allocates a 4KB buffer for an OHCI packet *)
  1383. PROCEDURE AllocPcktBuf*(num: LONGINT; VAR bufs: ARRAY OF SET;VAR ptrBufs: ARRAY OF CharBuffer);
  1384. VAR i: LONGINT; buffer: CharBuffer; adr: ADDRESS; s: SET;
  1385. BEGIN
  1386. FOR i:= 0 TO num-1 DO
  1387. (* Allocating a 4096 byte buffer + 4 byte for the alignement *)
  1388. NEW(buffer, BufSize + 4);
  1389. adr:= ADDRESSOF(buffer[0]);
  1390. (* Find a 4 byte aligned address *)
  1391. DEC(adr, adr MOD 4);
  1392. INC(adr, 4);
  1393. s:= SYSTEM.VAL(SET,adr);
  1394. bufs[i]:= s;
  1395. ptrBufs[i]:= buffer;
  1396. END
  1397. END AllocPcktBuf;
  1398. (** Returns the maximally allowed size for an asynchronous OHCI packet *)
  1399. PROCEDURE GetMaxPcktSize*():LONGINT;
  1400. CONST mask = {12..15};
  1401. VAR reg:SET; val,i: LONGINT; size: LONGINT;
  1402. BEGIN
  1403. size:= 1;
  1404. reg:= SYSTEM.VAL(SET,SYSTEM.GET32(base + BusOptions));
  1405. reg:= reg*mask;
  1406. reg:= DelOffset(reg,12);
  1407. (* convert to integer *)
  1408. val:= SYSTEM.VAL(LONGINT,reg);
  1409. (* increment by one, because smallest value should be two *)
  1410. INC(val);
  1411. FOR i:= 0 TO val-1 DO size:= size*2 END;
  1412. (* add 20 bytes for header and trailer *)
  1413. size:= size + 20;
  1414. RETURN size;
  1415. END GetMaxPcktSize;
  1416. (** Checks the self identification counter *)
  1417. PROCEDURE CheckSelfIDCount*;
  1418. CONST selfIDError= 31;
  1419. VAR reg:SET;
  1420. BEGIN
  1421. reg:= SYSTEM.VAL(SET,SYSTEM.GET32(base + SelfIDCount));
  1422. IF selfIDError IN reg THEN (* KernelLog.String("There was an error during the self ID process"); KernelLog.Ln() *) END;
  1423. (* KernelLog.String("Printing the contents of the Self Id Count register:" ); KernelLog.Ln(); PrintSet(reg); KernelLog.Ln(); *)
  1424. END CheckSelfIDCount;
  1425. (** Checks the status of the OHCI *)
  1426. PROCEDURE CheckStatus*;
  1427. BEGIN
  1428. CheckSelfIDCount();
  1429. CheckIntEvent();
  1430. CheckLinkControl();
  1431. CheckHCControl();
  1432. CheckBusID();
  1433. PrintNodeInfo();
  1434. CheckBusManagerID();
  1435. END CheckStatus;
  1436. (** Checks the bus manager id *)
  1437. PROCEDURE CheckBusManagerID;
  1438. CONST csrDone= 31;
  1439. VAR reg: SET; done: BOOLEAN;
  1440. BEGIN
  1441. (* First check who is Bus Manager *)
  1442. WriteReg(CSRData,{0..5});
  1443. WriteReg(CSRCompare,{0..5});
  1444. WriteReg(CSRControl,{});
  1445. (* Wait until compare swap operation has been done *)
  1446. reg:= ReadReg(CSRControl);
  1447. done:= FALSE;
  1448. WHILE ~done DO
  1449. IF csrDone IN reg THEN done:= TRUE ELSE
  1450. reg:= ReadReg(CSRControl)
  1451. END
  1452. END;
  1453. (* Read the bus manager ID *)
  1454. reg:= ReadReg(CSRData);
  1455. (* Print it out *)
  1456. KernelLog.String("Printing the bus manager id");
  1457. PrintSet(reg);
  1458. (* Print the node id to compare it *)
  1459. KernelLog.String("Printing the node id");
  1460. reg:= ReadReg(NodeID);
  1461. reg:= reg*{0..5};
  1462. PrintSet(reg);
  1463. END CheckBusManagerID;
  1464. (** Checks the bus id *)
  1465. PROCEDURE CheckBusID;
  1466. VAR reg:SET;
  1467. BEGIN
  1468. KernelLog.String("Checking the BusID"); KernelLog.Ln();
  1469. reg:= SYSTEM.VAL(SET, SYSTEM.GET32(base + BusID));
  1470. PrintSet(reg);
  1471. END CheckBusID;
  1472. (** Checks the LinkControl register content *)
  1473. PROCEDURE CheckLinkControl*;
  1474. VAR reg:SET;
  1475. BEGIN
  1476. reg := ReadReg(LinkControl);
  1477. KernelLog.String("Checking LinkControl");
  1478. KernelLog.Ln;
  1479. PrintSet(reg);
  1480. END CheckLinkControl;
  1481. (** Used to force a softreset *)
  1482. PROCEDURE SoftReset*; (* not used *)
  1483. BEGIN
  1484. SetHCControl({softReset});
  1485. WHILE softReset IN (ReadReg(HCControl)) DO END
  1486. END SoftReset;
  1487. (** Sets the base address of the OHCI register set *)
  1488. PROCEDURE SetBase*(b: LONGINT);
  1489. BEGIN
  1490. base := b;
  1491. (* KernelLog.String("base is: ");
  1492. KernelLog.Int(base,2);
  1493. KernelLog.Ln(); *)
  1494. END SetBase;
  1495. (** Returns an asynchronous output more immediate descriptor *)
  1496. PROCEDURE GetAOMIDesc*():OutputMoreImmediate;
  1497. CONST keyOMI= {25};
  1498. VAR descOMI: OutputMoreImmediate;
  1499. BEGIN
  1500. descOMI.key:= keyOMI;
  1501. RETURN descOMI
  1502. END GetAOMIDesc;
  1503. (** Returns an asynchronous output last descriptor *)
  1504. PROCEDURE GetAOLDesc*():OutputLast;
  1505. CONST cmdOL= {28}; bOL= {18,19}; iOL= {20,21};
  1506. VAR descOL: OutputLast;
  1507. BEGIN
  1508. descOL.cmd:= cmdOL; descOL.b:= bOL; descOL.i:= iOL;
  1509. RETURN descOL
  1510. END GetAOLDesc;
  1511. (** Returns an asynchronous last immediate descriptor *)
  1512. PROCEDURE GetAOLIDesc*(): OutputLastImmediate;
  1513. CONST cmdOLI= {28}; keyOLI= {25}; bOLI= {18,19}; iOLI= {20,21};
  1514. VAR descOLI: OutputLastImmediate;
  1515. BEGIN
  1516. descOLI.cmd:= cmdOLI; descOLI.key:= keyOLI; descOLI.b:= bOLI; descOLI.i:= iOLI;
  1517. RETURN descOLI
  1518. END GetAOLIDesc;
  1519. (** Returns an isochronous input last descriptor *)
  1520. PROCEDURE GetIILDesc*(): InputLastDesc;
  1521. CONST cmdIL = {28,29};
  1522. VAR descIL: InputLastDesc;
  1523. BEGIN
  1524. descIL.cmd:= cmdIL;
  1525. RETURN descIL
  1526. END GetIILDesc;
  1527. (** Returns an isochronous input more descriptor *)
  1528. PROCEDURE GetIIMDesc*():InputMoreDesc;
  1529. CONST cmdIM= {29};
  1530. VAR descIM: InputMoreDesc;
  1531. BEGIN
  1532. descIM.cmd:= cmdIM;
  1533. RETURN descIM
  1534. END GetIIMDesc;
  1535. (** Returns an isochronous dual buffer descriptor *)
  1536. PROCEDURE GetIDBDesc*(): DualBufferDesc;
  1537. CONST s = {27}; b = {19,18};
  1538. VAR descDB: DualBufferDesc;
  1539. BEGIN
  1540. descDB.s := s; descDB.b := b;
  1541. RETURN descDB
  1542. END GetIDBDesc;
  1543. (** Returns an isochronous output more immediate descriptor *)
  1544. PROCEDURE GetIOMIDesc*(): OutputMoreImmediate;
  1545. CONST keyOMI = {25}; reqCountOMI = {4};
  1546. VAR descOMI: OutputMoreImmediate;
  1547. BEGIN
  1548. descOMI.key:= keyOMI; descOMI.reqCount:= reqCountOMI;
  1549. RETURN descOMI
  1550. END GetIOMIDesc;
  1551. (** Returns an isochronous output last descriptor *)
  1552. PROCEDURE GetIOLDesc*(): OutputLast;
  1553. CONST cmdOL = {28}; bOL = {19,18};
  1554. VAR descOL: OutputLast;
  1555. BEGIN
  1556. descOL.cmd:= cmdOL; descOL.b:= bOL;
  1557. RETURN descOL
  1558. END GetIOLDesc;
  1559. (** Returns an isochronous output last immediate descriptor *)
  1560. PROCEDURE GetIOLIDesc*(): OutputLastImmediate;
  1561. CONST cmdOLI = {28}; keyOLI = {25}; bOLI= {19,18}; reqCountOLI= {4};
  1562. VAR descOLI: OutputLastImmediate;
  1563. BEGIN
  1564. descOLI.cmd:= cmdOLI; descOLI.key:= keyOLI; descOLI.b:= bOLI; descOLI.reqCount:= reqCountOLI;
  1565. RETURN descOLI
  1566. END GetIOLIDesc;
  1567. (** Returns an isochronous store value descriptor *)
  1568. PROCEDURE GetISVDesc*(): StoreValueDesc;
  1569. CONST cmdSV= {31}; keySV= {26,25};
  1570. VAR descSV: StoreValueDesc;
  1571. BEGIN
  1572. descSV.cmd:= cmdSV; descSV.key:= keySV;
  1573. RETURN descSV
  1574. END GetISVDesc;
  1575. (** Prints the status information of the ohci *)
  1576. PROCEDURE PrintNodeInfo*;
  1577. CONST iDValid = 31; root = 30; CPS = 27;
  1578. VAR reg: SET;
  1579. BEGIN
  1580. reg:= SYSTEM.VAL(SET, SYSTEM.GET32(base + NodeID));
  1581. KernelLog.String("Printing node information:"); KernelLog.Ln();
  1582. IF iDValid IN reg THEN
  1583. KernelLog.String("Node has a valid node number."); KernelLog.Ln();
  1584. ELSE KernelLog.String("Node has no valid node number."); KernelLog.Ln() END;
  1585. PrintSet(reg);
  1586. reg:= SYSTEM.VAL(SET, SYSTEM.GET32(base + NodeID));
  1587. IF root IN reg THEN
  1588. KernelLog.String("Node is root."); KernelLog.Ln();
  1589. ELSE KernelLog.String("Node is not root."); KernelLog.Ln() END;
  1590. PrintSet(reg);
  1591. IF CPS IN reg THEN
  1592. KernelLog.String("Cable power status is ok.");KernelLog.Ln();
  1593. ELSE KernelLog.String("Cable power status is not ok.");KernelLog.Ln() END;
  1594. CheckIntEvent();
  1595. END PrintNodeInfo;
  1596. (** Is used to print out a set *)
  1597. PROCEDURE PrintSet*(set:SET);
  1598. VAR x:LONGINT;
  1599. BEGIN
  1600. x := 0;
  1601. WHILE x < 32 DO
  1602. IF x IN set THEN KernelLog.Int(x,2); KernelLog.String(", "); END;
  1603. INC(x);
  1604. END;
  1605. KernelLog.Ln();
  1606. END PrintSet;
  1607. (** Builds the header of a response packet *)
  1608. PROCEDURE BuildHeaderResp*(tc: LONGINT; VAR packet: OHCIPacket; rCode: LONGINT);
  1609. VAR busNumber: SET;
  1610. BEGIN
  1611. busNumber:= LSH(ReadReg(NodeID)*{6..15},16);
  1612. packet.tCode:= ConvertToSet(tc);
  1613. packet.header[0]:= LSH(packet.nodeID,16) + busNumber + LSH(packet.tLabel,10) + LSH({0},8) +
  1614. ConvertToSet(LSH(tc,4));
  1615. packet.header[1]:= ConvertToSet(LSH(packet.host.nodeID,16)) + SYSTEM.VAL(SET,LSH(rCode,12));
  1616. packet.header[2]:= {};
  1617. END BuildHeaderResp;
  1618. (** Fill an asynchronous write response packet *)
  1619. PROCEDURE FillAsyncWriteResp*(VAR packet: OHCIPacket; rCode: LONGINT);
  1620. BEGIN
  1621. BuildHeaderResp(NoDataWARRes,packet,rCode);
  1622. packet.header[2]:= {};
  1623. packet.headerSize:= 12;
  1624. packet.dataSize:= 0;
  1625. packet.respExpected:= FALSE;
  1626. END FillAsyncWriteResp;
  1627. (** Fills an asynchronous read quadlet response packet *)
  1628. PROCEDURE FillAsyncReadQuadResp*(VAR packet: OHCIPacket; rCode,bufferAddr: LONGINT);
  1629. BEGIN
  1630. BuildHeaderResp(QReadARRes,packet,rCode);
  1631. packet.header[3]:= SYSTEM.VAL(SET,SYSTEM.GET32(bufferAddr));
  1632. packet.headerSize:= 16;
  1633. packet.dataSize:= 0;
  1634. packet.respExpected:= FALSE;
  1635. END FillAsyncReadQuadResp;
  1636. (** Fills an asynchronous read block response packet *)
  1637. PROCEDURE FillAsyncReadBlockResp*(VAR packet: OHCIPacket; rCode,length: LONGINT);
  1638. VAR padding: LONGINT;
  1639. BEGIN
  1640. IF rCode # respComplete THEN length:= 0 END;
  1641. BuildHeaderResp(BReadARRes,packet,rCode);
  1642. packet.header[3]:= SYSTEM.VAL(SET,LSH(length,16));
  1643. packet.headerSize:= 16;
  1644. IF (length MOD 4 > 0) THEN padding:= 4 - (length MOD 4) ELSE padding:= 0 END;
  1645. packet.dataSize:= length + padding;
  1646. packet.respExpected:= FALSE;
  1647. END FillAsyncReadBlockResp;
  1648. (** Builds the header of a packet *)
  1649. PROCEDURE BuildHeader(tc: LONGINT; VAR packet: OHCIPacket; addrLow,addrHigh: SET);
  1650. VAR busNumber: SET;
  1651. BEGIN
  1652. busNumber:= LSH(ReadReg(NodeID)*{6..15},16);
  1653. packet.tCode:= ConvertToSet(tc);
  1654. (* KernelLog.String("Setting header[0]"); KernelLog.Ln(); *)
  1655. packet.header[0]:= LSH(packet.nodeID,16) + busNumber + LSH(packet.tLabel,10) + LSH({0},8) +
  1656. ConvertToSet(LSH(tc,4));
  1657. (* KernelLog.String("Setting header[1]"); KernelLog.Ln(); *)
  1658. packet.header[1]:= ConvertToSet(LSH(packet.host.nodeID,16)) + addrHigh + busNumber;
  1659. (* KernelLog.String("Printing the nodeID: "); PrintSet(packet.nodeID); KernelLog.Ln();
  1660. KernelLog.String("Printing the address: "); PrintSet(addrLow); PrintSet(addrHigh); KernelLog.Ln(); *)
  1661. (* KernelLog.String("Setting header[2]"); KernelLog.Ln(); *)
  1662. packet.header[2]:= addrLow
  1663. END BuildHeader;
  1664. (* Procedure needed to build packets from here on *)
  1665. (** Fills a lock packet *)
  1666. PROCEDURE FillLockPacket(packet: OHCIPacket; addrLow,addrHigh: SET; extCode: LONGINT; length: LONGINT);
  1667. BEGIN
  1668. (* KernelLog.String("Building header::FillLockPacket!"); KernelLog.Ln(); *)
  1669. BuildHeader(LockATReq, packet, addrLow, addrHigh);
  1670. packet.header[3]:= SYSTEM.VAL(SET,LSH(length,16)) + SYSTEM.VAL(SET,extCode);
  1671. packet.headerSize:= 16;
  1672. packet.dataSize:= length;
  1673. packet.respExpected:= TRUE;
  1674. END FillLockPacket;
  1675. (** Fills an asynchronous write quadlet packet *)
  1676. PROCEDURE FillAsyncWriteQuadlet*(packet: OHCIPacket; addrLow, addrHigh, data: SET);
  1677. BEGIN
  1678. (* KernelLog.String("Building header::FillAsyncWriteQuadlet!"); KernelLog.Ln(); *)
  1679. BuildHeader(QWriteATReq, packet, addrLow, addrHigh);
  1680. packet.header[3]:= data;
  1681. packet.headerSize:= 16;
  1682. packet.dataSize:= 0;
  1683. packet.respExpected:= TRUE;
  1684. END FillAsyncWriteQuadlet;
  1685. (** Fills an asynchronous write block packet *)
  1686. PROCEDURE FillAsyncWriteBlock*(packet: OHCIPacket; addrLow, addrHigh: SET; length: LONGINT);
  1687. VAR padding: LONGINT;
  1688. BEGIN
  1689. (* KernelLog.String("Building header::FillAsyncWriteBlock!"); KernelLog.Ln(); *)
  1690. BuildHeader(BWriteATReq, packet,addrLow, addrHigh);
  1691. packet.header[3]:= SYSTEM.VAL(SET,LSH(length,16));
  1692. packet.headerSize:= 16;
  1693. packet.respExpected:= TRUE;
  1694. IF (length MOD 4 > 0) THEN padding:= 4 - (length MOD 4) ELSE padding:= 0 END;
  1695. packet.dataSize:= length + padding;
  1696. END FillAsyncWriteBlock;
  1697. (** Fills an asynchronous read quadlet packet *)
  1698. PROCEDURE FillAsyncReadQuadlet*(VAR packet: OHCIPacket; addrLow,addrHigh: SET);
  1699. BEGIN
  1700. (* KernelLog.String("Building header::FillAsyncReadQuadlet!"); KernelLog.Ln(); *)
  1701. BuildHeader(NoDataWATReq,packet,addrLow,addrHigh);
  1702. (* PrintSet(packet.header[0]);
  1703. PrintSet(packet.header[1]);
  1704. PrintSet(packet.header[2]); *)
  1705. packet.headerSize:= 12;
  1706. packet.dataSize:= 0;
  1707. packet.respExpected:= TRUE;
  1708. END FillAsyncReadQuadlet;
  1709. (** Fills an asynchronous read block packet *)
  1710. PROCEDURE FillAsyncReadBlock*(VAR packet: OHCIPacket; addrLow,addrHigh: SET; length: LONGINT);
  1711. BEGIN
  1712. BuildHeader(BReadATReq,packet,addrLow,addrHigh);
  1713. packet.header[3]:= ConvertToSet(LSH(length,16));
  1714. packet.headerSize:= 16;
  1715. packet.dataSize:= 0;
  1716. packet.respExpected:= TRUE;
  1717. END FillAsyncReadBlock;
  1718. (** Test if a packet and eventually its response were successfully sent and received *)
  1719. PROCEDURE TestIfSuccess*(packet:OHCIPacket):BOOLEAN;
  1720. VAR tCode: LONGINT;
  1721. BEGIN
  1722. tCode:= SYSTEM.VAL(LONGINT,packet.tCode);
  1723. CASE SYSTEM.VAL(LONGINT,packet.ack) OF
  1724. AckPending:
  1725. (* KernelLog.String("The packet received an ackPending::testIFSuccess"); KernelLog.Ln(); *)
  1726. CASE SYSTEM.VAL(LONGINT,LSH(packet.header[1],-12) * {0..3}) OF
  1727. respComplete: RETURN TRUE;
  1728. |respConflictError: KernelLog.String("The packet had a conflict error!"); KernelLog.Ln();
  1729. RETURN FALSE;
  1730. |respDataError: KernelLog.String("The packet had a data error!"); KernelLog.Ln();
  1731. RETURN FALSE;
  1732. |respTypeError: KernelLog.String("The packet had a type error!"); KernelLog.Ln();
  1733. RETURN FALSE;
  1734. |respAddressError: KernelLog.String("The packet had an address error!"); KernelLog.Ln();
  1735. RETURN FALSE;
  1736. ELSE KernelLog.String("Received reserved code!"); KernelLog.Ln();
  1737. (* dump packet data *)
  1738. PrintSet(packet.header[0]);
  1739. PrintSet(packet.header[1]);
  1740. PrintSet(packet.header[2]);
  1741. RETURN FALSE
  1742. END;
  1743. |AckBusyX: RETURN FALSE; KernelLog.String("AckBusyX"); KernelLog.Ln();
  1744. |AckBusyA: RETURN FALSE; KernelLog.String("AckBusyA"); KernelLog.Ln();
  1745. |AckBusyB: RETURN FALSE; KernelLog.String("AckBusyB"); KernelLog.Ln();
  1746. |AckTypeError: RETURN FALSE;
  1747. |AckComplete:
  1748. (* KernelLog.String("The packet received an ackComplete::testIFSuccess"); KernelLog.Ln(); *)
  1749. IF (tCode = QWriteATReq) OR (tCode = BWriteATReq) THEN
  1750. RETURN TRUE
  1751. ELSE
  1752. KernelLog.String("Impossible ack complete!"); KernelLog.Ln(); RETURN FALSE
  1753. END;
  1754. |AckDataError:
  1755. KernelLog.String("AckDataError"); KernelLog.Ln();
  1756. IF (tCode = BWriteATReq) OR (tCode = LockATReq) THEN
  1757. RETURN FALSE
  1758. ELSE
  1759. KernelLog.String("Impossible ack data error!"); KernelLog.Ln(); RETURN FALSE
  1760. END;
  1761. |AckError: KernelLog.String("AckError"); KernelLog.Ln(); RETURN FALSE;
  1762. ELSE KernelLog.String("An invalid ack was received!"); KernelLog.Ln(); RETURN FALSE
  1763. END
  1764. END TestIfSuccess;
  1765. (** Instantiates a lock packet *)
  1766. PROCEDURE MakeLockPacket*(ohci: OHCIDesc; nodeID: SET; addrLow, addrHigh:SET; extcode: LONGINT;
  1767. data,arg: SET):OHCIPacket;
  1768. VAR p: OHCIPacket; length: LONGINT;
  1769. BEGIN
  1770. p:= ohci.packetFIFO.GetPacket();
  1771. p.dataSize:= 8;
  1772. (* reset packet *)
  1773. ResetPacket(p);
  1774. p.host:= ohci;
  1775. p.nodeID:= nodeID;
  1776. p.tLabel:= ohci.labeler.GetTransLabel();
  1777. CASE extcode OF
  1778. FetchAdd: length:= 4;
  1779. IF data # {} THEN p.data[0]:= data; (* KernelLog.String("Data is not an empty set"); KernelLog.Ln() *) END;
  1780. |LittleAdd: length:= 4;
  1781. IF data #{} THEN p.data[0]:= data; (* KernelLog.String("Data is not an empty set"); KernelLog.Ln() *) END;
  1782. ELSE length:= 8;
  1783. IF data # {} THEN p.data[0]:= arg; p.data[1]:= data; (* KernelLog.String("Data is not an empty set"); KernelLog.Ln() *) END
  1784. END;
  1785. (* KernelLog.String("The length is::MakeLockpacket:: "); KernelLog.Int(length,2); KernelLog.Ln(); *)
  1786. FillLockPacket(p, addrLow, addrHigh, extcode, length);
  1787. (* Dump data
  1788. KernelLog.String("Dumping the data::MakeLockPacket"); KernelLog.Ln();
  1789. FOR i:= 0 TO (p.dataSize DIV 4)-1 DO
  1790. PrintSet(p.data[i])
  1791. END; *)
  1792. RETURN p;
  1793. END MakeLockPacket;
  1794. (** Instantiates a write packet *)
  1795. PROCEDURE MakeWritePacket*(ohci:OHCIDesc; nodeID, addrLow, addrHigh, buffer: SET; length: LONGINT ): OHCIPacket;
  1796. VAR packet: OHCIPacket; i,padding: LONGINT;
  1797. BEGIN
  1798. IF length = 0 THEN RETURN NIL END;
  1799. IF (length MOD 4 > 0) THEN padding:= 4 - (length MOD 4) END;
  1800. (* KernelLog.String("Allocating a new packet!"); KernelLog.Ln(); *)
  1801. packet:= ohci.packetFIFO.GetPacket();
  1802. packet.dataSize:= length + padding;
  1803. (* reset packet *)
  1804. ResetPacket(packet);
  1805. packet.host:= ohci;
  1806. packet.nodeID:= nodeID;
  1807. (* KernelLog.String("Getting transaction label"); KernelLog.Ln(); *)
  1808. packet.tLabel:= ohci.labeler.GetTransLabel(); (* Hier wird gewartet wenn nichts frei ist *)
  1809. (* KernelLog.String("Filling the packets!"); KernelLog.Ln(); *)
  1810. IF length = 4 THEN
  1811. (* KernelLog.String("Filling asynchronous write quadlet packet!"); KernelLog.Ln(); *)
  1812. FillAsyncWriteQuadlet(packet,addrLow,addrHigh,buffer)
  1813. ELSE
  1814. (* KernelLog.String("Filling asynchronous write+ block packet!"); KernelLog.Ln(); *)
  1815. FillAsyncWriteBlock(packet,addrLow,addrHigh,length);
  1816. IF buffer # {} THEN (* SYSTEM.MOVE(SYSTEM.VAL(LONGINT,buffer),ADDRESSOF(packet.data),length) *)
  1817. WHILE i # (length DIV 4) DO
  1818. packet.data[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,buffer)+i*4));
  1819. INC(i);
  1820. END
  1821. END;
  1822. (* KernelLog.String("Dumping the packet!"); KernelLog.Ln();
  1823. i:= 0;
  1824. WHILE i # (length DIV 4) DO
  1825. PrintSet(packet.data[i]); INC(i);
  1826. END *)
  1827. END;
  1828. RETURN packet
  1829. END MakeWritePacket;
  1830. (** Instantiates a read packet *)
  1831. PROCEDURE MakeReadPacket*(ohci: OHCIDesc; nodeID: SET; addrLow,addrHigh: SET; length: LONGINT): OHCIPacket;
  1832. VAR packet: OHCIPacket; padding: LONGINT;
  1833. BEGIN
  1834. IF length = 0 THEN RETURN NIL END;
  1835. IF (length MOD 4 > 0) THEN padding:= 4 - (length MOD 4) END;
  1836. (* KernelLog.String("Allocating a new packet!"); KernelLog.Ln(); *)
  1837. packet:= ohci.packetFIFO.GetPacket();
  1838. packet.dataSize:= length + padding;
  1839. (* reset packet *)
  1840. ResetPacket(packet);
  1841. packet.host:= ohci;
  1842. packet.nodeID:= nodeID;
  1843. (* KernelLog.String("Getting transaction label"); KernelLog.Ln(); *)
  1844. packet.tLabel:= ohci.labeler.GetTransLabel(); (* Hier wird gewartet wenn nichts frei ist *)
  1845. (* KernelLog.String("Filling the packets!"); KernelLog.Ln(); *)
  1846. IF length = 4 THEN
  1847. (* KernelLog.String("Filling asynchronous read quadlet packet!"); KernelLog.Ln(); *)
  1848. FillAsyncReadQuadlet(packet,addrLow,addrHigh)
  1849. ELSE
  1850. (* KernelLog.String("Filling asynchronous read block packet!"); KernelLog.Ln(); *)
  1851. FillAsyncReadBlock(packet,addrLow,addrHigh,length)
  1852. END;
  1853. RETURN packet
  1854. END MakeReadPacket;
  1855. (** Resets all packet fields *)
  1856. PROCEDURE ResetPacket*(VAR packet: OHCIPacket);
  1857. VAR block: Block; ohci: OHCIDesc;
  1858. BEGIN
  1859. packet.host:= ohci;
  1860. packet.nodeID:= {};
  1861. packet.type:= {};
  1862. packet.tCode:= {};
  1863. packet.speed:= {};
  1864. packet.ack:= {};
  1865. packet.pending:= FALSE;
  1866. packet.respExpected:= FALSE;
  1867. packet.tLabel:= {};
  1868. packet.block:= block;
  1869. END ResetPacket;
  1870. END FirewireLowUtil.
  1871. Aos.Call FirewireLowUtil.TestPrint ~