cardinit.c
5.3 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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#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)
u8 __osBbCardMultiplane;
u8 __osBbCardChange = 1;
u8 __osBbCardInit;
u16 __osBbCardBlocks;
#define _EPI_DMA
#ifdef _EPI_DMA
static OSPiHandle __osBbCardHandler;
static OSMesgQueue __osBbCardDmaQ;
static OSMesg __osBbCardDmaBuf;
#define DEVICE_TYPE_PI 6
#endif
const struct {
u8 mfg;
u8 dev;
u16 blocks;
u32 config;
} __osBbCardConfig[] = {
/* default */
{ 0x0, 0x0, 0x0, 0x7 << PI_FLASH_CONFIG_EO_CYC_T_SHIFT |
0x5 << PI_FLASH_CONFIG_RD_SAM_T_SHIFT |
0x3e << PI_FLASH_CONFIG_RE_ACT_T_SHIFT |
0x3e << PI_FLASH_CONFIG_WE_ACT_T_SHIFT |
0xff << PI_FLASH_CONFIG_CA_ACT_T_SHIFT } ,
/* Samsung K9F1208U0M */
{ 0xec, 0x76, 4096, 0x4 << PI_FLASH_CONFIG_EO_CYC_T_SHIFT |
0x4 << PI_FLASH_CONFIG_RD_SAM_T_SHIFT |
0x1f << PI_FLASH_CONFIG_RE_ACT_T_SHIFT |
0x1f << PI_FLASH_CONFIG_WE_ACT_T_SHIFT |
0x3f << PI_FLASH_CONFIG_CA_ACT_T_SHIFT } ,
/* Samsung K9K1G08U0M */
{ 0xec, 0x79, 8192, 0x4 << PI_FLASH_CONFIG_EO_CYC_T_SHIFT |
0x4 << PI_FLASH_CONFIG_RD_SAM_T_SHIFT |
0x1f << PI_FLASH_CONFIG_RE_ACT_T_SHIFT |
0x1f << PI_FLASH_CONFIG_WE_ACT_T_SHIFT |
0x3f << PI_FLASH_CONFIG_CA_ACT_T_SHIFT } ,
/* Toshiba TC58512FT */
{ 0x98, 0x76, 4096, 0x7 << PI_FLASH_CONFIG_EO_CYC_T_SHIFT |
0x5 << PI_FLASH_CONFIG_RD_SAM_T_SHIFT |
0x3e << PI_FLASH_CONFIG_RE_ACT_T_SHIFT |
0x1f << PI_FLASH_CONFIG_WE_ACT_T_SHIFT |
0x3f << PI_FLASH_CONFIG_CA_ACT_T_SHIFT } ,
/* ST NAND512-A */
{ 0x20, 0x76, 4096, 0x4 << PI_FLASH_CONFIG_EO_CYC_T_SHIFT |
0x4 << PI_FLASH_CONFIG_RD_SAM_T_SHIFT |
0x1f << PI_FLASH_CONFIG_RE_ACT_T_SHIFT |
0x1f << PI_FLASH_CONFIG_WE_ACT_T_SHIFT |
0x3f << PI_FLASH_CONFIG_CA_ACT_T_SHIFT } ,
/* end of table */
{ 0xff, 0xff, 0x0, 0xff }
};
u32
__osBbCardPresent(void) {
/* hook to detect that card has changed even when we aren't explicitly
* performing a card operation
*/
if (__osBbCardFlushEvent())
__osBbCardChange = 1;
return (IO_READ(MI_EINTR_REG)&MI_EINTR_MD_STATUS) != MI_EINTR_MODULE_REMOVED;
}
/* Access queue used for mutual exclusion on PI FLASH */
#define NUM_ACCESS_MESG 1
static OSMesg cardAccessBuf[NUM_ACCESS_MESG];
OSMesgQueue __osBbCardAccessQueue;
void
__osBbCardRelAccess(void) {
(void)osSendMesg(&__osBbCardAccessQueue, (OSMesg)0, OS_MESG_NOBLOCK);
}
s32
__osBbCardGetAccess(void) {
(void)osRecvMesg(&__osBbCardAccessQueue, NULL, OS_MESG_BLOCK);
if (!__osBbCardPresent() || __osBbCardChange) {
/* cancel */
__osBbCardRelAccess();
return __osBbCardPresent() ? BBCARD_ERR_CHANGED : BBCARD_ERR_NO_CARD;
}
return 0;
}
void
osBbCardInit(void) {
u32 type, mfg;
if (!__osBbCardInit) {
osCreateMesgQueue(&__osBbCardAccessQueue, cardAccessBuf, NUM_ACCESS_MESG);
/* Initialize the access queue with a resource token */
(void)osSendMesg(&__osBbCardAccessQueue, (OSMesg)0, OS_MESG_NOBLOCK);
__osBbCardInitEvent();
IO_WRITE(MI_INTR_EMASK_REG, MI_INTR_MASK_SET_FLASH|MI_INTR_MASK_SET_MD);
#ifdef _EPI_DMA
__osBbCardHandler.type = DEVICE_TYPE_PI;
__osBbCardHandler.baseAddress = 0;
__osBbCardHandler.latency = 0;
__osBbCardHandler.pulse = 0;
__osBbCardHandler.pageSize = /*512*/0; /*XXXblythe doesn't get used*/
__osBbCardHandler.relDuration = 0;
__osBbCardHandler.domain = 0;
__osBbCardHandler.speed = 0;
bzero((void *)&(__osBbCardHandler.transferInfo),
sizeof(__osBbCardHandler.transferInfo));
osEPiLinkHandle(&__osBbCardHandler);
osCreateMesgQueue(&__osBbCardDmaQ, &__osBbCardDmaBuf, 1);
#endif
__osBbCardInit = 1;
}
IO_WRITE(PI_FLASH_CTRL_REG, 0);
__osBbCardChange = 0;
/* flush queue */
/*XXXblythe should probably be mutexed*/
(void)__osBbCardFlushEvent();
if ((IO_READ(MI_EINTR_REG)&MI_EINTR_MD_STATUS) != MI_EINTR_MODULE_REMOVED) {
u16 i;
s32 rv;
IO_WRITE(PI_FLASH_CONFIG_REG, __osBbCardConfig[0].config);
if ((rv = osBbCardReadId(0, &mfg, &type)) < 0) {
#ifdef DEBUG
osSyncPrintf("Read id failed %d\n", rv);
#endif
}
for(i = 0; __osBbCardConfig[i].mfg != 0xff; i++) {
if (__osBbCardConfig[i].mfg == mfg && __osBbCardConfig[i].dev == type) {
__osBbCardBlocks = __osBbCardConfig[i].blocks;
IO_WRITE(PI_FLASH_CONFIG_REG, __osBbCardConfig[i].config);
break;
}
}
} else
__osBbCardBlocks = 0;
}
void
__osBbCardDmaCopy(u32 which, void *addr, u32 dir) {
#ifdef _EPI_DMA
OSIoMesg m;
m.hdr.pri = OS_MESG_PRI_NORMAL;
m.hdr.retQueue = &__osBbCardDmaQ;
m.dramAddr = addr;
m.size = 512;
m.devAddr = which*512;
if (dir == OS_WRITE) osWritebackDCache(addr, 512);
osEPiStartDma(&__osBbCardHandler, &m, dir);
osRecvMesg(&__osBbCardDmaQ, NULL, OS_MESG_BLOCK);
if (dir == OS_READ) osInvalDCache(addr, 512);
#else
__osPiGetAccess();
IO_WRITE(PI_CART_ADDR_REG, which*512);
IO_WRITE(PI_DRAM_ADDR_REG, osVirtualToPhysical(addr));
if (dir == OS_READ) {
IO_WRITE(PI_DMA_BUFFER_WR_REG, 511);
while(IO_READ(PI_STATUS_REG)&PI_STATUS_DMA_BUSY)
;
osInvalDCache(addr, 512);
} else {
osWritebackDCache(addr, 512);
IO_WRITE(PI_DMA_BUFFER_RD_REG, 511);
while(IO_READ(PI_STATUS_REG)&PI_STATUS_DMA_BUSY)
;
}
__osPiRelAccess();
#endif
}