Welcome to mirror list, hosted at ThFree Co, Russian Federation.

crt1-sim.S « xtensa « libgloss - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4f9924c3b041bb0ce171a19a7eb89fa611b199ff (plain)
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// crt1-sim.S
// For the Xtensa simulator target, this code sets up the C calling context
// and calls main()  (via __clibrary_start).
// Control arrives here at _start from the reset vector or from crt0-app.S.

// Copyright (c) 1998-2012 Tensilica Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include <xtensa/config/core-isa.h>
#include <xtensa/corebits.h>
#include <syscalls.h>

// Exports
.global _start

// Imports
//   __clibrary_init	from C library (eg. newlib or uclibc)
//   exit		from C library
//   main		from user application
//   __stack		from linker script (see LSP Ref Manual)

.type	__clibrary_init, @function
.type	main, @function
.type	exit, @function

# define CALL	call4
# define CALLX	callx4
# define ARG1	a6	/* 1st outgoing call argument */
# define ARG2	a7	/* 2nd outgoing call argument */
# define ARG3	a8	/* 3rd outgoing call argument */
# define ARG4	a9	/* 4th outgoing call argument */
# define ARG5	a10	/* 5th outgoing call argument */

		.data
		.weak	_start_envp	// allow overriding
		.align	4
_start_envp:	.word	0		// empty environ

	.text
	.align 4

_start:
	//  _start is typically NOT at the beginning of the text segment --
	//  it is always called from either the reset vector or other code
	//  that does equivalent initialization (such as crt0-app.S).
	//
	//  Assumptions on entry to _start:
	//	- low (level-one) and medium priority interrupts are disabled
	//	  via PS.INTLEVEL and/or INTENABLE (PS.INTLEVEL is expected to
	//	  be zeroed, to potentially enable them, before calling main)
	//	- C calling context not initialized:
	//	  - PS not initialized
	//	  - SP not initialized
	//	- the following are initialized:
	//	  - LITBASE, cache attributes, WindowBase, WindowStart,
	//	    CPENABLE, FP's FCR and FSR, EXCSAVE[n]

	// Keep a0 zero.  It is used to initialize a few things.
	// It is also the return address, where zero indicates
	// that the frame used by _start is the bottommost frame.
	//
	movi	a0, 0		// keep this register zero.

	wsr	a0, INTENABLE	// INTENABLE value is not defined after reset.
				//make sure that interrupts are shut off (*before* we lower PS.INTLEVEL and PS.EXCM!)

	//  Windowed register init, so we can call windowed code (eg. C code).
	movi	a1, 1
	wsr	a1, WINDOWSTART
	//  The processor always clears WINDOWBASE at reset, so no need to clear it here.
	//  It resets WINDOWSTART to 1 starting with LX2.0/X7.0 (RB-2006.0).
	//  However, assuming hard reset is not yet always practical, so do this anyway:
	wsr	a0, WINDOWBASE
	rsync

	// Set VECBASE to use our vectors instead vectors in ROM
	movi	a1, _vector_table
	wsr	a1, VECBASE


	// Run only one core
	// Multi-threading could be supported in future
	rsr.prid a1		// core and multiprocessor ID
	extui	a1, a1, 13, 1	// extract core ID
	beqz	a1, .Lcore0	// goto Lcore0 for core0 only
.Lsuspend:			// other cores are suspended
	waiti	0
	j	.Lsuspend

.Lcore0:
	// Initialize the stack pointer.
	// See the "ABI and Software Conventions" chapter in the
	// Xtensa ISA Reference manual for details.

	// NOTE: Because the _start routine does not use any memory in its
	// stack frame, and because all of its CALL instructions use a
	// window size of 4, the stack frame for _start can be empty.
	movi	sp, __stack

	// reserve stack space for
	//    - argv array
	//    - argument strings
	movi	a2, SYS_argv_size
	simcall		// returns size of argv[] + its strings in a2

	// The stack only needs 16-byte alignment.
	// However, here we round up the argv size further to 128 byte multiples
	// so that in most cases, variations in argv[0]'s path do not result in
	// different stack allocation.  Otherwise, such variations can impact
	// execution timing (eg. due to cache effects etc) for the same code and data.
	// If we have a PIF, it's more likely the extra required space is okay.
	addi	a2, a2, 127
	srli	a2, a2, 7
	slli	a2, a2, 7

	// No need to use MOVSP because we have no caller (we're the
	// base caller); in fact it's better not to use MOVSP in this
	// context, to avoid unnecessary ALLOCA exceptions and copying
	// from undefined memory:
	//   sub     a3, sp, a2
	//   movsp   sp, a3
	sub	sp, sp, a2

	/*
	 *  Now that sp (a1) is set, we can set PS as per the application
	 *  (user vector mode, enable interrupts, enable window exceptions if applicable).
	 */
	movi	a3, PS_UM|PS_WOE	// PS.WOE = 1, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0
	wsr	a3, PS
	rsync

	#if XCHAL_HAVE_FP || XCHAL_HAVE_DFP
	movi	a3, 1
	wsr	a3, CPENABLE
	#endif

1:

	/*
	 *  Clear the BSS (uninitialized data) segments.
	 *  This code supports multiple zeroed sections (*.bss).
	 *  For speed, we clear memory using an ISS simcall
	 *  (see crt1-boards.S for more generic BSS clearing code).
	 */
	movi	a6, __bss_start
	movi	a7, _end
	bgeu	a6, a7, .Lnobss
.Lbssloop:
	movi	a2, SYS_memset
	l32i	a3, a6, 0	// arg1 = fill start address
	movi	a4, 0		// arg2 = fill pattern
	l32i	a5, a6, 4	// get end address
	addi	a6, a6, 8	// next bss table entry
	sub	a5, a5, a3	// arg3 = fill size in bytes
	simcall			// memset(a3,a4,a5)
	bltu	a6, a7, .Lbssloop	// loop until end of bss table
.Lnobss:

	mov	a3, sp			// tell simcall where to write argv[]
	movi	a2, SYS_argv
	simcall			// write argv[] array at a3

	movi	a2, SYS_argc
	simcall			// put argc in a2

	.weak	_init
	.weak	_fini
	mov	ARG2, sp		// argv
	movi	ARG3, _start_envp	// envp
	movi	ARG4, _init		// _init
	movi	ARG5, _fini		// _fini
	CALL	__clibrary_init

	mov	ARG1, a2		// argc
	mov	ARG2, sp		// argv
	CALL	main

	//  The return value is the same register as the first outgoing argument.
	CALL	exit			// exit with main's return value
	// Does not return here.

	.size	_start, . - _start