diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig | 8 | ||||
-rw-r--r-- | lib/acpi/acpi_device.c | 45 | ||||
-rw-r--r-- | lib/acpi/acpi_dp.c | 4 | ||||
-rw-r--r-- | lib/acpi/acpi_table.c | 64 | ||||
-rw-r--r-- | lib/acpi/acpigen.c | 354 | ||||
-rw-r--r-- | lib/efi_loader/Kconfig | 1 | ||||
-rw-r--r-- | lib/efi_loader/efi_load_initrd.c | 59 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest.c | 31 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest_console.c | 35 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest_load_initrd.c | 2 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest_set_virtual_address_map.c | 2 | ||||
-rw-r--r-- | lib/fdtdec.c | 17 | ||||
-rw-r--r-- | lib/lmb.c | 9 | ||||
-rw-r--r-- | lib/optee/optee.c | 2 |
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) |