[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