Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
9efff389
Commit
9efff389
authored
Sep 05, 2013
by
Matt Fleming
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'arm/efi-stub' into next
parents
6f9dd30c
258f6fd7
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
170 additions
and
159 deletions
+170
-159
arch/ia64/include/asm/io.h
arch/ia64/include/asm/io.h
+1
-0
arch/ia64/kernel/efi.c
arch/ia64/kernel/efi.c
+11
-43
arch/x86/platform/efi/efi.c
arch/x86/platform/efi/efi.c
+10
-116
drivers/firmware/efi/efi.c
drivers/firmware/efi/efi.c
+140
-0
include/linux/efi.h
include/linux/efi.h
+8
-0
No files found.
arch/ia64/include/asm/io.h
View file @
9efff389
...
...
@@ -424,6 +424,7 @@ extern void __iomem * ioremap(unsigned long offset, unsigned long size);
extern
void
__iomem
*
ioremap_nocache
(
unsigned
long
offset
,
unsigned
long
size
);
extern
void
iounmap
(
volatile
void
__iomem
*
addr
);
extern
void
__iomem
*
early_ioremap
(
unsigned
long
phys_addr
,
unsigned
long
size
);
#define early_memremap(phys_addr, size) early_ioremap(phys_addr, size)
extern
void
early_iounmap
(
volatile
void
__iomem
*
addr
,
unsigned
long
size
);
static
inline
void
__iomem
*
ioremap_cache
(
unsigned
long
phys_addr
,
unsigned
long
size
)
{
...
...
arch/ia64/kernel/efi.c
View file @
9efff389
...
...
@@ -44,10 +44,15 @@
#define EFI_DEBUG 0
static
__initdata
unsigned
long
palo_phys
;
static
__initdata
efi_config_table_type_t
arch_tables
[]
=
{
{
PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID
,
"PALO"
,
&
palo_phys
},
{
NULL_GUID
,
NULL
,
0
},
};
extern
efi_status_t
efi_call_phys
(
void
*
,
...);
struct
efi
efi
;
EXPORT_SYMBOL
(
efi
);
static
efi_runtime_services_t
*
runtime
;
static
u64
mem_limit
=
~
0UL
,
max_addr
=
~
0UL
,
min_addr
=
0UL
;
...
...
@@ -423,9 +428,9 @@ static u8 __init palo_checksum(u8 *buffer, u32 length)
* Parse and handle PALO table which is published at:
* http://www.dig64.org/home/DIG64_PALO_R1_0.pdf
*/
static
void
__init
handle_palo
(
unsigned
long
p
alo_phys
)
static
void
__init
handle_palo
(
unsigned
long
p
hys_addr
)
{
struct
palo_table
*
palo
=
__va
(
p
alo_phys
);
struct
palo_table
*
palo
=
__va
(
p
hys_addr
);
u8
checksum
;
if
(
strncmp
(
palo
->
signature
,
PALO_SIG
,
sizeof
(
PALO_SIG
)
-
1
))
{
...
...
@@ -467,12 +472,10 @@ void __init
efi_init
(
void
)
{
void
*
efi_map_start
,
*
efi_map_end
;
efi_config_table_t
*
config_tables
;
efi_char16_t
*
c16
;
u64
efi_desc_size
;
char
*
cp
,
vendor
[
100
]
=
"unknown"
;
int
i
;
unsigned
long
palo_phys
;
/*
* It's too early to be able to use the standard kernel command line
...
...
@@ -514,8 +517,6 @@ efi_init (void)
efi
.
systab
->
hdr
.
revision
>>
16
,
efi
.
systab
->
hdr
.
revision
&
0xffff
);
config_tables
=
__va
(
efi
.
systab
->
tables
);
/* Show what we know for posterity */
c16
=
__va
(
efi
.
systab
->
fw_vendor
);
if
(
c16
)
{
...
...
@@ -528,43 +529,10 @@ efi_init (void)
efi
.
systab
->
hdr
.
revision
>>
16
,
efi
.
systab
->
hdr
.
revision
&
0xffff
,
vendor
);
efi
.
mps
=
EFI_INVALID_TABLE_ADDR
;
efi
.
acpi
=
EFI_INVALID_TABLE_ADDR
;
efi
.
acpi20
=
EFI_INVALID_TABLE_ADDR
;
efi
.
smbios
=
EFI_INVALID_TABLE_ADDR
;
efi
.
sal_systab
=
EFI_INVALID_TABLE_ADDR
;
efi
.
boot_info
=
EFI_INVALID_TABLE_ADDR
;
efi
.
hcdp
=
EFI_INVALID_TABLE_ADDR
;
efi
.
uga
=
EFI_INVALID_TABLE_ADDR
;
palo_phys
=
EFI_INVALID_TABLE_ADDR
;
for
(
i
=
0
;
i
<
(
int
)
efi
.
systab
->
nr_tables
;
i
++
)
{
if
(
efi_guidcmp
(
config_tables
[
i
].
guid
,
MPS_TABLE_GUID
)
==
0
)
{
efi
.
mps
=
config_tables
[
i
].
table
;
printk
(
" MPS=0x%lx"
,
config_tables
[
i
].
table
);
}
else
if
(
efi_guidcmp
(
config_tables
[
i
].
guid
,
ACPI_20_TABLE_GUID
)
==
0
)
{
efi
.
acpi20
=
config_tables
[
i
].
table
;
printk
(
" ACPI 2.0=0x%lx"
,
config_tables
[
i
].
table
);
}
else
if
(
efi_guidcmp
(
config_tables
[
i
].
guid
,
ACPI_TABLE_GUID
)
==
0
)
{
efi
.
acpi
=
config_tables
[
i
].
table
;
printk
(
" ACPI=0x%lx"
,
config_tables
[
i
].
table
);
}
else
if
(
efi_guidcmp
(
config_tables
[
i
].
guid
,
SMBIOS_TABLE_GUID
)
==
0
)
{
efi
.
smbios
=
config_tables
[
i
].
table
;
printk
(
" SMBIOS=0x%lx"
,
config_tables
[
i
].
table
);
}
else
if
(
efi_guidcmp
(
config_tables
[
i
].
guid
,
SAL_SYSTEM_TABLE_GUID
)
==
0
)
{
efi
.
sal_systab
=
config_tables
[
i
].
table
;
printk
(
" SALsystab=0x%lx"
,
config_tables
[
i
].
table
);
}
else
if
(
efi_guidcmp
(
config_tables
[
i
].
guid
,
HCDP_TABLE_GUID
)
==
0
)
{
efi
.
hcdp
=
config_tables
[
i
].
table
;
printk
(
" HCDP=0x%lx"
,
config_tables
[
i
].
table
);
}
else
if
(
efi_guidcmp
(
config_tables
[
i
].
guid
,
PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID
)
==
0
)
{
palo_phys
=
config_tables
[
i
].
table
;
printk
(
" PALO=0x%lx"
,
config_tables
[
i
].
table
);
}
}
printk
(
"
\n
"
);
if
(
efi_config_init
(
arch_tables
)
!=
0
)
return
;
if
(
palo_phys
!=
EFI_INVALID_TABLE_ADDR
)
handle_palo
(
palo_phys
);
...
...
arch/x86/platform/efi/efi.c
View file @
9efff389
...
...
@@ -60,19 +60,6 @@
static
efi_char16_t
efi_dummy_name
[
6
]
=
{
'D'
,
'U'
,
'M'
,
'M'
,
'Y'
,
0
};
struct
efi
__read_mostly
efi
=
{
.
mps
=
EFI_INVALID_TABLE_ADDR
,
.
acpi
=
EFI_INVALID_TABLE_ADDR
,
.
acpi20
=
EFI_INVALID_TABLE_ADDR
,
.
smbios
=
EFI_INVALID_TABLE_ADDR
,
.
sal_systab
=
EFI_INVALID_TABLE_ADDR
,
.
boot_info
=
EFI_INVALID_TABLE_ADDR
,
.
hcdp
=
EFI_INVALID_TABLE_ADDR
,
.
uga
=
EFI_INVALID_TABLE_ADDR
,
.
uv_systab
=
EFI_INVALID_TABLE_ADDR
,
};
EXPORT_SYMBOL
(
efi
);
struct
efi_memory_map
memmap
;
static
struct
efi
efi_phys
__initdata
;
...
...
@@ -80,6 +67,13 @@ static efi_system_table_t efi_systab __initdata;
unsigned
long
x86_efi_facility
;
static
__initdata
efi_config_table_type_t
arch_tables
[]
=
{
#ifdef CONFIG_X86_UV
{
UV_SYSTEM_TABLE_GUID
,
"UVsystab"
,
&
efi
.
uv_systab
},
#endif
{
NULL_GUID
,
NULL
,
0
},
};
/*
* Returns 1 if 'facility' is enabled, 0 otherwise.
*/
...
...
@@ -399,6 +393,8 @@ int __init efi_memblock_x86_reserve_range(void)
memblock_reserve
(
pmap
,
memmap
.
nr_map
*
memmap
.
desc_size
);
efi
.
memmap
=
&
memmap
;
return
0
;
}
...
...
@@ -578,80 +574,6 @@ static int __init efi_systab_init(void *phys)
return
0
;
}
static
int
__init
efi_config_init
(
u64
tables
,
int
nr_tables
)
{
void
*
config_tables
,
*
tablep
;
int
i
,
sz
;
if
(
efi_enabled
(
EFI_64BIT
))
sz
=
sizeof
(
efi_config_table_64_t
);
else
sz
=
sizeof
(
efi_config_table_32_t
);
/*
* Let's see what config tables the firmware passed to us.
*/
config_tables
=
early_ioremap
(
tables
,
nr_tables
*
sz
);
if
(
config_tables
==
NULL
)
{
pr_err
(
"Could not map Configuration table!
\n
"
);
return
-
ENOMEM
;
}
tablep
=
config_tables
;
pr_info
(
""
);
for
(
i
=
0
;
i
<
efi
.
systab
->
nr_tables
;
i
++
)
{
efi_guid_t
guid
;
unsigned
long
table
;
if
(
efi_enabled
(
EFI_64BIT
))
{
u64
table64
;
guid
=
((
efi_config_table_64_t
*
)
tablep
)
->
guid
;
table64
=
((
efi_config_table_64_t
*
)
tablep
)
->
table
;
table
=
table64
;
#ifdef CONFIG_X86_32
if
(
table64
>>
32
)
{
pr_cont
(
"
\n
"
);
pr_err
(
"Table located above 4GB, disabling EFI.
\n
"
);
early_iounmap
(
config_tables
,
efi
.
systab
->
nr_tables
*
sz
);
return
-
EINVAL
;
}
#endif
}
else
{
guid
=
((
efi_config_table_32_t
*
)
tablep
)
->
guid
;
table
=
((
efi_config_table_32_t
*
)
tablep
)
->
table
;
}
if
(
!
efi_guidcmp
(
guid
,
MPS_TABLE_GUID
))
{
efi
.
mps
=
table
;
pr_cont
(
" MPS=0x%lx "
,
table
);
}
else
if
(
!
efi_guidcmp
(
guid
,
ACPI_20_TABLE_GUID
))
{
efi
.
acpi20
=
table
;
pr_cont
(
" ACPI 2.0=0x%lx "
,
table
);
}
else
if
(
!
efi_guidcmp
(
guid
,
ACPI_TABLE_GUID
))
{
efi
.
acpi
=
table
;
pr_cont
(
" ACPI=0x%lx "
,
table
);
}
else
if
(
!
efi_guidcmp
(
guid
,
SMBIOS_TABLE_GUID
))
{
efi
.
smbios
=
table
;
pr_cont
(
" SMBIOS=0x%lx "
,
table
);
#ifdef CONFIG_X86_UV
}
else
if
(
!
efi_guidcmp
(
guid
,
UV_SYSTEM_TABLE_GUID
))
{
efi
.
uv_systab
=
table
;
pr_cont
(
" UVsystab=0x%lx "
,
table
);
#endif
}
else
if
(
!
efi_guidcmp
(
guid
,
HCDP_TABLE_GUID
))
{
efi
.
hcdp
=
table
;
pr_cont
(
" HCDP=0x%lx "
,
table
);
}
else
if
(
!
efi_guidcmp
(
guid
,
UGA_IO_PROTOCOL_GUID
))
{
efi
.
uga
=
table
;
pr_cont
(
" UGA=0x%lx "
,
table
);
}
tablep
+=
sz
;
}
pr_cont
(
"
\n
"
);
early_iounmap
(
config_tables
,
efi
.
systab
->
nr_tables
*
sz
);
return
0
;
}
static
int
__init
efi_runtime_init
(
void
)
{
efi_runtime_services_t
*
runtime
;
...
...
@@ -745,7 +667,7 @@ void __init efi_init(void)
efi
.
systab
->
hdr
.
revision
>>
16
,
efi
.
systab
->
hdr
.
revision
&
0xffff
,
vendor
);
if
(
efi_config_init
(
efi
.
systab
->
tables
,
efi
.
systab
->
nr
_tables
))
if
(
efi_config_init
(
arch
_tables
))
return
;
set_bit
(
EFI_CONFIG_TABLES
,
&
x86_efi_facility
);
...
...
@@ -816,34 +738,6 @@ static void __init runtime_code_page_mkexec(void)
}
}
/*
* We can't ioremap data in EFI boot services RAM, because we've already mapped
* it as RAM. So, look it up in the existing EFI memory map instead. Only
* callable after efi_enter_virtual_mode and before efi_free_boot_services.
*/
void
__iomem
*
efi_lookup_mapped_addr
(
u64
phys_addr
)
{
void
*
p
;
if
(
WARN_ON
(
!
memmap
.
map
))
return
NULL
;
for
(
p
=
memmap
.
map
;
p
<
memmap
.
map_end
;
p
+=
memmap
.
desc_size
)
{
efi_memory_desc_t
*
md
=
p
;
u64
size
=
md
->
num_pages
<<
EFI_PAGE_SHIFT
;
u64
end
=
md
->
phys_addr
+
size
;
if
(
!
(
md
->
attribute
&
EFI_MEMORY_RUNTIME
)
&&
md
->
type
!=
EFI_BOOT_SERVICES_CODE
&&
md
->
type
!=
EFI_BOOT_SERVICES_DATA
)
continue
;
if
(
!
md
->
virt_addr
)
continue
;
if
(
phys_addr
>=
md
->
phys_addr
&&
phys_addr
<
end
)
{
phys_addr
+=
md
->
virt_addr
-
md
->
phys_addr
;
return
(
__force
void
__iomem
*
)(
unsigned
long
)
phys_addr
;
}
}
return
NULL
;
}
void
efi_memory_uc
(
u64
addr
,
unsigned
long
size
)
{
unsigned
long
page_shift
=
1UL
<<
EFI_PAGE_SHIFT
;
...
...
drivers/firmware/efi/efi.c
View file @
9efff389
...
...
@@ -13,11 +13,27 @@
* This file is released under the GPLv2.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/efi.h>
#include <linux/io.h>
struct
efi
__read_mostly
efi
=
{
.
mps
=
EFI_INVALID_TABLE_ADDR
,
.
acpi
=
EFI_INVALID_TABLE_ADDR
,
.
acpi20
=
EFI_INVALID_TABLE_ADDR
,
.
smbios
=
EFI_INVALID_TABLE_ADDR
,
.
sal_systab
=
EFI_INVALID_TABLE_ADDR
,
.
boot_info
=
EFI_INVALID_TABLE_ADDR
,
.
hcdp
=
EFI_INVALID_TABLE_ADDR
,
.
uga
=
EFI_INVALID_TABLE_ADDR
,
.
uv_systab
=
EFI_INVALID_TABLE_ADDR
,
};
EXPORT_SYMBOL
(
efi
);
static
struct
kobject
*
efi_kobj
;
static
struct
kobject
*
efivars_kobj
;
...
...
@@ -132,3 +148,127 @@ static int __init efisubsys_init(void)
}
subsys_initcall
(
efisubsys_init
);
/*
* We can't ioremap data in EFI boot services RAM, because we've already mapped
* it as RAM. So, look it up in the existing EFI memory map instead. Only
* callable after efi_enter_virtual_mode and before efi_free_boot_services.
*/
void
__iomem
*
efi_lookup_mapped_addr
(
u64
phys_addr
)
{
struct
efi_memory_map
*
map
;
void
*
p
;
map
=
efi
.
memmap
;
if
(
!
map
)
return
NULL
;
if
(
WARN_ON
(
!
map
->
map
))
return
NULL
;
for
(
p
=
map
->
map
;
p
<
map
->
map_end
;
p
+=
map
->
desc_size
)
{
efi_memory_desc_t
*
md
=
p
;
u64
size
=
md
->
num_pages
<<
EFI_PAGE_SHIFT
;
u64
end
=
md
->
phys_addr
+
size
;
if
(
!
(
md
->
attribute
&
EFI_MEMORY_RUNTIME
)
&&
md
->
type
!=
EFI_BOOT_SERVICES_CODE
&&
md
->
type
!=
EFI_BOOT_SERVICES_DATA
)
continue
;
if
(
!
md
->
virt_addr
)
continue
;
if
(
phys_addr
>=
md
->
phys_addr
&&
phys_addr
<
end
)
{
phys_addr
+=
md
->
virt_addr
-
md
->
phys_addr
;
return
(
__force
void
__iomem
*
)(
unsigned
long
)
phys_addr
;
}
}
return
NULL
;
}
static
__initdata
efi_config_table_type_t
common_tables
[]
=
{
{
ACPI_20_TABLE_GUID
,
"ACPI 2.0"
,
&
efi
.
acpi20
},
{
ACPI_TABLE_GUID
,
"ACPI"
,
&
efi
.
acpi
},
{
HCDP_TABLE_GUID
,
"HCDP"
,
&
efi
.
hcdp
},
{
MPS_TABLE_GUID
,
"MPS"
,
&
efi
.
mps
},
{
SAL_SYSTEM_TABLE_GUID
,
"SALsystab"
,
&
efi
.
sal_systab
},
{
SMBIOS_TABLE_GUID
,
"SMBIOS"
,
&
efi
.
smbios
},
{
UGA_IO_PROTOCOL_GUID
,
"UGA"
,
&
efi
.
uga
},
{
NULL_GUID
,
NULL
,
0
},
};
static
__init
int
match_config_table
(
efi_guid_t
*
guid
,
unsigned
long
table
,
efi_config_table_type_t
*
table_types
)
{
u8
str
[
EFI_VARIABLE_GUID_LEN
+
1
];
int
i
;
if
(
table_types
)
{
efi_guid_unparse
(
guid
,
str
);
for
(
i
=
0
;
efi_guidcmp
(
table_types
[
i
].
guid
,
NULL_GUID
);
i
++
)
{
efi_guid_unparse
(
&
table_types
[
i
].
guid
,
str
);
if
(
!
efi_guidcmp
(
*
guid
,
table_types
[
i
].
guid
))
{
*
(
table_types
[
i
].
ptr
)
=
table
;
pr_cont
(
" %s=0x%lx "
,
table_types
[
i
].
name
,
table
);
return
1
;
}
}
}
return
0
;
}
int
__init
efi_config_init
(
efi_config_table_type_t
*
arch_tables
)
{
void
*
config_tables
,
*
tablep
;
int
i
,
sz
;
if
(
efi_enabled
(
EFI_64BIT
))
sz
=
sizeof
(
efi_config_table_64_t
);
else
sz
=
sizeof
(
efi_config_table_32_t
);
/*
* Let's see what config tables the firmware passed to us.
*/
config_tables
=
early_memremap
(
efi
.
systab
->
tables
,
efi
.
systab
->
nr_tables
*
sz
);
if
(
config_tables
==
NULL
)
{
pr_err
(
"Could not map Configuration table!
\n
"
);
return
-
ENOMEM
;
}
tablep
=
config_tables
;
pr_info
(
""
);
for
(
i
=
0
;
i
<
efi
.
systab
->
nr_tables
;
i
++
)
{
efi_guid_t
guid
;
unsigned
long
table
;
if
(
efi_enabled
(
EFI_64BIT
))
{
u64
table64
;
guid
=
((
efi_config_table_64_t
*
)
tablep
)
->
guid
;
table64
=
((
efi_config_table_64_t
*
)
tablep
)
->
table
;
table
=
table64
;
#ifndef CONFIG_64BIT
if
(
table64
>>
32
)
{
pr_cont
(
"
\n
"
);
pr_err
(
"Table located above 4GB, disabling EFI.
\n
"
);
early_iounmap
(
config_tables
,
efi
.
systab
->
nr_tables
*
sz
);
return
-
EINVAL
;
}
#endif
}
else
{
guid
=
((
efi_config_table_32_t
*
)
tablep
)
->
guid
;
table
=
((
efi_config_table_32_t
*
)
tablep
)
->
table
;
}
if
(
!
match_config_table
(
&
guid
,
table
,
common_tables
))
match_config_table
(
&
guid
,
table
,
arch_tables
);
tablep
+=
sz
;
}
pr_cont
(
"
\n
"
);
early_iounmap
(
config_tables
,
efi
.
systab
->
nr_tables
*
sz
);
return
0
;
}
include/linux/efi.h
View file @
9efff389
...
...
@@ -404,6 +404,12 @@ typedef struct {
unsigned
long
table
;
}
efi_config_table_t
;
typedef
struct
{
efi_guid_t
guid
;
const
char
*
name
;
unsigned
long
*
ptr
;
}
efi_config_table_type_t
;
#define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL)
#define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30))
...
...
@@ -552,6 +558,7 @@ extern struct efi {
efi_get_next_high_mono_count_t
*
get_next_high_mono_count
;
efi_reset_system_t
*
reset_system
;
efi_set_virtual_address_map_t
*
set_virtual_address_map
;
struct
efi_memory_map
*
memmap
;
}
efi
;
static
inline
int
...
...
@@ -587,6 +594,7 @@ static inline efi_status_t efi_query_variable_store(u32 attributes, unsigned lon
}
#endif
extern
void
__iomem
*
efi_lookup_mapped_addr
(
u64
phys_addr
);
extern
int
efi_config_init
(
efi_config_table_type_t
*
arch_tables
);
extern
u64
efi_get_iobase
(
void
);
extern
u32
efi_mem_type
(
unsigned
long
phys_addr
);
extern
u64
efi_mem_attributes
(
unsigned
long
phys_addr
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment