1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
/*
* systrap.S
*
* This file contains emulated system calls using software trap 0.
* The following calls are supported:
*
* + SYS_exit (halt)
* + SYS_irqdis (disable interrupts)
* + SYS_irqset (set interrupt level)
*
* COPYRIGHT (c) 2010. Gedare Bloom.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems/asm.h>
#include "sparc64-syscall.h"
.seg "text"
/*
* system call
*
* On entry:
* g4[AG | GL=1] = tstate (from trap table)
* g2[AG | GL=1] = trap vector # (256)
* g3[AG | GL=1] = address of SYM(syscall)
* g4[AG | GL-1] = system call id
* if arch = sun4v:
* We need to back to GL-1 to read the system call id.
* on sun4u:
* We need to go back to the normal globals to read the system call id.
*
* First thing is to return to the previous set of globals, so
* that the system call id can be read. The syscall code needs
* to re-read tstate.
*
* syscall should only ever be entered by ta 0 being called explicitly
* by a function that knows what is happening. This means the syscall
* code can safely use any scratch registers and the %o registers.
*/
PUBLIC(syscall)
SYM(syscall):
mov %g0, %g4 ! clear %g4 at this GL
#if defined (SUN4U)
rdpr %pstate, %g1
andn %g1, SPARC_PSTATE_AG_MASK, %g1
wrpr %g1, %g0, %pstate ! go to regular globals
#elif defined (SUN4V)
rdpr %gl, %g1
dec %g1
wrpr %g0, %g1, %gl ! go back to GL = GL - 1
#endif
subcc %g4, 2, %g0
bne 3f
rdpr %tstate, %g5 ! re-read tstate, use delay slot
! syscall 2, disable interrupts
rdpr %pil, %g1
and %g5, SPARC_TSTATE_IE_MASK, %o0
or %o0, %g1, %o0 ! return TSTATE_IE | PIL
wrpr %g0, 0xf, %pil ! set PIL to 15
andn %g5, SPARC_TSTATE_IE_MASK, %g1
wrpr %g0, %g1, %tstate ! disable interrupts in trap state
ba,a 9f
3: ! syscall 3, enable interrupts
subcc %g4, 3, %g0
bne 1f
and %o0, 0xf, %g1
wrpr %g0, %g1, %pil ! restore PIL
! and %o0, SPARC_TSTATE_IE_MASK, %g1
! or %g5, %g1, %g1 ! restore saved IE
or %g5, SPARC_TSTATE_IE_MASK, %g1 ! restore IE (safe?)
wrpr %g0, %g1, %tstate
ba,a 9f
1:
ba,a 1b ! spin. taking a trap here -> htrap
9: ! leave
mov 0, %g4 ! clear %g4
DONE
PUBLIC(sparc_disable_interrupts)
SYM(sparc_disable_interrupts):
mov SYS_irqdis, %g4
ta 0
#if 0
rdpr %pstate, %g5
rdpr %pil, %g1
and %g5, SPARC_PSTATE_IE_MASK, %o0
or %o0, %g1, %o0 ! return PSTATE_IE | PIL
wrpr %g0, 0xf, %pil ! set PIL to 15
andn %g5, SPARC_PSTATE_IE_MASK, %g1
wrpr %g0, %g1, %pstate ! disable interrupts
#endif
retl
nop
PUBLIC(sparc_enable_interrupts)
SYM(sparc_enable_interrupts):
mov SYS_irqen, %g4
ta 0
#if 0
rdpr %pstate, %g5
and %o0, 0xf, %g1
wrpr %g0, %g1, %pil ! restore PIL
and %o0, SPARC_PSTATE_IE_MASK, %g1
or %g5, %g1, %g1 ! restore saved IE
! or %g5, SPARC_PSTATE_IE_MASK, %g1 ! set IE regardless of old (safe?)
wrpr %g0, %g1, %pstate
#endif
retl
nop
/* end of file */
|