PS2SDK
PS2 Homebrew Libraries
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 
13 static flash_probe_t probes_22[2] = {&flash_probe_i28f640f5, &flash_probe_mbm29f033c};
14 static struct flash_softc Flashc;
15 
16 int 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 
29 int 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 
60 int 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 
73 int 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 
90 int 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 
128 int 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 
172 int 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 
185 int 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 
205 int acFlashModuleStatus()
206 {
207  return Flashc.status;
208 }
209 
210 int 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 
252 int acFlashModuleStop()
253 {
254  if ( acFlashModuleStatus() != 0 )
255  {
256  acFlashStop();
257  }
258  return 0;
259 }
260 
261 int acFlashModuleRestart(int argc, char **argv)
262 {
263  (void)argc;
264  (void)argv;
265 
266  return -88;
267 }
s_info
Definition: xprintf.c:78
flash_softc
Definition: acflash_internal.h:37
flash_ops
Definition: acflash_internal.h:21
count
u32 count
start sector of fragmented bd/file
Definition: usbhdfsd-common.h:3
ac_flash_info
Definition: acflash.h:18