Mercurial > ecos
annotate packages/hal/sparclite/arch/current/src/context.S @ 3292:7f8e529b4d82 default tip
Fix FREESCALE_EDMA_NBYTES_MLOFFYES_MLOFF() so it works with negative offsets.
| author | vae |
|---|---|
| date | Wed, 29 Apr 2015 23:31:48 +0000 |
| parents | 74dbf4c3f2e1 |
| children |
| rev | line source |
|---|---|
| 2 | 1 /*============================================================================= |
| 2 // | |
| 3 // context.S | |
| 4 // | |
| 5 // SPARClite context switch code | |
| 6 // | |
| 7 //============================================================================= | |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
8 // ####ECOSGPLCOPYRIGHTBEGIN#### |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
9 // ------------------------------------------- |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
12 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
13 // eCos is free software; you can redistribute it and/or modify it under |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
14 // the terms of the GNU General Public License as published by the Free |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
15 // Software Foundation; either version 2 or (at your option) any later |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
16 // version. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
17 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
18 // eCos is distributed in the hope that it will be useful, but WITHOUT |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
19 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
21 // for more details. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
22 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
23 // You should have received a copy of the GNU General Public License |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
24 // along with eCos; if not, write to the Free Software Foundation, Inc., |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
25 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
26 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
27 // As a special exception, if other files instantiate templates or use |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
28 // macros or inline functions from this file, or you compile this file |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
29 // and link it with other works to produce a work based on this file, |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
30 // this file does not by itself cause the resulting work to be covered by |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
31 // the GNU General Public License. However the source code for this file |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
32 // must still be made available in accordance with section (3) of the GNU |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
33 // General Public License v2. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
34 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
35 // This exception does not invalidate any other reasons why a work based |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
36 // on this file might be covered by the GNU General Public License. |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
37 // ------------------------------------------- |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
38 // ####ECOSGPLCOPYRIGHTEND#### |
| 2 | 39 //============================================================================= |
| 40 //#####DESCRIPTIONBEGIN#### | |
| 41 // | |
| 42 // Author(s): nickg, gthomas, hmt | |
| 43 // Contributors: nickg, gthomas, hmt | |
| 44 // Date: 1998-12-15 | |
| 45 // Purpose: SPARClite context switch code | |
| 46 // Description: This file contains implementations of the thread context | |
| 47 // switch routines. It also contains the longjmp() and setjmp() | |
| 48 // routines. | |
| 49 // | |
| 50 //####DESCRIPTIONEND#### | |
| 51 // | |
| 52 //===========================================================================*/ | |
| 53 | |
| 54 #include <pkgconf/hal.h> | |
| 55 | |
| 56 #include <cyg/hal/vectors.h> | |
| 57 | |
| 58 #define DELAYS_AFTER_WRPSR_SAME_WINDOW | |
| 59 #define DELAYS_AFTER_WRWIM | |
| 60 | |
| 61 .text | |
| 62 | |
| 63 ! ------------------------------------------------------------------------------ | |
| 64 ! hal_thread_switch_context | |
| 65 ! Switch thread contexts | |
| 66 ! %o0 = address of sp of next thread to execute | |
| 67 ! %o1 = address of sp save location of current thread | |
| 68 | |
| 69 .global hal_thread_switch_context | |
| 70 hal_thread_switch_context: | |
| 71 | |
| 72 ! First take the stack down to make room for the saved register | |
| 73 ! state, including a window save area at the base. Leave the | |
| 74 ! current window save area undisturbed. It is unused within the | |
| 75 ! save but will become current again when we continue in this | |
| 76 ! context. This lets us do this whole piece of work without | |
| 77 ! diabling interrupts for too long, since, for example, we can | |
| 78 ! lower the stack atomically with one instruction: | |
| 79 sub %sp, SAVE_REGS_SIZE, %sp | |
| 80 st %sp, [ %o1 ] ! return SP for this thread | |
| 81 | |
| 82 std %l0, [%sp + 0 * 4] ! save L & I registers | |
| 83 std %l2, [%sp + 2 * 4] | |
| 84 std %l4, [%sp + 4 * 4] | |
| 85 std %l6, [%sp + 6 * 4] | |
| 86 | |
| 87 std %i0, [%sp + 8 * 4] | |
| 88 std %i2, [%sp + 10 * 4] | |
| 89 std %i4, [%sp + 12 * 4] | |
| 90 std %i6, [%sp + 14 * 4] | |
| 91 | |
| 92 #ifdef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM | |
| 93 st %o7, [%sp + 31 * 4] ! save only the return address | |
| 94 ! and no need to preserve %o0 even though it is restored | |
| 95 #else // save a maximal context | |
| 96 st %g1, [%sp + 17 * 4] ! save G & O registers | |
| 97 std %g2, [%sp + 18 * 4] | |
| 98 std %g4, [%sp + 20 * 4] | |
| 99 std %g6, [%sp + 22 * 4] | |
| 100 | |
| 101 std %o0, [%sp + 24 * 4] | |
| 102 std %o2, [%sp + 26 * 4] | |
| 103 std %o4, [%sp + 28 * 4] | |
| 104 std %o6, [%sp + 30 * 4] | |
| 105 #endif // !CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM | |
| 106 ! and save the CWP in %g0 save place | |
| 107 rd %psr, %g7 | |
| 108 st %g7, [%sp + 16 * 4] | |
| 109 | |
| 110 ! Now load the destination thread by dropping through | |
| 111 ! to hal_thread_load_context | |
| 112 | |
| 113 ! ------------------------------------------------------------------------------ | |
| 114 ! hal_thread_load_context | |
| 115 ! Load thread context | |
| 116 ! %o0 = address of sp of next thread to execute | |
| 117 ! Note that this function is also the second half of hal_thread_switch_context | |
| 118 ! and is simply dropped into from it. | |
| 119 | |
| 120 .global hal_thread_load_context | |
| 121 hal_thread_load_context: | |
| 122 | |
| 123 ! Here, we are a leaf routine but with slightly odd properties. | |
| 124 ! The stack is still the callers at this point but the register | |
| 125 ! set is up for grabs. So we can use globals: | |
| 126 | |
| 127 ld [ %o0 ], %g7 ! Get the next saved SP | |
| 128 | |
| 129 ! DISABLE INTERRUPTS *ONLY* NOT TRAPS | |
| 130 rd %psr, %g6 | |
| 131 or %g6, 0xfe0, %g5 ! PIL up to 15 leave traps enabled | |
| 132 wr %g5, %psr | |
| 133 | |
| 134 ! force out all our callers register sets onto the stack | |
| 135 ! if necessary: the system will handily take care of this for | |
| 136 ! us as follows: | |
| 137 save %sp, -16 * 4, %sp ! need all these to preserve | |
| 138 save %sp, -16 * 4, %sp ! the linked list property... | |
| 139 save %sp, -16 * 4, %sp | |
| 140 save %sp, -16 * 4, %sp | |
|
40
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
141 #if 6 < __WINSIZE |
| 2 | 142 save %sp, -16 * 4, %sp |
|
40
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
143 #if 7 < __WINSIZE |
| 2 | 144 save %sp, -16 * 4, %sp |
|
40
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
145 #endif |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
146 #endif |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
147 ! Fewer saves if fewer register windows. For 8 register windows, |
| 2 | 148 ! six of these is correct; a seventh would force out the current |
| 149 ! set that was already saved manually above. Note that minimal | |
| 150 ! space is allowed on stack for locals and ins in case this | |
| 151 ! sequence itself gets interrupted and recurses too deep. | |
| 152 | |
| 153 ! now select the new window with traps disabled... | |
| 154 | |
|
8
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
155 ! get the new PSR and CWP that we will ultimately restore |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
156 ! from the %g0 save place... |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
157 ld [%g7 + 16 * 4], %g6 ! %g7 holds the new stack pointer |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
158 andn %g6, 0x20, %g5 ! clear ET into %g5 |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
159 and %g6, __WINBITS, %g4 ! CWP bits only in %g4 |
| 2 | 160 |
| 161 ! calculate a new WIM... | |
| 162 add %g4, 1, %g3 ! required invalid window number | |
|
40
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
163 #if 8 == __WINSIZE |
| 2 | 164 and %g3, __WINBITS, %g3 ! modulo 8 |
|
40
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
165 #else // expect 5 or 6 or 7 windows |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
166 cmp %g3, __WINSIZE |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
167 bge,a 567f ! taken: do delay slot, handle overflow |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
168 mov 0, %g3 ! only if .ge. above |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
169 567: |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
170 #endif |
| 2 | 171 mov 1, %g2 |
| 172 sll %g2, %g3, %g2 ! converted to a mask for the WIM | |
| 173 | |
|
8
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
174 ! DISABLE INTERRUPTS (TRAPS) |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
175 wr %g5, %psr ! set CWP to new window, disable traps |
| 2 | 176 wr %g2, %wim ! and WIM to new value |
| 177 nop | |
| 178 nop | |
| 179 nop | |
| 180 | |
| 181 ! Must do this atomically so that the registers match the stack. | |
| 182 ! After locals and ins are loaded, we are conformant to the PCS | |
| 183 ! so can re-enable interrupts. | |
| 184 mov %g7, %sp ! target sp in situ (%sp = %o6) | |
| 185 | |
| 186 ldd [%sp + 0 * 4], %l0 ! restore L & I registers | |
| 187 ldd [%sp + 2 * 4], %l2 | |
| 188 ldd [%sp + 4 * 4], %l4 | |
| 189 ldd [%sp + 6 * 4], %l6 | |
| 190 | |
| 191 ldd [%sp + 8 * 4], %i0 | |
| 192 ldd [%sp + 10 * 4], %i2 | |
| 193 ldd [%sp + 12 * 4], %i4 | |
| 194 ldd [%sp + 14 * 4], %i6 | |
| 195 | |
|
8
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
196 ! RESTORE INTERRUPTS to saved state |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
197 wr %g6, %psr ! set new CWP and old ET and PIL |
| 2 | 198 nop |
| 199 nop | |
| 200 nop | |
| 201 | |
|
8
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
202 ! now load the rest of the context; we can be interrupted here |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
203 ! (if the saved context was a voluntary yield or threadstart) |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
204 ! but that is OK, other state will be preserved in that case... |
| 2 | 205 |
| 206 #ifdef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM | |
| 207 ld [%sp + 24 * 4], %o0 ! must load the initial argument | |
| 208 #else // restore a maximal context | |
| 209 ld [%sp + 17 * 4], %g1 | |
| 210 ldd [%sp + 18 * 4], %g2 | |
| 211 ldd [%sp + 20 * 4], %g4 | |
| 212 ldd [%sp + 22 * 4], %g6 | |
| 213 | |
| 214 ldd [%sp + 24 * 4], %o0 | |
| 215 ldd [%sp + 26 * 4], %o2 | |
| 216 ldd [%sp + 28 * 4], %o4 | |
| 217 #endif // !CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM | |
| 218 ! %o6 = %sp, already set up | |
| 219 ld [%sp + 31 * 4], %o7 ! "return" address | |
| 220 | |
| 221 retl | |
| 222 add %sp, SAVE_REGS_SIZE, %sp ! and set the stack back | |
| 223 ! to its entrant value | |
| 224 | |
| 225 ! ------------------------------------------------------------------------------ | |
| 226 ! HAL longjmp, setjmp implementations | |
| 227 | |
| 228 !FUNC_START(hal_setjmp) | |
| 229 .global hal_setjmp | |
| 230 hal_setjmp: | |
| 231 ! Treat this as a leaf routine, may as well. | |
| 232 ! %o0 is the address of the buffer. | |
| 233 | |
| 234 std %l0, [%o0 + 0 * 4] ! save L & I registers | |
| 235 std %l2, [%o0 + 2 * 4] | |
| 236 std %l4, [%o0 + 4 * 4] | |
| 237 std %l6, [%o0 + 6 * 4] | |
| 238 | |
| 239 std %i0, [%o0 + 8 * 4] | |
| 240 std %i2, [%o0 + 10 * 4] | |
| 241 std %i4, [%o0 + 12 * 4] | |
| 242 std %i6, [%o0 + 14 * 4] | |
| 243 | |
| 244 #ifdef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM | |
| 245 std %o6, [%o0 + 30 * 4] ! just save %sp and return address | |
| 246 #else // save a maximal context | |
| 247 st %g1, [%o0 + 17 * 4] ! save G & O registers | |
| 248 std %g2, [%o0 + 18 * 4] | |
| 249 std %g4, [%o0 + 20 * 4] | |
| 250 std %g6, [%o0 + 22 * 4] | |
| 251 | |
| 252 std %o0, [%o0 + 24 * 4] | |
| 253 std %o2, [%o0 + 26 * 4] | |
| 254 std %o4, [%o0 + 28 * 4] | |
| 255 std %o6, [%o0 + 30 * 4] | |
| 256 #endif // !CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM | |
| 257 | |
| 258 ! and save the CWP in %g0 save place | |
| 259 rd %psr, %g7 | |
| 260 st %g7, [%o0 + 16 * 4] | |
| 261 | |
| 262 ! DISABLE INTERRUPTS *ONLY* NOT TRAPS | |
| 263 or %g7, 0xfe0, %g6 ! PIL up to 15 leave traps enabled | |
| 264 wr %g6, %psr | |
| 265 | |
| 266 ! force out all our callers register sets onto the stack | |
| 267 ! if necessary: the system will handily take care of this for | |
| 268 ! us as follows: | |
| 269 save %sp, -16 * 4, %sp ! need all these to preserve | |
| 270 save %sp, -16 * 4, %sp ! the linked list property... | |
| 271 save %sp, -16 * 4, %sp | |
| 272 save %sp, -16 * 4, %sp | |
|
40
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
273 #if 6 < __WINSIZE |
| 2 | 274 save %sp, -16 * 4, %sp |
|
40
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
275 #if 7 < __WINSIZE |
| 2 | 276 save %sp, -16 * 4, %sp |
|
40
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
277 #endif |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
278 #endif |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
279 ! Fewer saves if fewer register windows. For 8 register windows, |
| 2 | 280 ! six of these is correct; a seventh would force out the current |
| 281 ! set that was already saved manually above. Note that minimal | |
| 282 ! space is allowed on stack for locals and ins in case this | |
| 283 ! sequence itself gets interrupted and recurses too deep. | |
| 284 | |
| 285 ! (after all, we are about to call deeper not shallower, otherwise | |
| 286 ! using setjmp is inappropriate) | |
| 287 | |
| 288 ! ENABLE INTERRUPTS | |
| 289 wr %g7, %psr ! set CWP back to as-was | |
| 290 nop | |
| 291 nop | |
| 292 nop | |
| 293 | |
| 294 #ifndef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM | |
| 295 ldd [%o0 + 22 * 4], %g6 ! preserve %g7 and %g6 | |
| 296 #endif | |
| 297 | |
| 298 retl ! ret and return zero to indicate | |
| 299 mov 0, %o0 ! not longjumped-to | |
| 300 | |
| 301 ! hal_longjmp loads state from arg0 and returns arg1 | |
| 302 !FUNC_START(hal_longjmp) | |
| 303 .global hal_longjmp | |
| 304 hal_longjmp: | |
| 305 ! This is kind of a leaf routine, it returns elsewhere | |
| 306 ! %o0 is the address of the buffer. | |
| 307 ! %o1 is the value to return in %o0 (since we are a leaf) | |
| 308 | |
| 309 mov %o0, %g7 ! keep the pointer handy | |
| 310 mov %o1, %g1 ! and the return value | |
| 311 ! now select the new window with traps disabled... | |
| 312 rd %psr, %g6 | |
| 313 ! preserve ET, clear CWP | |
| 314 andn %g6, __WINBITS_MAXIMAL, %g6 | |
| 315 andn %g6, 0x20, %g5 ! clear ET also into %g5 | |
| 316 | |
| 317 ! get new CWP from %g0 save place... | |
| 318 ld [%g7 + 16 * 4], %g4 ! %g7 holds the new stack pointer | |
| 319 and %g4, __WINBITS, %g4 ! preserve CWP bits | |
| 320 | |
| 321 ! calculate a new WIM... | |
| 322 add %g4, 1, %g3 ! required invalid window number | |
|
40
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
323 #if 8 == __WINSIZE |
| 2 | 324 and %g3, __WINBITS, %g3 ! modulo 8 |
|
40
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
325 #else // expect 5 or 6 or 7 windows |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
326 cmp %g3, __WINSIZE |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
327 bge,a 567f ! taken: do delay slot, handle overflow |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
328 mov 0, %g3 ! only if .ge. above |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
329 567: |
|
a3cc6665b684
Merge from eCos master repository on 1999-10-01-07:47:04-BST
jlarmour
parents:
8
diff
changeset
|
330 #endif |
| 2 | 331 mov 1, %g2 |
| 332 sll %g2, %g3, %g2 ! converted to a mask for the WIM | |
| 333 | |
| 334 ! DISABLE INTERRUPTS | |
| 335 wr %g5, %g4, %psr ! set CWP to new window, disable traps | |
| 336 wr %g2, %wim ! and WIM to new value | |
| 337 nop | |
| 338 nop | |
| 339 nop | |
| 340 | |
| 341 ! Must do this atomically so that the registers match the stack. | |
| 342 ! After locals and ins are loaded, we are conformant to the PCS | |
| 343 ! so can re-enable interrupts. | |
| 344 | |
| 345 ldd [%g7 + 0 * 4], %l0 ! restore L & I registers | |
| 346 ldd [%g7 + 2 * 4], %l2 | |
| 347 ldd [%g7 + 4 * 4], %l4 | |
| 348 ldd [%g7 + 6 * 4], %l6 | |
| 349 | |
| 350 ldd [%g7 + 8 * 4], %i0 | |
| 351 ldd [%g7 + 10 * 4], %i2 | |
| 352 ldd [%g7 + 12 * 4], %i4 | |
| 353 ldd [%g7 + 14 * 4], %i6 | |
| 354 | |
| 355 ld [%g7 + 30 * 4], %sp ! %o6 = %sp, set up now so as to conform | |
| 356 ! to PCS and so be interruptible | |
| 357 ! ENABLE INTERRUPTS | |
| 358 wr %g6, %g4, %psr ! set new CWP and old ET | |
| 359 nop | |
| 360 nop | |
| 361 nop | |
| 362 | |
| 363 ! now load the rest of the context; we can be interrupted here, but | |
| 364 ! that is OK, other state will be preserved in that case... | |
| 365 #ifdef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM | |
| 366 ! we are not preserving globals... | |
| 367 ! %o6 = %sp, already set up | |
| 368 ld [%g7 + 31 * 4], %o7 ! "return" address | |
| 369 retl ! %g1 still holds the return value | |
| 370 mov %g1, %o0 | |
| 371 | |
| 372 #else // load a maximal context | |
| 373 mov %g7, %o0 ! original pointer was in %o0 anyway | |
| 374 | |
| 375 ldd [%o0 + 18 * 4], %g2 | |
| 376 ldd [%o0 + 20 * 4], %g4 | |
| 377 ldd [%o0 + 22 * 4], %g6 | |
| 378 | |
| 379 ld [%o0 + 25 * 4], %o1 ! %o0 = original pointer | |
| 380 ldd [%o0 + 26 * 4], %o2 | |
| 381 ldd [%o0 + 28 * 4], %o4 | |
| 382 ! %o6 = %sp, already set up | |
| 383 ld [%o0 + 31 * 4], %o7 ! "return" address | |
| 384 | |
| 385 ! %g1 still holds the return value; want to get this into %o0 | |
| 386 ! and restore %g1 from the saved state; %o0 is the state pointer: | |
| 387 ! g1 = R, o0 = P | |
| 388 xor %o0, %g1, %g1 ! g1 = R^P, o0 = P | |
| 389 xor %o0, %g1, %o0 ! g1 = R^P, o0 = R | |
| 390 xor %o0, %g1, %g1 ! g1 = P, o0 = R all done | |
| 391 | |
| 392 retl | |
| 393 ld [%g1 + 17 * 4], %g1 ! and finally restore %g1 | |
| 394 #endif // !CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM | |
| 395 | |
| 396 ! ------------------------------------------------------------------------------ | |
| 397 ! end of context.S | |
| 398 | |
| 399 | |
| 400 |
