Base call to start task.
[SquirrelJME.git] / nanocoat / src / boot.c
blob78a7c69a94305a1952c908bb34e9a9d011a3d67a
1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
3 // SquirrelJME
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 // -------------------------------------------------------------------------*/
10 #include <string.h>
12 #include "sjme/allocSizeOf.h"
13 #include "sjme/boot.h"
14 #include "sjme/debug.h"
15 #include "sjme/except.h"
16 #include "sjme/nvm.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)
23 sjme_errorCode error;
24 void* reservedBase;
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... */
32 reservedBase = NULL;
33 reservedSize = -1;
34 if (SJME_IS_ERROR(error = sjme_alloc_sizeOf(
35 SJME_ALLOC_SIZEOF_RESERVED_POOL, 0, &reservedSize)))
36 return error;
37 if (SJME_IS_ERROR(error = sjme_alloc(mainPool,
38 reservedSize, (void**)&reservedBase) ||
39 reservedBase == NULL))
40 return error;
42 /* Initialize a reserved pool where all of our own data structures go. */
43 reservedPool = NULL;
44 if (SJME_IS_ERROR(error = sjme_alloc_poolInitStatic(
45 &reservedPool, reservedBase, reservedSize)) ||
46 reservedPool == NULL)
47 return error;
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
59 SJME_EXCEPT_VDEF;
60 sjme_errorCode error;
61 sjme_exceptTrace* trace;
62 sjme_jint i, n;
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. */
72 trace = NULL;
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,
79 &reservedPool)))
80 SJME_EXCEPT_TOSS(error);
82 /* Allocate resultant state. */
83 result = NULL;
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)) ||
92 result == NULL)
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));
101 numMergeSuites = 0;
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)
114 numMergeSuites++;
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)
128 numMergeSuites++;
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. */
140 else
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)
150 /* 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]);
170 #endif
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. */
187 *outState = result;
188 return SJME_ERROR_NONE;
190 SJME_EXCEPT_FAIL:
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)
199 if (state == NULL)
200 return SJME_ERROR_NULL_ARGUMENTS;
202 /* Free sub-structures. */
203 if (SJME_JNI_TRUE)
204 sjme_todo("sjme_nvm_destroy()");
206 /* Free main structure. */
207 if (SJME_JNI_TRUE)
208 sjme_todo("sjme_nvm_destroy()");
210 /* Set exit code, if requested. */
211 if (SJME_JNI_TRUE)
212 sjme_todo("sjme_nvm_destroy()");
214 /* Finished. */
215 sjme_todo("sjme_nvm_destroy()");
216 return SJME_ERROR_NOT_IMPLEMENTED;