mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-07 23:11:27 +00:00
x86: EFI_PAGE_SHIFT fix
Make x86 EFI code works when EFI_PAGE_SHIFT != PAGE_SHIFT. The memrage_efi_to_native() provided in this patch can be used on other EFI platform such as IA64 too. This patch has been tested on Intel x86_64 platform with EFI 64/32 firmware. Signed-off-by: Huang Ying <ying.huang@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
f8dfd5ed14
commit
4a3575fd43
3 changed files with 26 additions and 11 deletions
|
@ -383,6 +383,7 @@ static void __init runtime_code_page_mkexec(void)
|
||||||
{
|
{
|
||||||
efi_memory_desc_t *md;
|
efi_memory_desc_t *md;
|
||||||
void *p;
|
void *p;
|
||||||
|
u64 addr, npages;
|
||||||
|
|
||||||
/* Make EFI runtime service code area executable */
|
/* Make EFI runtime service code area executable */
|
||||||
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
||||||
|
@ -391,7 +392,10 @@ static void __init runtime_code_page_mkexec(void)
|
||||||
if (md->type != EFI_RUNTIME_SERVICES_CODE)
|
if (md->type != EFI_RUNTIME_SERVICES_CODE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
set_memory_x(md->virt_addr, md->num_pages);
|
addr = md->virt_addr;
|
||||||
|
npages = md->num_pages;
|
||||||
|
memrange_efi_to_native(&addr, &npages);
|
||||||
|
set_memory_x(addr, npages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +412,7 @@ 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;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
u64 end, systab;
|
u64 end, systab, addr, npages;
|
||||||
void *p, *va;
|
void *p, *va;
|
||||||
|
|
||||||
efi.systab = NULL;
|
efi.systab = NULL;
|
||||||
|
@ -420,7 +424,7 @@ void __init efi_enter_virtual_mode(void)
|
||||||
size = md->num_pages << EFI_PAGE_SHIFT;
|
size = md->num_pages << EFI_PAGE_SHIFT;
|
||||||
end = md->phys_addr + size;
|
end = md->phys_addr + size;
|
||||||
|
|
||||||
if ((end >> PAGE_SHIFT) <= max_pfn_mapped)
|
if (PFN_UP(end) <= max_pfn_mapped)
|
||||||
va = __va(md->phys_addr);
|
va = __va(md->phys_addr);
|
||||||
else
|
else
|
||||||
va = efi_ioremap(md->phys_addr, size);
|
va = efi_ioremap(md->phys_addr, size);
|
||||||
|
@ -433,8 +437,12 @@ void __init efi_enter_virtual_mode(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(md->attribute & EFI_MEMORY_WB))
|
if (!(md->attribute & EFI_MEMORY_WB)) {
|
||||||
set_memory_uc(md->virt_addr, md->num_pages);
|
addr = md->virt_addr;
|
||||||
|
npages = md->num_pages;
|
||||||
|
memrange_efi_to_native(&addr, &npages);
|
||||||
|
set_memory_uc(addr, npages);
|
||||||
|
}
|
||||||
|
|
||||||
systab = (u64) (unsigned long) efi_phys.systab;
|
systab = (u64) (unsigned long) efi_phys.systab;
|
||||||
if (md->phys_addr <= systab && systab < end) {
|
if (md->phys_addr <= systab && systab < end) {
|
||||||
|
|
|
@ -105,14 +105,14 @@ void __init efi_reserve_bootmem(void)
|
||||||
|
|
||||||
void __iomem * __init efi_ioremap(unsigned long phys_addr, unsigned long size)
|
void __iomem * __init efi_ioremap(unsigned long phys_addr, unsigned long size)
|
||||||
{
|
{
|
||||||
static unsigned pages_mapped;
|
static unsigned pages_mapped __initdata;
|
||||||
unsigned i, pages;
|
unsigned i, pages;
|
||||||
|
unsigned long offset;
|
||||||
|
|
||||||
/* phys_addr and size must be page aligned */
|
pages = PFN_UP(phys_addr + size) - PFN_DOWN(phys_addr);
|
||||||
if ((phys_addr & ~PAGE_MASK) || (size & ~PAGE_MASK))
|
offset = phys_addr & ~PAGE_MASK;
|
||||||
return NULL;
|
phys_addr &= PAGE_MASK;
|
||||||
|
|
||||||
pages = size >> PAGE_SHIFT;
|
|
||||||
if (pages_mapped + pages > MAX_EFI_IO_PAGES)
|
if (pages_mapped + pages > MAX_EFI_IO_PAGES)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -124,5 +124,5 @@ void __iomem * __init efi_ioremap(unsigned long phys_addr, unsigned long size)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (void __iomem *)__fix_to_virt(FIX_EFI_IO_MAP_FIRST_PAGE - \
|
return (void __iomem *)__fix_to_virt(FIX_EFI_IO_MAP_FIRST_PAGE - \
|
||||||
(pages_mapped - pages));
|
(pages_mapped - pages)) + offset;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <linux/rtc.h>
|
#include <linux/rtc.h>
|
||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/pfn.h>
|
||||||
|
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
|
@ -394,4 +395,10 @@ struct efi_generic_dev_path {
|
||||||
u16 length;
|
u16 length;
|
||||||
} __attribute ((packed));
|
} __attribute ((packed));
|
||||||
|
|
||||||
|
static inline void memrange_efi_to_native(u64 *addr, u64 *npages)
|
||||||
|
{
|
||||||
|
*npages = PFN_UP(*addr + (*npages<<EFI_PAGE_SHIFT)) - PFN_DOWN(*addr);
|
||||||
|
*addr &= PAGE_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _LINUX_EFI_H */
|
#endif /* _LINUX_EFI_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue