|
@@ -233,22 +233,23 @@ void __init efi_map_memmap(void)
|
|
{
|
|
{
|
|
memmap.map = NULL;
|
|
memmap.map = NULL;
|
|
|
|
|
|
- memmap.map = (efi_memory_desc_t *)
|
|
|
|
- bt_ioremap((unsigned long) memmap.phys_map,
|
|
|
|
- (memmap.nr_map * sizeof(efi_memory_desc_t)));
|
|
|
|
-
|
|
|
|
|
|
+ memmap.map = bt_ioremap((unsigned long) memmap.phys_map,
|
|
|
|
+ (memmap.nr_map * memmap.desc_size));
|
|
if (memmap.map == NULL)
|
|
if (memmap.map == NULL)
|
|
printk(KERN_ERR PFX "Could not remap the EFI memmap!\n");
|
|
printk(KERN_ERR PFX "Could not remap the EFI memmap!\n");
|
|
|
|
+
|
|
|
|
+ memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
|
|
}
|
|
}
|
|
|
|
|
|
#if EFI_DEBUG
|
|
#if EFI_DEBUG
|
|
static void __init print_efi_memmap(void)
|
|
static void __init print_efi_memmap(void)
|
|
{
|
|
{
|
|
efi_memory_desc_t *md;
|
|
efi_memory_desc_t *md;
|
|
|
|
+ void *p;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- for (i = 0; i < memmap.nr_map; i++) {
|
|
|
|
- md = &memmap.map[i];
|
|
|
|
|
|
+ for (p = memmap.map, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) {
|
|
|
|
+ md = p;
|
|
printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, "
|
|
printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, "
|
|
"range=[0x%016llx-0x%016llx) (%lluMB)\n",
|
|
"range=[0x%016llx-0x%016llx) (%lluMB)\n",
|
|
i, md->type, md->attribute, md->phys_addr,
|
|
i, md->type, md->attribute, md->phys_addr,
|
|
@@ -271,10 +272,10 @@ void efi_memmap_walk(efi_freemem_callback_t callback, void *arg)
|
|
} prev, curr;
|
|
} prev, curr;
|
|
efi_memory_desc_t *md;
|
|
efi_memory_desc_t *md;
|
|
unsigned long start, end;
|
|
unsigned long start, end;
|
|
- int i;
|
|
|
|
|
|
+ void *p;
|
|
|
|
|
|
- for (i = 0; i < memmap.nr_map; i++) {
|
|
|
|
- md = &memmap.map[i];
|
|
|
|
|
|
+ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
|
|
|
+ md = p;
|
|
|
|
|
|
if ((md->num_pages == 0) || (!is_available_memory(md)))
|
|
if ((md->num_pages == 0) || (!is_available_memory(md)))
|
|
continue;
|
|
continue;
|
|
@@ -325,6 +326,7 @@ void __init efi_init(void)
|
|
memmap.phys_map = EFI_MEMMAP;
|
|
memmap.phys_map = EFI_MEMMAP;
|
|
memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE;
|
|
memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE;
|
|
memmap.desc_version = EFI_MEMDESC_VERSION;
|
|
memmap.desc_version = EFI_MEMDESC_VERSION;
|
|
|
|
+ memmap.desc_size = EFI_MEMDESC_SIZE;
|
|
|
|
|
|
efi.systab = (efi_system_table_t *)
|
|
efi.systab = (efi_system_table_t *)
|
|
boot_ioremap((unsigned long) efi_phys.systab,
|
|
boot_ioremap((unsigned long) efi_phys.systab,
|
|
@@ -428,22 +430,30 @@ void __init efi_init(void)
|
|
printk(KERN_ERR PFX "Could not map the runtime service table!\n");
|
|
printk(KERN_ERR PFX "Could not map the runtime service table!\n");
|
|
|
|
|
|
/* Map the EFI memory map for use until paging_init() */
|
|
/* Map the EFI memory map for use until paging_init() */
|
|
-
|
|
|
|
- memmap.map = (efi_memory_desc_t *)
|
|
|
|
- boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE);
|
|
|
|
-
|
|
|
|
|
|
+ memmap.map = boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE);
|
|
if (memmap.map == NULL)
|
|
if (memmap.map == NULL)
|
|
printk(KERN_ERR PFX "Could not map the EFI memory map!\n");
|
|
printk(KERN_ERR PFX "Could not map the EFI memory map!\n");
|
|
|
|
|
|
- if (EFI_MEMDESC_SIZE != sizeof(efi_memory_desc_t)) {
|
|
|
|
- printk(KERN_WARNING PFX "Warning! Kernel-defined memdesc doesn't "
|
|
|
|
- "match the one from EFI!\n");
|
|
|
|
- }
|
|
|
|
|
|
+ memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
|
|
|
|
+
|
|
#if EFI_DEBUG
|
|
#if EFI_DEBUG
|
|
print_efi_memmap();
|
|
print_efi_memmap();
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline void __init check_range_for_systab(efi_memory_desc_t *md)
|
|
|
|
+{
|
|
|
|
+ if (((unsigned long)md->phys_addr <= (unsigned long)efi_phys.systab) &&
|
|
|
|
+ ((unsigned long)efi_phys.systab < md->phys_addr +
|
|
|
|
+ ((unsigned long)md->num_pages << EFI_PAGE_SHIFT))) {
|
|
|
|
+ unsigned long addr;
|
|
|
|
+
|
|
|
|
+ addr = md->virt_addr - md->phys_addr +
|
|
|
|
+ (unsigned long)efi_phys.systab;
|
|
|
|
+ efi.systab = (efi_system_table_t *)addr;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* This function will switch the EFI runtime services to virtual mode.
|
|
* This function will switch the EFI runtime services to virtual mode.
|
|
* Essentially, look through the EFI memmap and map every region that
|
|
* Essentially, look through the EFI memmap and map every region that
|
|
@@ -457,43 +467,32 @@ void __init efi_enter_virtual_mode(void)
|
|
{
|
|
{
|
|
efi_memory_desc_t *md;
|
|
efi_memory_desc_t *md;
|
|
efi_status_t status;
|
|
efi_status_t status;
|
|
- int i;
|
|
|
|
|
|
+ void *p;
|
|
|
|
|
|
efi.systab = NULL;
|
|
efi.systab = NULL;
|
|
|
|
|
|
- for (i = 0; i < memmap.nr_map; i++) {
|
|
|
|
- md = &memmap.map[i];
|
|
|
|
|
|
+ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
|
|
|
+ md = p;
|
|
|
|
|
|
- if (md->attribute & EFI_MEMORY_RUNTIME) {
|
|
|
|
- md->virt_addr =
|
|
|
|
- (unsigned long)ioremap(md->phys_addr,
|
|
|
|
- md->num_pages << EFI_PAGE_SHIFT);
|
|
|
|
- if (!(unsigned long)md->virt_addr) {
|
|
|
|
- printk(KERN_ERR PFX "ioremap of 0x%lX failed\n",
|
|
|
|
- (unsigned long)md->phys_addr);
|
|
|
|
- }
|
|
|
|
|
|
+ if (!(md->attribute & EFI_MEMORY_RUNTIME))
|
|
|
|
+ continue;
|
|
|
|
|
|
- if (((unsigned long)md->phys_addr <=
|
|
|
|
- (unsigned long)efi_phys.systab) &&
|
|
|
|
- ((unsigned long)efi_phys.systab <
|
|
|
|
- md->phys_addr +
|
|
|
|
- ((unsigned long)md->num_pages <<
|
|
|
|
- EFI_PAGE_SHIFT))) {
|
|
|
|
- unsigned long addr;
|
|
|
|
-
|
|
|
|
- addr = md->virt_addr - md->phys_addr +
|
|
|
|
- (unsigned long)efi_phys.systab;
|
|
|
|
- efi.systab = (efi_system_table_t *)addr;
|
|
|
|
- }
|
|
|
|
|
|
+ md->virt_addr = (unsigned long)ioremap(md->phys_addr,
|
|
|
|
+ md->num_pages << EFI_PAGE_SHIFT);
|
|
|
|
+ if (!(unsigned long)md->virt_addr) {
|
|
|
|
+ printk(KERN_ERR PFX "ioremap of 0x%lX failed\n",
|
|
|
|
+ (unsigned long)md->phys_addr);
|
|
}
|
|
}
|
|
|
|
+ /* update the virtual address of the EFI system table */
|
|
|
|
+ check_range_for_systab(md);
|
|
}
|
|
}
|
|
|
|
|
|
if (!efi.systab)
|
|
if (!efi.systab)
|
|
BUG();
|
|
BUG();
|
|
|
|
|
|
status = phys_efi_set_virtual_address_map(
|
|
status = phys_efi_set_virtual_address_map(
|
|
- sizeof(efi_memory_desc_t) * memmap.nr_map,
|
|
|
|
- sizeof(efi_memory_desc_t),
|
|
|
|
|
|
+ memmap.desc_size * memmap.nr_map,
|
|
|
|
+ memmap.desc_size,
|
|
memmap.desc_version,
|
|
memmap.desc_version,
|
|
memmap.phys_map);
|
|
memmap.phys_map);
|
|
|
|
|
|
@@ -533,10 +532,10 @@ efi_initialize_iomem_resources(struct resource *code_resource,
|
|
{
|
|
{
|
|
struct resource *res;
|
|
struct resource *res;
|
|
efi_memory_desc_t *md;
|
|
efi_memory_desc_t *md;
|
|
- int i;
|
|
|
|
|
|
+ void *p;
|
|
|
|
|
|
- for (i = 0; i < memmap.nr_map; i++) {
|
|
|
|
- md = &memmap.map[i];
|
|
|
|
|
|
+ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
|
|
|
+ md = p;
|
|
|
|
|
|
if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >
|
|
if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >
|
|
0x100000000ULL)
|
|
0x100000000ULL)
|
|
@@ -613,10 +612,10 @@ efi_initialize_iomem_resources(struct resource *code_resource,
|
|
u32 efi_mem_type(unsigned long phys_addr)
|
|
u32 efi_mem_type(unsigned long phys_addr)
|
|
{
|
|
{
|
|
efi_memory_desc_t *md;
|
|
efi_memory_desc_t *md;
|
|
- int i;
|
|
|
|
|
|
+ void *p;
|
|
|
|
|
|
- for (i = 0; i < memmap.nr_map; i++) {
|
|
|
|
- md = &memmap.map[i];
|
|
|
|
|
|
+ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
|
|
|
+ md = p;
|
|
if ((md->phys_addr <= phys_addr) && (phys_addr <
|
|
if ((md->phys_addr <= phys_addr) && (phys_addr <
|
|
(md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
|
|
(md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
|
|
return md->type;
|
|
return md->type;
|
|
@@ -627,10 +626,10 @@ u32 efi_mem_type(unsigned long phys_addr)
|
|
u64 efi_mem_attributes(unsigned long phys_addr)
|
|
u64 efi_mem_attributes(unsigned long phys_addr)
|
|
{
|
|
{
|
|
efi_memory_desc_t *md;
|
|
efi_memory_desc_t *md;
|
|
- int i;
|
|
|
|
|
|
+ void *p;
|
|
|
|
|
|
- for (i = 0; i < memmap.nr_map; i++) {
|
|
|
|
- md = &memmap.map[i];
|
|
|
|
|
|
+ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
|
|
|
+ md = p;
|
|
if ((md->phys_addr <= phys_addr) && (phys_addr <
|
|
if ((md->phys_addr <= phys_addr) && (phys_addr <
|
|
(md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
|
|
(md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
|
|
return md->attribute;
|
|
return md->attribute;
|