iplleoutil.c 7.83 KB
/*
 *  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);
}