* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: isa3_asi_cmp_core_2.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 MAIN_PAGE_NUCLEUS_ALSO
#define MAIN_PAGE_HV_ALSO
! can set this to 1 to stop test after thread 0 & 1 have
! parked/unparked all threads.
! a threads unique addr for incrementing a counter.
! addr that stores which thread is the master thread.
#define MASK_OUT_SELF %l4
! holds user_data_start addr
! what threads are expected to be active
#define EXPECT_ACTIVE %o4
#define ALL1S 0xffffffffffffffff
/************************************************************************
************************************************************************/
ta T_CHANGE_HPRIV ! run in Hpriv mode
rdth_id ! get thread ID in %o1
! 9 64 bit memory locations. last is shared, init all to 0.
! offset 0 = thread 0 counter area
! offset 8 = common area that stores which thread is the master thread.
!umul MY_ID, 8, MY_ADDR ! per thread offset
sllx MY_ID, 6, MY_ADDR ! per thread offset, ID selects bank
setx user_data_start, %g1, USER_DATA ! data area base
add MY_ADDR, USER_DATA , MY_ADDR ! per thread address ('my' address)
add %g2, 0x40, COMN_ADDR ! common address
add COMN_ADDR, 0x8, COMN_ADDR2 ! common address 2
! what threads are expected to be active
ldxa [%g0 + ASI_CMP_CORE_ENABLED] %asi, EXPECT_ACTIVE
! what thread will be the last thread
mov 0, LAST_THREAD ! init
mov EXPECT_ACTIVE, %g1 ! thread enabled mask
mov LAST_THREAD, THREAD_COUNT
ba thread_x ! all threads do the same
wr %g0, ASI_CMP_CORE, %asi
! signal that thread has gotten here (started).
stb %g2, [COMN_ADDR2 + MY_ID]
! am I the master thread?
! master waits for other threads to have started.
! yes, skip first loop and control the parking instead
! If we were just master, goto pass_control
ba pass_control !call will ret here
! not master, then loop doing visible busy work,
! waiting to become master on return
! now we are master. next, pass control
! pass control to next thread
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! make sure all other threads are spinning counters.
! park all other threads.
! make sure all other threads are NOT spinning counters.
! UN park all other threads.
! make sure all other threads are spinning counters.
! save return address, nested calls
! make a mask, the only 0 is for self
sllx MASK_OUT_SELF, MY_ID, MASK_OUT_SELF
xor MASK_OUT_SELF, %g1, MASK_OUT_SELF ! the only 0 is for me
! make sure all other threads are spinning counters
call run_check ! changes %o7
! park all other threads except self
stxa MASK_OUT_SELF, [%g0 + ASI_CMP_CORE_RUNNING_W1C] %asi
ldxa [%g0 + ASI_CMP_CORE_RUNNING_RW] %asi, %l0
! make sure all other threads are NOT spinning counters
call park_check ! changes %o7
! UN park all other threads
stxa MASK_OUT_SELF, [%g0 + ASI_CMP_CORE_RUNNING_W1S] %asi
ldxa [%g0 + ASI_CMP_CORE_RUNNING_RW] %asi, %l0
! make sure all other threads are spinning counters
call run_check ! changes %o7
! restore original return address
! confirm all threads are running/counting. (except for myself)
! save return address, nested calls
!umul %g4, 0x8, %g5 ! g4=tid, offset
sllx %g4, 6, %g5 ! move tid up to bank select position
ldx [USER_DATA + %g5], %g6
ldx [USER_DATA + %g5], %g7
! check ASI_CORE_RUNNING_STATUS, all active
ldxa [%g0 + ASI_CMP_CORE_RUNNING_STATUS] %asi, %g6
cmp %g6, EXPECT_ACTIVE ! what threads are expected to be active
! restore original return address
! confirm, all threads are parked, except self.
! loop for each thread and insure counter does not inc
! save return address, nested calls
!umul %g4, 0x8, %g5 ! g4=tid, offset
sllx %g4, 6, %g5 ! move tid up to bank select position
ldx [USER_DATA + %g5], %g6
ldx [USER_DATA + %g5], %g7
! check ASI_CORE_RUNNING_STATUS, all active
ldxa [%g0 + ASI_CMP_CORE_RUNNING_STATUS] %asi, %g6
xor MASK_OUT_SELF, ALL1S, %g7 ! only self is set
! restore original return address
! spin incrementing a mem location.
! look at the master address to see when I become master.
cmp %g2, MY_ID ! thread id
! spin incrementing a mem location.
! look at the master address to see when I need to exit
cmp %g2, THREAD_COUNT ! final thread is done
! kill time, do a few divides
ldd [COMN_ADDR + 0x10], %f0
ldd [COMN_ADDR + 0x18], %f2
/************************************************************************
************************************************************************/
.xword 0x5555555555555555
.xword 0xaaaaaaaaaaaaaaaa
.xword 0x5555555555555555
.xword 0xaaaaaaaaaaaaaaaa
.xword 0x5555555555555555
.xword 0xaaaaaaaaaaaaaaaa
.xword 0x5555555555555555
.xword 0xaaaaaaaaaaaaaaaa
.xword 0x5555555555555555
.xword 0xaaaaaaaaaaaaaaaa
.xword 0x5555555555555555
.xword 0xaaaaaaaaaaaaaaaa
.xword 0x5555555555555555
.xword 0xaaaaaaaaaaaaaaaa
.xword 0x5555555555555555
.xword 0xaaaaaaaaaaaaaaaa