PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
iLink_internal.c
1/* iLink_internal.c
2 * Purpose: Contains the functions that are used internally by the iLinkman driver.
3 *
4 * Last Updated: 2012/02/28
5 * Programmer: SP193
6 */
7
8#include <dmacman.h>
9#include <intrman.h>
10#include <stdio.h>
11#include <sysclib.h>
12#include <sysmem.h>
13#include <thbase.h>
14#include <thevent.h>
15#include <cdvdman.h>
16
17#include "iLinkman.h"
18#include "iLink_internal.h"
19
20extern struct ILINKMemMap *ILINKRegisterBase;
21extern struct DMAChannelRegBlock *iLinkDMACRegs;
22extern struct DMARRegBlock *iLinkDMARRegs;
23
24extern void (*CallBackFunction)(int reason, unsigned int offset, unsigned int size);
25
26int GenerationNumber;
27int nNodes;
28int NodeCapabilities;
29struct TransactionContextData TransactionContexts[10];
30extern int IntrEventFlag;
31
32extern const void *RequestHandlers[];
33
34void UBUFThread(void *arg)
35{
36 void (*RequestResponseHandler)(unsigned int header, volatile unsigned int *buffer, unsigned int nQuads);
37 unsigned int data;
38 u32 ef_bits;
39
40 (void)arg;
41
42 while (1) {
43 unsigned int DataBufferLevel;
44
45 WaitEventFlag(IntrEventFlag, iLinkEventBusReset | iLinkEventURx, WEF_OR, &ef_bits);
46 ClearEventFlag(IntrEventFlag, ~(iLinkEventBusReset | iLinkEventURx));
47
48 while ((DataBufferLevel = ILINKRegisterBase->ubufReceiveLevel) > 0) {
49 data = ILINKRegisterBase->ubufReceive;
50 iDEBUG_PRINTF("Handling UBUF data... handler: 0x%02lx.\n", (data >> 4) & 0xF);
51 RequestResponseHandler = RequestHandlers[(data >> 4) & 0xF];
52 RequestResponseHandler(data, (volatile unsigned int *)&ILINKRegisterBase->ubufReceive, DataBufferLevel - 1);
53 }
54 }
55}
56
57int GetConsoleIDs(u64 *guid, char *ModelName)
58{
59 u64 ilink_id;
60 u32 stat;
61 int result;
62
63 if (sceCdRI((u8 *)&ilink_id, &stat) < 0 || stat != 0) {
64 result = -1;
65 DEBUG_PRINTF("Error reading console/ILINK ID.\n");
66 } else {
67 *guid = (ilink_id & 0xFFFFFFFF00000000) | ((*(u8 *)&ilink_id) | 0x08004600);
68 if (sceCdRM(ModelName, &stat) < 0 || stat != 0) {
69 result = -1;
70 DEBUG_PRINTF("Error reading console model name.\n");
71 } else {
72 result = 0;
73 }
74 }
75
76 return result;
77}
78
79void iLinkDisableIntr(void)
80{
81 ILINKRegisterBase->intr0Mask = 0;
82 ILINKRegisterBase->intr1Mask = 0;
83 ILINKRegisterBase->intr2Mask = 0;
84
85 /* Set all interrupt bits, to acknowledge any pending interrupts that there may be. */
86 ILINKRegisterBase->intr0 = 0xFFFFFFFF;
87 ILINKRegisterBase->intr1 = 0xFFFFFFFF;
88 ILINKRegisterBase->intr2 = 0xFFFFFFFF;
89}
90
91void iLinkEnableIntr(void)
92{
93 /* Enable the interrupt events */
94 ILINKRegisterBase->intr0Mask = iLink_INTR0_CmdRst | iLink_INTR0_PhyRst | iLink_INTR0_RetEx | iLink_INTR0_STO | iLink_INTR0_PBCntR | iLink_INTR0_UResp | iLink_INTR0_URx;
95#ifdef REQ_CHECK_DMAC_STAT
96 ILINKRegisterBase->intr0Mask |= iLink_INTR0_DRFR;
97#endif
98
99#ifdef REQ_CHECK_ERRORS
100 ILINKRegisterBase->intr0Mask |= (iLink_INTR0_HdrErr | iLink_INTR0_SntBsyAck); /* For debugging purposes */
101#endif
102 ILINKRegisterBase->intr1Mask = iLink_INTR1_UTD;
103}
104
105static void ShutDownDMAChannels(void)
106{
107 /* Stop all DMA-related activities */
108 ILINKRegisterBase->dmaCtrlSR0 = ILINKRegisterBase->dmaCtrlSR1 = 0;
109
110 /* Stop all DMA-related activities */
111 iLinkDMACRegs[0].chcr = iLinkDMACRegs[1].chcr = iLinkDMACRegs[2].chcr = 0;
112
113 /* Disable all DMAC channels connected to the i.Link hardware.
114 (Disable DMA channels 13, 14 and 15) */
115 sceDisableDMAChannel(IOP_DMAC_FDMA0);
116 sceDisableDMAChannel(IOP_DMAC_FDMA1);
117 sceDisableDMAChannel(IOP_DMAC_FDMA2);
118}
119
120int iLinkResetHW(void)
121{
122 ShutDownDMAChannels();
123
124 /* Turn off, and then turn back on the LINK and PHY. If this is not done, the iLink hardware might not function correctly on some consoles. :( */
125 ILINKRegisterBase->UnknownRegister7C = 0x40; /* Shut down. */
126 DelayThread(400000);
127 ILINKRegisterBase->UnknownRegister7C = 0;
128
129 /* If the LINK is off, switch it on. */
130 if (!(ILINKRegisterBase->ctrl2 & iLink_CTRL2_LPSEn))
131 ILINKRegisterBase->ctrl2 = iLink_CTRL2_LPSEn;
132
133 /* Wait for the clock to stabilize. */
134 while (!(ILINKRegisterBase->ctrl2 & iLink_CTRL2_SOK))
135 DelayThread(50);
136
137 return 0;
138}
139
140void iLinkShutdownHW(void)
141{
142 ShutDownDMAChannels();
143 ILINKRegisterBase->ctrl2 &= (~iLink_CTRL2_LPSEn); /* Set the LINK to enter standby mode. */
144}
145
146void iLinkHWInitialize(void)
147{
148 iLinkPHY_SetLCTRL(0);
149
150 /* Configure the Control 0 register, resetting the transmitter and receiver at the same time. */
151 // ILINKRegisterBase->ctrl0 = iLink_CTRL0_TxRst | iLink_CTRL0_RxRst | iLink_CTRL0_RcvSelfID | iLink_CTRL0_BusIDRst | iLink_CTRL0_CycTmrEn | iLink_CTRL0_RetLim(0x0F) | iLink_CTRL0_RSP0 | iLink_CTRL0_DELim(3);
152 ILINKRegisterBase->ctrl0 = iLink_CTRL0_TxRst | iLink_CTRL0_RxRst | iLink_CTRL0_RcvSelfID | iLink_CTRL0_BusIDRst | iLink_CTRL0_CycTmrEn | iLink_CTRL0_RetLim(0x0F) | iLink_CTRL0_DELim(3);
153 while (ILINKRegisterBase->ctrl0 & (iLink_CTRL0_RxRst | iLink_CTRL0_TxRst)) {};
154
155 ILINKRegisterBase->ubufTransmitClear = 0; /* Clear UBUF Tx FIFO. */
156 ILINKRegisterBase->ubufReceiveClear = 0; /* Clear UBUF Rx FIFO. */
157
158 ILINKRegisterBase->dbufFIFO_lvlR0 = DBUF_FIFO_RESET_TX | DBUF_FIFO_RESET_RX; /* Reset DBUF FIFO 0 */
159 ILINKRegisterBase->dbufFIFO_lvlR1 = DBUF_FIFO_RESET_TX | DBUF_FIFO_RESET_RX; /* Reset DBUF FIFO 1 */
160
161 iLinkInitPHT();
162 iLinkEnableIntr();
163
164 iLinkWritePhy(5, iLinkReadPhy(5) | REG05_EN_ACCL | REG05_EN_MULTI); /* Enable supported P1394A-2000 enhancements. */
165
166 /* Enable DMA channels 13 and 15. */
167 sceEnableDMAChannel(IOP_DMAC_FDMA0);
168 sceEnableDMAChannel(IOP_DMAC_FDMA2);
169
170 GenerationNumber = 0;
171 NodeCapabilities = 0;
172}
173
174void iLinkEnableCMaster(void)
175{
176 ILINKRegisterBase->ctrl0 |= iLink_CTRL0_CMstr;
177}
178
179void iLinkBusEnable(void)
180{
181 ILINKRegisterBase->ctrl0 |= (iLink_CTRL0_RxEn | iLink_CTRL0_TxEn); /* Enable transmitter and receiver. */
182}
183
184void *malloc(unsigned int nBytes)
185{
186 int OldState;
187 void *result;
188
189 CpuSuspendIntr(&OldState);
190 result = AllocSysMemory(ALLOC_FIRST, nBytes, NULL);
191 CpuResumeIntr(OldState);
192
193 return result;
194}
195
196void free(void *buffer)
197{
198 int OldState;
199
200 CpuSuspendIntr(&OldState);
201 FreeSysMemory(buffer);
202 CpuResumeIntr(OldState);
203}
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
int sceCdRM(char *buffer, u32 *status)
Definition cdvdman.c:5692
int sceCdRI(u8 *buffer, u32 *result)
Definition cdvdman.c:5681