PS2SDK
PS2 Homebrew Libraries
crt0.c
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright (c) 2003 Marcus R. Brown <mrbrown@0xd6.org>
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 */
10 
11 #include <kernel.h>
12 #include <stdio.h>
13 #include <stdint.h>
14 #include <stdnoreturn.h> // noreturn
15 #include <string.h>
16 #include <startup.h>
17 
18 extern char* _end;
19 extern char* _heap_size;
20 extern char* _fbss;
21 extern char* _stack;
22 extern char* _stack_size;
23 
24 __attribute__((weak)) void _ps2sdk_memory_init();
25 __attribute__((weak)) void _init();
26 __attribute__((weak)) void _fini();
27 
28 void _libcglue_args_parse(int argc, char** argv);
29 void _libcglue_init();
30 void _libcglue_deinit();
31 int main(int argc, char** argv);
32 
33 static void _main();
34 
35 static struct sargs args;
36 static struct sargs_start *args_start;
37 
38 /*
39  * First function to be called by the loader
40  * This function sets up the stack and heap.
41  * DO NOT USE THE STACK IN THIS FUNCTION!
42  */
43 void __start(struct sargs_start *pargs)
44 {
45  __asm__ __volatile__(
46  "# Clear bss area \n"
47  ".set noat \n"
48  "la $2, _fbss \n"
49  "la $3, _end \n"
50  "1: \n"
51  "sltu $1, $2, $3 \n"
52  "beq $1, $0, 2f \n"
53  "nop \n"
54  "sq $0, ($2) \n"
55  "addiu $2, $2, 16 \n"
56  "j 1b \n"
57  "nop \n"
58  "2: \n"
59  " \n"
60  "# Save first argument \n"
61  "sw %1, %0 \n"
62  " \n"
63  "# SetupThread \n"
64  "la $4, _gp \n"
65  "la $5, _stack \n"
66  "la $6, _stack_size \n"
67  "la $7, args \n"
68  "la $8, ExitThread \n"
69  "move $gp, $4 \n"
70  "addiu $3, $0, 60 \n"
71  "syscall \n"
72  "move $sp, $2 \n"
73  " \n"
74  "# Jump to _main \n"
75  "j %2 \n"
76  ".set at \n"
77  : /* No outputs. */
78  : "m"(args_start), "r"(pargs), "Csy"(_main)
79  : "1", "2", "3", "4", "5", "6", "7", "8");
80 }
81 
82 /*
83  * Intermediate function between _start and main, stack can be used as normal.
84  */
85 static void _main()
86 {
87  int retval;
88  struct sargs *pa;
89 
90  // initialize heap
91  SetupHeap(&_end, (int)&_heap_size);
92 
93  // writeback data cache
94  FlushCache(0);
95 
96  // Capability to override 32MiB on DESR/DVR models
97  // NOTE: this call can restart the application
98  if (_ps2sdk_memory_init)
99  _ps2sdk_memory_init();
100 
101  // Initialize the kernel (Apply necessary patches).
102  _InitSys();
103 
104  // Use arguments sent through start if sent (by ps2link for instance)
105  pa = &args;
106  if (args.argc == 0 && args_start != NULL && args_start->args.argc != 0)
107  pa = &args_start->args;
108 
109  // call libcglue argument parsing
110  _libcglue_args_parse(pa->argc, pa->argv);
111 
112  // initialize libcglue
113  _libcglue_init();
114 
115  // Enable interruts
116  EI();
117 
118  // call global constructors (weak)
119  if (_init)
120  _init();
121 
122  // call main
123  retval = main(pa->argc, pa->argv);
124 
125  // call global destructors (weak)
126  if (_fini)
127  _fini();
128 
129  // uninitialize libcglue
130  _libcglue_deinit();
131 
132  // Exit
133  Exit(retval);
134 }
135 
136 noreturn void _exit(int status)
137 {
138  // call global destructors (weak)
139  if (_fini)
140  _fini();
141 
142  // uninitialize libcglue
143  _libcglue_deinit();
144 
145  // Exit
146  Exit(status);
147 }
kernel.h
sargs
Definition: startup.h:30
__attribute__
typedef __attribute__
Definition: tlbfunc.c:60
stdio.h
startup.h
sargs_start
Definition: startup.h:37