ide_test.c 11.2 KB
#define BCP_IPC
#include "pi_util.h"
#include <PR/bbsim.h>
#include <PR/bbdebug.h>

#define IDE_DEBUG_INT_IS_SET (IDE_READ(IDE_DEBUG_CMD_REG) & \
                              IDE_DEBUG_CMD_IN_INT_CHK)

#define PI_CPU_INTR_IS_SET   (CHECK_INTERRUPT&2)
#define MI_IDE_INTR_IS_SET   (IO_READ(MI_EINTR_REG)&MI_INTR_IDE)


int ideCheckIntClear()
{
    /* insure int clear on debug port */
    if(IDE_DEBUG_INT_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"Failed to clear IDE int.\n"));
        return FAIL;
    }
    
    /* insure int clear on MI */
    if(MI_IDE_INTR_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"MI IDE int should not be set.\n"));
        return FAIL;
    }

    /* insure int clear at cpu */
    if(PI_CPU_INTR_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"PI cpu int should not be set.\n"));
        return FAIL;
    }

    return PASS;
}


int ideDebugResetValueCheck()
{
    u32 val32;
    u16 val16;

    /* reset ide bus */
    val32 = IO_READ(PI_IDE_CONFIG_REG);
    IO_WRITE(PI_IDE_CONFIG_REG,val32|(PI_IDE_CONFIG_RESET));    

    /* take ide bus out of reset */
    val32 = IO_READ(PI_IDE_CONFIG_REG);
    IO_WRITE(PI_IDE_CONFIG_REG,val32&(~PI_IDE_CONFIG_RESET));
        
    /* read reset values (all zero) */
    _TRACE(DLOG, fprintf(LogFp,"Checking reset values.\n"));
    val16 = IDE_READ(IDE_DEBUG_CMD_REG);
    if(val16 != 0){
        _TRACE(DERROR, fprintf(LogFp,
                               " bad reset value of IDE_DEBUG_CMD_REG "
                               "(%04x).\n",val16));
        return FAIL;
    }
    val16 = IDE_READ(IDE_DEBUG_DATA_LO_REG);
    if(val16 != 0){
        _TRACE(DERROR, fprintf(LogFp,
                               " bad reset value of IDE_DEBUG_DATA_LO_REG "
                               "(%04x).\n",val16));
        return FAIL;
    }
    val16 = IDE_READ(IDE_DEBUG_DATA_HI_REG);
    if(val16 != 0){
        _TRACE(DERROR, fprintf(LogFp,
                               " bad reset value of IDE_DEBUG_DATA_HI_REG "
                               "(%04x).\n",val16));
        return FAIL;
    }

    return PASS;
}

/*
 * IDE, Debug Port Verification
 */
void ideDebugPort()
{
    u32 val32;
    u16 val16;
    int i;
    int result = FAIL;

    /* insure we come out of IDE reset with appropriate values */
    if(PASS!=ideDebugResetValueCheck()){
        goto print_result;
    }

    /* check int generation. cause int:
     *  - with mi mask on and off to check expected results.
     *  - repeat with MI_CTRL_REG[MI_CTRL_UNMASK_IDE] set to override.
     *
     * cause debug port int by writing IDE_DEBUG_CMD_REG with 1.
     * clear debug port int by writing 1 to cmd_t_reg[7].
     *
     * should always see debug port int by reading IDE_DEBUG_CMD_REG[0].
     * only see cpu int1 (CHECK_INTERRUPT&2) according to MI mask
     * settings.
     *
     */
    _TRACE(DLOG, fprintf(LogFp,"Checking int generation and masks.\n"));

    /* clear MI_CTRL_REG IDE mask override */
    IO_WRITE(MI_CTRL_REG,(IO_READ(MI_CTRL_REG))&(~MI_CTRL_UNMASK_IDE));
    /* check */
    if(IO_READ(MI_CTRL_REG)&MI_CTRL_UNMASK_IDE){
        _TRACE(DERROR, fprintf(LogFp,
                     " failed to clear MI_CTRL_REG[MI_CTRL_UMASK_IDE].\n"));
        goto print_result;
    }

    /* mask IDE int */
    IO_WRITE(MI_INTR_EMASK_REG,MI_INTR_MASK_SET_IDE);
    /* check */
    if(!(IO_READ(MI_INTR_EMASK_REG)&MI_INTR_MASK_IDE)){
        _TRACE(DERROR, fprintf(LogFp,
                " failed to set MI_INTR_EMASK_REG[MI_INTR_MASK_IDE].\n"));
        goto print_result;
    }
    
    /* insure int clear at all levels */
    if(ideCheckIntClear()==FAIL)
        goto print_result;
        
    /* 
     * generate int with mask set 
     */

    _TRACE(DLOG, fprintf(LogFp,"generating int with mask set\n"));
    bd_dbug_cwrite(1);

    /* insure int set on debug port */
    if(!IDE_DEBUG_INT_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"Failed to set IDE int.\n"));
        goto print_result;
    }
    
    /* insure int set on MI */
    if(!MI_IDE_INTR_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"MI IDE int should be set.\n"));
        goto print_result;
    }

    /* insure int set at cpu */
    if(!PI_CPU_INTR_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"PI cpu int should be set.\n"));
        goto print_result;
    }

    /* clear int */
    IDE_WRITE(IDE_DEBUG_CMD_REG,IDE_DEBUG_CMD_IN_INT_CLR);

    /* insure int clear at all levels */
    if(ideCheckIntClear()==FAIL)
        goto print_result;

    /*
     * generate int with MI_INTR_EMASK clear */

    /* unmask IDE int */
    IO_WRITE(MI_INTR_EMASK_REG,MI_INTR_MASK_CLR_IDE);
    /* check */
    if(IO_READ(MI_INTR_EMASK_REG)&MI_INTR_MASK_IDE){
        _TRACE(DERROR, fprintf(LogFp,
                " failed to clear MI_INTR_EMASK_REG[MI_INTR_MASK_IDE].\n"));
        goto print_result;
    }

    _TRACE(DLOG, fprintf(LogFp,"generating int with mi mask clear\n"));
    bd_dbug_cwrite(1);

    /* insure int set on debug port */
    if(!IDE_DEBUG_INT_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"Failed to set IDE int.\n"));
        goto print_result;
    }
    
    /* insure int set on MI */
    if(!MI_IDE_INTR_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"MI IDE int should be set.\n"));
        goto print_result;
    }

    /* insure int not set at cpu */
    if(PI_CPU_INTR_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"PI cpu int should not be set.\n"));
        goto print_result;
    }

    /* clear int */
    IDE_WRITE(IDE_DEBUG_CMD_REG,IDE_DEBUG_CMD_IN_INT_CLR);

    /* insure int clear at all levels */
    if(ideCheckIntClear()==FAIL)
        goto print_result;

    /*
     * with mi mask clear, override with MI_CTRL_REG[MI_CTRL_UNMASK_IDE]
     * and insure ints generated.
     */

    _TRACE(DLOG, fprintf(LogFp,"generating int with mi mask clear, but \n"
                         "       overide by setting (MI_CTRL_REG).\n"));

    /* set MI_CTRL_REG IDE mask override */
    IO_WRITE(MI_CTRL_REG,(IO_READ(MI_CTRL_REG))|(MI_CTRL_UNMASK_IDE));
    /* check */
    if(!(IO_READ(MI_CTRL_REG)&MI_CTRL_UNMASK_IDE)){
        _TRACE(DERROR, fprintf(LogFp,
                     " failed to set MI_CTRL_REG[MI_CTRL_UMASK_IDE].\n"));
        goto print_result;
    }

    bd_dbug_cwrite(1);

    /* insure int set on debug port */
    if(!IDE_DEBUG_INT_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"Failed to set IDE int.\n"));
        goto print_result;
    }
    
    /* insure int set on MI */
    if(!MI_IDE_INTR_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"MI IDE int should be set.\n"));
        goto print_result;
    }

    /* insure int set at cpu */
    if(!PI_CPU_INTR_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"PI cpu int should be set.\n"));
        goto print_result;
    }

    /* clear int */
    IDE_WRITE(IDE_DEBUG_CMD_REG,IDE_DEBUG_CMD_IN_INT_CLR);

    /* insure int clear at all levels */
    if(ideCheckIntClear()==FAIL)
        goto print_result;


    /*
     * with mi mask set, override with MI_CTRL_REG[MI_CTRL_UNMASK_IDE]
     * and insure ints generated (sanity check).
     */

    _TRACE(DLOG, fprintf(LogFp,"generating int with mi mask set, and "
                         "overide not set (MI_CTRL_REG).\n"));

    /* mask IDE int */
    IO_WRITE(MI_INTR_EMASK_REG,MI_INTR_MASK_SET_IDE);
    /* check */
    if(!(IO_READ(MI_INTR_EMASK_REG)&MI_INTR_MASK_IDE)){
        _TRACE(DERROR, fprintf(LogFp,
                " failed to set MI_INTR_EMASK_REG[MI_INTR_MASK_IDE].\n"));
        goto print_result;
    }

    bd_dbug_cwrite(1);

    /* insure int set on debug port */
    if(!IDE_DEBUG_INT_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"Failed to set IDE int.\n"));
        goto print_result;
    }
    
    /* insure int set on MI */
    if(!MI_IDE_INTR_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"MI IDE int should be set.\n"));
        goto print_result;
    }

    /* insure int set at cpu */
    if(!PI_CPU_INTR_IS_SET){
        _TRACE(DERROR, fprintf(LogFp,"PI cpu int should be set.\n"));
        goto print_result;
    }

    /* clear int */
    IDE_WRITE(IDE_DEBUG_CMD_REG,IDE_DEBUG_CMD_IN_INT_CLR);

    /* insure int clear at all levels */
    if(ideCheckIntClear()==FAIL)
        goto print_result;

    /* clear MI_CTRL_REG IDE mask override */
    IO_WRITE(MI_CTRL_REG,(IO_READ(MI_CTRL_REG))&(~MI_CTRL_UNMASK_IDE));
    /* check */
    if(IO_READ(MI_CTRL_REG)&MI_CTRL_UNMASK_IDE){
        _TRACE(DERROR, fprintf(LogFp,
                     " failed to clear MI_CTRL_REG[MI_CTRL_UMASK_IDE].\n"));
        goto print_result;
    }


    /* 
     * check reads from data register (HI and LO) 
     */
    _TRACE(DLOG, fprintf(LogFp,"Testing data reads from HI and LO.\n"));
    for(i=0;i<16;i++){
        bd_dbug_dwrite((1<<i)+(1<<(i+16)));
        val16 = IDE_READ(IDE_DEBUG_DATA_LO_REG);
        if(val16 != (1<<i)){
            _TRACE(DERROR, fprintf(LogFp,
                  "DATA_LO_REG read, expected %04x, read %04x\n",
                                   (1<<i),val16));
            goto print_result;
        }
        val16 = IDE_READ(IDE_DEBUG_DATA_HI_REG);
        if(val16 != (1<<i)){
            _TRACE(DERROR, fprintf(LogFp,
                  "DATA_HI_REG read, expected %04x, read %04x\n",
                                   (1<<i),val16));
            goto print_result;
        }
    }
    bd_dbug_dwrite(0xf0f0f0f0);
    val16 = IDE_READ(IDE_DEBUG_DATA_LO_REG);
    if(val16 != 0xf0f0){
        _TRACE(DERROR, fprintf(LogFp,
                  "DATA_LO_REG read, expected %04x, read %04x\n",
                               (0xf0f0,val16)));
        goto print_result;
    }
    val16 = IDE_READ(IDE_DEBUG_DATA_HI_REG);
    if(val16 != 0xf0f0){
        _TRACE(DERROR, fprintf(LogFp,
                  "DATA_HI_REG read, expected %04x, read %04x\n",
                               (0xf0f0,val16)));
        goto print_result;
    }


    /* 
     * check writes to data register (HI and LO) 
     */
    _TRACE(DLOG, fprintf(LogFp,"Testing data writes to HI and LO.\n"));
    for(i=0;i<16;i++){
        IDE_WRITE(IDE_DEBUG_DATA_LO_REG,(1<<i));
        IDE_WRITE(IDE_DEBUG_DATA_HI_REG,(1<<i));
        val32 = bd_dbug_dread();
        if((val32&0xffff) != (1<<i)){
            _TRACE(DERROR, fprintf(LogFp,
                              "DATA_LO_REG write, expected %04x, wrote %04x\n",
                                   (1<<i),val32&0xffff));
            goto print_result;
        }
        if(((val32>>16)&0xffff) != (1<<i)){
            _TRACE(DERROR, fprintf(LogFp,
                              "DATA_HI_REG write, expected %04x, wrote %04x\n",
                                   (1<<i),(val32>>16)&0xffff));
            goto print_result;
        }
    }
    IDE_WRITE(IDE_DEBUG_DATA_LO_REG,0xf0f0);
    IDE_WRITE(IDE_DEBUG_DATA_HI_REG,0xf0f0);
    val32 = bd_dbug_dread();
    if((val32&0xffff) != 0xf0f0){
        _TRACE(DERROR, fprintf(LogFp,
                         "DATA_LO_REG write, expected %04x, wrote %04x\n",
                               0xf0f0,val32&0xffff));
        goto print_result;
    }
    if(((val32>>16)&0xffff) != 0xf0f0){
        _TRACE(DERROR, fprintf(LogFp,
                         "DATA_HI_REG write, expected %04x, wrote %04x\n",
                               0xf0f0,(val32>>16)&0xffff));
        goto print_result;
    }

    /* re-check reset */
    if(PASS!=ideDebugResetValueCheck()){
        goto print_result;
    }

    result = PASS;

 print_result:
    printf("ideDebugPort ");
    OUTPUT_TEST_PASSFAIL(result);
    fflush(NULL);
}