~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to grub-core/loader/i386/xnu.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Robert Millan, Updated translations
  • Date: 2010-11-22 12:24:56 UTC
  • mfrom: (1.26.4 upstream) (17.3.36 sid)
  • mto: (17.3.43 sid)
  • mto: This revision was merged to the branch mainline in revision 89.
  • Revision ID: james.westby@ubuntu.com-20101122122456-y82z3sfb7k4zfdcc
Tags: 1.99~20101122-1
[ Colin Watson ]
* New Bazaar snapshot.  Too many changes to list in full, but some of the
  more user-visible ones are as follows:
  - GRUB script:
    + Function parameters, "break", "continue", "shift", "setparams",
      "return", and "!".
    + "export" command supports multiple variable names.
    + Multi-line quoted strings support.
    + Wildcard expansion.
  - sendkey support.
  - USB hotunplugging and USB serial support.
  - Rename CD-ROM to cd on BIOS.
  - Add new --boot-directory option to grub-install, grub-reboot, and
    grub-set-default; the old --root-directory option is still accepted
    but was often confusing.
  - Basic btrfs detection/UUID support (but no file reading yet).
  - bash-completion for utilities.
  - If a device is listed in device.map, always assume that it is
    BIOS-visible rather than using extra layers such as LVM or RAID.
  - Add grub-mknetdir script (closes: #550658).
  - Remove deprecated "root" command.
  - Handle RAID devices containing virtio components.
  - GRUB Legacy configuration file support (via grub-menulst2cfg).
  - Keyboard layout support (via grub-mklayout and grub-kbdcomp).
  - Check generated grub.cfg for syntax errors before saving.
  - Pause execution for at most ten seconds if any errors are displayed,
    so that the user has a chance to see them.
  - Support submenus.
  - Write embedding zone using Reed-Solomon, so that it's robust against
    being partially overwritten (closes: #550702, #591416, #593347).
  - GRUB_DISABLE_LINUX_RECOVERY and GRUB_DISABLE_NETBSD_RECOVERY merged
    into a single GRUB_DISABLE_RECOVERY variable.
  - Fix loader memory allocation failure (closes: #551627).
  - Don't call savedefault on recovery entries (closes: #589325).
  - Support triple-indirect blocks on ext2 (closes: #543924).
  - Recognise DDF1 fake RAID (closes: #603354).

[ Robert Millan ]
* Use dpkg architecture wildcards.

[ Updated translations ]
* Slovenian (Vanja Cvelbar).  Closes: #604003
* Dzongkha (dawa pemo via Tenzin Dendup).  Closes: #604102

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  GRUB  --  GRand Unified Bootloader
 
3
 *  Copyright (C) 2009  Free Software Foundation, Inc.
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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/>.
 
17
 */
 
18
 
 
19
#include <grub/env.h>
 
20
#include <grub/file.h>
 
21
#include <grub/disk.h>
 
22
#include <grub/xnu.h>
 
23
#include <grub/cpu/xnu.h>
 
24
#include <grub/mm.h>
 
25
#include <grub/loader.h>
 
26
#include <grub/autoefi.h>
 
27
#include <grub/i386/tsc.h>
 
28
#include <grub/efi/api.h>
 
29
#include <grub/i386/pit.h>
 
30
#include <grub/misc.h>
 
31
#include <grub/charset.h>
 
32
#include <grub/term.h>
 
33
#include <grub/command.h>
 
34
#include <grub/i18n.h>
 
35
#include <grub/bitmap_scale.h>
 
36
 
 
37
#define min(a,b) (((a) < (b)) ? (a) : (b))
 
38
#define max(a,b) (((a) > (b)) ? (a) : (b))
 
39
 
 
40
#define DEFAULT_VIDEO_MODE "auto"
 
41
 
 
42
char grub_xnu_cmdline[1024];
 
43
grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack;
 
44
 
 
45
/* Aliases set for some tables. */
 
46
struct tbl_alias
 
47
{
 
48
  grub_efi_guid_t guid;
 
49
  char *name;
 
50
};
 
51
 
 
52
struct tbl_alias table_aliases[] =
 
53
  {
 
54
    {GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI_20"},
 
55
    {GRUB_EFI_ACPI_TABLE_GUID, "ACPI"},
 
56
  };
 
57
 
 
58
struct grub_xnu_devprop_device_descriptor
 
59
{
 
60
  struct grub_xnu_devprop_device_descriptor *next;
 
61
  struct property_descriptor *properties;
 
62
  struct grub_efi_device_path *path;
 
63
  int pathlen;
 
64
};
 
65
 
 
66
static int
 
67
utf16_strlen (grub_uint16_t *in)
 
68
{
 
69
  int i;
 
70
  for (i = 0; in[i]; i++);
 
71
  return i;
 
72
}
 
73
 
 
74
/* Read frequency from a string in MHz and return it in Hz. */
 
75
static grub_uint64_t
 
76
readfrequency (const char *str)
 
77
{
 
78
  grub_uint64_t num = 0;
 
79
  int mul = 1000000;
 
80
  int found = 0;
 
81
 
 
82
  while (*str)
 
83
    {
 
84
      unsigned long digit;
 
85
 
 
86
      digit = grub_tolower (*str) - '0';
 
87
      if (digit > 9)
 
88
        break;
 
89
 
 
90
      found = 1;
 
91
 
 
92
      num = num * 10 + digit;
 
93
      str++;
 
94
    }
 
95
  num *= 1000000;
 
96
  if (*str == '.')
 
97
    {
 
98
      str++;
 
99
      while (*str)
 
100
        {
 
101
          unsigned long digit;
 
102
 
 
103
          digit = grub_tolower (*str) - '0';
 
104
          if (digit > 9)
 
105
            break;
 
106
 
 
107
          found = 1;
 
108
 
 
109
          mul /= 10;
 
110
          num = num + mul * digit;
 
111
          str++;
 
112
        }
 
113
    }
 
114
  if (! found)
 
115
    return 0;
 
116
 
 
117
  return num;
 
118
}
 
119
 
 
120
/* Thanks to Kabyl for precious information about Intel architecture. */
 
121
static grub_uint64_t
 
122
guessfsb (void)
 
123
{
 
124
  const grub_uint64_t sane_value = 100000000;
 
125
  grub_uint32_t manufacturer[3], max_cpuid, capabilities, msrlow;
 
126
  grub_uint64_t start_tsc;
 
127
  grub_uint64_t end_tsc;
 
128
  grub_uint64_t tsc_ticks_per_ms;
 
129
 
 
130
  if (! grub_cpu_is_cpuid_supported ())
 
131
    return sane_value;
 
132
 
 
133
#ifdef APPLE_CC
 
134
  asm volatile ("movl $0, %%eax\n"
 
135
#ifdef __x86_64__
 
136
                "push %%rbx\n"
 
137
#else
 
138
                "push %%ebx\n"
 
139
#endif
 
140
                "cpuid\n"
 
141
#ifdef __x86_64__
 
142
                "pop %%rbx\n"
 
143
#else
 
144
                "pop %%ebx\n"
 
145
#endif
 
146
                : "=a" (max_cpuid),
 
147
                  "=d" (manufacturer[1]), "=c" (manufacturer[2]));
 
148
 
 
149
  /* Only Intel for now is done. */
 
150
  if (grub_memcmp (manufacturer + 1, "ineIntel", 12) != 0)
 
151
    return sane_value;
 
152
 
 
153
#else
 
154
  asm volatile ("movl $0, %%eax\n"
 
155
                "cpuid"
 
156
                : "=a" (max_cpuid), "=b" (manufacturer[0]),
 
157
                  "=d" (manufacturer[1]), "=c" (manufacturer[2]));
 
158
 
 
159
  /* Only Intel for now is done. */
 
160
  if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0)
 
161
    return sane_value;
 
162
#endif
 
163
 
 
164
  /* Check Speedstep. */
 
165
  if (max_cpuid < 1)
 
166
    return sane_value;
 
167
 
 
168
#ifdef APPLE_CC
 
169
  asm volatile ("movl $1, %%eax\n"
 
170
#ifdef __x86_64__
 
171
                "push %%rbx\n"
 
172
#else
 
173
                "push %%ebx\n"
 
174
#endif
 
175
                "cpuid\n"
 
176
#ifdef __x86_64__
 
177
                "pop %%rbx\n"
 
178
#else
 
179
                "pop %%ebx\n"
 
180
#endif
 
181
                : "=c" (capabilities):
 
182
                : "%rax", "%rdx");
 
183
#else
 
184
  asm volatile ("movl $1, %%eax\n"
 
185
                "cpuid"
 
186
                : "=c" (capabilities):
 
187
                : "%rax", "%rbx", "%rdx");
 
188
#endif
 
189
 
 
190
  if (! (capabilities & (1 << 7)))
 
191
    return sane_value;
 
192
 
 
193
  /* Calibrate the TSC rate. */
 
194
 
 
195
  start_tsc = grub_get_tsc ();
 
196
  grub_pit_wait (0xffff);
 
197
  end_tsc = grub_get_tsc ();
 
198
 
 
199
  tsc_ticks_per_ms = grub_divmod64 (end_tsc - start_tsc, 55, 0);
 
200
 
 
201
  /* Read the multiplier. */
 
202
  asm volatile ("movl $0x198, %%ecx\n"
 
203
                "rdmsr"
 
204
                : "=d" (msrlow)
 
205
                :
 
206
                : "%ecx", "%eax");
 
207
 
 
208
  return grub_divmod64 (2000 * tsc_ticks_per_ms,
 
209
                        ((msrlow >> 7) & 0x3e) + ((msrlow >> 14) & 1), 0);
 
210
}
 
211
 
 
212
struct property_descriptor
 
213
{
 
214
  struct property_descriptor *next;
 
215
  grub_uint8_t *name;
 
216
  grub_uint16_t *name16;
 
217
  int name16len;
 
218
  int length;
 
219
  void *data;
 
220
};
 
221
 
 
222
struct grub_xnu_devprop_device_descriptor *devices = 0;
 
223
 
 
224
grub_err_t
 
225
grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev,
 
226
                                  char *name)
 
227
{
 
228
  struct property_descriptor *prop;
 
229
  prop = grub_named_list_find (GRUB_AS_NAMED_LIST_P (&dev->properties), name);
 
230
  if (!prop)
 
231
    return GRUB_ERR_NONE;
 
232
 
 
233
  grub_free (prop->name);
 
234
  grub_free (prop->name16);
 
235
  grub_free (prop->data);
 
236
 
 
237
  grub_list_remove (GRUB_AS_LIST_P (&dev->properties), GRUB_AS_LIST (prop));
 
238
 
 
239
  return GRUB_ERR_NONE;
 
240
}
 
241
 
 
242
grub_err_t
 
243
grub_xnu_devprop_remove_device (struct grub_xnu_devprop_device_descriptor *dev)
 
244
{
 
245
  void *t;
 
246
  struct property_descriptor *prop;
 
247
 
 
248
  grub_list_remove (GRUB_AS_LIST_P (&devices), GRUB_AS_LIST (dev));
 
249
 
 
250
  for (prop = dev->properties; prop; )
 
251
    {
 
252
      grub_free (prop->name);
 
253
      grub_free (prop->name16);
 
254
      grub_free (prop->data);
 
255
      t = prop;
 
256
      prop = prop->next;
 
257
      grub_free (t);
 
258
    }
 
259
 
 
260
  grub_free (dev->path);
 
261
  grub_free (dev);
 
262
 
 
263
  return GRUB_ERR_NONE;
 
264
}
 
265
 
 
266
struct grub_xnu_devprop_device_descriptor *
 
267
grub_xnu_devprop_add_device (struct grub_efi_device_path *path, int length)
 
268
{
 
269
  struct grub_xnu_devprop_device_descriptor *ret;
 
270
 
 
271
  ret = grub_zalloc (sizeof (*ret));
 
272
  if (!ret)
 
273
    return 0;
 
274
 
 
275
  ret->path = grub_malloc (length);
 
276
  if (!ret->path)
 
277
    {
 
278
      grub_free (ret);
 
279
      return 0;
 
280
    }
 
281
  ret->pathlen = length;
 
282
  grub_memcpy (ret->path, path, length);
 
283
 
 
284
  grub_list_push (GRUB_AS_LIST_P (&devices), GRUB_AS_LIST (ret));
 
285
 
 
286
  return ret;
 
287
}
 
288
 
 
289
static grub_err_t
 
290
grub_xnu_devprop_add_property (struct grub_xnu_devprop_device_descriptor *dev,
 
291
                               grub_uint8_t *utf8, grub_uint16_t *utf16,
 
292
                               int utf16len, void *data, int datalen)
 
293
{
 
294
  struct property_descriptor *prop;
 
295
 
 
296
  prop = grub_malloc (sizeof (*prop));
 
297
  if (!prop)
 
298
    return grub_errno;
 
299
 
 
300
  prop->name = utf8;
 
301
  prop->name16 = utf16;
 
302
  prop->name16len = utf16len;
 
303
 
 
304
  prop->length = datalen;
 
305
  prop->data = grub_malloc (prop->length);
 
306
  if (!prop->data)
 
307
    {
 
308
      grub_free (prop);
 
309
      grub_free (prop->name);
 
310
      grub_free (prop->name16);
 
311
      return grub_errno;
 
312
    }
 
313
  grub_memcpy (prop->data, data, prop->length);
 
314
  grub_list_push (GRUB_AS_LIST_P (&dev->properties),
 
315
                  GRUB_AS_LIST (prop));
 
316
  return GRUB_ERR_NONE;
 
317
}
 
318
 
 
319
grub_err_t
 
320
grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev,
 
321
                                    char *name, void *data, int datalen)
 
322
{
 
323
  grub_uint8_t *utf8;
 
324
  grub_uint16_t *utf16;
 
325
  int len, utf16len;
 
326
  grub_err_t err;
 
327
 
 
328
  utf8 = (grub_uint8_t *) grub_strdup (name);
 
329
  if (!utf8)
 
330
    return grub_errno;
 
331
 
 
332
  len = grub_strlen (name);
 
333
  utf16 = grub_malloc (sizeof (grub_uint16_t) * len);
 
334
  if (!utf16)
 
335
    {
 
336
      grub_free (utf8);
 
337
      return grub_errno;
 
338
    }
 
339
 
 
340
  utf16len = grub_utf8_to_utf16 (utf16, len, utf8, len, NULL);
 
341
  if (utf16len < 0)
 
342
    {
 
343
      grub_free (utf8);
 
344
      grub_free (utf16);
 
345
      return grub_errno;
 
346
    }
 
347
 
 
348
  err = grub_xnu_devprop_add_property (dev, utf8, utf16,
 
349
                                       utf16len, data, datalen);
 
350
  if (err)
 
351
    {
 
352
      grub_free (utf8);
 
353
      grub_free (utf16);
 
354
      return err;
 
355
    }
 
356
 
 
357
  return GRUB_ERR_NONE;
 
358
}
 
359
 
 
360
grub_err_t
 
361
grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *dev,
 
362
                                     grub_uint16_t *name, int namelen,
 
363
                                     void *data, int datalen)
 
364
{
 
365
  grub_uint8_t *utf8;
 
366
  grub_uint16_t *utf16;
 
367
  grub_err_t err;
 
368
 
 
369
  utf16 = grub_malloc (sizeof (grub_uint16_t) * namelen);
 
370
  if (!utf16)
 
371
    return grub_errno;
 
372
  grub_memcpy (utf16, name, sizeof (grub_uint16_t) * namelen);
 
373
 
 
374
  utf8 = grub_malloc (namelen * 4 + 1);
 
375
  if (!utf8)
 
376
    {
 
377
      grub_free (utf8);
 
378
      return grub_errno;
 
379
    }
 
380
 
 
381
  *grub_utf16_to_utf8 ((grub_uint8_t *) utf8, name, namelen) = '\0';
 
382
 
 
383
  err = grub_xnu_devprop_add_property (dev, utf8, utf16,
 
384
                                       namelen, data, datalen);
 
385
  if (err)
 
386
    {
 
387
      grub_free (utf8);
 
388
      grub_free (utf16);
 
389
      return err;
 
390
    }
 
391
 
 
392
  return GRUB_ERR_NONE;
 
393
}
 
394
 
 
395
static inline int
 
396
hextoval (char c)
 
397
{
 
398
  if (c >= '0' && c <= '9')
 
399
    return c - '0';
 
400
  if (c >= 'a' && c <= 'z')
 
401
    return c - 'a' + 10;
 
402
  if (c >= 'A' && c <= 'Z')
 
403
    return c - 'A' + 10;
 
404
  return 0;
 
405
}
 
406
 
 
407
void
 
408
grub_cpu_xnu_unload (void)
 
409
{
 
410
  struct grub_xnu_devprop_device_descriptor *dev1, *dev2;
 
411
 
 
412
  for (dev1 = devices; dev1; )
 
413
    {
 
414
      dev2 = dev1->next;
 
415
      grub_xnu_devprop_remove_device (dev1);
 
416
      dev1 = dev2;
 
417
    }
 
418
}
 
419
 
 
420
static grub_err_t
 
421
grub_cpu_xnu_fill_devprop (void)
 
422
{
 
423
  struct grub_xnu_devtree_key *efikey;
 
424
  int total_length = sizeof (struct grub_xnu_devprop_header);
 
425
  struct grub_xnu_devtree_key *devprop;
 
426
  struct grub_xnu_devprop_device_descriptor *device;
 
427
  void *ptr;
 
428
  struct grub_xnu_devprop_header *head;
 
429
  void *t;
 
430
  int numdevs = 0;
 
431
 
 
432
  /* The key "efi". */
 
433
  efikey = grub_xnu_create_key (&grub_xnu_devtree_root, "efi");
 
434
  if (! efikey)
 
435
    return grub_errno;
 
436
 
 
437
  for (device = devices; device; device = device->next)
 
438
    {
 
439
      struct property_descriptor *propdesc;
 
440
      total_length += sizeof (struct grub_xnu_devprop_device_header);
 
441
      total_length += device->pathlen;
 
442
 
 
443
      for (propdesc = device->properties; propdesc; propdesc = propdesc->next)
 
444
        {
 
445
          total_length += sizeof (grub_uint32_t);
 
446
          total_length += sizeof (grub_uint16_t)
 
447
            * (propdesc->name16len + 1);
 
448
          total_length += sizeof (grub_uint32_t);
 
449
          total_length += propdesc->length;
 
450
        }
 
451
      numdevs++;
 
452
    }
 
453
 
 
454
  devprop = grub_xnu_create_value (&(efikey->first_child), "device-properties");
 
455
  if (devprop)
 
456
    {
 
457
      devprop->data = grub_malloc (total_length);
 
458
      devprop->datasize = total_length;
 
459
    }
 
460
 
 
461
  ptr = devprop->data;
 
462
  head = ptr;
 
463
  ptr = head + 1;
 
464
  head->length = total_length;
 
465
  head->alwaysone = 1;
 
466
  head->num_devices = numdevs;
 
467
  for (device = devices; device; )
 
468
    {
 
469
      struct grub_xnu_devprop_device_header *devhead;
 
470
      struct property_descriptor *propdesc;
 
471
      devhead = ptr;
 
472
      devhead->num_values = 0;
 
473
      ptr = devhead + 1;
 
474
 
 
475
      grub_memcpy (ptr, device->path, device->pathlen);
 
476
      ptr = (char *) ptr + device->pathlen;
 
477
 
 
478
      for (propdesc = device->properties; propdesc; )
 
479
        {
 
480
          grub_uint32_t *len;
 
481
          grub_uint16_t *name;
 
482
          void *data;
 
483
 
 
484
          len = ptr;
 
485
          *len = 2 * propdesc->name16len + sizeof (grub_uint16_t)
 
486
            + sizeof (grub_uint32_t);
 
487
          ptr = len + 1;
 
488
 
 
489
          name = ptr;
 
490
          grub_memcpy (name, propdesc->name16, 2 * propdesc->name16len);
 
491
          name += propdesc->name16len;
 
492
 
 
493
          /* NUL terminator.  */
 
494
          *name = 0;
 
495
          ptr = name + 1;
 
496
 
 
497
          len = ptr;
 
498
          *len = propdesc->length + sizeof (grub_uint32_t);
 
499
          data = len + 1;
 
500
          ptr = data;
 
501
          grub_memcpy (ptr, propdesc->data, propdesc->length);
 
502
          ptr = (char *) ptr + propdesc->length;
 
503
 
 
504
          grub_free (propdesc->name);
 
505
          grub_free (propdesc->name16);
 
506
          grub_free (propdesc->data);
 
507
          t = propdesc;
 
508
          propdesc = propdesc->next;
 
509
          grub_free (t);
 
510
          devhead->num_values++;
 
511
        }
 
512
 
 
513
      devhead->length = (char *) ptr - (char *) devhead;
 
514
      t = device;
 
515
      device = device->next;
 
516
      grub_free (t);
 
517
    }
 
518
 
 
519
  devices = 0;
 
520
 
 
521
  return GRUB_ERR_NONE;
 
522
}
 
523
 
 
524
static grub_err_t
 
525
grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)),
 
526
                       int argc, char *args[])
 
527
{
 
528
  grub_file_t file;
 
529
  void *buf, *bufstart, *bufend;
 
530
  struct grub_xnu_devprop_header *head;
 
531
  grub_size_t size;
 
532
  unsigned i, j;
 
533
 
 
534
  if (argc != 1)
 
535
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
 
536
 
 
537
  file = grub_file_open (args[0]);
 
538
  if (! file)
 
539
    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
 
540
                       "couldn't load device-propertie dump");
 
541
  size = grub_file_size (file);
 
542
  buf = grub_malloc (size);
 
543
  if (!buf)
 
544
    {
 
545
      grub_file_close (file);
 
546
      return grub_errno;
 
547
    }
 
548
  if (grub_file_read (file, buf, size) != (grub_ssize_t) size)
 
549
    {
 
550
      grub_file_close (file);
 
551
      return grub_errno;
 
552
    }
 
553
  grub_file_close (file);
 
554
 
 
555
  bufstart = buf;
 
556
  bufend = (char *) buf + size;
 
557
  head = buf;
 
558
  buf = head + 1;
 
559
  for (i = 0; i < grub_le_to_cpu32 (head->num_devices) && buf < bufend; i++)
 
560
    {
 
561
      struct grub_efi_device_path *dp, *dpstart;
 
562
      struct grub_xnu_devprop_device_descriptor *dev;
 
563
      struct grub_xnu_devprop_device_header *devhead;
 
564
 
 
565
      devhead = buf;
 
566
      buf = devhead + 1;
 
567
      dpstart = buf;
 
568
 
 
569
      do
 
570
        {
 
571
          dp = buf;
 
572
          buf = (char *) buf + GRUB_EFI_DEVICE_PATH_LENGTH (dp);
 
573
        }
 
574
      while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp) && buf < bufend);
 
575
 
 
576
      dev = grub_xnu_devprop_add_device (dpstart, (char *) buf
 
577
                                         - (char *) dpstart);
 
578
 
 
579
      for (j = 0; j < grub_le_to_cpu32 (devhead->num_values) && buf < bufend;
 
580
           j++)
 
581
        {
 
582
          grub_uint32_t *namelen;
 
583
          grub_uint32_t *datalen;
 
584
          grub_uint16_t *utf16;
 
585
          void *data;
 
586
          grub_err_t err;
 
587
 
 
588
          namelen = buf;
 
589
          buf = namelen + 1;
 
590
          if (buf >= bufend)
 
591
            break;
 
592
 
 
593
          utf16 = buf;
 
594
          buf = (char *) buf + *namelen - sizeof (grub_uint32_t);
 
595
          if (buf >= bufend)
 
596
            break;
 
597
 
 
598
          datalen = buf;
 
599
          buf = datalen + 1;
 
600
          if (buf >= bufend)
 
601
            break;
 
602
 
 
603
          data = buf;
 
604
          buf = (char *) buf + *datalen - sizeof (grub_uint32_t);
 
605
          if (buf >= bufend)
 
606
            break;
 
607
          err = grub_xnu_devprop_add_property_utf16
 
608
            (dev, utf16, (*namelen - sizeof (grub_uint32_t)
 
609
                          - sizeof (grub_uint16_t)) / sizeof (grub_uint16_t),
 
610
             data, *datalen - sizeof (grub_uint32_t));
 
611
          if (err)
 
612
            {
 
613
              grub_free (bufstart);
 
614
              return err;
 
615
            }
 
616
        }
 
617
    }
 
618
 
 
619
  grub_free (bufstart);
 
620
  return GRUB_ERR_NONE;
 
621
}
 
622
 
 
623
/* Fill device tree. */
 
624
/* FIXME: some entries may be platform-agnostic. Move them to loader/xnu.c. */
 
625
grub_err_t
 
626
grub_cpu_xnu_fill_devicetree (void)
 
627
{
 
628
  struct grub_xnu_devtree_key *efikey;
 
629
  struct grub_xnu_devtree_key *cfgtablekey;
 
630
  struct grub_xnu_devtree_key *curval;
 
631
  struct grub_xnu_devtree_key *runtimesrvkey;
 
632
  struct grub_xnu_devtree_key *platformkey;
 
633
  unsigned i, j;
 
634
 
 
635
  /* The value "model". */
 
636
  /* FIXME: may this value be sometimes different? */
 
637
  curval = grub_xnu_create_value (&grub_xnu_devtree_root, "model");
 
638
  if (! curval)
 
639
    return grub_errno;
 
640
  curval->datasize = sizeof ("ACPI");
 
641
  curval->data = grub_strdup ("ACPI");
 
642
  curval = grub_xnu_create_value (&grub_xnu_devtree_root, "compatible");
 
643
  if (! curval)
 
644
    return grub_errno;
 
645
  curval->datasize = sizeof ("ACPI");
 
646
  curval->data = grub_strdup ("ACPI");
 
647
 
 
648
  /* The key "efi". */
 
649
  efikey = grub_xnu_create_key (&grub_xnu_devtree_root, "efi");
 
650
  if (! efikey)
 
651
    return grub_errno;
 
652
 
 
653
  /* Information about firmware. */
 
654
  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-revision");
 
655
  if (! curval)
 
656
    return grub_errno;
 
657
  curval->datasize = (SYSTEM_TABLE_SIZEOF (firmware_revision));
 
658
  curval->data = grub_malloc (curval->datasize);
 
659
  if (! curval->data)
 
660
    return grub_errno;
 
661
  grub_memcpy (curval->data, (SYSTEM_TABLE_VAR(firmware_revision)),
 
662
               curval->datasize);
 
663
 
 
664
  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-vendor");
 
665
  if (! curval)
 
666
    return grub_errno;
 
667
  curval->datasize =
 
668
    2 * (utf16_strlen (SYSTEM_TABLE_PTR (firmware_vendor)) + 1);
 
669
  curval->data = grub_malloc (curval->datasize);
 
670
  if (! curval->data)
 
671
    return grub_errno;
 
672
  grub_memcpy (curval->data, SYSTEM_TABLE_PTR (firmware_vendor),
 
673
               curval->datasize);
 
674
 
 
675
  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-abi");
 
676
  if (! curval)
 
677
    return grub_errno;
 
678
  curval->datasize = sizeof ("EFI32");
 
679
  curval->data = grub_malloc (curval->datasize);
 
680
  if (! curval->data)
 
681
    return grub_errno;
 
682
  if (SIZEOF_OF_UINTN == 4)
 
683
    grub_memcpy (curval->data, "EFI32", curval->datasize);
 
684
  else
 
685
    grub_memcpy (curval->data, "EFI64", curval->datasize);
 
686
 
 
687
  /* The key "platform". */
 
688
  platformkey = grub_xnu_create_key (&(efikey->first_child),
 
689
                                     "platform");
 
690
  if (! platformkey)
 
691
    return grub_errno;
 
692
 
 
693
  /* Pass FSB frequency to the kernel. */
 
694
  curval = grub_xnu_create_value (&(platformkey->first_child), "FSBFrequency");
 
695
  if (! curval)
 
696
    return grub_errno;
 
697
  curval->datasize = sizeof (grub_uint64_t);
 
698
  curval->data = grub_malloc (curval->datasize);
 
699
  if (!curval->data)
 
700
    return grub_errno;
 
701
 
 
702
  /* First see if user supplies the value. */
 
703
  char *fsbvar = grub_env_get ("fsb");
 
704
  if (! fsbvar)
 
705
    *((grub_uint64_t *) curval->data) = 0;
 
706
  else
 
707
    *((grub_uint64_t *) curval->data) = readfrequency (fsbvar);
 
708
  /* Try autodetect. */
 
709
  if (! *((grub_uint64_t *) curval->data))
 
710
    *((grub_uint64_t *) curval->data) = guessfsb ();
 
711
  grub_dprintf ("xnu", "fsb autodetected as %llu\n",
 
712
                (unsigned long long) *((grub_uint64_t *) curval->data));
 
713
 
 
714
  cfgtablekey = grub_xnu_create_key (&(efikey->first_child),
 
715
                                     "configuration-table");
 
716
  if (!cfgtablekey)
 
717
    return grub_errno;
 
718
 
 
719
  /* Fill "configuration-table" key. */
 
720
  for (i = 0; i < SYSTEM_TABLE (num_table_entries); i++)
 
721
    {
 
722
      void *ptr;
 
723
      struct grub_xnu_devtree_key *curkey;
 
724
      grub_efi_guid_t guid;
 
725
      char guidbuf[64];
 
726
 
 
727
      /* Retrieve current key. */
 
728
#ifdef GRUB_MACHINE_EFI
 
729
      {
 
730
        ptr = (void *)
 
731
          grub_efi_system_table->configuration_table[i].vendor_table;
 
732
        guid = grub_efi_system_table->configuration_table[i].vendor_guid;
 
733
      }
 
734
#else
 
735
      if (SIZEOF_OF_UINTN == 4)
 
736
        {
 
737
          ptr = UINT_TO_PTR (((grub_efiemu_configuration_table32_t *)
 
738
                              SYSTEM_TABLE_PTR (configuration_table))[i]
 
739
                             .vendor_table);
 
740
          guid =
 
741
            ((grub_efiemu_configuration_table32_t *)
 
742
             SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid;
 
743
        }
 
744
      else
 
745
        {
 
746
          ptr = UINT_TO_PTR (((grub_efiemu_configuration_table64_t *)
 
747
                              SYSTEM_TABLE_PTR (configuration_table))[i]
 
748
                             .vendor_table);
 
749
          guid =
 
750
            ((grub_efiemu_configuration_table64_t *)
 
751
             SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid;
 
752
        }
 
753
#endif
 
754
 
 
755
      /* The name of key for new table. */
 
756
      grub_snprintf (guidbuf, sizeof (guidbuf), "%08x-%04x-%04x-%02x%02x-",
 
757
                     guid.data1, guid.data2, guid.data3, guid.data4[0],
 
758
                     guid.data4[1]);
 
759
      for (j = 2; j < 8; j++)
 
760
        grub_snprintf (guidbuf + grub_strlen (guidbuf),
 
761
                       sizeof (guidbuf) - grub_strlen (guidbuf),
 
762
                       "%02x", guid.data4[j]);
 
763
      /* For some reason GUID has to be in uppercase. */
 
764
      for (j = 0; guidbuf[j] ; j++)
 
765
        if (guidbuf[j] >= 'a' && guidbuf[j] <= 'f')
 
766
          guidbuf[j] += 'A' - 'a';
 
767
      curkey = grub_xnu_create_key (&(cfgtablekey->first_child), guidbuf);
 
768
      if (! curkey)
 
769
        return grub_errno;
 
770
 
 
771
      curval = grub_xnu_create_value (&(curkey->first_child), "guid");
 
772
      if (! curval)
 
773
        return grub_errno;
 
774
      curval->datasize = sizeof (guid);
 
775
      curval->data = grub_malloc (curval->datasize);
 
776
      if (! curval->data)
 
777
        return grub_errno;
 
778
      grub_memcpy (curval->data, &guid, curval->datasize);
 
779
 
 
780
      /* The value "table". */
 
781
      curval = grub_xnu_create_value (&(curkey->first_child), "table");
 
782
      if (! curval)
 
783
        return grub_errno;
 
784
      curval->datasize = SIZEOF_OF_UINTN;
 
785
      curval->data = grub_malloc (curval->datasize);
 
786
      if (! curval->data)
 
787
        return grub_errno;
 
788
      if (SIZEOF_OF_UINTN == 4)
 
789
        *((grub_uint32_t *)curval->data) = PTR_TO_UINT32 (ptr);
 
790
      else
 
791
        *((grub_uint64_t *)curval->data) = PTR_TO_UINT64 (ptr);
 
792
 
 
793
      /* Create alias. */
 
794
      for (j = 0; j < sizeof (table_aliases) / sizeof (table_aliases[0]); j++)
 
795
        if (grub_memcmp (&table_aliases[j].guid, &guid, sizeof (guid)) == 0)
 
796
          break;
 
797
      if (j != sizeof (table_aliases) / sizeof (table_aliases[0]))
 
798
        {
 
799
          curval = grub_xnu_create_value (&(curkey->first_child), "alias");
 
800
          if (!curval)
 
801
            return grub_errno;
 
802
          curval->datasize = grub_strlen (table_aliases[j].name) + 1;
 
803
          curval->data = grub_malloc (curval->datasize);
 
804
          if (!curval->data)
 
805
            return grub_errno;
 
806
          grub_memcpy (curval->data, table_aliases[j].name, curval->datasize);
 
807
        }
 
808
    }
 
809
 
 
810
  /* Create and fill "runtime-services" key. */
 
811
  runtimesrvkey = grub_xnu_create_key (&(efikey->first_child),
 
812
                                       "runtime-services");
 
813
  if (! runtimesrvkey)
 
814
    return grub_errno;
 
815
  curval = grub_xnu_create_value (&(runtimesrvkey->first_child), "table");
 
816
  if (! curval)
 
817
    return grub_errno;
 
818
  curval->datasize = SIZEOF_OF_UINTN;
 
819
  curval->data = grub_malloc (curval->datasize);
 
820
  if (! curval->data)
 
821
    return grub_errno;
 
822
  if (SIZEOF_OF_UINTN == 4)
 
823
    *((grub_uint32_t *) curval->data)
 
824
      = PTR_TO_UINT32 (SYSTEM_TABLE_PTR (runtime_services));
 
825
  else
 
826
    *((grub_uint64_t *) curval->data)
 
827
      = PTR_TO_UINT64 (SYSTEM_TABLE_PTR (runtime_services));
 
828
 
 
829
  return GRUB_ERR_NONE;
 
830
}
 
831
 
 
832
grub_err_t
 
833
grub_xnu_boot_resume (void)
 
834
{
 
835
  struct grub_relocator32_state state;
 
836
 
 
837
  state.esp = grub_xnu_stack;
 
838
  state.ebp = grub_xnu_stack;
 
839
  state.eip = grub_xnu_entry_point;
 
840
  state.eax = grub_xnu_arg1;
 
841
 
 
842
  return grub_relocator32_boot (grub_xnu_relocator, state); 
 
843
}
 
844
 
 
845
/* Setup video for xnu. */
 
846
static grub_err_t
 
847
grub_xnu_set_video (struct grub_xnu_boot_params *params)
 
848
{
 
849
  struct grub_video_mode_info mode_info;
 
850
  int ret;
 
851
  char *tmp;
 
852
  const char *modevar;
 
853
  void *framebuffer;
 
854
  grub_err_t err;
 
855
  struct grub_video_bitmap *bitmap = NULL;
 
856
 
 
857
  modevar = grub_env_get ("gfxpayload");
 
858
  /* Consider only graphical 32-bit deep modes.  */
 
859
  if (! modevar || *modevar == 0)
 
860
    err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
 
861
                               GRUB_VIDEO_MODE_TYPE_PURE_TEXT
 
862
                               | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
 
863
                               32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
 
864
  else
 
865
    {
 
866
      tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
 
867
      if (! tmp)
 
868
        return grub_errno;
 
869
      err = grub_video_set_mode (tmp,
 
870
                                 GRUB_VIDEO_MODE_TYPE_PURE_TEXT
 
871
                                 | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
 
872
                                 32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
 
873
      grub_free (tmp);
 
874
    }
 
875
 
 
876
  if (err)
 
877
    return err;
 
878
 
 
879
  ret = grub_video_get_info (&mode_info);
 
880
  if (ret)
 
881
    return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
 
882
 
 
883
  if (grub_xnu_bitmap)
 
884
     {
 
885
       if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH)
 
886
         err = grub_video_bitmap_create_scaled (&bitmap,
 
887
                                                mode_info.width,
 
888
                                                mode_info.height,
 
889
                                                grub_xnu_bitmap,
 
890
                                                GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
 
891
       else
 
892
         bitmap = grub_xnu_bitmap;
 
893
     }
 
894
 
 
895
  if (bitmap)
 
896
    {
 
897
      if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH)
 
898
        err = grub_video_bitmap_create_scaled (&bitmap,
 
899
                                               mode_info.width,
 
900
                                               mode_info.height,
 
901
                                               grub_xnu_bitmap,
 
902
                                               GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
 
903
      else
 
904
        bitmap = grub_xnu_bitmap;
 
905
    }
 
906
 
 
907
  if (bitmap)
 
908
    {
 
909
      int x, y;
 
910
 
 
911
      x = mode_info.width - bitmap->mode_info.width;
 
912
      x /= 2;
 
913
      y = mode_info.height - bitmap->mode_info.height;
 
914
      y /= 2;
 
915
      err = grub_video_blit_bitmap (bitmap,
 
916
                                    GRUB_VIDEO_BLIT_REPLACE,
 
917
                                    x > 0 ? x : 0,
 
918
                                    y > 0 ? y : 0,
 
919
                                    x < 0 ? -x : 0,
 
920
                                    y < 0 ? -y : 0,
 
921
                                    min (bitmap->mode_info.width,
 
922
                                         mode_info.width),
 
923
                                    min (bitmap->mode_info.height,
 
924
                                         mode_info.height));
 
925
    }
 
926
  if (err)
 
927
    {
 
928
      grub_print_error ();
 
929
      grub_errno = GRUB_ERR_NONE;
 
930
      bitmap = 0;
 
931
    }
 
932
 
 
933
  ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
 
934
  if (ret)
 
935
    return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
 
936
 
 
937
  params->lfb_width = mode_info.width;
 
938
  params->lfb_height = mode_info.height;
 
939
  params->lfb_depth = mode_info.bpp;
 
940
  params->lfb_line_len = mode_info.pitch;
 
941
 
 
942
  params->lfb_base = PTR_TO_UINT32 (framebuffer);
 
943
  params->lfb_mode = bitmap ? GRUB_XNU_VIDEO_SPLASH 
 
944
    : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
 
945
 
 
946
  return GRUB_ERR_NONE;
 
947
}
 
948
 
 
949
/* Boot xnu. */
 
950
grub_err_t
 
951
grub_xnu_boot (void)
 
952
{
 
953
  struct grub_xnu_boot_params *bootparams;
 
954
  grub_addr_t bootparams_target;
 
955
  grub_err_t err;
 
956
  grub_efi_uintn_t memory_map_size = 0;
 
957
  grub_efi_memory_descriptor_t *memory_map;
 
958
  grub_addr_t memory_map_target;
 
959
  grub_efi_uintn_t map_key = 0;
 
960
  grub_efi_uintn_t descriptor_size = 0;
 
961
  grub_efi_uint32_t descriptor_version = 0;
 
962
  grub_uint64_t firstruntimepage, lastruntimepage;
 
963
  grub_uint64_t curruntimepage;
 
964
  grub_addr_t devtree_target;
 
965
  grub_size_t devtreelen;
 
966
  int i;
 
967
  struct grub_relocator32_state state;
 
968
 
 
969
  err = grub_autoefi_prepare ();
 
970
  if (err)
 
971
    return err;
 
972
 
 
973
  err = grub_cpu_xnu_fill_devprop ();
 
974
  if (err)
 
975
    return err;
 
976
 
 
977
  err = grub_cpu_xnu_fill_devicetree ();
 
978
  if (err)
 
979
    return err;
 
980
 
 
981
  err = grub_xnu_fill_devicetree ();
 
982
  if (err)
 
983
    return err;
 
984
 
 
985
  /* Page-align to avoid following parts to be inadvertently freed. */
 
986
  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
 
987
  if (err)
 
988
    return err;
 
989
 
 
990
  /* Pass memory map to kernel. */
 
991
  memory_map_size = 0;
 
992
  memory_map = 0;
 
993
  map_key = 0;
 
994
  descriptor_size = 0;
 
995
  descriptor_version = 0;
 
996
 
 
997
  grub_dprintf ("xnu", "eip=%x\n", grub_xnu_entry_point);
 
998
 
 
999
  const char *debug = grub_env_get ("debug");
 
1000
 
 
1001
  if (debug && (grub_strword (debug, "all") || grub_strword (debug, "xnu")))
 
1002
    {
 
1003
      grub_printf ("Press any key to launch xnu\n");
 
1004
      grub_getkey ();
 
1005
    }
 
1006
 
 
1007
  /* Relocate the boot parameters to heap. */
 
1008
  err = grub_xnu_heap_malloc (sizeof (*bootparams),
 
1009
                              (void **) &bootparams, &bootparams_target);
 
1010
  if (err)
 
1011
    return err;
 
1012
 
 
1013
  /* Set video. */
 
1014
  err = grub_xnu_set_video (bootparams);
 
1015
  if (err != GRUB_ERR_NONE)
 
1016
    {
 
1017
      grub_print_error ();
 
1018
      grub_errno = GRUB_ERR_NONE;
 
1019
      grub_printf ("Booting in blind mode\n");
 
1020
 
 
1021
      bootparams->lfb_mode = 0;
 
1022
      bootparams->lfb_width = 0;
 
1023
      bootparams->lfb_height = 0;
 
1024
      bootparams->lfb_depth = 0;
 
1025
      bootparams->lfb_line_len = 0;
 
1026
      bootparams->lfb_base = 0;
 
1027
    }
 
1028
 
 
1029
  if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
 
1030
                                   &map_key, &descriptor_size,
 
1031
                                   &descriptor_version) < 0)
 
1032
    return grub_errno;
 
1033
 
 
1034
  /* We will do few allocations later. Reserve some space for possible
 
1035
     memory map growth.  */
 
1036
  memory_map_size += 20 * descriptor_size;
 
1037
  err = grub_xnu_heap_malloc (memory_map_size,
 
1038
                              (void **) &memory_map, &memory_map_target);
 
1039
  if (err)
 
1040
    return err;
 
1041
 
 
1042
  err = grub_xnu_writetree_toheap (&devtree_target, &devtreelen);
 
1043
  if (err)
 
1044
    return err;
 
1045
 
 
1046
  grub_memcpy (bootparams->cmdline, grub_xnu_cmdline,
 
1047
               sizeof (bootparams->cmdline));
 
1048
 
 
1049
  bootparams->devtree = devtree_target;
 
1050
  bootparams->devtreelen = devtreelen;
 
1051
 
 
1052
  err = grub_autoefi_finish_boot_services (&memory_map_size, memory_map,
 
1053
                                           &map_key, &descriptor_size,
 
1054
                                           &descriptor_version);
 
1055
  if (err)
 
1056
    return err;
 
1057
 
 
1058
  bootparams->efi_system_table = PTR_TO_UINT32 (grub_autoefi_system_table);
 
1059
 
 
1060
  firstruntimepage = (((grub_addr_t) grub_xnu_heap_target_start
 
1061
                       + grub_xnu_heap_size + GRUB_XNU_PAGESIZE - 1)
 
1062
                      / GRUB_XNU_PAGESIZE) + 20;
 
1063
  curruntimepage = firstruntimepage;
 
1064
 
 
1065
  for (i = 0; (unsigned) i < memory_map_size / descriptor_size; i++)
 
1066
    {
 
1067
      grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *)
 
1068
        ((char *) memory_map + descriptor_size * i);
 
1069
 
 
1070
      curdesc->virtual_start = curdesc->physical_start;
 
1071
 
 
1072
      if (curdesc->type == GRUB_EFI_RUNTIME_SERVICES_DATA
 
1073
          || curdesc->type == GRUB_EFI_RUNTIME_SERVICES_CODE)
 
1074
        {
 
1075
          curdesc->virtual_start = curruntimepage << 12;
 
1076
          curruntimepage += curdesc->num_pages;
 
1077
          if (curdesc->physical_start
 
1078
              <= PTR_TO_UINT64 (grub_autoefi_system_table)
 
1079
              && curdesc->physical_start + (curdesc->num_pages << 12)
 
1080
              > PTR_TO_UINT64 (grub_autoefi_system_table))
 
1081
            bootparams->efi_system_table
 
1082
              = PTR_TO_UINT64 (grub_autoefi_system_table)
 
1083
              - curdesc->physical_start + curdesc->virtual_start;
 
1084
          if (SIZEOF_OF_UINTN == 8 && grub_xnu_is_64bit)
 
1085
            curdesc->virtual_start |= 0xffffff8000000000ULL;
 
1086
        }
 
1087
    }
 
1088
 
 
1089
  lastruntimepage = curruntimepage;
 
1090
 
 
1091
  bootparams->efi_mmap = memory_map_target;
 
1092
  bootparams->efi_mmap_size = memory_map_size;
 
1093
  bootparams->efi_mem_desc_size = descriptor_size;
 
1094
  bootparams->efi_mem_desc_version = descriptor_version;
 
1095
 
 
1096
  bootparams->heap_start = grub_xnu_heap_target_start;
 
1097
  bootparams->heap_size = grub_xnu_heap_size;
 
1098
  bootparams->efi_runtime_first_page = firstruntimepage;
 
1099
 
 
1100
  bootparams->efi_runtime_npages = lastruntimepage - firstruntimepage;
 
1101
  bootparams->efi_uintnbits = SIZEOF_OF_UINTN * 8;
 
1102
 
 
1103
  bootparams->verminor = GRUB_XNU_BOOTARGS_VERMINOR;
 
1104
  bootparams->vermajor = GRUB_XNU_BOOTARGS_VERMAJOR;
 
1105
 
 
1106
  /* Parameters for asm helper. */
 
1107
  grub_xnu_stack = bootparams->heap_start
 
1108
    + bootparams->heap_size + GRUB_XNU_PAGESIZE;
 
1109
  grub_xnu_arg1 = bootparams_target;
 
1110
 
 
1111
  grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size,
 
1112
                                        descriptor_version,memory_map);
 
1113
 
 
1114
  state.eip = grub_xnu_entry_point;
 
1115
  state.eax = grub_xnu_arg1;
 
1116
  state.esp = grub_xnu_stack;
 
1117
  state.ebp = grub_xnu_stack;
 
1118
  return grub_relocator32_boot (grub_xnu_relocator, state);
 
1119
}
 
1120
 
 
1121
static grub_command_t cmd_devprop_load;
 
1122
 
 
1123
void
 
1124
grub_cpu_xnu_init (void)
 
1125
{
 
1126
  cmd_devprop_load = grub_register_command ("xnu_devprop_load",
 
1127
                                            grub_cmd_devprop_load,
 
1128
                                            0, N_("Load device-properties dump."));
 
1129
}
 
1130
 
 
1131
void
 
1132
grub_cpu_xnu_fini (void)
 
1133
{
 
1134
  grub_unregister_command (cmd_devprop_load);
 
1135
}