summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig8
-rw-r--r--lib/acpi/acpi_device.c45
-rw-r--r--lib/acpi/acpi_dp.c4
-rw-r--r--lib/acpi/acpi_table.c64
-rw-r--r--lib/acpi/acpigen.c354
-rw-r--r--lib/efi_loader/Kconfig1
-rw-r--r--lib/efi_loader/efi_load_initrd.c59
-rw-r--r--lib/efi_selftest/efi_selftest.c31
-rw-r--r--lib/efi_selftest/efi_selftest_console.c35
-rw-r--r--lib/efi_selftest/efi_selftest_load_initrd.c2
-rw-r--r--lib/efi_selftest/efi_selftest_set_virtual_address_map.c2
-rw-r--r--lib/fdtdec.c17
-rw-r--r--lib/lmb.c9
-rw-r--r--lib/optee/optee.c2
14 files changed, 572 insertions, 61 deletions
diff --git a/lib/Kconfig b/lib/Kconfig
index 8efb154f734..37aae73a266 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -542,6 +542,14 @@ config HEXDUMP
help
This enables functions for printing dumps of binary data.
+config SPL_HEXDUMP
+ bool "Enable hexdump in SPL"
+ depends on HEXDUMP
+ default y
+ help
+ This enables functions for printing dumps of binary data in
+ SPL.
+
config OF_LIBFDT
bool "Enable the FDT library"
default y if OF_CONTROL
diff --git a/lib/acpi/acpi_device.c b/lib/acpi/acpi_device.c
index 3c75b6d9629..95dfac583fc 100644
--- a/lib/acpi/acpi_device.c
+++ b/lib/acpi/acpi_device.c
@@ -487,7 +487,50 @@ int acpi_device_add_power_res(struct acpi_ctx *ctx, u32 tx_state_val,
return 0;
}
-/* ACPI 6.3 section 6.4.3.8.2.1 - I2cSerialBus() */
+int acpi_device_write_dsm_i2c_hid(struct acpi_ctx *ctx,
+ int hid_desc_reg_offset)
+{
+ int ret;
+
+ acpigen_write_dsm_start(ctx);
+ ret = acpigen_write_dsm_uuid_start(ctx, ACPI_DSM_I2C_HID_UUID);
+ if (ret)
+ return log_ret(ret);
+
+ acpigen_write_dsm_uuid_start_cond(ctx, 0);
+ /* ToInteger (Arg1, Local2) */
+ acpigen_write_to_integer(ctx, ARG1_OP, LOCAL2_OP);
+ /* If (LEqual (Local2, 0x0)) */
+ acpigen_write_if_lequal_op_int(ctx, LOCAL2_OP, 0x0);
+ /* Return (Buffer (One) { 0x1f }) */
+ acpigen_write_return_singleton_buffer(ctx, 0x1f);
+ acpigen_pop_len(ctx); /* Pop : If */
+ /* Else */
+ acpigen_write_else(ctx);
+ /* If (LEqual (Local2, 0x1)) */
+ acpigen_write_if_lequal_op_int(ctx, LOCAL2_OP, 0x1);
+ /* Return (Buffer (One) { 0x3f }) */
+ acpigen_write_return_singleton_buffer(ctx, 0x3f);
+ acpigen_pop_len(ctx); /* Pop : If */
+ /* Else */
+ acpigen_write_else(ctx);
+ /* Return (Buffer (One) { 0x0 }) */
+ acpigen_write_return_singleton_buffer(ctx, 0x0);
+ acpigen_pop_len(ctx); /* Pop : Else */
+ acpigen_pop_len(ctx); /* Pop : Else */
+ acpigen_write_dsm_uuid_end_cond(ctx);
+
+ acpigen_write_dsm_uuid_start_cond(ctx, 1);
+ acpigen_write_return_byte(ctx, hid_desc_reg_offset);
+ acpigen_write_dsm_uuid_end_cond(ctx);
+
+ acpigen_write_dsm_uuid_end(ctx);
+ acpigen_write_dsm_end(ctx);
+
+ return 0;
+}
+
+/* ACPI 6.3 section 6.4.3.8.2.1 - I2cSerialBusV2() */
static void acpi_device_write_i2c(struct acpi_ctx *ctx,
const struct acpi_i2c *i2c)
{
diff --git a/lib/acpi/acpi_dp.c b/lib/acpi/acpi_dp.c
index 579cab47715..7e3e3259d8d 100644
--- a/lib/acpi/acpi_dp.c
+++ b/lib/acpi/acpi_dp.c
@@ -324,7 +324,7 @@ struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name,
struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
const char *ref, int index, int pin,
- enum acpi_irq_polarity polarity)
+ enum acpi_gpio_polarity polarity)
{
struct acpi_dp *gpio;
@@ -336,7 +336,7 @@ struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
if (!acpi_dp_add_reference(gpio, NULL, ref) ||
!acpi_dp_add_integer(gpio, NULL, index) ||
!acpi_dp_add_integer(gpio, NULL, pin) ||
- !acpi_dp_add_integer(gpio, NULL, polarity == ACPI_IRQ_ACTIVE_LOW))
+ !acpi_dp_add_integer(gpio, NULL, polarity == ACPI_GPIO_ACTIVE_LOW))
return NULL;
if (!acpi_dp_add_array(dp, gpio))
diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c
index acc55e7fad6..908d8903893 100644
--- a/lib/acpi/acpi_table.c
+++ b/lib/acpi/acpi_table.c
@@ -264,3 +264,67 @@ void acpi_setup_base_tables(struct acpi_ctx *ctx, void *start)
*/
acpi_align64(ctx);
}
+
+void acpi_create_dbg2(struct acpi_dbg2_header *dbg2,
+ int port_type, int port_subtype,
+ struct acpi_gen_regaddr *address, u32 address_size,
+ const char *device_path)
+{
+ uintptr_t current;
+ struct acpi_dbg2_device *device;
+ u32 *dbg2_addr_size;
+ struct acpi_table_header *header;
+ size_t path_len;
+ const char *path;
+ char *namespace;
+
+ /* Fill out header fields. */
+ current = (uintptr_t)dbg2;
+ memset(dbg2, '\0', sizeof(struct acpi_dbg2_header));
+ header = &dbg2->header;
+
+ header->revision = acpi_get_table_revision(ACPITAB_DBG2);
+ acpi_fill_header(header, "DBG2");
+ header->aslc_revision = ASL_REVISION;
+
+ /* One debug device defined */
+ dbg2->devices_offset = sizeof(struct acpi_dbg2_header);
+ dbg2->devices_count = 1;
+ current += sizeof(struct acpi_dbg2_header);
+
+ /* Device comes after the header */
+ device = (struct acpi_dbg2_device *)current;
+ memset(device, 0, sizeof(struct acpi_dbg2_device));
+ current += sizeof(struct acpi_dbg2_device);
+
+ device->revision = 0;
+ device->address_count = 1;
+ device->port_type = port_type;
+ device->port_subtype = port_subtype;
+
+ /* Base Address comes after device structure */
+ memcpy((void *)current, address, sizeof(struct acpi_gen_regaddr));
+ device->base_address_offset = current - (uintptr_t)device;
+ current += sizeof(struct acpi_gen_regaddr);
+
+ /* Address Size comes after address structure */
+ dbg2_addr_size = (uint32_t *)current;
+ device->address_size_offset = current - (uintptr_t)device;
+ *dbg2_addr_size = address_size;
+ current += sizeof(uint32_t);
+
+ /* Namespace string comes last, use '.' if not provided */
+ path = device_path ? : ".";
+ /* Namespace string length includes NULL terminator */
+ path_len = strlen(path) + 1;
+ namespace = (char *)current;
+ device->namespace_string_length = path_len;
+ device->namespace_string_offset = current - (uintptr_t)device;
+ strncpy(namespace, path, path_len);
+ current += path_len;
+
+ /* Update structure lengths and checksum */
+ device->length = current - (uintptr_t)device;
+ header->length = current - (uintptr_t)dbg2;
+ header->checksum = table_compute_checksum(dbg2, header->length);
+}
diff --git a/lib/acpi/acpigen.c b/lib/acpi/acpigen.c
index c609ef4daa4..e395226e3de 100644
--- a/lib/acpi/acpigen.c
+++ b/lib/acpi/acpigen.c
@@ -17,6 +17,9 @@
#include <acpi/acpi_table.h>
#include <dm/acpi.h>
+/* CPU path format */
+#define ACPI_CPU_STRING "\\_PR.CP%02d"
+
u8 *acpigen_get_current(struct acpi_ctx *ctx)
{
return ctx->current;
@@ -340,6 +343,58 @@ void acpigen_write_method_serialized(struct acpi_ctx *ctx, const char *name,
ACPI_METHOD_SERIALIZED_MASK);
}
+void acpigen_write_processor(struct acpi_ctx *ctx, uint cpuindex,
+ u32 pblock_addr, uint pblock_len)
+{
+ /*
+ * Processor (\_PR.CPnn, cpuindex, pblock_addr, pblock_len)
+ * {
+ */
+ char pscope[16];
+
+ acpigen_emit_ext_op(ctx, PROCESSOR_OP);
+ acpigen_write_len_f(ctx);
+
+ snprintf(pscope, sizeof(pscope), ACPI_CPU_STRING, cpuindex);
+ acpigen_emit_namestring(ctx, pscope);
+ acpigen_emit_byte(ctx, cpuindex);
+ acpigen_emit_dword(ctx, pblock_addr);
+ acpigen_emit_byte(ctx, pblock_len);
+}
+
+void acpigen_write_processor_package(struct acpi_ctx *ctx,
+ const char *const name,
+ const uint first_core,
+ const uint core_count)
+{
+ uint i;
+ char pscope[16];
+
+ acpigen_write_name(ctx, name);
+ acpigen_write_package(ctx, core_count);
+ for (i = first_core; i < first_core + core_count; ++i) {
+ snprintf(pscope, sizeof(pscope), ACPI_CPU_STRING, i);
+ acpigen_emit_namestring(ctx, pscope);
+ }
+ acpigen_pop_len(ctx);
+}
+
+void acpigen_write_processor_cnot(struct acpi_ctx *ctx, const uint num_cores)
+{
+ int core_id;
+
+ acpigen_write_method(ctx, "\\_PR.CNOT", 1);
+ for (core_id = 0; core_id < num_cores; core_id++) {
+ char buffer[30];
+
+ snprintf(buffer, sizeof(buffer), ACPI_CPU_STRING, core_id);
+ acpigen_emit_byte(ctx, NOTIFY_OP);
+ acpigen_emit_namestring(ctx, buffer);
+ acpigen_emit_byte(ctx, ARG0_OP);
+ }
+ acpigen_pop_len(ctx);
+}
+
void acpigen_write_device(struct acpi_ctx *ctx, const char *name)
{
acpigen_emit_ext_op(ctx, DEVICE_OP);
@@ -426,6 +481,183 @@ void acpigen_write_register_resource(struct acpi_ctx *ctx,
acpigen_write_resourcetemplate_footer(ctx);
}
+void acpigen_write_ppc(struct acpi_ctx *ctx, uint num_pstates)
+{
+ /*
+ * Method (_PPC, 0, NotSerialized)
+ * {
+ * Return (num_pstates)
+ * }
+ */
+ acpigen_write_method(ctx, "_PPC", 0);
+ acpigen_emit_byte(ctx, RETURN_OP);
+ acpigen_write_byte(ctx, num_pstates);
+ acpigen_pop_len(ctx);
+}
+
+/*
+ * Generates a func with max supported P-states saved
+ * in the variable PPCM.
+ */
+void acpigen_write_ppc_nvs(struct acpi_ctx *ctx)
+{
+ /*
+ * Method (_PPC, 0, NotSerialized)
+ * {
+ * Return (PPCM)
+ * }
+ */
+ acpigen_write_method(ctx, "_PPC", 0);
+ acpigen_emit_byte(ctx, RETURN_OP);
+ acpigen_emit_namestring(ctx, "PPCM");
+ acpigen_pop_len(ctx);
+}
+
+void acpigen_write_tpc(struct acpi_ctx *ctx, const char *gnvs_tpc_limit)
+{
+ /*
+ * // Sample _TPC method
+ * Method (_TPC, 0, NotSerialized)
+ * {
+ * Return (\TLVL)
+ * }
+ */
+ acpigen_write_method(ctx, "_TPC", 0);
+ acpigen_emit_byte(ctx, RETURN_OP);
+ acpigen_emit_namestring(ctx, gnvs_tpc_limit);
+ acpigen_pop_len(ctx);
+}
+
+void acpigen_write_prw(struct acpi_ctx *ctx, uint wake, uint level)
+{
+ /* Name (_PRW, Package () { wake, level } */
+ acpigen_write_name(ctx, "_PRW");
+ acpigen_write_package(ctx, 2);
+ acpigen_write_integer(ctx, wake);
+ acpigen_write_integer(ctx, level);
+ acpigen_pop_len(ctx);
+}
+
+void acpigen_write_pss_package(struct acpi_ctx *ctx, u32 core_freq, u32 power,
+ u32 trans_lat, u32 busm_lat, u32 control,
+ u32 status)
+{
+ acpigen_write_package(ctx, 6);
+ acpigen_write_dword(ctx, core_freq);
+ acpigen_write_dword(ctx, power);
+ acpigen_write_dword(ctx, trans_lat);
+ acpigen_write_dword(ctx, busm_lat);
+ acpigen_write_dword(ctx, control);
+ acpigen_write_dword(ctx, status);
+ acpigen_pop_len(ctx);
+
+ log_debug("PSS: %uMHz power %u control 0x%x status 0x%x\n",
+ core_freq, power, control, status);
+}
+
+void acpigen_write_psd_package(struct acpi_ctx *ctx, uint domain, uint numprocs,
+ enum psd_coord coordtype)
+{
+ acpigen_write_name(ctx, "_PSD");
+ acpigen_write_package(ctx, 1);
+ acpigen_write_package(ctx, 5);
+ acpigen_write_byte(ctx, 5); // 5 values
+ acpigen_write_byte(ctx, 0); // revision 0
+ acpigen_write_dword(ctx, domain);
+ acpigen_write_dword(ctx, coordtype);
+ acpigen_write_dword(ctx, numprocs);
+ acpigen_pop_len(ctx);
+ acpigen_pop_len(ctx);
+}
+
+static void acpigen_write_cst_package_entry(struct acpi_ctx *ctx,
+ const struct acpi_cstate *cstate)
+{
+ acpigen_write_package(ctx, 4);
+ acpigen_write_register_resource(ctx, &cstate->resource);
+ acpigen_write_dword(ctx, cstate->ctype);
+ acpigen_write_dword(ctx, cstate->latency);
+ acpigen_write_dword(ctx, cstate->power);
+ acpigen_pop_len(ctx);
+}
+
+void acpigen_write_cst_package(struct acpi_ctx *ctx,
+ const struct acpi_cstate *cstate, int nentries)
+{
+ int i;
+
+ acpigen_write_name(ctx, "_CST");
+ acpigen_write_package(ctx, nentries + 1);
+ acpigen_write_dword(ctx, nentries);
+
+ for (i = 0; i < nentries; i++)
+ acpigen_write_cst_package_entry(ctx, cstate + i);
+
+ acpigen_pop_len(ctx);
+}
+
+void acpigen_write_csd_package(struct acpi_ctx *ctx, uint domain, uint numprocs,
+ enum csd_coord coordtype, uint index)
+{
+ acpigen_write_name(ctx, "_CSD");
+ acpigen_write_package(ctx, 1);
+ acpigen_write_package(ctx, 6);
+ acpigen_write_byte(ctx, 6); // 6 values
+ acpigen_write_byte(ctx, 0); // revision 0
+ acpigen_write_dword(ctx, domain);
+ acpigen_write_dword(ctx, coordtype);
+ acpigen_write_dword(ctx, numprocs);
+ acpigen_write_dword(ctx, index);
+ acpigen_pop_len(ctx);
+ acpigen_pop_len(ctx);
+}
+
+void acpigen_write_tss_package(struct acpi_ctx *ctx,
+ struct acpi_tstate *entry, int nentries)
+{
+ /*
+ * Sample _TSS package with 100% and 50% duty cycles
+ * Name (_TSS, Package (0x02)
+ * {
+ * Package(){100, 1000, 0, 0x00, 0)
+ * Package(){50, 520, 0, 0x18, 0)
+ * })
+ */
+ struct acpi_tstate *tstate = entry;
+ int i;
+
+ acpigen_write_name(ctx, "_TSS");
+ acpigen_write_package(ctx, nentries);
+
+ for (i = 0; i < nentries; i++) {
+ acpigen_write_package(ctx, 5);
+ acpigen_write_dword(ctx, tstate->percent);
+ acpigen_write_dword(ctx, tstate->power);
+ acpigen_write_dword(ctx, tstate->latency);
+ acpigen_write_dword(ctx, tstate->control);
+ acpigen_write_dword(ctx, tstate->status);
+ acpigen_pop_len(ctx);
+ tstate++;
+ }
+
+ acpigen_pop_len(ctx);
+}
+
+void acpigen_write_tsd_package(struct acpi_ctx *ctx, u32 domain, u32 numprocs,
+ enum psd_coord coordtype)
+{
+ acpigen_write_name(ctx, "_TSD");
+ acpigen_write_package(ctx, 1);
+ acpigen_write_package(ctx, 5);
+ acpigen_write_byte(ctx, 5); // 5 values
+ acpigen_write_byte(ctx, 0); // revision 0
+ acpigen_write_dword(ctx, domain);
+ acpigen_write_dword(ctx, coordtype);
+ acpigen_write_dword(ctx, numprocs);
+ acpigen_pop_len(ctx);
+ acpigen_pop_len(ctx);
+}
+
/*
* ToUUID(uuid)
*
@@ -531,6 +763,128 @@ void acpigen_write_debug_string(struct acpi_ctx *ctx, const char *str)
acpigen_emit_ext_op(ctx, DEBUG_OP);
}
+void acpigen_write_if(struct acpi_ctx *ctx)
+{
+ acpigen_emit_byte(ctx, IF_OP);
+ acpigen_write_len_f(ctx);
+}
+
+void acpigen_write_if_lequal_op_int(struct acpi_ctx *ctx, uint op, u64 val)
+{
+ acpigen_write_if(ctx);
+ acpigen_emit_byte(ctx, LEQUAL_OP);
+ acpigen_emit_byte(ctx, op);
+ acpigen_write_integer(ctx, val);
+}
+
+void acpigen_write_else(struct acpi_ctx *ctx)
+{
+ acpigen_emit_byte(ctx, ELSE_OP);
+ acpigen_write_len_f(ctx);
+}
+
+void acpigen_write_to_buffer(struct acpi_ctx *ctx, uint src, uint dst)
+{
+ acpigen_emit_byte(ctx, TO_BUFFER_OP);
+ acpigen_emit_byte(ctx, src);
+ acpigen_emit_byte(ctx, dst);
+}
+
+void acpigen_write_to_integer(struct acpi_ctx *ctx, uint src, uint dst)
+{
+ acpigen_emit_byte(ctx, TO_INTEGER_OP);
+ acpigen_emit_byte(ctx, src);
+ acpigen_emit_byte(ctx, dst);
+}
+
+void acpigen_write_byte_buffer(struct acpi_ctx *ctx, u8 *arr, size_t size)
+{
+ size_t i;
+
+ acpigen_emit_byte(ctx, BUFFER_OP);
+ acpigen_write_len_f(ctx);
+ acpigen_write_integer(ctx, size);
+
+ for (i = 0; i < size; i++)
+ acpigen_emit_byte(ctx, arr[i]);
+
+ acpigen_pop_len(ctx);
+}
+
+void acpigen_write_return_byte_buffer(struct acpi_ctx *ctx, u8 *arr,
+ size_t size)
+{
+ acpigen_emit_byte(ctx, RETURN_OP);
+ acpigen_write_byte_buffer(ctx, arr, size);
+}
+
+void acpigen_write_return_singleton_buffer(struct acpi_ctx *ctx, uint arg)
+{
+ u8 buf = arg;
+
+ acpigen_write_return_byte_buffer(ctx, &buf, 1);
+}
+
+void acpigen_write_return_byte(struct acpi_ctx *ctx, uint arg)
+{
+ acpigen_emit_byte(ctx, RETURN_OP);
+ acpigen_write_byte(ctx, arg);
+}
+
+void acpigen_write_dsm_start(struct acpi_ctx *ctx)
+{
+ /* Method (_DSM, 4, Serialized) */
+ acpigen_write_method_serialized(ctx, "_DSM", 4);
+
+ /* ToBuffer (Arg0, Local0) */
+ acpigen_write_to_buffer(ctx, ARG0_OP, LOCAL0_OP);
+}
+
+int acpigen_write_dsm_uuid_start(struct acpi_ctx *ctx, const char *uuid)
+{
+ int ret;
+
+ /* If (LEqual (Local0, ToUUID(uuid))) */
+ acpigen_write_if(ctx);
+ acpigen_emit_byte(ctx, LEQUAL_OP);
+ acpigen_emit_byte(ctx, LOCAL0_OP);
+ ret = acpigen_write_uuid(ctx, uuid);
+ if (ret)
+ return log_msg_ret("uuid", ret);
+
+ /* ToInteger (Arg2, Local1) */
+ acpigen_write_to_integer(ctx, ARG2_OP, LOCAL1_OP);
+
+ return 0;
+}
+
+void acpigen_write_dsm_uuid_start_cond(struct acpi_ctx *ctx, int seq)
+{
+ /* If (LEqual (Local1, i)) */
+ acpigen_write_if_lequal_op_int(ctx, LOCAL1_OP, seq);
+}
+
+void acpigen_write_dsm_uuid_end_cond(struct acpi_ctx *ctx)
+{
+ acpigen_pop_len(ctx); /* If */
+}
+
+void acpigen_write_dsm_uuid_end(struct acpi_ctx *ctx)
+{
+ /* Default case: Return (Buffer (One) { 0x0 }) */
+ acpigen_write_return_singleton_buffer(ctx, 0x0);
+
+ acpigen_pop_len(ctx); /* If (LEqual (Local0, ToUUID(uuid))) */
+}
+
+void acpigen_write_dsm_end(struct acpi_ctx *ctx)
+{
+ /* Return (Buffer (One) { 0x0 }) */
+ acpigen_write_return_singleton_buffer(ctx, 0x0);
+
+ acpigen_pop_len(ctx); /* Method _DSM */
+}
+
/**
* acpigen_get_dw0_in_local5() - Generate code to put dw0 cfg0 in local5
*
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index bad1a29ba80..ab42f3ba75b 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -164,6 +164,7 @@ config EFI_HAVE_RUNTIME_RESET
config EFI_GRUB_ARM32_WORKAROUND
bool "Workaround for GRUB on 32bit ARM"
+ default n if ARCH_QEMU
default y
depends on ARM && !ARM64
help
diff --git a/lib/efi_loader/efi_load_initrd.c b/lib/efi_loader/efi_load_initrd.c
index 574a83d7e30..d517d686c33 100644
--- a/lib/efi_loader/efi_load_initrd.c
+++ b/lib/efi_loader/efi_load_initrd.c
@@ -47,9 +47,9 @@ static const struct efi_initrd_dp dp = {
/**
* get_file_size() - retrieve the size of initramfs, set efi status on error
*
- * @dev: device to read from. i.e "mmc"
- * @part: device partition. i.e "0:1"
- * @file: name fo file
+ * @dev: device to read from, e.g. "mmc"
+ * @part: device partition, e.g. "0:1"
+ * @file: name of file
* @status: EFI exit code in case of failure
*
* Return: size of file
@@ -78,15 +78,16 @@ out:
}
/**
- * load_file2() - get information about random number generation
+ * efi_load_file2initrd() - load initial RAM disk
+ *
+ * This function implements the LoadFile service of the EFI_LOAD_FILE2_PROTOCOL
+ * in order to load an initial RAM disk requested by the Linux kernel stub.
*
- * This function implement the LoadFile2() service in order to load an initram
- * disk requested by the Linux kernel stub.
* See the UEFI spec for details.
*
- * @this: loadfile2 protocol instance
- * @file_path: relative path of the file. "" in this case
- * @boot_policy: must be false for Loadfile2
+ * @this: EFI_LOAD_FILE2_PROTOCOL instance
+ * @file_path: media device path of the file, "" in this case
+ * @boot_policy: must be false
* @buffer_size: size of allocated buffer
* @buffer: buffer to load the file
*
@@ -97,19 +98,20 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this,
struct efi_device_path *file_path, bool boot_policy,
efi_uintn_t *buffer_size, void *buffer)
{
- const char *filespec = CONFIG_EFI_INITRD_FILESPEC;
+ char *filespec;
efi_status_t status = EFI_NOT_FOUND;
loff_t file_sz = 0, read_sz = 0;
char *dev, *part, *file;
- char *s;
+ char *pos;
int ret;
EFI_ENTRY("%p, %p, %d, %p, %p", this, file_path, boot_policy,
buffer_size, buffer);
- s = strdup(filespec);
- if (!s)
+ filespec = strdup(CONFIG_EFI_INITRD_FILESPEC);
+ if (!filespec)
goto out;
+ pos = filespec;
if (!this || this != &efi_lf2_protocol ||
!buffer_size) {
@@ -128,14 +130,20 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this,
goto out;
}
- /* expect something like 'mmc 0:1 initrd.cpio.gz' */
- dev = strsep(&s, " ");
+ /*
+ * expect a string with three space separated parts:
+ *
+ * * a block device type, e.g. "mmc"
+ * * a device and partition identifier, e.g. "0:1"
+ * * a file path on the block device, e.g. "/boot/initrd.cpio.gz"
+ */
+ dev = strsep(&pos, " ");
if (!dev)
goto out;
- part = strsep(&s, " ");
+ part = strsep(&pos, " ");
if (!part)
goto out;
- file = strsep(&s, " ");
+ file = strsep(&pos, " ");
if (!file)
goto out;
@@ -163,28 +171,25 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this,
}
out:
- free(s);
+ free(filespec);
return EFI_EXIT(status);
}
/**
- * efi_initrd_register() - Register a handle and loadfile2 protocol
+ * efi_initrd_register() - create handle for loading initial RAM disk
*
- * This function creates a new handle and installs a linux specific GUID
- * to handle initram disk loading during boot.
- * See the UEFI spec for details.
+ * This function creates a new handle and installs a Linux specific vendor
+ * device path and an EFI_LOAD_FILE_2_PROTOCOL. Linux uses the device path
+ * to identify the handle and then calls the LoadFile service of the
+ * EFI_LOAD_FILE_2_PROTOCOL to read the initial RAM disk.
*
- * Return: status code
+ * Return: status code
*/
efi_status_t efi_initrd_register(void)
{
efi_handle_t efi_initrd_handle = NULL;
efi_status_t ret;
- /*
- * Set up the handle with the EFI_LOAD_FILE2_PROTOCOL which Linux may
- * use to load the initial ramdisk.
- */
ret = EFI_CALL(efi_install_multiple_protocol_interfaces
(&efi_initrd_handle,
/* initramfs */
diff --git a/lib/efi_selftest/efi_selftest.c b/lib/efi_selftest/efi_selftest.c
index 165fa265f23..85e819bdfa1 100644
--- a/lib/efi_selftest/efi_selftest.c
+++ b/lib/efi_selftest/efi_selftest.c
@@ -143,6 +143,27 @@ static int teardown(struct efi_unit_test *test, unsigned int *failures)
}
/*
+ * Check that a test requiring reset exists.
+ *
+ * @testname: name of the test
+ * @return: test, or NULL if not found
+ */
+static bool need_reset(const u16 *testname)
+{
+ struct efi_unit_test *test;
+
+ for (test = ll_entry_start(struct efi_unit_test, efi_unit_test);
+ test < ll_entry_end(struct efi_unit_test, efi_unit_test); ++test) {
+ if (testname && efi_st_strcmp_16_8(testname, test->name))
+ continue;
+ if (test->phase == EFI_SETUP_BEFORE_BOOTTIME_EXIT ||
+ test->phase == EFI_SETUP_AFTER_BOOTTIME_EXIT)
+ return true;
+ }
+ return false;
+}
+
+/*
* Check that a test exists.
*
* @testname: name of the test
@@ -290,6 +311,16 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle,
EFI_ST_SETUP | EFI_ST_EXECUTE | EFI_ST_TEARDOWN,
&failures);
+ if (!need_reset(testname)) {
+ if (failures)
+ ret = EFI_PROTOCOL_ERROR;
+
+ /* Give feedback */
+ efi_st_printc(EFI_WHITE, "\nSummary: %u failures\n\n",
+ failures);
+ return ret;
+ }
+
/* Execute mixed tests */
efi_st_do_tests(testname, EFI_SETUP_BEFORE_BOOTTIME_EXIT,
EFI_ST_SETUP, &failures);
diff --git a/lib/efi_selftest/efi_selftest_console.c b/lib/efi_selftest/efi_selftest_console.c
index 13f3ee6bc19..0219bd70e05 100644
--- a/lib/efi_selftest/efi_selftest_console.c
+++ b/lib/efi_selftest/efi_selftest_console.c
@@ -44,25 +44,28 @@ static void mac(void *pointer, u16 **buf)
}
/*
- * Print a pointer to an u16 string
+ * printx() - print hexadecimal number to an u16 string
*
- * @pointer: pointer
- * @buf: pointer to buffer address
- * on return position of terminating zero word
+ * @pointer: pointer
+ * @prec: minimum number of digits to print
+ * @buf: pointer to buffer address,
+ * on return position of terminating zero word
+ * @size: size of value to be printed in bytes
*/
-static void pointer(void *pointer, u16 **buf)
+static void printx(u64 p, int prec, u16 **buf)
{
int i;
u16 c;
- uintptr_t p = (uintptr_t)pointer;
u16 *pos = *buf;
- for (i = 8 * sizeof(p) - 4; i >= 0; i -= 4) {
- c = (p >> i) & 0x0f;
- c += '0';
- if (c > '9')
- c += 'a' - '9' - 1;
- *pos++ = c;
+ for (i = 2 * sizeof(p) - 1; i >= 0; --i) {
+ c = (p >> (4 * i)) & 0x0f;
+ if (c || pos != *buf || !i || i < prec) {
+ c += '0';
+ if (c > '9')
+ c += 'a' - '9' - 1;
+ *pos++ = c;
+ }
}
*pos = 0;
*buf = pos;
@@ -212,7 +215,9 @@ void efi_st_printc(int color, const char *fmt, ...)
break;
default:
--c;
- pointer(va_arg(args, void*), &pos);
+ printx((uintptr_t)va_arg(args, void *),
+ 2 * sizeof(void *), &pos);
+ break;
}
break;
case 's':
@@ -223,6 +228,10 @@ void efi_st_printc(int color, const char *fmt, ...)
case 'u':
uint2dec(va_arg(args, u32), prec, &pos);
break;
+ case 'x':
+ printx((u64)va_arg(args, unsigned int),
+ prec, &pos);
+ break;
default:
break;
}
diff --git a/lib/efi_selftest/efi_selftest_load_initrd.c b/lib/efi_selftest/efi_selftest_load_initrd.c
index e16163caca8..fe060a66440 100644
--- a/lib/efi_selftest/efi_selftest_load_initrd.c
+++ b/lib/efi_selftest/efi_selftest_load_initrd.c
@@ -200,7 +200,7 @@ static int execute(void)
efi_st_error("Could not determine CRC32\n");
return EFI_ST_FAILURE;
}
- efi_st_printf("CRC32 %u\n", (unsigned int)crc32);
+ efi_st_printf("CRC32 %.8x\n", (unsigned int)crc32);
status = boottime->free_pool(buf);
if (status != EFI_SUCCESS) {
diff --git a/lib/efi_selftest/efi_selftest_set_virtual_address_map.c b/lib/efi_selftest/efi_selftest_set_virtual_address_map.c
index a4e5a50f632..b097a811364 100644
--- a/lib/efi_selftest/efi_selftest_set_virtual_address_map.c
+++ b/lib/efi_selftest/efi_selftest_set_virtual_address_map.c
@@ -23,7 +23,7 @@ static u32 notify_call_count;
static bool convert_pointer_failed;
/**
- * notify () - notification function
+ * notify() - notification function
*
* This function is called when the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event
* occurs. The correct output of ConvertPointer() is checked.
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 5f41f58a63c..ee1bd41b081 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -746,7 +746,7 @@ int fdtdec_parse_phandle_with_args(const void *blob, int src_node,
if (cells_name || cur_index == index) {
node = fdt_node_offset_by_phandle(blob,
phandle);
- if (!node) {
+ if (node < 0) {
debug("%s: could not find phandle\n",
fdt_get_name(blob, src_node,
NULL));
@@ -1073,8 +1073,6 @@ int fdtdec_setup_mem_size_base(void)
return 0;
}
-#if defined(CONFIG_NR_DRAM_BANKS)
-
ofnode get_next_memory_node(ofnode mem)
{
do {
@@ -1170,7 +1168,6 @@ int fdtdec_setup_mem_size_base_lowest(void)
return 0;
}
-#endif
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
# if CONFIG_IS_ENABLED(MULTI_DTB_FIT_GZIP) ||\
@@ -1319,7 +1316,7 @@ static int fdtdec_init_reserved_memory(void *blob)
int fdtdec_add_reserved_memory(void *blob, const char *basename,
const struct fdt_memory *carveout,
- uint32_t *phandlep)
+ uint32_t *phandlep, bool no_map)
{
fdt32_t cells[4] = {}, *ptr = cells;
uint32_t upper, lower, phandle;
@@ -1419,6 +1416,12 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename,
if (err < 0)
return err;
+ if (no_map) {
+ err = fdt_setprop(blob, node, "no-map", NULL, 0);
+ if (err < 0)
+ return err;
+ }
+
/* return the phandle for the new node for the caller to use */
if (phandlep)
*phandlep = phandle;
@@ -1484,7 +1487,7 @@ int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name,
fdt32_t value;
void *prop;
- err = fdtdec_add_reserved_memory(blob, name, carveout, &phandle);
+ err = fdtdec_add_reserved_memory(blob, name, carveout, &phandle, false);
if (err < 0) {
debug("failed to add reserved memory: %d\n", err);
return err;
@@ -1633,7 +1636,6 @@ int fdtdec_resetup(int *rescan)
}
#endif
-#ifdef CONFIG_NR_DRAM_BANKS
int fdtdec_decode_ram_size(const void *blob, const char *area, int board_id,
phys_addr_t *basep, phys_size_t *sizep,
struct bd_info *bd)
@@ -1739,6 +1741,5 @@ int fdtdec_decode_ram_size(const void *blob, const char *area, int board_id,
return 0;
}
-#endif /* CONFIG_NR_DRAM_BANKS */
#endif /* !USE_HOSTCC */
diff --git a/lib/lmb.c b/lib/lmb.c
index 75082f35599..d126f8dc04a 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -117,22 +117,17 @@ static void lmb_reserve_common(struct lmb *lmb, void *fdt_blob)
/* Initialize the struct, add memory and call arch/board reserve functions */
void lmb_init_and_reserve(struct lmb *lmb, struct bd_info *bd, void *fdt_blob)
{
-#ifdef CONFIG_NR_DRAM_BANKS
int i;
-#endif
lmb_init(lmb);
-#ifdef CONFIG_NR_DRAM_BANKS
+
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
if (bd->bi_dram[i].size) {
lmb_add(lmb, bd->bi_dram[i].start,
bd->bi_dram[i].size);
}
}
-#else
- if (bd->bi_memsize)
- lmb_add(lmb, bd->bi_memstart, bd->bi_memsize);
-#endif
+
lmb_reserve_common(lmb, fdt_blob);
}
diff --git a/lib/optee/optee.c b/lib/optee/optee.c
index 457d4cca8a0..9e6606568f3 100644
--- a/lib/optee/optee.c
+++ b/lib/optee/optee.c
@@ -192,7 +192,7 @@ int optee_copy_fdt_nodes(const void *old_blob, void *new_blob)
ret = fdtdec_add_reserved_memory(new_blob,
nodename,
&carveout,
- NULL);
+ NULL, true);
free(oldname);
if (ret < 0)