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/>.
20
#include <grub/file.h>
21
#include <grub/disk.h>
23
#include <grub/cpu/xnu.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>
37
#define min(a,b) (((a) < (b)) ? (a) : (b))
38
#define max(a,b) (((a) > (b)) ? (a) : (b))
40
#define DEFAULT_VIDEO_MODE "auto"
42
char grub_xnu_cmdline[1024];
43
grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack;
45
/* Aliases set for some tables. */
52
struct tbl_alias table_aliases[] =
54
{GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI_20"},
55
{GRUB_EFI_ACPI_TABLE_GUID, "ACPI"},
58
struct grub_xnu_devprop_device_descriptor
60
struct grub_xnu_devprop_device_descriptor *next;
61
struct property_descriptor *properties;
62
struct grub_efi_device_path *path;
67
utf16_strlen (grub_uint16_t *in)
70
for (i = 0; in[i]; i++);
74
/* Read frequency from a string in MHz and return it in Hz. */
76
readfrequency (const char *str)
78
grub_uint64_t num = 0;
86
digit = grub_tolower (*str) - '0';
92
num = num * 10 + digit;
103
digit = grub_tolower (*str) - '0';
110
num = num + mul * digit;
120
/* Thanks to Kabyl for precious information about Intel architecture. */
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;
130
if (! grub_cpu_is_cpuid_supported ())
134
asm volatile ("movl $0, %%eax\n"
147
"=d" (manufacturer[1]), "=c" (manufacturer[2]));
149
/* Only Intel for now is done. */
150
if (grub_memcmp (manufacturer + 1, "ineIntel", 12) != 0)
154
asm volatile ("movl $0, %%eax\n"
156
: "=a" (max_cpuid), "=b" (manufacturer[0]),
157
"=d" (manufacturer[1]), "=c" (manufacturer[2]));
159
/* Only Intel for now is done. */
160
if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0)
164
/* Check Speedstep. */
169
asm volatile ("movl $1, %%eax\n"
181
: "=c" (capabilities):
184
asm volatile ("movl $1, %%eax\n"
186
: "=c" (capabilities):
187
: "%rax", "%rbx", "%rdx");
190
if (! (capabilities & (1 << 7)))
193
/* Calibrate the TSC rate. */
195
start_tsc = grub_get_tsc ();
196
grub_pit_wait (0xffff);
197
end_tsc = grub_get_tsc ();
199
tsc_ticks_per_ms = grub_divmod64 (end_tsc - start_tsc, 55, 0);
201
/* Read the multiplier. */
202
asm volatile ("movl $0x198, %%ecx\n"
208
return grub_divmod64 (2000 * tsc_ticks_per_ms,
209
((msrlow >> 7) & 0x3e) + ((msrlow >> 14) & 1), 0);
212
struct property_descriptor
214
struct property_descriptor *next;
216
grub_uint16_t *name16;
222
struct grub_xnu_devprop_device_descriptor *devices = 0;
225
grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev,
228
struct property_descriptor *prop;
229
prop = grub_named_list_find (GRUB_AS_NAMED_LIST_P (&dev->properties), name);
231
return GRUB_ERR_NONE;
233
grub_free (prop->name);
234
grub_free (prop->name16);
235
grub_free (prop->data);
237
grub_list_remove (GRUB_AS_LIST_P (&dev->properties), GRUB_AS_LIST (prop));
239
return GRUB_ERR_NONE;
243
grub_xnu_devprop_remove_device (struct grub_xnu_devprop_device_descriptor *dev)
246
struct property_descriptor *prop;
248
grub_list_remove (GRUB_AS_LIST_P (&devices), GRUB_AS_LIST (dev));
250
for (prop = dev->properties; prop; )
252
grub_free (prop->name);
253
grub_free (prop->name16);
254
grub_free (prop->data);
260
grub_free (dev->path);
263
return GRUB_ERR_NONE;
266
struct grub_xnu_devprop_device_descriptor *
267
grub_xnu_devprop_add_device (struct grub_efi_device_path *path, int length)
269
struct grub_xnu_devprop_device_descriptor *ret;
271
ret = grub_zalloc (sizeof (*ret));
275
ret->path = grub_malloc (length);
281
ret->pathlen = length;
282
grub_memcpy (ret->path, path, length);
284
grub_list_push (GRUB_AS_LIST_P (&devices), GRUB_AS_LIST (ret));
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)
294
struct property_descriptor *prop;
296
prop = grub_malloc (sizeof (*prop));
301
prop->name16 = utf16;
302
prop->name16len = utf16len;
304
prop->length = datalen;
305
prop->data = grub_malloc (prop->length);
309
grub_free (prop->name);
310
grub_free (prop->name16);
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;
320
grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev,
321
char *name, void *data, int datalen)
324
grub_uint16_t *utf16;
328
utf8 = (grub_uint8_t *) grub_strdup (name);
332
len = grub_strlen (name);
333
utf16 = grub_malloc (sizeof (grub_uint16_t) * len);
340
utf16len = grub_utf8_to_utf16 (utf16, len, utf8, len, NULL);
348
err = grub_xnu_devprop_add_property (dev, utf8, utf16,
349
utf16len, data, datalen);
357
return GRUB_ERR_NONE;
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)
366
grub_uint16_t *utf16;
369
utf16 = grub_malloc (sizeof (grub_uint16_t) * namelen);
372
grub_memcpy (utf16, name, sizeof (grub_uint16_t) * namelen);
374
utf8 = grub_malloc (namelen * 4 + 1);
381
*grub_utf16_to_utf8 ((grub_uint8_t *) utf8, name, namelen) = '\0';
383
err = grub_xnu_devprop_add_property (dev, utf8, utf16,
384
namelen, data, datalen);
392
return GRUB_ERR_NONE;
398
if (c >= '0' && c <= '9')
400
if (c >= 'a' && c <= 'z')
402
if (c >= 'A' && c <= 'Z')
408
grub_cpu_xnu_unload (void)
410
struct grub_xnu_devprop_device_descriptor *dev1, *dev2;
412
for (dev1 = devices; dev1; )
415
grub_xnu_devprop_remove_device (dev1);
421
grub_cpu_xnu_fill_devprop (void)
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;
428
struct grub_xnu_devprop_header *head;
433
efikey = grub_xnu_create_key (&grub_xnu_devtree_root, "efi");
437
for (device = devices; device; device = device->next)
439
struct property_descriptor *propdesc;
440
total_length += sizeof (struct grub_xnu_devprop_device_header);
441
total_length += device->pathlen;
443
for (propdesc = device->properties; propdesc; propdesc = propdesc->next)
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;
454
devprop = grub_xnu_create_value (&(efikey->first_child), "device-properties");
457
devprop->data = grub_malloc (total_length);
458
devprop->datasize = total_length;
464
head->length = total_length;
466
head->num_devices = numdevs;
467
for (device = devices; device; )
469
struct grub_xnu_devprop_device_header *devhead;
470
struct property_descriptor *propdesc;
472
devhead->num_values = 0;
475
grub_memcpy (ptr, device->path, device->pathlen);
476
ptr = (char *) ptr + device->pathlen;
478
for (propdesc = device->properties; propdesc; )
485
*len = 2 * propdesc->name16len + sizeof (grub_uint16_t)
486
+ sizeof (grub_uint32_t);
490
grub_memcpy (name, propdesc->name16, 2 * propdesc->name16len);
491
name += propdesc->name16len;
493
/* NUL terminator. */
498
*len = propdesc->length + sizeof (grub_uint32_t);
501
grub_memcpy (ptr, propdesc->data, propdesc->length);
502
ptr = (char *) ptr + propdesc->length;
504
grub_free (propdesc->name);
505
grub_free (propdesc->name16);
506
grub_free (propdesc->data);
508
propdesc = propdesc->next;
510
devhead->num_values++;
513
devhead->length = (char *) ptr - (char *) devhead;
515
device = device->next;
521
return GRUB_ERR_NONE;
525
grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)),
526
int argc, char *args[])
529
void *buf, *bufstart, *bufend;
530
struct grub_xnu_devprop_header *head;
535
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
537
file = grub_file_open (args[0]);
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);
545
grub_file_close (file);
548
if (grub_file_read (file, buf, size) != (grub_ssize_t) size)
550
grub_file_close (file);
553
grub_file_close (file);
556
bufend = (char *) buf + size;
559
for (i = 0; i < grub_le_to_cpu32 (head->num_devices) && buf < bufend; i++)
561
struct grub_efi_device_path *dp, *dpstart;
562
struct grub_xnu_devprop_device_descriptor *dev;
563
struct grub_xnu_devprop_device_header *devhead;
572
buf = (char *) buf + GRUB_EFI_DEVICE_PATH_LENGTH (dp);
574
while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp) && buf < bufend);
576
dev = grub_xnu_devprop_add_device (dpstart, (char *) buf
579
for (j = 0; j < grub_le_to_cpu32 (devhead->num_values) && buf < bufend;
582
grub_uint32_t *namelen;
583
grub_uint32_t *datalen;
584
grub_uint16_t *utf16;
594
buf = (char *) buf + *namelen - sizeof (grub_uint32_t);
604
buf = (char *) buf + *datalen - sizeof (grub_uint32_t);
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));
613
grub_free (bufstart);
619
grub_free (bufstart);
620
return GRUB_ERR_NONE;
623
/* Fill device tree. */
624
/* FIXME: some entries may be platform-agnostic. Move them to loader/xnu.c. */
626
grub_cpu_xnu_fill_devicetree (void)
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;
635
/* The value "model". */
636
/* FIXME: may this value be sometimes different? */
637
curval = grub_xnu_create_value (&grub_xnu_devtree_root, "model");
640
curval->datasize = sizeof ("ACPI");
641
curval->data = grub_strdup ("ACPI");
642
curval = grub_xnu_create_value (&grub_xnu_devtree_root, "compatible");
645
curval->datasize = sizeof ("ACPI");
646
curval->data = grub_strdup ("ACPI");
649
efikey = grub_xnu_create_key (&grub_xnu_devtree_root, "efi");
653
/* Information about firmware. */
654
curval = grub_xnu_create_value (&(efikey->first_child), "firmware-revision");
657
curval->datasize = (SYSTEM_TABLE_SIZEOF (firmware_revision));
658
curval->data = grub_malloc (curval->datasize);
661
grub_memcpy (curval->data, (SYSTEM_TABLE_VAR(firmware_revision)),
664
curval = grub_xnu_create_value (&(efikey->first_child), "firmware-vendor");
668
2 * (utf16_strlen (SYSTEM_TABLE_PTR (firmware_vendor)) + 1);
669
curval->data = grub_malloc (curval->datasize);
672
grub_memcpy (curval->data, SYSTEM_TABLE_PTR (firmware_vendor),
675
curval = grub_xnu_create_value (&(efikey->first_child), "firmware-abi");
678
curval->datasize = sizeof ("EFI32");
679
curval->data = grub_malloc (curval->datasize);
682
if (SIZEOF_OF_UINTN == 4)
683
grub_memcpy (curval->data, "EFI32", curval->datasize);
685
grub_memcpy (curval->data, "EFI64", curval->datasize);
687
/* The key "platform". */
688
platformkey = grub_xnu_create_key (&(efikey->first_child),
693
/* Pass FSB frequency to the kernel. */
694
curval = grub_xnu_create_value (&(platformkey->first_child), "FSBFrequency");
697
curval->datasize = sizeof (grub_uint64_t);
698
curval->data = grub_malloc (curval->datasize);
702
/* First see if user supplies the value. */
703
char *fsbvar = grub_env_get ("fsb");
705
*((grub_uint64_t *) curval->data) = 0;
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));
714
cfgtablekey = grub_xnu_create_key (&(efikey->first_child),
715
"configuration-table");
719
/* Fill "configuration-table" key. */
720
for (i = 0; i < SYSTEM_TABLE (num_table_entries); i++)
723
struct grub_xnu_devtree_key *curkey;
724
grub_efi_guid_t guid;
727
/* Retrieve current key. */
728
#ifdef GRUB_MACHINE_EFI
731
grub_efi_system_table->configuration_table[i].vendor_table;
732
guid = grub_efi_system_table->configuration_table[i].vendor_guid;
735
if (SIZEOF_OF_UINTN == 4)
737
ptr = UINT_TO_PTR (((grub_efiemu_configuration_table32_t *)
738
SYSTEM_TABLE_PTR (configuration_table))[i]
741
((grub_efiemu_configuration_table32_t *)
742
SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid;
746
ptr = UINT_TO_PTR (((grub_efiemu_configuration_table64_t *)
747
SYSTEM_TABLE_PTR (configuration_table))[i]
750
((grub_efiemu_configuration_table64_t *)
751
SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid;
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],
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);
771
curval = grub_xnu_create_value (&(curkey->first_child), "guid");
774
curval->datasize = sizeof (guid);
775
curval->data = grub_malloc (curval->datasize);
778
grub_memcpy (curval->data, &guid, curval->datasize);
780
/* The value "table". */
781
curval = grub_xnu_create_value (&(curkey->first_child), "table");
784
curval->datasize = SIZEOF_OF_UINTN;
785
curval->data = grub_malloc (curval->datasize);
788
if (SIZEOF_OF_UINTN == 4)
789
*((grub_uint32_t *)curval->data) = PTR_TO_UINT32 (ptr);
791
*((grub_uint64_t *)curval->data) = PTR_TO_UINT64 (ptr);
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)
797
if (j != sizeof (table_aliases) / sizeof (table_aliases[0]))
799
curval = grub_xnu_create_value (&(curkey->first_child), "alias");
802
curval->datasize = grub_strlen (table_aliases[j].name) + 1;
803
curval->data = grub_malloc (curval->datasize);
806
grub_memcpy (curval->data, table_aliases[j].name, curval->datasize);
810
/* Create and fill "runtime-services" key. */
811
runtimesrvkey = grub_xnu_create_key (&(efikey->first_child),
815
curval = grub_xnu_create_value (&(runtimesrvkey->first_child), "table");
818
curval->datasize = SIZEOF_OF_UINTN;
819
curval->data = grub_malloc (curval->datasize);
822
if (SIZEOF_OF_UINTN == 4)
823
*((grub_uint32_t *) curval->data)
824
= PTR_TO_UINT32 (SYSTEM_TABLE_PTR (runtime_services));
826
*((grub_uint64_t *) curval->data)
827
= PTR_TO_UINT64 (SYSTEM_TABLE_PTR (runtime_services));
829
return GRUB_ERR_NONE;
833
grub_xnu_boot_resume (void)
835
struct grub_relocator32_state state;
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;
842
return grub_relocator32_boot (grub_xnu_relocator, state);
845
/* Setup video for xnu. */
847
grub_xnu_set_video (struct grub_xnu_boot_params *params)
849
struct grub_video_mode_info mode_info;
855
struct grub_video_bitmap *bitmap = NULL;
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);
866
tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
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);
879
ret = grub_video_get_info (&mode_info);
881
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
885
if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH)
886
err = grub_video_bitmap_create_scaled (&bitmap,
890
GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
892
bitmap = grub_xnu_bitmap;
897
if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH)
898
err = grub_video_bitmap_create_scaled (&bitmap,
902
GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
904
bitmap = grub_xnu_bitmap;
911
x = mode_info.width - bitmap->mode_info.width;
913
y = mode_info.height - bitmap->mode_info.height;
915
err = grub_video_blit_bitmap (bitmap,
916
GRUB_VIDEO_BLIT_REPLACE,
921
min (bitmap->mode_info.width,
923
min (bitmap->mode_info.height,
929
grub_errno = GRUB_ERR_NONE;
933
ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
935
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
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;
942
params->lfb_base = PTR_TO_UINT32 (framebuffer);
943
params->lfb_mode = bitmap ? GRUB_XNU_VIDEO_SPLASH
944
: GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
946
return GRUB_ERR_NONE;
953
struct grub_xnu_boot_params *bootparams;
954
grub_addr_t bootparams_target;
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;
967
struct grub_relocator32_state state;
969
err = grub_autoefi_prepare ();
973
err = grub_cpu_xnu_fill_devprop ();
977
err = grub_cpu_xnu_fill_devicetree ();
981
err = grub_xnu_fill_devicetree ();
985
/* Page-align to avoid following parts to be inadvertently freed. */
986
err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
990
/* Pass memory map to kernel. */
995
descriptor_version = 0;
997
grub_dprintf ("xnu", "eip=%x\n", grub_xnu_entry_point);
999
const char *debug = grub_env_get ("debug");
1001
if (debug && (grub_strword (debug, "all") || grub_strword (debug, "xnu")))
1003
grub_printf ("Press any key to launch xnu\n");
1007
/* Relocate the boot parameters to heap. */
1008
err = grub_xnu_heap_malloc (sizeof (*bootparams),
1009
(void **) &bootparams, &bootparams_target);
1014
err = grub_xnu_set_video (bootparams);
1015
if (err != GRUB_ERR_NONE)
1017
grub_print_error ();
1018
grub_errno = GRUB_ERR_NONE;
1019
grub_printf ("Booting in blind mode\n");
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;
1029
if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
1030
&map_key, &descriptor_size,
1031
&descriptor_version) < 0)
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);
1042
err = grub_xnu_writetree_toheap (&devtree_target, &devtreelen);
1046
grub_memcpy (bootparams->cmdline, grub_xnu_cmdline,
1047
sizeof (bootparams->cmdline));
1049
bootparams->devtree = devtree_target;
1050
bootparams->devtreelen = devtreelen;
1052
err = grub_autoefi_finish_boot_services (&memory_map_size, memory_map,
1053
&map_key, &descriptor_size,
1054
&descriptor_version);
1058
bootparams->efi_system_table = PTR_TO_UINT32 (grub_autoefi_system_table);
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;
1065
for (i = 0; (unsigned) i < memory_map_size / descriptor_size; i++)
1067
grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *)
1068
((char *) memory_map + descriptor_size * i);
1070
curdesc->virtual_start = curdesc->physical_start;
1072
if (curdesc->type == GRUB_EFI_RUNTIME_SERVICES_DATA
1073
|| curdesc->type == GRUB_EFI_RUNTIME_SERVICES_CODE)
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;
1089
lastruntimepage = curruntimepage;
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;
1096
bootparams->heap_start = grub_xnu_heap_target_start;
1097
bootparams->heap_size = grub_xnu_heap_size;
1098
bootparams->efi_runtime_first_page = firstruntimepage;
1100
bootparams->efi_runtime_npages = lastruntimepage - firstruntimepage;
1101
bootparams->efi_uintnbits = SIZEOF_OF_UINTN * 8;
1103
bootparams->verminor = GRUB_XNU_BOOTARGS_VERMINOR;
1104
bootparams->vermajor = GRUB_XNU_BOOTARGS_VERMAJOR;
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;
1111
grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size,
1112
descriptor_version,memory_map);
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);
1121
static grub_command_t cmd_devprop_load;
1124
grub_cpu_xnu_init (void)
1126
cmd_devprop_load = grub_register_command ("xnu_devprop_load",
1127
grub_cmd_devprop_load,
1128
0, N_("Load device-properties dump."));
1132
grub_cpu_xnu_fini (void)
1134
grub_unregister_command (cmd_devprop_load);