iplleocmdex.c
13.8 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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
/*
* F i l e N a m e : i p l l e o c m d e x . c
*
****************************************************************************
* (C) Copyright ALPS Electric Co., Ltd. 1995-1996
****************************************************************************
* Version
*
* ver Data
* ---- --------
* 1.16 '97-01-10 Add recal at system read retry.
* 1.15 '96-12-24 Add leoiplReadTimer(),leoiplSetTimer() command.
* 1.14 '96-11-22 Add _ERRCHK definition.
* 1.13 '96-10-30 Add Check of CLR_QUEUE request .
* 1.12 '96-09-20 Add leoiplReadDiskId command.
* 1.12 '96-09-20 Change old format disk is "UNKNOWN FORMAT ERROR" .
* 1.11 '96-09-10 Change LeoIPL_sys_data structure .
* 1.10 '96-08-27 See LeoIPL_country_code to check system sector size to remove KAIHATU definition.
* 1.09 '96-08-21 Load segment to address LeoIPL_sys_data.param.loadptr.
* 1.08 '96-07-25 Change initialize for phase1.
* 1.07 '96-07-08 LeoIPL_country_code change union.
* 1.06 '96-07-03 Save LeoIPL_country_code for device driver .
* 1.05 '96-06-24 Modefy Read Command control bit .
* Deleted Timer Command .
* 1.04 '96-06-17 Modefy LeoIPL_country_code handling and bad_ecc check .
* 1.03 '96-05-08 Change System area read retrycntr (40 -> MAX_RETRY)
* Change Bad ECC Sector read retrycntr ( 5 -> MAX_RETRY)
* 1.02 '96-02-27 Change file name from iplmain.c to iplleocmdex.c
* Debug Bad ECC Sector read.
* 1.01 '96-02-03 Debug.
* 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 DEFINITIONS */
/*************************************/
void leoiplMain(void *arg);
u8 leoiplRead_system_area(void);
u8 leoiplRead_ipl(void);
/*************************************/
/* EXTERNAL FUNCTIONS */
/*************************************/
extern void leoiplRead_zone0(void);
extern u8 leoiplReadDiskId(void);
extern void leoiplReadTimer(void);
extern void leoiplSetTimer(void);
extern void leoIPLClr_queue(void);
/*************************************/
/* RAM DEFINITIONS */
/*************************************/
union data_trans_form LeoIPL_country_code;
/*************************************/
/* EXTERNAL RAMS */
/*************************************/
extern union leo_sys_form LeoIPL_sys_data;
extern OSMesg LeoIPLcur_command;
extern OSMesgQueue LeoIPLcommand_que;
extern OSMesgQueue LeoIPLevent_que;
extern OSMesgQueue LeoIPLdma_que;
extern u8 LeoIPLdrive_flag;
extern volatile u8 LeoIPLclr_que_flag;
extern u8 LeoIPLdisk_type;
extern u16 LeoIPLrw_flags;
extern u32 LeoIPLasic_bm_ctl_shadow;
extern u32 LeoIPLasic_seq_ctl_shadow;
/*************************************/
/* LOCAL DEFINITIONS */
/*************************************/
/*-----------------------------------*/
/* IPL READ(05H) COMMAND STRUCTURE */
/*-----------------------------------*/
struct ipl_read_cmd_form {
LEOCmdHeader header;
u64 *buff_ptr;
union data_trans_form code;
};
static const u8 ipl_system_lba[4] = {
SYS_DATA_LBA1,
SYS_DATA_LBA2,
SYS_DATA_LBA3,
SYS_DATA_LBA4 };
/*----------------- NEW OS -------------------*/
OSPiHandle *LeoIPLPiInfo;
OSIoMesg LeoIPLPiDmaParam;
#define chk_cmd ((LEOCmdHeader *)LeoIPLcur_command)
/* ==========================================================================
* Function : leoiplMain
* --------------------------------------------------------------------------
* Description : Excute command in command queue
* --------------------------------------------------------------------------
* IN : commnad in commnad que
* OUT : LeoIPLcur_command
* ARG : Not used
* RET : non
* ==========================================================================
*/
void leoiplMain(void *arg)
{
u32 sense;
u32 postoffset;
u32 cur_status;
u8 ret;
/* Initialize shadow ram */
LeoIPLasic_seq_ctl_shadow = 0;
LeoIPLasic_bm_ctl_shadow = 0;
/* Initialize flags */
leoiplClr_sys_read();
leoiplClr_clr_que_flag();
/* set AD16-bus speed & base address */
LeoIPLPiInfo = osLeoDiskInit();
LeoIPLPiDmaParam.hdr.pri = OS_MESG_PRI_HIGH;
LeoIPLPiDmaParam.hdr.retQueue = IPLDMA_QUE;
/* reset drive */
leoiplDrive_reset();
while (1)
{
/* Get command from queue */
(void)osRecvMesg(IPLCOMMAND_QUE, (OSMesg)&LeoIPLcur_command, OS_MESG_BLOCK);
/*----------------------------------*/
/* command check */
/*----------------------------------*/
switch (chk_cmd->command)
{
case 0:
leoiplDrive_reset();
(void)osRecvMesg(IPLEVENT_QUE, NULL, OS_MESG_NOBLOCK);
continue;
case LEO_COMMAND_TEST_UNIT_READY:
sense = leoiplChk_asic_ready(ASIC_RD_SEEK); /* Clear reset & disk_chg bits */
#ifdef _ERRCHK
if (sense == LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION)
sense = chk_cmd->reserve1;
#endif
pre_cmd_err:
if (chk_cmd->sense = sense)
chk_cmd->status = LEO_STATUS_CHECK_CONDITION;
else
chk_cmd->status = LEO_STATUS_GOOD;
break;
case LEO_COMMAND_READ:
case LEO_COMMAND_READ_DISK_ID:
(void)leoiplChk_asic_ready(ASIC_RD_SEEK); /* Clear reset & disk_chg bits */
/* check disk */
leoiplGet_leo_status(&sense);
if (!(sense & LEO_STAT_DISK))
{
sense = LEO_SENSE_MEDIUM_NOT_PRESENT;
goto pre_cmd_err;
}
if (chk_cmd->command == LEO_COMMAND_READ)
{
ret = leoiplRead_system_area(); /* read defect list and disk-type */
if (ret == LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION)
ret = leoiplRead_ipl();
}
else
{
ret = leoiplReadDiskId();
}
if (ret)
{
if (!leoiplChk_err_retry(ret) )
{
if (ret = leoiplSend_asic_cmd_w(ASIC_SLEEP, 0))
chk_cmd->sense = ret;
}
chk_cmd->status = LEO_STATUS_CHECK_CONDITION;
}
else
chk_cmd->status = LEO_STATUS_GOOD;
break;
case LEO_COMMAND_READ_TIMER:
(void)leoiplChk_asic_ready(ASIC_RD_SEEK); /* Clear reset & disk_chg bits */
leoiplReadTimer();
break;
case LEO_COMMAND_SET_TIMER:
(void)leoiplChk_asic_ready(ASIC_RD_SEEK); /* Clear reset & disk_chg bits */
leoiplSetTimer();
break;
default:
chk_cmd->sense = LEO_SENSE_INVALID_COMMAND_OPERATION_CODE;
chk_cmd->status = LEO_STATUS_CHECK_CONDITION;
continue;
}
/* Post queue */
if (chk_cmd->control & LEO_CONTROL_POST)
{
/* send sense code to post message */
osSendMesg(chk_cmd->post, (OSMesg)(chk_cmd->sense), OS_MESG_BLOCK);
}
/* Check CLR_QUEUE request */
if (leoiplChk_clr_que_flag())
leoIPLClr_queue();
}
}
/* ==========================================================================
* Function : leoiplRead_system_area
* --------------------------------------------------------------------------
* Description : Read system information
* : Hangup if copy protection function detect abnormal format.
* --------------------------------------------------------------------------
* IN : non
* OUT : non
* ARG : non
* RET : 00 - good
* : not 00 - not good. error sense code is set.
* ==========================================================================
*/
const static LEOCmdRead system_read_cmd =
{ { LEO_COMMAND_READ, /* COMMAND */
0x00, /* RESERVE */
0x00, /* CONTROL */
0x00, /* RESERVE */
0x00, /* STATUS */
0x00, /* SENSE */
0x00, /* RESERVE */
0x00, /* RESERVE */
NULL /* POST QUEUE */
},
SYS_UNCORR_LBA, /* LBA */
0x01, /* BLOCKS */
0x00, /* BUFFER POINTER */
0x00 /* READ BYTES */
};
u8 leoiplRead_system_area(void)
{
LEOCmdRead dummy_cmd;
struct ipl_read_cmd_form *backup_pointer;
u32 read_mode;
u32 retry_cntr;
/* Backup current command */
backup_pointer = (struct ipl_read_cmd_form*)LeoIPLcur_command;
LeoIPL_country_code = backup_pointer->code;
LeoIPLcur_command = &dummy_cmd;
read_mode = 0;
retry_cntr = 0;
do
{
/* Set disk_type,defect number to 0 to use in lba_to_phys() routine */
LeoIPLdisk_type = 0;
LeoIPL_sys_data.param.defect_num[0] = 0;
LeoIPLrw_flags = SECTOR_READ + NO_RETRY;
dummy_cmd = system_read_cmd;
dummy_cmd.buff_ptr = &LeoIPL_sys_data.u64_data[0];
if (read_mode == 0)
{
/*************************/
/* read BAD ECC sector */
/*************************/
leoiplRead_zone0();
switch (dummy_cmd.header.sense)
{
case LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION:
do {} while (LeoIPL_country_code.u32_data != 0);
break;
case LEO_SENSE_UNRECOVERED_READ_ERROR:
do {} while (LeoIPL_country_code.u32_data == 0);
break;
default:
goto system_retry;
}
read_mode--;
retry_cntr = 0;
continue;
}
else
{
/*************************/
/* read disk system data */
/*************************/
dummy_cmd.lba = ipl_system_lba[(retry_cntr & 0x03)];
if (LeoIPL_country_code.u32_data == 0)
dummy_cmd.lba += SYS_LBA_DEV_OFFSET;
/* call read routine */
leoiplRead_zone0();
if (dummy_cmd.header.status == LEO_STATUS_GOOD)
{
/* compare country_code */
do {} while (LeoIPL_sys_data.param.country != LeoIPL_country_code.u32_data);
/* Check format type */
switch (LeoIPL_sys_data.param.disk_type & (u8)0xf0)
{
case 0x10:
case 0x20:
case 0x30:
break;
default:
dummy_cmd.header.sense = LEO_SENSE_INCOMPATIBLE_MEDIUM_INSTALLED;
goto sys_read_end;
}
/* Save country_code */
*(u8*)OS_PHYSICAL_TO_K1(0x00000010) = LeoIPL_country_code.u8_data[0];
*(u8*)OS_PHYSICAL_TO_K1(0x00000090) = LeoIPL_country_code.u8_data[1];
*(u8*)OS_PHYSICAL_TO_K1(0x00000110) = LeoIPL_country_code.u8_data[2];
*(u8*)OS_PHYSICAL_TO_K1(0x00000190) = LeoIPL_country_code.u8_data[3];
goto sys_read_end;
}
}
system_retry:
if (leoiplChk_err_retry(dummy_cmd.header.sense))
break;
if (retry_cntr++ >= MAX_RETRY)
break;
if (leoChk_recal(retry_cntr))
{
dummy_cmd.header.sense = leoiplSend_asic_cmd_w(ASIC_RECAL, 0x00);
if (dummy_cmd.header.sense)
goto system_retry;
}
} while (1);
sys_read_end:
/* restore current command */
LeoIPLcur_command = backup_pointer;
return (chk_cmd->sense = dummy_cmd.header.sense);
}
/* ==========================================================================
* Function : leoiplRead_ipl
* --------------------------------------------------------------------------
* Description : Read first segment of application program.
* --------------------------------------------------------------------------
* IN : LeoIPLcur_command
* OUT : *LeoIPLcur_command
* ARG : non
* RET : 0:good , not 0: error sense code
* ==========================================================================
*/
u8 leoiplRead_ipl(void)
{
LEOCmdRead dummy_cmd;
struct ipl_read_cmd_form *backup_pointer;
/* Backup current command */
backup_pointer = LeoIPLcur_command;
LeoIPLcur_command = (void*)&dummy_cmd;
/********************************/
/* read first file in user area */
/********************************/
LeoIPLrw_flags = 0;
dummy_cmd = system_read_cmd;
#ifdef _ERRCHK
dummy_cmd.header.reserve1 = backup_pointer->header.reserve1;
dummy_cmd.header.reserve3 = backup_pointer->header.reserve3;
#endif
dummy_cmd.lba = SYSTEM_LBAS;
dummy_cmd.xfer_blks = LeoIPL_sys_data.param.ipl_load_len;
dummy_cmd.buff_ptr = backup_pointer->buff_ptr = LeoIPL_sys_data.param.loadptr;
/* call read routine */
leoiplRead_zone0();
#ifdef _ERRCHK
backup_pointer->header.reserve7 = dummy_cmd.header.reserve7;
#endif
/* Restore current command */
LeoIPLcur_command = backup_pointer;
return (chk_cmd->sense = dummy_cmd.header.sense);
}