PS2SDK
PS2 Homebrew Libraries
i28f640j5.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 int flash_erase(flash_addr_t addr);
14 static int flash_program(flash_addr_t addr, const flash_data_t *buf, int size);
15 static int flash_reset(flash_addr_t addr);
16 static int flash_status(flash_addr_t addr);
17 
18 static struct flash_ops ops_30 = {
19  "Intel 28F640J5", 131072u, 64u, 0, &flash_erase, &flash_program, &flash_reset, &flash_status};
20 
21 static int flash_wait(flash_ptr_t ptr, int tick, int count)
22 {
23  int threshold;
24 
25  threshold = tick - 1;
26  while ( threshold >= 0 )
27  {
28  int sr;
29 
30  *ptr = 0x70;
31  sr = *ptr;
32  if ( (sr & 0x80) == 0 )
33  sr = -116;
34  if ( sr >= 0 )
35  return sr;
36  threshold--;
37  }
38  do
39  {
40  int sr_v3;
41 
42  DelayThread(tick);
43  *ptr = 0x70;
44  sr_v3 = *ptr;
45  if ( (sr_v3 & 0x80) == 0 )
46  sr_v3 = -116;
47  if ( sr_v3 >= 0 )
48  return sr_v3;
49  --count;
50  } while ( count >= 0 );
51  return -116;
52 }
53 
54 static int flash_erase(flash_addr_t addr)
55 {
56  *(volatile acUint16 *)addr = 0x20;
57  *(volatile acUint16 *)addr = 0xD0;
58  return ((acUint32)(~flash_wait((flash_ptr_t)addr, 400, 2)) >> 31) & 0x20000;
59 }
60 
61 static int flash_program(flash_addr_t addr, const flash_data_t *buf, int size)
62 {
63  int rest;
64  int xlen;
65  int count;
66  int threshold;
67  int v12;
68  unsigned int v14;
69  int xlen_v9;
70 
71  rest = size;
72  while ( 1 )
73  {
74  int blen;
75 
76  if ( rest <= 0 )
77  return size - rest;
78  blen = 0x20000 - (addr & 0x1FFFF);
79  if ( rest < blen )
80  blen = rest;
81  rest -= blen;
82  while ( blen > 0 )
83  {
84  flash_addr_t v8;
85 
86  v8 = addr & 0xF;
87  xlen = 16 - v8;
88  count = 2;
89  if ( blen < (int)(16 - v8) )
90  xlen = blen;
91  threshold = 399;
92  while ( 1 )
93  {
94  *(volatile acUint16 *)addr = 0xE8;
95  v12 = *(acUint16 *)addr;
96  if ( (v12 & 0x80) != 0 )
97  break;
98  threshold--;
99  if ( threshold < 0 )
100  {
101  while ( count >= 0 )
102  {
103  DelayThread(400);
104  *(volatile acUint16 *)addr = 0xE8;
105  v12 = *(volatile acUint16 *)addr;
106  // cppcheck-suppress knownConditionTrueFalse
107  if ( (v12 & 0x80) != 0 )
108  break;
109  --count;
110  v12 = -116;
111  }
112  break;
113  }
114  }
115  v14 = xlen + 1;
116  if ( v12 < 0 )
117  break;
118  blen -= xlen;
119  *(volatile acUint16 *)addr = v14 >> 1;
120  xlen_v9 = (v14 >> 1) - 1;
121  for ( *(volatile acUint16 *)addr = *buf; xlen_v9 >= 0; addr += 2 )
122  {
123  --xlen_v9;
124  *(volatile acUint16 *)addr = *buf++;
125  }
126  *(volatile acUint16 *)(addr - 2) = 0xD0;
127  }
128  if ( flash_wait((flash_ptr_t)(addr - 2), 400, 2) < 0 || blen > 0 )
129  return rest + blen - size;
130  }
131 }
132 
133 static int flash_reset(flash_addr_t addr)
134 {
135  *(acUint16 *)addr = 0xFF;
136  return 0x800000;
137 }
138 
139 flash_ops_t flash_probe_i28f640f5(flash_addr_t addr)
140 {
141  acUint16 vendor;
142  acUint16 device;
143 
144  *(volatile acUint16 *)addr = 0xFF;
145  *(volatile acUint16 *)addr = 0x90;
146  vendor = *(volatile acUint16 *)addr;
147  *(volatile acUint16 *)addr = 0x90;
148  device = *(volatile acUint16 *)(addr + 2);
149  *(volatile acUint16 *)addr = 0xFF;
150  // cppcheck-suppress knownConditionTrueFalse
151  if ( vendor != 0x89 || device != 0x15 )
152  return 0;
153  return &ops_30;
154 }
155 
156 static int flash_status(flash_addr_t addr)
157 {
158  *(volatile acUint16 *)addr = 0x70;
159  // cppcheck-suppress knownConditionTrueFalse
160  if ( (*(volatile acUint16 *)addr & 0x80) != 0 )
161  return 1;
162  return 2;
163 }
flash_ops
Definition: acflash_internal.h:21
count
u32 count
start sector of fragmented bd/file
Definition: usbhdfsd-common.h:3