14#include "iLink_internal.h"
16extern int IntrEventFlag;
17extern unsigned short int LocalNodeID;
18extern int NodeCapabilities;
20extern int GenerationNumber;
23extern void (*CallBackFunction)(
int reason,
unsigned int offset,
unsigned int size);
25extern unsigned int *ConfigurationROM;
26extern unsigned int ConfigurationROMSize;
28unsigned int *TargetBuffer, NodeData[63];
29unsigned int LocalCachedIntr0Register;
31unsigned char IsBusRoot = 1;
33static void NoResponseHandler(
unsigned int header,
volatile unsigned int *buffer,
unsigned int nQuads)
40 DEBUG_PRINTF(
"NULL response handler called.\n");
42 for (i = 0; i < nQuads; i++) {
43#ifdef DEBUG_TTY_FEEDBACK
46 DEBUG_PRINTF(
"Unhandled data: 0x%08x.\n", data);
51static void PHYPacketHandler(
unsigned int header,
volatile unsigned int *buffer,
unsigned int nQuads)
55 DEBUG_PRINTF(
"Received PHY packet.\n");
57 if (header == PHY_SELF_ID_PACKET) {
60 while (nQuads-- > 0) {
61 if (data == PHY_SELF_ID_PACKET) {
62 DEBUG_PRINTF(
"Receiving SELFID packets...\n");
64 }
else if ((data != 1) && (data != 0xE)) {
65 if ((data >> 30) == 2) {
66 DEBUG_PRINTF(
"SELFID received from Node 0x%04x. Speed: 0x%02x. Power: 0x%02x.\n", SELF_ID_NODEID(data), SELF_ID_SPEED(data), SELF_ID_POWER(data));
67 NodeData[nNodes] = data;
70 DEBUG_PRINTF(
"Unknown quad received in SELF-ID phase: 0x%08x.\n", data);
74 LocalNodeID = ILINKRegisterBase->NodeID >> 16;
76 IsBusRoot = (ILINKRegisterBase->ctrl0 & iLink_CTRL0_Root) ? 1 : 0;
78 DEBUG_PRINTF(
"Local Node ID: 0x%04x.\n", LocalNodeID);
79 SetEventFlag(IntrEventFlag, iLinkEventGotSELFIDs);
80 if (CallBackFunction != NULL)
81 CallBackFunction(iLink_CB_BUS_RESET, 0, 0);
86 }
else if (header == PHY_CONFIG_PACKET) {
93 if (PHY_CONFIG_T(data)) {
94 DEBUG_PRINTF(
"gap count: %d.\n", PHY_CONFIG_GAP_CNT(data));
97 DEBUG_PRINTF(
"DEBUG: Unknown PHY packet type: 0x%8x.\n", header);
98 NoResponseHandler(header, buffer, nQuads);
102static void ResponseHandler(
unsigned int header,
volatile unsigned int *buffer,
unsigned int nQuads)
104 unsigned int i, HeaderLength;
110 tCode = (header >> 4) & 0xF;
112 HeaderLength = (tCode != IEEE1394_TCODE_WRITE_RESPONSE) ? 4 : 3;
114 ResponseData.header = header;
115 for (i = 1; i < HeaderLength; i++) {
116 ((
unsigned int *)&ResponseData)[i] = *buffer;
120 case IEEE1394_TCODE_WRITE_RESPONSE:
121 DEBUG_PRINTF(
"Data write result: ");
123 case IEEE1394_TCODE_READQ_RESPONSE:
124 DEBUG_PRINTF(
"Writing to buffer %p.\n", TargetBuffer);
125 DEBUG_PRINTF(
"Quadlet read result: ");
126 *TargetBuffer = BSWAP32(ResponseData.LastField);
128 case IEEE1394_TCODE_READB_RESPONSE:
129 DEBUG_PRINTF(
"Block read result: ");
132 DEBUG_PRINTF(
"Unknown IEE1394 transaction type 0x%02x result: ", (ResponseData.header >> 10) & 0x3F);
135 DEBUG_PRINTF(
"%u.\n", (ResponseData.header2 >> 12) & 0xF);
136 if (tCode == IEEE1394_TCODE_READB_RESPONSE) {
137 DEBUG_PRINTF(
"data length: 0x%08x.\n", ResponseData.LastField >> 16);
138 for (i = 0; i < (ResponseData.LastField >> 16); i += 4) {
139 *TargetBuffer = *buffer;
145 SetEventFlag(IntrEventFlag, iLinkEventDataReceived);
148static void WriteRequestHandler(
unsigned int header,
volatile unsigned int *buffer,
unsigned int nQuads)
151 unsigned int QuadsToRead, data;
153 unsigned char rCode, tLabel;
157 DEBUG_PRINTF(
"Incoming write request. Header: 0x%08x; Buffer: 0x%p; nQuads: 0x%08x.\n", header, buffer, nQuads);
161 WriteReqHeader.header = header;
163 if (((header >> 4) & 0xF) == IEEE1394_TCODE_WRITEQ) {
165 WriteReqHeader.misc = 4;
166 DEBUG_PRINTF(
"Quadlet");
168 DEBUG_PRINTF(
"Block");
171 for (i = 1; i < QuadsToRead; i++) {
173 ((
unsigned int *)(&WriteReqHeader))[i] = data;
176 WriteReqHeader.misc >>= 16;
178 DEBUG_PRINTF(
" write request to 0x%08x %08x with length %u.\n", WriteReqHeader.offset_high, WriteReqHeader.offset_low, WriteReqHeader.misc);
181#ifdef REQ_CHECK_MEM_BOUNDARIES
182 if (WriteReqHeader.offset_low < 0x00200000) {
184 for (i = 0; i < (WriteReqHeader.misc >> 2); i++) {
186 ((
unsigned int *)WriteReqHeader.offset_low)[i] = data;
188#ifdef REQ_CHECK_MEM_BOUNDARIES
190 DEBUG_PRINTF(
"Invalid write request.");
197 tLabel = (header >> 10) & 0x3F;
198 SendResponse(WriteReqHeader.offset_high >> 16, (header >> 16) >> 6, rCode, tLabel, IEEE1394_TCODE_WRITE_RESPONSE, (data >> 16) & 0x7, NULL, 0);
200 DEBUG_PRINTF(
"Response sent.\n");
202 if (CallBackFunction != NULL)
203 CallBackFunction(iLink_CB_WRITE_REQUEST, WriteReqHeader.offset_low, WriteReqHeader.misc);
209 unsigned int offset_high;
210 unsigned int offset_low;
218 unsigned int trailer;
225 unsigned int trailer;
228static void ReadRequestHandler(
unsigned int header,
volatile unsigned int *buffer,
unsigned int nQuads)
230 unsigned int QuadsToRead, offset_low, offset_high, nBytes;
231 unsigned int ReadReqHeader[5];
233 unsigned short int DestinationNodeID;
234 unsigned char tCode, speed, rCode, tLabel;
239 DEBUG_PRINTF(
"Incoming read request. Header: 0x%08x; Buffer: 0x%p; nQuads: 0x%08x.\n", header, buffer, nQuads);
242 ReadReqHeader[0] = header;
243 tCode = (header >> 4) & 0xF;
244 if (tCode == IEEE1394_TCODE_READQ) {
246 DEBUG_PRINTF(
"Quadlet");
249 DEBUG_PRINTF(
"Block");
252 for (i = 1; i < QuadsToRead; i++) {
253 ReadReqHeader[i] = *buffer;
256 if (tCode == IEEE1394_TCODE_READB) {
259 DestinationNodeID = BSWAP16((
unsigned short int)offset_high);
263 DestinationNodeID = (
unsigned short int)(offset_high >> 16);
266 if (tCode == IEEE1394_TCODE_READQ) {
274 DEBUG_PRINTF(
" read request to 0x%08x %08x with length %u.\n", offset_high, offset_low, nBytes);
276#ifdef REQ_CHECK_MEM_BOUNDARIES
277 if (((offset_high & 0x0000FFFF) == 0x0000FFFF) && ((offset_low & 0xF0000000) == 0xF0000000)) {
279 offset_low &= 0x0FFFFFFF;
280 if ((offset_low - 0x400) < ConfigurationROMSize) {
282 offset_low = (
unsigned int)ConfigurationROM + (offset_low - 0x400);
284#ifdef REQ_CHECK_MEM_BOUNDARIES
286 DEBUG_PRINTF(
"Read request is beyond the range of the configuration ROM.\n");
290 }
else if ((offset_low >= 0x00200000) || (offset_low == 0)) {
291 DEBUG_PRINTF(
"Invalid read request.");
297 tCode = (tCode == IEEE1394_TCODE_READQ) ? IEEE1394_TCODE_READQ_RESPONSE : IEEE1394_TCODE_READB_RESPONSE;
298 tLabel = (header >> 10) & 0x3F;
299 SendResponse(DestinationNodeID, DestinationNodeID >> 6, rCode, tLabel, tCode, speed, (
unsigned int *)offset_low, nBytes >> 2);
301 DEBUG_PRINTF(
"Response sent!2.\n");
303 if (CallBackFunction != NULL)
304 CallBackFunction(iLink_CB_READ_REQUEST, offset_low, nBytes);
307const void *RequestHandlers[] = {
308 &WriteRequestHandler,
309 &WriteRequestHandler,
326int iLinkIntrHandler(
void *arg)
328 unsigned int LocalCachedIntr1Register, EventFlagBitsToSet;
329#ifdef REQ_CHECK_DMAC_STAT
337 ILINKRegisterBase->intr0 = LocalCachedIntr0Register = ILINKRegisterBase->intr0 & ILINKRegisterBase->intr0Mask;
338 ILINKRegisterBase->intr1 = LocalCachedIntr1Register = ILINKRegisterBase->intr1 & ILINKRegisterBase->intr1Mask;
340 if (!LocalCachedIntr0Register && !LocalCachedIntr1Register)
343 EventFlagBitsToSet = 0;
345 DEBUG_PRINTF(
"iLink interrupt: 0x%08x 0x%08x\n", LocalCachedIntr0Register, LocalCachedIntr1Register);
347 if (LocalCachedIntr1Register & iLink_INTR1_UTD)
348 EventFlagBitsToSet |= iLinkEventDataSent;
350#ifdef REQ_CHECK_DMAC_STAT
351 if (LocalCachedIntr0Register & iLink_INTR0_DRFR) {
352 iDEBUG_PRINTF(
"Handling DBUF FIFO data...\n");
354 for (i = 0; i < 3; i++) {
355 iDEBUG_PRINTF(
"DMA Channel %d CHCR: 0x%08x MADR: 0x%08x DLEN: 0x%05x SLICE: 0x%03x\n", 13 + i, iLinkDMACRegs[i].chcr, iLinkDMACRegs[i].madr, iLinkDMACRegs[i].dlen, iLinkDMACRegs[i].slice);
357 if ((i > 0) && !(iLinkDMACRegs[i].chcr & DMAC_CHCR_AR)) {
358 iLinkDMACRegs[i].chcr = 0;
361 ILINKRegisterBase->dmaCtrlSR0 = 0;
364 ILINKRegisterBase->dmaCtrlSR1 = 0;
368 iDEBUG_PRINTF(
"DMAC Channel %d stalled. Flushing FIFOs and reseting PHTs.\n", 13 + i);
376 if (LocalCachedIntr0Register & iLink_INTR0_PhyRst) {
377 iDEBUG_PRINTF(
"-=Bus reset start detected=-\n");
382 EventFlagBitsToSet |= (iLinkEventBusReady | iLinkEventBusReset);
384 iDEBUG_PRINTF(
"-=PHTs initialized=-\n");
387 if (LocalCachedIntr0Register & iLink_INTR0_URx) {
388 EventFlagBitsToSet |= iLinkEventURx;
391 if (LocalCachedIntr0Register & (iLink_INTR0_InvAck | iLink_INTR0_RetEx | iLink_INTR0_UResp)) {
392 EventFlagBitsToSet |= iLinkEventError;
393 iDEBUG_PRINTF(
"-=Missing/invalid response detected=-\n");
397#ifdef REQ_CHECK_ERRORS
398 if (LocalCachedIntr0Register & iLink_INTR0_HdrErr) {
399 iDEBUG_PRINTF(
"-=HdrErr=-\n");
402 if (LocalCachedIntr0Register & iLink_INTR0_SntBsyAck) {
403 iDEBUG_PRINTF(
"-=iLink_INTR0_SntBsyAck=-\n");
407 if (LocalCachedIntr0Register & iLink_INTR0_PBCntR) {
408 EventFlagBitsToSet |= iLinkEventDMATransEnd;
409 iDEBUG_PRINTF(
"-=End of DMA transfer=-\n");
412 if (LocalCachedIntr0Register & iLink_INTR0_CmdRst) {
413 iDEBUG_PRINTF(
"-=CmdRst=-\n");
417 iSetEventFlag(IntrEventFlag, EventFlagBitsToSet);