On Tue, Sep 29, 2026 at 14:38:08 +0100, David Lechner wrote:
> On 9/24/26 3:44 PM, Carlo Caione wrote:
> > Genio firmware updates use MediaTek v1 metadata in misc to choose
> > between bootloaders and bootloaders_b. Support this ABI in SPL so
> > systems replacing BL2 can retain their firmware update and boot-success
> > handling.
> > 
> > Make selection opt-in, since trial boots need an updater and a
> > boot-success owner to maintain the retry state. Reject corrupt metadata
> > and failed state updates rather than silently restarting the retry
> > budget.
> > 
> > Signed-off-by: Carlo Caione <[email protected]>
> > ---
> > This is intended for systems with an updater and a boot-success owner
> > that maintain the MediaTek v1 metadata. The option stays disabled in the
> > standard defconfigs. It covers the firmware FIT slots; the DDR loader and
> > SPL in boot0 remain shared.
> 
> Hmm... this might not get compile-tested if it isn't enabled somewhere by
> default. Will have to think about that more. I don't really want a bunch
> of defconfigs for every possible usage senario either because it takes time
> to compile each one and gets confusing as to which one someone should
> actually use.

I can probably add this to sandbox_spl but you probably want a more
robust and general solution for the architecture?
 
> > This patch depends on the dynamic MMC partition selection series V3 [1].
> > The mediatek-staging base e3ed6c6436ab includes both that series and the
> > Genio SPL support.
> > 
> > [1] 
> > https://lore.kernel.org/all/20260914-ccaione-upstream-part-dynamic-v3-0-a38c19e74...@baylibre.com/
> > ---
> >  arch/arm/mach-mediatek/Kconfig          |  17 ++++
> >  arch/arm/mach-mediatek/Makefile         |   1 +
> >  arch/arm/mach-mediatek/spl_ab.c         |  35 ++++++++
> >  doc/board/mediatek/mt8188-genio-evk.rst |  88 +++++++++++++++++++-
> >  include/mediatek/mtk_ab.h               |  48 +++++++++++
> >  include/mmc.h                           |   1 +
> >  lib/Kconfig                             |   1 +
> >  lib/Makefile                            |   2 +
> >  lib/mediatek/Kconfig                    |   9 +++
> >  lib/mediatek/Makefile                   |   3 +
> >  lib/mediatek/mtk_ab.c                   | 139 
> > ++++++++++++++++++++++++++++++++
> 
> I don't see any other vendor libraries in lib/. Probably should live in
> arch/arm/mach-mediatek/ with the rest of it.

Fair point. I'll move it.
 
> >  11 files changed, 340 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
> > index 13d5819510e..316337949b4 100644
> > --- a/arch/arm/mach-mediatek/Kconfig
> > +++ b/arch/arm/mach-mediatek/Kconfig
> > @@ -221,6 +221,23 @@ config MTK_BROM_HEADER_INFO
> >     default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8366 
> > || TARGET_MT8183 || TARGET_MT8189 || TARGET_MT8195
> >     default "lk=1" if TARGET_MT7623
> >  
> > +config SPL_MTK_FIRMWARE_AB
> > +   bool "MediaTek firmware A/B boot in SPL"
> > +   depends on TARGET_MT8188 && SPL_MMC && SPL_LOAD_FIT && SPL_BLK
> > +   depends on !SPL_RAW_IMAGE_SUPPORT && !SPL_LEGACY_IMAGE_FORMAT
> > +   depends on SPL_EFI_PARTITION
> > +   depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_DYNAMIC
> > +   depends on !SPL_OS_BOOT && !SPL_FS_FAT && !SPL_FS_EXT4
> > +   depends on !SPL_FS_SQUASHFS && !SPL_RAM_SUPPORT && !SUPPORT_EMMC_BOOT
> > +   select SPL_MTK_AB
> > +   select SPL_MMC_WRITE
> > +   help
> > +     Select firmware FITs from the bootloaders and bootloaders_b GPT
> > +     partitions using MediaTek A/B metadata in misc. Track trial boots
> > +     and switch slots when retries are exhausted.
> > +
> > +     An updater and a boot-success owner must maintain the metadata.
> > +
> >  config MTK_GENIO_BOOT_IMAGES
> >     bool "Build MediaTek firmware images"
> >     depends on TARGET_MT8188 && SPL
> > diff --git a/arch/arm/mach-mediatek/Makefile 
> > b/arch/arm/mach-mediatek/Makefile
> > index be3604a6776..96eb3ccb35c 100644
> > --- a/arch/arm/mach-mediatek/Makefile
> > +++ b/arch/arm/mach-mediatek/Makefile
> > @@ -5,6 +5,7 @@ obj-y       += cpu.o
> >  obj-$(CONFIG_MTK_TZ_MOVABLE)       += tzcfg.o
> >  obj-$(CONFIG_XPL_BUILD)    += spl.o
> >  obj-$(CONFIG_MTK_BROM_DOWNLOAD_AGENT_SPL_FASTBOOT) += spl_fastboot.o
> > +obj-$(CONFIG_$(PHASE_)MTK_FIRMWARE_AB) += spl_ab.o
> >  
> >  obj-$(CONFIG_TARGET_MT7622) += mt7622/
> >  obj-$(CONFIG_TARGET_MT7623) += mt7623/
> > diff --git a/arch/arm/mach-mediatek/spl_ab.c 
> > b/arch/arm/mach-mediatek/spl_ab.c
> > new file mode 100644
> > index 00000000000..1a4b2f0bcc5
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/spl_ab.c
> > @@ -0,0 +1,35 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/* Copyright (c) 2026 BayLibre SAS */
> > +
> > +#include <mmc.h>
> > +#include <mediatek/mtk_ab.h>
> > +#include <spl.h>
> > +
> > +int spl_mmc_boot_partition(struct mmc *mmc, const u32 boot_device)
> > +{
> > +   struct blk_desc *desc = mmc_get_blk_desc(mmc);
> > +   unsigned int slot;
> > +   int ret;
> > +
> > +   /* This platform boots firmware FITs from the eMMC user area only. */
> > +   if (IS_SD(mmc) || desc->hwpart || !mmc->ext_csd) {
> 
> mtk_ab_select() already checks desc->hwpart so we don't need to do it here 
> too.

Agreed, I'll remove it.

> > +           ret = -ENODEV;
> > +           goto error;
> > +   }
> > +   /* U-Boot does not enable the eMMC cache; reject an unexpected cache. */
> 
> What code path could lead to this?

It was a speculative protection. I just checked if the cache is enabled
and it is not, so we can remove the check.

> > +   if (mmc->ext_csd[EXT_CSD_CACHE_CTRL]) {
> > +           ret = -EOPNOTSUPP;
> > +           goto error;
> > +   }
> > +
> > +   ret = mtk_ab_select(desc, &slot);
> > +   if (ret < 0)
> > +           goto error;
> > +
> > +   printf("MediaTek A/B: slot %c, partition %d\n", 'A' + slot, ret);
> > +   return ret;
> > +
> > +error:
> > +   printf("MediaTek A/B: selection failed (%d)\n", ret);
> > +   return ret;
> > +}
> > diff --git a/doc/board/mediatek/mt8188-genio-evk.rst 
> > b/doc/board/mediatek/mt8188-genio-evk.rst
> > index 43948bb4365..2f1d80c04cb 100644
> > --- a/doc/board/mediatek/mt8188-genio-evk.rst
> > +++ b/doc/board/mediatek/mt8188-genio-evk.rst
> > @@ -36,7 +36,8 @@ followed by U-Boot SPL. The DDR loader initializes DRAM, 
> > copies the fixed
> >  ``CONFIG_MTK_GENIO_DDR_LOADER_SIZE`` to ``CONFIG_SPL_TEXT_BASE`` and enters
> >  SPL at EL3 with exceptions masked.
> >  
> > -SPL reads a FIT image from partition 1 of the eMMC user area. The FIT 
> > contains
> > +By default, SPL reads a FIT image from partition 1 of the eMMC user area.
> > +Optional firmware A/B selection is described below. The FIT contains
> >  Arm Trusted Firmware-A (BL31), OP-TEE (BL32), U-Boot proper (BL33) and the
> >  U-Boot control devicetree. It is an ordinary, directly parseable FIT whose
> >  first word is the FDT magic; the complete FIT container must not be 
> > compressed.
> > @@ -225,7 +226,9 @@ For example, after enabling 
> > ``CONFIG_MTK_GENIO_BOOT_IMAGES`` as above::
> >           --enable SHA256 \
> >           --enable SPL_FIT_SIGNATURE \
> >           --enable SPL_RSA \
> > -         --enable SPL_SHA256
> > +         --enable SPL_SHA256 \
> > +         --disable SPL_RAW_IMAGE_SUPPORT \
> > +         --disable SPL_LEGACY_IMAGE_FORMAT
> 
> This seems unrelated. Should be a separate patch? Or not necessary? Seems
> like these should already be the default.

Ouch, this is actually something not related to this series. I'll push
it as standalone.

> >     $ make olddefconfig
> >     $ make BINMAN_INDIRS=/path/to/firmware-and-keys
> >  
> > @@ -252,12 +255,12 @@ Image                Destination
> >  ===================  ================================================
> >  
> >  The standard Genio 510 and Genio 700 partition layouts name GPT partition 1
> > -``bootloaders``. SPL selects the partition by number through
> > +``bootloaders``. By default, SPL selects the partition by number through
> >  ``CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION``; it does not locate it by 
> > name.
> >  
> >  Writing an invalid image to eMMC boot0 can make the board unbootable. 
> > Preserve
> >  the platform recovery path and any backup bootloader partition while 
> > testing.
> > -Selection of a backup partition is not implemented by this SPL 
> > configuration.
> > +Selection of a backup partition requires the optional firmware A/B support.
> >  
> >  Using Genio Tools
> >  ~~~~~~~~~~~~~~~~~
> > @@ -360,3 +363,80 @@ Use raw images with the eMMC boot-area aliases 
> > ``mmc0boot0`` and
> >  ``mmc0boot1``: these aliases write the downloaded bytes without expanding
> >  Android sparse images. Sparse flashing is supported for GPT partitions and
> >  the eMMC user-area alias.
> > +
> > +Firmware A/B in SPL
> > +------------------
> > +
> > +``CONFIG_SPL_MTK_FIRMWARE_AB`` enables A/B selection for the firmware 
> > loaded
> > +by SPL from eMMC. It is disabled by default. Enable it only with an updater
> > +that activates firmware slots and a service that confirms successful boots.
> > +After selecting the board defconfig, enable it with::
> > +
> > +   $ scripts/config --file "${KBUILD_OUTPUT}/.config" \
> > +         --disable SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION \
> > +         --enable SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_DYNAMIC \
> > +         --disable SPL_RAW_IMAGE_SUPPORT \
> > +         --disable SPL_LEGACY_IMAGE_FORMAT \
> > +         --enable SPL_MTK_FIRMWARE_AB
> > +   $ make olddefconfig
> > +
> > +Install a complete ``bootloaders.img`` FIT in each of the ``bootloaders``
> > +(slot A) and ``bootloaders_b`` (slot B) GPT partitions. The ``misc`` 
> > partition
> > +stores the selected slot and boot-attempt counters. When migrating from 
> > BL2,
> > +replace the FIP images in both slots with FIT images. If FIT signing is
> > +enabled, both images must be signed with a key trusted by the installed 
> > SPL.
> 
> And we would need the extra option enabled from the previous secton too
> for signed FIT images?

No, that is unrelated.

> > +
> > +The DDR loader and SPL in boot0 are shared by both firmware slots. Keep A/B
> > +disabled in download-agent builds.
> 
> Why does it matter? If there is a technical reason, maybe we should enforce
> that in Kconfig.

Wording is probably a bit too strong, it is just not used or tested,
especially if the user tries to issue a 'fastboot continue' when in DA.

> > +
> > +With SPL installed in the standard RITY eMMC layout, the boot flow is::
> > +
> > +              BootROM
> > +                 |
> > +                 v
> > +   +---------------------------+     +---------------------------+
> > +   | boot0                     |     | boot1                     |
> > +   | DDR loader -> SPL         |     | U-Boot environment        |
> > +   | shared by slots A and B   |     | not a firmware slot       |
> > +   +-------------+-------------+     +---------------------------+
> > +                 |
> > +                 v
> > +   +-------------------------------------------------------------+
> > +   | eMMC user area (GPT partitions)                             |
> > +   |                                                             |
> > +   |   +-----------------------------------------------------+   |
> > +   |   | misc                                                |   |
> > +   |   | Selected firmware slot and boot-attempt counters    |   |
> > +   |   +-------------------------+---------------------------+   |
> > +   |                             |                               |
> > +   |                     select A or B                           |
> > +   |              +--------------+--------------+                |
> > +   |              v                             v                |
> > +   |   +-----------------------+   +-------------------------+   |
> > +   |   | bootloaders (slot A)  |   | bootloaders_b (slot B)  |   |
> > +   |   | FIT: BL31, BL32, BL33 |   | FIT: BL31, BL32, BL33   |   |
> > +   |   +-----------------------+   +-------------------------+   |
> > +   +-------------------------------------------------------------+
> > +
> > +Firmware updates and rollback
> > +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > +
> > +Use an updater and boot-success service compatible with MediaTek firmware
> > +A/B metadata:
> > +
> > +1. Write and verify the new FIT in the inactive slot.
> > +2. Activate that slot for trial booting.
> > +3. After booting and completing the required health checks, mark the booted
> > +   slot successful.
> > +
> > +A newly activated trial slot has eight boot attempts. Without confirmation,
> > +even a working image eventually exhausts its attempts. SPL then selects the
> > +other slot on the following boot, provided that slot has attempts remaining
> > +or was previously marked successful. Blank metadata initially selects slot 
> > A.
> > +
> > +A failed FIT load or verification stops the current boot. Configure a 
> > watchdog
> > +or another reset mechanism if unattended retries are required. Keep a 
> > working
> > +download/recovery path for exhausted slots or damaged metadata, including
> > +damage caused by an interrupted metadata update. A slot already marked
> > +successful is no longer subject to trial retries; a later failure of that
> > +image requires recovery.
> 
> Are we going to need to add hooks for these extra recovery paths?

That would require an entirely different work not related to this IMO.
We are assuming a user intervention for recovery for these edge cases.

> > diff --git a/include/mediatek/mtk_ab.h b/include/mediatek/mtk_ab.h
> > new file mode 100644
> > index 00000000000..515c8c68f59
> > --- /dev/null
> > +++ b/include/mediatek/mtk_ab.h
> > @@ -0,0 +1,48 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause */
> 
> I think code added to U-Boot is supposed to be GPL-2.0-or-later, so this
> needs AND with both licenses.

Indeed.

> > +/*
> > + * Copyright (c) 2023, Mediatek Inc. All rights reserved.
> > + * Copyright (c) 2026 BayLibre SAS
> > + */
> > +
> > +#ifndef __MEDIATEK_MTK_AB_H
> > +#define __MEDIATEK_MTK_AB_H
> > +
> > +#include <linux/types.h>
> > +
> > +struct blk_desc;
> > +
> > +#define MTK_AB_MAGIC       0x544f494d
> > +#define MTK_AB_VERSION     1
> > +#define MTK_AB_MAX_TRIES   9
> > +
> > +/* MediaTek v1 disk ABI, including the original AArch64 structure padding. 
> > */
> > +struct mtk_ab_control {
> > +   __le32 slot;
> > +   __le32 magic;
> > +   u8 version;
> > +   u8 tries[2];
> > +   u8 padding;
> > +   u8 reserved[12];
> > +   __le32 crc32;
> > +};
> > +
> > +/**
> > + * mtk_ab_select() - Select and account for a MediaTek firmware slot
> > + * @desc: Block device containing the GPT user area
> > + * @slot: Returns the selected slot (0 for A, 1 for B), only on success
> > + *
> > + * Resolve bootloaders, bootloaders_b and misc by name, validate the v1 
> > record
> > + * at the start of misc, and persist any required retry update before 
> > returning.
> > + * The caller must provide a valid, non-overlapping GPT layout.
> > + * A zero counter denotes success; counters 1..8 consume a trial and 9 is
> > + * exhausted. Only an all-zero or all-0xff record is initialized 
> > automatically.
> > + * Writes preserve the rest of the block and are verified with an uncached 
> > read.
> > + * This single-copy format does not provide power-fail atomicity. The 
> > caller
> > + * must ensure device write caching cannot hide an uncommitted metadata 
> > write.
> 
> These last two sentances don't sound reasuring. Does our 
> spl_mmc_boot_partition()
> implementation handle these?

This was the reason for the cache check. Not needed anymore.

> > + *
> > + * Return: Positive GPT partition number to boot, or a negative error. The
> > + * caller must stop booting on error; a failed write may have changed 
> > storage.
> > + */
> > +int mtk_ab_select(struct blk_desc *desc, unsigned int *slot);
> > +
> > +#endif
> > diff --git a/include/mmc.h b/include/mmc.h
> > index 9a796e0655f..623ca027ccf 100644
> > --- a/include/mmc.h
> > +++ b/include/mmc.h
> > @@ -212,6 +212,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
> >  /*
> >   * EXT_CSD fields
> >   */
> > +#define EXT_CSD_CACHE_CTRL         33      /* R/W */
> >  #define EXT_CSD_BOOT_SIZE_MULT_MICRON      125     /* R/W, vendor specific 
> > field */
> >  #define EXT_CSD_ENH_START_ADDR             136     /* R/W */
> >  #define EXT_CSD_ENH_SIZE_MULT              140     /* R/W */
> 
> Would be good to split this out into a separate patch since it touches a
> separate subsytem.
> 
> I would also expect an explantion of why we need EXT_CSD_CACHE_CTRL when
> U-Boot hasn't needed it until now.

This is going to be entirely removed in the next version.

> > diff --git a/lib/Kconfig b/lib/Kconfig
> > index b6e65b17ab6..147bf6865be 100644
> > --- a/lib/Kconfig
> > +++ b/lib/Kconfig
> > @@ -1364,3 +1364,4 @@ config UTHREAD_STACK_SIZE
> >  endmenu
> >  
> >  source "lib/fwu_updates/Kconfig"
> > +source "lib/mediatek/Kconfig"
> > diff --git a/lib/Makefile b/lib/Makefile
> > index 8710be39f3f..646a25a4630 100644
> > --- a/lib/Makefile
> > +++ b/lib/Makefile
> > @@ -3,6 +3,8 @@
> >  # (C) Copyright 2000-2006
> >  # Wolfgang Denk, DENX Software Engineering, [email protected].
> >  
> > +obj-$(CONFIG_$(PHASE_)MTK_AB) += mediatek/
> > +
> >  ifndef CONFIG_XPL_BUILD
> >  
> >  obj-$(CONFIG_EFI_CLIENT) += efi_client/
> > diff --git a/lib/mediatek/Kconfig b/lib/mediatek/Kconfig
> > new file mode 100644
> > index 00000000000..20110734e1e
> > --- /dev/null
> > +++ b/lib/mediatek/Kconfig
> > @@ -0,0 +1,9 @@
> > +# SPDX-License-Identifier: GPL-2.0+
> > +
> > +config SPL_MTK_AB
> > +   bool
> > +   depends on SPL && SPL_EFI_PARTITION
> > +   select SPL_CRC32
> > +   help
> > +     Select and account for firmware boot attempts using MediaTek v1
> > +     metadata in the misc GPT partition.
> > diff --git a/lib/mediatek/Makefile b/lib/mediatek/Makefile
> > new file mode 100644
> > index 00000000000..71f8dbb374c
> > --- /dev/null
> > +++ b/lib/mediatek/Makefile
> > @@ -0,0 +1,3 @@
> > +# SPDX-License-Identifier: GPL-2.0+
> > +
> > +obj-y += mtk_ab.o
> > diff --git a/lib/mediatek/mtk_ab.c b/lib/mediatek/mtk_ab.c
> > new file mode 100644
> > index 00000000000..8fa69bc1dbc
> > --- /dev/null
> > +++ b/lib/mediatek/mtk_ab.c
> > @@ -0,0 +1,139 @@
> > +// SPDX-License-Identifier: BSD-3-Clause
> > +/*
> > + * Copyright (c) 2023, Mediatek Inc. All rights reserved.
> > + * Copyright (c) 2026 BayLibre SAS
> > + *
> > + * Disk format and valid-record transitions follow MediaTek's TF-A 
> > mtk_ab.c.
> > + */
> > +
> > +#include <blk.h>
> > +#include <log.h>
> 
> Either should be including <stdio.h> instead for printf() or switch to log
> functions.

I'll fix this.

> > +#include <malloc.h>
> > +#include <memalign.h>
> > +#include <mediatek/mtk_ab.h>
> > +#include <part.h>
> > +#include <linux/build_bug.h>
> > +#include <linux/errno.h>
> > +#include <linux/log2.h>
> > +#include <u-boot/crc.h>
> 
> And a few more that are only included indirectly.
> 
> linux/string.h (memcmp), asm/byteorder.h (cpu_to_le32), linux/kernel.h
> (ARRAY_SIZE).

ACK

> > +
> > +#define MTK_AB_MISC_INDEX  2
> > +
> > +static_assert(sizeof(struct mtk_ab_control) == 28);
> > +static_assert(offsetof(struct mtk_ab_control, padding) == 11);
> > +static_assert(offsetof(struct mtk_ab_control, reserved) == 12);
> > +static_assert(offsetof(struct mtk_ab_control, crc32) == 24);
> > +
> > +static u32 mtk_ab_crc(const struct mtk_ab_control *ctrl)
> > +{
> > +   return crc32(0, (const void *)ctrl, offsetof(struct mtk_ab_control, 
> > crc32));
> > +}
> > +
> > +static int mtk_ab_layout(struct blk_desc *desc, struct disk_partition 
> > *parts,
> > +                    int *numbers)
> > +{
> > +   static const char * const names[] = { "bootloaders", "bootloaders_b", 
> > "misc" };
> > +   int i;
> > +
> > +   part_init(desc);
> > +   if (desc->part_type != PART_TYPE_EFI)
> > +           return -EPROTONOSUPPORT;
> > +
> > +   for (i = 0; i < ARRAY_SIZE(names); i++) {
> > +           numbers[i] = part_get_info_by_name(desc, names[i], &parts[i]);
> > +           if (numbers[i] < 0)
> > +                   return numbers[i];
> > +   }
> > +
> > +   /* The metadata read-modify-write needs one block in misc. */
> > +   if (!parts[MTK_AB_MISC_INDEX].start || !parts[MTK_AB_MISC_INDEX].size ||
> > +       parts[MTK_AB_MISC_INDEX].start >= desc->lba)
> > +           return -EINVAL;
> > +
> > +   return 0;
> > +}
> > +
> > +int mtk_ab_select(struct blk_desc *desc, unsigned int *slot)
> > +{
> > +   struct disk_partition parts[3];
> > +   struct mtk_ab_control *ctrl;
> > +   unsigned int selected;
> > +   int numbers[3], ret;
> > +   void *block, *verify;
> > +   bool changed = false;
> > +
> > +   if (!desc || !slot || !desc->lba || desc->hwpart || desc->blksz < 512 ||
> > +       desc->blksz > 4096 || !is_power_of_2(desc->blksz) ||
> > +       desc->blksz % ARCH_DMA_MINALIGN)
> > +           return -EINVAL;
> > +
> > +   /* Locate all required partitions before updating the metadata. */
> > +   ret = mtk_ab_layout(desc, parts, numbers);
> > +   if (ret)
> > +           return ret;
> > +
> > +   block = malloc_cache_aligned(2 * desc->blksz);
> > +   if (!block)
> > +           return -ENOMEM;
> > +   verify = block + desc->blksz;
> > +   ctrl = block;
> > +
> > +   ret = -EIO;
> > +   blkcache_invalidate(desc->uclass_id, desc->devnum);
> > +   if (blk_dread(desc, parts[MTK_AB_MISC_INDEX].start, 1, block) != 1)
> > +           goto out;
> > +
> > +   if (!memchr_inv(ctrl, 0, sizeof(*ctrl)) ||
> > +       !memchr_inv(ctrl, 0xff, sizeof(*ctrl))) {
> > +           puts("MediaTek A/B: initializing blank metadata\n");
> > +           memset(ctrl, 0, sizeof(*ctrl));
> > +           ctrl->magic = cpu_to_le32(MTK_AB_MAGIC);
> > +           ctrl->version = MTK_AB_VERSION;
> > +           ctrl->tries[0] = 1;
> > +           ctrl->tries[1] = 1;
> > +           selected = 0;
> > +           changed = true;
> > +   } else {
> > +           ret = -EINVAL;
> > +           selected = le32_to_cpu(ctrl->slot);
> > +           if (le32_to_cpu(ctrl->magic) != MTK_AB_MAGIC ||
> > +               ctrl->version != MTK_AB_VERSION || selected > 1 ||
> > +               ctrl->tries[0] > MTK_AB_MAX_TRIES ||
> > +               ctrl->tries[1] > MTK_AB_MAX_TRIES)
> > +                   goto out;
> > +           ret = -EBADMSG;
> > +           if (le32_to_cpu(ctrl->crc32) != mtk_ab_crc(ctrl))
> > +                   goto out;
> > +
> > +           if (ctrl->tries[selected] == MTK_AB_MAX_TRIES) {
> > +                   selected ^= 1;
> > +                   ret = -ENOENT;
> > +                   if (ctrl->tries[selected] == MTK_AB_MAX_TRIES)
> > +                           goto out;
> > +                   ctrl->slot = cpu_to_le32(selected);
> > +                   changed = true;
> > +           }
> > +           if (ctrl->tries[selected]) {
> > +                   ctrl->tries[selected]++;
> > +                   changed = true;
> > +           }
> > +   }
> > +
> > +   if (changed) {
> > +           ctrl->crc32 = cpu_to_le32(mtk_ab_crc(ctrl));
> > +           ret = -EIO;
> > +           if (blk_dwrite(desc, parts[MTK_AB_MISC_INDEX].start, 1, block) 
> > != 1)
> > +                   goto out;
> > +           /* Do not verify a write against U-Boot's cached copy. */
> > +           blkcache_invalidate(desc->uclass_id, desc->devnum);
> > +           if (blk_dread(desc, parts[MTK_AB_MISC_INDEX].start, 1, verify) 
> > != 1 ||
> > +               memcmp(block, verify, desc->blksz))
> > +                   goto out;
> > +   }
> > +
> > +   *slot = selected;
> > +   ret = numbers[selected];
> > +out:
> > +   free(block);
> > +   return ret;
> > +}
> > 
> > ---
> > base-commit: e3ed6c6436abc18af0c7a0298ac72f83ebf2b5d1
> > change-id: 20260924-ccaione-upstream-mt8390-ab-631b4d4537f7
> > 
> > Best regards,
> > --  
> > Carlo Caione <[email protected]>
> 

Thanks!

--
Carlo Caione

Reply via email to