diff options
author | Hung-Te Lin <hungte@chromium.org> | 2019-05-27 11:02:00 +0800 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2019-06-03 13:22:01 +0000 |
commit | c345570acce55a2cb13a65bf06c4e1d8069f7b36 (patch) | |
tree | c75a2e8bf0421b2554515d4c866965b14e588eb6 /src/drivers/vpd/vpd_decode.c | |
parent | 6681f05373c2ec07168e279026962d7a63539e93 (diff) | |
download | coreboot-c345570acce55a2cb13a65bf06c4e1d8069f7b36.tar.xz |
src/driver/vpd: Update lib_vpd from upstream
Update lib_vpd.c (only containing vpd_decode.c) to latest version from
https://chromium.googlesource.com/chromiumos/platform/vpd
The called module (vpd.c) has been also corrected for new lib_vpd
types and constants.
BUG=chromium:967209
TEST=select VPD config on kukui; make; boots on at least kukui boards.
Change-Id: I3928e9c43cb87caf93fb44ee10434ce80f0a188a
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/33016
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Joel Kitching <kitching@google.com>
Diffstat (limited to 'src/drivers/vpd/vpd_decode.c')
-rw-r--r-- | src/drivers/vpd/vpd_decode.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/drivers/vpd/vpd_decode.c b/src/drivers/vpd/vpd_decode.c new file mode 100644 index 0000000000..0eab704ca8 --- /dev/null +++ b/src/drivers/vpd/vpd_decode.c @@ -0,0 +1,92 @@ +/* + * Copyright 2014 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This is a copy from upstream: + * https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/lib/vpd_decode.c + */ +#include "vpd_decode.h" + +int vpd_decode_len( + const u32 max_len, const u8 *in, u32 *length, u32 *decoded_len) +{ + u8 more; + int i = 0; + + if (!length || !decoded_len) + return VPD_DECODE_FAIL; + + *length = 0; + do { + if (i >= max_len) + return VPD_DECODE_FAIL; + + more = in[i] & 0x80; + *length <<= 7; + *length |= in[i] & 0x7f; + ++i; + } while (more); + + *decoded_len = i; + return VPD_DECODE_OK; +} + +int vpd_decode_string( + const u32 max_len, const u8 *input_buf, u32 *consumed, + vpd_decode_callback callback, void *callback_arg) +{ + int type; + int res; + u32 key_len; + u32 value_len; + u32 decoded_len; + const u8 *key; + const u8 *value; + + /* type */ + if (*consumed >= max_len) + return VPD_DECODE_FAIL; + + type = input_buf[*consumed]; + + switch (type) { + case VPD_TYPE_INFO: + case VPD_TYPE_STRING: + (*consumed)++; + + /* key */ + res = vpd_decode_len(max_len - *consumed, &input_buf[*consumed], + &key_len, &decoded_len); + /* key name cannot be empty, and must be followed by value. */ + if (res != VPD_DECODE_OK || key_len < 1 || + *consumed + decoded_len + key_len >= max_len) + return VPD_DECODE_FAIL; + + *consumed += decoded_len; + key = &input_buf[*consumed]; + *consumed += key_len; + + /* value */ + res = vpd_decode_len(max_len - *consumed, &input_buf[*consumed], + &value_len, &decoded_len); + /* value can be empty (value_len = 0). */ + if (res != VPD_DECODE_OK || + *consumed + decoded_len + value_len > max_len) + return VPD_DECODE_FAIL; + + *consumed += decoded_len; + value = &input_buf[*consumed]; + *consumed += value_len; + + if (type == VPD_TYPE_STRING) + return callback(key, key_len, value, value_len, + callback_arg); + break; + + default: + return VPD_DECODE_FAIL; + } + + return VPD_DECODE_OK; +} |