This patch makes use of a new sunxi SPL header format, where fields for passing data to U-Boot are reserved. This allows the "fel" utility to provide specific pieces of information by setting these fields (which will be evaluated by U-Boot then). For now, we may specify a memory region by address and size.
Currently the typical use case is to provide the memory location of the boot script file (boot.scr). A suitably modified U-Boot can adjust the boot process accordingly and will auto-execute the script. Signed-off-by: Bernhard Nortmann <[email protected]> --- fel.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/fel.c b/fel.c index c27ebe3..7befd15 100644 --- a/fel.c +++ b/fel.c @@ -259,6 +259,10 @@ void aw_fel_read(libusb_device_handle *usb, uint32_t offset, void *buf, size_t l aw_read_fel_status(usb); } +/* forward declaration to keep the compiler happy */ +void pass_fel_information(libusb_device_handle *usb, + uint32_t data_addr, size_t data_size); + void aw_fel_write(libusb_device_handle *usb, void *buf, uint32_t offset, size_t len) { /* safeguard against overwriting an already loaded U-Boot binary */ @@ -272,6 +276,15 @@ void aw_fel_write(libusb_device_handle *usb, void *buf, uint32_t offset, size_t aw_send_fel_request(usb, AW_FEL_1_WRITE, offset, len); aw_usb_write(usb, buf, len); aw_read_fel_status(usb); + + /* + * If we have transferred a script, try to inform U-Boot about it. + * An IH_TYPE_SCRIPT has a well-defined header (including length), + * so we pass only the address and keep the size value at zero. + * (Reserving size > 0 for different data / future extensions.) + */ + if (len > HEADER_SIZE && get_image_type(buf, 0) == IH_TYPE_SCRIPT) + pass_fel_information(usb, offset, 0); } void aw_fel_execute(libusb_device_handle *usb, uint32_t offset) @@ -280,6 +293,46 @@ void aw_fel_execute(libusb_device_handle *usb, uint32_t offset) aw_read_fel_status(usb); } +/* + * Test the SPL header for our "sunxi" variant. We want to make sure that + * we can safely use specific header fields to pass information to U-Boot. + * In case of a missing signature (e.g. Allwinner boot0) or header version + * mismatch, this function will return "false". If all seems fine, + * the result is "true". + */ +#define SPL_SIGNATURE "SPL" /* marks "sunxi" header */ +#define SPL_EXPECTED_VERSION 1 +int have_sunxi_spl(libusb_device_handle *usb) +{ + const uint8_t expected[] = SPL_SIGNATURE; + uint8_t spl_signature[4]; + + aw_fel_read(usb, 0x14, &spl_signature, sizeof(spl_signature)); + return (memcmp(spl_signature, expected, 3) == 0 + && spl_signature[3] == SPL_EXPECTED_VERSION); +} + +/* + * Pass information to U-Boot via specialized fields in the SPL header + * (see "boot_file_head" in ${U-BOOT}/tools/mksunxiboot.c), providing + * information about some data address and size. + * Typically this will be the DRAM location of a boot script (boot.scr). + */ +void pass_fel_information(libusb_device_handle *usb, + uint32_t data_addr, size_t data_size) +{ + /* write something _only_ if we have a suitable SPL header */ + if (have_sunxi_spl(usb)) { + struct { + uint32_t fel_data_address; + uint32_t fel_data_size; + } transfer = {data_addr, data_size}; + pr_info("Passing boot info via sunxi SPL: data addr 0x%08X, size 0x%X\n", + transfer.fel_data_address, transfer.fel_data_size); + aw_fel_write(usb, &transfer, 0x18, sizeof(transfer)); + } +} + void hexdump(void *data, uint32_t offset, size_t size) { size_t j; -- 2.4.6 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
