11#include "irx_imports.h"
15IRX_ID(
"EEConfig", 1, 1);
18static int eeconf_config_numblocks;
20static int eeconf_writeread_scmd(
char cmd,
const char *sdata,
int sdlen,
char *rdata,
int rdlen)
25 USE_DEV5_MMIO_HWPORT();
28 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) != 0 )
30 while ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x40) == 0 )
32 for ( i = 0; i < sdlen; i += 1 )
33 dev5_mmio_hwport->m_dev5_reg_017 = sdata[i];
34 dev5_mmio_hwport->m_dev5_reg_016 = cmd;
35 while ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) != 0 )
37 for ( i = 0; (dev5_mmio_hwport->m_dev5_reg_017 & 0x40) == 0; i += 1 )
38 rdata_tmp[i] = dev5_mmio_hwport->m_dev5_reg_018;
41 for ( i = 0; i < rdlen_tmp; i += 1 )
42 rdata[i] = rdata_tmp[i];
46static int eeconf_open_config(
int block,
int mode,
int NumBlocks,
char *status)
50 wdata = (u8)mode | ((u8)block << 8) | ((u8)NumBlocks << 16);
51 eeconf_config_numblocks = NumBlocks;
52 return eeconf_writeread_scmd(64, (
const char *)&wdata, 3, status, 1);
55static int eeconf_close_config(
char *status)
59 result = eeconf_writeread_scmd(67, 0, 0, status, 1);
60 eeconf_config_numblocks = 0;
64static int read_config_process(u32 *arg1,
char *status)
69 result = eeconf_writeread_scmd(65, 0, 0, rdata, 16);
70 *status = (u8)(rdata[14] + rdata[13] + rdata[12] + rdata[11] + rdata[10] + rdata[9] + rdata[8] + rdata[7] + rdata[6]
71 + rdata[5] + rdata[4] + rdata[3] + rdata[2] + rdata[0] + rdata[1])
73 arg1[0] = *(u32 *)&rdata[0];
74 arg1[1] = *(u32 *)&rdata[4];
75 arg1[2] = *(u32 *)&rdata[8];
76 *((u8 *)arg1 + 12) = rdata[12];
77 *((u8 *)arg1 + 13) = rdata[13];
78 *((u8 *)arg1 + 14) = rdata[14];
82static int eeconf_read_config(
void *buffer,
char *status)
86 for ( i = 0; i < eeconf_config_numblocks; i += 1 )
87 if ( !read_config_process((u32 *)((
char *)buffer + (15 * i)), status) || *status )
92static int write_config_process(
char *inval,
char *status)
97 *(u32 *)&wdata[0] = *(u32 *)inval;
98 *(u32 *)&wdata[4] = *((u32 *)inval + 1);
99 *(u32 *)&wdata[8] = *((u32 *)inval + 2);
100 wdata[12] = inval[12];
101 wdata[13] = inval[13];
102 wdata[14] = inval[14];
103 wdata[15] = inval[14] + inval[13] + inval[12] + inval[11] + inval[10] + inval[9] + inval[8] + inval[7] + inval[6]
104 + inval[5] + inval[4] + inval[3] + inval[2] + inval[0] + inval[1];
105 return eeconf_writeread_scmd(66, wdata, 16, status, 1);
108static int eeconf_write_config(
const void *buffer,
char *status)
112 for ( i = 0; i < eeconf_config_numblocks; i += 1 )
113 if ( !write_config_process((
char *)buffer + (15 * i), status) || *status )
118static void eeconf_ieee1394_reset()
120 USE_IOP_MMIO_HWPORT();
122 iop_mmio_hwport->ieee1394.PHYAccess = 0x417F0000;
123 while ( !(iop_mmio_hwport->ieee1394.NodeID & 1) )
125 iop_mmio_hwport->ieee1394.ubufReceiveClear = -1;
126 iop_mmio_hwport->ieee1394.intr0 = -1;
127 iop_mmio_hwport->ieee1394.intr1 = -1;
128 iop_mmio_hwport->ieee1394.intr2 = -1;
131static int eeconf_ieee1394_available()
133 USE_IOP_MMIO_HWPORT();
135 return (iop_mmio_hwport->ieee1394.UnknownRegister7C & 0xF0000000) == 0x10000000;
138static int eeconf_ee_ssbus_available()
140 USE_IOP_MMIO_HWPORT();
142 return iop_mmio_hwport->iop_sbus_ctrl[0] & 0x80000000;
145static void eeconf_dve_magic()
147 USE_IOP_MMIO_HWPORT();
149 if ( (
unsigned int)(iop_mmio_hwport->exp2_r2[4612]) - 96 < 2 )
151 iop_mmio_hwport->exp2_r2[4632] = 0;
154 if ( (iop_mmio_hwport->dev9c[14] & 0xF0) !=
'0' )
156 *(vu16 *)&iop_mmio_hwport->dev9c[16] = 0;
157 *(vu16 *)&iop_mmio_hwport->dev9c[18] = 0;
160 *((vu16 *)0xB600000A) = 0;
163static void eeconf_handle_mac_address()
168 for ( i = 0; i < 100; i += 1 )
169 if ( eeconf_writeread_scmd(55, 0, 0, rdata, 9) )
171 if ( i >= 100 || (rdata[0] & 0x80) != 0 )
172 memset(rdata, 255,
sizeof(rdata));
173 *((vu32 *)0xFFFE0188) = ((u8)rdata[4] << 24) | ((u8)rdata[3] << 16) | ((u8)rdata[2] << 8) | (u8)rdata[1];
174 *((vu32 *)0xFFFE018C) = ((u8)rdata[8] << 24) | ((u8)rdata[7] << 16) | ((u8)rdata[6] << 8) | (u8)rdata[5];
177static void eeconf_handle_region_param()
182 for ( i = 0; i < 100; i += 1 )
183 if ( eeconf_writeread_scmd(54, 0, 0, rdata, 15) )
185 if ( i < 100 && (rdata[0] & 0x80) == 0 )
188 *((vu32 *)0xFFFE0180) = 0xBFC7FF04;
189 *((vu32 *)0xFFFE0184) = (u8)rdata[3];
191 *((vu32 *)0xFFFE0180) = 0xBFC7FF52;
192 *((vu32 *)0xFFFE0184) = (u8)rdata[8];
194 *((vu32 *)0xFFFE0180) = 0xFFFFFFFF;
197static void eeconf_handle_eegs_config(
const u8 *buf)
199 *((vu32 *)0xFFFE0190) = buf ? (buf[1] & 0xF) : 3;
202int _start(
int ac,
char **av)
204 const int *p_bootmode3;
205 int read_conf_succeeded;
207 int any_ps1drv_flag_set;
209 char cfgblock_tmp[16];
211 USE_DEV5_MMIO_HWPORT();
216 p_bootmode3 = QueryBootMode(3);
217 if ( p_bootmode3 && (p_bootmode3[1] & (1 | 2)) )
219#pragma GCC diagnostic push
220#pragma GCC diagnostic ignored "-Warray-bounds"
221 *((
void **)0x3C0) = 0;
222#pragma GCC diagnostic pop
223 for ( i = 0; i < 0x30000; i += 1 )
224 if ( !(dev5_mmio_hwport->m_dev5_reg_005 & 8) )
228 read_conf_succeeded = 0;
229 cfgblock_mem = (
char *)AllocSysMemory(1, 96, 0);
232 read_conf_succeeded = 1;
233#pragma GCC diagnostic push
234#pragma GCC diagnostic ignored "-Warray-bounds"
235 *((
void **)0x3C0) = cfgblock_mem;
236#pragma GCC diagnostic pop
237 for ( i = 0; i < 90; i += 1 )
239 for ( i = 0; i < 0x10000; i += 1 )
240 if ( eeconf_open_config(0, 0, 4, &cfgstatus) && !(cfgstatus & 9) )
243 read_conf_succeeded = 0;
244 for ( i = 0; i < 0x10000; i += 1 )
245 if ( eeconf_read_config(cfgblock_mem, &cfgstatus) && !(cfgstatus & 9) )
248 read_conf_succeeded = 0;
249 for ( i = 0; i < 0x10000; i += 1 )
250 if ( eeconf_close_config(&cfgstatus) && !(cfgstatus & 9) )
253 read_conf_succeeded = 0;
254 for ( i = 0; i < 0x10000; i += 1 )
255 if ( eeconf_open_config(1u, 0, 2, &cfgstatus) && !(cfgstatus & 9) )
258 read_conf_succeeded = 0;
259 for ( i = 0; i < 0x10000; i += 1 )
260 if ( eeconf_read_config(cfgblock_mem + 60, &cfgstatus) && !(cfgstatus & 9) )
263 read_conf_succeeded = 0;
264 for ( i = 0; i < 0x10000; i += 1 )
265 if ( eeconf_close_config(&cfgstatus) && !(cfgstatus & 9) )
268 read_conf_succeeded = 0;
269 cfgblock_mem[15] &= ~8;
270 cfgblock_mem[15] |= ((cfgblock_mem[75] & 8) != 0);
272 if ( !read_conf_succeeded )
273#pragma GCC diagnostic push
274#pragma GCC diagnostic ignored "-Warray-bounds"
275 *((
void **)0x3C0) = 0;
276#pragma GCC diagnostic pop
278 if ( !*(u16 *)QueryBootMode(4) )
283 if ( eeconf_ee_ssbus_available() )
285 eeconf_handle_region_param();
286 eeconf_handle_mac_address();
287#pragma GCC diagnostic push
288#pragma GCC diagnostic ignored "-Warray-bounds"
289 eeconf_handle_eegs_config((u8 *)(
void **)0x3C0);
290#pragma GCC diagnostic pop
293 if ( eeconf_ieee1394_available() )
294 eeconf_ieee1394_reset();
296 if ( !(dev5_mmio_hwport->m_dev5_reg_005 & 2) || (dev5_mmio_hwport->m_dev5_reg_005 & 4) )
298 for ( i = 0; i < 0x10000; i += 1 )
299 if ( eeconf_open_config(1u, 0, 1, &cfgstatus) && !(cfgstatus & 9) )
301 for ( i = 0; i < 0x10000; i += 1 )
302 if ( eeconf_read_config(cfgblock_tmp, &cfgstatus) && !(cfgstatus & 9) )
304 for ( i = 0; i < 0x10000; i += 1 )
305 if ( eeconf_close_config(&cfgstatus) && !(cfgstatus & 9) )
307 any_ps1drv_flag_set = 0;
308 for ( i = 0; i < 15; i += 1 )
310 if ( cfgblock_tmp[i] )
312 any_ps1drv_flag_set = 1;
316 if ( any_ps1drv_flag_set )
318 for ( i = 0; i < 0x10000; i += 1 )
319 if ( eeconf_open_config(1u, 1u, 1, &cfgstatus) && !(cfgstatus & 9) )
321 for ( i = 0; i < 0x10000; i += 1 )
322 if ( eeconf_write_config(cfgblock_tmp, &cfgstatus) && !(cfgstatus & 9) )
324 for ( i = 0; i < 0x10000; i += 1 )
325 if ( eeconf_close_config(&cfgstatus) && !(cfgstatus & 9) )