[PATCH] arm64: zynqmp: Support semhosting boot method

Sean Anderson sean.anderson at seco.com
Thu Feb 15 20:31:34 CET 2024


On 2/15/24 14:08, Michal Simek wrote:
>
>
> On 2/15/24 18:19, Sean Anderson wrote:
>> Currently, when we boot from JTAG we try to boot U-Boot from RAM.
>> However, this is a bit tricky to time, since the debugger has to wait
>> for SPL to initialize RAM before it can load U-Boot. This can result in
>> long waits, since occasionally initializing RAM (and other things in
>> psu_init) takes a long time to complete and the debugger must wait for
>> this worst case.
>>
>> Support semihosting if it is enabled, as it lets U-Boot tell the
>> debugger when we are ready for the image. This means we don't have to
>> wait any more than necessary. We don't change the default config to
>> ensure we don't break compatibility with existing debuggers that don't
>> expect us to hit semihosting breakpoints.
>>
>> Signed-off-by: Sean Anderson <sean.anderson at seco.com>
>> ---
>>
>>   arch/arm/mach-zynqmp/spl.c | 10 ++++++++--
>>   1 file changed, 8 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-zynqmp/spl.c b/arch/arm/mach-zynqmp/spl.c
>> index a0f35f36faa..5af735aa5ce 100644
>> --- a/arch/arm/mach-zynqmp/spl.c
>> +++ b/arch/arm/mach-zynqmp/spl.c
>> @@ -9,6 +9,7 @@
>>   #include <image.h>
>>   #include <init.h>
>>   #include <log.h>
>> +#include <semihosting.h>
>>   #include <spl.h>
>>   #include <linux/delay.h>
>>
>> @@ -66,6 +67,11 @@ void spl_board_init(void)
>>   }
>>   #endif
>>
>> +static u32 jtag_boot_device(void)
>> +{
>> +       return semihosting_enabled() ? BOOT_DEVICE_SMH : BOOT_DEVICE_RAM;
>> +}
>> +
>>   void board_boot_order(u32 *spl_boot_list)
>>   {
>>          spl_boot_list[0] = spl_boot_device();
>> @@ -75,7 +81,7 @@ void board_boot_order(u32 *spl_boot_list)
>>          if (spl_boot_list[0] == BOOT_DEVICE_MMC2)
>>                  spl_boot_list[1] = BOOT_DEVICE_MMC1;
>>
>> -       spl_boot_list[2] = BOOT_DEVICE_RAM;
>> +       spl_boot_list[2] = jtag_boot_device();
>>   }
>>
>>   u32 spl_boot_device(void)
>> @@ -97,7 +103,7 @@ u32 spl_boot_device(void)
>>
>>          switch (bootmode) {
>>          case JTAG_MODE:
>> -               return BOOT_DEVICE_RAM;
>> +               return jtag_boot_device();
>>   #ifdef CONFIG_SPL_MMC
>>          case SD_MODE1:
>>          case SD1_LSHFT_MODE: /* not working on silicon v1 */
>
> Good timing. Can you please tell me how to test this? What's the setup?
> Which debugger are you using?

I am using OpenOCD with the patches at https://review.openocd.org/c/openocd/+/8133

My boot flow is

SPL -> ATF -> U-Boot (no FSBL)

This allows me to use a FIT which saves some time since I can
compress the bitstream. Right now I am using
xilinx_zynqmp_virt_defconfig with the following modifications:

CONFIG_SYS_LOAD_ADDR=0x30000000
# CONFIG_SPL_OS_BOOT is not set
CONFIG_SPL_SEMIHOSTING=y

I also have CONFIG_XILINX_PS_INIT_FILE,
CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE, and CONFIG_PMUFW_INIT_FILE defined as
appropriate. I use the following FIT for U-Boot:

/dts-v1/;

/ {
    description = "U-Boot and ATF";
    #address-cells = <1>;

    images {
        atf {
            description = "Arm Trusted Firmware";
            data = /incbin/("arm-trusted-firmware.bin");
            type = "firmware";
            os = "arm-trusted-firmware";
            arch = "arm64";
            compression = "none";
            load = <0xfffea000>;
            entry = <0xfffea000>;
        };

        fpga {
            description = "PL Bitstream";
            data = /incbin/("system.bit.gz");
            type = "fpga";
            arch = "arm64";
            compression = "gzip";
            load = <0x7c000000>;
            compatible = "u-boot,fpga-legacy";
        };

        u-boot {
            description = "U-Boot";
            data = /incbin/("u-boot-nodtb.bin");
            type = "firmware";
            os = "u-boot";
            arch = "arm64";
            compression = "none";
            load = <0x00080000>;
            entry = <0x00080000>;
        };

        fdt {
            description = "U-Boot FDT";
            data = /incbin/("u-boot.dtb");
            type = "flat_dt";
            arch = "arm64";
            compression = "none";
            hash-1 {
                algo = "crc32";
            };
        };
    };

    configurations {
        default = "conf";
        conf {
            description = "Boot ATF and U-Boot";
            firmware = "atf";
            loadables = "u-boot", "fpga";
            fdt = "fdt";
        };
    };
};

Boot output looks like

U-Boot SPL 2024.01 (Feb 15 2024 - 17:03:10 +0000)
Loading new PMUFW cfg obj (1848 bytes)
PMUFW:  v1.1
Silicon version:        3
EL Level:       EL3
Secure Boot:    not authenticated, not encrypted
Multiboot:      0
Trying to boot from MMC1
FPGA image loaded from FIT
NOTICE:  BL31: v2.6(release):xlnx_rebase_v2.6_2022.2
NOTICE:  BL31: Built : 03:55:03, Sep  9 2022

U-Boot 2024.01 (Feb 15 2024 - 17:03:10 +0000)

CPU:   ZynqMP
Silicon: v3
Chip:  zu4
Board: Xilinx ZynqMP
DRAM:  2 GiB (effective 4 GiB)
PMUFW:  v1.1
EL Level:       EL2
Secure Boot:    not authenticated, not encrypted
Core:  67 devices, 29 uclasses, devicetree: board
Warning: Device tree includes old 'u-boot,dm-' tags: please fix by 2023.07!
NAND:  0 MiB
MMC:   PMUFW:  No permission to change config object
arasan_sdhci mmc at ff170000: Sdhci card detect state not stable
arasan_sdhci mmc at ff170000: Sdhci card detect state not stable
mmc at ff170000 - probe failed: -110
mmc at ff160000: 0arasan_sdhci mmc at ff170000: Sdhci card detect state not stable

Loading Environment from nowhere... OK
In:    serial
Out:   serial,vidconsole
Err:   serial,vidconsole
Bootmode: JTAG_MODE
Reset reason:   EXTERNAL
Net:   zynq_gem ethernet at ff0b0000: failed to get tx_clock
zynq_gem ethernet at ff0c0000: failed to get tx_clock
zynq_gem ethernet at ff0d0000: failed to get tx_clock
zynq_gem ethernet at ff0e0000: failed to get tx_clock
No ethernet found.

scanning bus for devices...
SATA link 0 timeout.
SATA link 1 timeout.
AHCI 0001.0301 32 slots 2 ports 6 Gbps 0x3 impl SATA mode
flags: 64bit ncq pm clo only pmp fbss pio slum part ccc apst
starting USB...
Bus usb at fe300000: Register 2000440 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus usb at fe300000 for devices... 1 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
Hit any key to stop autoboot:  0

> Also curious if semihosting serial can be used in your setup.

I haven't tested it.

Hope that helps. Unfortunately, I don't think all of the above is
documented in one place.

--Sean

[Embedded World 2024, SECO SpA]<https://www.messe-ticket.de/Nuernberg/embeddedworld2024/Register/ew24517689>


More information about the U-Boot mailing list