Merge branch 'for-3.9/upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / metag / tbx / tbicore.S
CommitLineData
027f891f
JH
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 */