Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / diag / assembly / peu / PCIeEgrHPeDrainState.s
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: PCIeEgrHPeDrainState.s
* Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
* 4150 Network Circle, Santa Clara, California 95054, U.S.A.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For the avoidance of doubt, and except that if any non-GPL license
* choice is available it will apply instead, Sun elects to use only
* the General Public License version 2 (GPLv2) at this time for any
* software where a choice of GPL license versions is made
* available with the language indicating that GPLv2 or any later version
* may be used, or where a choice of which version of the GPL is applied is
* otherwise unspecified.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*
* ========== Copyright Header End ============================================
*/
#define ENABLE_PCIE_LINK_TRAINING
#define MAIN_PAGE_HV_ALSO
#ifndef PCIE_USE_SSYS_RESET
#define RESET_STAT_CHECK
#define RESET_CHECK_REG
#define H_HT0_Hw_Corrected_Error_0x63 hw_corrected_error_handler
#endif
#define H_HT0_Data_access_error_0x32
#define SUN_H_HT0_Data_access_error_0x32 \
inc %l4; \
done;
#include "hboot.s"
#include "peu_defines.h"
#include "dmu_peu_regs.h"
#include "rst_defines.h"
#define MEM_WR_ADDR mpeval(N2_PCIE_BASE_ADDR + MEM32_OFFSET_BASE_REG_DATA)
#define DMA_DATA_ADDR 0x0000000123456000
#define DMARD_ADDR1 0xfffc000123456000
#define DMARD_ADDR2 0xfffc000123457000
#define DMARD_ADDR3 0xfffc000123458000
#define DMARD_ADDR4 0xfffc000123459000
/*
Test case code start
*/
.text
.global main
main:
ta T_CHANGE_HPRIV
nop
/************************************************************
Check if this is the first time thru here
************************************************************/
setx test_entered, %g1, %g2
ldx [%g2], %g3
brnz %g3, After_Warm_Reset
nop
! First time thru, Store a non-zero value there
dec %g3
stx %g3, [%g2]
/************************************************************
make sure the detect.quiet bit is set
************************************************************/
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_ADDR, %g1, %g3
ldx [%g3], %g4
mov 0x100, %g5
orcc %g5, %g4, %g5 ! OR in bit 8 == 1
stx %g5, [%g3]
ldx [%g3], %g4
/************************************************************
Fire off some PIOs and DMA Reads, then bring down the link.
************************************************************/
Start_PIOs_and_DMARDs:
setx MEM_WR_ADDR, %g1, %g2
setx 0x3335373992828384, %g1, %l0
stb %l0, [%g2]
sth %l0, [%g2 + 4]
stw %l0, [%g2 + 8]
ldx [%g2], %l1
! here is where we bring down the link, to force an error
Bring_down_the_link:
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1C_ALIAS_ADDR, %g1, %g3
ldx [%g3], %l3
stx %l3, [%g3] ! clear any OE status bits
! setx FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DIAG_ADDR, %g1, %g4
! best_set_reg( 0xa5a50080, %g1, %l4 )
! stx %l4, [%g4] ! set the EHP error injection triggers
/***************************************************************
Write the EHI_PAR and EHI_TRG fields of the ILU DIAGNOSTIC CSR
***************************************************************/
setx FIRE_DLC_ILU_CIB_CSR_A_ILU_DIAGNOS_ADDR, %g1, %g4
ldx [%g4], %l3
best_set_reg(0x00000110, %g1, %l4) ! set bits 8 & 4 (EHI_PAR & EHI_TRG)
or %l3, %l4, %l3
stx %l3, [%g4] ! set the EDP error injection triggers
stx %l0, [%g2 + 16] ! PIO write ===> should get the EHP error
! now wait for the "Egress Parity Error (EHP)" primary or secondary status to be set
mov 10, %l0
setx 0x0000100000001000, %g1, %l1 ! mask for EHP Primary and Secondary Events
Wait_for_EHP:
ldx [%g3], %l3
andcc %l1, %l3, %l4
bne %xcc, Check_drain_state
nop
dec %l0
brnz %l0, Wait_for_EHP
nop
b test_failed
nop
/************************************************************
check that drain.state bit is set in the PEU Status Register
************************************************************/
Check_drain_state:
! This user event will force the next PIO to NOT to call expectPCIE().
! $EV trig_pc_d(1,@VA(.MAIN.Check_drain_state)) -> EnablePCIeIgCmd("PIO_NOEXP",0,0,0,1)
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_STS_ADDR, %g1, %g4
ldx [%g4], %l4
mov 0x100, %g5
andcc %l4, %g5, %l0
bz test_failed ! branch if drain state is not set
nop
! issue PIO read request(s) - these should complete with Bus Error
mov 0, %l4
setx MEM_WR_ADDR, %g1, %g5
PioBusErr:
ldx [%g5], %l3 ! ==> this should get a bus error
dec %l4 ! <== only one interrupt expected
brnz %l4, test_failed
nop
! insure that no outstanding DMA read requests are outstanding
! by checking that there are no entries on the Transaction Scoreboard
setx FIRE_DLC_TSB_CSR_A_TSB_STS_ADDR, %g1, %g5
mov 0, %l0
dec %l0
mov 0x01, %l1
xor %l1, %l0, %l1
Wait_for_dma_read_clear:
ldx [%g5], %l4
andcc %l4, %l1, %l2
bnz Wait_for_dma_read_clear
nop
! clear the EHP status bit
ldx [%g3], %l1
stx %l1, [%g3] ! RW1C
ldx [%g3], %l1
brnz %l1, test_failed ! branch if link down is not cleared
nop
! clear the drain bit - its also a RW1C bit
mov 0x100, %g5
stx %g5, [%g4] ! RW1C
ldx [%g4], %l4
andcc %l4, %g5, %l4
bnz test_failed ! branch if drain state is not cleared
nop
/************************************************************
do the warm reset
************************************************************/
do_WARM_RESET:
! xxx trig_pc_d(1,@VA(.MAIN.do_WARM_RESET)) -> EnablePCIeIgCmd("SOFTRESET",0,0,0,1)
#ifdef PCIE_USE_SSYS_RESET
setx RST_SSYS_RESET, %g1, %g5 ! subsystem reset reg
mov RST_SSYS_RESET__DMU_PEU, %g7 ! subsystem reset reg data
stx %g7, [%g5] ! Subsystem Reset
mov 10, %l0 ! loop timeout count
Wait4SsysReset:
ldx [%g5], %l7 ! check if reset bit has cleared
brz %l7, redo_link_training
nop
dec %l0
brnz %l0, Wait4SsysReset
nop
ba test_failed ! Subsystem reset should have completed
nop
/************************************************************
Now redo link training...
************************************************************/
redo_link_training:
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_LINK_CTL_ADDR, %g2, %g3
ldx [%g3], %g4
mov 0x0010, %g5 ! FAST LINK MODE, for simulation.
or %g4, %g5, %g5
stx %g5, [%g3]
! clear bit 8, to not remain in Detect.Quiet state
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_ADDR, %g1, %g3
mov 0x001, %l4
stx %l4, [%g3]
! enable bypass in IOMMU
setx FIRE_DLC_MMU_CSR_A_CTL_ADDR, %g1, %g2
setx FIRE_DLC_MMU_CSR_A_CTL__BYPASS_EN, %g1, %g3
stx %g3, [%g2]
! wait for the "Link Up" status bit to get set in the PEU
! (this code copied from peu_init.h)
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1C_ALIAS_ADDR, %g1, %g3
ldx [%g3], %l4
stx %l4, [%g3] ! clear any status bits that are set
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_ADDR, %g1, %g4
mov 255, %l0
mov FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_EN_ERR__LUP_P, %l1
LinkTrainingLoop2:
ldx [%g3], %l4 ! bit 8 is Link Up primary event
ldx [%g4], %l5 ! bits 48:44 are the LTSSM state
andcc %l1, %l4, %l4
bne After_Warm_Reset
nop
dec %l0
brnz %l0, LinkTrainingLoop2
nop
b test_failed
nop
#else
setx RST_RESET_GEN, %g1, %g5 ! warm reset reg
mov RST_RESET_GEN__WMR_GEN, %g7 ! warm reset reg data
mov 255, %l0 ! loop timeout count
stx %g7, [%g5] ! Warm Reset
ldx [%g5], %g7
Wait4WarmReset:
dec %l0
brnz %l0, Wait4WarmReset
nop
ba test_failed ! Warm reset should have happened
nop
#endif
/********************************************************************
Do a couple of PIOs and DMAs to verify that the PCIe link is working.
********************************************************************/
After_Warm_Reset:
nop
! clear any error bits from from the DLPL Status reg
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_ADDR, %g1, %g6
ldx [%g6], %l7
stx %l7, [%g6] ! RW1C
ldx [%g6], %l7
brnz %l7, test_failed ! branch if it is not cleared
nop
DmaRd5: nop
! $EV trig_pc_d(1, @VA(.MAIN.DmaRd5)) -> EnablePCIeIgCmd("DMARD",DMARD_ADDR2,DMARD_ADDR2,"64'h40",1)
setx MEM_WR_ADDR, %g1, %g5
mov 0, %l4
stx %g3, [%g5] ! 3 PIO Writes
stx %g4, [%g5+8]
stx %g5, [%g5+16]
DmaRd6: nop
! $EV trig_pc_d(1, @VA(.MAIN.DmaRd6)) -> EnablePCIeIgCmd("DMARD",DMARD_ADDR3,DMARD_ADDR3,"64'h40",1)
ldx [%g5], %l0 ! 3 PIO Reads
ldx [%g5+8], %l1
ldx [%g5+16], %l2
DmaRd7: nop
! $EV trig_pc_d(1, @VA(.MAIN.DmaRd7)) -> EnablePCIeIgCmd("DMARD",DMARD_ADDR4,DMARD_ADDR4,"64'h40",1)
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1C_ALIAS_ADDR, %g1, %g3
ldx [%g3], %l5 ! bit 8 is Link Up primary event
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_ADDR, %g1, %g4
ldx [%g4], %l6 ! bits 48:44 are the LTSSM state
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_ADDR, %g1, %g6
ldx [%g6], %l7 ! dlpl status
brnz %l4, test_failed ! no interrupts were expected
nop
nop
test_passed:
EXIT_GOOD
test_failed:
EXIT_BAD
/************************************************************************
Test case data start
************************************************************************/
.align 64
test_entered:
.xword 0
SECTION .DATA DATA_VA=DMA_DATA_ADDR
attr_data {
Name = .DATA,
hypervisor,
compressimage
}
.data
init_mem(0x0101010201030104, 256, 8, +, 0, +, 0x0004000400040004)
/************************************************************************/