iplleoutil.c
7.83 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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/*
* F i l e N a m e : i p l l e o u t i l . c
*
****************************************************************************
* (C) Copyright ALPS Electric Co., Ltd. 1995-1996
****************************************************************************
* Version
*
* ver Data
* ---- --------
* 1.20 '97-06-23 Updata device_driver revision(20->21).
* 1.19 '97-01-10 Updata device_driver revision(19->20).
* Change B014B for "_ERRCHK".
* 1.18 '96-12-25 Update internal revision (A18->A19,X18->X19).
* change (auto u64 rd_mseq_code) to (static u32)
* 1.17 '96-12-06 Change "#ifdef _ERRCHK" for revision B034X18 .
* Update internal revision (A17->A18) .
* 1.16 '96-11-27 Change "#ifdef _ERRCHK" revision "B044A17" -> "B074A17" .
* 1.15 '96-11-21 Add "#ifdef _ERRCHK" for revision B044A17 .
* 1.15 '96-11-15 Update internal revision (A16->A17) .
* 1.14 '96-11-05 Update internal revision (A15->A16) .
* 1.13 '96-10-01 Update internal revision (A14->A15) .
* Delete DMA transfer errStatus check .
* 1.12 '96-09-20 Update internal revision (A13->A14) .
* Change defect data check in leoiplLba_to_phys() .
* 1.11 '96-09-11 Update internal revision (A12->A13) .
* Change defect data check in leoiplLba_to_phys() .
* 1.10 '96-08-27 Update internal revision (A11->A12) .
* See LeoIPL_country_code to check system sector size to remove KAIHATU definition.
* 1.09 '96-08-21 Update internal revision (A10->A11) .
* 1.09 '96-08-09 Update internal revision (A09->A10) .
* 1.08 '96-08-02 Update internal revision (A08->A09) .
* 1.07 '96-07-16 Update internal revision (A06->A08) .
* Change micro sequencer setup .
* 1.06 '96-06-13 Add LeoIPLtgt_param.sec_bytes,.blk_byte calc in leoiplLba_to_phys().
* 1.05 '96-06-12 Update internal revision .
* 1.04 '96-05-22 Update internal revision .
* 1.03 '96-05-08 Update internal revision .
* 1.02 '96-04-12 Update internal revision .
* 1.01 '96-02-27 Rename iplutil.c to iplleoutil.c .
* 1.00 '95-12-20 Initial revision .
****************************************************************************
*/
#include "os.h"
#include <ultra64.h>
#include "leodefine.h"
#include "leodrive.h"
#include "iplleomacro.h"
#include "leoappli.h"
/*************************************/
/* PROTOTYPE */
/*************************************/
void leoiplSet_mseq(void);
u16 leoiplLba_to_phys(u32 lba);
/*************************************/
/* EXTERNAL FUNCTIONS */
/*************************************/
extern u32 LeoIPLasic_bm_ctl_shadow;
extern u32 LeoIPLasic_seq_ctl_shadow;
extern struct tgt_param_form LeoIPLtgt_param;
extern OSMesgQueue LeoIPLcontrol_que;
extern OSMesgQueue LeoIPLdma_que;
extern union leo_sys_form LeoIPL_sys_data;
extern OSPiHandle *LeoIPLPiInfo;
extern OSIoMesg LeoIPLPiDmaParam;
extern union data_trans_form LeoIPL_country_code;
/***************************************/
/* Micro Sequencer Address */
/***************************************/
#define MSEQ_LEN 16
/*************************************/
/* RAM DEFINITIONS */
/*************************************/
static u32 mseq_tbl[MSEQ_LEN]; /* must be top of this file */
/*************************************/
/* IPL DRIVER VERISION */
/*************************************/
#ifdef _ERRCHK
const s8 LEOiplfirmware_rev[] = {"B034B21"};
#else
const s8 LEOiplfirmware_rev[] = {"B034A21"};
#endif
/***************************************
* SEQUENCER MAP (for zone-0 use only)
***************************************/
static const u32 rd_mseq_code[MSEQ_LEN] = {
0x00010000, /* 00H WAIT */
0x00020200, /* 01H Gap */
0x80030100, /* 02H AM */
0x82040000, /* 03H DATA */
0xa8050000, /* 04H C1 */
0xa0060600, /* 05H SSP */
0x31760000, /* 06H Gap */
0x00020300, /* 07H Gap */
0x00000000, /* 08H NOT USE */
0x00000000, /* 09H NOT USE */
0x00000000, /* 0AH NOT USE */
0x00000000, /* 0BH NOT USE */
0x00000000, /* 0CH NOT USE */
0x00000000, /* 0DH NOT USE */
0x00000000, /* 0EH NOT USE */
0x00060000 }; /* 0FH NEXT SECTOR */
/* ==========================================================================
* Function : leoiplSet_mseq
* --------------------------------------------------------------------------
* Description : WRITE SEQUENCER MAP TO DRIVE
* --------------------------------------------------------------------------
* IN : LeoIPLtgt_param.zone
* OUT : non
* ARG : u16 rw_mode .. read/write
* RET : non
* ==========================================================================
*/
void leoiplSet_mseq(void)
{
u32 message;
u8 i;
leoiplMicro_pc_disable(); /* SLEEP BM */
for (i=0; i<MSEQ_LEN; i++)
mseq_tbl[i] = rd_mseq_code[i];
((u32*)mseq_tbl)[4] |= ((u32)(LeoIPLtgt_param.sec_bytes - 1) << 8);
osWritebackDCache((void *)mseq_tbl, (s32)(MSEQ_LEN * 4));
/* write map to drive */
LeoIPLPiDmaParam.dramAddr = (void*)mseq_tbl;
LeoIPLPiDmaParam.devAddr = MSEQ_RAM_ADDR;
LeoIPLPiDmaParam.size = (u32)(MSEQ_LEN * 4);
LeoIPLPiInfo->transferInfo.cmdType = OS_OTHERS; /* disk_read, disk-write or others */
leoiplAd16StartDma(OS_WRITE); /* start sequencer and dma */
/* Wait DMA done */
(void)osRecvMesg(IPLDMA_QUE, (OSMesg*)&message, OS_MESG_BLOCK);
/* Set sector and bytes */
leoiplAd16WriteIo(ASIC_HOST_SECBYTE, ((u32)(LeoIPLtgt_param.sec_bytes - 1) << 16));
/* Set bytes */
leoiplAd16WriteIo(ASIC_SEC_BYTE, (u32)((HALF_SECS_U16 | (LeoIPLtgt_param.sec_bytes + C1_LENGTH - 1)) << 16));
leoiplMicro_pc_enable(); /* Wakeup BM (not start) */
}
/* ==========================================================================
* Function : leoiplLba_to_phys
* --------------------------------------------------------------------------
* Description : Translate lba to physical address (for zone0 only)
* --------------------------------------------------------------------------
* IN :
* OUT : LeoIPLtgt_param
* ARG : lba
* RET : 0 .. GOOD
* : NOT 0 .. NG
* ==========================================================================
*/
u16 leoiplLba_to_phys(u32 lba)
{
u16 bad_tk_num;
u32 counter;
/* BLOCKS IN TK */
LeoIPLtgt_param.rdwr_blocks = (u32)0x02 - (lba & (u32)0x01);
/* START BLOCK */
switch (lba & (u32)0x03)
{
case 0: /* START AT BLOCK 0 */
case 3:
LeoIPLtgt_param.start_block = (u16)0x00;
break;
default: /* START AT BLOCK 1 */
LeoIPLtgt_param.start_block = (u16)0x01;
break;
}
LeoIPLtgt_param.zone = 0;
LeoIPLtgt_param.head = 0;
/* TRACK NUMBER */
LeoIPLtgt_param.cylinder = lba >> 1;
/* defect track check */
bad_tk_num = LeoIPL_sys_data.param.defect_num[0];
counter = 0;
while (bad_tk_num)
{
/* COUNT DEFECT */
if (LeoIPLtgt_param.cylinder < (u16)LeoIPL_sys_data.param.defect_data[counter])
break;
LeoIPLtgt_param.cylinder++;
counter++;
bad_tk_num--;
}
LeoIPLtgt_param.sec_bytes = SEC_SIZE_ZONE0;
LeoIPLtgt_param.blk_bytes = (SEC_SIZE_ZONE0*USR_SECS_PER_BLK );
if ((LeoIPL_country_code.u32_data == 0) && (lba < SYS_UNCORR_LBA))
{
LeoIPLtgt_param.sec_bytes = SEC_SIZE_SYSTEM;
LeoIPLtgt_param.blk_bytes = SEC_SIZE_SYSTEM*USR_SECS_PER_BLK;
}
return(FUNC_OK);
}