1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
12 #include "sjme/allocSizeOf.h"
13 #include "sjme/boot.h"
14 #include "sjme/debug.h"
15 #include "sjme/except.h"
17 #include "sjme/task.h"
19 sjme_errorCode
sjme_nvm_allocReservedPool(
20 sjme_attrInNotNull sjme_alloc_pool
* mainPool
,
21 sjme_attrOutNotNull sjme_alloc_pool
** outReservedPool
)
25 sjme_alloc_pool
* reservedPool
;
26 sjme_jint reservedSize
;
28 if (mainPool
== NULL
|| outReservedPool
== NULL
)
29 return SJME_ERROR_NULL_ARGUMENTS
;
31 /* Determine how big the reserved pool should be... */
34 if (SJME_IS_ERROR(error
= sjme_alloc_sizeOf(
35 SJME_ALLOC_SIZEOF_RESERVED_POOL
, 0, &reservedSize
)))
37 if (SJME_IS_ERROR(error
= sjme_alloc(mainPool
,
38 reservedSize
, (void**)&reservedBase
) ||
39 reservedBase
== NULL
))
42 /* Initialize a reserved pool where all of our own data structures go. */
44 if (SJME_IS_ERROR(error
= sjme_alloc_poolInitStatic(
45 &reservedPool
, reservedBase
, reservedSize
)) ||
49 /* Use the resultant pool. */
50 *outReservedPool
= reservedPool
;
51 return SJME_ERROR_NONE
;
54 sjme_errorCode
sjme_nvm_boot(sjme_alloc_pool
* mainPool
,
55 sjme_alloc_pool
* reservedPool
, const sjme_nvm_bootParam
* param
,
56 sjme_nvm_state
** outState
)
58 #define FIXED_SUITE_COUNT 16
61 sjme_exceptTrace
* trace
;
63 sjme_nvm_state
* volatile result
;
64 sjme_rom_suite
* volatile mergeSuites
[FIXED_SUITE_COUNT
];
65 volatile sjme_jint numMergeSuites
;
66 sjme_task_startConfig initTaskConfig
;
68 if (param
== NULL
|| outState
== NULL
)
69 return SJME_ERROR_NULL_ARGUMENTS
;
71 /* Initialize trace. */
74 SJME_EXCEPT_WITH(trace
):
75 /* Set up a reserved pool where all the data structures for the VM go... */
76 /* But only if one does not exist. */
77 if (reservedPool
== NULL
)
78 if (SJME_IS_ERROR(error
= sjme_nvm_allocReservedPool(mainPool
,
80 SJME_EXCEPT_TOSS(error
);
82 /* Allocate resultant state. */
84 if (SJME_IS_ERROR(error
= sjme_alloc(reservedPool
,
85 sizeof(*result
), (void**)&result
)) || result
== NULL
)
86 SJME_EXCEPT_TOSS(error
);
88 /* Make a defensive copy of the boot parameters. */
89 if (SJME_IS_ERROR(error
= sjme_alloc_copy(reservedPool
,
90 sizeof(sjme_nvm_bootParam
),
91 (void**)&result
->bootParamCopy
, param
)) ||
93 SJME_EXCEPT_TOSS(error
);
95 /* Set parameters accordingly. */
96 result
->allocPool
= mainPool
;
97 result
->reservedPool
= reservedPool
;
99 /* Initialize base for suite merging. */
100 memset(mergeSuites
, 0, sizeof(mergeSuites
));
103 /* Process payload suites. */
104 if (result
->bootParamCopy
->payload
!= NULL
)
106 /* Scan accordingly. */
107 if (SJME_IS_ERROR(error
= sjme_rom_fromPayload(reservedPool
,
108 &mergeSuites
[numMergeSuites
],
109 result
->bootParamCopy
->payload
)))
110 SJME_EXCEPT_TOSS(error
);
112 /* Was a suite generated? */
113 if (mergeSuites
[numMergeSuites
] != NULL
)
117 /* If there is a virtual suite, move it in. */
118 if (result
->bootParamCopy
->virtualSuite
!= NULL
)
120 /* Make a virtual suite for this. */
121 if (SJME_IS_ERROR(error
= sjme_rom_newSuite(reservedPool
,
122 &mergeSuites
[numMergeSuites
],
123 result
->bootParamCopy
->virtualSuite
)))
124 SJME_EXCEPT_TOSS(error
);
126 /* Was a suite generated? */
127 if (mergeSuites
[numMergeSuites
] != NULL
)
131 /* No suites at all? Running with absolutely nothing??? */
132 if (numMergeSuites
<= 0)
133 SJME_EXCEPT_TOSS(SJME_ERROR_NO_SUITES
);
135 /* Use the single suite only. */
136 else if (numMergeSuites
== 1)
137 result
->suite
= mergeSuites
[0];
139 /* Merge everything into one. */
142 /* Merge all the suites together into one. */
143 if (SJME_IS_ERROR(error
= sjme_rom_fromMerge(reservedPool
,
144 &result
->suite
, mergeSuites
,
145 numMergeSuites
)) || result
->suite
== NULL
)
146 SJME_EXCEPT_TOSS(error
);
149 #if defined(SJME_CONFIG_DEBUG)
151 sjme_message("Main class: %s", result
->bootParamCopy
->mainClass
);
153 sjme_message("Main arg: %d at %p",
154 result
->bootParamCopy
->mainArgC
,
155 result
->bootParamCopy
->mainArgV
);
156 for (i
= 0, n
= result
->bootParamCopy
->mainArgC
; i
< n
; i
++)
158 sjme_message("Main arg[%d] at %p",
159 i
, result
->bootParamCopy
->mainArgV
[i
]);
161 if (result
->bootParamCopy
->mainArgV
[i
] != NULL
)
162 sjme_message("Main arg[%d]: %s",
163 i
, result
->bootParamCopy
->mainArgV
[i
]);
166 for (i
= 0, n
= result
->bootParamCopy
->sysPropsC
& (~1); i
< n
; i
+= 2)
167 sjme_message("System Property: %s=%s",
168 result
->bootParamCopy
->sysPropsV
[i
],
169 result
->bootParamCopy
->sysPropsV
[i
+ 1]);
172 /* Setup task details. */
173 initTaskConfig
.stdOut
= SJME_TASK_PIPE_REDIRECT_TYPE_TERMINAL
;
174 initTaskConfig
.stdErr
= SJME_TASK_PIPE_REDIRECT_TYPE_TERMINAL
;
175 initTaskConfig
.mainClass
= result
->bootParamCopy
->mainClass
;
176 initTaskConfig
.mainArgC
= result
->bootParamCopy
->mainArgC
;
177 initTaskConfig
.mainArgV
= result
->bootParamCopy
->mainArgV
;
178 initTaskConfig
.sysPropsC
= result
->bootParamCopy
->sysPropsC
;
179 initTaskConfig
.sysPropsV
= result
->bootParamCopy
->sysPropsV
;
181 /* Spawn initial task which uses the main arguments. */
182 if (SJME_IS_ERROR(error
= sjme_task_start(result
,
183 &initTaskConfig
, NULL
)))
184 SJME_EXCEPT_TOSS(error
);
186 /* Return newly created VM. */
188 return SJME_ERROR_NONE
;
191 sjme_todo("Cleanup after failure.");
192 return SJME_ERROR_NOT_IMPLEMENTED
;
194 #undef FIXED_SUITE_COUNT
197 sjme_errorCode
sjme_nvm_destroy(sjme_nvm_state
* state
, sjme_jint
* exitCode
)
200 return SJME_ERROR_NULL_ARGUMENTS
;
202 /* Free sub-structures. */
204 sjme_todo("sjme_nvm_destroy()");
206 /* Free main structure. */
208 sjme_todo("sjme_nvm_destroy()");
210 /* Set exit code, if requested. */
212 sjme_todo("sjme_nvm_destroy()");
215 sjme_todo("sjme_nvm_destroy()");
216 return SJME_ERROR_NOT_IMPLEMENTED
;