Skip to content

Commit c307f48

Browse files
authored
Merge pull request #705 from uyjulian/eeconf_impl
Implementation of eeconf module
2 parents e965a23 + 4914631 commit c307f48

File tree

7 files changed

+413
-0
lines changed

7 files changed

+413
-0
lines changed

iop/system/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
SUBDIRS = \
1010
alloc \
1111
dmacman \
12+
eeconf \
1213
eesync \
1314
eesync-nano \
1415
excepman \

iop/system/eeconf/Makefile

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# _____ ___ ____ ___ ____
2+
# ____| | ____| | | |____|
3+
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
4+
#-----------------------------------------------------------------------
5+
# Copyright ps2dev - http://www.ps2dev.org
6+
# Licenced under Academic Free License version 2.0
7+
# Review ps2sdk README & LICENSE files for further details.
8+
9+
IOP_INCS += \
10+
-I$(PS2SDKSRC)/iop/system/loadcore/include \
11+
-I$(PS2SDKSRC)/iop/system/sysclib/include \
12+
-I$(PS2SDKSRC)/iop/system/sysmem/include
13+
14+
IOP_OBJS = \
15+
eeconf.o \
16+
imports.o \
17+
exports.o
18+
19+
include $(PS2SDKSRC)/Defs.make
20+
include $(PS2SDKSRC)/iop/Rules.bin.make
21+
include $(PS2SDKSRC)/iop/Rules.make
22+
include $(PS2SDKSRC)/iop/Rules.release

iop/system/eeconf/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# EE Configuration Module
2+
3+
This module reads configuration data needed by EE, and also sets up DVE,
4+
DECKARD region/video mode/MAC address information, and an unknown device.
5+
6+
## Configurations
7+
8+
There are multiple configurations of this library, allowing the choice of
9+
balancing between size, speed, and features.
10+
11+
* `eeconf` -> The recommended version.
12+
13+
## How to use this module in your program
14+
15+
In order to use this module in your program, use `LoadModule` or \
16+
`LoadModuleBuffer` with no arguments.

iop/system/eeconf/src/eeconf.c

Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
/*
2+
# _____ ___ ____ ___ ____
3+
# ____| | ____| | | |____|
4+
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5+
#-----------------------------------------------------------------------
6+
# Copyright ps2dev - http://www.ps2dev.org
7+
# Licenced under Academic Free License version 2.0
8+
# Review ps2sdk README & LICENSE files for further details.
9+
*/
10+
11+
#include "irx_imports.h"
12+
#include <dev5_mmio_hwport.h>
13+
#include <iop_mmio_hwport.h>
14+
15+
IRX_ID("EEConfig", 1, 1);
16+
// Based on the module from ROM 2.20+.
17+
18+
static int eeconf_config_numblocks;
19+
20+
static int eeconf_writeread_scmd(char cmd, const char *sdata, int sdlen, char *rdata, int rdlen)
21+
{
22+
int rdlen_tmp;
23+
int i;
24+
char rdata_tmp[64];
25+
USE_DEV5_MMIO_HWPORT();
26+
27+
rdlen_tmp = rdlen;
28+
if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) != 0 )
29+
return 0;
30+
while ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x40) == 0 )
31+
;
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 )
36+
;
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;
39+
if ( rdlen_tmp > i )
40+
rdlen_tmp = i;
41+
for ( i = 0; i < rdlen_tmp; i += 1 )
42+
rdata[i] = rdata_tmp[i];
43+
return 1;
44+
}
45+
46+
static int eeconf_open_config(int block, int mode, int NumBlocks, char *status)
47+
{
48+
int wdata;
49+
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);
53+
}
54+
55+
static int eeconf_close_config(char *status)
56+
{
57+
int result;
58+
59+
result = eeconf_writeread_scmd(67, 0, 0, status, 1);
60+
eeconf_config_numblocks = 0;
61+
return result;
62+
}
63+
64+
static int read_config_process(u32 *arg1, char *status)
65+
{
66+
int result;
67+
char rdata[16];
68+
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])
72+
!= (u8)rdata[15];
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];
79+
return result;
80+
}
81+
82+
static int eeconf_read_config(void *buffer, char *status)
83+
{
84+
int i;
85+
86+
for ( i = 0; i < eeconf_config_numblocks; i += 1 )
87+
if ( !read_config_process((u32 *)((char *)buffer + (15 * i)), status) || *status )
88+
break;
89+
return i;
90+
}
91+
92+
static int write_config_process(char *inval, char *status)
93+
{
94+
char wdata[16];
95+
96+
*status = 0;
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);
106+
}
107+
108+
static int eeconf_write_config(const void *buffer, char *status)
109+
{
110+
int i;
111+
112+
for ( i = 0; i < eeconf_config_numblocks; i += 1 )
113+
if ( !write_config_process((char *)buffer + (15 * i), status) || *status )
114+
break;
115+
return i;
116+
}
117+
118+
static void eeconf_ieee1394_reset()
119+
{
120+
USE_IOP_MMIO_HWPORT();
121+
122+
iop_mmio_hwport->ieee1394.PHYAccess = 0x417F0000;
123+
while ( !(iop_mmio_hwport->ieee1394.NodeID & 1) )
124+
;
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;
129+
}
130+
131+
static int eeconf_ieee1394_available()
132+
{
133+
USE_IOP_MMIO_HWPORT();
134+
135+
return (iop_mmio_hwport->ieee1394.UnknownRegister7C & 0xF0000000) == 0x10000000;
136+
}
137+
138+
static int eeconf_ee_ssbus_available()
139+
{
140+
USE_IOP_MMIO_HWPORT();
141+
142+
return iop_mmio_hwport->iop_sbus_ctrl[0] & 0x80000000;
143+
}
144+
145+
static void eeconf_dve_magic()
146+
{
147+
USE_IOP_MMIO_HWPORT();
148+
149+
if ( (unsigned int)(iop_mmio_hwport->exp2_r2[4612]) - 96 < 2 )
150+
{
151+
iop_mmio_hwport->exp2_r2[4632] = 0;
152+
return;
153+
}
154+
if ( (iop_mmio_hwport->dev9c[14] & 0xF0) != '0' )
155+
{
156+
*(vu16 *)&iop_mmio_hwport->dev9c[16] = 0;
157+
*(vu16 *)&iop_mmio_hwport->dev9c[18] = 0;
158+
return;
159+
}
160+
*((vu16 *)0xB600000A) = 0;
161+
}
162+
163+
static void eeconf_handle_mac_address()
164+
{
165+
char rdata[16];
166+
int i;
167+
168+
for ( i = 0; i < 100; i += 1 )
169+
if ( eeconf_writeread_scmd(55, 0, 0, rdata, 9) )
170+
break;
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];
175+
}
176+
177+
static void eeconf_handle_region_param()
178+
{
179+
char rdata[16];
180+
int i;
181+
182+
for ( i = 0; i < 100; i += 1 )
183+
if ( eeconf_writeread_scmd(54, 0, 0, rdata, 15) )
184+
break;
185+
if ( i < 100 && (rdata[0] & 0x80) == 0 )
186+
{
187+
// The following address is the byte at index 5 of ROMVER
188+
*((vu32 *)0xFFFE0180) = 0xBFC7FF04;
189+
*((vu32 *)0xFFFE0184) = (u8)rdata[3];
190+
// The following address is the byte at index 34 of VERSTR
191+
*((vu32 *)0xFFFE0180) = 0xBFC7FF52;
192+
*((vu32 *)0xFFFE0184) = (u8)rdata[8];
193+
}
194+
*((vu32 *)0xFFFE0180) = 0xFFFFFFFF;
195+
}
196+
197+
static void eeconf_handle_eegs_config(const u8 *buf)
198+
{
199+
*((vu32 *)0xFFFE0190) = buf ? (buf[1] & 0xF) : 3;
200+
}
201+
202+
int _start(int ac, char **av)
203+
{
204+
const int *p_bootmode3;
205+
int read_conf_succeeded;
206+
char *cfgblock_mem;
207+
int any_ps1drv_flag_set;
208+
int i;
209+
char cfgblock_tmp[16];
210+
char cfgstatus;
211+
USE_DEV5_MMIO_HWPORT();
212+
213+
(void)ac;
214+
(void)av;
215+
216+
p_bootmode3 = QueryBootMode(3);
217+
if ( p_bootmode3 && (p_bootmode3[1] & (1 | 2)) )
218+
return 1;
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) )
225+
break;
226+
if ( i >= 0x30000 )
227+
return 1;
228+
read_conf_succeeded = 0;
229+
cfgblock_mem = (char *)AllocSysMemory(1, 96, 0);
230+
if ( cfgblock_mem )
231+
{
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 )
238+
cfgblock_mem[i] = 0;
239+
for ( i = 0; i < 0x10000; i += 1 )
240+
if ( eeconf_open_config(0, 0, 4, &cfgstatus) && !(cfgstatus & 9) )
241+
break;
242+
if ( i >= 0x10000 )
243+
read_conf_succeeded = 0;
244+
for ( i = 0; i < 0x10000; i += 1 )
245+
if ( eeconf_read_config(cfgblock_mem, &cfgstatus) && !(cfgstatus & 9) )
246+
break;
247+
if ( i >= 0x10000 )
248+
read_conf_succeeded = 0;
249+
for ( i = 0; i < 0x10000; i += 1 )
250+
if ( eeconf_close_config(&cfgstatus) && !(cfgstatus & 9) )
251+
break;
252+
if ( i >= 0x10000 )
253+
read_conf_succeeded = 0;
254+
for ( i = 0; i < 0x10000; i += 1 )
255+
if ( eeconf_open_config(1u, 0, 2, &cfgstatus) && !(cfgstatus & 9) )
256+
break;
257+
if ( i >= 0x10000 )
258+
read_conf_succeeded = 0;
259+
for ( i = 0; i < 0x10000; i += 1 )
260+
if ( eeconf_read_config(cfgblock_mem + 60, &cfgstatus) && !(cfgstatus & 9) )
261+
break;
262+
if ( i >= 0x10000 )
263+
read_conf_succeeded = 0;
264+
for ( i = 0; i < 0x10000; i += 1 )
265+
if ( eeconf_close_config(&cfgstatus) && !(cfgstatus & 9) )
266+
break;
267+
if ( i >= 0x10000 )
268+
read_conf_succeeded = 0;
269+
cfgblock_mem[15] &= ~8;
270+
cfgblock_mem[15] |= ((cfgblock_mem[75] & 8) != 0);
271+
}
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
277+
// The following block is only in EECONF module in 1.60+, 1.70+, 2.20+, PS3 ps2_emu ROMs.
278+
if ( !*(u16 *)QueryBootMode(4) )
279+
{
280+
// The following block is only in EECONF module in 1.60+, 1.70+, 2.20+ ROMs.
281+
eeconf_dve_magic();
282+
// The following block is only in EECONF module in 2.20+ ROMs.
283+
if ( eeconf_ee_ssbus_available() )
284+
{
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
291+
}
292+
// The following block is only in EECONF module in 1.70+, 2.20+, PS3 ps2_emu ROMs.
293+
if ( eeconf_ieee1394_available() )
294+
eeconf_ieee1394_reset();
295+
}
296+
if ( !(dev5_mmio_hwport->m_dev5_reg_005 & 2) || (dev5_mmio_hwport->m_dev5_reg_005 & 4) )
297+
return 1;
298+
for ( i = 0; i < 0x10000; i += 1 )
299+
if ( eeconf_open_config(1u, 0, 1, &cfgstatus) && !(cfgstatus & 9) )
300+
break;
301+
for ( i = 0; i < 0x10000; i += 1 )
302+
if ( eeconf_read_config(cfgblock_tmp, &cfgstatus) && !(cfgstatus & 9) )
303+
break;
304+
for ( i = 0; i < 0x10000; i += 1 )
305+
if ( eeconf_close_config(&cfgstatus) && !(cfgstatus & 9) )
306+
break;
307+
any_ps1drv_flag_set = 0;
308+
for ( i = 0; i < 15; i += 1 )
309+
{
310+
if ( cfgblock_tmp[i] )
311+
{
312+
any_ps1drv_flag_set = 1;
313+
cfgblock_tmp[i] = 0;
314+
}
315+
}
316+
if ( any_ps1drv_flag_set )
317+
{
318+
for ( i = 0; i < 0x10000; i += 1 )
319+
if ( eeconf_open_config(1u, 1u, 1, &cfgstatus) && !(cfgstatus & 9) )
320+
break;
321+
for ( i = 0; i < 0x10000; i += 1 )
322+
if ( eeconf_write_config(cfgblock_tmp, &cfgstatus) && !(cfgstatus & 9) )
323+
break;
324+
for ( i = 0; i < 0x10000; i += 1 )
325+
if ( eeconf_close_config(&cfgstatus) && !(cfgstatus & 9) )
326+
break;
327+
}
328+
return 1;
329+
}

iop/system/eeconf/src/exports.tab

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
DECLARE_EXPORT_TABLE(eeconfig, 1, 3)
3+
DECLARE_EXPORT(_start)
4+
DECLARE_EXPORT(_retonly)
5+
DECLARE_EXPORT(_retonly)
6+
DECLARE_EXPORT(_retonly)
7+
DECLARE_EXPORT(_retonly)
8+
DECLARE_EXPORT(_retonly)
9+
DECLARE_EXPORT(_retonly)
10+
DECLARE_EXPORT(_retonly)
11+
END_EXPORT_TABLE
12+
13+
void _retonly() {}

0 commit comments

Comments
 (0)