Commit | Line | Data |
---|---|---|
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 | */ |