diff options
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/efi/Kconfig | 21 | ||||
-rw-r--r-- | drivers/firmware/efi/Makefile | 5 | ||||
-rw-r--r-- | drivers/firmware/efi/apple-properties.c | 18 | ||||
-rw-r--r-- | drivers/firmware/efi/arm-init.c | 9 | ||||
-rw-r--r-- | drivers/firmware/efi/arm-runtime.c | 24 | ||||
-rw-r--r-- | drivers/firmware/efi/efi.c | 15 | ||||
-rw-r--r-- | drivers/firmware/efi/esrt.c | 3 | ||||
-rw-r--r-- | drivers/firmware/efi/fake_mem.c | 26 | ||||
-rw-r--r-- | drivers/firmware/efi/fake_mem.h | 10 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/Makefile | 5 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/arm-stub.c | 2 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/arm32-stub.c | 5 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/efi-stub-helper.c | 19 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/efistub.h | 2 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/random.c | 27 | ||||
-rw-r--r-- | drivers/firmware/efi/x86_fake_mem.c | 69 | ||||
-rw-r--r-- | drivers/firmware/stratix10-rsu.c | 42 | ||||
-rw-r--r-- | drivers/firmware/stratix10-svc.c | 18 |
18 files changed, 258 insertions, 62 deletions
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index b248870a9806..bcc378c19ebe 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -75,6 +75,27 @@ config EFI_MAX_FAKE_MEM Ranges can be set up to this value using comma-separated list. The default value is 8. +config EFI_SOFT_RESERVE + bool "Reserve EFI Specific Purpose Memory" + depends on EFI && EFI_STUB && ACPI_HMAT + default ACPI_HMAT + help + On systems that have mixed performance classes of memory EFI + may indicate specific purpose memory with an attribute (See + EFI_MEMORY_SP in UEFI 2.8). A memory range tagged with this + attribute may have unique performance characteristics compared + to the system's general purpose "System RAM" pool. On the + expectation that such memory has application specific usage, + and its base EFI memory type is "conventional" answer Y to + arrange for the kernel to reserve it as a "Soft Reserved" + resource, and set aside for direct-access (device-dax) by + default. The memory range can later be optionally assigned to + the page allocator by system administrator policy via the + device-dax kmem facility. Say N to have the kernel treat this + memory as "System RAM" by default. + + If unsure, say Y. + config EFI_PARAMS_FROM_FDT bool help diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index 4ac2de4dfa72..554d795270d9 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile @@ -20,13 +20,16 @@ obj-$(CONFIG_UEFI_CPER) += cper.o obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o obj-$(CONFIG_EFI_RUNTIME_WRAPPERS) += runtime-wrappers.o obj-$(CONFIG_EFI_STUB) += libstub/ -obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_mem.o +obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_map.o obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o obj-$(CONFIG_EFI_TEST) += test/ obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o +fake_map-y += fake_mem.o +fake_map-$(CONFIG_X86) += x86_fake_mem.o + arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o obj-$(CONFIG_ARM) += $(arm-obj-y) obj-$(CONFIG_ARM64) += $(arm-obj-y) diff --git a/drivers/firmware/efi/apple-properties.c b/drivers/firmware/efi/apple-properties.c index 0e206c9e0d7a..5ccf39986a14 100644 --- a/drivers/firmware/efi/apple-properties.c +++ b/drivers/firmware/efi/apple-properties.c @@ -53,7 +53,8 @@ static void __init unmarshal_key_value_pairs(struct dev_header *dev_header, for (i = 0; i < dev_header->prop_count; i++) { int remaining = dev_header->len - (ptr - (void *)dev_header); - u32 key_len, val_len; + u32 key_len, val_len, entry_len; + const u8 *entry_data; char *key; if (sizeof(key_len) > remaining) @@ -85,17 +86,14 @@ static void __init unmarshal_key_value_pairs(struct dev_header *dev_header, ucs2_as_utf8(key, ptr + sizeof(key_len), key_len - sizeof(key_len)); - entry[i].name = key; - entry[i].length = val_len - sizeof(val_len); - entry[i].is_array = !!entry[i].length; - entry[i].type = DEV_PROP_U8; - entry[i].pointer.u8_data = ptr + key_len + sizeof(val_len); - + entry_data = ptr + key_len + sizeof(val_len); + entry_len = val_len - sizeof(val_len); + entry[i] = PROPERTY_ENTRY_U8_ARRAY_LEN(key, entry_data, + entry_len); if (dump_properties) { - dev_info(dev, "property: %s\n", entry[i].name); + dev_info(dev, "property: %s\n", key); print_hex_dump(KERN_INFO, pr_fmt(), DUMP_PREFIX_OFFSET, - 16, 1, entry[i].pointer.u8_data, - entry[i].length, true); + 16, 1, entry_data, entry_len, true); } ptr += key_len + val_len; diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c index 311cd349a862..904fa09e6a6b 100644 --- a/drivers/firmware/efi/arm-init.c +++ b/drivers/firmware/efi/arm-init.c @@ -164,6 +164,15 @@ static __init int is_usable_memory(efi_memory_desc_t *md) case EFI_CONVENTIONAL_MEMORY: case EFI_PERSISTENT_MEMORY: /* + * Special purpose memory is 'soft reserved', which means it + * is set aside initially, but can be hotplugged back in or + * be assigned to the dax driver after boot. + */ + if (efi_soft_reserve_enabled() && + (md->attribute & EFI_MEMORY_SP)) + return false; + + /* * According to the spec, these regions are no longer reserved * after calling ExitBootServices(). However, we can only use * them as System RAM if they can be mapped writeback cacheable. diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c index e2ac5fa5531b..899b803842bb 100644 --- a/drivers/firmware/efi/arm-runtime.c +++ b/drivers/firmware/efi/arm-runtime.c @@ -121,6 +121,30 @@ static int __init arm_enable_runtime_services(void) return 0; } + if (efi_soft_reserve_enabled()) { + efi_memory_desc_t *md; + + for_each_efi_memory_desc(md) { + int md_size = md->num_pages << EFI_PAGE_SHIFT; + struct resource *res; + + if (!(md->attribute & EFI_MEMORY_SP)) + continue; + + res = kzalloc(sizeof(*res), GFP_KERNEL); + if (WARN_ON(!res)) + break; + + res->start = md->phys_addr; + res->end = md->phys_addr + md_size - 1; + res->name = "Soft Reserved"; + res->flags = IORESOURCE_MEM; + res->desc = IORES_DESC_SOFT_RESERVED; + + insert_resource(&iomem_resource, res); + } + } + if (efi_runtime_disabled()) { pr_info("EFI runtime services will be disabled.\n"); return 0; diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index e98bbf8e56d9..d101f072c8f8 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -81,6 +81,11 @@ bool efi_runtime_disabled(void) return disable_runtime; } +bool __pure __efi_soft_reserve_enabled(void) +{ + return !efi_enabled(EFI_MEM_NO_SOFT_RESERVE); +} + static int __init parse_efi_cmdline(char *str) { if (!str) { @@ -94,6 +99,9 @@ static int __init parse_efi_cmdline(char *str) if (parse_option_str(str, "noruntime")) disable_runtime = true; + if (parse_option_str(str, "nosoftreserve")) + set_bit(EFI_MEM_NO_SOFT_RESERVE, &efi.flags); + return 0; } early_param("efi", parse_efi_cmdline); @@ -296,7 +304,7 @@ static __init int efivar_ssdt_load(void) goto free_data; } - ret = acpi_load_table(data); + ret = acpi_load_table(data, NULL); if (ret) { pr_err("failed to load table: %d\n", ret); goto free_data; @@ -842,15 +850,16 @@ char * __init efi_md_typeattr_format(char *buf, size_t size, if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO | EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP | - EFI_MEMORY_NV | + EFI_MEMORY_NV | EFI_MEMORY_SP | EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE)) snprintf(pos, size, "|attr=0x%016llx]", (unsigned long long)attr); else snprintf(pos, size, - "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", + "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", attr & EFI_MEMORY_RUNTIME ? "RUN" : "", attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "", + attr & EFI_MEMORY_SP ? "SP" : "", attr & EFI_MEMORY_NV ? "NV" : "", attr & EFI_MEMORY_XP ? "XP" : "", attr & EFI_MEMORY_RP ? "RP" : "", diff --git a/drivers/firmware/efi/esrt.c b/drivers/firmware/efi/esrt.c index d6dd5f503fa2..2762e0662bf4 100644 --- a/drivers/firmware/efi/esrt.c +++ b/drivers/firmware/efi/esrt.c @@ -246,6 +246,9 @@ void __init efi_esrt_init(void) int rc; phys_addr_t end; + if (!efi_enabled(EFI_MEMMAP)) + return; + pr_debug("esrt-init: loading.\n"); if (!esrt_table_exists()) return; diff --git a/drivers/firmware/efi/fake_mem.c b/drivers/firmware/efi/fake_mem.c index 9501edc0fcfb..bb9fc70d0cfa 100644 --- a/drivers/firmware/efi/fake_mem.c +++ b/drivers/firmware/efi/fake_mem.c @@ -17,12 +17,10 @@ #include <linux/memblock.h> #include <linux/types.h> #include <linux/sort.h> -#include <asm/efi.h> +#include "fake_mem.h" -#define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKE_MEM - -static struct efi_mem_range fake_mems[EFI_MAX_FAKEMEM]; -static int nr_fake_mem; +struct efi_mem_range efi_fake_mems[EFI_MAX_FAKEMEM]; +int nr_fake_mem; static int __init cmp_fake_mem(const void *x1, const void *x2) { @@ -44,13 +42,13 @@ void __init efi_fake_memmap(void) void *new_memmap; int i; - if (!nr_fake_mem) + if (!efi_enabled(EFI_MEMMAP) || !nr_fake_mem) return; /* count up the number of EFI memory descriptor */ for (i = 0; i < nr_fake_mem; i++) { for_each_efi_memory_desc(md) { - struct range *r = &fake_mems[i].range; + struct range *r = &efi_fake_mems[i].range; new_nr_map += efi_memmap_split_count(md, r); } @@ -70,7 +68,7 @@ void __init efi_fake_memmap(void) } for (i = 0; i < nr_fake_mem; i++) - efi_memmap_insert(&efi.memmap, new_memmap, &fake_mems[i]); + efi_memmap_insert(&efi.memmap, new_memmap, &efi_fake_mems[i]); /* swap into new EFI memmap */ early_memunmap(new_memmap, efi.memmap.desc_size * new_nr_map); @@ -104,22 +102,22 @@ static int __init setup_fake_mem(char *p) if (nr_fake_mem >= EFI_MAX_FAKEMEM) break; - fake_mems[nr_fake_mem].range.start = start; - fake_mems[nr_fake_mem].range.end = start + mem_size - 1; - fake_mems[nr_fake_mem].attribute = attribute; + efi_fake_mems[nr_fake_mem].range.start = start; + efi_fake_mems[nr_fake_mem].range.end = start + mem_size - 1; + efi_fake_mems[nr_fake_mem].attribute = attribute; nr_fake_mem++; if (*p == ',') p++; } - sort(fake_mems, nr_fake_mem, sizeof(struct efi_mem_range), + sort(efi_fake_mems, nr_fake_mem, sizeof(struct efi_mem_range), cmp_fake_mem, NULL); for (i = 0; i < nr_fake_mem; i++) pr_info("efi_fake_mem: add attr=0x%016llx to [mem 0x%016llx-0x%016llx]", - fake_mems[i].attribute, fake_mems[i].range.start, - fake_mems[i].range.end); + efi_fake_mems[i].attribute, efi_fake_mems[i].range.start, + efi_fake_mems[i].range.end); return *p == '\0' ? 0 : -EINVAL; } diff --git a/drivers/firmware/efi/fake_mem.h b/drivers/firmware/efi/fake_mem.h new file mode 100644 index 000000000000..d52791af4b18 --- /dev/null +++ b/drivers/firmware/efi/fake_mem.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __EFI_FAKE_MEM_H__ +#define __EFI_FAKE_MEM_H__ +#include <asm/efi.h> + +#define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKE_MEM + +extern struct efi_mem_range efi_fake_mems[EFI_MAX_FAKEMEM]; +extern int nr_fake_mem; +#endif /* __EFI_FAKE_MEM_H__ */ diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index ee0661ddb25b..c35f893897e1 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -38,7 +38,8 @@ OBJECT_FILES_NON_STANDARD := y # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. KCOV_INSTRUMENT := n -lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o +lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \ + random.o # include the stub's generic dependencies from lib/ when building for ARM/arm64 arm-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c @@ -47,7 +48,7 @@ arm-deps-$(CONFIG_ARM64) += sort.c $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE $(call if_changed_rule,cc_o_c) -lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o random.o \ +lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o \ $(patsubst %.c,lib-%.o,$(arm-deps-y)) lib-$(CONFIG_ARM) += arm32-stub.o diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c index c382a48c6678..817237ce2420 100644 --- a/drivers/firmware/efi/libstub/arm-stub.c +++ b/drivers/firmware/efi/libstub/arm-stub.c @@ -189,6 +189,8 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table, goto fail_free_cmdline; } + efi_retrieve_tpm2_eventlog(sys_table); + /* Ask the firmware to clear memory on unclean shutdown */ efi_enable_reset_attack_mitigation(sys_table); diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c index 41213bf5fcf5..4566640de650 100644 --- a/drivers/firmware/efi/libstub/arm32-stub.c +++ b/drivers/firmware/efi/libstub/arm32-stub.c @@ -146,6 +146,11 @@ static efi_status_t reserve_kernel_base(efi_system_table_t *sys_table_arg, continue; case EFI_CONVENTIONAL_MEMORY: + /* Skip soft reserved conventional memory */ + if (efi_soft_reserve_enabled() && + (desc->attribute & EFI_MEMORY_SP)) + continue; + /* * Reserve the intersection between this entry and the * region. diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 35dbc2791c97..e02579907f2e 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -32,6 +32,7 @@ static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE; static int __section(.data) __nokaslr; static int __section(.data) __quiet; static int __section(.data) __novamap; +static bool __section(.data) efi_nosoftreserve; int __pure nokaslr(void) { @@ -45,6 +46,10 @@ int __pure novamap(void) { return __novamap; } +bool __pure __efi_soft_reserve_enabled(void) +{ + return !efi_nosoftreserve; +} #define EFI_MMAP_NR_SLACK_SLOTS 8 @@ -211,6 +216,10 @@ again: if (desc->type != EFI_CONVENTIONAL_MEMORY) continue; + if (efi_soft_reserve_enabled() && + (desc->attribute & EFI_MEMORY_SP)) + continue; + if (desc->num_pages < nr_pages) continue; @@ -305,6 +314,10 @@ efi_status_t efi_low_alloc_above(efi_system_table_t *sys_table_arg, if (desc->type != EFI_CONVENTIONAL_MEMORY) continue; + if (efi_soft_reserve_enabled() && + (desc->attribute & EFI_MEMORY_SP)) + continue; + if (desc->num_pages < nr_pages) continue; @@ -484,6 +497,12 @@ efi_status_t efi_parse_options(char const *cmdline) __novamap = 1; } + if (IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) && + !strncmp(str, "nosoftreserve", 7)) { + str += strlen("nosoftreserve"); + efi_nosoftreserve = 1; + } + /* Group words together, delimited by "," */ while (*str && *str != ' ' && *str != ',') str++; diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index 7f1556fd867d..05739ae013c8 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -63,8 +63,6 @@ efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg, efi_status_t check_platform_features(efi_system_table_t *sys_table_arg); -efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg); - void *get_efi_config_table(efi_system_table_t *sys_table, efi_guid_t guid); /* Helper macros for the usual case of using simple C variables: */ diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c index b4b1d1dcb5fd..35edd7cfb6a1 100644 --- a/drivers/firmware/efi/libstub/random.c +++ b/drivers/firmware/efi/libstub/random.c @@ -9,6 +9,18 @@ #include "efistub.h" +typedef struct efi_rng_protocol efi_rng_protocol_t; + +typedef struct { + u32 get_info; + u32 get_rng; +} efi_rng_protocol_32_t; + +typedef struct { + u64 get_info; + u64 get_rng; +} efi_rng_protocol_64_t; + struct efi_rng_protocol { efi_status_t (*get_info)(struct efi_rng_protocol *, unsigned long *, efi_guid_t *); @@ -28,7 +40,7 @@ efi_status_t efi_get_random_bytes(efi_system_table_t *sys_table_arg, if (status != EFI_SUCCESS) return status; - return rng->get_rng(rng, NULL, size, out); + return efi_call_proto(efi_rng_protocol, get_rng, rng, NULL, size, out); } /* @@ -46,6 +58,10 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md, if (md->type != EFI_CONVENTIONAL_MEMORY) return 0; + if (efi_soft_reserve_enabled() && + (md->attribute & EFI_MEMORY_SP)) + return 0; + region_end = min((u64)ULONG_MAX, md->phys_addr + md->num_pages*EFI_PAGE_SIZE - 1); first_slot = round_up(md->phys_addr, align); @@ -161,15 +177,16 @@ efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg) if (status != EFI_SUCCESS) return status; - status = rng->get_rng(rng, &rng_algo_raw, EFI_RANDOM_SEED_SIZE, - seed->bits); + status = efi_call_proto(efi_rng_protocol, get_rng, rng, &rng_algo_raw, + EFI_RANDOM_SEED_SIZE, seed->bits); + if (status == EFI_UNSUPPORTED) /* * Use whatever algorithm we have available if the raw algorithm * is not implemented. */ - status = rng->get_rng(rng, NULL, EFI_RANDOM_SEED_SIZE, - seed->bits); + status = efi_call_proto(efi_rng_protocol, get_rng, rng, NULL, + EFI_RANDOM_SEED_SIZE, seed->bits); if (status != EFI_SUCCESS) goto err_freepool; diff --git a/drivers/firmware/efi/x86_fake_mem.c b/drivers/firmware/efi/x86_fake_mem.c new file mode 100644 index 000000000000..e5d6d5a1b240 --- /dev/null +++ b/drivers/firmware/efi/x86_fake_mem.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2019 Intel Corporation. All rights reserved. */ +#include <linux/efi.h> +#include <asm/e820/api.h> +#include "fake_mem.h" + +void __init efi_fake_memmap_early(void) +{ + int i; + + /* + * The late efi_fake_mem() call can handle all requests if + * EFI_MEMORY_SP support is disabled. + */ + if (!efi_soft_reserve_enabled()) + return; + + if (!efi_enabled(EFI_MEMMAP) || !nr_fake_mem) + return; + + /* + * Given that efi_fake_memmap() needs to perform memblock + * allocations it needs to run after e820__memblock_setup(). + * However, if efi_fake_mem specifies EFI_MEMORY_SP for a given + * address range that potentially needs to mark the memory as + * reserved prior to e820__memblock_setup(). Update e820 + * directly if EFI_MEMORY_SP is specified for an + * EFI_CONVENTIONAL_MEMORY descriptor. + */ + for (i = 0; i < nr_fake_mem; i++) { + struct efi_mem_range *mem = &efi_fake_mems[i]; + efi_memory_desc_t *md; + u64 m_start, m_end; + + if ((mem->attribute & EFI_MEMORY_SP) == 0) + continue; + + m_start = mem->range.start; + m_end = mem->range.end; + for_each_efi_memory_desc(md) { + u64 start, end; + + if (md->type != EFI_CONVENTIONAL_MEMORY) + continue; + + start = md->phys_addr; + end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1; + + if (m_start <= end && m_end >= start) + /* fake range overlaps descriptor */; + else + continue; + + /* + * Trim the boundary of the e820 update to the + * descriptor in case the fake range overlaps + * !EFI_CONVENTIONAL_MEMORY + */ + start = max(start, m_start); + end = min(end, m_end); + + if (end <= start) + continue; + e820__range_update(start, end - start + 1, E820_TYPE_RAM, + E820_TYPE_SOFT_RESERVED); + e820__update_table(e820_table); + } + } +} diff --git a/drivers/firmware/stratix10-rsu.c b/drivers/firmware/stratix10-rsu.c index bb008c019920..f8533338b018 100644 --- a/drivers/firmware/stratix10-rsu.c +++ b/drivers/firmware/stratix10-rsu.c @@ -20,7 +20,6 @@ #define RSU_VERSION_MASK GENMASK_ULL(63, 32) #define RSU_ERROR_LOCATION_MASK GENMASK_ULL(31, 0) #define RSU_ERROR_DETAIL_MASK GENMASK_ULL(63, 32) -#define RSU_FW_VERSION_MASK GENMASK_ULL(15, 0) #define RSU_TIMEOUT (msecs_to_jiffies(SVC_RSU_REQUEST_TIMEOUT_MS)) @@ -109,9 +108,12 @@ static void rsu_command_callback(struct stratix10_svc_client *client, { struct stratix10_rsu_priv *priv = client->priv; - if (data->status != BIT(SVC_STATUS_RSU_OK)) - dev_err(client->dev, "RSU returned status is %i\n", - data->status); + if (data->status == BIT(SVC_STATUS_RSU_NO_SUPPORT)) + dev_warn(client->dev, "Secure FW doesn't support notify\n"); + else if (data->status == BIT(SVC_STATUS_RSU_ERROR)) + dev_err(client->dev, "Failure, returned status is %lu\n", + BIT(data->status)); + complete(&priv->completion); } @@ -133,9 +135,11 @@ static void rsu_retry_callback(struct stratix10_svc_client *client, if (data->status == BIT(SVC_STATUS_RSU_OK)) priv->retry_counter = *counter; + else if (data->status == BIT(SVC_STATUS_RSU_NO_SUPPORT)) + dev_warn(client->dev, "Secure FW doesn't support retry\n"); else - dev_err(client->dev, "Failed to get retry counter %i\n", - data->status); + dev_err(client->dev, "Failed to get retry counter %lu\n", + BIT(data->status)); complete(&priv->completion); } @@ -333,15 +337,10 @@ static ssize_t notify_store(struct device *dev, return ret; } - /* only 19.3 or late version FW supports retry counter feature */ - if (FIELD_GET(RSU_FW_VERSION_MASK, priv->status.version)) { - ret = rsu_send_msg(priv, COMMAND_RSU_RETRY, - 0, rsu_retry_callback); - if (ret) { - dev_err(dev, - "Error, getting RSU retry %i\n", ret); - return ret; - } + ret = rsu_send_msg(priv, COMMAND_RSU_RETRY, 0, rsu_retry_callback); + if (ret) { + dev_err(dev, "Error, getting RSU retry %i\n", ret); + return ret; } return count; @@ -413,15 +412,10 @@ static int stratix10_rsu_probe(struct platform_device *pdev) stratix10_svc_free_channel(priv->chan); } - /* only 19.3 or late version FW supports retry counter feature */ - if (FIELD_GET(RSU_FW_VERSION_MASK, priv->status.version)) { - ret = rsu_send_msg(priv, COMMAND_RSU_RETRY, 0, - rsu_retry_callback); - if (ret) { - dev_err(dev, - "Error, getting RSU retry %i\n", ret); - stratix10_svc_free_channel(priv->chan); - } + ret = rsu_send_msg(priv, COMMAND_RSU_RETRY, 0, rsu_retry_callback); + if (ret) { + dev_err(dev, "Error, getting RSU retry %i\n", ret); + stratix10_svc_free_channel(priv->chan); } return ret; diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c index b485321189e1..c6c31402848d 100644 --- a/drivers/firmware/stratix10-svc.c +++ b/drivers/firmware/stratix10-svc.c @@ -493,8 +493,24 @@ static int svc_normal_to_secure_thread(void *data) pdata->chan->scl->receive_cb(pdata->chan->scl, cbdata); break; default: - pr_warn("it shouldn't happen\n"); + pr_warn("Secure firmware doesn't support...\n"); + + /* + * be compatible with older version firmware which + * doesn't support RSU notify or retry + */ + if ((pdata->command == COMMAND_RSU_RETRY) || + (pdata->command == COMMAND_RSU_NOTIFY)) { + cbdata->status = + BIT(SVC_STATUS_RSU_NO_SUPPORT); + cbdata->kaddr1 = NULL; + cbdata->kaddr2 = NULL; + cbdata->kaddr3 = NULL; + pdata->chan->scl->receive_cb( + pdata->chan->scl, cbdata); + } break; + } }; |