/* * ========== Copyright Header Begin ========================================== * * OpenSPARC T2 Processor File: bootprom_init.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 ============================================ */ #include "partial_modes.h" bootprom_init: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This section replicated from hred_reset_handler.s !! becuse we need to run the bootprom init fom chip master !! thread ONLY. ! rdhpr %hpstate, %l1 wrhpr %l1, 0x820, %hpstate wrpr 1, %tl ! set hyper trap base addr best_set_reg(HV_TRAP_BASE_PA, %g2, %l7) wrhpr %l7, %g0, %htba ! Doing this in delay slot of jump from boot prom ... !wrpr 0, %g0, %gl ! load core id to %g1 ldxa [%g0] ASI_INTR_ID, %g1 ! USING this on N2 as a shortcut #ifndef CMP_THREAD_START bootprom_init_non_cmp_check_master_tid: ! Non-cmp thread startup. #ifndef PORTABLE_CORE ! If T0 then chip-master brz %g1, bootprom_init_master ! T0 is chip master ! Else figure out if lowest running #endif wr %g0, ASI_CMP_CORE, %asi ldxa [0x50]%asi, %g2 ! Who is running ? and %g2, 1, %g3 ! T0 IS running brnz %g3, bootprom_init_notmaster neg %g2, %l1 xnor %g2, %l1, %l1 popc %l1, %l1 ! Get lowest bit set .. dec %l1 cmp %l1, %g1 be %xcc, bootprom_init_master srlx %g1, 3, %l1 ! Get core-id #else bootprom_init_cmp_check_master_tid: #ifndef SIXGUNS #ifndef PORTABLE_CORE ! CMP thread startup ! DONT USE %G1 until CMP IS Done ! Find out if current thread is chip master thread, changequote([, ])dnl ! The M4_* variables need this cmp %g1, M4_master_tid changequote(`,')dnl ! [] are not quotes anymore #else andcc %g1, 0x7, %g2 #endif #else ! Determine master thread by querying CORE_RUNNING mov 0x50, %g3 ldxa [%g3]ASI_CMP_CORE, %g2 ! Who is running ? neg %g2, %l1 xnor %g2, %l1, %l1 popc %l1, %l1 ! Get lowest bit set .. dec %l1 cmp %l1, %g1 #endif be %xcc, bootprom_init_master #endif !!!!!!!!!End of thread check for chip master !!!!!!!!!!!!!!!!!!! bootprom_init_notmaster: #ifndef CMP_THREAD_START ifelse(mpeval((HV_RED_TEXT_PA > 0xffffffff),2),1, `setx nc_check_core_master_thread, %g3, %g2', `set nc_check_core_master_thread, %g2') jmp %g2 wr %g0, ASI_CMP_CORE, %asi #else ifelse(mpeval((HV_RED_TEXT_PA > 0xffffffff),2),1, `setx check_core_master_thread, %g3, %g2', `set check_core_master_thread, %g2') jmp %g2 wr %g0, ASI_CMP_CORE, %asi #endif bootprom_init_master: !!!!!!!!!!!! Master Thread Inits Here !!!!!!!!!!!!!!!!!!!!!!!!!! #ifdef SYNC_SLAM_NO_SLAM #include "ccu_defines.h" setx RESET_STAT, %g3, %g2 ldx [%g2], %g3 !! read reset source and %g3, 2, %g3 !! nonzero if WMR brnz %g3, continue_por nop setx RESET_GEN, %g2, %g4 mov 0x1, %g3 stx %g3, [%g4] !!trigger a warm reset #endif !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !if ccu programming is required then it is done here !and then a warm reset is issued #ifdef WARM_RESET_INIT bootprom_init_check_reset_stat: #include "ccu_defines.h" setx RESET_STAT, %g3, %g2 ldx [%g2], %g3 !! read reset source and %g3, 2, %g3 !! nonzero if WMR brnz %g3, continue_por nop !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !program the ccu #ifdef CCU_REG_PROG bootprom_init_program_ccu: setx cregs_ccu_ctl_reg_r64, %g2, %g3 setx PLL_CTL, %g2, %g4 stx %g3, [%g4] !!store to pll_ctl reg to make freq change #endif !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! AT 04/12/06: Add DTM setup for PEU/PSR CSRs. #ifdef DTM_ENABLED #define PEU_MPY_FACTOR_DATA 0x0000000000000005 #define PEU_ILU_FACTOR_DATA 0x00000003ffff0004 #define PEU_PLL_CNTL_REG_ADDR 0x88006e2200 #define PEU_ILU_REG_ADDR 0x8800652000 ! program MPY field of PEU Serdes PLL Ctrl Reg to x10 setx PEU_MPY_FACTOR_DATA, %g1, %g4 setx PEU_PLL_CNTL_REG_ADDR, %g1, %g2 stx %g4, [%g2] ! Now switch the PEU rate scale from full to half rate setx PEU_ILU_FACTOR_DATA, %g1, %g4 setx PEU_ILU_REG_ADDR, %g1, %g2 stx %g4, [%g2] #if defined(NO_SLAM_INIT_MCUCTL) #ifndef MCU_CHANNEL_DATA #define MCU_CHANNEL_DATA 0x0000000000170017 #endif #define MCU_CHANNEL_MASK 0xffffffffff000000 #define MCU_CHANNEL_ADDR 0x84000008b8 #define SER_CONFIG_DATA 0x0000000010000000 #define SER_CONFIG_MASK 0xffffffffcfffffff #define SER_CONFIG_ADDR 0x84000008d0 mov 0x1, %g5 sllx %g5, 12, %g5 !! %g5 is 0x1000. MCU0/1/2/3's FBD_CHANNEL_STATE_REG is 0x1000 apart ! Now set the channel latency in the MCU to 0x14 setx MCU_CHANNEL_ADDR, %g1, %g2 setx MCU_CHANNEL_MASK, %g1, %g4 #ifdef BANK01 ldx [%g2], %g1 and %g1, %g4, %g3 setx MCU_CHANNEL_DATA, %g1, %g4 !MCU_CHANNEL_DATA or %g3, %g4, %g4 stx %g4, [%g2] #endif add %g2, %g5, %g2 !%g2 has MCU1 address #ifndef BANK01 #ifdef BANK23 ldx [%g2], %g1 and %g1, %g4, %g3 setx MCU_CHANNEL_DATA, %g1, %g4 !MCU_CHANNEL_DATA or %g3, %g4, %g4 #endif #endif #ifdef BANK23 stx %g4, [%g2] #endif add %g2, %g5, %g2 !%g2 has MCU2 address #ifndef BANK01 #ifndef BANK23 #ifdef BANK45 ldx [%g2], %g1 and %g1, %g4, %g3 setx MCU_CHANNEL_DATA, %g1, %g4 !MCU_CHANNEL_DATA or %g3, %g4, %g4 #endif #endif #endif #ifdef BANK45 stx %g4, [%g2] #endif add %g2, %g5, %g2 !%g2 has MCU3 address #ifndef BANK01 #ifndef BANK23 #ifndef BANK45 #ifdef BANK67 ldx [%g2], %g1 and %g1, %g4, %g3 setx MCU_CHANNEL_DATA, %g1, %g4 !MCU_CHANNEL_DATA or %g3, %g4, %g4 #endif #endif #endif #endif #ifdef BANK67 stx %g4, [%g2] #endif ! Now set the MCU serdes Configuration Register to half rate. setx SER_CONFIG_ADDR, %g1, %g2 setx SER_CONFIG_MASK, %g1, %g4 #ifdef BANK01 ldx [%g2], %g1 and %g1, %g4, %g3 setx SER_CONFIG_DATA, %g1, %g4 or %g3, %g4, %g4 stx %g4, [%g2] #endif add %g2, %g5, %g2 #ifndef BANK01 #ifdef BANK23 ldx [%g2], %g1 and %g1, %g4, %g3 setx SER_CONFIG_DATA, %g1, %g4 or %g3, %g4, %g4 #endif #endif #ifdef BANK23 stx %g4, [%g2] #endif add %g2, %g5, %g2 #ifndef BANK01 #ifndef BANK23 #ifdef BANK45 ldx [%g2], %g1 and %g1, %g4, %g3 setx SER_CONFIG_DATA, %g1, %g4 or %g3, %g4, %g4 #endif #endif #endif #ifdef BANK45 stx %g4, [%g2] #endif add %g2, %g5, %g2 #ifndef BANK01 #ifndef BANK23 #ifndef BANK45 #ifdef BANK67 ldx [%g2], %g1 and %g1, %g4, %g3 setx SER_CONFIG_DATA, %g1, %g4 or %g3, %g4, %g4 #endif #endif #endif #endif #ifdef BANK67 stx %g4, [%g2] #endif #include "boot_mcuctl_init_b4wmr.s" #endif ! end of ifdef NO_SLAM_INIT_MCUCTL #endif ! end of ifdef DTM_ENABLED ! END AT 04/12/06 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #ifdef MBIST_REG_PROG bootprom_init_program_mbist: #include "mbist_defines.h" setx MBIST_MODE, %g2, %g4 mov MBIST_MODE_REG, %g3 stx %g3, [%g4] !!store to mbist_mode to configure mbist operation setx MBIST_BYPASS_REG, %g2, %g3 setx MBIST_BYPASS, %g2, %g4 stx %g3, [%g4] !!Program mbist_bypass to select engines setx MBIST_START_WMR, %g2, %g4 mov 0x1, %g3 stx %g3, [%g4] !!Enable MBIST operation during warm reset #endif !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #ifdef L2_CORE_ENABLE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !program core enable register bootprom_init_program_core_enable: ldxa [%g0]0x41, %g3 stxa %g3, [%g0+0x20] !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !program bank enable register bootprom_init_program_l2_bank_enable: setx 0x8400001018, %g2, %g3 ldxa [%g3], %g4 add %g3, 0x8, %g3 stxa %g4, [%g3] #endif #ifdef L2_IDX_HASH_EN bootprom_init_program_l2_hash_enable: #include "ncu_defines.h" setx L2_IDX_HASH_EN_ADDR, %g2, %g3 mov 0x1, %g4 stx %g4, [%g3] #endif !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!Progam the SSI clock ratio io2clk/4 !!system defaults to io2clk/8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #ifdef SSI_CLK_4 bootprom_init_program_ssi_clk_4: #include "ncu_defines.h" setx NCU_SCKSEL, %l2, %l1 mov 0x1, %l2 stx %l2, [%l1] #endif #ifdef SSI_CLK_8_2 bootprom_init_program_ssi_clk_8_2: #include "ncu_defines.h" setx NCU_SCKSEL, %l2, %l1 mov 0x2, %l2 stx %l2, [%l1] #endif #ifdef SSI_CLK_8_3 bootprom_init_program_ssi_clk_8_3: #include "ncu_defines.h" setx NCU_SCKSEL, %l2, %l1 mov 0x3, %l2 stx %l2, [%l1] #endif !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !Down the FBD links b4 a warm reset is given setx 0x8400000800, %g3, %g4 !! MCU0's FBD_CHANNEL_STATE_REG mov 0x1, %g5 sllx %g5, 12, %g5 !! %g5 is 0x1000. MCU0/1/2/3's FBD_CHANNEL_STATE_REG is 0x1000 apart stx %g0, [%g4] add %g4, %g5, %g4 stx %g0, [%g4] add %g4, %g5, %g4 stx %g0, [%g4] add %g4, %g5, %g4 stx %g0, [%g4] ! AT 04/12/06: For DTM vector generation, JTAG asserts PB_RST to trigger ! WMR1 and WMR2. Hence, not trigger WMR here in boot code. ! In normal DTM runs, still want to issue the WMR. #ifndef DTM_JTAG_POR !Generate the warm reset setx RESET_GEN, %g2, %g4 mov 0x1, %g3 stx %g3, [%g4] !!trigger a warm reset #endif /* DTM_JTAG_POR */ #endif continue_por: #ifndef DTM_ENABLED /* Does not work for partial mode in DTM so removed for DTM */ setx 0x8400000280, %g2, %g3 ldx [%g3], %g4 stx %g4, [%g3] #endif !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !WRITE to ASI_VEC_MASK This will cause all threads started !from now on to vector to 0000020 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #ifdef BOOT_SLAVE_THREADS_FROM_MEMORY programm_asi_vec_mask: mov 1, %l0 mov 0x18, %l1 stxa %l0, [%l1]0x45 !set the vec mask to 1 this should cause !fetches to 0x0000 for other threads #endif #ifdef DTM_ENABLED #ifdef TOGGLE_ENFTP !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !Set and release the ENFTP signal !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #define SERDES_CONFIG_ENFTP_MASK 0x80000 setx SER_CONFIG_ADDR, %g3, %g2 ldx [%g2], %g4 setx SERDES_CONFIG_ENFTP_MASK, %g5, %g6 mov 0x1, %g5 sllx %g5, 12, %g5 !! %g5 is 0x1000. MCU0/1/2/3's FBD_CHANNEL_STATE_REG is 0x1000 apart xor %g6, %g4, %g4 stx %g4, [%g2] add %g2, %g5, %g2 stx %g4, [%g2] add %g2, %g5, %g2 stx %g4, [%g2] add %g2, %g5, %g2 stx %g4, [%g2] setx SER_CONFIG_ADDR, %g3, %g2 ldx [%g2], %g4 setx SERDES_CONFIG_ENFTP_MASK, %g5, %g6 mov 0x1, %g5 sllx %g5, 12, %g5 !! %g5 is 0x1000. MCU0/1/2/3's FBD_CHANNEL_STATE_REG is 0x1000 apart xor %g6, %g4, %g4 stx %g4, [%g2] add %g2, %g5, %g2 stx %g4, [%g2] add %g2, %g5, %g2 stx %g4, [%g2] add %g2, %g5, %g2 stx %g4, [%g2] #endif /* TOGGLE_ENFTP */ #endif /* DTM_ENABLED */ !! AT 04/12/06: Add DTM setup to bypass IOMMU, also disable scrambling. ! Note these are not wmr_protected, need to do this after WMR2. ! Then trigger user event to train PCI-E link. #ifdef DTM_ENABLED #ifdef SSI_VEC_DIAG_POST_WRM_PEU programm_peu_reg_dtm: #define PEU_IOMMU_CNTL_REG_ADDR 0x8800640000 #define PEU_IOMMU_DATA 0x0000000000000002 #define PEU_SYMBOL_TIMER_REG_ADDR 0x88006e2078 #define PEU_SYMBOL_TIMER_DATA 0x20 #define PEU_MAC_CTRL_REG_ADDR 0x88006e2060 #define PEU_MAC_CTRL_REG_SCRAMBLE_MASK 0xfffffffffffffffd #define PEU_MAC_CTRL_REG_SCRAMBLE_DATA 0x0000000000000002 setx PEU_IOMMU_DATA, %g1, %g4 setx PEU_IOMMU_CNTL_REG_ADDR, %g1, %g2 stx %g4, [%g2] nop ! Disable scrambling so that peu_mio_debug_txdata is meaningful. programm_peu_scrambling_reg_dtm: setx PEU_MAC_CTRL_REG_ADDR, %g1, %g2 setx PEU_MAC_CTRL_REG_SCRAMBLE_MASK, %g1, %g4 ldx [%g2], %g1 and %g1, %g4, %g3 setx PEU_MAC_CTRL_REG_SCRAMBLE_DATA, %g1, %g4 or %g3, %g4, %g4 stx %g4, [%g2] ! Now we need to create a user event for the tester to send ! sufficent FTS order sets ! Also need the tester to send one SKP order set ! Following user event does both #ifdef DTM_PCI_USER_EVENT !!!! StartDtm: !!!!! x$EV trig_pc_d(1,expr(@VA(.RED_SEC.StartDtm)&0x0000ffffffffffff,16,16)) -> EnablePCIeIgCmd("STARTDTM", 0, 0, 0, 1) ! the above User Event does 25 FTSs and 1 SKP #endif #include "peu_init_dtm.h" #endif ! end of ifdef SSI_VEC_DIAG_POST_WRM #endif ! end of ifdef DTM_ENABLED !!!! MCU Inits !!!!!!!#if defined(NO_SLAM_INIT_MCUCTL) #include "hboot_mcuctl_init.s" !!!!!!!#endif !!!! Partial Bank Enable #ifdef BANK_SET_MASK_CSR ! Check bank enable status setx 0x8000001028, %g3, %g2 ldx [%g2 + 0], %l1 sllx %l1, 0x4, %l1 and %l1, 1, %l1 brnz %l1, partial ! Set partial bank mode sub %g2, 8, %g2 mov BANK_SET_MASK_CSR, %l1 stx %l1, [%g2 + 0] stx %l1, [%g2 + 0x40] stx %l1, [%g2 + 0x80] stx %l1, [%g2 + 0xc0] stx %l1, [%g2 + 0x100] stx %l1, [%g2 + 0x140] stx %l1, [%g2 + 0x180] stx %l1, [%g2 + 0x1c0] ! Warm reset setx 0x8900000808, %g3, %g4 mov 0x1, %g5 stx %g5, [%g4] partial: #endif #ifdef SSI_VEC_DIAG_POST_WRM #include SSI_VEC_DIAG_POST_WRM #endif !!!!!!!!!!!! Master Thread Inits END !!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!! END OF BOOTPROM INIT !!!!!!!!!!!!!!!!!!!!!!!!!! #ifndef CMP_THREAD_START ifelse(mpeval((HV_RED_TEXT_PA > 0xffffffff),2),1, `setx nc_chip_master_thread, %g3, %g2', `set nc_chip_master_thread, %g2') jmp %g2 wr %g0, ASI_CMP_CORE, %asi #else ifelse(mpeval((HV_RED_TEXT_PA > 0xffffffff),2),1, `setx chip_master_thread, %g3, %g2', `set chip_master_thread, %g2') jmp %g2 wr %g0, ASI_CMP_CORE, %asi #endif ! No Code beyond this point