~ubuntu-branches/ubuntu/trusty/grub2/trusty

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2014-01-16 15:18:04 UTC
  • mfrom: (17.6.38 experimental)
  • Revision ID: package-import@ubuntu.com-20140116151804-3foouk7fpqcq3sxx
Tags: 2.02~beta2-2
* Convert patch handling to git-dpm.
* Add bi-endian support to ELF parser (Tomohiro B Berry).
* Adjust restore_mkdevicemap.patch to mark get_kfreebsd_version as static,
  to appease "gcc -Werror=missing-prototypes".
* Cherry-pick from upstream:
  - Change grub-macbless' manual page section to 8.
* Install grub-glue-efi, grub-macbless, grub-render-label, and
  grub-syslinux2cfg.
* grub-shell: Pass -no-pad to xorriso when building floppy images.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#include <grub/mm.h>
22
22
#include <grub/efi/api.h>
23
23
#include <grub/efi/efi.h>
 
24
#include <grub/cpu/efi/memory.h>
24
25
 
25
26
#if defined (__i386__) || defined (__x86_64__)
26
27
#include <grub/pci.h>
30
31
  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
31
32
 
32
33
#define BYTES_TO_PAGES(bytes)   (((bytes) + 0xfff) >> 12)
 
34
#define BYTES_TO_PAGES_DOWN(bytes)      ((bytes) >> 12)
33
35
#define PAGES_TO_BYTES(pages)   ((pages) << 12)
34
36
 
35
37
/* The size of a memory map obtained from the firmware. This must be
90
92
 
91
93
#if 1
92
94
  /* Limit the memory access to less than 4GB for 32-bit platforms.  */
93
 
  if (address > 0xffffffff)
 
95
  if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
94
96
    return 0;
95
97
#endif
96
98
 
98
100
  if (address == 0)
99
101
    {
100
102
      type = GRUB_EFI_ALLOCATE_MAX_ADDRESS;
101
 
      address = 0xffffffff;
 
103
      address = GRUB_EFI_MAX_USABLE_ADDRESS;
102
104
    }
103
105
  else
104
106
    type = GRUB_EFI_ALLOCATE_ADDRESS;
118
120
    {
119
121
      /* Uggh, the address 0 was allocated... This is too annoying,
120
122
         so reallocate another one.  */
121
 
      address = 0xffffffff;
 
123
      address = GRUB_EFI_MAX_USABLE_ADDRESS;
122
124
      status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address);
123
125
      grub_efi_free_pages (0, pages);
124
126
      if (status != GRUB_EFI_SUCCESS)
141
143
 
142
144
#if defined (__i386__) || defined (__x86_64__)
143
145
 
 
146
/* Helper for stop_broadcom.  */
 
147
static int
 
148
find_card (grub_pci_device_t dev, grub_pci_id_t pciid,
 
149
           void *data __attribute__ ((unused)))
 
150
{
 
151
  grub_pci_address_t addr;
 
152
  grub_uint8_t cap;
 
153
  grub_uint16_t pm_state;
 
154
 
 
155
  if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM)
 
156
    return 0;
 
157
 
 
158
  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
 
159
  if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK)
 
160
    return 0;
 
161
  cap = grub_pci_find_capability (dev, GRUB_PCI_CAP_POWER_MANAGEMENT);
 
162
  if (!cap)
 
163
    return 0;
 
164
  addr = grub_pci_make_address (dev, cap + 4);
 
165
  pm_state = grub_pci_read_word (addr);
 
166
  pm_state = pm_state | 0x03;
 
167
  grub_pci_write_word (addr, pm_state);
 
168
  grub_pci_read_word (addr);
 
169
  return 0;
 
170
}
 
171
 
144
172
static void
145
173
stop_broadcom (void)
146
174
{
147
 
  auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
148
 
                                       grub_pci_id_t pciid);
149
 
 
150
 
  int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
151
 
                                  grub_pci_id_t pciid)
152
 
    {
153
 
      grub_pci_address_t addr;
154
 
      grub_uint8_t cap;
155
 
      grub_uint16_t pm_state;
156
 
 
157
 
      if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM)
158
 
        return 0;
159
 
 
160
 
      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
161
 
      if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK)
162
 
        return 0;
163
 
      cap = grub_pci_find_capability (dev, GRUB_PCI_CAP_POWER_MANAGEMENT);
164
 
      if (!cap)
165
 
        return 0;
166
 
      addr = grub_pci_make_address (dev, cap + 4);
167
 
      pm_state = grub_pci_read_word (addr);
168
 
      pm_state = pm_state | 0x03;
169
 
      grub_pci_write_word (addr, pm_state);
170
 
      grub_pci_read_word (addr);
171
 
      return 0;
172
 
    }
173
 
 
174
 
  grub_pci_iterate (find_card);
 
175
  grub_pci_iterate (find_card, NULL);
175
176
}
176
177
 
177
178
#endif
193
194
                           apple, sizeof (apple)) == 0);
194
195
#endif
195
196
 
196
 
  if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
197
 
                               &finish_desc_size, &finish_desc_version) < 0)
198
 
    return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
199
 
 
200
 
  if (outbuf && *outbuf_size < finish_mmap_size)
201
 
    return grub_error (GRUB_ERR_IO, "memory map buffer is too small");
202
 
 
203
 
  finish_mmap_buf = grub_malloc (finish_mmap_size);
204
 
  if (!finish_mmap_buf)
205
 
    return grub_errno;
206
 
 
207
 
  if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
208
 
                               &finish_desc_size, &finish_desc_version) <= 0)
209
 
    return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
210
 
 
211
 
  b = grub_efi_system_table->boot_services;
212
 
  status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle,
213
 
                       finish_key);
214
 
  if (status != GRUB_EFI_SUCCESS)
215
 
    return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services");
216
 
 
 
197
  while (1)
 
198
    {
 
199
      if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
 
200
                                   &finish_desc_size, &finish_desc_version) < 0)
 
201
        return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
 
202
 
 
203
      if (outbuf && *outbuf_size < finish_mmap_size)
 
204
        return grub_error (GRUB_ERR_IO, "memory map buffer is too small");
 
205
 
 
206
      finish_mmap_buf = grub_malloc (finish_mmap_size);
 
207
      if (!finish_mmap_buf)
 
208
        return grub_errno;
 
209
 
 
210
      if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
 
211
                                   &finish_desc_size, &finish_desc_version) <= 0)
 
212
        {
 
213
          grub_free (finish_mmap_buf);
 
214
          return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
 
215
        }
 
216
 
 
217
      b = grub_efi_system_table->boot_services;
 
218
      status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle,
 
219
                           finish_key);
 
220
      if (status == GRUB_EFI_SUCCESS)
 
221
        break;
 
222
 
 
223
      if (status != GRUB_EFI_INVALID_PARAMETER)
 
224
        {
 
225
          grub_free (finish_mmap_buf);
 
226
          return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services");
 
227
        }
 
228
 
 
229
      grub_free (finish_mmap_buf);
 
230
      grub_printf ("Trying to terminate EFI services again\n");
 
231
    }
217
232
  grub_efi_is_finished = 1;
218
233
  if (outbuf_size)
219
234
    *outbuf_size = finish_mmap_size;
338
353
    {
339
354
      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
340
355
#if 1
341
 
          && desc->physical_start <= 0xffffffff
 
356
          && desc->physical_start <= GRUB_EFI_MAX_USABLE_ADDRESS
342
357
#endif
343
358
          && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000
344
359
          && desc->num_pages != 0)
356
371
#if 1
357
372
          if (BYTES_TO_PAGES (filtered_desc->physical_start)
358
373
              + filtered_desc->num_pages
359
 
              > BYTES_TO_PAGES (0x100000000LL))
 
374
              > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS))
360
375
            filtered_desc->num_pages
361
 
              = (BYTES_TO_PAGES (0x100000000LL)
 
376
              = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS)
362
377
                 - BYTES_TO_PAGES (filtered_desc->physical_start));
363
378
#endif
364
379
 
530
545
  grub_printf ("printing memory map\n");
531
546
  print_memory_map (memory_map, desc_size,
532
547
                    NEXT_MEMORY_DESCRIPTOR (memory_map, map_size));
533
 
  grub_abort ();
 
548
  grub_fatal ("Debug. ");
534
549
#endif
535
550
 
536
551
  /* Release the memory maps.  */