1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632 |
- MODULE FirewireLow; (** AUTHOR "VIP"; PURPOSE "IEEE 1394 Generic Driver"; *)
- IMPORT SYSTEM, KernelLog, Machine, PCI, Objects, Modules, FirewireLowUtil, Kernel, Strings;
- CONST
- MaxSelfIDErrors= 16;
- busNumber= {6..15};
- LinkEnable = 17;
- LPS = 19;
- masterIntEnable = 31;
- reqTxComplete = 0;
- respTxComplete = 1;
- ARRQ = 2;
- ARRS = 3;
- RQPkt = 4;
- RSPkt = 5;
- isochTx = 6;
- isochRx = 7;
- postedWriteErr = 8;
- lockRespErr = 9;
- selfIDComplete2 = 15;
- selfIDComplete = 16;
- busReset = 17;
- regAccessFail = 18;
- phy = 19;
- cycleSynch = 20;
- cycle64Seconds = 21;
- cycleLost = 22;
- cycleInconsistent = 23;
- unrecoverableError = 24;
- cycleTooLong = 25;
- phyRegRcvd = 26;
- ackTardy = 27;
- softInterrupt = 29;
- rcvSelfID = 9;
- TYPE
- OHCIPacket = FirewireLowUtil.OHCIPacket;
- Contest = FirewireLowUtil.Contest;
- ListMember= FirewireLowUtil.ListMember;
- Controller= OBJECT
- VAR
- base,irq:LONGINT; OHCI*: FirewireLowUtil.OHCIDesc; t: Kernel.Timer; timer: Kernel.MilliTimer;
- timeout: BOOLEAN; clock: Objects.Timer;
- (** Is used to handle an await timeout *)
- PROCEDURE HandleTimeout;
- VAR ms: LONGINT;
- BEGIN {EXCLUSIVE}
- ms:= Kernel.Left(timer);
- IF ms <= 0 THEN
- timeout := TRUE;
- ELSE
- (* KernelLog.Enter; KernelLog.String("Timer early "); KernelLog.Int(ms, 1); KernelLog.Exit; *)
- Objects.SetTimeout(clock, SELF.HandleTimeout, ms)
- END
- END HandleTimeout;
- (** Allocates the receive buffer for the SelfID DMA context *)
- PROCEDURE SelfIDAlloc;
- VAR buffer: FirewireLowUtil.CharBuffer; adr: ADDRESS; s: SET;
- BEGIN
- (* KernelLog.String("Entering ConfigSelfID"); *)
- KernelLog.Ln();
- (* Allocating 10K buffer , although I just need 8192 *)
- NEW(buffer,10240);
- (* find a 2K aligned address *)
- adr := ADDRESSOF(buffer[0]);
- DEC(adr,adr MOD 2048);
- INC(adr,2048);
- s := SYSTEM.VAL(SET,adr);
- (* setting the buffer address *)
- OHCI.SelfIDBufferAdr:= s;
- OHCI.ptrToSelfIDBuf:= buffer;
- (* Setting the max selfid retries *)
- OHCI.SelfIDErrors:= 0;
- (* KernelLog.String("Printing the buffer address"); KernelLog.Ln();
- FirewireLowUtil.PrintSet(s);
- KernelLog.String("Leaving ConfigSelfID"); *)
- KernelLog.Ln();
- END SelfIDAlloc;
- (** Reads a quadlet and returns the content as a set *)
- PROCEDURE ReadSetQuadlet(address:LONGINT):SET;
- BEGIN
- RETURN SYSTEM.VAL(SET, SYSTEM.GET32(address));
- END ReadSetQuadlet;
- (** Checks the selfID packet stream: checks if the generation counter corresponds to the actual one and also checks the integrity of the packets *)
- PROCEDURE CheckSelfIDStream():BOOLEAN;
- CONST offsetSize = 2; selfIDError= 31; selfIDSizeMask = {0..8};
- VAR selfIDSize, address, reg: SET; size: LONGINT; error: BOOLEAN;
- BEGIN
- (* KernelLog.String("Entering CheckSelfIDStream"); KernelLog.Ln(); *)
- error:= FALSE;
- address := OHCI.SelfIDBufferAdr;
- reg := FirewireLowUtil.ReadReg(FirewireLowUtil.SelfIDCount);
- (* Mask the size field *)
- selfIDSize := LSH(reg,-2);
- selfIDSize := selfIDSize*selfIDSizeMask;
- size := ConvertToLongint(selfIDSize);
- (* KernelLog.String("There are "); KernelLog.Int(size,2); KernelLog.String(" quadlets in the self id buffer."); KernelLog.Ln(); *)
- (* compare the selfIDGeneration field of the whole stream if there are errors do a bus reset *)
- IF CompareSelfIDGen(address,size) OR (selfIDError IN reg) THEN error:= TRUE;
- IF OHCI.SelfIDErrors < MaxSelfIDErrors THEN INC(OHCI.SelfIDErrors);
- KernelLog.String("There was an error checking the self id stream"); KernelLog.Ln();
- ELSE KernelLog.String("Too much errors in self id process, giving up"); KernelLog.Ln();
- END
- END;
- IF ~error THEN
- (* Reset selfID error counter *)
- OHCI.SelfIDErrors:= 0;
- (* Now Check the integrity *)
- IF CheckIntegrity(address,size) THEN error:= TRUE;
- KernelLog.String("There was an error checking the integrity of the self id stream"); KernelLog.Ln()
- END
- END;
- (* KernelLog.String("Leaving CheckSelfIDStream"); KernelLog.Ln(); *)
- RETURN error
- END CheckSelfIDStream;
- (** Prints the content of a buffer as a set *)
- PROCEDURE PrintBuffer(address: SET; size: LONGINT);
- VAR i, j, adr: LONGINT;
- BEGIN
- i:= 0;
- j:= 0;
- adr:= ConvertToLongint(address);
- WHILE i < size DO FirewireLowUtil.PrintSet(SYSTEM.VAL(SET, SYSTEM.GET32(adr+j)));
- INC(j,4); INC(i);
- END
- END PrintBuffer;
- (** Checks the integrity of selfID packets *)
- PROCEDURE CheckIntegrity(address: SET; size:LONGINT):BOOLEAN;
- VAR i: LONGINT;data, invData : SET; error: BOOLEAN; j: LONGINT;
- BEGIN
- (* KernelLog.String("Entering CheckIntegrity"); KernelLog.Ln(); *)
- error:= FALSE;
- j := 4; (* First bit holds status information, do not check *)
- i := 1;
- (* PrintBuffer(address,size); *)
- WHILE i < size DO
- data := SYSTEM.VAL(SET, SYSTEM.GET32(ConvertToLongint(address)+j)); INC(j,4);
- invData:= SYSTEM.VAL(SET, SYSTEM.GET32(ConvertToLongint(address)+j));
- IF ~(({0..31}-data) = invData) THEN
- KernelLog.String("Integrity is broken"); KernelLog.Ln(); error:= TRUE; i:= size;
- ELSE (* KernelLog.String("Integrity check was successfull"); KernelLog.Ln() *)
- END;
- INC(j,4);
- INC(i,2);
- END;
- (* KernelLog.String("Leaving CheckIntegrity"); KernelLog.Ln(); *)
- RETURN error
- END CheckIntegrity;
- (** Compares the generation field of selfID packets with the generation counter of the system to see if they correspond *)
- PROCEDURE CompareSelfIDGen(address:SET; size:LONGINT):BOOLEAN;
- CONST selfIDGenMask = {16..23}; offsetGen = 16;
- VAR header, selfIDGeneration: SET; i: LONGINT; error: BOOLEAN;
- BEGIN
- (* KernelLog.String("Entering Procedure CompareSelfIDGen"); KernelLog.Ln(); *)
- (* Read the header of the first SelfID packet *)
- error:= FALSE;
- header := SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(address)));
- (* Mask the selfIDGeneration field *)
- selfIDGeneration := header*selfIDGenMask;
- (* check if selfIDGen field is the same as in selfIDCountRegister *)
- i:= 0;
- header := ReadSetQuadlet(ConvertToLongint(address));
- header := header*selfIDGenMask;
- IF ~(header = selfIDGeneration) THEN
- KernelLog.String("selfIDGeneration mismatch");KernelLog.Ln(); error:= TRUE
- END;
- (* KernelLog.String("Leaving compare SelfIDGen "); KernelLog.Ln(); *)
- RETURN error;
- END CompareSelfIDGen;
- (** Converts a SET to a LONGINT *)
- PROCEDURE ConvertToLongint(reg: SET):LONGINT;
- BEGIN
- RETURN SYSTEM.VAL(LONGINT,reg);
- END ConvertToLongint;
- (** Processes sent packets *)
- PROCEDURE ProcSentPckts(contest: Contest) ;
- VAR packet: OHCIPacket; status: SET; ack,dataSize: LONGINT; block: FirewireLowUtil.Block;
- CONST acks= 4; code= {0..4};
- BEGIN
- (* KernelLog.String("Processing sent packets!"); KernelLog.Ln(); *)
- WHILE ~contest.listInserted.GetPacket(packet) DO
- dataSize:= packet.dataSize;
- block:= packet.block;
- IF (dataSize > 0) & (packet.type # FirewireLowUtil.raw) THEN
- status:= LSH(SYSTEM.VAL(SET, SYSTEM.GET32(block.end + 12)),-16)
- ELSE status:= LSH(SYSTEM.VAL(SET, SYSTEM.GET32(block.start + 12)),-16)
- END;
- (* KernelLog.String("Printing the status: "); FirewireLowUtil.PrintSet(status); KernelLog.Ln(); *)
- (* check if it's an ack *)
- IF (acks IN status) THEN ack:= SYSTEM.VAL(LONGINT,status*code);
- (* KernelLog.String("It's an ack!"); KernelLog.Ln(); *)
- ELSE (* it's an event code *)
- KernelLog.String("It's an event code!"); KernelLog.Ln();
- CASE (ConvertToLongint(status*code)) OF
- FirewireLowUtil.EvtNoStatus: KernelLog.String("No event status!"); KernelLog.Ln()
- | FirewireLowUtil.EvtLongPacket: ack:= FirewireLowUtil.AckError;
- KernelLog.String("The received data length was greater than the buffer's data length!");KernelLog.Ln()
- | FirewireLowUtil.EvtMissingAck: ack:= FirewireLowUtil.AckError;
- KernelLog.String("A subaction gap was detected before an ack arrived or the received ack had a parity error!");
- KernelLog.Ln()
- | FirewireLowUtil.EvtUnderrun: ack:= FirewireLowUtil.AckError;
- KernelLog.String("Underrun on the corresponding FIFO. The packet was truncated!"); KernelLog.Ln()
- | FirewireLowUtil.EvtOverrun: ack:= FirewireLowUtil.AckError;
- KernelLog.String("A receive FIFO overflowed during the reception of an isochronous packet!"); KernelLog.Ln()
- | FirewireLowUtil.EvtDescriptorRead: ack:= FirewireLowUtil.AckError;
- KernelLog.String("An unrecoverable error occurred while the Host Controller was reading a descriptor block!");
- KernelLog.Ln()
- | FirewireLowUtil.EvtDataRead: ack:= FirewireLowUtil.AckError;
- KernelLog.String("An error occurred while the Host Controller was attempting to"); KernelLog.Ln();
- KernelLog.String(" read from host memory in the data stage of descriptor processing!"); KernelLog.Ln();
- | FirewireLowUtil.EvtDataWrite: ack:= FirewireLowUtil.AckError;
- KernelLog.String("An error occurred while the Host Controller was attempting to "); KernelLog.Ln();
- KernelLog.String("write to host memory in the data stage of descriptor processing "); KernelLog.Ln();
- KernelLog.String("or when processing a single 16-bit host memory write!"); KernelLog.Ln()
- | FirewireLowUtil.EvtBusReset: ack:= FirewireLowUtil.AckError;
- KernelLog.String("This is the synthesized bus reset packet!"); KernelLog.Ln();
- | FirewireLowUtil.EvtTimeout: ack:= FirewireLowUtil.AckError;
- KernelLog.String("This asynchronous transmit response packet expired and"); KernelLog.Ln();
- KernelLog.String(" was not transmitted or an IT DMA context experienced "); KernelLog.Ln();
- KernelLog.String("a skip processing overflow!"); KernelLog.Ln();
- | FirewireLowUtil.EvtTcodeErr: ack:= FirewireLowUtil.AckError;
- KernelLog.String("This packet has a bad event code!"); KernelLog.Ln()
- | FirewireLowUtil.EvtUnknown: ack:= FirewireLowUtil.AckError;
- KernelLog.String("Unknown error condition!"); KernelLog.Ln();
- | FirewireLowUtil.EvtFlushed: ack:= FirewireLowUtil.AckError;
- KernelLog.String("This packet was flushed due to a bus reset!"); KernelLog.Ln();
- ELSE KernelLog.String("Unhandled or reserved event!"); KernelLog.Ln()
- END;
- RETURN
- END;
- PacketSent(contest,packet,FirewireLowUtil.ConvertToSet(ack));
- (* This should never happen, is already checked by while *)
- ASSERT(~contest.listInserted.DelPacket(packet));
- END;
- IF FillFifo(contest) THEN
- KernelLog.String("There was an error in FIllFifo"); KernelLog.Ln()
- END;
- (* KernelLog.String("Leaving process sent packets!"); KernelLog.Ln(); *)
- END ProcSentPckts;
- (** Processes dma receive buffers *)
- PROCEDURE ProcRcvdPckts(context: Contest);
- VAR block: FirewireLowUtil.Block; i, bufSize, packetSize, resCount,packetBytesLeft, packetBytesRight: LONGINT;
- bufferAddr, tCode,ack: SET; packetAddr,nextDesc: LONGINT; complete: BOOLEAN;
- BEGIN
- (* KernelLog.String("Entering ProcRcvdPckts"); KernelLog.Ln(); *)
- bufSize:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc)))*{0..15});
- resCount:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc) + 12))*{0..15});
- packetSize:= FirewireLowUtil.PacketLength(context);
- bufferAddr:= SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc) + 4));
- packetAddr:= ConvertToLongint(bufferAddr) + context.prgr.packetOffset;
- tCode:= SYSTEM.VAL(SET,LSH(SYSTEM.GET32(packetAddr),-4)) * {0..3};
- ASSERT(packetAddr > 0);
- (* dump packet
- i:=0;
- KernelLog.String("Dumping packet:"); KernelLog.Ln();
- WHILE i< packetSize DO
- quad:= SYSTEM.VAL(SET,SYSTEM.GET32(packetAddr +i));
- FirewireLowUtil.PrintSet(quad); INC(i,4);
- END; *)
- IF packetSize < 4 THEN (* Something is wrong, there must be an error *)
- KernelLog.String("The packet size is wrong::procRcvdPckts"); KernelLog.Ln();
- FirewireLowUtil.StopContext(context.ctrlClear);
- RETURN
- END;
- (* The first case handles packets that cross more than one buffer *)
- IF (context.prgr.packetOffset + packetSize) > bufSize THEN
- (* KernelLog.String("First case!"); KernelLog.Ln(); *)
- (* reassemble split packet in a new buffer and free the last one *)
- packetBytesLeft:= bufSize - context.prgr.packetOffset; i:= 0;
- ASSERT(packetBytesLeft <= FirewireLowUtil.BufSize);
- WHILE i < packetBytesLeft-1 DO
- SYSTEM.PUT32(ConvertToLongint(context.tempBuffer[0])+i,SYSTEM.GET32(packetAddr + i));
- INC(i,4)
- END;
- (* free this descriptor and its buffer to be reused *)
- block.end:= ConvertToLongint(context.prgr.curDesc);
- (* now go to next buffer/descriptor *)
- nextDesc:= SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc) + 8)-1; (* -1 to eliminate the z *)
- ASSERT(nextDesc > 0);
- bufSize:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(nextDesc))*{0..15});
- resCount:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(nextDesc + 12))*{0..15});
- packetBytesRight:= bufSize - resCount; i:= 0;
- ASSERT(packetAddr > 0);
- ASSERT(packetBytesRight <= FirewireLowUtil.BufSize-packetBytesLeft);
- WHILE i < packetBytesRight-1 DO
- SYSTEM.PUT32(ConvertToLongint(context.tempBuffer[0])+packetBytesLeft+i,SYSTEM.GET32(packetAddr + i));
- INC(i,4)
- END;
- context.prgr.curDesc:= SYSTEM.VAL(SET,nextDesc);
- ASSERT(ConvertToLongint(context.prgr.curDesc) > 0);
- block.start:= ConvertToLongint(context.prgr.curDesc);
- context.prgr.packetOffset:= bufSize-resCount;
- (* ok, we finished copying the packet into a safe place *)
- ELSE (* The packet is all in one buffer *)
- (* KernelLog.String("Second case"); KernelLog.Ln(); *)
- packetBytesLeft:= bufSize - context.prgr.packetOffset; i:= 0;
- ASSERT(packetBytesLeft <= FirewireLowUtil.BufSize);
- WHILE i < packetBytesLeft-1 DO
- SYSTEM.PUT32(ConvertToLongint(context.tempBuffer[0])+i,SYSTEM.GET32(packetAddr + i));
- INC(i,4)
- END;
- IF resCount = 0 THEN
- (* free this descriptor and its buffer to be reused *)
- block.end:= ConvertToLongint(context.prgr.curDesc);
- nextDesc:= SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc) + 8)-1;
- context.prgr.curDesc:= SYSTEM.VAL(SET,nextDesc);
- ASSERT(ConvertToLongint(context.prgr.curDesc) > 0);
- block.start:= ConvertToLongint(context.prgr.curDesc);
- END;
- context.prgr.packetOffset:= bufSize-resCount;
- END;
- IF (SYSTEM.VAL(LONGINT,tCode) = FirewireLowUtil.PhyARReq) THEN
- (* We always get this packet after bus reset, just throw it away *)
- (* i:=0;
- KernelLog.String("Dumping packet:"); KernelLog.Ln();
- WHILE i< packetSize DO
- quad:= SYSTEM.VAL(SET,SYSTEM.GET32(packetAddr +i));
- IF i= 12 THEN quad:= quad*{8..31}; KernelLog.Int(SYSTEM.VAL(LONGINT,LSH(quad,-8)),2);
- KernelLog.Ln()
- END;
- FirewireLowUtil.PrintSet(quad); INC(i,4);
- END;
- KernelLog.String("Discarding phy packet::ProcRcvdPckts"); KernelLog.Ln(); *)
- ELSE
- (* find out if we got an ack complete acknowledgement *)
- ack:= FirewireLowUtil.ReadReg(context.ctrlSet) * {0..4};
- IF ConvertToLongint(ack) = FirewireLowUtil.AckComplete THEN complete:= TRUE
- ELSE complete:= FALSE
- END;
- (* dump packet
- i:=0;
- KernelLog.String("Dumping packet:"); KernelLog.Ln();
- WHILE i< packetSize DO
- quad:= SYSTEM.VAL(SET,SYSTEM.GET32(packetAddr +i));
- IF i= 12 THEN quad:= quad*{8..31}; KernelLog.Int(SYSTEM.VAL(LONGINT,LSH(quad,-8)),2);
- KernelLog.Ln()
- END;
- FirewireLowUtil.PrintSet(quad); INC(i,4);
- END; *)
- PacketReceived(context,context.tempBuffer[0], packetSize, complete);
- END;
- (* KernelLog.String("Leaving ProcRcvdPckts"); KernelLog.Ln(); *)
- END ProcRcvdPckts;
- (** Frees unused DMA buffers of receive contexts *)
- PROCEDURE FreeDMABuffer(context:Contest);
- VAR curDesc: LONGINT; active: LONGINT;
- BEGIN
- active:= 10;
- curDesc:= ConvertToLongint(context.prgr.curDesc);
- ASSERT(ConvertToLongint(context.prgr.curDesc) > 0);
- context.prgr.SetBranchAddress(curDesc+1,curDesc+8,context.prgr.ptrToBuf);
- context.buffers.FreeBuffer(SYSTEM.VAL(SET,SYSTEM.GET32(curDesc + 4)));
- (* wake up the context if necessary *)
- IF ~(active IN FirewireLowUtil.ReadReg(context.ctrlSet)) THEN
- (* KernelLog.String("Waking context "); KernelLog.String(context.name); KernelLog.String("!"); KernelLog.Ln() *)
- END;
- (* Always wake it up, to avoid race conditions *)
- FirewireLowUtil.WriteReg(context.ctrlSet,{12});
- END FreeDMABuffer;
- (** Checks the transaction code of a received packet to see if its a response or request packet *)
- PROCEDURE PacketReceived(context: Contest; bufferAddr:SET; packetSize: LONGINT; complete: BOOLEAN);
- VAR tCode: LONGINT;
- BEGIN
- (* KernelLog.String("Entering Packet received"); KernelLog.Ln(); *)
- IF OHCI.inBusReset THEN KernelLog.String("Ignoring packet, because OHCI is in bus reset!"); RETURN END;
- (* get tCode *)
- tCode:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,LSH(SYSTEM.GET32(ConvertToLongint(bufferAddr)),-4))*{0..3});
- (* KernelLog.String("The transaction code is: ");KernelLog.Int(tCode,2); KernelLog.Ln(); *)
- CASE tCode OF
- FirewireLowUtil.NoDataWARRes: HandlePacketResponse(context,bufferAddr,packetSize,tCode)
- |FirewireLowUtil.QReadARRes: HandlePacketResponse(context,bufferAddr,packetSize,tCode)
- |FirewireLowUtil.BReadARRes: HandlePacketResponse(context,bufferAddr,packetSize,tCode)
- |FirewireLowUtil.LockARRes: HandlePacketResponse(context,bufferAddr,packetSize,tCode)
- |FirewireLowUtil.QWriteARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
- |FirewireLowUtil.BWriteARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
- |FirewireLowUtil.NoDataQRARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
- |FirewireLowUtil.BReadARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
- |FirewireLowUtil.LockARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
- |FirewireLowUtil.IRCode: KernelLog.String("Received iso packet: NOT YET IMPLEMENTED!");
- KernelLog.Ln()
- |FirewireLowUtil.CycleStartCode: (* Just ignore *) (* KernelLog.String("Cycle start packet ignored!");
- KernelLog.Ln() *)
- ELSE KernelLog.String("Received bad tCode for a packet!"); KernelLog.Ln()
- END;
- (* KernelLog.String("Leaving Packet received"); KernelLog.Ln(); *)
- END PacketReceived;
- (** Creates a reply packet to read or write requests *)
- PROCEDURE CreateReplyPacket(VAR p: FirewireLowUtil.OHCIPacket; dataAddr: LONGINT; dataSize: LONGINT);
- BEGIN
- (* KernelLog.String("Data size in CreateReaplyPacket is: "); KernelLog.Int(dataSize,2); KernelLog.Ln(); *)
- p:= OHCI.packetFIFO.GetPacket();
- p.dataSize:= dataSize;
- (* reset packet *)
- FirewireLowUtil.ResetPacket(p);
- p.type:= FirewireLowUtil.async;
- p.state:= FirewireLowUtil.UNUSED;
- p.host:= OHCI;
- p.nodeID:= SYSTEM.VAL(SET,LSH(SYSTEM.GET32(dataAddr+4),-16))*{0..5};
- p.tLabel:= SYSTEM.VAL(SET,LSH(SYSTEM.GET32(dataAddr),-10))*{0..5};
- p.generation:= FirewireLowUtil.GetGeneration();
- p.respExpected:= FALSE;
- END CreateReplyPacket;
- (** Writes packet data to a host memory address *)
- PROCEDURE WriteToAddress(dataAddr: LONGINT; dataLen: LONGINT; writeAddrLo, writeAddrHi: SET):LONGINT;
- VAR i: LONGINT;
- BEGIN
- (* KernelLog.String("WriteToAddress!"); KernelLog.Ln();
- KernelLog.String("Printing the address"); KernelLog.Ln();
- FirewireLowUtil.PrintSet(writeAddrLo);
- FirewireLowUtil.PrintSet(writeAddrHi); *)
- i:= 0;
- IF writeAddrHi*{0..15} # {} THEN
- RETURN FirewireLowUtil.respAddressError
- ELSIF ~OHCI.adrCheck.Find(ConvertToLongint(writeAddrLo)) THEN HALT(55);
- ELSE
- FOR i:= 0 TO dataLen-1 DO
- SYSTEM.PUT32(ConvertToLongint(writeAddrLo)+i*4,SYSTEM.GET32(dataAddr+i*4))
- END
- END;
- RETURN FirewireLowUtil.respComplete;
- END WriteToAddress;
- (** Reads packet data from a host memory address *)
- PROCEDURE ReadFromAddress(VAR bufferAddr: ARRAY OF SET; dataLen: LONGINT; readAddrLo, readAddrHi: SET): LONGINT;
- VAR i: LONGINT;
- BEGIN
- (* KernelLog.String("ReadFromAddress!"); KernelLog.Ln();
- KernelLog.String("Printing the address"); KernelLog.Ln();
- FirewireLowUtil.PrintSet(readAddrLo);
- FirewireLowUtil.PrintSet(readAddrHi); *)
- i:= 0;
- FOR i:= 0 TO dataLen-1 DO
- bufferAddr[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(readAddrLo)+i*4));
- (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(readAddrLo)+i*4))); *)
- END;
- RETURN FirewireLowUtil.respComplete;
- END ReadFromAddress;
- (** Handles incoming requests *)
- PROCEDURE HandleIncomingPacket(bufferAddr: SET; packetSize, tCode: LONGINT; complete: BOOLEAN);
- VAR addrHi,addrLo: SET; rCode,dataLen,addr: LONGINT; packet: FirewireLowUtil.OHCIPacket; respBufferAddr: LONGINT;
- respQuadlet: ARRAY 1 OF SET;
- BEGIN
- (* KernelLog.String("Entered routine HandleIcomingPacket!"); KernelLog.Ln(); *)
- addr:= ConvertToLongint(bufferAddr);
- CASE tCode OF
- FirewireLowUtil.QWriteARReq:
- (* KernelLog.String("It's a quadlet write request!"); KernelLog.Ln(); *)
- addrLo:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+8));
- addrHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
- rCode:= WriteToAddress(addr+12,1,addrLo,addrHi);
- IF ~complete THEN
- CreateReplyPacket(packet,addr,0);
- FirewireLowUtil.FillAsyncWriteResp(packet,rCode);
- IF SendPacket1394(OHCI.ATController.GetResContest(),packet) THEN
- (* KernelLog.String("Response successfully sent"); KernelLog.Ln() *)
- ELSE KernelLog.String("Response could not be sent"); KernelLog.Ln()
- END
- END
- |FirewireLowUtil.BWriteARReq:
- (* KernelLog.String("It's a block write request!"); KernelLog.Ln(); *)
- addrLo:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+8));
- addrHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
- dataLen:= (LSH(SYSTEM.GET32(addr+12),-16));
- rCode:= WriteToAddress(addr+16,(dataLen DIV 4),addrLo,addrHi);
- IF ~complete THEN
- CreateReplyPacket(packet,addr,0);
- FirewireLowUtil.FillAsyncWriteResp(packet,rCode);
- IF SendPacket1394(OHCI.ATController.GetResContest(),packet) THEN
- (* KernelLog.String("Response successfully sent"); KernelLog.Ln() *)
- ELSE KernelLog.String("Response could not be sent"); KernelLog.Ln()
- END
- END
- |FirewireLowUtil.NoDataQRARReq:
- (* KernelLog.String("It's a quadlet read request!"); KernelLog.Ln(); *)
- addrLo:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+8));
- addrHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
- rCode:= ReadFromAddress(respQuadlet,1,addrLo,addrHi);
- CreateReplyPacket(packet,addr,0);
- FirewireLowUtil.FillAsyncReadQuadResp(packet,rCode,respBufferAddr);
- IF SendPacket1394(OHCI.ATController.GetResContest(),packet) THEN
- (* KernelLog.String("Response successfully sent"); KernelLog.Ln() *)
- ELSE KernelLog.String("Response could not be sent"); KernelLog.Ln()
- END
- |FirewireLowUtil.BReadARReq:
- (* KernelLog.String("It's a block read request!"); KernelLog.Ln(); *)
- dataLen:= (LSH(SYSTEM.GET32(addr+12),-16));
- CreateReplyPacket(packet,addr,dataLen);
- addrLo:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+8));
- addrHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
- rCode:= ReadFromAddress(packet.data^,(dataLen DIV 4),addrLo,addrHi);
- FirewireLowUtil.FillAsyncReadBlockResp(packet,rCode,dataLen);
- IF SendPacket1394(OHCI.ATController.GetResContest(),packet) THEN
- (* KernelLog.String("Response successfully sent"); KernelLog.Ln() *)
- ELSE KernelLog.String("Response could not be sent"); KernelLog.Ln()
- END
- |FirewireLowUtil.LockARReq:
- ELSE KernelLog.String("This request is not supported!"); KernelLog.Ln();
- END;
- END HandleIncomingPacket;
- (** Handles incoming packet responses *)
- PROCEDURE HandlePacketResponse(respContext: Contest; bufferAddr: SET; packetSize, tCode: LONGINT);
- VAR oneBack,temp: POINTER TO ListMember; tLabel, nodeID: SET; found, tCodeMatch: BOOLEAN; packet: OHCIPacket;
- data: LONGINT; i: LONGINT; context: Contest; n: FirewireLowUtil.FIFONode;
- BEGIN
- (* KernelLog.String("Entering handle packet response!"); KernelLog.Ln(); *)
- context:= OHCI.ATController.GetReqContest();
- (* Find the request packet corresponding to this response *)
- found:= FALSE;
- oneBack:= context.listAwaiting.head;
- temp:= oneBack.next;
- nodeID:= SYSTEM.VAL(SET,LSH(SYSTEM.GET32(ConvertToLongint(bufferAddr)+4),-16))*{0..5};
- tLabel:= SYSTEM.VAL(SET,LSH(SYSTEM.GET32(ConvertToLongint(bufferAddr)),-10))*{0..5};
- (* KernelLog.String("Printing the transaction label of the response packet!"); KernelLog.Ln();
- FirewireLowUtil.PrintSet(tLabel); *)
- IF ~context.listAwaiting.GetPacket(packet) THEN
- (* KernelLog.String("Printing the request packet name: "); KernelLog.String(packet.name); KernelLog.Ln();
- KernelLog.String("Printing the request packet transaction label: "); FirewireLowUtil.PrintSet(packet.tLabel); *)
- ELSE
- KernelLog.String("We have a problem"); KernelLog.Ln()
- END;
- WHILE (temp # NIL) & ~(found) DO (*
- KernelLog.String("Comparing the transaction label"); KernelLog.Ln();
- FirewireLowUtil.PrintSet(temp.data.tLabel);
- FirewireLowUtil.PrintSet(tLabel);
- KernelLog.String("Comparing the node id"); KernelLog.Ln();
- FirewireLowUtil.PrintSet(temp.data.nodeID); FirewireLowUtil.PrintSet(nodeID); *)
- IF (temp.data.tLabel = tLabel) & (temp.data.nodeID = nodeID) THEN
- found:= TRUE; packet:= temp.data; (* KernelLog.String("name of the packet is: ");
- KernelLog.String(temp.data.name); KernelLog.Ln(); *)
- ELSE oneBack:= temp; temp:= temp.next
- END
- END;
- IF ~found THEN KernelLog.String("This packet was not expected, no tLabel match"); KernelLog.Ln();
- RETURN
- END;
- (*
- KernelLog.String("Dumping packet: "); KernelLog.Ln();
- KernelLog.String("The packet name is: "); KernelLog.String(packet.name); KernelLog.Ln();
- FOR i:= 0 TO (packet.headerSize DIV 4)-1 DO
- FirewireLowUtil.PrintSet(packet.header[i]);
- END; i:= 0;
- KernelLog.String("The transaction code is: "); KernelLog.Int(tCode,2); KernelLog.Ln();
- KernelLog.String("The packet transaction code is: "); KernelLog.Int(SYSTEM.VAL(LONGINT,packet.tCode),2); KernelLog.Ln();
- *)
- CASE SYSTEM.VAL(LONGINT,packet.tCode) OF
- FirewireLowUtil.QWriteATReq:
- IF (tCode = FirewireLowUtil.NoDataWARRes) THEN tCodeMatch:= TRUE END
- |FirewireLowUtil.BWriteATReq:
- IF (tCode = FirewireLowUtil.NoDataWARRes) THEN tCodeMatch:= TRUE END
- |FirewireLowUtil.BReadATReq:
- IF (tCode = FirewireLowUtil.BReadARRes) THEN tCodeMatch:= TRUE END
- |FirewireLowUtil.NoDataWATReq:
- IF (tCode = FirewireLowUtil.QReadARRes) THEN tCodeMatch:= TRUE END
- |FirewireLowUtil.LockATReq:
- IF (tCode = FirewireLowUtil.LockARRes) THEN tCodeMatch:= TRUE END
- END;
- IF (~tCodeMatch OR (packet.tLabel # tLabel)) OR (packet.nodeID # nodeID) THEN
- IF tCodeMatch THEN (* KernelLog.String("Transaction code matched!"); KernelLog.Ln() *)
- ELSE KernelLog.String("Transaction code didn't match: "); FirewireLowUtil.PrintSet(packet.tCode);
- FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,tCode)); KernelLog.Ln()
- END;
- KernelLog.String("This packet was not expected, tcode mismatch!"); RETURN
- END;
- IF found THEN (* delete packet from list *)
- IF oneBack = temp THEN (* It's the first object in the list *)
- context.listAwaiting.head:= context.listAwaiting.head.next
- ELSE oneBack.next:= temp.next;
- IF context.listAwaiting.last = temp THEN
- context.listAwaiting.last:= oneBack END;
- END;
- temp.next:= NIL;
- n:= context.listAwaiting.usedList.DequeuedNode(context.listAwaiting.usedQ);
- n.pListMember:= temp;
- context.listAwaiting.list.Enqueue(context.listAwaiting.q,n);
- END;
- data:= ConvertToLongint(bufferAddr);
- CASE tCode OF
- FirewireLowUtil.NoDataWARRes:
- packet.header[0]:= SYSTEM.VAL(SET,SYSTEM.GET32(data));
- packet.header[1]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 4));
- packet.header[2]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 8));
- |FirewireLowUtil.QReadARRes:
- packet.header[0]:= SYSTEM.VAL(SET,SYSTEM.GET32(data));
- packet.header[1]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 4));
- packet.header[2]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 8));
- packet.header[3]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 12));
- |FirewireLowUtil.BReadARRes:
- packet.header[0]:= SYSTEM.VAL(SET,SYSTEM.GET32(data));
- packet.header[1]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 4));
- packet.header[2]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 8));
- packet.header[3]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 12));
- FOR i:= 0 TO ((packetSize-16) DIV 4)-1 DO
- packet.data[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(data+16+i*4))
- END
- |FirewireLowUtil.LockARRes:
- packet.header[0]:= SYSTEM.VAL(SET,SYSTEM.GET32(data));
- packet.header[1]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 4));
- packet.header[2]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 8));
- packet.header[3]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 12));
- IF packetSize-16 > 8 THEN
- FOR i:= 0 TO (8 DIV 4)-1 DO
- packet.data[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(data+16+i*4))
- END
- ELSE
- FOR i:= 0 TO ((packetSize-16) DIV 4)-1 DO
- packet.data[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(data+16+i*4));
- END
- END
- END;
- BEGIN{EXCLUSIVE}
- packet.state:= FirewireLowUtil.COMPLETE;
- END;
- packet.pending:= FALSE;
- OHCI.labeler.FreeTransLabel(packet.tLabel);
- (* now free buffer if needed *)
- IF packet.dataSize > 0 THEN
- (* KernelLog.String("Freeing buffer!"); KernelLog.Ln(); *)
- respContext.buffers.FreeBuffer(SYSTEM.VAL(SET,SYSTEM.GET32(packet.block.start+36)))
- END;
- PacketComplete(context,packet);
- (* KernelLog.String("Leaving handle packet response!"); KernelLog.Ln(); *)
- END HandlePacketResponse;
- (** This function is unused *)
- PROCEDURE PacketComplete(context: Contest; VAR packet: OHCIPacket);
- (* This function is basically used if a custom routine has to handle the packet
- else this packet will just return to the calling routine *)
- END PacketComplete;
- (** This function checks if the packet expects a response or finished and accordingly adds the packet to the
- response await list *)
- PROCEDURE PacketSent(context:Contest;VAR packet: OHCIPacket; ack: SET);
- BEGIN
- packet.ack:= ack;
- IF packet.respExpected & (packet.ack # {0,4}) THEN (* KernelLog.String("Packet is pending!"); KernelLog.Ln(); *)
- packet.pending:= TRUE; context.listAwaiting.AddPacket(packet) (* This list will be traversed in handlePacketResponse *)
- ELSE packet.pending:= FALSE; packet.state:= FirewireLowUtil.COMPLETE; OHCI.labeler.FreeTransLabel(packet.tLabel);
- (* KernelLog.String("{{{{{{{{{{{{{{{{{{{{{{{{{Packet is complete}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}"); KernelLog.Ln(); *)
- END;
- END PacketSent;
- (** This is the interrupt handler *)
- PROCEDURE HandleInterrupt;
- VAR status, reg, nodeID: SET; ctx,i: LONGINT; root, error: BOOLEAN;
- CONST dead= 11; isValid= 31; id= {0..5}; isRoot= 30;
- BEGIN
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{31});
- status := FirewireLowUtil.ReadReg(FirewireLowUtil.CIntEvent);
- (* KernelLog.String("@@@@@@ Entering interrupt handler @@@@@@"); KernelLog.Ln(); *)
- IF reqTxComplete IN status THEN
- (* KernelLog.String("Completion of an AT DMA request OUTPUT-LAST* command"); KernelLog.Ln(); *)
- (* Read the status of the AT response context control register *)
- reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ATReqContCtrlSet);
- (* KernelLog.String("Printing the status of the AT request context control register: ");
- FirewireLowUtil.PrintSet(reg); *)
- IF (dead IN reg) THEN (* KernelLog.String("Context died"); KernelLog.Ln(); *) FirewireLowUtil.StopContext(FirewireLowUtil.ATReqContCtrlClear);
- ELSE ProcSentPckts(OHCI.ATController.GetReqContest()) END;
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{reqTxComplete});
- END;
- IF respTxComplete IN status THEN
- (* KernelLog.String("Completion of an AT DMA response OUTPUT-LAST* command "); KernelLog.Ln(); *)
- (* Read the status of the AT response context control register *)
- reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ATResContCtrlSet);
- (* KernelLog.String("Printing the status of the AT response context control register: ");
- FirewireLowUtil.PrintSet(reg); *)
- IF (dead IN reg) THEN FirewireLowUtil.StopContext(FirewireLowUtil.ATResContCtrlClear);
- ELSE ProcSentPckts(OHCI.ATController.GetResContest()) END;
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{respTxComplete});
- END;
- IF ARRQ IN status THEN
- (* KernelLog.String("Completion of an AR DMA Request context command descriptor "); KernelLog.Ln(); *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{ARRQ});
- END;
- IF ARRS IN status THEN
- (* KernelLog.String("Completion of an AR DMA Response context command descriptor "); KernelLog.Ln(); *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{ARRS});
- END;
- IF RQPkt IN status THEN
- (* KernelLog.String("A packet was sent to an asynchronous receive request context buffer "); KernelLog.Ln();
- KernelLog.String("*****************************************************************"); KernelLog.Ln(); *)
- (* Read the status of the AT response context control register *)
- reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ARReqContCtrlSet);
- (* KernelLog.String("Printing the status of the AR request context control register: ");
- FirewireLowUtil.PrintSet(reg); *)
- IF (dead IN reg) THEN FirewireLowUtil.StopContext(FirewireLowUtil.ARReqContCtrlClear);
- ELSE ProcRcvdPckts(OHCI.ARController.GetReqContest()) END;
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{RQPkt});
- END;
- IF RSPkt IN status THEN
- (* KernelLog.String("A packet was sent to an asynchronous receive response context buffer "); KernelLog.Ln(); *)
- (* Read the status of the AT response context control register *)
- reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ARResContCtrlSet);
- (* KernelLog.String("Printing the status of the AR response context control register: ");
- FirewireLowUtil.PrintSet(reg); *)
- IF (dead IN reg) THEN (* KernelLog.String("Context died"); KernelLog.Ln(); *) FirewireLowUtil.StopContext(FirewireLowUtil.ARResContCtrlClear);
- ELSE ProcRcvdPckts(OHCI.ARController.GetResContest()) END;
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{RSPkt});
- END;
- IF isochTx IN status THEN
- (* KernelLog.String("One or more isochronous Transmit contexts have generated an interrupt"); KernelLog.Ln(); *)
- reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochXmitIntEvntSet);
- FirewireLowUtil.WriteReg(FirewireLowUtil.isochXmitIntEvntClear,reg);
- IsoSchedule(reg);
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{isochTx});
- END;
- IF isochRx IN status THEN
- (* KernelLog.String("One or more isochronous Receive contexts have generated an interrupt "); KernelLog.Ln(); *)
- reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochRecvIntEvntSet);
- IsoSchedule(reg);
- FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvIntEvntClear,reg);
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{isochRx});
- END;
- IF postedWriteErr IN status THEN
- KernelLog.String("A host bus error occurred"); KernelLog.Ln();
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{postedWriteErr});
- END;
- IF lockRespErr IN status THEN
- KernelLog.String("Host controller attempted to return a lock response without receiving an ack"); KernelLog.Ln();
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{lockRespErr});
- END;
- IF busReset IN status THEN
- (* Masking out the interrupt *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{busReset});
- IF ~OHCI.inBusReset THEN (* KernelLog.String("bus Reset Interrupt was thrown"); KernelLog.Ln(); *)
- OHCI.inBusReset:= TRUE;
- ELSE KernelLog.String("bus Reset Interrupt was thrown while already in progress"); KernelLog.Ln();
- END;
- END;
- IF selfIDComplete2 IN status THEN
- (* KernelLog.String("Secondary indication of the end of a selfID packet stream "); KernelLog.Ln(); *)
- (* should not be cleared *)
- END;
- IF selfIDComplete IN status THEN
- error:= FALSE;
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{selfIDComplete});
- IF OHCI.inBusReset THEN
- (* KernelLog.String("Indication of the end of a selfID packet stream "); KernelLog.Ln(); *)
- reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID);
- (* FirewireLowUtil.PrintNodeInfo(); *)
- IF isValid IN reg THEN
- (* KernelLog.String("Self id is valid, check self id buffer!"); KernelLog.Ln(); *)
- IF isRoot IN reg THEN root:= TRUE; OHCI.IsRoot:= TRUE END;
- nodeID:= reg*id;
- IF CheckSelfIDStream() THEN error:= TRUE END;
- ELSE KernelLog.String("Self id is not valid, do not check self id buffer!"); KernelLog.Ln()
- END;
- (* Clear busreset event and reenable the busreset interrupt *)
- (* KernelLog.String("Reenabling bus interrupt"); KernelLog.Ln(); *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{busReset});
- FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{busReset});
- (* Accept physical requests from all nodes *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.ARFilterHISet, {0..31});
- FirewireLowUtil.WriteReg(FirewireLowUtil.ARFilterLowSet, {0..31});
- (* Turning on physical dma reception *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.PRFilterHiSet, {0..31});
- FirewireLowUtil.WriteReg(FirewireLowUtil.PRFilterLowSet, {0..31});
- FirewireLowUtil.WriteReg(FirewireLowUtil.PhyUpperBound, {16..31});
- IF OHCI.inBusReset THEN OHCI.inBusReset:= FALSE;
- ELSE KernelLog.String("This should not happen!"); KernelLog.Ln(); END;
- IF error THEN FirewireLowUtil.SetPhyControl({8},{6})
- ELSE (* Go on and build the maps *)
- OHCI.nodeID:= SYSTEM.VAL(LONGINT,FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID)*{0..5});
- BuildMaps(); BEGIN {EXCLUSIVE} OHCI.selfIDComplete:= TRUE; END;
- END;
- ELSE KernelLog.String("SelfID received outside of bus reset"); KernelLog.Ln() END;
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{selfIDComplete});
- FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{selfIDComplete});
- END;
- IF regAccessFail IN status THEN
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{regAccessFail});
- KernelLog.String("Open HCI register access failed "); KernelLog.Ln();
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{regAccessFail});
- FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{regAccessFail});
- END;
- IF phy IN status THEN
- KernelLog.String("phy requests an interrupt"); KernelLog.Ln();
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{phy});
- END;
- IF cycleSynch IN status THEN
- (* KernelLog.String("A new isochronous cycle has started"); KernelLog.Ln(); *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycleSynch});
- END;
- IF cycle64Seconds IN status THEN
- (* KernelLog.String("The 7th bit of the cycle second counter has changed "); KernelLog.Ln(); *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycle64Seconds});
- END;
- IF cycleLost IN status THEN
- KernelLog.String("No cyclestart packet is sent/received "); KernelLog.Ln();
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycleLost});
- END;
- IF cycleInconsistent IN status THEN
- (* Nothing has to be done, just clear the bit *)
- KernelLog.String("An inconsistent cycle start was received"); KernelLog.Ln();
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycleInconsistent});
- END;
- IF unrecoverableError IN status THEN
- KernelLog.String("Host controller encountered an unrecoverable error"); KernelLog.Ln();
- (* Asynchronous transmit request context *)
- reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ATReqContCtrlSet);
- IF dead IN reg THEN KernelLog.String("The asynchronous transmit request context died!"); KernelLog.Ln();
- KernelLog.String("With event code: "); reg:= reg*{0..4}; FirewireLowUtil.PrintSet(reg); KernelLog.Ln();
- KernelLog.String("The register content is: "); FirewireLowUtil.StopContext(FirewireLowUtil.ATReqContCtrlClear);
- FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(FirewireLowUtil.ATReqContCtrlSet)); KernelLog.Ln();
- END;
- (* Asynchronous transmit response context *)
- reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ATResContCtrlSet);
- IF dead IN reg THEN KernelLog.String("The asynchronous transmit response context died!"); KernelLog.Ln() END;
- (* Asynchronous receive request context *)
- reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ARReqContCtrlSet);
- IF dead IN reg THEN KernelLog.String("The asynchronous receive request context died!"); KernelLog.Ln() END;
- (* Asynchronous receive response context *)
- reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ARResContCtrlSet);
- IF dead IN reg THEN KernelLog.String("The asynchronous receive response context died!"); KernelLog.Ln() END;
- (* Isochronous transmit context control *)
- ctx:= FirewireLowUtil.GetAvailableITCont();
- FOR i:= 0 TO ctx-1 DO
- reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochXmitCntCtrlSet + i*16);
- IF dead IN reg THEN KernelLog.String("The isochronous transmit context "); KernelLog.Int(i,2); KernelLog.String(" died!");
- KernelLog.Ln()
- END
- END;
- (* Isochronous receive context control *)
- ctx:= FirewireLowUtil.GetAvailableIRCont();
- FOR i:= 0 TO ctx-1 DO
- reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochRecvCntCtrlSet + i*32);
- IF dead IN reg THEN KernelLog.String("The isochronous receive context "); KernelLog.Int(i,2); KernelLog.String(" died!");
- KernelLog.Ln()
- END
- END;
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{unrecoverableError});
- END;
- IF cycleTooLong IN status THEN
- KernelLog.String("An isochronous cycle lasted longer than the allotted time"); KernelLog.Ln();
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycleTooLong});
- END;
- IF ackTardy IN status THEN
- KernelLog.String("HCControl.ackTardyEnable is set to one and other conditions occur"); KernelLog.Ln();
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{ackTardy});
- END;
- IF softInterrupt IN status THEN
- (* KernelLog.String("Software Interrupt"); KernelLog.Ln(); *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{softInterrupt});
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{softInterrupt});
- FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{softInterrupt});
- END;
- IF phyRegRcvd IN status THEN
- (* KernelLog.String("OHCI has received a register data byte"); KernelLog.Ln(); *)
- (* Masking out the interrupt *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{phyRegRcvd});
- (* Clearing the interrupt *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{phyRegRcvd});
- (* Enabling the interrupt *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{phyRegRcvd});
- END;
- (* Enabling all interrupts *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{31});
- (* KernelLog.String("@@@@@@ Leaving interrupt handler @@@@@@"); KernelLog.Ln(); *)
- END HandleInterrupt;
- (** Builds the descriptor list to send a packet over the 1394 bus *)
- PROCEDURE SendPacket(contest: Contest; VAR packet : OHCIPacket; z: LONGINT);
- VAR cycleTimer: SET; desc,descLast: FirewireLowUtil.GeneralDesc; descOMI: FirewireLowUtil.OutputMoreImmediate;
- descOL: FirewireLowUtil.OutputLast; descOLI: FirewireLowUtil.OutputLastImmediate; block: FirewireLowUtil.Block;
- branchAddressPtr: ADDRESS; ptrToBuf: FirewireLowUtil.CharBuffer;
- BEGIN
- (* KernelLog.String("Sending packet to node: "); KernelLog.Int(SYSTEM.VAL(LONGINT,packet.nodeID),2); KernelLog.Ln(); *)
- desc.address := {};
- desc.branchAddress := {};
- IF contest.type = FirewireLowUtil.RES THEN
- (* KernelLog.String("Setting the timeout::SendPacket"); KernelLog.Ln(); *)
- (* I choose the maximum time out value: 3 sec *)
- cycleTimer:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochCycleTimer);
- desc.status:= LSH(cycleTimer*{12..24},-12) +
- FirewireLowUtil.ConvertToSet(LSH(LSH(ConvertToLongint(cycleTimer),-25)+3,13));
- ELSE desc.status:= {};
- END;
- IF (packet.type = FirewireLowUtil.async) OR (packet.type = FirewireLowUtil.raw) THEN
- descOMI:= FirewireLowUtil.GetAOMIDesc();
- descOL:= FirewireLowUtil.GetAOLDesc();
- descOLI:= FirewireLowUtil.GetAOLIDesc();
- (* KernelLog.String("Packet type is asynchronous or raw::SendPacket"); KernelLog.Ln(); *)
- IF packet.type = FirewireLowUtil.raw THEN
- (* KernelLog.String("Packet type is raw"); KernelLog.Ln(); *)
- desc.data[0]:= FirewireLowUtil.ConvertToSet(LSH(FirewireLowUtil.PhyATReq,4));
- desc.data[1]:= packet.header[0];
- desc.data[2]:= packet.header[1];
- ELSE (* KernelLog.String("Packet type is asynchronous"); KernelLog.Ln(); *)
- desc.data[0]:= LSH(packet.speed,16) + {23} +
- packet.header[0]*{0..15}; (* mask the first 16 bit of a packet header *)
- IF SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.StreamATReq THEN
- (* KernelLog.String("Sending an asynchronous stream packet"); KernelLog.Ln(); *)
- (* Sending an asynchronous stream packet *)
- desc.data[1]:= packet.header[0] * {16..31}; desc.data[0]:= desc.data[0] - {23}
- ELSE (* sending a normal async packet: request or response *)
- (* KernelLog.String("Sending a normal asynchronous packet"); KernelLog.Ln(); *)
- desc.data[1]:= packet.header[1] * {0..15} + packet.header[0] * {16..31};
- desc.data[2]:= packet.header[2]; desc.data[3]:= packet.header[3]
- END;
- END;
- IF packet.dataSize > 0 THEN (* block or stream transmit *)
- (* KernelLog.String("DataSize is bigger than zero: this is a block or stream transmit"); KernelLog.Ln(); *)
- IF SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.StreamATReq THEN
- (* KernelLog.String("It's a stream packet!"); KernelLog.Ln(); *)
- desc.control:= descOMI.key + {3}; (* two header quadlets for stream packets *)
- ELSE (* 4 header quadlets for block packets *)
- (* KernelLog.String("It's a block packet"); KernelLog.Ln(); *)
- desc.control:= descOMI.key + {4}
- END;
- descLast.control:= descOL.cmd + descOL.i + descOL.b +
- FirewireLowUtil.ConvertToSet(packet.dataSize);
- (* check if packet buffer crosses page boundaries *)
- (* KernelLog.String("Checking if packet crosses page size"); KernelLog.Ln(); *)
- ASSERT(packet.dataSize < FirewireLowUtil.BufSize);
- descLast.address:= FirewireLowUtil.AllocPacket(packet.data^,packet.dataSize,ADDRESSOF(OHCI.tempBuffer[0]));
- descLast.branchAddress:= {}; descLast.status:= {};
- ELSE (* quadlet or no data trasmit *)
- (* KernelLog.String("This is a quadlet or no data transmit, dataSize is zero"); KernelLog.Ln(); *)
- IF packet.type = FirewireLowUtil.raw THEN (* quadlet transmit *)
- (* KernelLog.String("This is quadlet transmit"); KernelLog.Ln(); *)
- desc.control:= descOLI.cmd + descOLI.key + descOLI.b + descOLI.i +
- FirewireLowUtil.ConvertToSet(packet.headerSize + 4)
- ELSE (* no data transmit *)
- (* KernelLog.String("This is a no data transmit"); KernelLog.Ln(); *)
- desc.control:= descOLI.cmd + descOLI.key + descOLI.b + descOLI.i +
- FirewireLowUtil.ConvertToSet(packet.headerSize)
- END
- END
- ELSE (* iso packet *)
- descOMI:= FirewireLowUtil.GetIOMIDesc();
- descOL:= FirewireLowUtil.GetIOLDesc();
- KernelLog.String("We have an iso packet"); KernelLog.Ln();
- desc.data[0]:= packet.header[0]*{0..15} +
- LSH(packet.speed,16);
- desc.data[1]:= packet.header[0]*{16..31};
- desc.control:= descOMI.key + {3};
- descLast.control:= descOL.cmd + descOL.b + descOL.i +
- FirewireLowUtil.ConvertToSet(packet.dataSize);
- descLast.address:= FirewireLowUtil.AllocPacket(packet.data^,packet.dataSize,ADDRESSOF(OHCI.tempBuffer[0]));
- descLast.branchAddress:= {}; descLast.status:= {};
- END;
- (* write descriptor block in program buffer *)
- (* KernelLog.String("Writing descriptor block in program buffer!"); KernelLog.Ln(); *)
- block.start:= packet.blockBufferAddr;
- (* KernelLog.String("Printing the block.start address!");
- KernelLog.Int(block.start,2); KernelLog.Ln(); *) ASSERT(block.start > 0);
- (* KernelLog.String("Putting first quadlet at address: "); *)(* KernelLog.Int(block.start,2); *) (* KernelLog.Ln(); *)
- SYSTEM.PUT32(block.start, desc.control); (* FirewireLowUtil.PrintSet(desc.control); *)
- SYSTEM.PUT32(block.start + 4, desc.address); (* FirewireLowUtil.PrintSet(desc.address); *)
- (* KernelLog.String("Putting second quadlet at address: "); KernelLog.Ln(); *)
- SYSTEM.PUT32(block.start + 8, desc.branchAddress); (* FirewireLowUtil.PrintSet(desc.branchAddress); *)
- SYSTEM.PUT32(block.start + 12, desc.status); (* FirewireLowUtil.PrintSet(desc.status); *)
- (* KernelLog.String("Putting third quadlet at address: "); KernelLog.Ln(); *)
- SYSTEM.PUT32(block.start + 16, desc.data[0]); (* FirewireLowUtil.PrintSet(desc.data[0]); *)
- SYSTEM.PUT32(block.start + 20, desc.data[1]); (* FirewireLowUtil.PrintSet(desc.data[1]); *)
- (* KernelLog.String("Putting forth quadlet at address: "); KernelLog.Ln(); *)
- SYSTEM.PUT32(block.start + 24, desc.data[2]); (* FirewireLowUtil.PrintSet(desc.data[2]); *)
- SYSTEM.PUT32(block.start + 28, desc.data[3]); (* FirewireLowUtil.PrintSet(desc.data[3]); *)
- IF packet.dataSize > 0 THEN
- (* KernelLog.String("DataSize is bigger than zero");KernelLog.Ln(); *)
- SYSTEM.PUT32(block.start + 32, descLast.control); (* FirewireLowUtil.PrintSet(descLast.control); *)
- SYSTEM.PUT32(block.start + 36, descLast.address); (* FirewireLowUtil.PrintSet(descLast.address); *)
- SYSTEM.PUT32(block.start + 40, descLast.branchAddress); (* FirewireLowUtil.PrintSet(descLast.branchAddress); *)
- SYSTEM.PUT32(block.start + 44, descLast.status); (* FirewireLowUtil.PrintSet(descLast.status); *)
- (* Dump data in buffer *)
- (* KernelLog.String("Dumping the data in buffer::SendPacket"); KernelLog.Ln();
- i:= 0;
- WHILE i< (packet.dataSize-1) DO
- FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,descLast.address)+i)));INC(i,4);
- END; *)
- branchAddressPtr:= block.start + 40; block.end:= block.start + 32;
- ptrToBuf:= packet.ptrToBlckBufAddr;
- ELSE
- branchAddressPtr:= block.start + 8; block.end:= block.start; (* This block is just one desc long *)
- ptrToBuf:= packet.ptrToBlckBufAddr;
- END;
- contest.prgr.SetBranchAddress(block.start+z,branchAddressPtr,ptrToBuf);
- packet.block:= block;
- contest.listInserted.AddPacket(packet);
- END SendPacket;
- (** This procedure checks the packet type to find out which context to use,
- builds the program and fills the FIFO. IF the packet awaits a response, It will wait until the response comes *)
- PROCEDURE OHCISend(VAR packet: OHCIPacket):BOOLEAN;
- VAR contest: FirewireLowUtil.Contest; result: BOOLEAN; i,ms: LONGINT;
- BEGIN
- IF packet.dataSize > OHCI.MaxPacketSize THEN KernelLog.String("The packet size is too big!"); KernelLog.Ln();
- RETURN FALSE;
- END;
- (* Find out what kind of packet we have *)
- IF packet.type = FirewireLowUtil.raw THEN contest:= OHCI.ATController.GetReqContest()
- ELSIF SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.ITCode THEN OHCI.ITController.ResetIterator();
- contest:= OHCI.ITController.GetNextContest() (* there are min 4 contests! *)
- ELSIF ((SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.NoDataWATRes) OR (SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.QReadATRes)
- OR (SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.BReadATRes) OR (SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.LockATRes))
- THEN contest:= OHCI.ATController.GetResContest()
- ELSE contest:= OHCI.ATController.GetReqContest()
- END;
- (* Add packet to the contest pending list *)
- contest.listPending.AddPacket(packet);
- (* KernelLog.String("Printing the content of the control set register in OHCISend:");
- FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(contest.ctrlSet)); KernelLog.Ln(); *)
- (* Fills the fifo with pending packets *)
- IF ~FillFifo(contest) THEN result:= TRUE ELSE result:= FALSE END;
- (* if packet awaits a response, wait until the response comes *)
- i:= 0;
- IF packet.respExpected THEN
- BEGIN{EXCLUSIVE}
- ms:= 5;
- Kernel.SetTimer(timer,ms);
- Objects.SetTimeout(clock, SELF.HandleTimeout, ms);
- timeout:= FALSE;
- AWAIT((packet.state = FirewireLowUtil.COMPLETE) OR timeout)
- END;
- END;
- IF packet.state = FirewireLowUtil.COMPLETE THEN
- (* KernelLog.String("Packet received answer and is complete::ohciSend"); KernelLog.Ln() *)
- ELSE (* KernelLog.String("Time out::ohciSend"); KernelLog.Ln(); *)
- END;
- RETURN result
- END OHCISend;
- (** Fills the FIFO with the context program *)
- PROCEDURE FillFifo(contest: FirewireLowUtil.Contest):BOOLEAN;
- VAR packet: OHCIPacket; error: BOOLEAN; z: LONGINT; tempAddr: LONGINT;
- CONST isRunning= 15; active= 10;
- BEGIN
- (* KernelLog.String("Entering FillFifo"); KernelLog.Ln(); *)
- error:= contest.listPending.GetPacket(packet);
- IF (error) THEN
- (* KernelLog.String("There are no more packets to send"); KernelLog.Ln(); *) RETURN FALSE
- END;
- (* find out if packet has data *)
- (* KernelLog.String("Finding out packet data size!"); KernelLog.Ln(); *)
- IF packet.dataSize > 0 THEN
- z:= 3 (* use one outputMoreImmediateDescriptor and one outputLast descriptor *)
- ELSE z:= 2 (* use one outputLastImmediate decriptor *)
- END;
- (* Insert the packet into the fifo *)
- WHILE ~error DO
- error:= contest.listPending.DelPacket(packet);
- SendPacket(contest,packet,z);
- error:= contest.listPending.GetPacket(packet);
- END;
- error:= FALSE;
- (* IF contest.prgr.GetFreeBlocks() = 0 THEN KernelLog.String("Fifo for context "); KernelLog.String(contest.name);
- KernelLog.String(" is full!"); KernelLog.Ln() END; *)
- tempAddr:= SYSTEM.GET32(packet.blockBufferAddr);
- (* Check if the context is running, else wake it up *)
- (* KernelLog.String("Printing the content of the control set register before setting the run bit:");
- FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(contest.ctrlSet)); KernelLog.Ln(); *)
- IF ~(isRunning IN FirewireLowUtil.ReadReg(contest.ctrlSet)) THEN (* KernelLog.String("Starting "); KernelLog.String(contest.name);
- KernelLog.String(" contest!"); KernelLog.Ln();
- KernelLog.String("The comamnd Ptr is: "); FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,contest.prgr.bufferAddr+z));
- KernelLog.Ln(); *)
- FirewireLowUtil.WriteReg(contest.cmdPtr,FirewireLowUtil.ConvertToSet(packet.blockBufferAddr + z));
- (* KernelLog.String("The content of the ctrl set register is: ");
- FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(contest.ctrlSet)); KernelLog.Ln(); *)
- IF FirewireLowUtil.StartContest(contest) THEN (* KernelLog.String("The context started successfully!"); KernelLog.Ln(); *)
- ELSE KernelLog.String("The context didn't start successfully!"); KernelLog.Ln();
- END
- ELSE (* wake up context *)
- IF ~(active IN FirewireLowUtil.ReadReg(contest.ctrlSet)) THEN (* KernelLog.String("Waking up ");
- KernelLog.String(contest.name); KernelLog.Ln() *)
- ELSE (* KernelLog.String("The context "); KernelLog.String(contest.name); KernelLog.String(" is already active!");
- KernelLog.Ln(); *)
- END;
- (* KernelLog.String("The comamnd Ptr is: "); FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,contest.prgr.bufferAddr+z));
- KernelLog.Ln(); *)
- FirewireLowUtil.WriteReg(contest.ctrlSet,{12}); (* wake *)
- END;
- (* KernelLog.String("Leaving FillFifo!"); KernelLog.Ln(); *)
- RETURN error;
- END FillFifo;
- (** Decides if it's a local or external 1394 packet. IF it's an external packet it will be sent to the OHCI send procedures *)
- PROCEDURE SendPacket1394(context: Contest;VAR packet: OHCIPacket):BOOLEAN; (* core.c *)
- CONST queued = 0;
- VAR speed: LONGINT;
- BEGIN
- IF packet.host.inBusReset
- OR (packet.generation # SYSTEM.VAL(LONGINT,LSH(FirewireLowUtil.ReadReg(FirewireLowUtil.SelfIDCount)*{16..23},-16))) THEN
- KernelLog.String("Generation mismatch or host in bus reset!"); KernelLog.Ln(); RETURN FALSE
- END;
- packet.state:= FirewireLowUtil.QUEUED;
- IF ( SYSTEM.VAL(LONGINT,packet.nodeID) = packet.host.nodeID ) THEN (* It's a local request *)
- KernelLog.String("It's an internal packet!"); KernelLog.Ln(); (*
- size:= packet.dataSize + packet.headerSize;
- SYSTEM.MOVE(packet.header, ConvertToLongint(tempBuf), packet.headerSize);
- IF packet.dataSize > 0 THEN
- SYSTEM.MOVE(packet.data, ConvertToLongint(tempBuf)+packet.headerSize, packet.dataSize)
- END;
- IF packet.respExpected THEN ack:= FirewireLowUtil.ConvertToSet(FirewireLowUtil.AckPending)
- ELSE ack:= FirewireLowUtil.ConvertToSet(FirewireLowUtil.AckComplete)
- END;
- PacketSent(context,packet,ack);
- PacketReceived(context,tempBuf,size,FALSE);
- RETURN TRUE *)
- RETURN FALSE
- END;
- IF (packet.type = FirewireLowUtil.async) & (packet.nodeID # {0..5}) THEN
- speed:= OHCI.SpeedMap[OHCI.nodeID][SYSTEM.VAL(LONGINT,packet.nodeID)];
- packet.speed:= FirewireLowUtil.ConvertToSet(speed);
- END;
- (* IF (speed = 1) OR (speed = 2) THEN
- speed:= speed*200;
- KernelLog.String("Sending packet with speed: "); KernelLog.Int(speed,2); KernelLog.String("!"); KernelLog.Ln()
- ELSE KernelLog.String("Sending packt with speed: 100!"); KernelLog.Ln()
- END; *)
- (*
- CASE speed OF
- 0: KernelLog.String("Sending packet with speed: 100!"); KernelLog.Ln()
- |1: KernelLog.String("Sending packet with speed: 200!"); KernelLog.Ln()
- |2: KernelLog.String("Sending packet with speed: 400!"); KernelLog.Ln()
- END; *)
- (*
- KernelLog.String("Dumping the packet::SendPacket1394!"); KernelLog.Ln();
- FOR i:= 0 TO (packet.headerSize DIV 4)-1 DO
- FirewireLowUtil.PrintSet(packet.header[i])
- END;
- IF packet.dataSize > 0 THEN
- FOR i:= 0 TO (packet.dataSize DIV 4)-1 DO
- FirewireLowUtil.PrintSet(packet.data[i])
- END
- ELSE KernelLog.String("PacketDataSize is: "); KernelLog.Int(packet.dataSize,2); KernelLog.Ln();
- END; *)
- RETURN OHCISend(packet);
- END SendPacket1394;
- (** Allocates a buffer for the configuration rom *)
- PROCEDURE ConfigRomAlloc;
- VAR buffer: FirewireLowUtil.CharBuffer; adr: ADDRESS; s: SET;
- BEGIN
- (* KernelLog.String("Entering configuration rom allocation"); KernelLog.Ln(); *)
- (* Allocating 2k buffer *)
- NEW(buffer, 2048);
- (* find a 1K aligned address *)
- adr:= ADDRESSOF(buffer[0]);
- DEC(adr,adr MOD 1024);
- INC(adr,1024);
- s:= SYSTEM.VAL(SET,adr);
- (* setting the buffer address *)
- (* KernelLog.String("Printing the buffer address"); KernelLog.Ln();
- FirewireLowUtil.PrintSet(s); *)
- OHCI.ptrToConfigRomBuf:= buffer;
- OHCI.ConfigRomBufferAdr:= s;
- END ConfigRomAlloc;
- (** Initializes the asynchronous receive request/response descriptors *)
- PROCEDURE InitARRDesc;
- CONST cmd = {29}; s = {27}; i = {21,20}; b = {19,18}; reqCount = {9}; resCount = {9};
- VAR desc: FirewireLowUtil.InputMoreDesc;
- BEGIN
- (* Input more AR *)
- desc.cmd := cmd; desc.s := s; desc.b := b;
- (* Input more *)
- desc.i := i; desc.reqCount := reqCount; desc.resCount := resCount;
- OHCI.IMDesc:= desc;
- END InitARRDesc;
- (** Configure the asynchronous receive request/response contexts *)
- PROCEDURE ConfigARR;
- VAR reqCont, resCont: FirewireLowUtil.Contest; controller: FirewireLowUtil.ADMAController; size: LONGINT;
- BEGIN
- OHCI.ARDescNum:= 4;
- InitARRDesc();
- (* Initialize contest with a scheduling buffer with place for 10 packets *)
- OHCI.MaxPacketSize:= FirewireLowUtil.GetMaxPcktSize();
- size:= 10;
- NEW(controller,size,OHCI.ARDescNum);
- OHCI.ARController:= controller;
- (* Initialize request contest *)
- reqCont:= OHCI.ARController.GetReqContest();
- reqCont.type:= FirewireLowUtil.REQ;
- reqCont.name := "AR request";
- reqCont.cmdPtr:= FirewireLowUtil.ARReqComPtr;
- reqCont.ctrlSet:= FirewireLowUtil.ARReqContCtrlSet;
- reqCont.ctrlClear:= FirewireLowUtil.ARReqContCtrlClear;
- (* Initialize response contest *)
- reqCont.type:= FirewireLowUtil.RES;
- resCont:= OHCI.ARController.GetResContest();
- resCont.name:= "AR response";
- resCont.cmdPtr:= FirewireLowUtil.ARResComPtr;
- resCont.ctrlSet:= FirewireLowUtil.ARResContCtrlSet;
- resCont.ctrlClear:= FirewireLowUtil.ARResContCtrlClear;
- (* Allocate buffers for programs and packets *)
- resCont.prgr.SetBufferAddr(FirewireLowUtil.AllocARResBuf(resCont.prgr.ptrToBuf));
- reqCont.prgr.SetBufferAddr(FirewireLowUtil.AllocARReqBuf(reqCont.prgr.ptrToBuf));
- FirewireLowUtil.AllocPcktBuf(1,reqCont.tempBuffer,reqCont.ptrToTmpBuf);
- FirewireLowUtil.AllocPcktBuf(1,resCont.tempBuffer,resCont.ptrToTmpBuf);
- END ConfigARR;
- (** Configure the asynchronous transmit request/response contexts *)
- PROCEDURE ConfigATR;
- VAR reqCont, resCont: FirewireLowUtil.Contest; controller: FirewireLowUtil.ADMAController; size : LONGINT;
- BEGIN
- OHCI.ATDescNum:= 32;
- (* Initialize contest with a scheduling buffer with place for 10 packets *)
- size:= 10;
- NEW(controller,size,OHCI.ATDescNum);
- OHCI.ATController:= controller;
- (* Initialize request contest *)
- reqCont:= OHCI.ATController.GetReqContest();
- reqCont.type:= FirewireLowUtil.REQ;
- reqCont.name:= "AT request";
- reqCont.cmdPtr:= FirewireLowUtil.ATReqComPtr;
- reqCont.ctrlSet:= FirewireLowUtil.ATReqContCtrlSet;
- reqCont.ctrlClear:= FirewireLowUtil.ATReqContCtrlClear;
- (* Initialize response contest *)
- resCont:= OHCI.ATController.GetResContest();
- resCont.type:= FirewireLowUtil.RES;
- resCont.name:= "AT response";
- resCont.cmdPtr:= FirewireLowUtil.ATResComPtr;
- resCont.ctrlSet:= FirewireLowUtil.ATResContCtrlSet;
- resCont.ctrlClear:= FirewireLowUtil.ATResContCtrlClear;
- (* Allocate buffers for programs and packets *)
- resCont.prgr.SetBufferAddr(FirewireLowUtil.AllocATResBuf(resCont.prgr.ptrToBuf));
- reqCont.prgr.SetBufferAddr(FirewireLowUtil.AllocATReqBuf(reqCont.prgr.ptrToBuf));
- END ConfigATR;
- (** Configures the isochronous receive contexts *)
- PROCEDURE ConfigIR;
- VAR contest: FirewireLowUtil.IRContest; controller: FirewireLowUtil.IRDMAController; size, avIRCont, i: LONGINT;
- str: ARRAY 5 OF CHAR;
- BEGIN
- avIRCont:= FirewireLowUtil.GetAvailableIRCont();
- size:= 10; i:= 0;
- OHCI.IRDescNum:= 16;
- NEW(controller,avIRCont,size,OHCI.IRDescNum);
- OHCI.IRController:= controller;
- WHILE controller.hasNext DO contest:= controller.GetNextContest();
- contest.type:= FirewireLowUtil.ISO;
- contest.name:= "IR "; Strings.IntToStr(i,str); Strings.Append(str,contest.name);
- contest.cmdPtr:= FirewireLowUtil.IRComPtr+(32*i);
- contest.ctrlSet:= FirewireLowUtil.isochRecvCntCtrlSet+(32*i);
- contest.ctrlClear:= FirewireLowUtil.isochRecvCntCtrlClear+(32*i);
- contest.match:= FirewireLowUtil.isochRecvContMatch+(32*i);
- contest.prgr.SetBufferAddr(FirewireLowUtil.AllocIRBuf(contest.prgr.ptrToBuf,OHCI.IRDescNum));
- INC(i);
- END;
- (* FirewireLowUtil.AllocPcktBuf(OHCI.IRDescNum*avIRCont, OHCI.IRPcktBuf); *)
- END ConfigIR;
- (** Configure the isochronous transmit contexts *)
- PROCEDURE ConfigIT;
- VAR contest: FirewireLowUtil.Contest; controller: FirewireLowUtil.ITDMAController; size, avITCont, i: LONGINT;
- str: ARRAY 5 OF CHAR;
- BEGIN
- avITCont:= FirewireLowUtil.GetAvailableITCont();
- size:= 10; i:= 0;
- OHCI.ITDescNum:= 16;
- NEW(controller,avITCont,size,OHCI.ITDescNum);
- OHCI.ITController:= controller;
- WHILE controller.hasNext DO contest:= controller.GetNextContest();
- contest.type:= FirewireLowUtil.ISO;
- contest.name:= "IT "; Strings.IntToStr(i,str); Strings.Append(str,contest.name);
- contest.cmdPtr:= FirewireLowUtil.ITComPtr+(16*i);
- contest.ctrlSet:= FirewireLowUtil.isochXmitCntCtrlSet+(16*i);
- contest.ctrlClear:= FirewireLowUtil.isochXmitCntCtrlClear+(16*i);
- contest.prgr.SetBufferAddr(FirewireLowUtil.AllocITBuf(contest.prgr.ptrToBuf,OHCI.ITDescNum));
- INC(i);
- END;
- (* FirewireLowUtil.AllocPcktBuf(OHCI.ITDescNum*avITCont, OHCI.ITPcktBuf); *)
- END ConfigIT;
- (** Generates the dma receive programs and starts the contexts *)
- PROCEDURE InitAsyncRecvCont;
- VAR i: LONGINT; desc: FirewireLowUtil.InputMoreDesc; s, Z, branchAddress, dataAddress:SET;
- quadlet1, quadlet2, quadlet3, quadlet4, reqCount: SET; reqCntst, resCntst: FirewireLowUtil.Contest; block: FirewireLowUtil.Block;
- branchAddressPtr: ADDRESS;
- BEGIN
- desc:= OHCI.IMDesc;
- reqCntst:= OHCI.ARController.GetReqContest();
- resCntst:= OHCI.ARController.GetResContest();
- (* Stop contexts if not already stopped *)
- (* KernelLog.String("Stopping arreq contest"); KernelLog.Ln(); *)
- FirewireLowUtil.StopContext(reqCntst.ctrlClear);
- (* KernelLog.String("Stopping arres contest"); KernelLog.Ln(); *)
- FirewireLowUtil.StopContext(resCntst.ctrlClear);
- (* Write descriptors for the asynchronous request context *)
- block.descNum:= OHCI.ARDescNum;
- block.start:= reqCntst.prgr.bufferAddr;
- FOR i:= 0 TO OHCI.ARDescNum-1 DO
- s:= desc.cmd + desc.s + desc.b;
- reqCount:= FirewireLowUtil.ConvertToSet(FirewireLowUtil.BufSize);
- (* KernelLog.String("Getting buffer::InitAsyncRecvCont"); KernelLog.Ln(); *)
- dataAddress:= reqCntst.buffers.GetBuffer();
- (* KernelLog.String("Got buffer!"); KernelLog.Ln(); *)
- quadlet1:= s + reqCount; quadlet2:= dataAddress; quadlet4:= reqCount;
- IF i+1 = OHCI.ARDescNum THEN (* build a ring *)
- quadlet3:= SYSTEM.VAL(SET,block.start) + {0}; block.end:= reqCntst.prgr.bufferAddr + i*16;
- branchAddressPtr:= reqCntst.prgr.bufferAddr + i*16+8;
- reqCntst.prgr.nextAddr:= reqCntst.prgr.bufferAddr + i*16+16;
- (* Is this the last descriptor? *)
- ELSE Z:= {0}; branchAddress:= FirewireLowUtil.ConvertToSet(reqCntst.prgr.bufferAddr + (i+1)*16);
- quadlet3:= branchAddress + Z;
- END;
- SYSTEM.PUT32(reqCntst.prgr.bufferAddr + i*16, quadlet1);
- SYSTEM.PUT32(reqCntst.prgr.bufferAddr + i*16+4, quadlet2);
- SYSTEM.PUT32(reqCntst.prgr.bufferAddr + i*16+8, quadlet3);
- SYSTEM.PUT32(reqCntst.prgr.bufferAddr + i*16+12, quadlet4);
- END;
- reqCntst.prgr.blockBuffer.Append(block);
- block.descNum:= OHCI.ARDescNum;
- block.start:= resCntst.prgr.bufferAddr;
- (* Write descriptors for the asynchronous response context *)
- FOR i:= 0 TO OHCI.ARDescNum-1 DO
- s:= desc.cmd + desc.s + desc.b;
- reqCount:= FirewireLowUtil.ConvertToSet(FirewireLowUtil.BufSize);
- dataAddress:= resCntst.buffers.GetBuffer();
- quadlet1:= s + reqCount; quadlet2:= dataAddress; quadlet4:= reqCount;
- IF i+1 = OHCI.ARDescNum THEN (* build a ring *)
- quadlet3:= SYSTEM.VAL(SET,block.start)+{0}; block.end:= resCntst.prgr.bufferAddr + i*16;
- branchAddressPtr:= resCntst.prgr.bufferAddr + i*16+8;
- resCntst.prgr.nextAddr:= resCntst.prgr.bufferAddr + i*16+16;
- (* Is this the last descriptor? *)
- ELSE Z:= {0}; branchAddress:= FirewireLowUtil.ConvertToSet(resCntst.prgr.bufferAddr + (i+1)*16);
- quadlet3:= branchAddress + Z;
- END;
- SYSTEM.PUT32(resCntst.prgr.bufferAddr + i*16, quadlet1);
- SYSTEM.PUT32(resCntst.prgr.bufferAddr + i*16+4, quadlet2);
- SYSTEM.PUT32(resCntst.prgr.bufferAddr + i*16+8, quadlet3);
- SYSTEM.PUT32(resCntst.prgr.bufferAddr + i*16+12, quadlet4);
- END;
- resCntst.prgr.blockBuffer.Append(block);
- (* Set the ARReq command ptr *)
- s:= FirewireLowUtil.ConvertToSet(reqCntst.prgr.bufferAddr) + {0};
- SYSTEM.PUT32(base + reqCntst.cmdPtr, s);
- (* Start the ARReq context *)
- ASSERT(FirewireLowUtil.StartContest(reqCntst));
- (* Set the ARRes command ptr *)
- s:= FirewireLowUtil.ConvertToSet(resCntst.prgr.bufferAddr) + {0};
- SYSTEM.PUT32(base + resCntst.cmdPtr, s);
- (* Start the ARReq context *)
- ASSERT(FirewireLowUtil.StartContest(resCntst));
- END InitAsyncRecvCont;
- (** Initializes the isochronous receive contexts *)
- PROCEDURE InitIsochRecvCont;
- VAR i: LONGINT; desc: FirewireLowUtil.InputMoreDesc; s, Z, branchAddress, dataAddress:SET;
- quadlet1, quadlet2, quadlet3, quadlet4, reqCount: SET; contest: FirewireLowUtil.IRContest; block: FirewireLowUtil.Block;
- branchAddressPtr: ADDRESS;
- BEGIN
- OHCI.IRController.ResetIterator();
- IF OHCI.IRController.hasNext THEN contest:= OHCI.IRController.GetNextContest() END;
- desc:= OHCI.IMDesc;
- (* Do not forget to start all other contexts too, if needed *)
- (* Stop contexts if not already stopped *)
- FirewireLowUtil.StopContext(contest.ctrlClear);
- (* Write descriptors for the asynchronous request context *)
- block.descNum:= OHCI.IRDescNum;
- block.start:= contest.prgr.bufferAddr;
- FOR i:= 0 TO OHCI.IRDescNum-1 DO
- s:= desc.cmd + desc.s + desc.b + desc.i;
- reqCount:= FirewireLowUtil.ConvertToSet(FirewireLowUtil.BufSize);
- (* dataAddress:= OHCI.IRPcktBuf[i]; *)
- dataAddress:= contest.buffers.GetBuffer();
- quadlet1:= s + reqCount; quadlet2:= dataAddress; quadlet4:= reqCount;
- (* Is this the last descriptor? *)
- IF i+1 = OHCI.IRDescNum THEN (* build a ring *)
- quadlet3:= SYSTEM.VAL(SET,block.start)+{0}; block.end:= contest.prgr.bufferAddr + i*16;
- branchAddressPtr:= contest.prgr.bufferAddr + i*16+8;
- contest.prgr.nextAddr:= contest.prgr.bufferAddr + i*16+16;
- ELSE Z:= {0}; branchAddress:= FirewireLowUtil.ConvertToSet(contest.prgr.bufferAddr + (i+1)*16);
- quadlet3:= branchAddress + Z;
- END;
- SYSTEM.PUT32(contest.prgr.bufferAddr + i*16, quadlet1);
- SYSTEM.PUT32(contest.prgr.bufferAddr + i*16+4, quadlet2);
- SYSTEM.PUT32(contest.prgr.bufferAddr + i*16+8, quadlet3);
- SYSTEM.PUT32(contest.prgr.bufferAddr + i*16+12, quadlet4);
- END;
- contest.prgr.blockBuffer.Append(block);
- (* Set the IR command ptr *)
- s:= FirewireLowUtil.ConvertToSet(contest.prgr.bufferAddr) + {0};
- SYSTEM.PUT32(base + contest.cmdPtr, s);
- (* Start the first IR context *)
- ASSERT(FirewireLowUtil.StartContest(contest));
- END InitIsochRecvCont;
- (** Initializes the isochronous transmit context *)
- PROCEDURE InitIsochXmitCont;
- VAR i: LONGINT; contest: FirewireLowUtil.Contest;
- BEGIN
- OHCI.ITController.ResetIterator();
- WHILE OHCI.ITController.hasNext DO contest:= OHCI.ITController.GetNextContest();
- FirewireLowUtil.StopContext(contest.ctrlClear + i*16);
- END
- END InitIsochXmitCont;
- (** Initializes the asynchronous transmit context *)
- PROCEDURE InitAsyncXmitCont;
- VAR reqCont, resCont: FirewireLowUtil.Contest;
- BEGIN
- reqCont:= OHCI.ATController.GetReqContest(); resCont:= OHCI.ATController.GetResContest();
- (* KernelLog.String("Stopping atreq contest"); KernelLog.Ln(); *)
- FirewireLowUtil.StopContext(reqCont.ctrlClear);
- (* KernelLog.String("Stopping atres contest"); KernelLog.Ln(); *)
- FirewireLowUtil.StopContext(resCont.ctrlClear);
- END InitAsyncXmitCont;
- (** Controls the status of the OHCI *)
- PROCEDURE ControlStatus;
- (* Not really used *)
- END ControlStatus;
- (** Checks if this node is bus manager *)
- PROCEDURE FindNodeInfo;
- CONST csrDone= 31;
- VAR reg: SET; done: BOOLEAN;
- BEGIN
- (* First check who is Bus Manager *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.CSRData,{0..5});
- FirewireLowUtil.WriteReg(FirewireLowUtil.CSRCompare,{0..5});
- FirewireLowUtil.WriteReg(FirewireLowUtil.CSRControl,{});
- (* Wait until compare swap operation has been done *)
- reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRControl);
- done:= FALSE;
- WHILE ~done DO
- IF csrDone IN reg THEN done:= TRUE ELSE
- reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRControl)
- END
- END;
- (* Read the bus manager ID *)
- reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRData);
- (* Print it out *)
- (* KernelLog.String("Printing the bus manager id");
- FirewireLowUtil.PrintSet(reg); *)
- (* Print the node id to compare it *)
- (* KernelLog.String("Printing the node id");
- reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID);
- reg:= reg*{0..5};
- FirewireLowUtil.PrintSet(reg); *)
- END FindNodeInfo;
- (* Not used: it was intended as a packet scheduler
- PROCEDURE Schedule(contest: FirewireLowUtil.Contest);
- VAR block: FirewireLowUtil.Block; quadlet3,quadlet: SET; branchAddress, avlbl, resdl, i: LONGINT; packet: FirewireLowUtil.Packet;
- dataAddress, copyAddress: LONGINT;
- CONST notLast= 0; reqCount = {0..15}; resCount = {0..15}; branchMask = {4..31};
- BEGIN
- (* read value of Z *)
- KernelLog.String("Scheduling a block, if there are any!"); KernelLog.Ln();
- ASSERT(contest.prgr.blockBuffer.num > 0);
- block:= contest.prgr.blockBuffer.Remove();
- quadlet3:= SYSTEM.VAL(SET, SYSTEM.GET32(block.start + 8));
- (* read value of reqCount and resCount *)
- quadlet:= SYSTEM.VAL(SET, SYSTEM.GET32(block.start));
- avlbl:= ConvertToLongint(quadlet*reqCount);
- quadlet:= SYSTEM.VAL(SET, SYSTEM.GET32(block.start + 12));
- resdl:= ConvertToLongint(quadlet*reqCount);
- (* read data address *)
- dataAddress:= SYSTEM.VAL(LONGINT, SYSTEM.GET32(block.start + 4));
- (* schedule packet *)
- copyAddress:= ADDRESSOF(packet);
- FOR i:= 0 TO avlbl-resdl-1 DO (* SYSTEM.MOVE(dataAddress+i,copyAddress+i,8) *)
- SYSTEM.PUT8(copyAddress+i,SYSTEM.GET8(dataAddress+i)) END;
- PrintBuffer(FirewireLowUtil.ConvertToSet(dataAddress),(avlbl-resdl) DIV 4);
- PrintBuffer(FirewireLowUtil.ConvertToSet(copyAddress),(avlbl-resdl) DIV 4);
- branchAddress:= ConvertToLongint(branchMask*quadlet3);
- IF avlbl > resdl THEN KernelLog.String("Appending packet"); KernelLog.Ln(); contest.procBuffer.Append(packet) END;
- WHILE notLast IN quadlet3 DO
- quadlet3:= SYSTEM.VAL(SET, SYSTEM.GET32(branchAddress + 8));
- (* read value of reqCount and resCount *)
- quadlet:= SYSTEM.VAL(SET, SYSTEM.GET32(branchAddress));
- avlbl:= ConvertToLongint(quadlet*reqCount);
- quadlet:= SYSTEM.VAL(SET, SYSTEM.GET32(branchAddress + 12));
- resdl:= ConvertToLongint(quadlet*reqCount);
- (* read data address *)
- dataAddress:= SYSTEM.VAL(LONGINT, SYSTEM.GET32(branchAddress + 4));
- FOR i:= 0 TO avlbl-resdl-1 DO SYSTEM.MOVE(dataAddress+i,copyAddress+i,8) END;
- (* KernelLog.String("Difference between available and residual is: "); KernelLog.Int(avlbl - resdl,2); KernelLog.Ln(); *)
- PrintBuffer(FirewireLowUtil.ConvertToSet(dataAddress),(avlbl-resdl) DIV 4);
- PrintBuffer(FirewireLowUtil.ConvertToSet(copyAddress),(avlbl-resdl) DIV 4);
- branchAddress:= ConvertToLongint(branchMask*quadlet3);
- IF avlbl > resdl THEN KernelLog.String("Appending packet"); KernelLog.Ln(); contest.procBuffer.Append(packet) END
- END;
- contest.prgr.blockBuffer.Append(block);
- END Schedule; *)
- (** Schedules packets for isochronous contexts *)
- PROCEDURE IsoSchedule(reg: SET);
- VAR controller: FirewireLowUtil.IRDMAController; i: LONGINT;
- BEGIN
- (* This call will fail in PacketReceived, because implementation is missing *)
- FOR i:= 0 TO controller.avIRCont-1 DO
- IF i IN reg THEN ProcRcvdPckts(controller.GetContest(i)) END
- END;
- END IsoSchedule;
- (** Does OHCI buffer allocation and context initialization *)
- PROCEDURE DevInit;
- VAR reg: SET; (* t: Kernel.Timer; *)
- BEGIN
- NEW(t);
- (* KernelLog.String("Entering device initialization"); KernelLog.Ln(); *)
- (* csr configuration rom allocation *)
- ConfigRomAlloc();
- (* self-id buffer allocation *)
- SelfIDAlloc();
- FirewireLowUtil.CheckSelfIDCount();
- (* allocate contexts *)
- (* initialize AR response and request context *)
- ConfigARR();
- (* initialize AT response and receive context *)
- ConfigATR();
- (* Do a softReset *)
- FirewireLowUtil.SoftReset();
- (*Give power to the Link Layer *)
- (* KernelLog.String("Giving power to the link layer"); KernelLog.Ln(); *)
- (* KernelLog.String("Control register before power: ");
- FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(FirewireLowUtil.HCControl)); *)
- reg := {};
- INCL(reg, LPS);
- FirewireLowUtil.SetHCControl(reg);
- t.Sleep(50);
- (* KernelLog.String("Control register after power: ");
- FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(FirewireLowUtil.HCControl)); *)
- (* Determine number of available IR and IT contexts *)
- FirewireLowUtil.CheckAvailableIR();
- FirewireLowUtil.CheckAvailableIT();
- (* initialize IR context *)
- ConfigIR();
- (* initialize IT context *)
- ConfigIT();
- END DevInit;
- (** Inits the OHCI data structure *)
- PROCEDURE InitOHCI;
- VAR i: LONGINT;
- BEGIN
- FOR i:= 0 TO 62 DO
- OHCI.Nodes[i]:= NIL
- END;
- OHCI.selfIDComplete:= FALSE;
- NEW(OHCI.adrCheck);
- NEW(t);NEW(clock);
- NEW(OHCI.packetFIFO,10);
- (* Get max packet size *)
- OHCI.MaxPacketSize:= FirewireLowUtil.GetMaxPcktSize();
- NEW(OHCI.tempBuffer,OHCI.MaxPacketSize);
- END InitOHCI;
- (** Initializes the OHCI registers *)
- PROCEDURE&Init*(base,irq:LONGINT);
- CONST irmcCmcIsc = {31,30,29}; cycClkAcc = {16..23}; pmcBmc = {28,27}; postedWriteEnable= {18};
- programPhyEnable= 23; aPhyEnhanceEnable= 22; rcvPhyPkt = 10; postedWriteErr = 8;
- VAR reg:SET;
- BEGIN
- SELF.base:=base;
- SELF.irq:=irq;
- DevInit();
- InitOHCI();
- (* Install the handler *)
- IF(irq >= 1) & (irq <= 15) THEN Objects.InstallHandler(SELF.HandleInterrupt, Machine.IRQ0+irq)
- END;
- (* Define some bus options *)
- reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.BusOptions);
- (* Enable IRMC, CMC and ISC *)
- reg:= reg + irmcCmcIsc;
- (* XXX: Set cyc clk acc to zero for now *)
- reg:= reg - cycClkAcc;
- (* Disable PMC and BMC *)
- reg:= reg - pmcBmc;
- FirewireLowUtil.WriteReg(FirewireLowUtil.BusOptions,reg);
- (* Set the bus number *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.NodeID,busNumber);
- (* Enable posted writes *)
- FirewireLowUtil.SetHCControl(postedWriteEnable);
- (* Clearing LinkControl *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.CLinkControl,{0..31});
- (* Check if OHCI has enhanced register map 1394a *)
- reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.HCControl);
- IF programPhyEnable IN reg THEN OHCI.ExstRegMap:= TRUE;
- IF ~(aPhyEnhanceEnable IN reg) THEN FirewireLowUtil.SetHCControl({aPhyEnhanceEnable}) END
- ELSE OHCI.ExstRegMap:= FALSE
- END; reg:= {};
- (* Enable cycle timer and cycle master and set the IRM contender bit in self ID packets *)
- (* Enable receive selfID packets outside bus reset *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.LinkControl,{10,20,21});
- IF OHCI.ExstRegMap THEN FirewireLowUtil.SetPhyControl({10},{6}) END;
- (* clearing interrupts *)
- (* KernelLog.String("Clearing interrupts"); KernelLog.Ln(); *)
- FirewireLowUtil.ClearIntEventAll();
- FirewireLowUtil.ClearIntMaskAll();
- (* Set SelfID dma buffer *)
- (* KernelLog.String("Setting the Self ID Buffer"); *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.SelfIDBuffer,OHCI.SelfIDBufferAdr);
- (* Enable SelfID dma *)
- (* KernelLog.String("Enabling SelfID"); KernelLog.Ln(); *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.LinkControl,{rcvSelfID});
- (* Do not accept phy packets into the AR request context clearing the rcvPhyPkt bit
- FirewireLowUtil.WriteReg(FirewireLowUtil.CLinkControl,{10}); *)
- (* Set bufferfill, isochHeader, multichannel for IR context 0 *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvCntCtrlSet,{28,30,31});
- (* Set all tags of the first isochronous receive match register *)
- FirewireLowUtil.SetIsochRecvContMatch({28..31});
- (* Clear the isochronous receive mask and event interrupt register *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvIntEvntClear,{0..31});
- FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvIntMaskClear,{0..31});
- (* Clear the isochronouse transmit mask and event interrupt register *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.isochXmitIntEvntClear,{0..31});
- FirewireLowUtil.WriteReg(FirewireLowUtil.isochXmitIntMaskClear,{0..31});
- (* Clear the isochronous receive mutlichannel high and low mask *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.IRmultiChanMaskHiClear,{0..31});
- FirewireLowUtil.WriteReg(FirewireLowUtil.IRmultiChanMaskLoClear,{0..31});
- (* Initialize asynchronous receive dma *)
- InitAsyncRecvCont();
- InitAsyncXmitCont();
- (* Initialize isochronous dma *)
- InitIsochRecvCont();
- InitIsochXmitCont();
- (* Set the isochronous receive interrupt mask for context 0 *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvIntMaskSet,{0});
- (* Set the isochronous transmit interrupt mask for context 0 *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.isochXmitIntMaskSet,{0});
- (* Receive asynchronous requests from all nodes *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.ARFilterHISet,{31});
- (* Set the asynchronous trasmit retries register *)
- reg:= FirewireLowUtil.MaxPhysRespRetries + FirewireLowUtil.MaxATReqRetries
- + FirewireLowUtil.MaxATRespRetries;
- FirewireLowUtil.WriteReg(FirewireLowUtil.ATRetries, reg);
- (* Set the physical upper bound if implemented *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.PhyUpperBound,{16..31});
- reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.PhyUpperBound);
- (* FirewireLowUtil.PrintSet(reg); *)
- IF reg = {16..31} THEN
- (* KernelLog.String("The physical upper bound is: 48hFFFF 0000 0000"); KernelLog.Ln(); *)
- ELSE (* KernelLog.String("The physical upper bound is: 48h0001 0000 0000"); KernelLog.Ln() *)
- END;
- (* Receive physical requests from every bys and every node *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.PRFilterHiSet,{0..30});
- FirewireLowUtil.WriteReg(FirewireLowUtil.PRFilterLowSet,{0..31});
- (* Set no byte swapping *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.HCControl,{30});
- (* Enabling interrupts *)
- (* KernelLog.String("Enabling interrupts"); KernelLog.Ln(); *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{31});
- reg:= {};
- INCL(reg,unrecoverableError);
- INCL(reg,busReset);
- INCL(reg,regAccessFail);
- INCL(reg,selfIDComplete);
- INCL(reg,RSPkt);
- INCL(reg,RQPkt);
- INCL(reg,respTxComplete);
- INCL(reg,reqTxComplete);
- INCL(reg,isochRx);
- INCL(reg,isochTx);
- INCL(reg,cycleInconsistent);
- INCL(reg,postedWriteErr);
- FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,reg);
- FirewireLowUtil.CheckIntMask();
- FirewireLowUtil.CheckIntEvent();
- (* Initialize the label pool of the OHCI *)
- NEW(OHCI.labeler,63);
- (* Initialize OHCI bus reset status *)
- OHCI.inBusReset:= FALSE;
- (*Enable Operation of the lInk Layer*)
- (* KernelLog.String("Enabling operation of the link layer"); KernelLog.Ln(); *)
- reg:= {};
- INCL(reg, LinkEnable);
- FirewireLowUtil.SetHCControl(reg);
- (* KernelLog.String("Control register after enabling operation of the link layer:");
- KernelLog.Ln();
- FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(FirewireLowUtil.HCControl)); *)
- (* Initiate bus reset *)
- (* KernelLog.String("Initiating bus reset!"); KernelLog.Ln(); *)
- FirewireLowUtil.SetPhyControl({8},{6});
- (* Print OHCI information *)
- (* PrintOHCIInfo(); *) BEGIN {EXCLUSIVE}
- AWAIT(OHCI.selfIDComplete)
- END;
- (* KernelLog.String("Scanning nodes!"); KernelLog.Ln(); *)
- ScanNodes();
- KernelLog.String("Finished OHCI initialization"); KernelLog.Ln();
- END Init;
- (** Checks to see who is the bus manager and tries to become it if necessary. This procedure is not complete *)
- PROCEDURE CheckBusManager;
- CONST isRoot= 30;
- VAR selfIDBuf: SET; reg: SET;nodeID,data: SET;countReg,selfIDSize,IRMID: SET; i,j,size: LONGINT;
- BEGIN
- nodeID:= FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID)*{0..5};
- OHCI.nodeID:= ConvertToLongint(nodeID);
- (* Check if OHCI is root *)
- reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID)*{30};
- (* Check if OHCI is IRM: note that contender bit must be set and link must be active *)
- IF isRoot IN reg THEN OHCI.IsRoot:= TRUE; OHCI.IsIRM:= TRUE;
- (* Now be fast and set the ID of the OHCI into the BusManagerID register *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.CSRData,nodeID);
- FirewireLowUtil.WriteReg(FirewireLowUtil.CSRCompare,{0..5});
- FirewireLowUtil.WriteReg(FirewireLowUtil.CSRControl,{});
- IRMID:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRData);
- IF IRMID = {0..5} THEN
- OHCI.IsBM:= TRUE; IRMID:= nodeID ELSE OHCI.IsBM:= FALSE
- END;
- ELSE (* Find out if some other IRM contender has higher ID *)
- selfIDBuf:= OHCI.SelfIDBufferAdr;
- countReg:= FirewireLowUtil.ReadReg(FirewireLowUtil.SelfIDCount);
- selfIDSize := LSH(countReg,-2);
- selfIDSize := selfIDSize*{0..8};
- size := ConvertToLongint(selfIDSize);
- j:= 4;
- (* Traverse self ID buffer *)
- OHCI.IsIRM:= TRUE;
- FOR i:= 0 TO size-2 DO
- data := SYSTEM.VAL(SET, SYSTEM.GET32(ConvertToLongint(selfIDBuf)+j)); INC(j,8);
- IF (11 IN data) & (22 IN data) THEN (* ok it's an IRM contender, check if ID is higher then mine *)
- data:= LSH(data,-24)*{0..5};
- IF OHCI.nodeID > ConvertToLongint(data) THEN (* shit, I'm not IRM *)
- OHCI.IsIRM:= FALSE
- END
- END
- END;
- IF OHCI.IsIRM THEN (* be fast and set OHCI ID into the BusManagerID register *)
- FirewireLowUtil.WriteReg(FirewireLowUtil.CSRData,nodeID);
- FirewireLowUtil.WriteReg(FirewireLowUtil.CSRCompare,{0..5});
- FirewireLowUtil.WriteReg(FirewireLowUtil.CSRControl,{});
- IRMID:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRData);
- IF IRMID = {0..5} THEN
- OHCI.IsBM:= TRUE; IRMID:= nodeID ELSE OHCI.IsBM:= FALSE
- END
- ELSE (* Go and try to set the nodeId of the OHCI into the IRM *)
- KernelLog.Ln();
- END;
- (* I'm not the bus manager *)
- (* Get the topology map *)
- OHCI.IsRoot:= FALSE; OHCI.IsIRM:= FALSE END;
- (* TODO *)
- END CheckBusManager;
- (** Scans the unit directory *)
- PROCEDURE ScanUnitDirectory(node: FirewireLowUtil.Node);
- (* not really needed *)
- END ScanUnitDirectory;
- (** Processes the unit directory of each device on the bus *)
- PROCEDURE ProcessUnitDirectory(VAR ud: FirewireLowUtil.UnitDirectory; node: FirewireLowUtil.Node; addrLow, addrHigh: SET; VAR id: LONGINT);
- VAR length,addr,code,value,i: LONGINT; udTemp: FirewireLowUtil.UnitDirectory; context: Contest; buffer: SET;
- BEGIN
- (* KernelLog.String("Processing the unit directory!"); KernelLog.Ln(); *)
- context:= OHCI.ATController.GetReqContest();
- addr:= SYSTEM.VAL(LONGINT,addrLow);
- (* Get the length of the unit directory *)
- IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
- KernelLog.String("There was an error::ProcessUnitDirectory"); KernelLog.Ln(); RETURN
- END;
- length:= SYSTEM.VAL(LONGINT,LSH(buffer,-16));
- NEW(ud,length);
- ud.addrLow:= addrLow;
- ud.addrHigh:= addrHigh;
- INC(id); ud.ID:= id;
- (* increment address *)
- INC(addr,4);
- addrLow:= SYSTEM.VAL(SET,addr);
- i:= 0;
- WHILE length > 0 DO
- IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
- KernelLog.String("There was an error::ProcessRootDirectory"); KernelLog.Ln(); RETURN
- END;
- ud.udEntries[i]:= buffer;
- code:= SYSTEM.VAL(LONGINT,LSH(buffer,-24));
- value:= SYSTEM.VAL(LONGINT,buffer*{0..23});
- CASE code OF
- FirewireLowUtil.ConfigRomVendorID: ud.vendorID:= value;
- |FirewireLowUtil.ConfigRomModelID: ud.modelID:= value;
- |FirewireLowUtil.ConfigRomSpecifierID: ud.specifierID:= value;
- |FirewireLowUtil.ConfigRomUnitSWVersion: ud.version:= value;
- |FirewireLowUtil.ConfigRomDescriptorLeaf: (* TODO *)
- |FirewireLowUtil.ConfigRomDescriptorDirectory: (* TODO *)
- |FirewireLowUtil.ConfigRomLogicalUnitDirectory:
- ud.hasLogicalUnitDir:= TRUE;
- ProcessUnitDirectory(udTemp,node,SYSTEM.VAL(SET,addr+value*4),addrHigh,id);
- (* inherit data if missing *)
- IF udTemp.vendorID = 0 THEN udTemp.vendorID:= ud.vendorID END;
- IF udTemp.modelID = 0 THEN udTemp.modelID:= ud.modelID END;
- IF udTemp.specifierID = 0 THEN udTemp.specifierID:= ud.specifierID END;
- IF udTemp.version = 0 THEN udTemp.version:= ud.version END;
- ud.luns[udTemp.ID]:= udTemp;
- ELSE (* NOTHING *)
- END;
- DEC(length); INC(addr,4); addrLow:= SYSTEM.VAL(SET,addr); INC(i);
- END;
- END ProcessUnitDirectory;
- (** Process the root directory of each device on the bus *)
- PROCEDURE ProcessRootDirectory(node: FirewireLowUtil.Node);
- VAR context: Contest; buffer, addrLow, addrHigh: SET; code, value, addr, busInfoLength, rootDirLength, id: LONGINT;
- ud: FirewireLowUtil.UnitDirectory;
- BEGIN
- (* KernelLog.String("Processing root directory"); KernelLog.Ln(); *)
- id:= -1;
- addrHigh:= FirewireLowUtil.CSRBaseHigh;
- addrLow:= FirewireLowUtil.CSRBaseLow;
- addrLow:= addrLow + FirewireLowUtil.CSRConfigRom;
- addr:= SYSTEM.VAL(LONGINT,addrLow);
- context:= OHCI.ATController.GetReqContest();
- (* get the length of the bus info block *)
- IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
- KernelLog.String("There was an error::ProcessRootDirectory"); KernelLog.Ln(); RETURN
- END;
- busInfoLength:= SYSTEM.VAL(LONGINT,LSH(buffer,-24));
- addr:= addr + 4 + busInfoLength*4;
- addrLow:= SYSTEM.VAL(SET,addr);
- (* now get the length of the root directory *)
- IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
- KernelLog.String("There was an error::ProcessRootDirectory"); KernelLog.Ln(); RETURN
- END;
- rootDirLength:= SYSTEM.VAL(LONGINT,LSH(buffer,-16));
- INC(addr,4);
- addrLow:= SYSTEM.VAL(SET,addr);
- WHILE rootDirLength > 0 DO
- IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
- KernelLog.String("There was an error::ProcessRootDirectory"); KernelLog.Ln(); RETURN
- END;
- code:= SYSTEM.VAL(LONGINT,LSH(buffer,-24));
- value:= SYSTEM.VAL(LONGINT,buffer*{0..23});
- CASE code OF
- FirewireLowUtil.ConfigRomVendorID: node.vendorID:= value; (* perhaps look also for a text leaf *)
- |FirewireLowUtil.ConfigRomNodeCapabilities: node.capabilities:= SYSTEM.VAL(SET,value);
- |FirewireLowUtil.ConfigRomUnitDirectory:
- ProcessUnitDirectory(ud,node,SYSTEM.VAL(SET,addr + value*4),addrHigh,id);
- node.uds[ud.ID]:= ud;
- ELSE (* NOTHING *)
- END;
- DEC(rootDirLength); INC(addr,4); addrLow:= SYSTEM.VAL(SET,addr);
- END;
- END ProcessRootDirectory;
- (** Scan the root directory *)
- PROCEDURE ScanRootDirectory;
- (* not really needed *)
- END ScanRootDirectory;
- (** Scan a node's directories *)
- PROCEDURE ScanEachNode(physicalID: SET; generation: LONGINT);
- VAR buffer: ARRAY 5 OF SET; bufferLength,i: LONGINT;
- node: FirewireLowUtil.Node; found: BOOLEAN; guid: FirewireLowUtil.GUID;
- BEGIN
- (* KernelLog.String("Entering scan each node"); KernelLog.Ln(); *)
- bufferLength:= 5;
- IF ReadBusInfoBlock(OHCI,physicalID,generation,buffer,bufferLength) THEN RETURN END;
- IF (buffer[1] # SYSTEM.VAL(SET,FirewireLowUtil.BusIDNumber)) THEN
- KernelLog.String("This device an invalid bus id number::ScanEachNode!"); KernelLog.Ln()
- END;
- guid.high:= buffer[3]; guid.low:= buffer[4];
- (* now find this node and update it or create it *)
- i:= 0; found:= FALSE;
- WHILE (OHCI.Nodes[i] # NIL) & ~found DO
- node:= OHCI.Nodes[i];
- IF (node.guid.low = guid.low) & (node.guid.high = guid.high) THEN
- found:= TRUE
- ELSE INC(i)
- END
- END;
- IF found THEN (* update *)
- (* KernelLog.String("Updating node"); KernelLog.Ln(); *)
- node.Update(buffer[2],physicalID,generation);
- ELSE (* create new *)
- (* KernelLog.String("Creating new node"); KernelLog.Ln(); *)
- NEW(node,guid,buffer[2],physicalID,generation); OHCI.Nodes[i]:= node;
- END;
- (* KernelLog.String("Leaving scan each node"); KernelLog.Ln(); *)
- END ScanEachNode;
- (** Scan all nodes on the bus *)
- PROCEDURE ScanNodes*;
- VAR i,generation: LONGINT; sid: FirewireLowUtil.SelfID; node: FirewireLowUtil.Node;
- BEGIN
- (* KernelLog.String("Entering scan nodes"); KernelLog.Ln(); *)
- WHILE OHCI.TopologyMap[i] # NIL DO
- sid:= OHCI.TopologyMap[i];
- IF ~sid.extended & (sid.linkActive={0}) THEN
- IF sid.physicalID # SYSTEM.VAL(SET,OHCI.nodeID) THEN
- generation:= FirewireLowUtil.GetGeneration();
- ScanEachNode(sid.physicalID,generation)
- END
- END;
- INC(i)
- END;
- i:= 0;
- WHILE OHCI.Nodes[i] # NIL DO
- node:= OHCI.Nodes[i];
- IF node.probe THEN ProcessRootDirectory(node) END; INC(i);
- END;
- (* i:= 0; j:= 0;
- WHILE c.OHCI.Nodes[i] # NIL DO
- node:= c.OHCI.Nodes[i];
- KernelLog.String("Printing the guid: "); KernelLog.Ln();
- FirewireLowUtil.PrintSet(node.guid.high); FirewireLowUtil.PrintSet(node.guid.low);
- KernelLog.String("Printing the unit directories if there are any"); KernelLog.Ln();
- WHILE node.uds[j] # NIL DO
- KernelLog.String("Printing the specifier id: "); KernelLog.Int(node.uds[j].specifierID,2); KernelLog.Ln();
- INC(j);
- END;
- INC(i);
- END; *)
- (* KernelLog.String("Leaving scan nodes"); KernelLog.Ln(); *)
- END ScanNodes;
- (** Builds the topology and the speed map *)
- PROCEDURE BuildMaps;
- VAR size,i,j,addr: LONGINT; quad,reg: SET; sid: FirewireLowUtil.SelfID; esid: FirewireLowUtil.ExtSelfID;
- speed, children: ARRAY 64 OF LONGINT; c: LONGINT;
- BEGIN
- OHCI.numOfNodes:= 0;
- (* KernelLog.String("Entering BuildMaps!"); KernelLog.Ln(); *)
- addr:= SYSTEM.VAL(LONGINT,OHCI.SelfIDBufferAdr) + 4; (* first quadlet has only management info *)
- (* Count the nodes and remember the ids *)
- reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.SelfIDCount);
- (* mask the size *)
- size:= SYSTEM.VAL(LONGINT,LSH(reg * {2..10},-2));
- size:= ((size-1) DIV 2)-1; (* we just need to look at the first quadlet of each selfid packet *)
- (* Initialize *)
- (* KernelLog.String("Initializing the children array!"); KernelLog.Ln(); *)
- FOR i:= 0 TO 64-1 DO children[i]:= 0 END;
- (* KernelLog.String("Initializing topology map!"); KernelLog.Ln();
- KernelLog.String("size is: ");KernelLog.Int(size,2); KernelLog.Ln();
- KernelLog.String("Number of nodes is: "); KernelLog.Int(OHCI.numOfNodes,2); KernelLog.Ln(); *)
- FOR i:= 0 TO size DO
- quad:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+(i*8)));
- IF 23 IN quad THEN NEW(esid,quad); OHCI.TopologyMap[i]:= esid;
- ELSE
- (* KernelLog.String("It's an sid, increase numOfNodes"); KernelLog.Ln(); *)
- NEW(sid,quad); OHCI.TopologyMap[i]:= sid; INC(OHCI.numOfNodes);
- (* KernelLog.String("Number of nodes is: "); KernelLog.Int(OHCI.numOfNodes,2); KernelLog.Ln(); *)
- END;
- END;
- OHCI.TopologyMap[i]:= NIL;
- i:= 0;
- (* check if port is active and connected to child node *)
- (* and remember how much direct children this node has *)
- (* KernelLog.String("Initialize speed array!"); KernelLog.Ln(); *)
- WHILE OHCI.TopologyMap[i] # NIL DO
- sid:= OHCI.TopologyMap[i]; c:= 0;
- IF sid.extended THEN
- esid:= sid (FirewireLowUtil.ExtSelfID);
- IF (esid.pa = {0,1}) THEN INC(children[i]) END;
- IF (esid.pb = {0,1}) THEN INC(children[i]) END;
- IF (esid.pc = {0,1}) THEN INC(children[i]) END;
- IF (esid.pd = {0,1}) THEN INC(children[i]) END;
- IF (esid.pe = {0,1}) THEN INC(children[i]) END;
- IF (esid.pf = {0,1}) THEN INC(children[i]) END;
- IF (esid.pg = {0,1}) THEN INC(children[i]) END;
- IF (esid.ph = {0,1}) THEN INC(children[i]) END;
- ELSE
- (* KernelLog.String("It's not an extended sid"); KernelLog.Ln(); *)
- IF (sid.p0 = {0,1}) THEN INC(children[i]) END;
- IF (sid.p1 = {0,1}) THEN INC(children[i]) END;
- IF (sid.p2 = {0,1}) THEN INC(children[i]) END;
- speed[i]:= SYSTEM.VAL(LONGINT,sid.sp);
- END;
- (* Check if there are more packets from this node *)
- IF ~(0 IN sid.m) THEN INC(i) END;
- END;
- (* Set the self mapping *)
- (* KernelLog.String("Initializing the speed map!"); KernelLog.Ln();
- KernelLog.String("Number of Nodes: ");KernelLog.Int(OHCI.numOfNodes,2); KernelLog.Ln(); *)
- FOR i:= 0 TO OHCI.numOfNodes-1 DO
- (* KernelLog.String("I is: "); KernelLog.Int(i,2); KernelLog.Ln();*)
- OHCI.SpeedMap[i][i]:= speed[i];
- END;
- (* KernelLog.String("Find out max communication speed!"); KernelLog.Ln(); *)
- (* count the total children of a node and find out the max comunication speed for each node pair *)
- i:= OHCI.numOfNodes-2;
- WHILE i >= 0 DO
- c:= children[i];
- FOR j:=1 TO c DO INC(children[i],children[i+j]);
- IF speed[i] < speed[i+j] THEN speed[i+j]:= speed[i] END;
- END;
- DEC(i);
- END;
- (* KernelLog.String("Complete speed map!"); KernelLog.Ln(); *)
- (* Fill speed capabilities in speed map *)
- i:= 0; j:= 0;
- FOR i:= 0 TO OHCI.numOfNodes-1 DO
- FOR j:= 0 TO OHCI.numOfNodes-1 DO
- IF i # j THEN
- OHCI.SpeedMap[i][j]:= speed[j]
- END
- END
- END;
- END BuildMaps;
- (** Transactions *)
- (** Creates a Lock packet *)
- PROCEDURE Lock1394(context: Contest; ohci: FirewireLowUtil.OHCIDesc; nodeID: SET; generation: LONGINT; addrLow, addrHigh: SET; extCode: LONGINT;
- VAR data: SET; VAR arg: SET):BOOLEAN;
- VAR packet: OHCIPacket; success: BOOLEAN;
- BEGIN
- success:= FALSE;
- packet:= FirewireLowUtil.MakeLockPacket(ohci,nodeID,addrLow,addrHigh,extCode,data,arg);
- (* Dump data
- KernelLog.String("Dumping the data:: Lock1394"); KernelLog.Ln();
- FOR i:= 0 TO (packet.dataSize DIV 4)-1 DO
- FirewireLowUtil.PrintSet(packet.data[i])
- END; *)
- packet.generation:= generation;
- IF (~SendPacket1394(context,packet)) THEN (* something went wrong, so try it again *)
- KernelLog.String("Something went wrong:: Lock1394"); KernelLog.Ln();
- OHCI.labeler.FreeTransLabel(packet.tLabel);
- RETURN success
- ELSE KernelLog.String("Everything ok::Lock1394"); KernelLog.Ln();
- END;
- success:= FirewireLowUtil.TestIfSuccess(packet);
- IF success THEN data:= packet.data[0] END;
- (* Release Packet *)
- OHCI.labeler.FreeTransLabel(packet.tLabel);
- OHCI.packetFIFO.ReleasePacket(packet);
- RETURN success
- END Lock1394;
- (** Creates a write packet *)
- PROCEDURE Write1394*(context: Contest; ohci: FirewireLowUtil.OHCIDesc; nodeID: SET; generation: LONGINT; VAR buffer: SET; addrLow, addrHigh: SET;
- length: LONGINT):BOOLEAN;
- VAR packet: OHCIPacket; success: BOOLEAN; tries: LONGINT;
- BEGIN
- success:= FALSE; tries:= 0;
- IF length = 0 THEN RETURN success END;
- (* KernelLog.String("Write1394"); KernelLog.Ln();
- FirewireLowUtil.PrintSet(addrHigh);
- FirewireLowUtil.PrintSet(addrLow); *)
- packet:= FirewireLowUtil.MakeWritePacket(ohci,nodeID,addrLow,addrHigh,buffer,length);
- packet.generation:= generation;
- WHILE (~success) & (tries < 4) DO
- (* IF (~SendPacket1394(context,packet)) THEN (* something went wrong, so try it again *)
- KernelLog.String("Something went wrong:: Write1394"); KernelLog.Ln();
- OHCI.labeler.FreeTransLabel(packet.tLabel);
- RETURN success
- ELSE (* KernelLog.String("Everything ok::Write1394"); KernelLog.Ln(); *) *)
- IF (SendPacket1394(context,packet)) THEN success:= TRUE
- ELSE INC(tries); KernelLog.String("Something went wrong:: Write1394"); KernelLog.Ln();
- END
- END;
- IF ~success THEN
- KernelLog.String("Something went wrong:: Write1394"); KernelLog.Ln();
- OHCI.labeler.FreeTransLabel(packet.tLabel);
- RETURN success
- END;
- success:= FirewireLowUtil.TestIfSuccess(packet);
- IF ~success THEN KernelLog.String("Not successfull:: Read1394"); KernelLog.Ln(); END;
- (* Release Packet *)
- OHCI.labeler.FreeTransLabel(packet.tLabel);
- OHCI.packetFIFO.ReleasePacket(packet);
- RETURN success
- END Write1394;
- (** Creates a read packet *)
- PROCEDURE Read1394*(context: Contest; ohci: FirewireLowUtil.OHCIDesc; nodeID: SET;generation: LONGINT; addrLow,addrHigh:SET;
- VAR buffer: SET; length: LONGINT):BOOLEAN;
- VAR packet: OHCIPacket; success: BOOLEAN; tries,i: LONGINT;
- BEGIN
- (* KernelLog.String("Read1394"); KernelLog.Ln(); *)
- success:= FALSE; tries:= 0;
- IF length = 0 THEN RETURN success END;
- packet:= FirewireLowUtil.MakeReadPacket(ohci,nodeID,addrLow,addrHigh,length);
- packet.generation:= generation;
- WHILE (~success) & (tries < 4) DO
- (*IF (~SendPacket1394(context,packet)) THEN (* something went wrong, so try it again *)
- KernelLog.String("Something went wrong:: Read1394"); KernelLog.Ln();
- OHCI.labeler.FreeTransLabel(packet.tLabel);
- RETURN success
- ELSE (* KernelLog.String("Everything ok::Read1394"); KernelLog.Ln(); *) *)
- IF (SendPacket1394(context,packet)) THEN success:= TRUE
- ELSE INC(tries)
- END
- END;
- IF ~success THEN
- KernelLog.String("Something went wrong:: Read1394"); KernelLog.Ln();
- OHCI.labeler.FreeTransLabel(packet.tLabel);
- RETURN success
- END;
- success:= FirewireLowUtil.TestIfSuccess(packet);
- IF success THEN
- (* KernelLog.String("Packet was successfull::read1394"); KernelLog.Ln(); *)
- IF length = 4 THEN (* It's a read quadlet packet *)
- buffer:= packet.header[3];
- ELSE (* It's a read block packet *) (* in this case buffer is an address *)
- FOR i:= 0 TO (length DIV 4)-1 DO
- SYSTEM.PUT32(ConvertToLongint(buffer) + i*4,packet.data[i])
- END
- END
- ELSE KernelLog.String("Packet was not successfull!"); KernelLog.Ln();
- END;
- (* Release Packet *)
- OHCI.labeler.FreeTransLabel(packet.tLabel);
- OHCI.packetFIFO.ReleasePacket(packet);
- RETURN success
- END Read1394;
- (** Node manager relative part *)
- (** Sends a read quadlet packet *)
- PROCEDURE NodeManagerReadQ(context: Contest; host:FirewireLowUtil.OHCIDesc; nodeID: SET; generation: LONGINT;
- addrLow,addrHigh: SET; VAR quad: SET):BOOLEAN;
- VAR success: BOOLEAN; i: LONGINT;
- BEGIN
- success:= FALSE; i:= 0;
- WHILE ~success & (i < 4) DO
- success:= Read1394(context,host,nodeID,generation,addrLow,addrHigh,quad,4);
- IF ~success THEN INC(i) END;
- END;
- IF i>=1 THEN KernelLog.String("Something went wrong::NodeManagerReadQ"); KernelLog.Ln()
- ELSE (* KernelLog.String("Everything ok::NodeManagerReadQ"); KernelLog.Ln(); *)
- END;
- RETURN success
- END NodeManagerReadQ;
- (** Reads the bus info block of a node *)
- PROCEDURE ReadBusInfoBlock(host: FirewireLowUtil.OHCIDesc; nodeID: SET; generation: LONGINT; VAR buffer: ARRAY OF SET;
- bufferLength: LONGINT):BOOLEAN;
- VAR addrLow,addrHigh, base: SET; i, headerSize: LONGINT; vendorID: LONGINT; context: Contest;
- BEGIN
- addrHigh:= FirewireLowUtil.CSRBaseHigh;
- addrLow:= FirewireLowUtil.CSRBaseLow + FirewireLowUtil.CSRConfigRom;
- (*
- KernelLog.String("The base low address is: "); FirewireLowUtil.PrintSet(addrLow); KernelLog.Ln();
- KernelLog.String("The base high address is: "); FirewireLowUtil.PrintSet(addrHigh); KernelLog.Ln();
- KernelLog.String("Reading bus info block of node with nodeID: "); KernelLog.Int(SYSTEM.VAL(LONGINT,nodeID),2);
- KernelLog.Ln(); *)
- buffer[0]:= {};
- context:= OHCI.ATController.GetReqContest();
- (* sometimes the device is not ready yet *)
- WHILE (buffer[0] = {}) & (i<1) DO
- IF ~NodeManagerReadQ(context,host,nodeID,generation,addrLow,addrHigh,buffer[0]) THEN
- KernelLog.String("Quadlet read error!"); KernelLog.Ln(); INC(i) END;
- END;
- (* KernelLog.String("(((((((((((((((((((((((((Going on))))))))))))))))))))))))))))))))"); KernelLog.Ln(); *)
- IF i>=1 THEN KernelLog.String("Error: DEVICE was not ready::ReadBusInfoBlock!");KernelLog.Ln();
- RETURN TRUE
- END;
- headerSize:= SYSTEM.VAL(LONGINT,LSH(buffer[0],-24));
- (* Increment address *)
- addrLow:= SYSTEM.VAL(SET,SYSTEM.VAL(LONGINT,addrLow)+4);
- IF headerSize = 1 THEN
- (* KernelLog.String("Node has a minimal rom format!"); KernelLog.Ln(); *)
- vendorID:= SYSTEM.VAL(LONGINT,buffer[0]*{0..23});
- (* KernelLog.String("The vendor ID is: "); KernelLog.Int(vendorID,2); KernelLog.Ln(); *)
- RETURN FALSE
- END;
- IF headerSize < 4 THEN
- KernelLog.String("Non standard rom format, cannot parse!"); KernelLog.Ln(); RETURN TRUE
- END;
- FOR i:= 1 TO bufferLength-1 DO
- (* KernelLog.String("Reading the quadlet number: "); KernelLog.Int(i,2); KernelLog.Ln(); *)
- IF ~NodeManagerReadQ(context,host,nodeID,generation,addrLow,addrHigh,buffer[i]) THEN
- KernelLog.String("Quadlet read error!"); KernelLog.Ln(); RETURN TRUE
- END;
- addrLow:= base + SYSTEM.VAL(SET,SYSTEM.VAL(LONGINT,addrLow)+4);
- END;
- vendorID:= SYSTEM.VAL(LONGINT,LSH(buffer[3],-8));
- (* KernelLog.String("The vendorID is "); KernelLog.Int(vendorID,2); KernelLog.Ln(); *)
- RETURN FALSE;
- END ReadBusInfoBlock;
- (** End node manager relative part *)
- (** Prints OHCI information *)
- PROCEDURE PrintOHCIInfo;
- VAR reg: SET; val: LONGINT;
- BEGIN
- reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.Version);
- KernelLog.String("Printing the OHCI information:"); KernelLog.Ln();
- val:= LSH(ConvertToLongint(reg*{16..23}),-16);
- KernelLog.String("OHCI version: "); KernelLog.Int(val,2); KernelLog.Ln();
- val:= ConvertToLongint(reg*{0..7});
- KernelLog.String("OHCI revision: "); KernelLog.Int(val,2); KernelLog.Ln();
- IF 24 IN reg THEN KernelLog.String("The OHCI has an GUIDROM"); KernelLog.Ln(); END;
- KernelLog.String("The OHCI is on interrupt: "); KernelLog.Int(irq,2); KernelLog.Ln();
- KernelLog.String("The max packet size is: "); KernelLog.Int(OHCI.MaxPacketSize,2); KernelLog.Ln();
- IF OHCI.ExstRegMap THEN
- KernelLog.String("The OHCI has an exstended register map conform to 1394a."); KernelLog.Ln();
- ELSE KernelLog.String("The OHCI has no exstended register map."); KernelLog.Ln();
- END;
- IF OHCI.IsRoot THEN
- KernelLog.String("The OHCI is root."); KernelLog.Ln();
- ELSE KernelLog.String("The OHCI is not root."); KernelLog.Ln()
- END;
- IF OHCI.IsIRM THEN
- KernelLog.String("The OHCI is isochronous resource manager"); KernelLog.Ln();
- ELSE KernelLog.String("The OHCI is not isochronous resource manager"); KernelLog.Ln()
- END;
- IF OHCI.IsBM THEN
- KernelLog.String("The OHCI is bus manager"); KernelLog.Ln();
- ELSE KernelLog.String("The OHCI is not bus manager"); KernelLog.Ln()
- END
- END PrintOHCIInfo;
- (** Tests if access to a register was successfull *)
- PROCEDURE TestAccess(name:ARRAY OF CHAR); (* not used *)
- VAR reg:SET;
- BEGIN
- reg := FirewireLowUtil.ReadReg(FirewireLowUtil.IntEvent);
- IF(18 IN reg) THEN KernelLog.String("RegAccess ");KernelLog.String(name);KernelLog.String(" failed");KernelLog.Ln;
- ELSE KernelLog.String("RegAccess ");KernelLog.String(name);KernelLog.String(" successfull");KernelLog.Ln;
- END
- END TestAccess;
- (** Removes the interrupt handler *)
- PROCEDURE Cleanup;
- BEGIN
- Objects.RemoveHandler(HandleInterrupt,Machine.IRQ0+irq);
- END Cleanup;
- END Controller;
- VAR c*:Controller;
- (** Procedure to print the specifier ID of a node; not used *)
- PROCEDURE ScanRomOfNodes*;
- VAR j,i:LONGINT; node: FirewireLowUtil.Node;
- BEGIN
- c.ScanNodes();
- (* Printing the content of the nodes array *)
- i:= 0; j:= 0;
- WHILE c.OHCI.Nodes[i] # NIL DO
- node:= c.OHCI.Nodes[i];
- KernelLog.String("Printing the guid: "); KernelLog.Ln();
- (* FirewireLowUtil.PrintSet(node.guid.high); FirewireLowUtil.PrintSet(node.guid.low); *)
- KernelLog.String("Printing the unit directories if there are any"); KernelLog.Ln();
- WHILE node.uds[j] # NIL DO
- KernelLog.String("Printing the specifier id: "); KernelLog.Int(node.uds[j].specifierID,2); KernelLog.Ln();
- INC(j);
- END;
- INC(i);
- END;
- END ScanRomOfNodes;
- (** Test procedure to send a ping packet *)
- PROCEDURE SendPingPacket*;
- VAR context: Contest;set0,set1,set2,set3,set4,set5,set6,set7: SET;
- dataSize: LONGINT; packet: OHCIPacket; block: FirewireLowUtil.Block;
- BEGIN
- context:= c.OHCI.ATController.GetReqContest();
- set0:= {28} + {25} + {23} + {20,21} + {18,19} + {2,3};
- set1:= {};
- set2:= {};
- set3:= {};
- set4:= {5,6,7};
- set5:= {};
- set6:= -set5;
- set7:= {};
- packet.type:= FirewireLowUtil.async;
- dataSize:= 0;
- block.start:= context.prgr.bufferAddr;
- block.end:= block.start;
- SYSTEM.PUT32(context.prgr.bufferAddr,set0);
- SYSTEM.PUT32(context.prgr.bufferAddr+4,set1);
- SYSTEM.PUT32(context.prgr.bufferAddr+8,set2);
- SYSTEM.PUT32(context.prgr.bufferAddr+12,set3);
- SYSTEM.PUT32(context.prgr.bufferAddr+16,set4);
- SYSTEM.PUT32(context.prgr.bufferAddr+20,set5);
- SYSTEM.PUT32(context.prgr.bufferAddr+24,set6);
- SYSTEM.PUT32(context.prgr.bufferAddr+28,set7);
- packet.block:= block;
- FirewireLowUtil.WriteReg(context.cmdPtr,FirewireLowUtil.ConvertToSet(context.prgr.bufferAddr+2));
- FirewireLowUtil.WriteReg(context.ctrlSet,{15});
- context.listInserted.AddPacket(packet);
- END SendPingPacket;
- (** Test procedure to send a read packet *)
- PROCEDURE SendReadPacket*;
- VAR context: Contest; set0, set1, set2, set3, set4, set5, set6, set7: SET;
- dataSize: LONGINT; packet: OHCIPacket; block: FirewireLowUtil.Block;
- BEGIN
- context:= c.OHCI.ATController.GetReqContest();
- set0:= {28} + {25} + {20,21} + {18,19} + {2,3};
- set1:= {};
- set2:= {};
- set3:= {};
- set4:= {8} + {6};
- set5:= {22..31} + {0..15};
- set6:= {28..31} + {2,3,4,9}; (* bus manager id *)
- set7:= {};
- NEW(packet,16,0);
- packet.type:= FirewireLowUtil.async;
- packet.tLabel:= {}; packet.tCode:= {2};
- dataSize:= 0;
- block.start:= context.prgr.bufferAddr;
- block.end:= block.start;
- packet.header[0]:= set4;
- packet.header[1]:= set5;
- packet.header[2]:= set6;
- packet.header[3]:= set7;
- packet.name:= "vito";
- SYSTEM.PUT32(context.prgr.bufferAddr,set0);
- SYSTEM.PUT32(context.prgr.bufferAddr+4,set1);
- SYSTEM.PUT32(context.prgr.bufferAddr+8,set2);
- SYSTEM.PUT32(context.prgr.bufferAddr+12,set3);
- SYSTEM.PUT32(context.prgr.bufferAddr+16,set4);
- SYSTEM.PUT32(context.prgr.bufferAddr+20,set5);
- SYSTEM.PUT32(context.prgr.bufferAddr+24,set6);
- SYSTEM.PUT32(context.prgr.bufferAddr+28,set7);
- packet.block:= block;
- FirewireLowUtil.WriteReg(context.cmdPtr,FirewireLowUtil.ConvertToSet(context.prgr.bufferAddr+2));
- context.listInserted.AddPacket(packet);
- context.listAwaiting.AddPacket(packet);
- IF ~context.listAwaiting.GetPacket(packet) THEN
- KernelLog.String("Printing packet name: "); KernelLog.String(packet.name); KernelLog.Ln()
- ELSE
- KernelLog.String("We have a problem"); KernelLog.Ln()
- END;
- FirewireLowUtil.WriteReg(context.ctrlSet,{15});
- END SendReadPacket;
- (** Send a compare swap lock packet to hd to access maint-utility register *)
- PROCEDURE SendLockPacket*;
- VAR nodeID: SET; context: Contest; generation: LONGINT; addrLow, addrHigh: SET; extCode: LONGINT; data, arg: SET;
- BEGIN
- extCode:= 2H; (* compare swap extended transaction code *)
- addrLow:= FirewireLowUtil.CSRBaseLow; addrHigh:= FirewireLowUtil.CSRBaseHigh;
- (* set the address of the maint utility register *)
- addrLow:= addrLow + {4,5,9};
- context:= c.OHCI.ATController.GetReqContest();
- nodeID:= {};
- generation:= FirewireLowUtil.GetGeneration();
- data:= {0..31}; arg:= {};
- IF c.Lock1394(context,c.OHCI,nodeID,generation,addrLow,addrHigh,extCode,data,arg) THEN
- KernelLog.String("First read was successfull::SendLockPacket"); KernelLog.Ln();
- KernelLog.String("Printing old value: "); FirewireLowUtil.PrintSet(data); KernelLog.Ln()
- ELSE
- KernelLog.String("Something went wrong::SendLockPacket"); KernelLog.Ln();
- END;
- END SendLockPacket;
- (** Test procedure to send a write packet *)
- PROCEDURE SendWritePacket*;
- VAR nodeID: SET; context: Contest; generation: LONGINT; addrLow, addrHigh: SET;
- buffer: ARRAY 1 OF SET;
- BEGIN
- addrLow:= FirewireLowUtil.CSRBaseLow; addrHigh:= FirewireLowUtil.CSRBaseHigh;
- (* set the address of the maint utility register *)
- addrLow:= addrLow + {4,5,9};
- context:= c.OHCI.ATController.GetReqContest();
- nodeID:= {};
- buffer[0]:= {0..31};
- generation:= FirewireLowUtil.GetGeneration();
- IF c.Write1394(context,c.OHCI,nodeID,generation,buffer[0],addrLow,addrHigh,4) THEN
- KernelLog.String("Write was successfull::SendWritePacket"); KernelLog.Ln();
- (* KernelLog.String("Printing old value: "); FirewireLowUtil.PrintSet(data); KernelLog.Ln() *)
- ELSE
- KernelLog.String("Something went wrong::SendLockPacket"); KernelLog.Ln();
- END;
- END SendWritePacket;
- (** Test procedure to read the bus info block *)
- PROCEDURE Test1394*;
- VAR ohci: FirewireLowUtil.OHCIDesc; generation: LONGINT; sid: FirewireLowUtil.SelfID;
- buffer: ARRAY 4 OF SET; i: LONGINT;
- BEGIN
- ohci:= c.OHCI; generation:= FirewireLowUtil.GetGeneration(); i:= 0;
- WHILE ohci.TopologyMap[i] # NIL DO
- IF ~(ohci.TopologyMap[i] IS FirewireLowUtil.ExtSelfID) &
- (SYSTEM.VAL(LONGINT,ohci.TopologyMap[i].physicalID) # c.OHCI.nodeID) THEN
- sid:= ohci.TopologyMap[i];
- IF c.ReadBusInfoBlock(ohci,sid.physicalID,generation,buffer,4) THEN
- KernelLog.String("There was a problem reading the bus info block::Test1394!"); KernelLog.Ln()
- END
- END;
- INC(i);
- END;
- END Test1394;
- (** Scan the PCI for 1394 devices *)
- PROCEDURE ScanPCI(vendor,device: LONGINT);
- VAR index, bus, dev, fct, base, irq: LONGINT; res: WORD;
- BEGIN
- index := 0;
- WHILE(PCI.FindPCIDevice(device, vendor, index, bus, dev, fct) = PCI.Done) (*?*)
- DO
- (* KernelLog.String("Ok");
- KernelLog.Ln; *)
- res := PCI.ReadConfigDword(bus,dev,fct,PCI.Adr0Reg,base);
- ASSERT(res = PCI.Done);
- ASSERT(~ODD(base)); (* Operational registers mapped correctly in main memory memory space *)
- DEC(base, base MOD 16);
- Machine.MapPhysical(base,800H,SYSTEM.VAL(ADDRESS,base));
- res := PCI.ReadConfigByte(bus,dev,fct,PCI.IntlReg,irq);
- (* KernelLog.Int(irq,2);
- KernelLog.Ln; *)
- ASSERT(res = PCI.Done);
- INC(index);
- (* Set base in helper module *)
- (* KernelLog.Int(base,2); *)
- FirewireLowUtil.SetBase(base);
- NEW(c,base,irq);
- END;
- END ScanPCI;
- (** Dummy procedure *)
- PROCEDURE Install*;
- END Install;
- (** Cleanup procedure *)
- PROCEDURE Cleanup;
- BEGIN
- c.Cleanup();
- END Cleanup;
- (** Module initialization procedure *)
- PROCEDURE Init;
- BEGIN
- (* KernelLog.String("Entering ScanPCI");
- KernelLog.Ln; *)
- ScanPCI(1106H,3044H);
- END Init;
- BEGIN
- Modules.InstallTermHandler(Cleanup);
- Init
- END FirewireLow.
- System.Free FirewireLow~
- Builder.Compile \s *
- Aos.Call FirewireLow.Install ~
- Aos.Call FirewireLowUtil.PrintSelfIDCount ~
- Aos.Call FirewireLow.TestReset ~
- System.OpenKernelLog
|