diff options
author | Tom Rini <trini@konsulko.com> | 2024-11-03 17:23:29 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2024-11-03 21:27:13 -0600 |
commit | bf066dc3ebfe79ed24f889a41abe43d48d26c454 (patch) | |
tree | 7a967c47cb8d2bc242b241f35d3dcdaee257a883 /cmd/x86/cbcmos.c | |
parent | 93cfcb026a124b133e85a025c51fcc6c85bc385e (diff) | |
parent | dc24948a457e2f5cb7c518a9458be851b8b7e9ea (diff) |
Merge tag 'dm-pull-2nov24' of https://source.denx.de/u-boot/custodians/u-boot-dm
CI: https://source.denx.de/u-boot/custodians/u-boot-dm/-/pipelines/23152
CI: https://dev.azure.com/simon0972/u-boot/_build/results?buildId=71&view=results
- alist enhancements and fixes
- minor test and sandbox fixes
- some more x86/coreboot patches
Diffstat (limited to 'cmd/x86/cbcmos.c')
-rw-r--r-- | cmd/x86/cbcmos.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/cmd/x86/cbcmos.c b/cmd/x86/cbcmos.c new file mode 100644 index 00000000000..fe5582fbf51 --- /dev/null +++ b/cmd/x86/cbcmos.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Support for booting from coreboot + * + * Copyright 2021 Google LLC + */ + +#define LOG_CATEGORY UCLASS_RTC + +#include <command.h> +#include <dm.h> +#include <rtc.h> +#include <asm/cb_sysinfo.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +const struct sysinfo_t *get_table(void) +{ + if (!gd->arch.coreboot_table) { + printf("No coreboot sysinfo table found\n"); + return NULL; + } + + return &lib_sysinfo; +} + +static int calc_sum(struct udevice *dev, uint start_bit, uint bit_count) +{ + uint start_byte = start_bit / 8; + uint byte_count = bit_count / 8; + int ret, i; + uint sum; + + log_debug("Calc sum from %x: %x bytes\n", start_byte, byte_count); + sum = 0; + for (i = 0; i < bit_count / 8; i++) { + ret = rtc_read8(dev, start_bit / 8 + i); + if (ret < 0) + return ret; + sum += ret; + } + + return (sum & 0xff) << 8 | (sum & 0xff00) >> 8; +} + +/** + * prep_cbcmos() - Prepare for a CMOS-RAM command + * + * @tab: coreboot table + * @devnum: RTC device name to use, or NULL for the first one + * @dep: Returns RTC device on success + * Return: calculated checksum for CMOS RAM or -ve on error + */ +static int prep_cbcmos(const struct sysinfo_t *tab, const char *devname, + struct udevice **devp) +{ + struct udevice *dev; + int ret; + + if (!tab) + return CMD_RET_FAILURE; + if (devname) + ret = uclass_get_device_by_name(UCLASS_RTC, devname, &dev); + else + ret = uclass_first_device_err(UCLASS_RTC, &dev); + if (ret) { + printf("Failed to get RTC device: %dE\n", ret); + return ret; + } + + ret = calc_sum(dev, tab->cmos_range_start, + tab->cmos_range_end + 1 - tab->cmos_range_start); + if (ret < 0) { + printf("Failed to read RTC device: %dE\n", ret); + return ret; + } + *devp = dev; + + return ret; +} + +static int do_cbcmos_check(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + const struct sysinfo_t *tab = get_table(); + struct udevice *dev; + u16 cur, sum; + int ret; + + ret = prep_cbcmos(tab, argv[1], &dev); + if (ret < 0) + return CMD_RET_FAILURE; + sum = ret; + + ret = rtc_read16(dev, tab->cmos_checksum_location / 8, &cur); + if (ret < 0) { + printf("Failed to read RTC device: %dE\n", ret); + return CMD_RET_FAILURE; + } + if (sum != cur) { + printf("Checksum %04x error: calculated %04x\n", cur, sum); + return CMD_RET_FAILURE; + } + + return 0; +} + +static int do_cbcmos_update(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + const struct sysinfo_t *tab = get_table(); + struct udevice *dev; + u16 sum; + int ret; + + ret = prep_cbcmos(tab, argv[1], &dev); + if (ret < 0) + return CMD_RET_FAILURE; + sum = ret; + + ret = rtc_write16(dev, tab->cmos_checksum_location / 8, sum); + if (ret < 0) { + printf("Failed to read RTC device: %dE\n", ret); + return CMD_RET_FAILURE; + } + printf("Checksum %04x written\n", sum); + + return 0; +} + +U_BOOT_LONGHELP(cbcmos, + "check - check CMOS RAM\n" + "cbcmos update - Update CMOS-RAM checksum"; +); + +U_BOOT_CMD_WITH_SUBCMDS(cbcmos, "coreboot CMOS RAM", cbcmos_help_text, + U_BOOT_SUBCMD_MKENT(check, 2, 1, do_cbcmos_check), + U_BOOT_SUBCMD_MKENT(update, 2, 1, do_cbcmos_update)); |