@@ -601,10 +601,10 @@ int mpfs_read_serial_number(uint8_t *serial)
601601#define MICROCHIP_OUI_1 0x04
602602#define MICROCHIP_OUI_2 0xA3
603603
604- static int mpfs_dts_fixup_inplace (void * dts_addr )
604+ static int mpfs_dts_fixup_inplace (void * dts_addr , uint32_t capacity )
605605{
606+ fdt_ctx ctx ;
606607 int off , ret ;
607- struct fdt_header * fdt = (struct fdt_header * )dts_addr ;
608608 uint8_t device_serial_number [DEVICE_SERIAL_NUMBER_SIZE ];
609609 uint8_t mac_addr [6 ];
610610#if defined(MPFS_DDR_INIT ) && defined(WOLFBOOT_MMODE_SMODE_BOOT )
@@ -620,31 +620,33 @@ static int mpfs_dts_fixup_inplace(void* dts_addr)
620620 unsigned int i ;
621621#endif
622622
623- /* Verify FDT header */
624- ret = fdt_check_header ( dts_addr );
623+ /* Validate the blob against the window it actually occupies. */
624+ ret = fdt_open ( & ctx , dts_addr , capacity );
625625 if (ret != 0 ) {
626626 wolfBoot_printf ("FDT: Invalid header! %d\n" , ret );
627627 return ret ;
628628 }
629629
630- wolfBoot_printf ("FDT: Version %d, Size %d\n" ,
631- fdt_version (fdt ), fdt_totalsize (fdt ));
630+ wolfBoot_printf ("FDT: Size %d\n" , (int )fdt_size (& ctx ));
632631
633- /* Expand total size to allow adding/modifying properties.
632+ /* Reserve free space to allow adding/modifying properties.
634633 * Sizing comes from WOLFBOOT_FDT_FIXUP_HEADROOM in include/fdt.h. */
635- fdt_set_totalsize (fdt ,
636- fdt_totalsize (fdt ) + WOLFBOOT_FDT_FIXUP_HEADROOM );
634+ ret = fdt_grow (& ctx , WOLFBOOT_FDT_FIXUP_HEADROOM );
635+ if (ret != 0 ) {
636+ wolfBoot_printf ("FDT: No headroom for fixups (%d)\n" , ret );
637+ return ret ;
638+ }
637639
638640 /* Find /chosen node */
639- off = fdt_find_node_offset ( fdt , -1 , "chosen" );
641+ off = fdt_subnode_offset ( & ctx , 0 , "chosen" );
640642 if (off < 0 ) {
641643 /* Create /chosen node if it doesn't exist */
642- off = fdt_add_subnode (fdt , 0 , "chosen" );
644+ off = fdt_add_subnode (& ctx , 0 , "chosen" );
643645 }
644646
645647 if (off >= 0 ) {
646648 /* Set bootargs property */
647- fdt_fixup_str (fdt , off , "chosen" , "bootargs" , LINUX_BOOTARGS );
649+ fdt_fixup_str (& ctx , off , "chosen" , "bootargs" , LINUX_BOOTARGS );
648650 }
649651
650652#if defined(MPFS_DDR_INIT ) && defined(WOLFBOOT_MMODE_SMODE_BOOT )
@@ -665,9 +667,9 @@ static int mpfs_dts_fixup_inplace(void* dts_addr)
665667 * parked harts on the kernel's request (SMP). cpu@0 (E51) is already
666668 * disabled in the Yocto DTB; cpu@1 stays enabled so Linux boots on it. */
667669 for (i = 0 ; i < sizeof (cpu_off ) / sizeof (cpu_off [0 ]); i ++ ) {
668- off = fdt_find_node_offset (fdt , -1 , cpu_off [i ]);
670+ off = fdt_find_node_offset (& ctx , -1 , cpu_off [i ]);
669671 if (off >= 0 ) {
670- ret = fdt_fixup_str (fdt , off , cpu_off [i ], "status" ,
672+ ret = fdt_fixup_str (& ctx , off , cpu_off [i ], "status" ,
671673 "disabled" );
672674 if (ret != 0 ) {
673675 wolfBoot_printf ("FDT: Failed to disable %s (%d)\n" ,
@@ -713,9 +715,9 @@ static int mpfs_dts_fixup_inplace(void* dts_addr)
713715 mac_addr [3 ], mac_addr [4 ], mac_addr [5 ]);
714716
715717 /* Set local-mac-address for ethernet@20110000 (mac0) */
716- off = fdt_find_node_offset (fdt , -1 , "ethernet@20110000" );
718+ off = fdt_find_node_offset (& ctx , -1 , "ethernet@20110000" );
717719 if (off >= 0 ) {
718- ret = fdt_setprop (fdt , off , "local-mac-address" , mac_addr , 6 );
720+ ret = fdt_setprop (& ctx , off , "local-mac-address" , mac_addr , 6 );
719721 if (ret != 0 ) {
720722 wolfBoot_printf ("FDT: Failed to set mac0 address (%d)\n" , ret );
721723 }
@@ -732,9 +734,9 @@ static int mpfs_dts_fixup_inplace(void* dts_addr)
732734 mac_addr [0 ], mac_addr [1 ], mac_addr [2 ],
733735 mac_addr [3 ], mac_addr [4 ], mac_addr [5 ]);
734736
735- off = fdt_find_node_offset (fdt , -1 , "ethernet@20112000" );
737+ off = fdt_find_node_offset (& ctx , -1 , "ethernet@20112000" );
736738 if (off >= 0 ) {
737- ret = fdt_setprop (fdt , off , "local-mac-address" , mac_addr , 6 );
739+ ret = fdt_setprop (& ctx , off , "local-mac-address" , mac_addr , 6 );
738740 if (ret != 0 ) {
739741 wolfBoot_printf ("FDT: Failed to set mac1 address (%d)\n" , ret );
740742 }
@@ -824,9 +826,10 @@ int wolfBoot_fit_memcpy(void *dst, const void *src, uint32_t len)
824826 * (WOLFBOOT_LOAD_DTS_ADDRESS) but CPU writes to DDR do not land here, so copy
825827 * it (non-cached read) into an L2 scratch buffer, run the FDT fixups there
826828 * (CPU L2 writes work), then PDMA the result back to DDR. */
827- int hal_dts_fixup (void * dts_addr )
829+ int hal_dts_fixup (void * dts_addr , uint32_t capacity )
828830{
829831 static uint8_t l2_dtb [64 * 1024 ] __attribute__((aligned (8 )));
832+ fdt_ctx ctx ;
830833 const uint8_t * ddr_nc ;
831834 uint32_t sz ;
832835 int ret ;
@@ -835,29 +838,29 @@ int hal_dts_fixup(void* dts_addr)
835838 return -1 ;
836839 }
837840 ddr_nc = (const uint8_t * )((uintptr_t )dts_addr | 0x40000000UL );
838- if (fdt_check_header ((void * )ddr_nc ) != 0 ) {
841+ /* The source is bounded by whichever is smaller: the caller's DDR
842+ * window, or what the L2 scratch buffer can hold once the fixup
843+ * headroom is set aside. fdt_open() enforces it, so the memcpy below
844+ * cannot overrun l2_dtb however corrupt the header is. */
845+ sz = (uint32_t )(sizeof (l2_dtb ) - WOLFBOOT_FDT_FIXUP_HEADROOM );
846+ if (capacity < sz ) {
847+ sz = capacity ;
848+ }
849+ if (fdt_open (& ctx , (void * )ddr_nc , sz ) != 0 ) {
839850 wolfBoot_printf ("FDT: invalid header at %p\n" , dts_addr );
840851 return -1 ;
841852 }
842- sz = (uint32_t )fdt_totalsize ((void * )ddr_nc );
843- /* Overflow-safe bound: compare without adding. A near-UINT32_MAX
844- * totalsize (fdt_check_header does not bound it) would make
845- * sz + WOLFBOOT_FDT_FIXUP_HEADROOM wrap to a small value that passes the
846- * check, after which memcpy(l2_dtb, ., sz) overruns the 64 KB buffer.
847- * sizeof(l2_dtb) (64 KB) is always greater than the headroom. */
848- if (sz > sizeof (l2_dtb ) - WOLFBOOT_FDT_FIXUP_HEADROOM ) {
849- wolfBoot_printf ("FDT: dtb too large for L2 fixup (%u > %u)\n" ,
850- (unsigned )sz ,
851- (unsigned )(sizeof (l2_dtb ) - WOLFBOOT_FDT_FIXUP_HEADROOM ));
852- return -1 ;
853- }
853+ sz = fdt_size (& ctx );
854854 /* DDR (non-cached) -> L2 */
855855 memcpy (l2_dtb , ddr_nc , sz );
856- /* fixup in the CPU-writable L2 buffer */
857- ret = mpfs_dts_fixup_inplace (l2_dtb );
856+ /* fixup in the CPU-writable L2 buffer, which may use the whole of it */
857+ ret = mpfs_dts_fixup_inplace (l2_dtb , ( uint32_t ) sizeof ( l2_dtb ) );
858858 /* L2 -> DDR via PDMA (expanded totalsize) */
859- if (wolfBoot_fit_memcpy (dts_addr , l2_dtb ,
860- (uint32_t )fdt_totalsize (l2_dtb )) != 0 ) {
859+ if (fdt_open (& ctx , l2_dtb , (uint32_t )sizeof (l2_dtb )) != 0 ) {
860+ wolfBoot_printf ("FDT: fixed-up dtb rejected\n" );
861+ return -1 ;
862+ }
863+ if (wolfBoot_fit_memcpy (dts_addr , l2_dtb , fdt_size (& ctx )) != 0 ) {
861864 wolfBoot_printf ("FDT: dtb copy-back to DDR failed\n" );
862865 return -1 ;
863866 }
@@ -868,12 +871,12 @@ int hal_dts_fixup(void* dts_addr)
868871 * run the fixups directly in place (the original behavior, kept so
869872 * FDT-enabled non-DDR builds do not silently fall back to the weak
870873 * no-op hal_dts_fixup). */
871- int hal_dts_fixup (void * dts_addr )
874+ int hal_dts_fixup (void * dts_addr , uint32_t capacity )
872875{
873876 if (dts_addr == NULL ) {
874877 return -1 ;
875878 }
876- return mpfs_dts_fixup_inplace (dts_addr );
879+ return mpfs_dts_fixup_inplace (dts_addr , capacity );
877880}
878881#endif /* WOLFBOOT_RISCV_MMODE && MPFS_DDR_INIT */
879882
0 commit comments