* ========== 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
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* ========== Copyright Header End ============================================
#define ENABLE_PCIE_LINK_TRAINING
#define MAIN_PAGE_HV_ALSO
#ifndef PCIE_USE_SSYS_RESET
#define H_HT0_Hw_Corrected_Error_0x63 hw_corrected_error_handler
#define H_HT0_Data_access_error_0x32
#define SUN_H_HT0_Data_access_error_0x32 \
#include "dmu_peu_regs.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
/************************************************************
Check if this is the first time thru here
************************************************************/
setx test_entered, %g1, %g2
brnz %g3, After_Warm_Reset
! First time thru, Store a non-zero value there
/************************************************************
make sure the detect.quiet bit is set
************************************************************/
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_ADDR, %g1, %g3
orcc %g5, %g4, %g5 ! OR in bit 8 == 1
/************************************************************
Fire off some PIOs and DMA Reads, then bring down the link.
************************************************************/
setx MEM_WR_ADDR, %g1, %g2
setx 0x3335373992828384, %g1, %l0
! here is where we bring down the link, to force an error
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1C_ALIAS_ADDR, %g1, %g3
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
best_set_reg(0x00000110, %g1, %l4) ! set bits 8 & 4 (EHI_PAR & EHI_TRG)
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
setx 0x0000100000001000, %g1, %l1 ! mask for EHP Primary and Secondary Events
bne %xcc, Check_drain_state
/************************************************************
check that drain.state bit is set in the PEU Status Register
************************************************************/
! 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
bz test_failed ! branch if drain state is not set
! issue PIO read request(s) - these should complete with Bus Error
setx MEM_WR_ADDR, %g1, %g5
ldx [%g5], %l3 ! ==> this should get a bus error
dec %l4 ! <== only one interrupt expected
! 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
bnz Wait_for_dma_read_clear
! clear the EHP status bit
brnz %l1, test_failed ! branch if link down is not cleared
! clear the drain bit - its also a RW1C bit
bnz test_failed ! branch if drain state is not cleared
/************************************************************
************************************************************/
! 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
ldx [%g5], %l7 ! check if reset bit has cleared
brz %l7, redo_link_training
ba test_failed ! Subsystem reset should have completed
/************************************************************
Now redo link training...
************************************************************/
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_LINK_CTL_ADDR, %g2, %g3
mov 0x0010, %g5 ! FAST LINK MODE, for simulation.
! clear bit 8, to not remain in Detect.Quiet state
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_ADDR, %g1, %g3
setx FIRE_DLC_MMU_CSR_A_CTL_ADDR, %g1, %g2
setx FIRE_DLC_MMU_CSR_A_CTL__BYPASS_EN, %g1, %g3
! 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
stx %l4, [%g3] ! clear any status bits that are set
setx FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_ADDR, %g1, %g4
mov FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_EN_ERR__LUP_P, %l1
ldx [%g3], %l4 ! bit 8 is Link Up primary event
ldx [%g4], %l5 ! bits 48:44 are the LTSSM state
brnz %l0, LinkTrainingLoop2
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
ba test_failed ! Warm reset should have happened
/********************************************************************
Do a couple of PIOs and DMAs to verify that the PCIe link is working.
********************************************************************/
! 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
brnz %l7, test_failed ! branch if it is not cleared
! $EV trig_pc_d(1, @VA(.MAIN.DmaRd5)) -> EnablePCIeIgCmd("DMARD",DMARD_ADDR2,DMARD_ADDR2,"64'h40",1)
setx MEM_WR_ADDR, %g1, %g5
stx %g3, [%g5] ! 3 PIO Writes
! $EV trig_pc_d(1, @VA(.MAIN.DmaRd6)) -> EnablePCIeIgCmd("DMARD",DMARD_ADDR3,DMARD_ADDR3,"64'h40",1)
ldx [%g5], %l0 ! 3 PIO Reads
! $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
/************************************************************************
************************************************************************/
SECTION .DATA DATA_VA=DMA_DATA_ADDR
init_mem(0x0101010201030104, 256, 8, +, 0, +, 0x0004000400040004)
/************************************************************************/