PS2SDK
PS2 Homebrew Libraries
iLink_DMA.c
1 /* iLink_PHT.c
2  * Purpose: Contains the functions related to IEEE1394 read/write requests that are to be generated by PHT 00, and functions related to initializing both PHTs and DMAC #3.
3  * Only block reads and writes are supported by functions in this files.
4  *
5  * Last Updated: 2012/02/22
6  * Programmer: SP193
7  */
8 
9 #include <dmacman.h>
10 #include <stdio.h>
11 #include <sysmem.h>
12 #include <thbase.h>
13 #include <thevent.h>
14 
15 #include "iLinkman.h"
16 #include "iLink_internal.h"
17 
18 extern unsigned short int LocalNodeID;
19 extern int IntrEventFlag;
20 
21 extern int GenerationNumber;
22 
23 extern struct ILINKMemMap *ILINKRegisterBase;
24 extern unsigned int *TargetBuffer;
25 extern unsigned int LocalCachedIntr0Register;
26 
27 struct DMAChannelRegBlock *iLinkDMACRegs = (struct DMAChannelRegBlock *)ILINK_DMAC_REGISTER_BASE;
28 struct DMARRegBlock *iLinkDMARRegs = (struct DMARRegBlock *)ILINK_DMAC_DMAR_CTRL_BASE;
29 
30 static int iLinkPHTSendData(struct TransactionContextData *trContext, unsigned char tCode, unsigned short int offset_high, unsigned int offset_low, unsigned int *payload, unsigned int nBytes, char ByteSwap);
31 
32 void iLinkInitPHT(void)
33 {
34  /* Stop all DMA-related activities */
35  iLinkDMACRegs[0].chcr = iLinkDMACRegs[2].chcr = 0;
36 
37  ILINKRegisterBase->PHT_ctrl_ST_R0 = PHT_CTRL_ST_PHTRst; /* Reset PHT 00 */
38  ILINKRegisterBase->PHT_ctrl_ST_R1 = PHT_CTRL_ST_PHTRst; /* Reset PHT 01 */
39 
40  while ((ILINKRegisterBase->PHT_ctrl_ST_R0 & PHT_CTRL_ST_PHTRst) || (ILINKRegisterBase->PHT_ctrl_ST_R1 & PHT_CTRL_ST_PHTRst)) {};
41 
42  ILINKRegisterBase->dmar = 0x00000020; /* DMA space is within the 2MB of IOP memory. */
43  ILINKRegisterBase->PHT_ctrl_ST_R1 = PHT_CTRL_ST_EnDMAS | PHT_CTRL_ST_IHdr; /* EnDMAS | IHdr */
44  ILINKRegisterBase->PHT_ctrl_ST_R0 = 0;
45 
46  ILINKRegisterBase->STRxNIDSel0_R1 = ILINKRegisterBase->STRxNIDSel1_R1 = 0xFFFFFFFF; /* Accept DMA transfers from all nodes. */
47  ILINKRegisterBase->STRxNIDSel0_R0 = ILINKRegisterBase->STRxNIDSel1_R0 = 0; /* Reject DMA transfers from all nodes. */
48 
49  iLinkDMACRegs[0].slice = iLinkDMACRegs[2].slice = 0x400;
50  iLinkDMACRegs[2].chcr = DMAC_CHCR_AR | DMAC_CHCR_CO;
51 
52  iLinkDMACRegs[0].DmarReadStart = iLinkDMACRegs[2].DmarReadStart = iLinkDMARRegs->DmarWriteStart = 0x00000800;
53  iLinkDMACRegs[0].DmarReadEnd = iLinkDMACRegs[2].DmarReadEnd = iLinkDMARRegs->DmarWriteEnd = 0x00200000;
54 
55  ILINKRegisterBase->dmaTransTRSH0 = 0x03FF0000;
56  ILINKRegisterBase->dmaTransTRSH1 = 0x000F03FF;
57  ILINKRegisterBase->dmaCtrlSR0 = ILINKRegisterBase->dmaCtrlSR1 = iLinkDMA_CTRL_SR_LFirst | iLinkDMA_CTRL_SR_DWidth(2) | iLinkDMA_CTRL_SR_DEn | iLinkDMA_CTRL_SR_RActl;
58 
59  ILINKRegisterBase->PHT_split_TO_R1 = ILINKRegisterBase->PHT_split_TO_R0 = 0x00000800; /* STO: 0x800 */
60 }
61 
62 static int iLinkPHTSendData(struct TransactionContextData *trContext, unsigned char tCode, unsigned short int offset_high, unsigned int offset_low, unsigned int *payload, unsigned int nBytes, char ByteSwap)
63 {
64  unsigned char tLabel;
65  unsigned int PHT_ctrl_ST_R0_flags;
66 
67  (void)ByteSwap;
68 
69  if (trContext->GenerationNumber != GenerationNumber)
70  return (-1021);
71 
72  ClearEventFlag(IntrEventFlag, ~(iLinkEventDMATransEnd | iLinkEventError));
73 
74  PHT_ctrl_ST_R0_flags = (tCode == IEEE1394_TCODE_WRITEB) ? PHT_CTRL_ST_EPCNT | PHT_CTRL_ST_EWREQ : PHT_CTRL_ST_EPCNT | PHT_CTRL_ST_ERREQ; /* EWReq and EPCnt, OR ERReq and EPCnt. */
75  tLabel = 0x3F; /* PHT 00 */
76 
77  ILINKRegisterBase->PHT_ReqResHdr0_R0 = (((unsigned int)trContext->NodeID) << 16) | offset_high;
78  ILINKRegisterBase->PHT_ReqResHdr1_R0 = offset_low;
79  ILINKRegisterBase->PHT_ReqResHdr2_R0 = (((unsigned int)tLabel) << 19) | (((unsigned int)trContext->speed) << 16) | nBytes;
80 
81  ILINKRegisterBase->DTransCTRL0 = 1; /* Only 1 packet. */
82  ILINKRegisterBase->PHT_ctrl_ST_R0 |= PHT_ctrl_ST_R0_flags;
83 
84  iLinkDMACRegs[0].madr = (unsigned int)payload;
85  iLinkDMACRegs[0].dlen = nBytes;
86  iLinkDMACRegs[0].chcr = DMAC_CHCR_TR | DMAC_CHCR_CO;
87 
88  DEBUG_PRINTF("Waiting for interrupt...\n");
89  WaitEventFlag(IntrEventFlag, iLinkEventDMATransEnd | iLinkEventError, WEF_OR, NULL);
90 
91  ILINKRegisterBase->PHT_ctrl_ST_R0 &= (~PHT_ctrl_ST_R0_flags);
92 
93  DEBUG_PRINTF("Processing results...\n");
94 
95  if (LocalCachedIntr0Register & iLink_INTR0_InvAck)
96  return (-1023);
97  if (LocalCachedIntr0Register & iLink_INTR0_STO)
98  return (-1024);
99  if (LocalCachedIntr0Register & iLink_INTR0_AckMiss)
100  return (-1025);
101  if (LocalCachedIntr0Register & iLink_INTR0_RetEx)
102  return (-1026);
103 
104  return nBytes;
105 }
106 
107 /* !!! NOTE !!! This function only supports issuing BLOCK read requests! Quadlet read requests should be issued with the equilvalent function that uses the UBUF. */
108 int iLinkReadPHTReq(struct TransactionContextData *trContext, unsigned short int offset_high, unsigned int offset_low, void *buffer, unsigned int nBytes)
109 {
110  DEBUG_PRINTF("iLinkReadPHTReq() 0x%08x 0x%08x; nbytes: 0x%08x. Node: 0x%04x.\n", offset_high, offset_low, nBytes, trContext->NodeID);
111 
112  TargetBuffer = buffer;
113 
114  return (iLinkPHTSendData(trContext, IEEE1394_TCODE_READB, offset_high, offset_low, NULL, nBytes, 0));
115 }
116 
117 /* !!! NOTE !!! This function only supports issuing BLOCK write requests! Quadlet write requests should be issued with the equilvalent function that uses the UBUF. */
118 int iLinkWritePHTReq(struct TransactionContextData *trContext, unsigned short int offset_high, unsigned int offset_low, void *buffer, unsigned int nBytes)
119 {
120  DEBUG_PRINTF("iLinkWritePHTReq() 0x%08x 0x%08x; nbytes: 0x%08x. Node: 0x%04x.\n", offset_high, offset_low, nBytes, trContext->NodeID);
121 
122  return (iLinkPHTSendData(trContext, IEEE1394_TCODE_WRITEB, offset_high, offset_low, buffer, nBytes, 1));
123 }
dmacman.h
thbase.h
DMAChannelRegBlock
Definition: iLink_internal.h:258
DMAC_CHCR_CO
#define DMAC_CHCR_CO
Definition: dmacman.h:39
stdio.h
DMARRegBlock
Definition: iLink_internal.h:273
ILINKMemMap
Definition: iLink_internal.h:158
sysmem.h
TransactionContextData
Definition: iLink_internal.h:284
DMAC_CHCR_TR
#define DMAC_CHCR_TR
Definition: dmacman.h:35
thevent.h