cardread.c
2.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <ultra64.h>
#include "bcp.h"
#include "bbnand.h"
#include "bbfs.h"
#include "os_bbcard.h"
#include "bbint.h"
#include "piint.h"
#define VERBOSE(x)
u32 __osBbCardSbErr;
static void
read_page(u32 dev, u32 addr, u32 which_buf) {
IO_WRITE(PI_FLASH_ADDR_REG, addr << PI_FLASH_PAGE_ADDR_SHIFT);
IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
PI_FLASH_CTRL_INTR |
PI_FLASH_CTRL_RDPH |
0xf << PI_FLASH_CTRL_ADPH_SHIFT |
0x0 << PI_FLASH_CTRL_CMD_SHIFT |
PI_FLASH_CTRL_WRDY |
which_buf << PI_FLASH_CTRL_BUF_SHIFT |
dev << PI_FLASH_CTRL_DEV_SHIFT |
PI_FLASH_CTRL_ECC |
528);
}
s32
osBbCardReadBlock(u32 dev, u16 block, void* addr, void* spare) {
u32 x, i, b = 0;
s32 rv, db = 0;
VERBOSE(osSyncPrintf("read block %d\n", block));
#ifdef _DEBUG
if ((u32)addr&15) return BBCARD_ERR_INVALID;
#endif
if ((rv = __osBbCardGetAccess()) < 0) return rv;
if (spare) ((u8*)spare)[BB_FL_BLOCK_STATUS_OFF] = 0xff;
for(i = 0; i < BB_FL_BLOCK_PAGES; i++) {
read_page(dev, BB_FL_BYTE_TO_PAGE(BB_FL_BLOCK_TO_BYTE(block)+i*BB_FL_PAGE_SIZE), b);
if (i) {
__osBbCardDmaCopy(b^1, addr+BB_FL_PAGE_SIZE*(i-1), OS_READ);
if (spare) {
u32 addr = PI_BUFFER_0_OOB_START+(b^1)*(PI_BUFFER_OOB_SIZE>>1);
((u8*)spare)[BB_FL_BLOCK_STATUS_OFF] &= IO_READ(addr+4) >> 8;
}
}
if ((rv = __osBbCardWaitEvent()) < 0) goto error;
if ((x = IO_READ(PI_FLASH_CTRL_REG)) & PI_FLASH_CTRL_DBERR) {
#ifdef _DEBUG
#if 0
osSyncPrintf("double bit error block %d (page %d)\n", block, i);
#endif
#endif
db = BBCARD_ERR_FAIL;
if (!spare || i == BB_FL_BLOCK_PAGES-1)
goto error;
}
if (x & PI_FLASH_CTRL_SBERR)
__osBbCardSbErr++;
b ^= 1;
}
__osBbCardDmaCopy(b^1, addr+BB_FL_PAGE_SIZE*(i-1), OS_READ);
error:
if (spare) {
u8 *p = spare;
u32 addr = PI_BUFFER_0_OOB_START+(b^1)*(PI_BUFFER_OOB_SIZE>>1);
for(i = 0; i < BB_FL_SPARE_SIZE/4; i++) {
u32 x = IO_READ(addr+4*i);
p[0] = x >> 24;
p[1] = x >> 16;
if (i == 1) p[2] &= x >> 8;
else p[2] = x >> 8;
p[3] = x;
p += 4;
}
}
__osBbCardRelAccess();
return db ? db : rv;
}