docs/system/device-emulation.rst | 1 + docs/system/devices/emmc.rst | 53 +++++ hw/sd/sd.c | 369 ++++++++++++++++++++++++++++--- hw/sd/sdmmc-internal.h | 22 ++ hw/sd/trace-events | 2 + scripts/mkemmc.sh | 219 ++++++++++++++++++ 6 files changed, 636 insertions(+), 30 deletions(-) create mode 100644 docs/system/devices/emmc.rst create mode 100755 scripts/mkemmc.sh
Changes in v6 [1]:
- incorporated review suggestions, specifically
- style and structuring suggestion for sd.c changes
- usage of lduw_be_p, ldl_be_p, stw_be_p, stl_be_p
- usage of QEMU_IS_ALIGNED
- optimized rpmb_calc_hmac
- introduction of further RPMB_*_LEN constants
- truncate argument ordering in mkemmc.sh
- comment for unclear code in mkemmc.sh
- improvide description of patch 2
- rebased over master + [2]
Changes in v5:
- fix regression of patch 1 with unplugged SD cards
- address review comments on documentation
Changes in v4:
- add truncation warning to mkemmc.sh
- fix typos in doc and mkemmc.sh
Changes in v3:
- rebased, dropping merged patches
- rework image alignment rules to match hardware
- improve/fix mkemmc script
- add emmc documentation
Changes in v2:
- handle write counter expiry
- assert() availability of QCRYPTO_HASH_ALGO_SHA256
- add missing SPDX-License-Identifier
This closes an old gap in system integration testing for the very
complex ARM firmware stacks by adding fairly advanced Replay Protected
Memory Block (RPMB) emulation to the eMMC device model. Key programming
and message authentication are working, so is the write counter. Known
users are happy with the result. What is missing, but not only for RPMB-
related registers, is state persistence across QEMU restarts. This is OK
at this stage for most test scenarios, though, and could still be added
later on.
What can already be done with it is demonstrated in the WIP branch of
isar-cip-core at [3]: TF-A + OP-TEE + StandaloneMM TA + fTPM TA, used by
U-Boot and Linux for UEFI variable storage and TPM scenarios. If you
want to try: build qemu-arm64 target for trixie with 6.12-cip *head*
kernel, enable secure boot and disk encryption, then run
$ QEMU_PATH=/path/to/qemu-build/ ./start-qemu.sh
Deploy snakeoil keys into PK, KEK and db after first boot to enable
secure booting:
root@demo:~# cert-to-efi-sig-list PkKek-1-snakeoil.pem PK.esl
root@demo:~# sign-efi-sig-list -k PkKek-1-snakeoil.key -c PkKek-1-snakeoil.pem PK PK.esl PK.auth
root@demo:~# efi-updatevar -f PK.auth db
root@demo:~# efi-updatevar -f PK.auth KEK
root@demo:~# efi-updatevar -f PK.auth PK
Note that emulation is a bit slow in general, and specifically the
partition encryption on first boot is taking 20 min. - we should
probably reduce its size or understand if there is still something to
optimize.
Jan
[1] https://github.com/siemens/qemu/commits/queues/emmc/
[2] https://patchwork.kernel.org/project/qemu-devel/patch/20251103133727.423041-4-berrange@redhat.com/
[3] https://gitlab.com/cip-project/cip-core/isar-cip-core/-/commits/next
CC: Alexander Bulekov <alxndr@bu.edu>
CC: Alistair Francis <alistair@alistair23.me>
CC: Cédric Le Goater <clg@kaod.org>
CC: Joel Stanley <joel@jms.id.au>
CC: Warner Losh <imp@bsdimp.com>
Jan Kiszka (6):
hw/sd/sdcard: Fix size check for backing block image
hw/sd/sdcard: Allow user-instantiated eMMC
hw/sd/sdcard: Add basic support for RPMB partition
hw/sd/sdcard: Handle RPMB MAC field
scripts: Add helper script to generate eMMC block device images
docs: Add eMMC device model description
docs/system/device-emulation.rst | 1 +
docs/system/devices/emmc.rst | 53 +++++
hw/sd/sd.c | 369 ++++++++++++++++++++++++++++---
hw/sd/sdmmc-internal.h | 22 ++
hw/sd/trace-events | 2 +
scripts/mkemmc.sh | 219 ++++++++++++++++++
6 files changed, 636 insertions(+), 30 deletions(-)
create mode 100644 docs/system/devices/emmc.rst
create mode 100755 scripts/mkemmc.sh
--
2.51.0
On 4/11/25 14:03, Jan Kiszka wrote: > This closes an old gap in system integration testing for the very > complex ARM firmware stacks by adding fairly advanced Replay Protected > Memory Block (RPMB) emulation to the eMMC device model. Key programming > and message authentication are working, so is the write counter. Known > users are happy with the result. What is missing, but not only for RPMB- > related registers, is state persistence across QEMU restarts. This is OK > at this stage for most test scenarios, though, and could still be added > later on. > Jan Kiszka (6): > hw/sd/sdcard: Fix size check for backing block image > hw/sd/sdcard: Allow user-instantiated eMMC > hw/sd/sdcard: Add basic support for RPMB partition > hw/sd/sdcard: Handle RPMB MAC field > scripts: Add helper script to generate eMMC block device images > docs: Add eMMC device model description FTR: Tested-by: Cédric Le Goater <clg@redhat.com> and also for u-boot I got a late: Tested-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
If the patches haven't landed yet feel free to add my acked-by as well On Wed, 5 Nov 2025 at 18:13, Philippe Mathieu-Daudé <philmd@linaro.org> wrote: > > On 4/11/25 14:03, Jan Kiszka wrote: > > > This closes an old gap in system integration testing for the very > > complex ARM firmware stacks by adding fairly advanced Replay Protected > > Memory Block (RPMB) emulation to the eMMC device model. Key programming > > and message authentication are working, so is the write counter. Known > > users are happy with the result. What is missing, but not only for RPMB- > > related registers, is state persistence across QEMU restarts. This is OK > > at this stage for most test scenarios, though, and could still be added > > later on. > > > > Jan Kiszka (6): > > hw/sd/sdcard: Fix size check for backing block image > > hw/sd/sdcard: Allow user-instantiated eMMC > > hw/sd/sdcard: Add basic support for RPMB partition > > hw/sd/sdcard: Handle RPMB MAC field > > scripts: Add helper script to generate eMMC block device images > > docs: Add eMMC device model description > > FTR: > Tested-by: Cédric Le Goater <clg@redhat.com> > > and also for u-boot I got a late: > Tested-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> cheers /Ilias
On 5/11/25 17:13, Philippe Mathieu-Daudé wrote:
> On 4/11/25 14:03, Jan Kiszka wrote:
>
>> This closes an old gap in system integration testing for the very
>> complex ARM firmware stacks by adding fairly advanced Replay Protected
>> Memory Block (RPMB) emulation to the eMMC device model. Key programming
>> and message authentication are working, so is the write counter. Known
>> users are happy with the result. What is missing, but not only for RPMB-
>> related registers, is state persistence across QEMU restarts. This is OK
>> at this stage for most test scenarios, though, and could still be added
>> later on.
>
>
>> Jan Kiszka (6):
>> hw/sd/sdcard: Fix size check for backing block image
>> hw/sd/sdcard: Allow user-instantiated eMMC
>> hw/sd/sdcard: Add basic support for RPMB partition
>> hw/sd/sdcard: Handle RPMB MAC field
>> scripts: Add helper script to generate eMMC block device images
>> docs: Add eMMC device model description
>
> FTR:
> Tested-by: Cédric Le Goater <clg@redhat.com>
>
> and also for u-boot I got a late:
> Tested-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
(and my own testing with your scripts)
(qemu) info block
disk (#block156):
/isar-cip-core/build/tmp/deploy/images/qemu-arm64/cip-core-image-cip-core-trixie-qemu-arm64.qemu-emmc
(raw)
Attached to: /machine/peripheral-anon/device[4]
Removable device: not locked, tray closed
Cache mode: writeback
root@demo:~# dmesg|fgrep -i mmc
[ 3.586239] mmc0: SDHCI controller on PCI [0000:00:01.0] using ADMA
[ 3.660691] mmc0: new high speed MMC card at address 0001
[ 3.668342] mmcblk0: mmc0:0001 QEMU!! 2.65 GiB
[ 3.999076] mmcblk0: p1 p2 p3 p4 p5 p6
[ 4.006997] mmcblk0rpmb: mmc0:0001 QEMU!! 2.00 MiB, chardev (239:0)
Hi Jan,
On 4/11/25 14:03, Jan Kiszka wrote:
> Jan Kiszka (6):
> hw/sd/sdcard: Fix size check for backing block image
> hw/sd/sdcard: Allow user-instantiated eMMC
> hw/sd/sdcard: Add basic support for RPMB partition
> hw/sd/sdcard: Handle RPMB MAC field
> scripts: Add helper script to generate eMMC block device images
> docs: Add eMMC device model description
Series queued with the following squashed to please checkpatch:
-- >8 --
diff --git a/docs/system/devices/emmc.rst b/docs/system/devices/emmc.rst
index 7e15b622706..8fcb47e25b2 100644
--- a/docs/system/devices/emmc.rst
+++ b/docs/system/devices/emmc.rst
@@ -0,0 +1,2 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 61754bf1083..9c86c016cc9 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1166,2 +1166 @@ static bool rpmb_calc_hmac(SDState *sd, const
RPMBDataFrame *frame,
- offset = lduw_be_p(&frame->address) * RPMB_DATA_LEN +
- sd_part_offset(sd);
+ offset = lduw_be_p(&frame->address) * RPMB_DATA_LEN +
sd_part_offset(sd);
@@ -1207,2 +1206,2 @@ static void emmc_rpmb_blk_read(SDState *sd,
uint64_t addr, uint32_t len)
- curr_block += lduw_be_p(&sd->rpmb.result.block_count) -
- sd->multi_blk_cnt;
+ curr_block += lduw_be_p(&sd->rpmb.result.block_count);
+ curr_block -= sd->multi_blk_cnt;
@@ -1211 +1210,2 @@ static void emmc_rpmb_blk_read(SDState *sd, uint64_t
addr, uint32_t len)
- if (blk_pread(sd->blk, addr, RPMB_DATA_LEN,
sd->rpmb.result.data, 0) < 0) {
+ if (blk_pread(sd->blk, addr, RPMB_DATA_LEN,
+ sd->rpmb.result.data, 0) < 0) {
@@ -1215,2 +1215,2 @@ static void emmc_rpmb_blk_read(SDState *sd,
uint64_t addr, uint32_t len)
- RPMB_RESULT_READ_FAILURE |
- (result & RPMB_RESULT_COUTER_EXPIRED));
+ RPMB_RESULT_READ_FAILURE
+ | (result & RPMB_RESULT_COUTER_EXPIRED));
@@ -1308,2 +1308 @@ exit:
- lduw_be_p(&sd->rpmb.result.result) |
- RPMB_RESULT_COUTER_EXPIRED);
+ lduw_be_p(&sd->rpmb.result.result) |
RPMB_RESULT_COUTER_EXPIRED);
diff --git a/scripts/mkemmc.sh b/scripts/mkemmc.sh
index 45dc3f08fa5..429388213c6 100755
--- a/scripts/mkemmc.sh
+++ b/scripts/mkemmc.sh
@@ -11,3 +10,0 @@
-# This work is licensed under the terms of the GNU GPL version 2.
-# See the COPYING file in the top-level directory.
-#
---
I apologize it took me so long to review, I needed to study the spec.
Thanks for this high quality contribution!
Phil.
© 2016 - 2025 Red Hat, Inc.