X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=lib%2Fefi_loader%2Fefi_variable.c;h=889a7f2ba06f4a0189b9d988e40c4f07aa6c4f9c;hb=df9a7a195bdf0722399199bf373afc8309ae3ad7;hp=e0d7f5736db20cfe3d1d94c4c069d93f2edd6d98;hpb=e35171e94efdd0fa6c63083a682d452a2403bea1;p=oweals%2Fu-boot.git diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index e0d7f5736d..889a7f2ba0 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -125,6 +125,8 @@ static const char *parse_attr(const char *str, u32 *attrp) if ((s = prefix(str, "ro"))) { attr |= READ_ONLY; + } else if ((s = prefix(str, "nv"))) { + attr |= EFI_VARIABLE_NON_VOLATILE; } else if ((s = prefix(str, "boot"))) { attr |= EFI_VARIABLE_BOOTSERVICE_ACCESS; } else if ((s = prefix(str, "run"))) { @@ -146,7 +148,7 @@ static const char *parse_attr(const char *str, u32 *attrp) } /** - * efi_efi_get_variable() - retrieve value of a UEFI variable + * efi_get_variable() - retrieve value of a UEFI variable * * This function implements the GetVariable runtime service. * @@ -180,7 +182,7 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, if (ret) return EFI_EXIT(ret); - debug("%s: get '%s'\n", __func__, native_name); + EFI_PRINT("get '%s'\n", native_name); val = env_get(native_name); free(native_name); @@ -202,8 +204,10 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, len /= 2; *data_size = len; - if (in_size < len) - return EFI_EXIT(EFI_BUFFER_TOO_SMALL); + if (in_size < len) { + ret = EFI_BUFFER_TOO_SMALL; + goto out; + } if (!data) return EFI_EXIT(EFI_INVALID_PARAMETER); @@ -211,14 +215,16 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, if (hex2bin(data, s, len)) return EFI_EXIT(EFI_DEVICE_ERROR); - debug("%s: got value: \"%s\"\n", __func__, s); + EFI_PRINT("got value: \"%s\"\n", s); } else if ((s = prefix(val, "(utf8)"))) { unsigned len = strlen(s) + 1; *data_size = len; - if (in_size < len) - return EFI_EXIT(EFI_BUFFER_TOO_SMALL); + if (in_size < len) { + ret = EFI_BUFFER_TOO_SMALL; + goto out; + } if (!data) return EFI_EXIT(EFI_INVALID_PARAMETER); @@ -226,16 +232,17 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, memcpy(data, s, len); ((char *)data)[len] = '\0'; - debug("%s: got value: \"%s\"\n", __func__, (char *)data); + EFI_PRINT("got value: \"%s\"\n", (char *)data); } else { - debug("%s: invalid value: '%s'\n", __func__, val); + EFI_PRINT("invalid value: '%s'\n", val); return EFI_EXIT(EFI_DEVICE_ERROR); } +out: if (attributes) *attributes = attr & EFI_VARIABLE_MASK; - return EFI_EXIT(EFI_SUCCESS); + return EFI_EXIT(ret); } static char *efi_variables_list; @@ -256,8 +263,8 @@ static char *efi_cur_variable; * is the size of variable name including NULL. * * Return: EFI_SUCCESS if parsing is OK, EFI_NOT_FOUND when - the entire variable list has been returned, - otherwise non-zero status code + * the entire variable list has been returned, + * otherwise non-zero status code */ static efi_status_t parse_uboot_variable(char *variable, efi_uintn_t *variable_name_size, @@ -308,6 +315,7 @@ static efi_status_t parse_uboot_variable(char *variable, /** * efi_get_next_variable_name() - enumerate the current variable names + * * @variable_name_size: size of variable_name buffer in byte * @variable_name: name of uefi variable's name in u16 * @vendor: vendor's guid @@ -315,8 +323,7 @@ static efi_status_t parse_uboot_variable(char *variable, * This function implements the GetNextVariableName service. * * See the Unified Extensible Firmware Interface (UEFI) specification for - * details: http://wiki.phoenix.com/wiki/index.php/ - * EFI_RUNTIME_SERVICES#GetNextVariableName.28.29 + * details. * * Return: status code */ @@ -335,7 +342,7 @@ efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, EFI_ENTRY("%p \"%ls\" %pUl", variable_name_size, variable_name, vendor); if (!variable_name_size || !variable_name || !vendor) - EFI_EXIT(EFI_INVALID_PARAMETER); + return EFI_EXIT(EFI_INVALID_PARAMETER); if (variable_name[0]) { /* check null-terminated string */ @@ -397,7 +404,7 @@ efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, } /** - * efi_efi_set_variable() - set value of a UEFI variable + * efi_set_variable() - set value of a UEFI variable * * This function implements the SetVariable runtime service. * @@ -422,7 +429,11 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, EFI_ENTRY("\"%ls\" %pUl %x %zu %p", variable_name, vendor, attributes, data_size, data); - if (!variable_name || !vendor) { + /* TODO: implement APPEND_WRITE */ + if (!variable_name || !*variable_name || !vendor || + ((attributes & EFI_VARIABLE_RUNTIME_ACCESS) && + !(attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)) || + (attributes & EFI_VARIABLE_APPEND_WRITE)) { ret = EFI_INVALID_PARAMETER; goto out; } @@ -444,15 +455,24 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, if (val) { parse_attr(val, &attr); + /* We should not free val */ + val = NULL; if (attr & READ_ONLY) { - /* We should not free val */ - val = NULL; ret = EFI_WRITE_PROTECTED; goto out; } + + /* + * attributes won't be changed + * TODO: take care of APPEND_WRITE once supported + */ + if (attr != attributes) { + ret = EFI_INVALID_PARAMETER; + goto out; + } } - val = malloc(2 * data_size + strlen("{ro,run,boot}(blob)") + 1); + val = malloc(2 * data_size + strlen("{ro,run,boot,nv}(blob)") + 1); if (!val) { ret = EFI_OUT_OF_RESOURCES; goto out; @@ -464,12 +484,16 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, * store attributes * TODO: several attributes are not supported */ - attributes &= (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS); + attributes &= (EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS); s += sprintf(s, "{"); while (attributes) { u32 attr = 1 << (ffs(attributes) - 1); - if (attr == EFI_VARIABLE_BOOTSERVICE_ACCESS) + if (attr == EFI_VARIABLE_NON_VOLATILE) + s += sprintf(s, "nv"); + else if (attr == EFI_VARIABLE_BOOTSERVICE_ACCESS) s += sprintf(s, "boot"); else if (attr == EFI_VARIABLE_RUNTIME_ACCESS) s += sprintf(s, "run"); @@ -485,7 +509,7 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, s = bin2hex(s, data, data_size); *s = '\0'; - debug("%s: setting: %s=%s\n", __func__, native_name, val); + EFI_PRINT("setting: %s=%s\n", native_name, val); if (env_set(native_name, val)) ret = EFI_DEVICE_ERROR; @@ -496,3 +520,103 @@ out: return EFI_EXIT(ret); } + +/** + * efi_query_variable_info() - get information about EFI variables + * + * This function implements the QueryVariableInfo() runtime service. + * + * See the Unified Extensible Firmware Interface (UEFI) specification for + * details. + * + * @attributes: bitmask to select variables to be + * queried + * @maximum_variable_storage_size: maximum size of storage area for the + * selected variable types + * @remaining_variable_storage_size: remaining size of storage are for the + * selected variable types + * @maximum_variable_size: maximum size of a variable of the + * selected type + * Returns: status code + */ +efi_status_t __efi_runtime EFIAPI efi_query_variable_info( + u32 attributes, + u64 *maximum_variable_storage_size, + u64 *remaining_variable_storage_size, + u64 *maximum_variable_size) +{ + return EFI_UNSUPPORTED; +} + +/** + * efi_get_variable_runtime() - runtime implementation of GetVariable() + * + * @variable_name: name of the variable + * @vendor: vendor GUID + * @attributes: attributes of the variable + * @data_size: size of the buffer to which the variable value is copied + * @data: buffer to which the variable value is copied + * Return: status code + */ +static efi_status_t __efi_runtime EFIAPI +efi_get_variable_runtime(u16 *variable_name, const efi_guid_t *vendor, + u32 *attributes, efi_uintn_t *data_size, void *data) +{ + return EFI_UNSUPPORTED; +} + +/** + * efi_get_next_variable_name_runtime() - runtime implementation of + * GetNextVariable() + * + * @variable_name_size: size of variable_name buffer in byte + * @variable_name: name of uefi variable's name in u16 + * @vendor: vendor's guid + * Return: status code + */ +static efi_status_t __efi_runtime EFIAPI +efi_get_next_variable_name_runtime(efi_uintn_t *variable_name_size, + u16 *variable_name, const efi_guid_t *vendor) +{ + return EFI_UNSUPPORTED; +} + +/** + * efi_set_variable_runtime() - runtime implementation of SetVariable() + * + * @variable_name: name of the variable + * @vendor: vendor GUID + * @attributes: attributes of the variable + * @data_size: size of the buffer with the variable value + * @data: buffer with the variable value + * Return: status code + */ +static efi_status_t __efi_runtime EFIAPI +efi_set_variable_runtime(u16 *variable_name, const efi_guid_t *vendor, + u32 attributes, efi_uintn_t data_size, + const void *data) +{ + return EFI_UNSUPPORTED; +} + +/** + * efi_variables_boot_exit_notify() - notify ExitBootServices() is called + */ +void efi_variables_boot_exit_notify(void) +{ + efi_runtime_services.get_variable = efi_get_variable_runtime; + efi_runtime_services.get_next_variable_name = + efi_get_next_variable_name_runtime; + efi_runtime_services.set_variable = efi_set_variable_runtime; + efi_update_table_header_crc32(&efi_runtime_services.hdr); +} + +/** + * efi_init_variables() - initialize variable services + * + * Return: status code + */ +efi_status_t efi_init_variables(void) +{ + return EFI_SUCCESS; +}