warning fixes. new function dnode_get_fullpath
[grub2/phcoder.git] / efiemu / main.c
blobb5608e666bccfab8b4e8ccc2716eec78a785d65e
1 /*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2009 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 /* This is an emulation of EFI runtime services.
20 This allows a more uniform boot on i386 machines.
21 As it emulates only runtime service it isn't able
22 to chainload EFI bootloader on non-EFI system. */
25 #include <grub/file.h>
26 #include <grub/err.h>
27 #include <grub/normal.h>
28 #include <grub/mm.h>
29 #include <grub/dl.h>
30 #include <grub/misc.h>
31 #include <grub/efiemu/efiemu.h>
32 #include <grub/machine/efiemu.h>
33 #include <grub/command.h>
35 /* System table. Two version depending on mode */
36 grub_efi_system_table32_t *grub_efiemu_system_table32 = 0;
37 grub_efi_system_table64_t *grub_efiemu_system_table64 = 0;
38 /* Modules may need to execute some actions after memory allocation happens */
39 static struct grub_efiemu_prepare_hook *efiemu_prepare_hooks = 0;
40 /* Linked list of configuration tables */
41 static struct grub_efiemu_configuration_table *efiemu_config_tables = 0;
43 /* Free all allocated space */
44 grub_err_t
45 grub_efiemu_unload (void)
47 struct grub_efiemu_configuration_table *cur, *d;
48 struct grub_efiemu_prepare_hook *curhook, *d2;
49 grub_efiemu_loadcore_unload ();
51 grub_efiemu_mm_unload ();
53 for (cur = efiemu_config_tables; cur;)
55 d = cur->next;
56 if (cur->unload)
57 cur->unload (cur->data);
58 grub_free (cur);
59 cur = d;
61 efiemu_config_tables = 0;
63 for (curhook = efiemu_prepare_hooks; curhook;)
65 d2 = curhook->next;
66 if (curhook->unload)
67 curhook->unload (curhook->data);
68 grub_free (curhook);
69 curhook = d2;
71 efiemu_prepare_hooks = 0;
73 return GRUB_ERR_NONE;
76 /* Remove previously registered table from the list */
77 grub_err_t
78 grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid)
80 struct grub_efiemu_configuration_table *cur, *prev;
82 /* Special treating if head is to remove */
83 while (efiemu_config_tables
84 && !grub_memcmp (&(efiemu_config_tables->guid), &guid, sizeof (guid)))
86 if (efiemu_config_tables->unload)
87 efiemu_config_tables->unload (efiemu_config_tables->data);
88 cur = efiemu_config_tables->next;
89 grub_free (efiemu_config_tables);
90 efiemu_config_tables = cur;
92 if (!efiemu_config_tables)
93 return GRUB_ERR_NONE;
95 /* Remove from chain */
96 for (prev = efiemu_config_tables, cur = prev->next; cur;)
97 if (grub_memcmp (&(cur->guid), &guid, sizeof (guid)) == 0)
99 if (cur->unload)
100 cur->unload (cur->data);
101 prev->next = cur->next;
102 grub_free (cur);
103 cur = prev->next;
105 else
107 prev = cur;
108 cur = cur->next;
110 return GRUB_ERR_NONE;
113 grub_err_t
114 grub_efiemu_register_prepare_hook (grub_err_t (*hook) (void *data),
115 void (*unload) (void *data),
116 void *data)
118 struct grub_efiemu_prepare_hook *nhook;
119 if (! hook)
120 return grub_error (GRUB_ERR_BAD_ARGUMENT, "you must supply the hook");
121 nhook = (struct grub_efiemu_prepare_hook *) grub_malloc (sizeof (*nhook));
122 if (! nhook)
123 return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't prepare hook");
124 nhook->hook = hook;
125 nhook->unload = unload;
126 nhook->data = data;
127 nhook->next = efiemu_prepare_hooks;
128 efiemu_prepare_hooks = nhook;
129 return GRUB_ERR_NONE;
132 /* Register a configuration table either supplying the address directly
133 or with a hook
135 grub_err_t
136 grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
137 void * (*get_table) (void *data),
138 void (*unload) (void *data),
139 void *data)
141 struct grub_efiemu_configuration_table *tbl;
142 grub_err_t err;
144 if (! get_table && ! data)
145 return grub_error (GRUB_ERR_BAD_ARGUMENT,
146 "you must set at least get_table or data");
147 if ((err = grub_efiemu_unregister_configuration_table (guid)))
148 return err;
150 tbl = (struct grub_efiemu_configuration_table *) grub_malloc (sizeof (*tbl));
151 if (! tbl)
152 return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't register table");
154 tbl->guid = guid;
155 tbl->get_table = get_table;
156 tbl->unload = unload;
157 tbl->data = data;
158 tbl->next = efiemu_config_tables;
159 efiemu_config_tables = tbl;
161 return GRUB_ERR_NONE;
164 static grub_err_t
165 grub_cmd_efiemu_unload (grub_command_t cmd __attribute__ ((unused)),
166 int argc __attribute__ ((unused)),
167 char *args[] __attribute__ ((unused)))
169 return grub_efiemu_unload ();
172 static grub_err_t
173 grub_cmd_efiemu_prepare (grub_command_t cmd __attribute__ ((unused)),
174 int argc __attribute__ ((unused)),
175 char *args[] __attribute__ ((unused)))
177 return grub_efiemu_prepare ();
184 grub_efiemu_exit_boot_services (grub_efi_uintn_t map_key
185 __attribute__ ((unused)))
187 /* Nothing to do here yet */
188 return 1;
192 grub_efiemu_finish_boot_services (void)
194 /* Nothing to do here yet */
195 return 1;
198 /* Load the runtime from the file FILENAME. */
199 static grub_err_t
200 grub_efiemu_load_file (const char *filename)
202 grub_file_t file;
203 grub_err_t err;
205 file = grub_file_open (filename);
206 if (! file)
207 return 0;
209 err = grub_efiemu_mm_init ();
210 if (err)
212 grub_file_close (file);
213 grub_efiemu_unload ();
214 return grub_error (grub_errno, "Couldn't init memory management");
217 grub_dprintf ("efiemu", "mm initialized\n");
219 err = grub_efiemu_loadcore_init (file);
220 if (err)
222 grub_file_close (file);
223 grub_efiemu_unload ();
224 return err;
227 grub_file_close (file);
229 /* For configuration tables entry in system table. */
230 grub_efiemu_request_symbols (1);
232 return GRUB_ERR_NONE;
235 grub_err_t
236 grub_efiemu_autocore (void)
238 const char *prefix;
239 char *filename;
240 char *suffix;
241 grub_err_t err;
243 if (grub_efiemu_sizeof_uintn_t () != 0)
244 return GRUB_ERR_NONE;
246 prefix = grub_env_get ("prefix");
248 if (! prefix)
249 return grub_error (GRUB_ERR_FILE_NOT_FOUND,
250 "couldn't find efiemu core because prefix "
251 "isn't set");
253 suffix = grub_efiemu_get_default_core_name ();
255 filename = grub_malloc (grub_strlen (prefix) + grub_strlen (suffix) + 2);
256 if (! filename)
257 return grub_error (GRUB_ERR_OUT_OF_MEMORY,
258 "couldn't allocate temporary space");
260 grub_sprintf (filename, "%s/%s", prefix, suffix);
262 err = grub_efiemu_load_file (filename);
263 grub_free (filename);
264 if (err)
265 return err;
266 #ifndef GRUB_UTIL
267 err = grub_machine_efiemu_init_tables ();
268 if (err)
269 return err;
270 #endif
272 return GRUB_ERR_NONE;
275 grub_err_t
276 grub_efiemu_prepare (void)
278 grub_err_t err;
280 grub_dprintf ("efiemu", "Preparing %d-bit efiemu\n",
281 8 * grub_efiemu_sizeof_uintn_t ());
283 err = grub_efiemu_autocore ();
285 /* Create NVRAM if not yet done. */
286 grub_efiemu_pnvram ();
288 if (grub_efiemu_sizeof_uintn_t () == 4)
289 return grub_efiemu_prepare32 (efiemu_prepare_hooks, efiemu_config_tables);
290 else
291 return grub_efiemu_prepare64 (efiemu_prepare_hooks, efiemu_config_tables);
295 static grub_err_t
296 grub_cmd_efiemu_load (grub_command_t cmd __attribute__ ((unused)),
297 int argc, char *args[])
299 grub_err_t err;
301 grub_efiemu_unload ();
303 if (argc != 1)
304 return grub_error (GRUB_ERR_BAD_ARGUMENT, "filename required");
306 err = grub_efiemu_load_file (args[0]);
307 if (err)
308 return err;
309 #ifndef GRUB_UTIL
310 err = grub_machine_efiemu_init_tables ();
311 if (err)
312 return err;
313 #endif
314 return GRUB_ERR_NONE;
317 static grub_command_t cmd_loadcore, cmd_prepare, cmd_unload;
319 void
320 grub_efiemu_pnvram_cmd_register (void);
322 GRUB_MOD_INIT(efiemu)
324 cmd_loadcore = grub_register_command ("efiemu_loadcore",
325 grub_cmd_efiemu_load,
326 "efiemu_loadcore FILE",
327 "Load and initialize EFI emulator");
328 cmd_prepare = grub_register_command ("efiemu_prepare",
329 grub_cmd_efiemu_prepare,
330 "efiemu_prepare",
331 "Finalize loading of EFI emulator");
332 cmd_unload = grub_register_command ("efiemu_unload", grub_cmd_efiemu_unload,
333 "efiemu_unload",
334 "Unload EFI emulator");
335 grub_efiemu_pnvram_cmd_register ();
338 GRUB_MOD_FINI(efiemu)
340 grub_unregister_command (cmd_loadcore);
341 grub_unregister_command (cmd_prepare);
342 grub_unregister_command (cmd_unload);
343 grub_efiemu_pnvram_cmd_unregister ();