1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098 |
- MODULE FirewireLowUtil; (** AUTHOR "VIP"; PURPOSE "IEEE 1394 Generic Driver Utilities"; *)
- IMPORT SYSTEM, KernelLog;
- CONST
- (* 1394 in ASCII *)
- BusIDNumber* = 31333934H;
- (* CSR Registers *)
- CSRBaseLow* = {28..31};
- CSRBaseHigh* = {0..15};
- CSRConfigRom*= {10};
- (* root directory entries *)
- ConfigRomLogicalUnitNumber*= 14H;
- ConfigRomVendorID*= 03H;
- ConfigRomModelID*= 17H;
- ConfigRomNodeCapabilities*= 0CH;
- ConfigRomUnitDirectory*= 0D1H;
- ConfigRomLogicalUnitDirectory*= 0D4H;
- ConfigRomSpecifierID*= 12H;
- ConfigRomUnitSWVersion*= 13H;
- ConfigRomDescriptorLeaf*= 81H;
- ConfigRomDescriptorDirectory*= 0C1H;
- (* offsets *)
- CSRTopologyMapStart* = 01000H;
- CSRTopologyMapEnd = 1400H;
- CSRSpeedMapStart = 2000H;
- CSRSpeedMapEnd = 3000H;
- (* Packet constants *)
- QUEUED* = 0;
- PENDING* = 1;
- COMPLETE* = 2;
- INCOMING* = 3;
- UNUSED* = 4;
- maxBlock = 10;
- REQU = 0; RESP = 1;
- (* Response codes *)
- respComplete*= 0;
- respConflictError=4;
- respDataError=5;
- respTypeError=6;
- respAddressError*=7;
- (* Extended transaction codes *)
- MaskSwap= 0001H;
- CompareSwap= 0002H;
- FetchAdd= 0003H;
- LittleAdd = 0004H;
- BoundedAdd = 0005H;
- WrapAdd = 0006H;
- (* Event and ack codes *)
- EvtNoStatus*= 0H; (* No event status *)
- EvtReserved1*= 1H;
- EvtLongPacket*= 2H; (* The received data length was greater than the buffer's data length *)
- EvtMissingAck*= 3H; (* A subaction gap was detected before an ack arrived or the received ack had a parity error *)
- EvtUnderrun*= 4H; (* Underrun on the corresponding FIFO. The packet was truncated *)
- EvtOverrun*= 5H; (* A receive FIFO overflowed during the reception of an isochronous packet *)
- EvtDescriptorRead*= 6H;
- EvtDataRead*= 7H;
- EvtDataWrite*= 8H;
- EvtBusReset*= 9H;
- EvtTimeout*= 0AH;
- EvtTcodeErr*= 0BH;
- EvtReserved2*= 0CH;
- EvtReserved3*= 0DH;
- EvtUnknown*= 0EH;
- EvtFlushed*= 0FH;
- EvtReserved4*= 10H;
- AckComplete*= 11H;
- AckPending*= 12H;
- EvtReserved5*= 13H;
- AckBusyX*= 14H;
- AckBusyA*= 15H;
- AckBusyB*= 16H;
- EvtReserved6*= 17H;
- EvtReserved7*= 18H;
- EvtReserved8*= 19H;
- EvtReserved9*= 1AH;
- AckTardy*= 1BH;
- EvtReserved10*= 1CH;
- AckDataError*= 1DH;
- AckTypeError*= 1EH;
- EvtReserved11*= 1FH;
- AckError*= -1;
- (* tcodes *)
- QWriteATReq* = 0H;
- BWriteATReq* = 1H;
- NoDataWATReq* = 4H;
- BReadATReq* = 5H;
- LockATReq* = 9H;
- StreamATReq* = 0AH;
- PhyATReq* = 0EH;
- NoDataWATRes* = 2H;
- QReadATRes* = 6H;
- BReadATRes* = 7H;
- LockATRes* = 0BH;
- QWriteARReq* = 0H;
- BWriteARReq* = 1H;
- NoDataQRARReq* = 4H;
- BReadARReq* = 5H;
- LockARReq* = 9H;
- PhyARReq* = 0EH;
- NoDataWARRes* = 2H;
- QReadARRes* = 6H;
- BReadARRes* = 7H;
- LockARRes* = 0BH;
- ITCode* = 0AH;
- IRCode* = 0AH;
- CycleStartCode* = 8H;
- Version*= 0H;
- MaxPhysRespRetries*= {10}; (* eight retries *)
- MaxATReqRetries*= {1}; (* two retries *)
- MaxATRespRetries*= {5}; (* two retries *)
- BufSize*= 4096;
- (* contest type *)
- ISO*= 0;
- REQ*= 1;
- RES*= 2;
- (* packet type *)
- async* = {};
- iso* = {0};
- raw* = {1};
- IntMask* = 088H;
- CIntMask*= 08CH;
- SelfIDCount* = 068H;
- SelfIDBuffer* = 064H;
- HCControl* = 050H;
- IntEvent* = 080H;
- CIntEvent* = 084H;
- PhyControl* = 0ECH;
- LinkControl* = 0E0H;
- CLinkControl* = 0E4H;
- softReset* = 16;
- NodeID* = 0E8H;
- BusID* = 01CH;
- ConfigRomMap* = 034H;
- ARReqComPtr* = 1CCH;
- ARResComPtr* = 1ECH;
- ATResComPtr* = 1ACH;
- ATReqComPtr* = 18CH;
- isoRecvIntMaskSet* = 0A8H;
- isoRecvIntMaskClear* = 0ACH;
- isoXmitIntMaskSet* = 098H;
- isoXmitIntMaskClear* = 09CH;
- IRComPtr* = 40CH;
- ITComPtr* = 20CH;
- BusOptions* = 020H;
- postedWriteEnable = 18;
- isochXmitCntCtrlClear* = 204H;
- isochXmitCntCtrlSet* = 200H;
- isochRecvCntCtrlSet* = 400H;
- isochRecvCntCtrlClear* = 404H;
- isochRecvContMatch* = 410H;
- isochRecvIntEvntClear* = 0A4H;
- isochRecvIntEvntSet* = 0A0H;
- isochRecvIntMaskClear* = 0ACH;
- isochRecvIntMaskSet* = 0A8H;
- isochXmitIntEvntSet* = 090H;
- isochXmitIntEvntClear* = 094H;
- isochXmitIntMaskSet* = 098H;
- isochXmitIntMaskClear* = 09CH;
- IRmultiChanMaskLoClear* = 07CH;
- IRmultiChanMaskLoSet* = 078H;
- IRmultiChanMaskHiClear* = 074H;
- IRmultiChanMaskHiSet* = 070H;
- ARReqContCtrlSet* = 1C0H;
- ARReqContCtrlClear* = 1C4H;
- ARResContCtrlSet* = 1E0H;
- ARResContCtrlClear* = 1E4H;
- ATReqContCtrlSet* = 180H;
- ATReqContCtrlClear* = 184H;
- ATResContCtrlSet* = 1A0H;
- ATResContCtrlClear* = 1A4H;
- ARFilterHISet* = 100H;
- ARFilterHIClaer* = 104H;
- ARFilterLowSet* = 108H;
- ARFilterLowClear* = 10CH;
- PRFilterHiSet*= 110H;
- PRFilterHiClear*= 114H;
- PRFilterLowSet*= 118H;
- PRFilterLowClear*= 11CH;
- PhyUpperBound*= 120H;
- ATRetries* = 008H;
- isochCycleTimer* = 0F0H;
- CSRData*= 00CH;
- CSRCompare*= 010H;
- CSRControl*= 014H;
- TYPE
- FIFONode*= POINTER TO NodeDesc;
- (** Data structure used only by lists *)
- NodeDesc*= RECORD
- packet: OHCIPacket;
- pListMember*: POINTER TO ListMember; (* used only by List *)
- next: FIFONode;
- END;
- (** FIFO list pointer *)
- FIFO = RECORD
- first, last: FIFONode
- END;
- (** FIFO list *)
- FIFOList= OBJECT
- PROCEDURE Enqueue*(VAR q: FIFO; n: FIFONode);
- BEGIN
- n.next:= NIL;
- IF q.first # NIL THEN q.last.next := n ELSE q.first := n END;
- q.last := n;
- END Enqueue;
- PROCEDURE DequeuedNode*(VAR q: FIFO): FIFONode;
- VAR n: FIFONode;
- BEGIN
- n := q.first;
- IF n # NIL THEN q.first := n.next END;
- RETURN n
- END DequeuedNode;
- END FIFOList;
- (** FIFO list for packets *)
- PacketFIFO*= OBJECT
- VAR q,usedQ: FIFO; list,usedList: FIFOList; bufSize: LONGINT;
- PROCEDURE GetPacket*():OHCIPacket;
- VAR n:FIFONode; packet: OHCIPacket;
- BEGIN {EXCLUSIVE}
- n:=list.DequeuedNode(q); (* Print(debug,"Dequeuning node"); *)
- IF n = NIL THEN KernelLog.String("Allocating new buffer!"); KernelLog.Ln();
- NEW(n); NEW(packet,0,bufSize); n.packet:= packet;
- END;
- usedList.Enqueue(usedQ,n);
- (* Print(debug,"Returning address!");
- KernelLog.Int(n.bufAddr,2); *)
- RETURN n.packet
- END GetPacket;
- PROCEDURE ReleasePacket*(packet: OHCIPacket);
- VAR n: FIFONode;
- BEGIN {EXCLUSIVE}
- n:= usedList.DequeuedNode(usedQ);
- n.packet:= packet;
- list.Enqueue(q,n);
- END ReleasePacket;
- PROCEDURE &Init*(numOfPacket :LONGINT);
- VAR n: FIFONode;i: LONGINT; packet: OHCIPacket;
- BEGIN {EXCLUSIVE}
- bufSize:= GetMaxPcktSize();
- NEW(list);NEW(usedList);
- IF numOfPacket > 0 THEN
- FOR i:= 0 TO numOfPacket-1 DO
- NEW(n);
- NEW(packet,0,bufSize);
- n.packet:= packet;
- list.Enqueue(q,n)
- END
- END
- END Init;
- END PacketFIFO;
- (** Used to hold addresses that must be checked before being accessed *)
- AddressChecker*= OBJECT
- VAR index: LONGINT; addrs: ARRAY 100 OF LONGINT;
- PROCEDURE Add*(adr: LONGINT);
- BEGIN
- addrs[index]:= adr;
- index:= index MOD 100;
- END Add;
- PROCEDURE Find*(adr: LONGINT): BOOLEAN;
- VAR i: LONGINT; found: BOOLEAN;
- BEGIN
- found:= FALSE;
- WHILE ~found & (i # 100) DO
- IF addrs[i] = adr THEN found:= TRUE END;
- INC(i);
- END;
- END Find;
- PROCEDURE &Init*;
- BEGIN
- index:= 0;
- END Init;
- END AddressChecker;
- CharBuffer*= POINTER TO ARRAY OF CHAR;
- (** Data structure that represents a unit directory *)
- UnitDirectory*= OBJECT
- VAR
- addrHigh*: SET;
- addrLow*: SET;
- vendorID*: LONGINT;
- vendorNameSize*: LONGINT;
- modelID*: LONGINT;
- modelNameSize*: LONGINT;
- specifierID*: LONGINT;
- version*: LONGINT;
- ID*: LONGINT;
- length: LONGINT;
- udEntries*: POINTER TO ARRAY OF SET;
- hasLogicalUnitDir*: BOOLEAN;
- luns*: ARRAY 10 OF UnitDirectory;
- PROCEDURE GetLength*():LONGINT;
- BEGIN
- RETURN length
- END GetLength;
- PROCEDURE &Init*(length: LONGINT);
- VAR i: LONGINT;
- BEGIN
- hasLogicalUnitDir:= FALSE;
- SELF.length:= length;
- NEW(udEntries,length);
- FOR i:= 0 TO 9 DO
- luns[i]:= NIL;
- END
- END Init;
- END UnitDirectory;
- (** Data structure for the global user id *)
- GUID*= RECORD
- low*: SET;
- high*: SET;
- END;
- (** Bus options *)
- BusOpt*= RECORD
- irmc*: BOOLEAN;
- cmc*: BOOLEAN;
- isc*: BOOLEAN;
- bmc*: BOOLEAN;
- pmc*: BOOLEAN;
- cycClkAcc*: LONGINT;
- maxRec*: LONGINT;
- generation*: LONGINT;
- linkSpd*: LONGINT;
- END;
- (** 1394 Node *)
- Node*= OBJECT
- VAR
- capabilities*: SET;
- phyID*: SET;
- linkAct: BOOLEAN;
- phySpeed: SET;
- delay: SET;
- contender: BOOLEAN;
- pwrClass: SET;
- portStatus: ARRAY 16 OF SET;
- guid*: GUID;
- vendorID*: LONGINT;
- generation*: LONGINT;
- probe*: BOOLEAN;
- busOptions*: BusOpt;
- uds*: ARRAY 10 OF UnitDirectory; (* should be enough *)
- PROCEDURE Update*(busOptions: SET; physicalID: SET; generation: LONGINT);
- BEGIN
- IF physicalID # phyID THEN
- KernelLog.String("The physicalID has changed "); KernelLog.Ln();
- phyID:= physicalID
- END;
- IF SELF.busOptions.generation # generation THEN
- UpdateBusOpt(busOptions);
- probe:= TRUE
- END;
- SELF.generation:= generation;
- END Update;
- (* Updates the bus options *)
- PROCEDURE UpdateBusOpt(busOpt: SET);
- BEGIN
- IF 31 IN busOpt THEN busOptions.irmc:= TRUE ELSE busOptions.irmc:= FALSE END;
- IF 30 IN busOpt THEN busOptions.cmc:= TRUE ELSE busOptions.cmc:= FALSE END;
- IF 29 IN busOpt THEN busOptions.isc:= TRUE ELSE busOptions.isc:= FALSE END;
- IF 28 IN busOpt THEN busOptions.bmc:= TRUE ELSE busOptions.bmc:= FALSE END;
- IF 27 IN busOpt THEN busOptions.pmc:= TRUE ELSE busOptions.pmc:= FALSE END;
- busOptions.cycClkAcc:= SYSTEM.VAL(LONGINT,LSH(busOpt,-16)*{0..7});
- busOptions.maxRec:= LSH(SYSTEM.VAL(LONGINT,LSH(busOpt,-12)*{0..3})+1,1);
- busOptions.generation:= SYSTEM.VAL(LONGINT,LSH(busOpt,-4)*{0..3});
- busOptions.linkSpd:= SYSTEM.VAL(LONGINT,busOpt*{0..2});
- END UpdateBusOpt;
- PROCEDURE &Init*(guid: GUID; busOptions: SET; physicalID: SET; generation: LONGINT);
- VAR i: LONGINT;
- BEGIN
- SELF.guid:= guid; phyID:= physicalID; SELF.generation:= generation;
- vendorID:= SYSTEM.VAL(LONGINT,LSH(guid.high,-8)); probe:= TRUE; UpdateBusOpt(busOptions);
- FOR i:= 0 TO 9 DO
- uds[i]:= NIL;
- END;
- END Init;
- END Node;
- (** Is used to distribute the transaction labels *)
- LabelPool*= OBJECT
- VAR freeLabel: LONGINT;
- freeLabelField: ARRAY 64 OF BOOLEAN;
- PROCEDURE GetTransLabel*():SET;
- VAR i: LONGINT; found: BOOLEAN;
- BEGIN {EXCLUSIVE}
- IF freeLabel = 0 THEN KernelLog.String("Awating free label!"); KernelLog.Ln();
- AWAIT(freeLabel > 0);
- END;
- (* search a free label *)
- (* KernelLog.String("Looking for a free label:: GetTransLabel "); KernelLog.Ln(); *)
- found:= FALSE; i:= 0;
- WHILE ~found DO
- IF freeLabelField[i] THEN found:= TRUE; DEC(freeLabel);
- freeLabelField[i]:= FALSE
- ELSE INC(i)
- END
- END;
- (* KernelLog.String("Returning transaction label: "); KernelLog.Int(i,2); KernelLog.Ln(); *)
- RETURN ConvertToSet(i);
- END GetTransLabel;
- PROCEDURE FreeTransLabel*(lab: SET);
- VAR label: LONGINT;
- BEGIN {EXCLUSIVE} label:= SYSTEM.VAL(LONGINT,lab);
- freeLabelField[label]:= TRUE; (* KernelLog.String("Freeing transaction label"); KernelLog.Ln(); *)
- INC(freeLabel)
- END FreeTransLabel;
- PROCEDURE &Init*(freeLabel: LONGINT);
- VAR i: LONGINT;
- BEGIN SELF.freeLabel:= freeLabel;
- FOR i:= 0 TO freeLabel-1 DO
- freeLabelField[i]:=TRUE;
- END
- END Init;
- END LabelPool;
- (** Data structure used in lists *)
- ListMember*=RECORD
- next*: POINTER TO ListMember;
- data*: OHCIPacket;
- END;
- (** Another kind of FIFO list *)
- List*= OBJECT
- VAR head*: POINTER TO ListMember; last*: POINTER TO ListMember; usedList*,list*: FIFOList;
- usedQ*,q*: FIFO;
- PROCEDURE AddPacket*(data: OHCIPacket);
- VAR temp: POINTER TO ListMember; n: FIFONode;
- BEGIN
- n:= list.DequeuedNode(q);
- 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);
- END;
- last.next:= temp; temp.data:= data;
- last:= temp; last.next:= NIL;
- END AddPacket;
- PROCEDURE GetPacket*(VAR packet:OHCIPacket):BOOLEAN;
- VAR error: BOOLEAN;
- BEGIN
- error:= FALSE;
- IF (head.next # NIL) THEN
- packet:= head.next.data;
- ELSE error:= TRUE END;
- RETURN error
- END GetPacket;
- PROCEDURE DelPacket*(VAR packet: OHCIPacket):BOOLEAN;
- VAR error: BOOLEAN; n: FIFONode;
- BEGIN
- error:= FALSE;
- IF (head.next # NIL) THEN
- packet:= head.next.data;
- IF last = head.next THEN last:= head END;
- n:= usedList.DequeuedNode(usedQ);
- n.pListMember:= head.next;
- list.Enqueue(q,n);
- head.next:= head.next.next;
- ELSE error:= TRUE END;
- RETURN error
- END DelPacket;
- PROCEDURE &Init*(numOfPacket: LONGINT);
- VAR n: FIFONode; i: LONGINT;
- BEGIN
- NEW(head); head.next:= NIL; last:= head; NEW(usedList); NEW(list);
- IF numOfPacket > 0 THEN
- FOR i:= 0 TO numOfPacket-1 DO
- NEW(n);
- NEW(n.pListMember);
- list.Enqueue(q,n);
- END
- END
- END Init;
- END List;
- (** Data structure to represent self identification information of each node on the bus *)
- SelfID*= OBJECT (* 1394-1995 *)
- VAR
- packetIdentifier*: SET;
- physicalID*: SET;
- extended*: BOOLEAN;
- linkActive*: SET;
- gapCount*: SET;
- sp*: SET;
- del*: SET;
- c*: SET;
- pwr*: SET;
- p0*: SET;
- p1*: SET;
- p2*: SET;
- i*: SET;
- m*: SET;
- PROCEDURE &Init*(packetZero: SET);
- BEGIN
- packetIdentifier:= LSH(packetZero * {30,31},-30);
- physicalID:= LSH(packetZero * {24..29},-24);
- IF 23 IN packetZero THEN extended:= TRUE ELSE extended:= FALSE END;
- linkActive:= LSH(packetZero * {22},-22);
- gapCount:= LSH(packetZero * {16..21},-16);
- sp:= LSH(packetZero * {14,15},-14);
- del:= LSH(packetZero * {12,13},-12);
- c:= LSH(packetZero * {11},-11);
- pwr:= LSH(packetZero * {8..10},-8);
- p0:= LSH(packetZero * {6,7},-6);
- p1:= LSH(packetZero * {4,5},-4);
- p2:= LSH(packetZero * {2,3},-2);
- i:= LSH(packetZero * {1},-1);
- m:= packetZero * {0};
- END Init;
- END SelfID;
- (** Data structure used to hold extended selfidentification information *)
- ExtSelfID*= OBJECT(SelfID) (* 1394-1995 *)
- VAR
- seq*: SET;
- pa*: SET;
- pb*: SET;
- pc*: SET;
- pd*: SET;
- pe*: SET;
- pf*: SET;
- pg*: SET;
- ph*: SET;
- PROCEDURE &Init*(packetZero: SET);
- BEGIN
- packetIdentifier:= LSH(packetZero * {30,31},-30);
- physicalID:= LSH(packetZero * {24..29},-24);
- IF 23 IN packetZero THEN extended:= TRUE ELSE extended:= FALSE END;
- seq:= LSH(packetZero * {20..22},-20);
- pa:= LSH(packetZero * {16,17},-16);
- pb:= LSH(packetZero * {14,15},-14);
- pa:= LSH(packetZero * {12,13},-12);
- pa:= LSH(packetZero * {10,11},-10);
- pa:= LSH(packetZero * {8,9},-8);
- pa:= LSH(packetZero * {6,7},-6);
- pa:= LSH(packetZero * {4,5},-4);
- pa:= LSH(packetZero * {2,3},-2);
- m:= packetZero * {0};
- END Init;
- END ExtSelfID;
- (** Holds OHCI informatin and status *)
- OHCIDesc*= RECORD
- SelfIDErrors*: LONGINT;
- SelfIDBufferAdr*: SET;
- ptrToSelfIDBuf*: CharBuffer;
- ConfigRomBufferAdr*: SET;
- ptrToConfigRomBuf*: CharBuffer;
- MaxPacketSize*: LONGINT;
- ARDescNum*: LONGINT;
- ATDescNum*: LONGINT;
- IRDescNum*: LONGINT;
- ITDescNum*: LONGINT;
- IMDesc*: InputMoreDesc;
- inBusReset*: BOOLEAN;
- ARController*: ADMAController;
- ATController*: ADMAController;
- IRController*: IRDMAController;
- ITController*: ITDMAController;
- Nodes*: ARRAY 63 OF Node;
- IsRoot*: BOOLEAN;
- ExstRegMap*: BOOLEAN;
- IsIRM*: BOOLEAN;
- IsBM*: BOOLEAN;
- nodeID*: LONGINT;
- TopologyMap*: ARRAY 256 OF SelfID;
- SpeedMap*: ARRAY 64,64 OF LONGINT;
- numOfNodes*: LONGINT;
- labeler*: LabelPool;
- selfIDComplete*: BOOLEAN;
- adrCheck*: AddressChecker;
- packetFIFO*: PacketFIFO;
- tempBuffer*: POINTER TO ARRAY OF CHAR;
- END ;
- (** Represents an OHCI packet *)
- OHCIPacket*= OBJECT
- VAR
- host*: OHCIDesc;
- nodeID*: SET;
- type*: SET;
- header*: POINTER TO ARRAY OF SET; (* data from the response packet *)
- 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 *)
- headerSize*: LONGINT;
- dataSize*: LONGINT;
- tCode*: SET;
- speed*: SET;
- ack*: SET;
- pending*: BOOLEAN;
- respExpected*: BOOLEAN;
- tLabel*: SET;
- generation*: LONGINT;
- state*: LONGINT;
- block*: Block; (* only needed when sending *)
- size*: LONGINT;
- name*: ARRAY 5 OF CHAR;
- blockBufferAddr*: ADDRESS;
- ptrToBlckBufAddr*: CharBuffer;
- PROCEDURE &Init*(hSize,dSize: LONGINT);
- BEGIN
- blockBufferAddr:= AllocATReqBuf(ptrToBlckBufAddr);
- headerSize:= hSize; dataSize:= dSize; size:= 0;
- IF headerSize = 0 THEN (* using embedded header *)
- headerSize:= 4*5 END;
- NEW(header,headerSize DIV 4); NEW(data,dataSize DIV 4);
- generation:= -1; state:= UNUSED;
- END Init;
- END OHCIPacket;
- (** Represents a descriptor block *)
- Block* = RECORD
- descNum*: LONGINT;
- start*: ADDRESS;
- end*: ADDRESS; (* Points to first quadlet of last descriptor *)
- END;
- (** Represents a context program *)
- Program* = OBJECT
- VAR blockBuffer*: BlockBuffer; bufferAddr*: ADDRESS; j,blockNum: LONGINT; hasNext,result: BOOLEAN;
- branchAddressPtr, branchAddress: ADDRESS; nextAddr*: ADDRESS; packetOffset*: LONGINT; curDesc*: SET;
- ptrToBuf*: CharBuffer; oldPtrToBlck,ptrToBlck: CharBuffer;
- PROCEDURE SetBranchAddress*(address,ptr: ADDRESS;newPtrToBlck: CharBuffer);
- BEGIN
- oldPtrToBlck:= ptrToBlck;
- ptrToBlck:= newPtrToBlck;
- (* set branchAddress in precedent block *)
- IF branchAddressPtr # 0 THEN
- branchAddress:= address; SYSTEM.PUT32(branchAddressPtr,branchAddress) END;
- (* update branchAddress pointer to this block and set Z to zero because this is the last block*)
- branchAddressPtr:= ptr; SYSTEM.PUT32(branchAddressPtr,{})
- END SetBranchAddress;
- (* Used to set the program buffer address *)
- PROCEDURE SetBufferAddr*(addr: ADDRESS);
- BEGIN
- bufferAddr:= addr;
- (* nextAddr and curDesc represent basically the same thing *)
- nextAddr:= addr; (* just to initialize *)
- curDesc:= SYSTEM.VAL(SET,bufferAddr); (* just to initialize *)
- END SetBufferAddr;
- PROCEDURE GetBufferAddr*():ADDRESS;
- BEGIN
- RETURN bufferAddr;
- END GetBufferAddr;
- (* Block buffer holds free blocks, if there is no block left then one has to wait *)
- PROCEDURE GetFreeBlocks*():LONGINT;
- BEGIN
- RETURN blockBuffer.GetFreeBlocks()
- END GetFreeBlocks;
- PROCEDURE &Init*;
- BEGIN
- NEW(blockBuffer,maxBlock); branchAddressPtr:= 0;ptrToBlck:= NIL;
- hasNext:= FALSE; j:= 0; blockNum:= 0; packetOffset:= 0;
- END Init;
- END Program;
- Packet* = ARRAY BufSize OF CHAR;
- (** Represents a DMA context *)
- Contest* = OBJECT
- VAR
- type*: LONGINT;
- prgr*: Program;
- procBuffer*: PacketBuffer; (* received packets *)
- cmdPtr*: LONGINT;
- ctrlSet*: LONGINT;
- ctrlClear*: LONGINT;
- name*: ARRAY 20 OF CHAR;
- listAwaiting*: List; (* packets awaiting an ack or a response after being sent from list inserted*)
- listPending*: List; (* packets to send *)
- listInserted*: List; (* sent packets coming from list pending*)
- tempBuffer*: ARRAY 1 OF SET;
- ptrToTmpBuf*: ARRAY 1 OF CharBuffer;
- buffers*: BufferBuffer;
- PROCEDURE &Init*(pcktNum,bufferNum: LONGINT);
- BEGIN
- NEW(listPending,100); NEW(listInserted,100); NEW(listAwaiting,100);
- NEW(procBuffer,pcktNum);
- NEW(prgr); NEW(buffers,bufferNum);
- END Init;
- END Contest;
- (** The isochronous receive context *)
- IRContest* =OBJECT(Contest)
- VAR match*: LONGINT;
- END IRContest;
- (** The isochronous transmit controller*)
- ITDMAController*= OBJECT
- VAR contests: POINTER TO ARRAY OF Contest; contest: Contest; i,j,avITCont: LONGINT; hasNext*:BOOLEAN;
- PROCEDURE GetNextContest*():Contest;
- BEGIN
- contest:= contests[j];
- INC(j);
- IF ~(j < avITCont) THEN hasNext:= FALSE; j:= 0 END;
- RETURN contest;
- END GetNextContest;
- PROCEDURE ResetIterator*;
- BEGIN
- IF avITCont > 0 THEN hasNext:= TRUE END
- END ResetIterator;
- PROCEDURE &Init*(contNum,pcktNum,bufferNum: LONGINT);
- BEGIN
- NEW(contests,contNum);
- FOR i:= 0 TO contNum-1 DO NEW(contest,pcktNum,contNum*bufferNum);
- contests[i]:= contest;
- END;
- j:= 0; avITCont:= contNum; IF avITCont > 0 THEN hasNext:= TRUE END
- END Init;
- END ITDMAController;
- (** The asynchronous controller *)
- ADMAController* = OBJECT
- VAR contests: POINTER TO ARRAY OF Contest; contest: Contest;
- PROCEDURE GetReqContest*(): Contest;
- BEGIN
- RETURN contests[REQU];
- END GetReqContest;
- PROCEDURE GetResContest*(): Contest;
- BEGIN
- RETURN contests[RESP];
- END GetResContest;
- PROCEDURE &Init*(pcktNum, bufferNum :LONGINT);
- BEGIN
- NEW(contests,2);
- NEW(contest,pcktNum,bufferNum);
- contests[REQU]:= contest;
- NEW(contest,pcktNum,bufferNum);
- contests[RESP]:= contest;
- END Init;
- END ADMAController;
- (** The isochronous controller *)
- IRDMAController*= OBJECT
- VAR contests: POINTER TO ARRAY OF IRContest; contest: IRContest; i,j,avIRCont*: LONGINT; hasNext*:BOOLEAN;
- PROCEDURE GetNextContest*():IRContest;
- BEGIN
- contest:= contests[j];
- INC(j);
- IF ~(j < avIRCont) THEN hasNext:= FALSE; j:= 0 END;
- RETURN contest;
- END GetNextContest;
- PROCEDURE GetContest*(n: LONGINT):IRContest;
- BEGIN
- RETURN contests[n]
- END GetContest;
- PROCEDURE ResetIterator*;
- BEGIN
- IF avIRCont > 0 THEN hasNext:= TRUE END
- END ResetIterator;
- PROCEDURE &Init*(contNum,pcktNum,bufferNum :LONGINT);
- BEGIN
- NEW(contests,contNum);
- FOR i:=0 TO contNum-1 DO NEW(contest,pcktNum,contNum*bufferNum);
- contests[i]:= contest
- END;
- j:= 0; avIRCont:= contNum; IF avIRCont > 0 THEN hasNext:= TRUE END
- END Init;
- END IRDMAController;
- (** This is a ring buffer for generic buffers *)
- BufferBuffer* = OBJECT
- VAR head, num: LONGINT; buffer: POINTER TO ARRAY OF SET;
- ptrToBuf: POINTER TO ARRAY OF CharBuffer;
- PROCEDURE FreeBuffer*(x: SET);
- BEGIN {EXCLUSIVE}
- AWAIT(num # LEN(buffer));
- buffer[(head+num) MOD LEN(buffer)] := x;
- INC(num)
- END FreeBuffer;
- PROCEDURE GetBuffer*(): SET;
- VAR x: SET;
- BEGIN {EXCLUSIVE}
- AWAIT(num # 0);
- x := buffer[head];
- head := (head+1) MOD LEN(buffer);
- DEC(num);
- RETURN x
- END GetBuffer;
- PROCEDURE &Init*(n: LONGINT);
- BEGIN
- head := 0; num := n; NEW(buffer, n); NEW(ptrToBuf, n);
- AllocPcktBuf(n,buffer^,ptrToBuf^);
- END Init;
- END BufferBuffer;
- (** This is a ring buffer for packet buffers *)
- PacketBuffer* = OBJECT
- VAR head, num: LONGINT; buffer: POINTER TO ARRAY OF Packet;
- PROCEDURE Append*(x: Packet);
- BEGIN {EXCLUSIVE}
- AWAIT(num # LEN(buffer));
- buffer[(head+num) MOD LEN(buffer)] := x;
- INC(num)
- END Append;
- PROCEDURE Remove*(): Packet;
- VAR x: Packet;
- BEGIN {EXCLUSIVE}
- AWAIT(num # 0);
- x := buffer[head];
- head := (head+1) MOD LEN(buffer);
- DEC(num);
- RETURN x
- END Remove;
- PROCEDURE GetPckt*(): Packet;
- VAR x: Packet;
- BEGIN {EXCLUSIVE}
- AWAIT(num # 0);
- x := buffer[head];
- RETURN x
- END GetPckt;
- PROCEDURE &Init*(n: LONGINT);
- BEGIN
- head := 0; num := 0; NEW(buffer, n)
- END Init;
- END PacketBuffer;
- (** This is a ring buffer for block buffers *)
- BlockBuffer* = OBJECT
- VAR head, (* free places in the fifo *) num*: LONGINT; buffer: POINTER TO ARRAY OF Block;
- PROCEDURE Append*(x: Block);
- BEGIN {EXCLUSIVE}
- AWAIT(num # LEN(buffer));
- buffer[(head+num) MOD LEN(buffer)] := x;
- INC(num);
- END Append;
- PROCEDURE Remove*(): Block;
- VAR x: Block;
- BEGIN {EXCLUSIVE}
- AWAIT(num # 0);
- x := buffer[head];
- head := (head+1) MOD LEN(buffer);
- DEC(num);
- RETURN x
- END Remove;
- PROCEDURE GetBlock*():Block;
- VAR x: Block;
- BEGIN {EXCLUSIVE}
- AWAIT(num # 0);
- x := buffer[head];
- RETURN x;
- END GetBlock;
- PROCEDURE GetFreeBlocks*():LONGINT;
- BEGIN {EXCLUSIVE}
- RETURN num
- END GetFreeBlocks;
- PROCEDURE &Init*(n: LONGINT);
- BEGIN
- head := 0; num := 0; NEW(buffer, n)
- END Init;
- END BlockBuffer;
- (** A generic descriptor *)
- GeneralDesc*= RECORD
- control*: SET;
- address*: SET;
- branchAddress*: SET;
- status*: SET;
- data*: ARRAY 4 OF SET;
- END;
- (** Data structure for an input more descriptor *)
- InputMoreDesc* = RECORD
- cmd*: SET;
- s*: SET;
- key*: SET;
- i*: SET;
- b*: SET;
- w*:SET;
- reqCount*: SET;
- dataAddress*: SET;
- branchAddress*: SET;
- Z*: SET;
- xferStatus*: SET;
- resCount*: SET;
- END;
- (** Data structure for an input last descriptor *)
- InputLastDesc* = RECORD
- cmd*: SET;
- s*: SET;
- key*: SET;
- i*: SET;
- b*: SET;
- w*:SET;
- reqCount*: SET;
- dataAddress*: SET;
- branchAddress*: SET;
- Z*: SET;
- xferStatus*: SET;
- resCount*: SET;
- END;
- (** Data structure for an output more descriptor *)
- OutputMore*= RECORD
- cmd*: SET;
- key*: SET;
- b*: SET;
- resCount*: SET;
- reqCount*: SET;
- dataAddress*: SET;
- END;
- (** Data structure for an output more immediate descriptor *)
- OutputMoreImmediate*= RECORD
- cmd*: SET;
- key*: SET;
- i*: SET;
- b*: SET;
- reqCount*: SET;
- skipAddress*: SET;
- Z*: SET;
- timeStamp*: SET;
- firstQuadlet*: SET;
- secondQuadlet*: SET;
- thirdQuadlet*: SET;
- fourthQuadlet*: SET;
- END;
- (** Data structure for an output last descriptor *)
- OutputLast*= RECORD
- cmd*: SET;
- s*: SET;
- key*: SET;
- p*: SET;
- i*: SET;
- b*: SET;
- reqCount*: SET;
- dataAddress*: SET;
- brachAddress*: SET;
- Z*: SET;
- xferStatus*: SET;
- timeStamp*: SET;
- END;
- (** Data structure for an output last immediate descriptor *)
- OutputLastImmediate*= RECORD
- cmd*: SET;
- s*: SET;
- key*: SET;
- p*: SET;
- i*: SET;
- b*: SET;
- reqCount*: SET;
- brachAddress*: SET;
- Z*: SET;
- xferStatus*: SET;
- timeStamp*: SET;
- firstQuadlet*: SET;
- secondQuadlet*: SET;
- thirdQuadlet*: SET;
- fourthQuadlet*: SET;
- END;
- (** Data structure for a store value descriptor *)
- StoreValueDesc*= RECORD
- cmd*: SET;
- key*: SET;
- i*: SET;
- storeDoublet*: SET;
- dataAddress*: SET;
- skipAddress*: SET;
- Z*: SET;
- END;
- (** Data structure for a dual buffer descriptor *)
- DualBufferDesc* = RECORD
- s*: SET;
- key*: SET;
- i*: SET;
- b*: SET;
- w*: SET;
- firstSize*: SET;
- firstReqCount*: SET;
- secondReqCount*: SET;
- brachAddress*: SET;
- Z*: SET;
- firstBuffer*: SET;
- secondBuffer*: SET;
- END;
- VAR avIRCont, avITCont: LONGINT; base: LONGINT;
- (** Returns the bus id *)
- PROCEDURE GetBusID*():SET;
- BEGIN
- RETURN LSH(ReadReg(NodeID)*{6..15},-6);
- END GetBusID;
- (** Returns the generation counter *)
- PROCEDURE GetGeneration*():LONGINT;
- VAR reg: SET;
- BEGIN
- reg:= ReadReg(SelfIDCount);
- reg:= LSH(reg,-16)*{0..7};
- RETURN SYSTEM.VAL(LONGINT,reg);
- END GetGeneration;
- (** Computes the packet length *)
- PROCEDURE PacketLength*(context: Contest):LONGINT;
- VAR bufferAddr: SET; bufSize, resCount, packetSize, packetOffset: LONGINT; nextBlock, curBlock: LONGINT;
- BEGIN
- (* KernelLog.String("Entering PacketLength"); KernelLog.Ln(); *)
- curBlock:= SYSTEM.VAL(LONGINT,context.prgr.curDesc);
- packetOffset:= context.prgr.packetOffset;
- bufferAddr:= SYSTEM.VAL(SET,SYSTEM.GET32(curBlock + 4));
- bufSize:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(curBlock))*{0..15});
- resCount:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(curBlock + 12))*{0..15});
- (* remember that packet cannot cross more than one buffer boundary *)
- IF resCount > 0 THEN (* Packet is not split *)
- (* KernelLog.String("Packet is not split::PacketLength"); KernelLog.Ln(); *)
- packetSize:= bufSize - packetOffset - resCount;
- ELSE (* packet is split or exactly filled the buffer *)
- (* KernelLog.String("Packet is split or exactly fills the buffer!::PacketLength"); KernelLog.Ln(); *)
- packetSize:= bufSize - packetOffset;
- nextBlock:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(curBlock+8))*{4..31});
- bufSize:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(nextBlock))*{0..15});
- resCount:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(nextBlock + 12))*{0..15});
- ASSERT(resCount > 0); (* This should never happen *)
- packetSize:= packetSize+ bufSize - resCount;
- END;
- (* KernelLog.String("Leaving PacketLength"); KernelLog.Ln(); *)
- ASSERT(packetSize > 0);
- RETURN packetSize;
- (* remember that we always need at least one free descriptor to handle next incoming packet *)
- END PacketLength;
- (** This function maps tCodes to packetSizes in bytes *)
- PROCEDURE TCodeToSize*(tCode: SET):LONGINT;
- VAR tCodeSize: ARRAY 16 OF LONGINT;
- BEGIN
- tCodeSize[0]:= 20;
- tCodeSize[1]:= 0;
- tCodeSize[2]:= 16;
- tCodeSize[3]:= -1;
- tCodeSize[4]:= 16;
- tCodeSize[5]:= 20;
- tCodeSize[6]:= 20;
- tCodeSize[7]:= 0;
- tCodeSize[8]:= -1;
- tCodeSize[9]:= 0;
- tCodeSize[10]:= -1;
- tCodeSize[11]:= 0;
- tCodeSize[12]:= -1;
- tCodeSize[13]:= -1;
- tCodeSize[14]:= 16;
- tCodeSize[15]:= -1;
- RETURN tCodeSize[SYSTEM.VAL(LONGINT,tCode)];
- END TCodeToSize;
- (** Writes to register *)
- PROCEDURE WriteReg*(reg: LONGINT; val: SET);
- BEGIN
- SYSTEM.PUT32(base + reg, val);
- END WriteReg;
- (** Reads from a register *)
- PROCEDURE ReadReg*(reg: LONGINT):SET;
- BEGIN
- RETURN SYSTEM.VAL(SET, SYSTEM.GET32(base + reg));
- END ReadReg;
- (** Starts a context *)
- PROCEDURE StartContest*(contest: Contest):BOOLEAN;
- CONST isValid= 31; nodeNumber= {0..5};
- BEGIN
- (* check if node id is valid *)
- IF ~(isValid IN ReadReg(NodeID)) THEN KernelLog.String("Node id is not valid"); KernelLog.Ln();
- RETURN FALSE
- END;
- (* check if node id is not equal 63 *)
- IF ConvertToSet(63) = (ReadReg(NodeID)*nodeNumber) THEN KernelLog.String("Node id is 63");
- KernelLog.Ln(); RETURN FALSE
- END;
- (* run the contest*)
- (* KernelLog.String("Running contest "); KernelLog.String(contest.name); KernelLog.Ln(); *)
- WriteReg(contest.ctrlSet,{15}); RETURN TRUE;
- END StartContest;
- (* isoRecvIntMask *)
- (** Checks how much isochronous transmit contexts are availble *)
- PROCEDURE CheckAvailableIT*;
- VAR reg: SET; i,av: LONGINT;
- BEGIN
- reg:= {0..31};
- SYSTEM.PUT32(base + isoXmitIntMaskSet,reg);
- reg:= SYSTEM.VAL(SET, SYSTEM.GET32(base + isoXmitIntMaskSet));
- FOR i:= 0 TO 31 DO
- IF i IN reg THEN INC(av);
- END
- END;
- (* KernelLog.String("There are ");KernelLog.Int(av,2);
- KernelLog.String(" available isoXmit contexts"); KernelLog.Ln(); *)
- avITCont:= av;
- END CheckAvailableIT;
- (** Checks how much isochronous receive contexts are availble *)
- PROCEDURE CheckAvailableIR*;
- VAR reg: SET; i,av: LONGINT;
- BEGIN
- reg:= {0..31};
- SYSTEM.PUT32(base + isoRecvIntMaskSet,reg);
- reg:= SYSTEM.VAL(SET, SYSTEM.GET32(base + isoRecvIntMaskSet));
- FOR i:= 0 TO 31 DO
- IF i IN reg THEN INC(av);
- END
- END;
- (* KernelLog.String("There are ");KernelLog.Int(av,2);
- KernelLog.String(" available isoRecv contexts"); KernelLog.Ln(); *)
- avIRCont:= av;
- END CheckAvailableIR;
- (** Returns the availble number of isochronous receive contexts *)
- PROCEDURE GetAvailableIRCont*():LONGINT;
- BEGIN
- RETURN avIRCont;
- END GetAvailableIRCont;
- (** Returns the availble number of isochronous transmit contexts *)
- PROCEDURE GetAvailableITCont*():LONGINT;
- BEGIN
- RETURN avITCont;
- END GetAvailableITCont;
- (** Sets the isochronous receive context match register *)
- PROCEDURE SetIsochRecvContMatch*(s: SET);
- VAR reg: SET;
- BEGIN
- reg:= SYSTEM.VAL(SET,SYSTEM.GET32(base+isochRecvContMatch));
- reg:= reg + s;
- SYSTEM.PUT32(base+isochRecvContMatch,reg);
- END SetIsochRecvContMatch;
- (** Allocates a buffer for the asynchronous transmit context *)
- PROCEDURE AllocATReqBuf*(VAR ptrToBfr: CharBuffer):ADDRESS;
- VAR buffer: CharBuffer; adr: ADDRESS;
- BEGIN
- (* Allocating a 128 byte address + 16 byte padding *)
- NEW(buffer, 144);
- (* find a 16 byte aligned address *)
- adr:= ADDRESSOF(buffer[0]);
- DEC(adr, adr MOD 16);
- INC(adr, 16);
- ptrToBfr:= buffer;
- RETURN adr;
- END AllocATReqBuf;
- (** Allocates a buffer for the asynchronous receive context *)
- PROCEDURE AllocATResBuf*(VAR ptrToBfr: CharBuffer):ADDRESS;
- VAR buffer: CharBuffer; adr: ADDRESS;
- BEGIN
- (* Allocating a 128 byte address + 16 byte padding *)
- NEW(buffer, 144);
- (* find a 16 byte aligned address *)
- adr:= ADDRESSOF(buffer[0]);
- DEC(adr, adr MOD 16);
- INC(adr, 16);
- ptrToBfr:= buffer;
- RETURN adr;
- END AllocATResBuf;
- (** Allocates a buffer for the isochronous transmit context *)
- PROCEDURE AllocITBuf*(VAR ptrToBfr: CharBuffer;descNum: LONGINT):ADDRESS;
- VAR buffer: CharBuffer; adr: ADDRESS;
- BEGIN
- (* Allocating buffer for the isochronous context *)
- NEW(buffer, 16*descNum+16);
- (* Find a 16 byte aligned address *)
- adr:= ADDRESSOF(buffer[0]);
- DEC(adr, adr MOD 16);
- INC(adr, 16);
- ptrToBfr:= buffer;
- RETURN adr;
- END AllocITBuf;
- (** Allocates a buffer for the isochronous receive context *)
- PROCEDURE AllocIRBuf*(VAR ptrToBfr: CharBuffer;descNum: LONGINT):ADDRESS;
- VAR buffer: CharBuffer; adr: ADDRESS;
- BEGIN
- (* Allocating buffer for the isochronous context *)
- NEW(buffer, 16*descNum+16);
- (* Find a 16 byte aligned address *)
- adr:= ADDRESSOF(buffer[0]);
- DEC(adr, adr MOD 16);
- INC(adr, 16);
- ptrToBfr:= buffer;
- RETURN adr
- END AllocIRBuf;
- (** Allocates a buffer for the asynchronous receive request context *)
- PROCEDURE AllocARReqBuf*(VAR ptrToBfr: CharBuffer):ADDRESS;
- VAR buffer: CharBuffer; adr: ADDRESS;
- BEGIN
- (* Allocating a 80 byte address *)
- NEW(buffer, 80);
- (* find a 16 byte aligned address *)
- adr:= ADDRESSOF(buffer[0]);
- DEC(adr, adr MOD 16);
- INC(adr, 16);
- ptrToBfr:= buffer;
- RETURN adr;
- END AllocARReqBuf;
- (** Allocates a buffer for the asynchronous receive response context *)
- PROCEDURE AllocARResBuf*(VAR ptrToBfr: CharBuffer):ADDRESS;
- VAR buffer: CharBuffer; adr: ADDRESS;
- BEGIN
- (* Allocating a 80 byte address *)
- NEW(buffer, 80);
- (* find a 16 byte aligned address *)
- adr:= ADDRESSOF(buffer[0]);
- DEC(adr, adr MOD 16);
- INC(adr, 16);
- ptrToBfr:= buffer;
- RETURN adr;
- END AllocARResBuf;
- (** Sets the isochronous receive command pointer *)
- PROCEDURE SetIRComPtr*(VAR ptrToBuf: CharBuffer);
- VAR buffer: CharBuffer; adr: ADDRESS; s: SET; i: LONGINT;
- BEGIN
- FOR i:= 0 TO avIRCont-1 DO
- (* Allocating a 80 byte address *)
- NEW(buffer, 80);
- (* find a 16 byte aligned address *)
- adr:= ADDRESSOF(buffer[0]);
- DEC(adr, adr MOD 16);
- INC(adr, 16);
- s:= SYSTEM.VAL(SET,adr);
- (* Setting the address *)
- SYSTEM.PUT32(base + IRComPtr + 32*i, s);
- ptrToBuf:= buffer;
- END
- END SetIRComPtr;
- (** Sets the isochronous transmit command pointer *)
- PROCEDURE SetITComPtr*(VAR ptrToBuf: CharBuffer);
- VAR buffer: CharBuffer; adr: ADDRESS; s: SET; i: LONGINT;
- BEGIN
- FOR i:= 0 TO avITCont-1 DO
- (* Allocating a 80 byte address *)
- NEW(buffer, 80);
- (* find a 16 byte aligned address *)
- adr:= ADDRESSOF(buffer[0]);
- DEC(adr, adr MOD 16);
- INC(adr, 16);
- s:= SYSTEM.VAL(SET,adr);
- (* Setting the address *)
- SYSTEM.PUT32(base + ITComPtr + 16*i, s);
- ptrToBuf:= buffer;
- END
- END SetITComPtr;
- (* Int Mask *)
- (** Clears the interrupt mask *)
- PROCEDURE ClearIntMaskAll*;
- VAR s,s2:SET; i: LONGINT;
- BEGIN
- (* KernelLog.String("Entering ClearIntMaskAll");
- KernelLog.Ln(); *)
- CheckIntMask();
- s := ReadReg(IntMask);
- i := 0;
- WHILE i < 32 DO
- s2 := {};
- IF ~(i IN {10,11,12,13,14,28,30,31}) & (i IN s) THEN
- INCL(s2,i);
- WriteReg(CIntMask,s2);
- END;
- INC(i);
- END;
- CheckIntMask();
- (* KernelLog.String("Leaving ClearIntMaskAll");
- KernelLog.Ln(); *)
- END ClearIntMaskAll;
- (** Prints the interrupt mask register *)
- PROCEDURE CheckIntMask*;
- VAR reg:SET;
- BEGIN
- reg := ReadReg(IntMask);
- (* KernelLog.String("Checking IntMask");
- KernelLog.Ln;
- PrintSet(reg); *)
- END CheckIntMask;
- (* HCControl *)
- (** Sets HCControl register fields *)
- PROCEDURE SetHCControl*(reg:SET);
- VAR reg2: SET;
- BEGIN
- reg2:= ReadReg(HCControl);
- reg:= reg + reg2;
- SYSTEM.PUT32(base+HCControl,reg);
- END SetHCControl;
- (* IntEvent *)
- PROCEDURE SoftInterrupt*; (* not used *)
- CONST softInterrupt= 29;
- VAR reg:SET;
- BEGIN
- INCL(reg,softInterrupt);
- SYSTEM.PUT32(base + IntEvent,reg);
- END SoftInterrupt;
- (** Clears all occured interrupt event *)
- PROCEDURE ClearIntEventAll*;
- VAR s,s2:SET; i: LONGINT;
- BEGIN
- (* KernelLog.String("Entering ClearIntEventAll");
- KernelLog.Ln(); *)
- CheckIntEvent();
- s := ReadReg(IntEvent);
- i := 0;
- WHILE i < 32 DO
- s2 := {};
- IF ~(i IN {10,11,12,13,14,28,30,31}) & (i IN s) THEN
- INCL(s2,i);
- WriteReg(CIntEvent,s2);
- END;
- INC(i);
- END;
- CheckIntEvent();
- (* KernelLog.String("Leaving ClearIntEventAll");
- KernelLog.Ln(); *)
- END ClearIntEventAll;
- (** Checks the HCControl register *)
- PROCEDURE CheckHCControl;
- VAR reg: SET;
- BEGIN
- reg:= ReadReg(HCControl);
- KernelLog.String("Checking HCControl");
- KernelLog.Ln;
- PrintSet(reg);
- END CheckHCControl;
- (** Checks the int event register *)
- PROCEDURE CheckIntEvent*;
- VAR reg:SET;
- BEGIN
- reg := ReadReg(IntEvent);
- (* KernelLog.String("Checking IntEvent");
- KernelLog.Ln;
- PrintSet(reg); *)
- END CheckIntEvent;
- (* Context Control *)
- (** Stops a context *)
- PROCEDURE StopContext*(reg: LONGINT);
- CONST run= {15}; active= 10;
- VAR s: SET;
- BEGIN
- SYSTEM.PUT32(base + reg,run);
- s:= SYSTEM.VAL(SET, SYSTEM.GET32(base + reg));
- WHILE active IN s DO
- s:= SYSTEM.VAL(SET, SYSTEM.GET32(base + reg));
- END;
- (* KernelLog.String("Stopped context"); KernelLog.Ln();
- PrintSet(ReadReg(reg)); *)
- END StopContext;
- (* PhyControl *)
- (** Sets the physical control register to write data to regAddr *)
- PROCEDURE SetPhyControl*(regAddr:SET; data: SET);
- CONST rdReg = 15; rdData = {16..23}; IBR = 6; wrReg = 14; rdDone = 31;
- VAR phyReg: SET; done: BOOLEAN; dataRead: SET; offset: LONGINT; i: LONGINT;
- BEGIN
- (* KernelLog.String("Setting the phy control register"); KernelLog.Ln(); *)
- phyReg:= ReadReg(PhyControl);
- (* Set register address *)
- phyReg:= phyReg + regAddr;
- (* Initiate read request *)
- INCL(phyReg,rdReg);
- (* Write the register back *)
- SYSTEM.PUT32(base+PhyControl,phyReg);
- done:= FALSE;
- (* wait until register is read *)
- WHILE ~done DO
- (* KernelLog.String("I'm waiting");
- KernelLog.Ln(); *)
- phyReg := ReadReg(PhyControl);
- IF rdDone IN phyReg THEN done := TRUE;
- END
- END;
- (* masking out ridden Data *)
- dataRead := phyReg*rdData;
- (* eliminate offset *)
- offset := 16;
- i := 16;
- WHILE i<24 DO
- IF i IN dataRead THEN EXCL(dataRead,i);INCL(dataRead,(i-offset));
- END;
- INC(i)
- END;
- (* setting bit *)
- dataRead:= dataRead + data;
- (* to be sure read out one more time *)
- phyReg := ReadReg(PhyControl);
- (* set register address although could still be set *)
- phyReg:= phyReg + regAddr;
- (* write to wrData the data that has to be written *)
- phyReg := phyReg+dataRead;
- (*initiate write request*)
- (* set "write request" bit *)
- SYSTEM.PUT32(base+PhyControl,phyReg);
- INCL(phyReg,wrReg);
- SYSTEM.PUT32(base+PhyControl,phyReg);
- done := FALSE;
- (* wait until register is written *)
- WHILE ~done DO
- (* KernelLog.String("I'm waiting");
- KernelLog.Ln(); *)
- phyReg := ReadReg(PhyControl);
- IF ~(wrReg IN phyReg) THEN done := TRUE;
- END
- END;
- END SetPhyControl;
- (** Converts a value to a set *)
- PROCEDURE ConvertToSet*(l: ADDRESS):SET;
- BEGIN
- RETURN SYSTEM.VAL(SET,l)
- END ConvertToSet;
- (** Does the same as LSH but only for sets, better use LSH *)
- PROCEDURE DelOffset*(reg:SET;offset:LONGINT):SET;
- VAR i: LONGINT;
- BEGIN
- i := 0;
- WHILE i<32 DO
- IF i IN reg THEN
- EXCL(reg,i); INCL(reg,(i-offset))
- END;
- INC(i);
- END;
- RETURN reg;
- END DelOffset;
- (** Basically does what system.move does *)
- PROCEDURE AllocPacket*(dataAddr: ARRAY OF SET; dataSize: SIZE;adr: ADDRESS):SET;
- VAR i,j: SIZE; address: SET;
- BEGIN
- (* dataSize is in bytes *)
- address:= SYSTEM.VAL(SET,adr);
- j:= 0; i:= 0;
- WHILE i< (dataSize-1) DO
- SYSTEM.PUT32(SYSTEM.VAL(LONGINT,address)+i,dataAddr[j]);
- INC(i,4); INC(j);
- END;
- RETURN address
- END AllocPacket;
- (** Allocates a 4KB buffer for an OHCI packet *)
- PROCEDURE AllocPcktBuf*(num: LONGINT; VAR bufs: ARRAY OF SET;VAR ptrBufs: ARRAY OF CharBuffer);
- VAR i: LONGINT; buffer: CharBuffer; adr: ADDRESS; s: SET;
- BEGIN
- FOR i:= 0 TO num-1 DO
- (* Allocating a 4096 byte buffer + 4 byte for the alignement *)
- NEW(buffer, BufSize + 4);
- adr:= ADDRESSOF(buffer[0]);
- (* Find a 4 byte aligned address *)
- DEC(adr, adr MOD 4);
- INC(adr, 4);
- s:= SYSTEM.VAL(SET,adr);
- bufs[i]:= s;
- ptrBufs[i]:= buffer;
- END
- END AllocPcktBuf;
- (** Returns the maximally allowed size for an asynchronous OHCI packet *)
- PROCEDURE GetMaxPcktSize*():LONGINT;
- CONST mask = {12..15};
- VAR reg:SET; val,i: LONGINT; size: LONGINT;
- BEGIN
- size:= 1;
- reg:= SYSTEM.VAL(SET,SYSTEM.GET32(base + BusOptions));
- reg:= reg*mask;
- reg:= DelOffset(reg,12);
- (* convert to integer *)
- val:= SYSTEM.VAL(LONGINT,reg);
- (* increment by one, because smallest value should be two *)
- INC(val);
- FOR i:= 0 TO val-1 DO size:= size*2 END;
- (* add 20 bytes for header and trailer *)
- size:= size + 20;
- RETURN size;
- END GetMaxPcktSize;
- (** Checks the self identification counter *)
- PROCEDURE CheckSelfIDCount*;
- CONST selfIDError= 31;
- VAR reg:SET;
- BEGIN
- reg:= SYSTEM.VAL(SET,SYSTEM.GET32(base + SelfIDCount));
- IF selfIDError IN reg THEN (* KernelLog.String("There was an error during the self ID process"); KernelLog.Ln() *) END;
- (* KernelLog.String("Printing the contents of the Self Id Count register:" ); KernelLog.Ln(); PrintSet(reg); KernelLog.Ln(); *)
- END CheckSelfIDCount;
- (** Checks the status of the OHCI *)
- PROCEDURE CheckStatus*;
- BEGIN
- CheckSelfIDCount();
- CheckIntEvent();
- CheckLinkControl();
- CheckHCControl();
- CheckBusID();
- PrintNodeInfo();
- CheckBusManagerID();
- END CheckStatus;
- (** Checks the bus manager id *)
- PROCEDURE CheckBusManagerID;
- CONST csrDone= 31;
- VAR reg: SET; done: BOOLEAN;
- BEGIN
- (* First check who is Bus Manager *)
- WriteReg(CSRData,{0..5});
- WriteReg(CSRCompare,{0..5});
- WriteReg(CSRControl,{});
- (* Wait until compare swap operation has been done *)
- reg:= ReadReg(CSRControl);
- done:= FALSE;
- WHILE ~done DO
- IF csrDone IN reg THEN done:= TRUE ELSE
- reg:= ReadReg(CSRControl)
- END
- END;
- (* Read the bus manager ID *)
- reg:= ReadReg(CSRData);
- (* Print it out *)
- KernelLog.String("Printing the bus manager id");
- PrintSet(reg);
- (* Print the node id to compare it *)
- KernelLog.String("Printing the node id");
- reg:= ReadReg(NodeID);
- reg:= reg*{0..5};
- PrintSet(reg);
- END CheckBusManagerID;
- (** Checks the bus id *)
- PROCEDURE CheckBusID;
- VAR reg:SET;
- BEGIN
- KernelLog.String("Checking the BusID"); KernelLog.Ln();
- reg:= SYSTEM.VAL(SET, SYSTEM.GET32(base + BusID));
- PrintSet(reg);
- END CheckBusID;
- (** Checks the LinkControl register content *)
- PROCEDURE CheckLinkControl*;
- VAR reg:SET;
- BEGIN
- reg := ReadReg(LinkControl);
- KernelLog.String("Checking LinkControl");
- KernelLog.Ln;
- PrintSet(reg);
- END CheckLinkControl;
- (** Used to force a softreset *)
- PROCEDURE SoftReset*; (* not used *)
- BEGIN
- SetHCControl({softReset});
- WHILE softReset IN (ReadReg(HCControl)) DO END
- END SoftReset;
- (** Sets the base address of the OHCI register set *)
- PROCEDURE SetBase*(b: LONGINT);
- BEGIN
- base := b;
- (* KernelLog.String("base is: ");
- KernelLog.Int(base,2);
- KernelLog.Ln(); *)
- END SetBase;
- (** Returns an asynchronous output more immediate descriptor *)
- PROCEDURE GetAOMIDesc*():OutputMoreImmediate;
- CONST keyOMI= {25};
- VAR descOMI: OutputMoreImmediate;
- BEGIN
- descOMI.key:= keyOMI;
- RETURN descOMI
- END GetAOMIDesc;
- (** Returns an asynchronous output last descriptor *)
- PROCEDURE GetAOLDesc*():OutputLast;
- CONST cmdOL= {28}; bOL= {18,19}; iOL= {20,21};
- VAR descOL: OutputLast;
- BEGIN
- descOL.cmd:= cmdOL; descOL.b:= bOL; descOL.i:= iOL;
- RETURN descOL
- END GetAOLDesc;
- (** Returns an asynchronous last immediate descriptor *)
- PROCEDURE GetAOLIDesc*(): OutputLastImmediate;
- CONST cmdOLI= {28}; keyOLI= {25}; bOLI= {18,19}; iOLI= {20,21};
- VAR descOLI: OutputLastImmediate;
- BEGIN
- descOLI.cmd:= cmdOLI; descOLI.key:= keyOLI; descOLI.b:= bOLI; descOLI.i:= iOLI;
- RETURN descOLI
- END GetAOLIDesc;
- (** Returns an isochronous input last descriptor *)
- PROCEDURE GetIILDesc*(): InputLastDesc;
- CONST cmdIL = {28,29};
- VAR descIL: InputLastDesc;
- BEGIN
- descIL.cmd:= cmdIL;
- RETURN descIL
- END GetIILDesc;
- (** Returns an isochronous input more descriptor *)
- PROCEDURE GetIIMDesc*():InputMoreDesc;
- CONST cmdIM= {29};
- VAR descIM: InputMoreDesc;
- BEGIN
- descIM.cmd:= cmdIM;
- RETURN descIM
- END GetIIMDesc;
- (** Returns an isochronous dual buffer descriptor *)
- PROCEDURE GetIDBDesc*(): DualBufferDesc;
- CONST s = {27}; b = {19,18};
- VAR descDB: DualBufferDesc;
- BEGIN
- descDB.s := s; descDB.b := b;
- RETURN descDB
- END GetIDBDesc;
- (** Returns an isochronous output more immediate descriptor *)
- PROCEDURE GetIOMIDesc*(): OutputMoreImmediate;
- CONST keyOMI = {25}; reqCountOMI = {4};
- VAR descOMI: OutputMoreImmediate;
- BEGIN
- descOMI.key:= keyOMI; descOMI.reqCount:= reqCountOMI;
- RETURN descOMI
- END GetIOMIDesc;
- (** Returns an isochronous output last descriptor *)
- PROCEDURE GetIOLDesc*(): OutputLast;
- CONST cmdOL = {28}; bOL = {19,18};
- VAR descOL: OutputLast;
- BEGIN
- descOL.cmd:= cmdOL; descOL.b:= bOL;
- RETURN descOL
- END GetIOLDesc;
- (** Returns an isochronous output last immediate descriptor *)
- PROCEDURE GetIOLIDesc*(): OutputLastImmediate;
- CONST cmdOLI = {28}; keyOLI = {25}; bOLI= {19,18}; reqCountOLI= {4};
- VAR descOLI: OutputLastImmediate;
- BEGIN
- descOLI.cmd:= cmdOLI; descOLI.key:= keyOLI; descOLI.b:= bOLI; descOLI.reqCount:= reqCountOLI;
- RETURN descOLI
- END GetIOLIDesc;
- (** Returns an isochronous store value descriptor *)
- PROCEDURE GetISVDesc*(): StoreValueDesc;
- CONST cmdSV= {31}; keySV= {26,25};
- VAR descSV: StoreValueDesc;
- BEGIN
- descSV.cmd:= cmdSV; descSV.key:= keySV;
- RETURN descSV
- END GetISVDesc;
- (** Prints the status information of the ohci *)
- PROCEDURE PrintNodeInfo*;
- CONST iDValid = 31; root = 30; CPS = 27;
- VAR reg: SET;
- BEGIN
- reg:= SYSTEM.VAL(SET, SYSTEM.GET32(base + NodeID));
- KernelLog.String("Printing node information:"); KernelLog.Ln();
- IF iDValid IN reg THEN
- KernelLog.String("Node has a valid node number."); KernelLog.Ln();
- ELSE KernelLog.String("Node has no valid node number."); KernelLog.Ln() END;
- PrintSet(reg);
- reg:= SYSTEM.VAL(SET, SYSTEM.GET32(base + NodeID));
- IF root IN reg THEN
- KernelLog.String("Node is root."); KernelLog.Ln();
- ELSE KernelLog.String("Node is not root."); KernelLog.Ln() END;
- PrintSet(reg);
- IF CPS IN reg THEN
- KernelLog.String("Cable power status is ok.");KernelLog.Ln();
- ELSE KernelLog.String("Cable power status is not ok.");KernelLog.Ln() END;
- CheckIntEvent();
- END PrintNodeInfo;
- (** Is used to print out a set *)
- PROCEDURE PrintSet*(set:SET);
- VAR x:LONGINT;
- BEGIN
- x := 0;
- WHILE x < 32 DO
- IF x IN set THEN KernelLog.Int(x,2); KernelLog.String(", "); END;
- INC(x);
- END;
- KernelLog.Ln();
- END PrintSet;
- (** Builds the header of a response packet *)
- PROCEDURE BuildHeaderResp*(tc: LONGINT; VAR packet: OHCIPacket; rCode: LONGINT);
- VAR busNumber: SET;
- BEGIN
- busNumber:= LSH(ReadReg(NodeID)*{6..15},16);
- packet.tCode:= ConvertToSet(tc);
- packet.header[0]:= LSH(packet.nodeID,16) + busNumber + LSH(packet.tLabel,10) + LSH({0},8) +
- ConvertToSet(LSH(tc,4));
- packet.header[1]:= ConvertToSet(LSH(packet.host.nodeID,16)) + SYSTEM.VAL(SET,LSH(rCode,12));
- packet.header[2]:= {};
- END BuildHeaderResp;
- (** Fill an asynchronous write response packet *)
- PROCEDURE FillAsyncWriteResp*(VAR packet: OHCIPacket; rCode: LONGINT);
- BEGIN
- BuildHeaderResp(NoDataWARRes,packet,rCode);
- packet.header[2]:= {};
- packet.headerSize:= 12;
- packet.dataSize:= 0;
- packet.respExpected:= FALSE;
- END FillAsyncWriteResp;
- (** Fills an asynchronous read quadlet response packet *)
- PROCEDURE FillAsyncReadQuadResp*(VAR packet: OHCIPacket; rCode,bufferAddr: LONGINT);
- BEGIN
- BuildHeaderResp(QReadARRes,packet,rCode);
- packet.header[3]:= SYSTEM.VAL(SET,SYSTEM.GET32(bufferAddr));
- packet.headerSize:= 16;
- packet.dataSize:= 0;
- packet.respExpected:= FALSE;
- END FillAsyncReadQuadResp;
- (** Fills an asynchronous read block response packet *)
- PROCEDURE FillAsyncReadBlockResp*(VAR packet: OHCIPacket; rCode,length: LONGINT);
- VAR padding: LONGINT;
- BEGIN
- IF rCode # respComplete THEN length:= 0 END;
- BuildHeaderResp(BReadARRes,packet,rCode);
- packet.header[3]:= SYSTEM.VAL(SET,LSH(length,16));
- packet.headerSize:= 16;
- IF (length MOD 4 > 0) THEN padding:= 4 - (length MOD 4) ELSE padding:= 0 END;
- packet.dataSize:= length + padding;
- packet.respExpected:= FALSE;
- END FillAsyncReadBlockResp;
- (** Builds the header of a packet *)
- PROCEDURE BuildHeader(tc: LONGINT; VAR packet: OHCIPacket; addrLow,addrHigh: SET);
- VAR busNumber: SET;
- BEGIN
- busNumber:= LSH(ReadReg(NodeID)*{6..15},16);
- packet.tCode:= ConvertToSet(tc);
- (* KernelLog.String("Setting header[0]"); KernelLog.Ln(); *)
- packet.header[0]:= LSH(packet.nodeID,16) + busNumber + LSH(packet.tLabel,10) + LSH({0},8) +
- ConvertToSet(LSH(tc,4));
- (* KernelLog.String("Setting header[1]"); KernelLog.Ln(); *)
- packet.header[1]:= ConvertToSet(LSH(packet.host.nodeID,16)) + addrHigh + busNumber;
- (* KernelLog.String("Printing the nodeID: "); PrintSet(packet.nodeID); KernelLog.Ln();
- KernelLog.String("Printing the address: "); PrintSet(addrLow); PrintSet(addrHigh); KernelLog.Ln(); *)
- (* KernelLog.String("Setting header[2]"); KernelLog.Ln(); *)
- packet.header[2]:= addrLow
- END BuildHeader;
- (* Procedure needed to build packets from here on *)
- (** Fills a lock packet *)
- PROCEDURE FillLockPacket(packet: OHCIPacket; addrLow,addrHigh: SET; extCode: LONGINT; length: LONGINT);
- BEGIN
- (* KernelLog.String("Building header::FillLockPacket!"); KernelLog.Ln(); *)
- BuildHeader(LockATReq, packet, addrLow, addrHigh);
- packet.header[3]:= SYSTEM.VAL(SET,LSH(length,16)) + SYSTEM.VAL(SET,extCode);
- packet.headerSize:= 16;
- packet.dataSize:= length;
- packet.respExpected:= TRUE;
- END FillLockPacket;
- (** Fills an asynchronous write quadlet packet *)
- PROCEDURE FillAsyncWriteQuadlet*(packet: OHCIPacket; addrLow, addrHigh, data: SET);
- BEGIN
- (* KernelLog.String("Building header::FillAsyncWriteQuadlet!"); KernelLog.Ln(); *)
- BuildHeader(QWriteATReq, packet, addrLow, addrHigh);
- packet.header[3]:= data;
- packet.headerSize:= 16;
- packet.dataSize:= 0;
- packet.respExpected:= TRUE;
- END FillAsyncWriteQuadlet;
- (** Fills an asynchronous write block packet *)
- PROCEDURE FillAsyncWriteBlock*(packet: OHCIPacket; addrLow, addrHigh: SET; length: LONGINT);
- VAR padding: LONGINT;
- BEGIN
- (* KernelLog.String("Building header::FillAsyncWriteBlock!"); KernelLog.Ln(); *)
- BuildHeader(BWriteATReq, packet,addrLow, addrHigh);
- packet.header[3]:= SYSTEM.VAL(SET,LSH(length,16));
- packet.headerSize:= 16;
- packet.respExpected:= TRUE;
- IF (length MOD 4 > 0) THEN padding:= 4 - (length MOD 4) ELSE padding:= 0 END;
- packet.dataSize:= length + padding;
- END FillAsyncWriteBlock;
- (** Fills an asynchronous read quadlet packet *)
- PROCEDURE FillAsyncReadQuadlet*(VAR packet: OHCIPacket; addrLow,addrHigh: SET);
- BEGIN
- (* KernelLog.String("Building header::FillAsyncReadQuadlet!"); KernelLog.Ln(); *)
- BuildHeader(NoDataWATReq,packet,addrLow,addrHigh);
- (* PrintSet(packet.header[0]);
- PrintSet(packet.header[1]);
- PrintSet(packet.header[2]); *)
- packet.headerSize:= 12;
- packet.dataSize:= 0;
- packet.respExpected:= TRUE;
- END FillAsyncReadQuadlet;
- (** Fills an asynchronous read block packet *)
- PROCEDURE FillAsyncReadBlock*(VAR packet: OHCIPacket; addrLow,addrHigh: SET; length: LONGINT);
- BEGIN
- BuildHeader(BReadATReq,packet,addrLow,addrHigh);
- packet.header[3]:= ConvertToSet(LSH(length,16));
- packet.headerSize:= 16;
- packet.dataSize:= 0;
- packet.respExpected:= TRUE;
- END FillAsyncReadBlock;
- (** Test if a packet and eventually its response were successfully sent and received *)
- PROCEDURE TestIfSuccess*(packet:OHCIPacket):BOOLEAN;
- VAR tCode: LONGINT;
- BEGIN
- tCode:= SYSTEM.VAL(LONGINT,packet.tCode);
- CASE SYSTEM.VAL(LONGINT,packet.ack) OF
- AckPending:
- (* KernelLog.String("The packet received an ackPending::testIFSuccess"); KernelLog.Ln(); *)
- CASE SYSTEM.VAL(LONGINT,LSH(packet.header[1],-12) * {0..3}) OF
- respComplete: RETURN TRUE;
- |respConflictError: KernelLog.String("The packet had a conflict error!"); KernelLog.Ln();
- RETURN FALSE;
- |respDataError: KernelLog.String("The packet had a data error!"); KernelLog.Ln();
- RETURN FALSE;
- |respTypeError: KernelLog.String("The packet had a type error!"); KernelLog.Ln();
- RETURN FALSE;
- |respAddressError: KernelLog.String("The packet had an address error!"); KernelLog.Ln();
- RETURN FALSE;
- ELSE KernelLog.String("Received reserved code!"); KernelLog.Ln();
- (* dump packet data *)
- PrintSet(packet.header[0]);
- PrintSet(packet.header[1]);
- PrintSet(packet.header[2]);
- RETURN FALSE
- END;
- |AckBusyX: RETURN FALSE; KernelLog.String("AckBusyX"); KernelLog.Ln();
- |AckBusyA: RETURN FALSE; KernelLog.String("AckBusyA"); KernelLog.Ln();
- |AckBusyB: RETURN FALSE; KernelLog.String("AckBusyB"); KernelLog.Ln();
- |AckTypeError: RETURN FALSE;
- |AckComplete:
- (* KernelLog.String("The packet received an ackComplete::testIFSuccess"); KernelLog.Ln(); *)
- IF (tCode = QWriteATReq) OR (tCode = BWriteATReq) THEN
- RETURN TRUE
- ELSE
- KernelLog.String("Impossible ack complete!"); KernelLog.Ln(); RETURN FALSE
- END;
- |AckDataError:
- KernelLog.String("AckDataError"); KernelLog.Ln();
- IF (tCode = BWriteATReq) OR (tCode = LockATReq) THEN
- RETURN FALSE
- ELSE
- KernelLog.String("Impossible ack data error!"); KernelLog.Ln(); RETURN FALSE
- END;
- |AckError: KernelLog.String("AckError"); KernelLog.Ln(); RETURN FALSE;
- ELSE KernelLog.String("An invalid ack was received!"); KernelLog.Ln(); RETURN FALSE
- END
- END TestIfSuccess;
- (** Instantiates a lock packet *)
- PROCEDURE MakeLockPacket*(ohci: OHCIDesc; nodeID: SET; addrLow, addrHigh:SET; extcode: LONGINT;
- data,arg: SET):OHCIPacket;
- VAR p: OHCIPacket; length: LONGINT;
- BEGIN
- p:= ohci.packetFIFO.GetPacket();
- p.dataSize:= 8;
- (* reset packet *)
- ResetPacket(p);
- p.host:= ohci;
- p.nodeID:= nodeID;
- p.tLabel:= ohci.labeler.GetTransLabel();
- CASE extcode OF
- FetchAdd: length:= 4;
- IF data # {} THEN p.data[0]:= data; (* KernelLog.String("Data is not an empty set"); KernelLog.Ln() *) END;
- |LittleAdd: length:= 4;
- IF data #{} THEN p.data[0]:= data; (* KernelLog.String("Data is not an empty set"); KernelLog.Ln() *) END;
- ELSE length:= 8;
- IF data # {} THEN p.data[0]:= arg; p.data[1]:= data; (* KernelLog.String("Data is not an empty set"); KernelLog.Ln() *) END
- END;
- (* KernelLog.String("The length is::MakeLockpacket:: "); KernelLog.Int(length,2); KernelLog.Ln(); *)
- FillLockPacket(p, addrLow, addrHigh, extcode, length);
- (* Dump data
- KernelLog.String("Dumping the data::MakeLockPacket"); KernelLog.Ln();
- FOR i:= 0 TO (p.dataSize DIV 4)-1 DO
- PrintSet(p.data[i])
- END; *)
- RETURN p;
- END MakeLockPacket;
- (** Instantiates a write packet *)
- PROCEDURE MakeWritePacket*(ohci:OHCIDesc; nodeID, addrLow, addrHigh, buffer: SET; length: LONGINT ): OHCIPacket;
- VAR packet: OHCIPacket; i,padding: LONGINT;
- BEGIN
- IF length = 0 THEN RETURN NIL END;
- IF (length MOD 4 > 0) THEN padding:= 4 - (length MOD 4) END;
- (* KernelLog.String("Allocating a new packet!"); KernelLog.Ln(); *)
- packet:= ohci.packetFIFO.GetPacket();
- packet.dataSize:= length + padding;
- (* reset packet *)
- ResetPacket(packet);
- packet.host:= ohci;
- packet.nodeID:= nodeID;
- (* KernelLog.String("Getting transaction label"); KernelLog.Ln(); *)
- packet.tLabel:= ohci.labeler.GetTransLabel(); (* Hier wird gewartet wenn nichts frei ist *)
- (* KernelLog.String("Filling the packets!"); KernelLog.Ln(); *)
- IF length = 4 THEN
- (* KernelLog.String("Filling asynchronous write quadlet packet!"); KernelLog.Ln(); *)
- FillAsyncWriteQuadlet(packet,addrLow,addrHigh,buffer)
- ELSE
- (* KernelLog.String("Filling asynchronous write+ block packet!"); KernelLog.Ln(); *)
- FillAsyncWriteBlock(packet,addrLow,addrHigh,length);
- IF buffer # {} THEN (* SYSTEM.MOVE(SYSTEM.VAL(LONGINT,buffer),ADDRESSOF(packet.data),length) *)
- WHILE i # (length DIV 4) DO
- packet.data[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,buffer)+i*4));
- INC(i);
- END
- END;
- (* KernelLog.String("Dumping the packet!"); KernelLog.Ln();
- i:= 0;
- WHILE i # (length DIV 4) DO
- PrintSet(packet.data[i]); INC(i);
- END *)
- END;
- RETURN packet
- END MakeWritePacket;
- (** Instantiates a read packet *)
- PROCEDURE MakeReadPacket*(ohci: OHCIDesc; nodeID: SET; addrLow,addrHigh: SET; length: LONGINT): OHCIPacket;
- VAR packet: OHCIPacket; padding: LONGINT;
- BEGIN
- IF length = 0 THEN RETURN NIL END;
- IF (length MOD 4 > 0) THEN padding:= 4 - (length MOD 4) END;
- (* KernelLog.String("Allocating a new packet!"); KernelLog.Ln(); *)
- packet:= ohci.packetFIFO.GetPacket();
- packet.dataSize:= length + padding;
- (* reset packet *)
- ResetPacket(packet);
- packet.host:= ohci;
- packet.nodeID:= nodeID;
- (* KernelLog.String("Getting transaction label"); KernelLog.Ln(); *)
- packet.tLabel:= ohci.labeler.GetTransLabel(); (* Hier wird gewartet wenn nichts frei ist *)
- (* KernelLog.String("Filling the packets!"); KernelLog.Ln(); *)
- IF length = 4 THEN
- (* KernelLog.String("Filling asynchronous read quadlet packet!"); KernelLog.Ln(); *)
- FillAsyncReadQuadlet(packet,addrLow,addrHigh)
- ELSE
- (* KernelLog.String("Filling asynchronous read block packet!"); KernelLog.Ln(); *)
- FillAsyncReadBlock(packet,addrLow,addrHigh,length)
- END;
- RETURN packet
- END MakeReadPacket;
- (** Resets all packet fields *)
- PROCEDURE ResetPacket*(VAR packet: OHCIPacket);
- VAR block: Block; ohci: OHCIDesc;
- BEGIN
- packet.host:= ohci;
- packet.nodeID:= {};
- packet.type:= {};
- packet.tCode:= {};
- packet.speed:= {};
- packet.ack:= {};
- packet.pending:= FALSE;
- packet.respExpected:= FALSE;
- packet.tLabel:= {};
- packet.block:= block;
- END ResetPacket;
- END FirewireLowUtil.
- Aos.Call FirewireLowUtil.TestPrint ~
|