carderase.c
2.94 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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#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)
static void
erase_block(u32 dev, u32 addr) {
IO_WRITE(PI_FLASH_ADDR_REG, addr << (PI_FLASH_PAGE_ADDR_SHIFT+PI_FLASH_PAGE_PER_BLOCK_POW2));
IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
0xe << PI_FLASH_CTRL_ADPH_SHIFT |
NAND_CMD_ERASE_0 << PI_FLASH_CTRL_CMD_SHIFT |
dev << PI_FLASH_CTRL_DEV_SHIFT |
PI_FLASH_CTRL_MCMD);
do {
if (IO_READ(MI_EINTR_REG)&(MI_EINTR_MODULE_REMOVED)) return /*1*/;
} while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
PI_FLASH_CTRL_INTR |
0x0 << PI_FLASH_CTRL_ADPH_SHIFT |
NAND_CMD_ERASE_1 << PI_FLASH_CTRL_CMD_SHIFT |
PI_FLASH_CTRL_WRDY |
dev << PI_FLASH_CTRL_DEV_SHIFT);
}
static void
erase_blocks(u32 dev, const u16 addr[], u32 n) {
do {
IO_WRITE(PI_FLASH_ADDR_REG, addr[--n] << (PI_FLASH_PAGE_ADDR_SHIFT+PI_FLASH_PAGE_PER_BLOCK_POW2));
IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
0xe << PI_FLASH_CTRL_ADPH_SHIFT |
NAND_CMD_ERASE_0 << PI_FLASH_CTRL_CMD_SHIFT |
dev << PI_FLASH_CTRL_DEV_SHIFT |
PI_FLASH_CTRL_MCMD);
do {
if (IO_READ(MI_EINTR_REG)&(MI_EINTR_MODULE_REMOVED)) return /*1*/;
} while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
} while(n > 0);
IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
PI_FLASH_CTRL_INTR |
0x0 << PI_FLASH_CTRL_ADPH_SHIFT |
NAND_CMD_ERASE_1 << PI_FLASH_CTRL_CMD_SHIFT |
PI_FLASH_CTRL_WRDY |
dev << PI_FLASH_CTRL_DEV_SHIFT);
}
s32
osBbCardEraseBlock(u32 dev, u16 block) {
s32 rv;
u8 tmp;
VERBOSE(osSyncPrintf("erase block %d\n", block));
if ((rv = __osBbCardGetAccess()) < 0) return rv;
erase_block(dev, block);
if ((rv = __osBbCardWaitEvent()) < 0 || __osBbCardStatus(dev, &tmp, 0))
rv = BBCARD_ERR_CHANGED;
else if (tmp != (NAND_STATUS_CMD_PASS|NAND_STATUS_READY|NAND_STATUS_WRITE_OK))
rv = BBCARD_ERR_FAIL;
__osBbCardRelAccess();
return rv;
}
#define BLOCK_PLANE(baddr) ((baddr)&3)
#define BLOCK_SEG(baddr) ((baddr)>>12)
s32
osBbCardEraseBlocks(u32 dev, const u16 block[], u32 n) {
u32 i = 0;
s32 rv;
u8 tmp;
VERBOSE(osSyncPrintf("erase blocks %d %d\n", block[0], n));
if ((rv = __osBbCardGetAccess()) < 0) return rv;
while(i < n) {
int j = i+1;
u32 plane = 1 << BLOCK_PLANE(block[i]);
u32 seg = BLOCK_SEG(block[i]);
while(__osBbCardMultiplane && j < n) {
int p = 1 << BLOCK_PLANE(block[j]);
if ((p & plane) || seg != BLOCK_SEG(block[j])) break;
plane |= p;
j++;
}
erase_blocks(dev, block+i, j-i);
if ((rv = __osBbCardWaitEvent()) < 0) goto error;
i = j;
}
if (__osBbCardStatus(dev, &tmp, 0))
rv = BBCARD_ERR_CHANGED;
else if (tmp != (NAND_STATUS_CMD_PASS|NAND_STATUS_READY|NAND_STATUS_WRITE_OK))
rv = BBCARD_ERR_FAIL;
error:
__osBbCardRelAccess();
return rv;
}