mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
sandbox: smbios: Update to support sandbox
At present this code casts addresses to pointers so cannot be used with sandbox. Update it to use mapmem instead. Signed-off-by: Simon Glass <sjg@chromium.org> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
f31239acff
commit
a2505fc8a9
2 changed files with 56 additions and 16 deletions
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <efi_loader.h>
|
#include <efi_loader.h>
|
||||||
|
#include <mapmem.h>
|
||||||
#include <smbios.h>
|
#include <smbios.h>
|
||||||
|
|
||||||
static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID;
|
static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID;
|
||||||
|
@ -19,17 +20,19 @@ static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID;
|
||||||
efi_status_t efi_smbios_register(void)
|
efi_status_t efi_smbios_register(void)
|
||||||
{
|
{
|
||||||
/* Map within the low 32 bits, to allow for 32bit SMBIOS tables */
|
/* Map within the low 32 bits, to allow for 32bit SMBIOS tables */
|
||||||
u64 dmi = U32_MAX;
|
u64 dmi_addr = U32_MAX;
|
||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
|
void *dmi;
|
||||||
|
|
||||||
/* Reserve 4kiB page for SMBIOS */
|
/* Reserve 4kiB page for SMBIOS */
|
||||||
ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
|
ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
|
||||||
EFI_RUNTIME_SERVICES_DATA, 1, &dmi);
|
EFI_RUNTIME_SERVICES_DATA, 1, &dmi_addr);
|
||||||
|
|
||||||
if (ret != EFI_SUCCESS) {
|
if (ret != EFI_SUCCESS) {
|
||||||
/* Could not find space in lowmem, use highmem instead */
|
/* Could not find space in lowmem, use highmem instead */
|
||||||
ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
|
ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
|
||||||
EFI_RUNTIME_SERVICES_DATA, 1, &dmi);
|
EFI_RUNTIME_SERVICES_DATA, 1,
|
||||||
|
&dmi_addr);
|
||||||
|
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -39,11 +42,14 @@ efi_status_t efi_smbios_register(void)
|
||||||
* Generate SMBIOS tables - we know that efi_allocate_pages() returns
|
* Generate SMBIOS tables - we know that efi_allocate_pages() returns
|
||||||
* a 4k-aligned address, so it is safe to assume that
|
* a 4k-aligned address, so it is safe to assume that
|
||||||
* write_smbios_table() will write the table at that address.
|
* write_smbios_table() will write the table at that address.
|
||||||
|
*
|
||||||
|
* Note that on sandbox, efi_allocate_pages() unfortunately returns a
|
||||||
|
* pointer even though it uses a uint64_t type. Convert it.
|
||||||
*/
|
*/
|
||||||
assert(!(dmi & 0xf));
|
assert(!(dmi_addr & 0xf));
|
||||||
write_smbios_table(dmi);
|
dmi = (void *)(uintptr_t)dmi_addr;
|
||||||
|
write_smbios_table(map_to_sysmem(dmi));
|
||||||
|
|
||||||
/* And expose them to our EFI payload */
|
/* And expose them to our EFI payload */
|
||||||
return efi_install_configuration_table(&smbios_guid,
|
return efi_install_configuration_table(&smbios_guid, dmi);
|
||||||
(void *)(uintptr_t)dmi);
|
|
||||||
}
|
}
|
||||||
|
|
52
lib/smbios.c
52
lib/smbios.c
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <mapmem.h>
|
||||||
#include <smbios.h>
|
#include <smbios.h>
|
||||||
#include <tables_csum.h>
|
#include <tables_csum.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
|
@ -72,9 +73,10 @@ static int smbios_string_table_len(char *start)
|
||||||
|
|
||||||
static int smbios_write_type0(ulong *current, int handle)
|
static int smbios_write_type0(ulong *current, int handle)
|
||||||
{
|
{
|
||||||
struct smbios_type0 *t = (struct smbios_type0 *)*current;
|
struct smbios_type0 *t;
|
||||||
int len = sizeof(struct smbios_type0);
|
int len = sizeof(struct smbios_type0);
|
||||||
|
|
||||||
|
t = map_sysmem(*current, len);
|
||||||
memset(t, 0, sizeof(struct smbios_type0));
|
memset(t, 0, sizeof(struct smbios_type0));
|
||||||
fill_smbios_header(t, SMBIOS_BIOS_INFORMATION, len, handle);
|
fill_smbios_header(t, SMBIOS_BIOS_INFORMATION, len, handle);
|
||||||
t->vendor = smbios_add_string(t->eos, "U-Boot");
|
t->vendor = smbios_add_string(t->eos, "U-Boot");
|
||||||
|
@ -101,16 +103,18 @@ static int smbios_write_type0(ulong *current, int handle)
|
||||||
|
|
||||||
len = t->length + smbios_string_table_len(t->eos);
|
len = t->length + smbios_string_table_len(t->eos);
|
||||||
*current += len;
|
*current += len;
|
||||||
|
unmap_sysmem(t);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smbios_write_type1(ulong *current, int handle)
|
static int smbios_write_type1(ulong *current, int handle)
|
||||||
{
|
{
|
||||||
struct smbios_type1 *t = (struct smbios_type1 *)*current;
|
struct smbios_type1 *t;
|
||||||
int len = sizeof(struct smbios_type1);
|
int len = sizeof(struct smbios_type1);
|
||||||
char *serial_str = env_get("serial#");
|
char *serial_str = env_get("serial#");
|
||||||
|
|
||||||
|
t = map_sysmem(*current, len);
|
||||||
memset(t, 0, sizeof(struct smbios_type1));
|
memset(t, 0, sizeof(struct smbios_type1));
|
||||||
fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle);
|
fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle);
|
||||||
t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
|
t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
|
||||||
|
@ -122,15 +126,17 @@ static int smbios_write_type1(ulong *current, int handle)
|
||||||
|
|
||||||
len = t->length + smbios_string_table_len(t->eos);
|
len = t->length + smbios_string_table_len(t->eos);
|
||||||
*current += len;
|
*current += len;
|
||||||
|
unmap_sysmem(t);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smbios_write_type2(ulong *current, int handle)
|
static int smbios_write_type2(ulong *current, int handle)
|
||||||
{
|
{
|
||||||
struct smbios_type2 *t = (struct smbios_type2 *)*current;
|
struct smbios_type2 *t;
|
||||||
int len = sizeof(struct smbios_type2);
|
int len = sizeof(struct smbios_type2);
|
||||||
|
|
||||||
|
t = map_sysmem(*current, len);
|
||||||
memset(t, 0, sizeof(struct smbios_type2));
|
memset(t, 0, sizeof(struct smbios_type2));
|
||||||
fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle);
|
fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle);
|
||||||
t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
|
t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
|
||||||
|
@ -140,15 +146,17 @@ static int smbios_write_type2(ulong *current, int handle)
|
||||||
|
|
||||||
len = t->length + smbios_string_table_len(t->eos);
|
len = t->length + smbios_string_table_len(t->eos);
|
||||||
*current += len;
|
*current += len;
|
||||||
|
unmap_sysmem(t);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smbios_write_type3(ulong *current, int handle)
|
static int smbios_write_type3(ulong *current, int handle)
|
||||||
{
|
{
|
||||||
struct smbios_type3 *t = (struct smbios_type3 *)*current;
|
struct smbios_type3 *t;
|
||||||
int len = sizeof(struct smbios_type3);
|
int len = sizeof(struct smbios_type3);
|
||||||
|
|
||||||
|
t = map_sysmem(*current, len);
|
||||||
memset(t, 0, sizeof(struct smbios_type3));
|
memset(t, 0, sizeof(struct smbios_type3));
|
||||||
fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle);
|
fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle);
|
||||||
t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
|
t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
|
||||||
|
@ -160,6 +168,7 @@ static int smbios_write_type3(ulong *current, int handle)
|
||||||
|
|
||||||
len = t->length + smbios_string_table_len(t->eos);
|
len = t->length + smbios_string_table_len(t->eos);
|
||||||
*current += len;
|
*current += len;
|
||||||
|
unmap_sysmem(t);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
@ -198,9 +207,10 @@ static void smbios_write_type4_dm(struct smbios_type4 *t)
|
||||||
|
|
||||||
static int smbios_write_type4(ulong *current, int handle)
|
static int smbios_write_type4(ulong *current, int handle)
|
||||||
{
|
{
|
||||||
struct smbios_type4 *t = (struct smbios_type4 *)*current;
|
struct smbios_type4 *t;
|
||||||
int len = sizeof(struct smbios_type4);
|
int len = sizeof(struct smbios_type4);
|
||||||
|
|
||||||
|
t = map_sysmem(*current, len);
|
||||||
memset(t, 0, sizeof(struct smbios_type4));
|
memset(t, 0, sizeof(struct smbios_type4));
|
||||||
fill_smbios_header(t, SMBIOS_PROCESSOR_INFORMATION, len, handle);
|
fill_smbios_header(t, SMBIOS_PROCESSOR_INFORMATION, len, handle);
|
||||||
t->processor_type = SMBIOS_PROCESSOR_TYPE_CENTRAL;
|
t->processor_type = SMBIOS_PROCESSOR_TYPE_CENTRAL;
|
||||||
|
@ -214,32 +224,37 @@ static int smbios_write_type4(ulong *current, int handle)
|
||||||
|
|
||||||
len = t->length + smbios_string_table_len(t->eos);
|
len = t->length + smbios_string_table_len(t->eos);
|
||||||
*current += len;
|
*current += len;
|
||||||
|
unmap_sysmem(t);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smbios_write_type32(ulong *current, int handle)
|
static int smbios_write_type32(ulong *current, int handle)
|
||||||
{
|
{
|
||||||
struct smbios_type32 *t = (struct smbios_type32 *)*current;
|
struct smbios_type32 *t;
|
||||||
int len = sizeof(struct smbios_type32);
|
int len = sizeof(struct smbios_type32);
|
||||||
|
|
||||||
|
t = map_sysmem(*current, len);
|
||||||
memset(t, 0, sizeof(struct smbios_type32));
|
memset(t, 0, sizeof(struct smbios_type32));
|
||||||
fill_smbios_header(t, SMBIOS_SYSTEM_BOOT_INFORMATION, len, handle);
|
fill_smbios_header(t, SMBIOS_SYSTEM_BOOT_INFORMATION, len, handle);
|
||||||
|
|
||||||
*current += len;
|
*current += len;
|
||||||
|
unmap_sysmem(t);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smbios_write_type127(ulong *current, int handle)
|
static int smbios_write_type127(ulong *current, int handle)
|
||||||
{
|
{
|
||||||
struct smbios_type127 *t = (struct smbios_type127 *)*current;
|
struct smbios_type127 *t;
|
||||||
int len = sizeof(struct smbios_type127);
|
int len = sizeof(struct smbios_type127);
|
||||||
|
|
||||||
|
t = map_sysmem(*current, len);
|
||||||
memset(t, 0, sizeof(struct smbios_type127));
|
memset(t, 0, sizeof(struct smbios_type127));
|
||||||
fill_smbios_header(t, SMBIOS_END_OF_TABLE, len, handle);
|
fill_smbios_header(t, SMBIOS_END_OF_TABLE, len, handle);
|
||||||
|
|
||||||
*current += len;
|
*current += len;
|
||||||
|
unmap_sysmem(t);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
@ -257,6 +272,7 @@ static smbios_write_type smbios_write_funcs[] = {
|
||||||
ulong write_smbios_table(ulong addr)
|
ulong write_smbios_table(ulong addr)
|
||||||
{
|
{
|
||||||
struct smbios_entry *se;
|
struct smbios_entry *se;
|
||||||
|
ulong table_addr;
|
||||||
ulong tables;
|
ulong tables;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int max_struct_size = 0;
|
int max_struct_size = 0;
|
||||||
|
@ -268,7 +284,7 @@ ulong write_smbios_table(ulong addr)
|
||||||
/* 16 byte align the table address */
|
/* 16 byte align the table address */
|
||||||
addr = ALIGN(addr, 16);
|
addr = ALIGN(addr, 16);
|
||||||
|
|
||||||
se = (struct smbios_entry *)(uintptr_t)addr;
|
se = map_sysmem(addr, sizeof(struct smbios_entry));
|
||||||
memset(se, 0, sizeof(struct smbios_entry));
|
memset(se, 0, sizeof(struct smbios_entry));
|
||||||
|
|
||||||
addr += sizeof(struct smbios_entry);
|
addr += sizeof(struct smbios_entry);
|
||||||
|
@ -290,7 +306,24 @@ ulong write_smbios_table(ulong addr)
|
||||||
se->max_struct_size = max_struct_size;
|
se->max_struct_size = max_struct_size;
|
||||||
memcpy(se->intermediate_anchor, "_DMI_", 5);
|
memcpy(se->intermediate_anchor, "_DMI_", 5);
|
||||||
se->struct_table_length = len;
|
se->struct_table_length = len;
|
||||||
se->struct_table_address = tables;
|
|
||||||
|
/*
|
||||||
|
* We must use a pointer here so things work correctly on sandbox. The
|
||||||
|
* user of this table is not aware of the mapping of addresses to
|
||||||
|
* sandbox's DRAM buffer.
|
||||||
|
*/
|
||||||
|
table_addr = (ulong)map_sysmem(tables, 0);
|
||||||
|
if (sizeof(table_addr) > sizeof(u32) && table_addr > (ulong)UINT_MAX) {
|
||||||
|
/*
|
||||||
|
* We need to put this >32-bit pointer into the table but the
|
||||||
|
* field is only 32 bits wide.
|
||||||
|
*/
|
||||||
|
printf("WARNING: SMBIOS table_address overflow %llx\n",
|
||||||
|
(unsigned long long)table_addr);
|
||||||
|
table_addr = 0;
|
||||||
|
}
|
||||||
|
se->struct_table_address = table_addr;
|
||||||
|
|
||||||
se->struct_count = handle;
|
se->struct_count = handle;
|
||||||
|
|
||||||
/* calculate checksums */
|
/* calculate checksums */
|
||||||
|
@ -298,6 +331,7 @@ ulong write_smbios_table(ulong addr)
|
||||||
isize = sizeof(struct smbios_entry) - SMBIOS_INTERMEDIATE_OFFSET;
|
isize = sizeof(struct smbios_entry) - SMBIOS_INTERMEDIATE_OFFSET;
|
||||||
se->intermediate_checksum = table_compute_checksum(istart, isize);
|
se->intermediate_checksum = table_compute_checksum(istart, isize);
|
||||||
se->checksum = table_compute_checksum(se, sizeof(struct smbios_entry));
|
se->checksum = table_compute_checksum(se, sizeof(struct smbios_entry));
|
||||||
|
unmap_sysmem(se);
|
||||||
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue