1/*
2 * crt0.S -- startup file for m68k-coff
3 *
4 * Copyright (c) 1995, 1996, 1998 Cygnus Support
5 *
6 * The authors hereby grant permission to use, copy, modify, distribute,
7 * and license this software and its documentation for any purpose, provided
8 * that existing copyright notices are retained in all copies and that this
9 * notice is included verbatim in any distributions. No written agreement,
10 * license, or royalty fee is required for any of the authorized uses.
11 * Modifications to this software may be copyrighted by their authors
12 * and need not follow the licensing terms described here, provided that
13 * the new terms are clearly indicated on the first page of each file where
14 * they apply.
15 */
16
17#include "asm.h"
18
19	.title "crt0.S for m68k-coff"
20#define STACKSIZE	0x4000
21
22/*
23 * Define an empty environment.
24 */
25        .data
26        .align 2
27SYM (environ):
28        .long 0
29
30 	.align	2
31	.text
32
33/*
34 * These symbols are defined in C code, so they need to always be
35 * named with SYM because of the difference between object file formats.
36 */
37
38/* These are defined in C code. */
39	.extern SYM (main)
40	.extern SYM (exit)
41	.extern SYM (hardware_init_hook)
42	.extern SYM (software_init_hook)
43	.extern SYM (atexit)
44	.extern SYM(__do_global_dtors)
45
46/*
47 * These values are set in the linker script, so they must be
48 * explicitly named here without SYM.
49 */
50	.extern __stack
51	.extern __bss_start
52	.extern _end
53
54/*
55 * set things up so the application will run. This *must* be called start.
56 */
57	.global SYM (start)
58
59SYM (start):
60	/*
61	 * put any hardware init code here
62	 */
63
64	/* See if user supplied their own stack (__stack != 0).  If not, then
65	 * default to using the value of %sp as set by the ROM monitor.
66	 */
67	movel	IMM(__stack), a0
68	cmpl	IMM(0), a0
69	jbeq    1f
70	movel	a0, sp
711:
72	/* set up initial stack frame */
73	link	a6, IMM(-8)
74
75/*
76 * zero out the bss section.
77 */
78	movel	IMM(__bss_start), d1
79	movel	IMM(_end), d0
80	cmpl	d0, d1
81	jbeq	3f
82	movl	d1, a0
83	subl	d1, d0
84	subql	IMM(1), d0
852:
86	clrb	(a0)+
87#if !defined(__mcoldfire__) && !defined(__mcf5200__)
88	dbra	d0, 2b
89	clrw	d0
90	subql	IMM(1), d0
91	jbcc	2b
92#else
93	subql	IMM(1), d0
94	jbpl	2b
95#endif
96
973:
98
99/*
100 * initialize target specific stuff. Only execute these
101 * functions it they exist.
102 */
103	PICLEA	SYM (hardware_init_hook), a0
104	cmpl	IMM(0),a0
105	jbeq	4f
106	jsr     (a0)
1074:
108
109	PICLEA	SYM (software_init_hook), a0
110	cmpl	IMM(0),a0
111	jbeq	5f
112	jsr     (a0)
1135:
114
115/*
116 * call the main routine from the application to get it going.
117 * main (argc, argv, environ)
118 * we pass argv as a pointer to NULL.
119 */
120
121#ifdef ADD_DTORS
122	/* put __do_global_dtors in the atexit list so the destructors get run */
123	movel	IMM (SYM(__do_global_dtors)),(sp)
124	PICCALL	SYM (atexit)
125#endif
126	movel	IMM (__FINI_SECTION__),(sp)
127	PICCALL	SYM (atexit)
128
129	PICCALL	__INIT_SECTION__
130
131        pea     0
132	PICPEA	SYM (environ),a0
133        pea     sp@(4)
134        pea     0
135	PICCALL	SYM (main)
136	movel	d0, sp@-
137
138/*
139 * drop down into exit incase the user doesn't. This should drop
140 * control back to the ROM monitor, if there is one. This calls the
141 * exit() from the C library so the C++ tables get cleaned up right.
142 */
143	PICCALL	SYM (exit)
144