PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
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
18extern unsigned short int LocalNodeID;
19extern int IntrEventFlag;
20
21extern int GenerationNumber;
22
23extern struct ILINKMemMap *ILINKRegisterBase;
24extern unsigned int *TargetBuffer;
25extern unsigned int LocalCachedIntr0Register;
26
27struct DMAChannelRegBlock *iLinkDMACRegs = (struct DMAChannelRegBlock *)ILINK_DMAC_REGISTER_BASE;
28struct DMARRegBlock *iLinkDMARRegs = (struct DMARRegBlock *)ILINK_DMAC_DMAR_CTRL_BASE;
29
30static 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
32void 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
62static 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. */
108int 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. */
118int 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}
#define DMAC_CHCR_TR
Definition dmacman.h:35
#define DMAC_CHCR_CO
Definition dmacman.h:39