Home | History | Annotate | Download | only in sbcp
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 	.file	"sbcp.s"
     27 
     28 #include <sys/asm_linkage.h>
     29 #include <sys/link.h>
     30 #include <sys/syscall.h>
     31 
     32 #define	PIC_SETUP(r)						\
     33 	mov	%o7, %g1;					\
     34 9:	call	8f;						\
     35 	sethi	%hi(_GLOBAL_OFFSET_TABLE_ - (9b - .)), %r;	\
     36 8:	or	%r, %lo(_GLOBAL_OFFSET_TABLE_ - (9b - .)), %r;	\
     37 	add	%r, %o7, %r;					\
     38 	mov	%g1, %o7
     39 
     40 #define	FUNC(x) \
     41 	.section	".text"; \
     42 	.align	4; \
     43 	.type	x, #function; \
     44 x:
     45 
     46 #define	ENOSYS	90		/* 4.x ENOSYS */
     47 
     48 /* derived from <sys/exechdr.h>, which we can't include */
     49 #define	A_MAGIC	0x02	/* offset of a_magic field */
     50 #define	A_ENTRY	0x14	/* offset of a_entry field */
     51 #define	ZMAGIC	0413	/* magic number for demand paged executable */
     52 
     53 	.global	atexit, errno
     54 
     55 !
     56 !	_start - execution starts here (after the runtime linker runs)
     57 !
     58 !	The SPARC ABI defines our "environment" at this point, see page 3-34.
     59 !	Register the exit handler, register the trap0 handler, find the
     60 !	entry point, and jump to it.  We depend on the stack (argv, envp)
     61 !	being compatible between 4.x and 5.x.  We also depend on the
     62 !	runtime linker to set up ``environ''.
     63 !
     64 
     65 ENTRY_NP(_start)
     66 	tst	%g1			! is there a handler to register?
     67 	bz	1f			! no
     68 	nop
     69 	mov	%g1, %o0
     70 	call	atexit			! yes, register it with atexit()
     71 	nop
     72 1:
     73 
     74 	!
     75 	! Aside from a value in %g1, there were no arguments explicitly
     76 	! passed to this routine, but we do know how our initial stack has
     77 	! been setup by the kernel.  The stack format is documented in:
     78 	!	usr/src/cmd/sgs/rtld/sparc/boot.s
     79 	!	usr/src/cmd/sgs/rtld/sparcv9/boot.s
     80 	!
     81 	! Since we want to invoke the following c initalization routine:
     82 	!	sbcp_init(int argc, char *argv[], char *envp[]))
     83 	! we need to troll through the stack to setup it's argument values.
     84 	!
     85 	save	%sp, -SA(MINFRAME + EB_MAX_SIZE32), %sp
     86 
     87 	ldn	[%fp + WINDOWSIZE + STACK_BIAS], %o0		! get argc
     88 	add	%fp, + WINDOWSIZE + CPTRSIZE + STACK_BIAS, %o1	! get argv
     89 
     90 	add	%o0, 1, %l0		! add 1 to argc for last element of 0
     91 	sll	%l0, CPTRSHIFT, %l0	! multiply argc by pointer size
     92 	add	%o1, %l0, %o2		!  and add to argv to get envp
     93 
     94 	call	sbcp_init		! Call our c initalization routine
     95 	nop
     96 	restore
     97 
     98 	PIC_SETUP(g2)
     99 	ld	[%g2+trap0], %g1
    100 	ta	9
    101 
    102 	! jump to the main program's entry point
    103 
    104 	sethi   %hi(0x2000), %o0
    105 	lduh    [%o0 + A_MAGIC], %g1
    106 	cmp     %g1, ZMAGIC		! is it a ZMAGIC executable?
    107 	be,a    1f			! yes,
    108 	ld      [%o0 + A_ENTRY], %o0	!   get entry point
    109 1:					! else, assume entry point is 0x2000
    110 	jmp	%o0
    111 	nop
    112 	SET_SIZE(_start)
    113 
    114 !
    115 !	trap0 - glue between 4.x syscall trap and 5.x BCP routine
    116 !
    117 !	enter with:
    118 !		%g1	syscall number
    119 !		%g6	return address (after trap instruction)
    120 !
    121 !	We used to use %g7, but that conflicts with threading code
    122 !	which uses %g7 as the curthread pointer.  That is why we
    123 !	changed to using %g6 instead.
    124 !
    125 !	We use an extra window to save the %o registers we're entered
    126 !	with (which the 4.x system call stubs depend on) and to allow
    127 !	recursive traps (e.g., from a signal handler).
    128 !
    129 
    130 FUNC(trap0)
    131 	save	%sp, -SA(MINFRAME), %sp
    132 	tst	%g1
    133 	be	1f
    134 	nop
    135 	mov	%i0, %o0
    136 	mov	%i1, %o1
    137 	mov	%i2, %o2
    138 	mov	%i3, %o3
    139 	mov	%i4, %o4
    140 	mov	%i5, %o5
    141 	ba,a	2f
    142 1:
    143 	! indir syscall
    144 	mov	%i0, %g1
    145 	mov	%i1, %o0
    146 	mov	%i2, %o1
    147 	mov	%i3, %o2
    148 	mov	%i4, %o3
    149 	mov	%i5, %o4
    150 	ld	[%fp + MINFRAME], %o5
    151 2:
    152 	sll	%g1, 4, %l1
    153 	PIC_SETUP(l0)
    154 	ld	[%l0+sysent], %l0
    155 	add	%l1, %l0, %l1
    156 	jmp	%l1			! jump into branch table
    157 	nop
    158 	SET_SIZE(trap0)
    159 
    160 FUNC(trap0rtn)
    161 	cmp	%o0, -1
    162 	bne	1f
    163 	addcc	%g0, %g0, %g0		! psr &= ~C
    164 	PIC_SETUP(o1)
    165 	ld	[%o1+errno], %o1
    166 	ld	[%o1], %o0
    167 	subcc	%g0, 1, %g0		! psr |= C
    168 1:
    169 	mov	%o0, %i0
    170 	restore
    171 	jmp	%g6
    172 	nop
    173 	SET_SIZE(trap0rtn)
    174 
    175 !
    176 !	nullsys
    177 !
    178 FUNC(nullsys)
    179 	clr	%o0
    180 	b,a	trap0rtn
    181 	SET_SIZE(nullsys)
    182 
    183 !
    184 !	nosys
    185 !
    186 FUNC(nosys)
    187 	set	ENOSYS, %o1
    188 	PIC_SETUP(g2)
    189 	ld	[%g2+errno], %g2
    190 	st	%o1, [%g2]
    191 	set	-1, %o0
    192 	b,a	trap0rtn
    193 	SET_SIZE(nosys)
    194 
    195 !
    196 !	Have to #include the sysent table and stubs so that all
    197 !	symbols referenced between here and there are "static"
    198 !	to this module so the assembler can resolve them without
    199 !	the linker needing to deal with them at run time.
    200 !
    201 #include "sysent.s"
    202