summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/sparc/syscall/syscall.S
blob: a36ffaf220aaac6fb1e69fd202ff24d59ab5626b (plain) (blame)
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
/*
 *  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:
 *
 *  COPYRIGHT (c) 1995. European Space Agency.
 *
 *  This terms of the RTEMS license apply to this file.
 *
 */

#include <rtems/asm.h>
#include "syscall.h"

        .seg    "text"
        /*
         *  system call
         *
         *  On entry:
         *
         *    l0 = psr (from trap table)
         *    l1 = pc
         *    l2 = npc
         *    g1 = system call id
         *
         *  System Call 1 (exit):
         *    g2 = additional exit code 1
         *    g3 = additional exit code 2
         */

.align 32				! Align to 32-byte cache-line
        PUBLIC(syscall)

SYM(syscall):

	! "subcc, %g1, 3, %g0" done in trap table
	bne	2f			! syscall 3? enable interrupt
	 and	%i0, SPARC_PSR_PIL_MASK, %l4
	andn	%l0, SPARC_PSR_PIL_MASK, %l5
	wr	%l4, %l5, %psr		! Update PSR according to syscall 3
1:					! leave, with 3 inst PSR-write delay
	mov	0, %g1			! clear %g1
	or	%l0, SPARC_PSR_ET_MASK, %i0	! return old psr with ET=1. No
						! effect on syscall 3
	jmpl	%l2, %g0
	 rett	%l2 + 4

2:	or	%l0, 0x0f00, %l4	! set PIL=15
	subcc	%g1, 2, %g0		! syscall 2? disable interrupts
	beq,a	1b			! Annul delay-slot for syscall 1
	 mov	%l4, %psr		! Update PSR according to Syscall 2
	ta	0			! syscall 1 (not 2 or 3), halt

        PUBLIC(sparc_disable_interrupts)

SYM(sparc_disable_interrupts):

	mov	SYS_irqdis, %g1
	retl
	 ta	0

        PUBLIC(sparc_enable_interrupts)

SYM(sparc_enable_interrupts):

	mov	SYS_irqen, %g1
	retl
	 ta	0

        PUBLIC(sparc_syscall_exit)

SYM(sparc_syscall_exit):

	mov	SYS_exit, %g1
	mov	%o0, %g2	! Additional exit code 1
	mov	%o1, %g3	! Additional exit code 2
	ta	0

/* end of file */