From 4bbaa88fad00205b6f2ae9ea0e57cfd878354a3a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jul 2021 16:32:39 -0600 Subject: dm: core: Add logging for DM_SEQ_ALIAS It is sometimes helpful to see which sequence is assigned to a device. Add debugging info for that. Signed-off-by: Simon Glass --- drivers/core/device.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/core/device.c b/drivers/core/device.c index 9f1400768de..29668f6fb30 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -87,8 +87,10 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { if (uc->uc_drv->name && ofnode_valid(node)) { - if (!dev_read_alias_seq(dev, &dev->seq_)) + if (!dev_read_alias_seq(dev, &dev->seq_)) { auto_seq = false; + log_debug(" - seq=%d\n", dev->seq_); + } } } } -- cgit v1.3.1 From 504fb6699778c77be80498400ef6206204f69a6b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jul 2021 16:32:40 -0600 Subject: dm: Support lzma in the flashmap Allow lzma compression as well as lz4. Signed-off-by: Simon Glass --- drivers/core/of_extra.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/core/of_extra.c b/drivers/core/of_extra.c index 7702beff97b..632a1c2210e 100644 --- a/drivers/core/of_extra.c +++ b/drivers/core/of_extra.c @@ -31,6 +31,8 @@ int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry) if (prop) { if (!strcmp(prop, "lz4")) entry->compress_algo = FMAP_COMPRESS_LZ4; + else if (!strcmp(prop, "lzma")) + entry->compress_algo = FMAP_COMPRESS_LZMA; else return log_msg_ret("compression algo", -EINVAL); } else { -- cgit v1.3.1 From 201efb2bb0f7c4ae5f08f51b6f6b7cdfdba5b4f4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jul 2021 16:32:49 -0600 Subject: cros_ec: Allow reading the battery-charge state Add a function to read this information from the EC. It is useful for determining whether the battery has enough charge to boot. Signed-off-by: Simon Glass --- drivers/misc/cros_ec.c | 17 +++++++++++++++++ include/cros_ec.h | 8 ++++++++ 2 files changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index 7904d5cc72d..0818ef8ad6e 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -1661,6 +1661,23 @@ int cros_ec_get_switches(struct udevice *dev) return ret; } +int cros_ec_read_batt_charge(struct udevice *dev, uint *chargep) +{ + struct ec_params_charge_state req; + struct ec_response_charge_state resp; + int ret; + + req.cmd = CHARGE_STATE_CMD_GET_STATE; + ret = ec_command(dev, EC_CMD_CHARGE_STATE, 0, &req, sizeof(req), + &resp, sizeof(resp)); + if (ret) + return log_msg_ret("read", ret); + + *chargep = resp.get_state.batt_state_of_charge; + + return 0; +} + UCLASS_DRIVER(cros_ec) = { .id = UCLASS_CROS_EC, .name = "cros-ec", diff --git a/include/cros_ec.h b/include/cros_ec.h index 9396b4d2466..9dab6cdf9ba 100644 --- a/include/cros_ec.h +++ b/include/cros_ec.h @@ -652,4 +652,12 @@ int cros_ec_vstore_read(struct udevice *dev, int slot, uint8_t *data); int cros_ec_vstore_write(struct udevice *dev, int slot, const uint8_t *data, size_t size); +/** + * cros_ec_read_batt_charge() - Read the battery-charge state + * + * @dev: CROS-EC device + * @chargep: Return battery-charge state as a percentage + */ +int cros_ec_read_batt_charge(struct udevice *dev, uint *chargep); + #endif -- cgit v1.3.1 From 1e465eb6698e294e8fa9ed41165483b88062396a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jul 2021 16:32:50 -0600 Subject: cros_ec: Drop cros_ec_entering_mode() This function is not needed anymore. Drop it. Signed-off-by: Simon Glass --- drivers/misc/cros_ec.c | 11 ----------- drivers/misc/cros_ec_sandbox.c | 3 --- include/cros_ec.h | 9 --------- 3 files changed, 23 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index 0818ef8ad6e..2a15094d20a 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -754,17 +754,6 @@ int cros_ec_flash_protect(struct udevice *dev, uint32_t set_mask, return 0; } -int cros_ec_entering_mode(struct udevice *dev, int mode) -{ - int rc; - - rc = ec_command(dev, EC_CMD_ENTERING_MODE, 0, &mode, sizeof(mode), - NULL, 0); - if (rc) - return -1; - return 0; -} - static int cros_ec_check_version(struct udevice *dev) { struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c index beea47caa33..ab91f3fa67a 100644 --- a/drivers/misc/cros_ec_sandbox.c +++ b/drivers/misc/cros_ec_sandbox.c @@ -496,9 +496,6 @@ static int process_cmd(struct ec_state *ec, case EC_CMD_MKBP_STATE: len = cros_ec_keyscan(ec, resp_data); break; - case EC_CMD_ENTERING_MODE: - len = 0; - break; case EC_CMD_GET_NEXT_EVENT: { struct ec_response_get_next_event *resp = resp_data; diff --git a/include/cros_ec.h b/include/cros_ec.h index 9dab6cdf9ba..ef89deff762 100644 --- a/include/cros_ec.h +++ b/include/cros_ec.h @@ -198,15 +198,6 @@ int cros_ec_flash_protect(struct udevice *dev, uint32_t set_mask, uint32_t set_flags, struct ec_response_flash_protect *resp); -/** - * Notify EC of current boot mode - * - * @param dev CROS-EC device - * @param vboot_mode Verified boot mode - * @return 0 if ok, <0 on error - */ -int cros_ec_entering_mode(struct udevice *dev, int mode); - /** * Run internal tests on the cros_ec interface. * -- cgit v1.3.1 From 656d7447705550af0b464e7f6bc10fc1547e69ee Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jul 2021 16:32:51 -0600 Subject: cros_ec: Support the full-size vboot context The v2 format is 64-bytes in size. Support this and drop v1 since it is not used anymore. Signed-off-by: Simon Glass --- drivers/misc/cros_ec_sandbox.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c index ab91f3fa67a..12cc11efbd0 100644 --- a/drivers/misc/cros_ec_sandbox.c +++ b/drivers/misc/cros_ec_sandbox.c @@ -343,15 +343,13 @@ static int process_cmd(struct ec_state *ec, switch (req->op) { case EC_VBNV_CONTEXT_OP_READ: - /* TODO(sjg@chromium.org): Support full-size context */ memcpy(resp->block, ec->vbnv_context, - EC_VBNV_BLOCK_SIZE); - len = 16; + EC_VBNV_BLOCK_SIZE_V2); + len = EC_VBNV_BLOCK_SIZE_V2; break; case EC_VBNV_CONTEXT_OP_WRITE: - /* TODO(sjg@chromium.org): Support full-size context */ memcpy(ec->vbnv_context, req->block, - EC_VBNV_BLOCK_SIZE); + EC_VBNV_BLOCK_SIZE_V2); len = 0; break; default: -- cgit v1.3.1 From 56dae9ef3c56a7de6ed4af5efb82e661329d4738 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jul 2021 16:32:52 -0600 Subject: cros_ec: Use standard calls for recovery-request checking Rather than calling directly into the sandbox SDL code, we can use the normal U-Boot console handling for this feature. Update the code, to make it more generic. Signed-off-by: Simon Glass --- drivers/misc/cros_ec_sandbox.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c index 12cc11efbd0..2173517cff3 100644 --- a/drivers/misc/cros_ec_sandbox.c +++ b/drivers/misc/cros_ec_sandbox.c @@ -624,15 +624,19 @@ void cros_ec_check_keyboard(struct udevice *dev) struct ec_state *ec = dev_get_priv(dev); ulong start; - printf("Press keys for EC to detect on reset (ESC=recovery)..."); + printf("\nPress keys for EC to detect on reset (ESC=recovery)..."); start = get_timer(0); - while (get_timer(start) < 1000) - ; - putc('\n'); - if (!sandbox_sdl_key_pressed(KEY_ESC)) { - ec->recovery_req = true; - printf(" - EC requests recovery\n"); + while (get_timer(start) < 2000) { + if (tstc()) { + int ch = getchar(); + + if (ch == 0x1b) { + ec->recovery_req = true; + printf("EC requests recovery"); + } + } } + putc('\n'); } /* Return the byte of EC switch states */ -- cgit v1.3.1 From 6b165ab2b7b1dc89357afbe86c1977addf5aed3b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jul 2021 16:32:58 -0600 Subject: sandbox: mmc: Support fixed MMC devices Add support for reading devicetree flags for MMC devices. With this we can distinguish between fixed and removable drives. Note that this information is only available when the device is probed, not when it is bound, since it is read in the of_to_plat() method. This could be changed if needed later. Signed-off-by: Simon Glass Reviewed-by: Jaehoon Chung --- arch/sandbox/dts/test.dts | 1 + drivers/mmc/sandbox_mmc.c | 24 +++++++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index d85bb46ceba..0cee15a0ea2 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -819,6 +819,7 @@ mmc2 { compatible = "sandbox,mmc"; + non-removable; }; mmc1 { diff --git a/drivers/mmc/sandbox_mmc.c b/drivers/mmc/sandbox_mmc.c index 18ba020aacc..895fbffecfc 100644 --- a/drivers/mmc/sandbox_mmc.c +++ b/drivers/mmc/sandbox_mmc.c @@ -136,14 +136,31 @@ static const struct dm_mmc_ops sandbox_mmc_ops = { .get_cd = sandbox_mmc_get_cd, }; -int sandbox_mmc_probe(struct udevice *dev) +static int sandbox_mmc_of_to_plat(struct udevice *dev) +{ + struct sandbox_mmc_plat *plat = dev_get_plat(dev); + struct mmc_config *cfg = &plat->cfg; + struct blk_desc *blk; + int ret; + + ret = mmc_of_parse(dev, cfg); + if (ret) + return ret; + blk = mmc_get_blk_desc(&plat->mmc); + if (blk) + blk->removable = !(cfg->host_caps & MMC_CAP_NONREMOVABLE); + + return 0; +} + +static int sandbox_mmc_probe(struct udevice *dev) { struct sandbox_mmc_plat *plat = dev_get_plat(dev); return mmc_init(&plat->mmc); } -int sandbox_mmc_bind(struct udevice *dev) +static int sandbox_mmc_bind(struct udevice *dev) { struct sandbox_mmc_plat *plat = dev_get_plat(dev); struct mmc_config *cfg = &plat->cfg; @@ -158,7 +175,7 @@ int sandbox_mmc_bind(struct udevice *dev) return mmc_bind(dev, &plat->mmc, cfg); } -int sandbox_mmc_unbind(struct udevice *dev) +static int sandbox_mmc_unbind(struct udevice *dev) { mmc_unbind(dev); @@ -177,6 +194,7 @@ U_BOOT_DRIVER(mmc_sandbox) = { .ops = &sandbox_mmc_ops, .bind = sandbox_mmc_bind, .unbind = sandbox_mmc_unbind, + .of_to_plat = sandbox_mmc_of_to_plat, .probe = sandbox_mmc_probe, .priv_auto = sizeof(struct sandbox_mmc_priv), .plat_auto = sizeof(struct sandbox_mmc_plat), -- cgit v1.3.1 From 96f37b092fdbb604e43c313265995d72ff1a82fe Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jul 2021 16:32:59 -0600 Subject: blk: Support iteration It is useful to be able to iterate over block devices. Typically there are fixed and removable devices. For security reasons it is sometimes useful to ignore removable devices since they are under user control. Add iterators which support selecting the block-device type. Signed-off-by: Simon Glass --- drivers/block/blk-uclass.c | 49 ++++++++++++++++++++++++++++++++++++++++ include/blk.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++ test/dm/blk.c | 55 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+) (limited to 'drivers') diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index dfc0d469702..83682dcc181 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -540,6 +540,55 @@ int blk_next_free_devnum(enum if_type if_type) return ret + 1; } +static int blk_flags_check(struct udevice *dev, enum blk_flag_t req_flags) +{ + const struct blk_desc *desc = dev_get_uclass_plat(dev); + enum blk_flag_t flags; + + flags = desc->removable ? BLKF_REMOVABLE : BLKF_FIXED; + + return flags & req_flags ? 0 : 1; +} + +int blk_first_device_err(enum blk_flag_t flags, struct udevice **devp) +{ + int ret; + + for (ret = uclass_first_device_err(UCLASS_BLK, devp); + !ret; + ret = uclass_next_device_err(devp)) { + if (!blk_flags_check(*devp, flags)) + return 0; + } + + return -ENODEV; +} + +int blk_next_device_err(enum blk_flag_t flags, struct udevice **devp) +{ + int ret; + + for (ret = uclass_next_device_err(devp); + !ret; + ret = uclass_next_device_err(devp)) { + if (!blk_flags_check(*devp, flags)) + return 0; + } + + return -ENODEV; +} + +int blk_count_devices(enum blk_flag_t flag) +{ + struct udevice *dev; + int count = 0; + + blk_foreach_probe(flag, dev) + count++; + + return count; +} + static int blk_claim_devnum(enum if_type if_type, int devnum) { struct udevice *dev; diff --git a/include/blk.h b/include/blk.h index c4401b00253..19bab081c2c 100644 --- a/include/blk.h +++ b/include/blk.h @@ -19,6 +19,8 @@ typedef ulong lbaint_t; #define LBAF "%" LBAFlength "x" #define LBAFU "%" LBAFlength "u" +struct udevice; + /* Interface types: */ enum if_type { IF_TYPE_UNKNOWN = 0, @@ -683,4 +685,58 @@ const char *blk_get_if_type_name(enum if_type if_type); int blk_common_cmd(int argc, char *const argv[], enum if_type if_type, int *cur_devnump); +enum blk_flag_t { + BLKF_FIXED = 1 << 0, + BLKF_REMOVABLE = 1 << 1, + BLKF_BOTH = BLKF_FIXED | BLKF_REMOVABLE, +}; + +/** + * blk_first_device_err() - Get the first block device + * + * The device returned is probed if necessary, and ready for use + * + * @flags: Indicates type of device to return + * @devp: Returns pointer to the first device in that uclass, or NULL if none + * @return 0 if found, -ENODEV if not found, other -ve on error + */ +int blk_first_device_err(enum blk_flag_t flags, struct udevice **devp); + +/** + * blk_next_device_err() - Get the next block device + * + * The device returned is probed if necessary, and ready for use + * + * @flags: Indicates type of device to return + * @devp: On entry, pointer to device to lookup. On exit, returns pointer + * to the next device in the uclass if no error occurred, or -ENODEV if + * there is no next device. + * @return 0 if found, -ENODEV if not found, other -ve on error + */ +int blk_next_device_err(enum blk_flag_t flags, struct udevice **devp); + +/** + * blk_foreach_probe() - Helper function to iteration through block devices + * + * This creates a for() loop which works through the available devices in + * a uclass in order from start to end. Devices are probed if necessary, + * and ready for use. + * + * @flags: Indicates type of device to return + * @dev: struct udevice * to hold the current device. Set to NULL when there + * are no more devices. + */ +#define blk_foreach_probe(flags, pos) \ + for (int _ret = blk_first_device_err(flags, &(pos)); \ + !_ret && pos; \ + _ret = blk_next_device_err(flags, &(pos))) + +/** + * blk_count_devices() - count the number of devices of a particular type + * + * @flags: Indicates type of device to find + * @return number of devices matching those flags + */ +int blk_count_devices(enum blk_flag_t flag); + #endif diff --git a/test/dm/blk.c b/test/dm/blk.c index b7f4304e9e9..deccf05289b 100644 --- a/test/dm/blk.c +++ b/test/dm/blk.c @@ -162,3 +162,58 @@ static int dm_test_blk_get_from_parent(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_blk_get_from_parent, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* Test iteration through block devices */ +static int dm_test_blk_iter(struct unit_test_state *uts) +{ + struct udevice *dev; + int i; + + /* + * See sandbox test.dts - it has: + * + * mmc0 - removable + * mmc1 - removable + * mmc2 - fixed + */ + ut_assertok(blk_first_device_err(BLKF_FIXED, &dev)); + ut_asserteq_str("mmc2.blk", dev->name); + ut_asserteq(-ENODEV, blk_next_device_err(BLKF_FIXED, &dev)); + + ut_assertok(blk_first_device_err(BLKF_REMOVABLE, &dev)); + ut_asserteq_str("mmc1.blk", dev->name); + ut_assertok(blk_next_device_err(BLKF_REMOVABLE, &dev)); + ut_asserteq_str("mmc0.blk", dev->name); + ut_asserteq(-ENODEV, blk_next_device_err(BLKF_REMOVABLE, &dev)); + + ut_assertok(blk_first_device_err(BLKF_BOTH, &dev)); + ut_asserteq_str("mmc2.blk", dev->name); + ut_assertok(blk_next_device_err(BLKF_BOTH, &dev)); + ut_asserteq_str("mmc1.blk", dev->name); + ut_assertok(blk_next_device_err(BLKF_BOTH, &dev)); + ut_asserteq_str("mmc0.blk", dev->name); + ut_asserteq(-ENODEV, blk_next_device_err(BLKF_FIXED, &dev)); + + ut_asserteq(1, blk_count_devices(BLKF_FIXED)); + ut_asserteq(2, blk_count_devices(BLKF_REMOVABLE)); + ut_asserteq(3, blk_count_devices(BLKF_BOTH)); + + i = 0; + blk_foreach_probe(BLKF_FIXED, dev) + ut_asserteq_str((i++, "mmc2.blk"), dev->name); + ut_asserteq(1, i); + + i = 0; + blk_foreach_probe(BLKF_REMOVABLE, dev) + ut_asserteq_str(i++ ? "mmc0.blk" : "mmc1.blk", dev->name); + ut_asserteq(2, i); + + i = 0; + blk_foreach_probe(BLKF_BOTH, dev) + ut_asserteq_str((++i == 1 ? "mmc2.blk" : i == 2 ? + "mmc1.blk" : "mmc0.blk"), dev->name); + ut_asserteq(3, i); + + return 0; +} +DM_TEST(dm_test_blk_iter, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); -- cgit v1.3.1 From 1b098b3e655451572054ce933a87231ee16f7133 Mon Sep 17 00:00:00 2001 From: Chen Guanqiao Date: Mon, 12 Jul 2021 15:40:20 +0800 Subject: dm: core: fix no null pointer detection in ofnode_get_addr_size_index() Fixed a defect of a null pointer being discovered by Coverity Scan: CID 331544: Null pointer dereferences (REVERSE_INULL) Null-checking "size" suggests that it may be null, but it has already been dereferenced on all paths leading to the check. Signed-off-by: Chen Guanqiao --- drivers/core/ofnode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index eeeccfb4467..dda6c76e834 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -329,7 +329,8 @@ static fdt_addr_t __ofnode_get_addr_size_index(ofnode node, int index, { int na, ns; - *size = FDT_SIZE_T_NONE; + if (size) + *size = FDT_SIZE_T_NONE; if (ofnode_is_np(node)) { const __be32 *prop_val; @@ -340,6 +341,7 @@ static fdt_addr_t __ofnode_get_addr_size_index(ofnode node, int index, &flags); if (!prop_val) return FDT_ADDR_T_NONE; + if (size) *size = size64; @@ -359,8 +361,6 @@ static fdt_addr_t __ofnode_get_addr_size_index(ofnode node, int index, index, na, ns, size, translate); } - - return FDT_ADDR_T_NONE; } fdt_addr_t ofnode_get_addr_size_index(ofnode node, int index, fdt_size_t *size) -- cgit v1.3.1