PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
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
18extern char* _end;
19extern char* _heap_size;
20extern char* _fbss;
21extern char* _stack;
22extern char* _stack_size;
23
24__attribute__((weak)) void _ps2sdk_memory_init();
25__attribute__((weak)) void _init();
26__attribute__((weak)) void _fini();
27
28void _libcglue_args_parse(int argc, char** argv);
29void _libcglue_init();
30void _libcglue_deinit();
31int main(int argc, char** argv);
32
33static void _main();
34
35static struct sargs args;
36static 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 */
43void __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 */
85static 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
136noreturn 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}
typedef __attribute__
Definition tlbfunc.c:60