~darkmuggle-deactivatedaccount/ubuntu/quantal/grub2/fix-872244

« back to all changes in this revision

Viewing changes to grub-core/kern/efi/efi.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* efi.c - generic EFI support */
 
2
/*
 
3
 *  GRUB  --  GRand Unified Bootloader
 
4
 *  Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
 
5
 *
 
6
 *  GRUB is free software: you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation, either version 3 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  GRUB is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include <grub/misc.h>
 
21
#include <grub/charset.h>
 
22
#include <grub/efi/api.h>
 
23
#include <grub/efi/efi.h>
 
24
#include <grub/efi/console_control.h>
 
25
#include <grub/efi/pe32.h>
 
26
#include <grub/machine/time.h>
 
27
#include <grub/term.h>
 
28
#include <grub/kernel.h>
 
29
#include <grub/mm.h>
 
30
 
 
31
/* The handle of GRUB itself. Filled in by the startup code.  */
 
32
grub_efi_handle_t grub_efi_image_handle;
 
33
 
 
34
/* The pointer to a system table. Filled in by the startup code.  */
 
35
grub_efi_system_table_t *grub_efi_system_table;
 
36
 
 
37
static grub_efi_guid_t console_control_guid = GRUB_EFI_CONSOLE_CONTROL_GUID;
 
38
static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID;
 
39
static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
 
40
 
 
41
void *
 
42
grub_efi_locate_protocol (grub_efi_guid_t *protocol, void *registration)
 
43
{
 
44
  void *interface;
 
45
  grub_efi_status_t status;
 
46
 
 
47
  status = efi_call_3 (grub_efi_system_table->boot_services->locate_protocol,
 
48
                       protocol, registration, &interface);
 
49
  if (status != GRUB_EFI_SUCCESS)
 
50
    return 0;
 
51
 
 
52
  return interface;
 
53
}
 
54
 
 
55
/* Return the array of handles which meet the requirement. If successful,
 
56
   the number of handles is stored in NUM_HANDLES. The array is allocated
 
57
   from the heap.  */
 
58
grub_efi_handle_t *
 
59
grub_efi_locate_handle (grub_efi_locate_search_type_t search_type,
 
60
                        grub_efi_guid_t *protocol,
 
61
                        void *search_key,
 
62
                        grub_efi_uintn_t *num_handles)
 
63
{
 
64
  grub_efi_boot_services_t *b;
 
65
  grub_efi_status_t status;
 
66
  grub_efi_handle_t *buffer;
 
67
  grub_efi_uintn_t buffer_size = 8 * sizeof (grub_efi_handle_t);
 
68
 
 
69
  buffer = grub_malloc (buffer_size);
 
70
  if (! buffer)
 
71
    return 0;
 
72
 
 
73
  b = grub_efi_system_table->boot_services;
 
74
  status = efi_call_5 (b->locate_handle, search_type, protocol, search_key,
 
75
                             &buffer_size, buffer);
 
76
  if (status == GRUB_EFI_BUFFER_TOO_SMALL)
 
77
    {
 
78
      grub_free (buffer);
 
79
      buffer = grub_malloc (buffer_size);
 
80
      if (! buffer)
 
81
        return 0;
 
82
 
 
83
      status = efi_call_5 (b->locate_handle, search_type, protocol, search_key,
 
84
                                 &buffer_size, buffer);
 
85
    }
 
86
 
 
87
  if (status != GRUB_EFI_SUCCESS)
 
88
    {
 
89
      grub_free (buffer);
 
90
      return 0;
 
91
    }
 
92
 
 
93
  *num_handles = buffer_size / sizeof (grub_efi_handle_t);
 
94
  return buffer;
 
95
}
 
96
 
 
97
void *
 
98
grub_efi_open_protocol (grub_efi_handle_t handle,
 
99
                        grub_efi_guid_t *protocol,
 
100
                        grub_efi_uint32_t attributes)
 
101
{
 
102
  grub_efi_boot_services_t *b;
 
103
  grub_efi_status_t status;
 
104
  void *interface;
 
105
 
 
106
  b = grub_efi_system_table->boot_services;
 
107
  status = efi_call_6 (b->open_protocol, handle,
 
108
                       protocol,
 
109
                       &interface,
 
110
                       grub_efi_image_handle,
 
111
                       0,
 
112
                       attributes);
 
113
  if (status != GRUB_EFI_SUCCESS)
 
114
    return 0;
 
115
 
 
116
  return interface;
 
117
}
 
118
 
 
119
int
 
120
grub_efi_set_text_mode (int on)
 
121
{
 
122
  grub_efi_console_control_protocol_t *c;
 
123
  grub_efi_screen_mode_t mode, new_mode;
 
124
 
 
125
  c = grub_efi_locate_protocol (&console_control_guid, 0);
 
126
  if (! c)
 
127
    /* No console control protocol instance available, assume it is
 
128
       already in text mode. */
 
129
    return 1;
 
130
 
 
131
  if (efi_call_4 (c->get_mode, c, &mode, 0, 0) != GRUB_EFI_SUCCESS)
 
132
    return 0;
 
133
 
 
134
  new_mode = on ? GRUB_EFI_SCREEN_TEXT : GRUB_EFI_SCREEN_GRAPHICS;
 
135
  if (mode != new_mode)
 
136
    if (efi_call_2 (c->set_mode, c, new_mode) != GRUB_EFI_SUCCESS)
 
137
      return 0;
 
138
 
 
139
  return 1;
 
140
}
 
141
 
 
142
void
 
143
grub_efi_stall (grub_efi_uintn_t microseconds)
 
144
{
 
145
  efi_call_1 (grub_efi_system_table->boot_services->stall, microseconds);
 
146
}
 
147
 
 
148
grub_efi_loaded_image_t *
 
149
grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
 
150
{
 
151
  return grub_efi_open_protocol (image_handle,
 
152
                                 &loaded_image_guid,
 
153
                                 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
 
154
}
 
155
 
 
156
void
 
157
grub_exit (void)
 
158
{
 
159
  grub_efi_fini ();
 
160
  efi_call_4 (grub_efi_system_table->boot_services->exit,
 
161
              grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0);
 
162
  for (;;) ;
 
163
}
 
164
 
 
165
/* On i386, a firmware-independant grub_reboot() is provided by realmode.S.  */
 
166
#ifndef __i386__
 
167
void
 
168
grub_reboot (void)
 
169
{
 
170
  grub_efi_fini ();
 
171
  efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
 
172
              GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
 
173
  for (;;) ;
 
174
}
 
175
#endif
 
176
 
 
177
grub_err_t
 
178
grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
 
179
                                  grub_efi_uintn_t descriptor_size,
 
180
                                  grub_efi_uint32_t descriptor_version,
 
181
                                  grub_efi_memory_descriptor_t *virtual_map)
 
182
{
 
183
  grub_efi_runtime_services_t *r;
 
184
  grub_efi_status_t status;
 
185
 
 
186
  r = grub_efi_system_table->runtime_services;
 
187
  status = efi_call_4 (r->set_virtual_address_map, memory_map_size,
 
188
                       descriptor_size, descriptor_version, virtual_map);
 
189
 
 
190
  if (status == GRUB_EFI_SUCCESS)
 
191
    return GRUB_ERR_NONE;
 
192
 
 
193
  return grub_error (GRUB_ERR_IO, "set_virtual_address_map failed");
 
194
}
 
195
 
 
196
grub_uint32_t
 
197
grub_get_rtc (void)
 
198
{
 
199
  grub_efi_time_t time;
 
200
  grub_efi_runtime_services_t *r;
 
201
 
 
202
  r = grub_efi_system_table->runtime_services;
 
203
  if (efi_call_2 (r->get_time, &time, 0) != GRUB_EFI_SUCCESS)
 
204
    /* What is possible in this case?  */
 
205
    return 0;
 
206
 
 
207
  return (((time.minute * 60 + time.second) * 1000
 
208
           + time.nanosecond / 1000000)
 
209
          * GRUB_TICKS_PER_SECOND / 1000);
 
210
}
 
211
 
 
212
/* Search the mods section from the PE32/PE32+ image. This code uses
 
213
   a PE32 header, but should work with PE32+ as well.  */
 
214
grub_addr_t
 
215
grub_arch_modules_addr (void)
 
216
{
 
217
  grub_efi_loaded_image_t *image;
 
218
  struct grub_pe32_header *header;
 
219
  struct grub_pe32_coff_header *coff_header;
 
220
  struct grub_pe32_section_table *sections;
 
221
  struct grub_pe32_section_table *section;
 
222
  struct grub_module_info *info;
 
223
  grub_uint16_t i;
 
224
 
 
225
  image = grub_efi_get_loaded_image (grub_efi_image_handle);
 
226
  if (! image)
 
227
    return 0;
 
228
 
 
229
  header = image->image_base;
 
230
  coff_header = &(header->coff_header);
 
231
  sections
 
232
    = (struct grub_pe32_section_table *) ((char *) coff_header
 
233
                                          + sizeof (*coff_header)
 
234
                                          + coff_header->optional_header_size);
 
235
 
 
236
  for (i = 0, section = sections;
 
237
       i < coff_header->num_sections;
 
238
       i++, section++)
 
239
    {
 
240
      if (grub_strcmp (section->name, "mods") == 0)
 
241
        break;
 
242
    }
 
243
 
 
244
  if (i == coff_header->num_sections)
 
245
    return 0;
 
246
 
 
247
  info = (struct grub_module_info *) ((char *) image->image_base
 
248
                                      + section->virtual_address);
 
249
  if (info->magic != GRUB_MODULE_MAGIC)
 
250
    return 0;
 
251
 
 
252
  return (grub_addr_t) info;
 
253
}
 
254
 
 
255
char *
 
256
grub_efi_get_filename (grub_efi_device_path_t *dp)
 
257
{
 
258
  char *name = 0;
 
259
 
 
260
  while (1)
 
261
    {
 
262
      grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
 
263
      grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
 
264
 
 
265
      if (type == GRUB_EFI_END_DEVICE_PATH_TYPE)
 
266
        break;
 
267
      else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
 
268
               && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
 
269
        {
 
270
          grub_efi_file_path_device_path_t *fp;
 
271
          grub_efi_uint16_t len;
 
272
          char *p;
 
273
          grub_size_t size;
 
274
 
 
275
          if (name)
 
276
            {
 
277
              size = grub_strlen (name);
 
278
              name[size] = '/';
 
279
              size++;
 
280
            }
 
281
          else
 
282
            size = 0;
 
283
 
 
284
          len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
 
285
                 / sizeof (grub_efi_char16_t));
 
286
          p = grub_realloc (name, size + len * 4 + 1);
 
287
          if (! p)
 
288
            {
 
289
              grub_free (name);
 
290
              return 0;
 
291
            }
 
292
 
 
293
          name = p;
 
294
          fp = (grub_efi_file_path_device_path_t *) dp;
 
295
          *grub_utf16_to_utf8 ((grub_uint8_t *) name + size,
 
296
                               fp->path_name, len) = '\0';
 
297
        }
 
298
 
 
299
      dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
 
300
    }
 
301
 
 
302
  if (name)
 
303
    {
 
304
      /* EFI breaks paths with backslashes.  */
 
305
      char *p;
 
306
 
 
307
      for (p = name; *p; p++)
 
308
        if (*p == '\\')
 
309
          *p = '/';
 
310
    }
 
311
 
 
312
  return name;
 
313
}
 
314
 
 
315
grub_efi_device_path_t *
 
316
grub_efi_get_device_path (grub_efi_handle_t handle)
 
317
{
 
318
  return grub_efi_open_protocol (handle, &device_path_guid,
 
319
                                 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
 
320
}
 
321
 
 
322
/* Print the chain of Device Path nodes. This is mainly for debugging. */
 
323
void
 
324
grub_efi_print_device_path (grub_efi_device_path_t *dp)
 
325
{
 
326
  while (1)
 
327
    {
 
328
      grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
 
329
      grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
 
330
      grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
 
331
 
 
332
      switch (type)
 
333
        {
 
334
        case GRUB_EFI_END_DEVICE_PATH_TYPE:
 
335
          switch (subtype)
 
336
            {
 
337
            case GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE:
 
338
              grub_printf ("/EndEntire\n");
 
339
              //grub_putchar ('\n');
 
340
              break;
 
341
            case GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE:
 
342
              grub_printf ("/EndThis\n");
 
343
              //grub_putchar ('\n');
 
344
              break;
 
345
            default:
 
346
              grub_printf ("/EndUnknown(%x)\n", (unsigned) subtype);
 
347
              break;
 
348
            }
 
349
          break;
 
350
 
 
351
        case GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE:
 
352
          switch (subtype)
 
353
            {
 
354
            case GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE:
 
355
              {
 
356
                grub_efi_pci_device_path_t pci;
 
357
                grub_memcpy (&pci, dp, len);
 
358
                grub_printf ("/PCI(%x,%x)",
 
359
                             (unsigned) pci.function, (unsigned) pci.device);
 
360
              }
 
361
              break;
 
362
            case GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE:
 
363
              {
 
364
                grub_efi_pccard_device_path_t pccard;
 
365
                grub_memcpy (&pccard, dp, len);
 
366
                grub_printf ("/PCCARD(%x)",
 
367
                             (unsigned) pccard.function);
 
368
              }
 
369
              break;
 
370
            case GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE:
 
371
              {
 
372
                grub_efi_memory_mapped_device_path_t mmapped;
 
373
                grub_memcpy (&mmapped, dp, len);
 
374
                grub_printf ("/MMap(%x,%llx,%llx)",
 
375
                             (unsigned) mmapped.memory_type,
 
376
                             (unsigned long long) mmapped.start_address,
 
377
                             (unsigned long long) mmapped.end_address);
 
378
              }
 
379
              break;
 
380
            case GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE:
 
381
              {
 
382
                grub_efi_vendor_device_path_t vendor;
 
383
                grub_memcpy (&vendor, dp, sizeof (vendor));
 
384
                grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
 
385
                             (unsigned) vendor.vendor_guid.data1,
 
386
                             (unsigned) vendor.vendor_guid.data2,
 
387
                             (unsigned) vendor.vendor_guid.data3,
 
388
                             (unsigned) vendor.vendor_guid.data4[0],
 
389
                             (unsigned) vendor.vendor_guid.data4[1],
 
390
                             (unsigned) vendor.vendor_guid.data4[2],
 
391
                             (unsigned) vendor.vendor_guid.data4[3],
 
392
                             (unsigned) vendor.vendor_guid.data4[4],
 
393
                             (unsigned) vendor.vendor_guid.data4[5],
 
394
                             (unsigned) vendor.vendor_guid.data4[6],
 
395
                             (unsigned) vendor.vendor_guid.data4[7]);
 
396
              }
 
397
              break;
 
398
            case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE:
 
399
              {
 
400
                grub_efi_controller_device_path_t controller;
 
401
                grub_memcpy (&controller, dp, len);
 
402
                grub_printf ("/Ctrl(%x)",
 
403
                             (unsigned) controller.controller_number);
 
404
              }
 
405
              break;
 
406
            default:
 
407
              grub_printf ("/UnknownHW(%x)", (unsigned) subtype);
 
408
              break;
 
409
            }
 
410
          break;
 
411
 
 
412
        case GRUB_EFI_ACPI_DEVICE_PATH_TYPE:
 
413
          switch (subtype)
 
414
            {
 
415
            case GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE:
 
416
              {
 
417
                grub_efi_acpi_device_path_t acpi;
 
418
                grub_memcpy (&acpi, dp, len);
 
419
                grub_printf ("/ACPI(%x,%x)",
 
420
                             (unsigned) acpi.hid,
 
421
                             (unsigned) acpi.uid);
 
422
              }
 
423
              break;
 
424
            case GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE:
 
425
              {
 
426
                grub_efi_expanded_acpi_device_path_t eacpi;
 
427
                grub_memcpy (&eacpi, dp, sizeof (eacpi));
 
428
                grub_printf ("/ACPI(");
 
429
 
 
430
                if (GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp)[0] == '\0')
 
431
                  grub_printf ("%x,", (unsigned) eacpi.hid);
 
432
                else
 
433
                  grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp));
 
434
 
 
435
                if (GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp)[0] == '\0')
 
436
                  grub_printf ("%x,", (unsigned) eacpi.uid);
 
437
                else
 
438
                  grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp));
 
439
 
 
440
                if (GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp)[0] == '\0')
 
441
                  grub_printf ("%x)", (unsigned) eacpi.cid);
 
442
                else
 
443
                  grub_printf ("%s)", GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp));
 
444
              }
 
445
              break;
 
446
            default:
 
447
              grub_printf ("/UnknownACPI(%x)", (unsigned) subtype);
 
448
              break;
 
449
            }
 
450
          break;
 
451
 
 
452
        case GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE:
 
453
          switch (subtype)
 
454
            {
 
455
            case GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE:
 
456
              {
 
457
                grub_efi_atapi_device_path_t atapi;
 
458
                grub_memcpy (&atapi, dp, len);
 
459
                grub_printf ("/ATAPI(%x,%x,%x)",
 
460
                             (unsigned) atapi.primary_secondary,
 
461
                             (unsigned) atapi.slave_master,
 
462
                             (unsigned) atapi.lun);
 
463
              }
 
464
              break;
 
465
            case GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE:
 
466
              {
 
467
                grub_efi_scsi_device_path_t scsi;
 
468
                grub_memcpy (&scsi, dp, len);
 
469
                grub_printf ("/SCSI(%x,%x)",
 
470
                             (unsigned) scsi.pun,
 
471
                             (unsigned) scsi.lun);
 
472
              }
 
473
              break;
 
474
            case GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE:
 
475
              {
 
476
                grub_efi_fibre_channel_device_path_t fc;
 
477
                grub_memcpy (&fc, dp, len);
 
478
                grub_printf ("/FibreChannel(%llx,%llx)",
 
479
                             (unsigned long long) fc.wwn,
 
480
                             (unsigned long long) fc.lun);
 
481
              }
 
482
              break;
 
483
            case GRUB_EFI_1394_DEVICE_PATH_SUBTYPE:
 
484
              {
 
485
                grub_efi_1394_device_path_t firewire;
 
486
                grub_memcpy (&firewire, dp, len);
 
487
                grub_printf ("/1394(%llx)", (unsigned long long) firewire.guid);
 
488
              }
 
489
              break;
 
490
            case GRUB_EFI_USB_DEVICE_PATH_SUBTYPE:
 
491
              {
 
492
                grub_efi_usb_device_path_t usb;
 
493
                grub_memcpy (&usb, dp, len);
 
494
                grub_printf ("/USB(%x,%x)",
 
495
                             (unsigned) usb.parent_port_number,
 
496
                             (unsigned) usb.interface);
 
497
              }
 
498
              break;
 
499
            case GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE:
 
500
              {
 
501
                grub_efi_usb_class_device_path_t usb_class;
 
502
                grub_memcpy (&usb_class, dp, len);
 
503
                grub_printf ("/USBClass(%x,%x,%x,%x,%x)",
 
504
                             (unsigned) usb_class.vendor_id,
 
505
                             (unsigned) usb_class.product_id,
 
506
                             (unsigned) usb_class.device_class,
 
507
                             (unsigned) usb_class.device_subclass,
 
508
                             (unsigned) usb_class.device_protocol);
 
509
              }
 
510
              break;
 
511
            case GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE:
 
512
              {
 
513
                grub_efi_i2o_device_path_t i2o;
 
514
                grub_memcpy (&i2o, dp, len);
 
515
                grub_printf ("/I2O(%x)", (unsigned) i2o.tid);
 
516
              }
 
517
              break;
 
518
            case GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE:
 
519
              {
 
520
                grub_efi_mac_address_device_path_t mac;
 
521
                grub_memcpy (&mac, dp, len);
 
522
                grub_printf ("/MacAddr(%02x:%02x:%02x:%02x:%02x:%02x,%x)",
 
523
                             (unsigned) mac.mac_address[0],
 
524
                             (unsigned) mac.mac_address[1],
 
525
                             (unsigned) mac.mac_address[2],
 
526
                             (unsigned) mac.mac_address[3],
 
527
                             (unsigned) mac.mac_address[4],
 
528
                             (unsigned) mac.mac_address[5],
 
529
                             (unsigned) mac.if_type);
 
530
              }
 
531
              break;
 
532
            case GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE:
 
533
              {
 
534
                grub_efi_ipv4_device_path_t ipv4;
 
535
                grub_memcpy (&ipv4, dp, len);
 
536
                grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x)",
 
537
                             (unsigned) ipv4.local_ip_address[0],
 
538
                             (unsigned) ipv4.local_ip_address[1],
 
539
                             (unsigned) ipv4.local_ip_address[2],
 
540
                             (unsigned) ipv4.local_ip_address[3],
 
541
                             (unsigned) ipv4.remote_ip_address[0],
 
542
                             (unsigned) ipv4.remote_ip_address[1],
 
543
                             (unsigned) ipv4.remote_ip_address[2],
 
544
                             (unsigned) ipv4.remote_ip_address[3],
 
545
                             (unsigned) ipv4.local_port,
 
546
                             (unsigned) ipv4.remote_port,
 
547
                             (unsigned) ipv4.protocol,
 
548
                             (unsigned) ipv4.static_ip_address);
 
549
              }
 
550
              break;
 
551
            case GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE:
 
552
              {
 
553
                grub_efi_ipv6_device_path_t ipv6;
 
554
                grub_memcpy (&ipv6, dp, len);
 
555
                grub_printf ("/IPv6(%x:%x:%x:%x:%x:%x:%x:%x,%x:%x:%x:%x:%x:%x:%x:%x,%u,%u,%x,%x)",
 
556
                             (unsigned) ipv6.local_ip_address[0],
 
557
                             (unsigned) ipv6.local_ip_address[1],
 
558
                             (unsigned) ipv6.local_ip_address[2],
 
559
                             (unsigned) ipv6.local_ip_address[3],
 
560
                             (unsigned) ipv6.local_ip_address[4],
 
561
                             (unsigned) ipv6.local_ip_address[5],
 
562
                             (unsigned) ipv6.local_ip_address[6],
 
563
                             (unsigned) ipv6.local_ip_address[7],
 
564
                             (unsigned) ipv6.remote_ip_address[0],
 
565
                             (unsigned) ipv6.remote_ip_address[1],
 
566
                             (unsigned) ipv6.remote_ip_address[2],
 
567
                             (unsigned) ipv6.remote_ip_address[3],
 
568
                             (unsigned) ipv6.remote_ip_address[4],
 
569
                             (unsigned) ipv6.remote_ip_address[5],
 
570
                             (unsigned) ipv6.remote_ip_address[6],
 
571
                             (unsigned) ipv6.remote_ip_address[7],
 
572
                             (unsigned) ipv6.local_port,
 
573
                             (unsigned) ipv6.remote_port,
 
574
                             (unsigned) ipv6.protocol,
 
575
                             (unsigned) ipv6.static_ip_address);
 
576
              }
 
577
              break;
 
578
            case GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE:
 
579
              {
 
580
                grub_efi_infiniband_device_path_t ib;
 
581
                grub_memcpy (&ib, dp, len);
 
582
                grub_printf ("/InfiniBand(%x,%llx,%llx,%llx)",
 
583
                             (unsigned) ib.port_gid[0], /* XXX */
 
584
                             (unsigned long long) ib.remote_id,
 
585
                             (unsigned long long) ib.target_port_id,
 
586
                             (unsigned long long) ib.device_id);
 
587
              }
 
588
              break;
 
589
            case GRUB_EFI_UART_DEVICE_PATH_SUBTYPE:
 
590
              {
 
591
                grub_efi_uart_device_path_t uart;
 
592
                grub_memcpy (&uart, dp, len);
 
593
                grub_printf ("/UART(%llu,%u,%x,%x)",
 
594
                             (unsigned long long) uart.baud_rate,
 
595
                             uart.data_bits,
 
596
                             uart.parity,
 
597
                             uart.stop_bits);
 
598
              }
 
599
              break;
 
600
            case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE:
 
601
              {
 
602
                grub_efi_vendor_messaging_device_path_t vendor;
 
603
                grub_memcpy (&vendor, dp, sizeof (vendor));
 
604
                grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
 
605
                             (unsigned) vendor.vendor_guid.data1,
 
606
                             (unsigned) vendor.vendor_guid.data2,
 
607
                             (unsigned) vendor.vendor_guid.data3,
 
608
                             (unsigned) vendor.vendor_guid.data4[0],
 
609
                             (unsigned) vendor.vendor_guid.data4[1],
 
610
                             (unsigned) vendor.vendor_guid.data4[2],
 
611
                             (unsigned) vendor.vendor_guid.data4[3],
 
612
                             (unsigned) vendor.vendor_guid.data4[4],
 
613
                             (unsigned) vendor.vendor_guid.data4[5],
 
614
                             (unsigned) vendor.vendor_guid.data4[6],
 
615
                             (unsigned) vendor.vendor_guid.data4[7]);
 
616
              }
 
617
              break;
 
618
            default:
 
619
              grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype);
 
620
              break;
 
621
            }
 
622
          break;
 
623
 
 
624
        case GRUB_EFI_MEDIA_DEVICE_PATH_TYPE:
 
625
          switch (subtype)
 
626
            {
 
627
            case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
 
628
              {
 
629
                grub_efi_hard_drive_device_path_t hd;
 
630
                grub_memcpy (&hd, dp, len);
 
631
                grub_printf ("/HD(%u,%llx,%llx,%02x%02x%02x%02x%02x%02x%02x%02x,%x,%x)",
 
632
                             hd.partition_number,
 
633
                             (unsigned long long) hd.partition_start,
 
634
                             (unsigned long long) hd.partition_size,
 
635
                             (unsigned) hd.partition_signature[0],
 
636
                             (unsigned) hd.partition_signature[1],
 
637
                             (unsigned) hd.partition_signature[2],
 
638
                             (unsigned) hd.partition_signature[3],
 
639
                             (unsigned) hd.partition_signature[4],
 
640
                             (unsigned) hd.partition_signature[5],
 
641
                             (unsigned) hd.partition_signature[6],
 
642
                             (unsigned) hd.partition_signature[7],
 
643
                             (unsigned) hd.mbr_type,
 
644
                             (unsigned) hd.signature_type);
 
645
              }
 
646
              break;
 
647
            case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
 
648
              {
 
649
                grub_efi_cdrom_device_path_t cd;
 
650
                grub_memcpy (&cd, dp, len);
 
651
                grub_printf ("/CD(%u,%llx,%llx)",
 
652
                             cd.boot_entry,
 
653
                             (unsigned long long) cd.partition_start,
 
654
                             (unsigned long long) cd.partition_size);
 
655
              }
 
656
              break;
 
657
            case GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE:
 
658
              {
 
659
                grub_efi_vendor_media_device_path_t vendor;
 
660
                grub_memcpy (&vendor, dp, sizeof (vendor));
 
661
                grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
 
662
                             (unsigned) vendor.vendor_guid.data1,
 
663
                             (unsigned) vendor.vendor_guid.data2,
 
664
                             (unsigned) vendor.vendor_guid.data3,
 
665
                             (unsigned) vendor.vendor_guid.data4[0],
 
666
                             (unsigned) vendor.vendor_guid.data4[1],
 
667
                             (unsigned) vendor.vendor_guid.data4[2],
 
668
                             (unsigned) vendor.vendor_guid.data4[3],
 
669
                             (unsigned) vendor.vendor_guid.data4[4],
 
670
                             (unsigned) vendor.vendor_guid.data4[5],
 
671
                             (unsigned) vendor.vendor_guid.data4[6],
 
672
                             (unsigned) vendor.vendor_guid.data4[7]);
 
673
              }
 
674
              break;
 
675
            case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE:
 
676
              {
 
677
                grub_efi_file_path_device_path_t *fp;
 
678
                grub_uint8_t buf[(len - 4) * 2 + 1];
 
679
                fp = (grub_efi_file_path_device_path_t *) dp;
 
680
                *grub_utf16_to_utf8 (buf, fp->path_name,
 
681
                                     (len - 4) / sizeof (grub_efi_char16_t))
 
682
                  = '\0';
 
683
                grub_printf ("/File(%s)", buf);
 
684
              }
 
685
              break;
 
686
            case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE:
 
687
              {
 
688
                grub_efi_protocol_device_path_t proto;
 
689
                grub_memcpy (&proto, dp, sizeof (proto));
 
690
                grub_printf ("/Protocol(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
 
691
                             (unsigned) proto.guid.data1,
 
692
                             (unsigned) proto.guid.data2,
 
693
                             (unsigned) proto.guid.data3,
 
694
                             (unsigned) proto.guid.data4[0],
 
695
                             (unsigned) proto.guid.data4[1],
 
696
                             (unsigned) proto.guid.data4[2],
 
697
                             (unsigned) proto.guid.data4[3],
 
698
                             (unsigned) proto.guid.data4[4],
 
699
                             (unsigned) proto.guid.data4[5],
 
700
                             (unsigned) proto.guid.data4[6],
 
701
                             (unsigned) proto.guid.data4[7]);
 
702
              }
 
703
              break;
 
704
            default:
 
705
              grub_printf ("/UnknownMedia(%x)", (unsigned) subtype);
 
706
              break;
 
707
            }
 
708
          break;
 
709
 
 
710
        case GRUB_EFI_BIOS_DEVICE_PATH_TYPE:
 
711
          switch (subtype)
 
712
            {
 
713
            case GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE:
 
714
              {
 
715
                grub_efi_bios_device_path_t bios;
 
716
                grub_memcpy (&bios, dp, sizeof (bios));
 
717
                grub_printf ("/BIOS(%x,%x,%s)",
 
718
                             (unsigned) bios.device_type,
 
719
                             (unsigned) bios.status_flags,
 
720
                             (char *) (dp + 1));
 
721
              }
 
722
              break;
 
723
            default:
 
724
              grub_printf ("/UnknownBIOS(%x)", (unsigned) subtype);
 
725
              break;
 
726
            }
 
727
          break;
 
728
 
 
729
        default:
 
730
          grub_printf ("/UnknownType(%x,%x)\n",
 
731
                       (unsigned) type,
 
732
                       (unsigned) subtype);
 
733
          return;
 
734
          break;
 
735
        }
 
736
 
 
737
      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
 
738
        break;
 
739
 
 
740
      dp = (grub_efi_device_path_t *) ((char *) dp + len);
 
741
    }
 
742
}