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
49	lgdtl gdt_desc - _start + 0x10
50	mov $1, %eax
51	mov %eax, %cr0
52	ljmpl $0x10,$_start32
53	.code32
54_start32:
55	#mov	$0x08, %eax		# TSS needed later for handling
56	#ltr	%ax			# exceptions and interrupts
57	mov	$0x18, %eax		# selector for 32-bit data segment
58	mov	%eax, %es		# propagate to all data segments
59	mov	%eax, %ss
60	mov	%eax, %ds
61	mov	%eax, %fs
62	mov	%eax, %gs
63	fninit				# initialize x87 FPU
64
65	/* Check for SSE and enable if present */
66	mov	$0x1, %eax
67	cpuid
68	test	$(1<<25), %edx
69	jz	1f
70	mov	$0x600, %eax
71	mov	%eax, %cr4
721:
73
74	/* Initialize the stack */
75	mov	$__stack, %esp
76
77	/* Initialize data segment */
78	pushl	$__data_size
79	pushl	$__data_source
80	pushl	$__data_start
81	call	memcpy
82	addl	$12, %esp
83
84	/* Initialize BSS */
85	pushl	$__bss_size
86	pushl	$0
87	pushl	$__bss_start
88	call	memset
89	addl	$12, %esp
90
91#ifdef PICOLIBC_TLS
92	// call to _set_tls(__tls_base)
93	pushl	$__tls_base
94	call	_set_tls
95	addl	$4, %esp
96#endif
97
98#if defined(_HAVE_INITFINI_ARRAY) && CONSTRUCTORS
99	call	__libc_init_array
100#endif
101
102	call	main
103
104#ifdef CRT0_EXIT
105	/* keep stack aligned to 16-byte boundary so SSE works */
106	push	$0
107	push	$0
108	push	$0
109	push	%eax
110	call	exit
111#else
1121:
113	jmp	1b
114#endif
115
116gdt_desc:
117	.word gdt_end - gdt - 1
118	.long gdt
119
120gdt:
121	.quad 0x0000000000000000	# unused (null selector)
122	.quad 0x0000000000000000	# 0x08: space for Task State Segment
123	.quad 0x00CF9B000000FFFF        # 0x10: ring 0 32-bit code segment
124	.quad 0x00CF93000000FFFF        # 0x18: ring 0 data segment
125gdt_end:
126
127#if defined(__linux__) && defined(__ELF__)
128.section .note.GNU-stack,"",%progbits
129#endif
130