PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
flash.c
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 "acflash_internal.h"
12
13static flash_probe_t probes_22[2] = {&flash_probe_i28f640f5, &flash_probe_mbm29f033c};
14static struct flash_softc Flashc;
15
16int acFlashStart()
17{
18 if ( Flashc.status == 2 )
19 return -11;
20 if ( Flashc.status != 1 )
21 {
22 return -6;
23 }
24 *((volatile acUint16 *)0xB2416006) = 0;
25 Flashc.status = 2;
26 return 0;
27}
28
29int acFlashStop()
30{
31 flash_ops_t ops;
32 int bsize;
33 int blocks;
34 acFlashAddr addr;
35 acFlashAddr v5;
36
37 if ( Flashc.status == 1 )
38 return 0;
39 if ( Flashc.status != 2 )
40 {
41 return -6;
42 }
43 ops = Flashc.ops;
44 bsize = Flashc.ops->fo_bsize;
45 blocks = Flashc.ops->fo_blocks - 1;
46 addr = 0xB0000000;
47 v5 = 0xB0000000;
48 while ( blocks >= 0 )
49 {
50 addr += bsize;
51 --blocks;
52 ops->fo_reset(v5);
53 v5 = addr;
54 }
55 Flashc.status = 1;
56 *((volatile acUint16 *)0xB2416004) = 0;
57 return 0;
58}
59
60int acFlashErase(acFlashAddr addr)
61{
62 if ( Flashc.status == 1 )
63 return -13;
64 if ( Flashc.status != 2 )
65 {
66 return -6;
67 }
68 if ( addr >= (acUint32)Flashc.size )
69 return -34;
70 return Flashc.ops->fo_erase(addr + 0xB0000000);
71}
72
73int acFlashProgram(acFlashAddr addr, void *buf, int count)
74{
75 if ( Flashc.status == 1 )
76 return -13;
77 if ( Flashc.status != 2 )
78 {
79 return -6;
80 }
81 if ( (addr & 1) != 0 )
82 {
83 return -14;
84 }
85 if ( addr >= (acUint32)Flashc.size )
86 return -34;
87 return Flashc.ops->fo_program(addr + 0xB0000000, (flash_data_t *)buf, count);
88}
89
90int acFlashRead(acFlashAddr addr, void *buf, int count)
91{
92 void *v3;
93 flash_addr_t v6;
94 int size;
95 signed int v8;
96 struct flash_softc *flashc;
97
98 v3 = buf;
99 if ( Flashc.status == 0 )
100 {
101 return -6;
102 }
103 if ( (addr & 1) != 0 )
104 {
105 return -14;
106 }
107 if ( addr + count >= (acUint32)Flashc.size )
108 {
109 return -34;
110 }
111 v6 = (flash_addr_t)(addr + 0xB0000000);
112 if ( Flashc.status >= 2 )
113 {
114 Flashc.ops->fo_reset(v6);
115 buf = v3;
116 }
117 size = count;
118 v8 = (unsigned int)count >> 1;
119 for ( flashc = (struct flash_softc *)v6; v8 > 0; buf = (char *)buf + 2 )
120 {
121 --v8;
122 *(acUint16 *)buf = flashc->status;
123 flashc = (struct flash_softc *)((char *)flashc + 2);
124 }
125 return size - 2 * v8;
126}
127
128int acFlashVerify(acFlashAddr addr, void *buf, int count)
129{
130 void *v3;
131 flash_addr_t v6;
132 int size;
133 signed int v8;
134 struct flash_softc *flashc;
135
136 v3 = buf;
137 if ( Flashc.status == 0 )
138 {
139 return -6;
140 }
141 if ( (addr & 1) != 0 )
142 {
143 return -14;
144 }
145 if ( addr + count >= (acUint32)Flashc.size )
146 {
147 return -34;
148 }
149 v6 = (flash_addr_t)(addr + 0xB0000000);
150 if ( Flashc.status >= 2 )
151 {
152 Flashc.ops->fo_reset(v6);
153 buf = v3;
154 }
155 size = count;
156 v8 = (unsigned int)count >> 1;
157 for ( flashc = (struct flash_softc *)v6; v8 > 0; --v8 )
158 {
159 int status_low;
160 int v11;
161
162 status_low = flashc->status & 0xFFFF;
163 flashc = (struct flash_softc *)((char *)flashc + 2);
164 v11 = *(acUint16 *)buf;
165 buf = (char *)buf + 2;
166 if ( v11 != status_low )
167 break;
168 }
169 return size - 2 * v8;
170}
171
172int acFlashStatus(acFlashAddr addr)
173{
174 if ( Flashc.status == 1 )
175 return 1;
176 if ( Flashc.status == 2 )
177 {
178 if ( addr >= (acUint32)Flashc.size )
179 return -34;
180 return Flashc.ops->fo_status(addr + 0xB0000000);
181 }
182 return -6;
183}
184
185int acFlashInfo(acFlashInfoData *info)
186{
187 flash_ops_t ops;
188 struct flash_softc *flashc;
189
190 if ( info == NULL )
191 {
192 return -22;
193 }
194 if ( Flashc.status == 0 )
195 {
196 return -6;
197 }
198 ops = Flashc.ops;
199 info->fi_blocks = Flashc.ops->fo_blocks;
200 flashc = (struct flash_softc *)ops->fo_bsize;
201 info->fi_bsize = (acUint32)flashc;
202 return 0;
203}
204
205int acFlashModuleStatus()
206{
207 return Flashc.status;
208}
209
210int acFlashModuleStart(int argc, char **argv)
211{
212 acInt32 v4;
213 int v5;
214 int index;
215 struct flash_ops *v9;
216
217 (void)argc;
218 (void)argv;
219 if ( acFlashModuleStatus() != 0 )
220 {
221 return -16;
222 }
223 *((volatile acUint16 *)0xB2416006) = 0;
224 DelayThread(100000);
225 index = 0;
226 while ( (unsigned int)index < 2 )
227 {
228 if ( *(probes_22[index]) )
229 {
230 v9 = (probes_22[index])(0xB0000000);
231 if ( v9 )
232 {
233 Flashc.status = 1;
234 v4 = v9->fo_bsize * v9->fo_blocks;
235 Flashc.ops = v9;
236 v5 = 0;
237 Flashc.size = v4;
238 break;
239 }
240 }
241 ++index;
242 }
243 if ( (unsigned int)index >= 2 )
244 {
245 printf("acflash: no flash\n");
246 v5 = -6;
247 }
248 *((volatile acUint16 *)0xB2416004) = 0;
249 return v5;
250}
251
252int acFlashModuleStop()
253{
254 if ( acFlashModuleStatus() != 0 )
255 {
256 acFlashStop();
257 }
258 return 0;
259}
260
261int acFlashModuleRestart(int argc, char **argv)
262{
263 (void)argc;
264 (void)argv;
265
266 return -88;
267}
u32 count
start sector of fragmented bd/file