1/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright © 2021 Mike Haertel and Keith Packard
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above
14 *    copyright notice, this list of conditions and the following
15 *    disclaimer in the documentation and/or other materials provided
16 *    with the distribution.
17 *
18 * 3. Neither the name of the copyright holder nor the names of its
19 *    contributors may be used to endorse or promote products derived
20 *    from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33 * OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#include <picolibc.h>
37
38#ifndef CONSTRUCTORS
39#define CONSTRUCTORS 1
40#endif
41
42	.text
43	.section	.text.init.enter
44	.globl	_start
45	.type	start, @function
46_start:
47	.code16
48	cs lgdtl gdt_desc - _start + 0x10
49	mov $1, %eax
50	mov %eax, %cr0
51	ljmpl $0x10,$_start32
52	.code32
53_start32:
54	#mov	$0x08, %eax		# TSS needed later for handling
55	#ltr	%ax			# exceptions and interrupts
56	mov	$0x18, %eax		# selector for 32-bit data segment
57	mov	%eax, %es		# propagate to all data segments
58	mov	%eax, %ss
59	mov	%eax, %ds
60	mov	%eax, %fs
61	mov	%eax, %gs
62	fninit				# initialize x87 FPU
63
64	/* Check for SSE and enable if present */
65	mov	$0x1, %eax
66	cpuid
67	test	$(1<<25), %edx
68	jz	1f
69	mov	$0x600, %eax
70	mov	%eax, %cr4
711:
72
73	/* Initialize the stack */
74	mov	$__stack, %esp
75
76	/* Initialize data segment */
77	pushl	$__data_size
78	pushl	$__data_source
79	pushl	$__data_start
80	call	memcpy
81	addl	$12, %esp
82
83	/* Initialize BSS */
84	pushl	$__bss_size
85	pushl	$0
86	pushl	$__bss_start
87	call	memset
88	addl	$12, %esp
89
90#ifdef PICOLIBC_TLS
91	// call to _set_tls(__tls_base)
92	pushl	$__tls_base
93	call	_set_tls
94	addl	$4, %esp
95#endif
96
97#if defined(_HAVE_INITFINI_ARRAY) && CONSTRUCTORS
98	call	__libc_init_array
99#endif
100
101	call	main
102
103#ifdef CRT0_EXIT
104	/* keep stack aligned to 16-byte boundary so SSE works */
105	push	$0
106	push	$0
107	push	$0
108	push	%eax
109	call	exit
110#else
1111:
112	jmp	1b
113#endif
114
115gdt_desc:
116	.word gdt_end - gdt - 1
117	.long gdt
118
119gdt:
120	.quad 0x0000000000000000	# unused (null selector)
121	.quad 0x0000000000000000	# 0x08: space for Task State Segment
122	.quad 0x00CF9B000000FFFF        # 0x10: ring 0 32-bit code segment
123	.quad 0x00CF93000000FFFF        # 0x18: ring 0 data segment
124gdt_end:
125
126#if defined(__linux__) && defined(__ELF__)
127.section .note.GNU-stack,"",%progbits
128#endif
129