[PATCH] arm64: zynqmp: Support semhosting boot method

Sean Anderson sean.anderson at seco.com
Thu Feb 15 20:35:45 CET 2024


On 2/15/24 14:31, Sean Anderson wrote:
> 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://cas5-0-urlprotect.trendmicro.com:443/wis/clicktime/v1/query?url=https%3a%2f%2freview.openocd.org%2fc%2fopenocd%2f%2b%2f8133&umid=819f1021-60b3-42c6-ac85-f327c489da7c&auth=d807158c60b7d2502abde8a2fc01f40662980862-7485d72bf875c6ddb963725debf981fe8dd33731
> 
> 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

Whoops, I attached a regular boot log. Semihosting looks pretty much the same:

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 SEMIHOSTING
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://cas5-0-urlprotect.trendmicro.com:443/wis/clicktime/v1/query?url=https%3a%2f%2fwww.messe%2dticket.de%2fNuernberg%2fembeddedworld2024%2fRegister%2few24517689&umid=819f1021-60b3-42c6-ac85-f327c489da7c&auth=d807158c60b7d2502abde8a2fc01f40662980862-bc7bc969189f8a12494ee2b4c211c8f322e167f8>



More information about the U-Boot mailing list