1/* 2 * tbicore.S 3 * 4 * Copyright (C) 2001, 2002, 2007, 2012 Imagination Technologies. 5 * 6 * This program is free software; you can redistribute it and/or modify it under 7 * the terms of the GNU General Public License version 2 as published by the 8 * Free Software Foundation. 9 * 10 * Core functions needed to support use of the thread binary interface for META 11 * processors 12 */ 13 14 .file "tbicore.S" 15/* Get data structures and defines from the TBI C header */ 16#include <asm/metag_mem.h> 17#include <asm/metag_regs.h> 18#include <asm/tbx.h> 19 20 .data 21 .balign 8 22 .global ___pTBISegs 23 .type ___pTBISegs,object 24___pTBISegs: 25 .quad 0 /* Segment list pointer with it's */ 26 .size ___pTBISegs,.-___pTBISegs 27 /* own id or spin-lock location */ 28/* 29 * Return ___pTBISegs value specific to privilege level - not very complicated 30 * at the moment 31 * 32 * Register Usage: D0Re0 is the result, D1Re0 is used as a scratch 33 */ 34 .text 35 .balign 4 36 .global ___TBISegList 37 .type ___TBISegList,function 38___TBISegList: 39 MOVT A1LbP,#HI(___pTBISegs) 40 ADD A1LbP,A1LbP,#LO(___pTBISegs) 41 GETL D0Re0,D1Re0,[A1LbP] 42 MOV PC,D1RtP 43 .size ___TBISegList,.-___TBISegList 44 45/* 46 * Search the segment list for a match given Id, pStart can be NULL 47 * 48 * Register Usage: D1Ar1 is pSeg, D0Ar2 is Id, D0Re0 is the result 49 * D0Ar4, D1Ar3 are used as a scratch 50 * NB: The PSTAT bit if Id in D0Ar2 may be toggled 51 */ 52 .text 53 .balign 4 54 .global ___TBIFindSeg 55 .type ___TBIFindSeg,function 56___TBIFindSeg: 57 MOVT A1LbP,#HI(___pTBISegs) 58 ADD A1LbP,A1LbP,#LO(___pTBISegs) 59 GETL D1Ar3,D0Ar4,[A1LbP] /* Read segment list head */ 60 MOV D0Re0,TXSTATUS /* What priv level are we at? */ 61 CMP D1Ar1,#0 /* Is pStart provided? */ 62/* Disable privilege adaption for now */ 63 ANDT D0Re0,D0Re0,#0 /*HI(TXSTATUS_PSTAT_BIT) ; Is PSTAT set? Zero if not */ 64 LSL D0Re0,D0Re0,#(TBID_PSTAT_S-TXSTATUS_PSTAT_S) 65 XOR D0Ar2,D0Ar2,D0Re0 /* Toggle Id PSTAT if privileged */ 66 MOVNZ D1Ar3,D1Ar1 /* Use pStart if provided */ 67$LFindSegLoop: 68 ADDS D0Re0,D1Ar3,#0 /* End of list? Load result into D0Re0 */ 69 MOVZ PC,D1RtP /* If result is NULL we leave */ 70 GETL D1Ar3,D0Ar4,[D1Ar3] /* Read pLink and Id */ 71 CMP D0Ar4,D0Ar2 /* Does it match? */ 72 BNZ $LFindSegLoop /* Loop if there is no match */ 73 TST D0Re0,D0Re0 /* Clear zero flag - we found it! */ 74 MOV PC,D1RtP /* Return */ 75 .size ___TBIFindSeg,.-___TBIFindSeg 76 77/* Useful offsets to encode the lower bits of the lock/unlock addresses */ 78#define UON (LINSYSEVENT_WR_ATOMIC_LOCK & 0xFFF8) 79#define UOFF (LINSYSEVENT_WR_ATOMIC_UNLOCK & 0xFFF8) 80 81/* 82 * Perform a whole spin-lock sequence as used by the TBISignal routine 83 * 84 * Register Usage: D1Ar1 is pLock, D0Ar2 is Mask, D0Re0 is the result 85 * (All other usage due to ___TBIPoll - D0Ar6, D1Re0) 86 */ 87 .text 88 .balign 4 89 .global ___TBISpin 90 .type ___TBISpin,function 91___TBISpin: 92 SETL [A0StP++],D0FrT,D1RtP /* Save our return address */ 93 ORS D0Re0,D0Re0,#1 /* Clear zero flag */ 94 MOV D1RtP,PC /* Setup return address to form loop */ 95$LSpinLoop: 96 BNZ ___TBIPoll /* Keep repeating if fail to set */ 97 GETL D0FrT,D1RtP,[--A0StP] /* Restore return address */ 98 MOV PC,D1RtP /* Return */ 99 .size ___TBISpin,.-___TBISpin 100 101/* 102 * Perform an attempt to gain access to a spin-lock and set some bits 103 * 104 * Register Usage: D1Ar1 is pLock, D0Ar2 is Mask, D0Re0 is the result 105 * !!On return Zero flag is SET if we are sucessfull!! 106 * A0.3 is used to hold base address of system event region 107 * D1Re0 use to hold TXMASKI while interrupts are off 108 */ 109 .text 110 .balign 4 111 .global ___TBIPoll 112 .type ___TBIPoll,function 113___TBIPoll: 114 MOV D1Re0,#0 /* Prepare to disable ints */ 115 MOVT A0.3,#HI(LINSYSEVENT_WR_ATOMIC_LOCK) 116 SWAP D1Re0,TXMASKI /* Really stop ints */ 117 LOCK2 /* Gain all locks */ 118 SET [A0.3+#UON],D1RtP /* Stop shared memory access too */ 119 DCACHE [D1Ar1],A0.3 /* Flush Cache line */ 120 GETD D0Re0,[D1Ar1] /* Get new state from memory or hit */ 121 DCACHE [D1Ar1],A0.3 /* Flush Cache line */ 122 GETD D0Re0,[D1Ar1] /* Get current state */ 123 TST D0Re0,D0Ar2 /* Are we clear to send? */ 124 ORZ D0Re0,D0Re0,D0Ar2 /* Yes: So set bits and */ 125 SETDZ [D1Ar1],D0Re0 /* transmit new state */ 126 SET [A0.3+#UOFF],D1RtP /* Allow shared memory access */ 127 LOCK0 /* Release all locks */ 128 MOV TXMASKI,D1Re0 /* Allow ints */ 129$LPollEnd: 130 XORNZ D0Re0,D0Re0,D0Re0 /* No: Generate zero result */ 131 MOV PC,D1RtP /* Return (NZ indicates failure) */ 132 .size ___TBIPoll,.-___TBIPoll 133 134/* 135 * End of tbicore.S 136 */ 137