mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 15:41:40 +00:00
dm: core: Handle global_data moving in SPL
When CONFIG_SPL_STACK_R is enabled, and spl_init() is called before board_init_r(), spl_relocate_stack_gd() will move global_data to a new place in memory. This affects driver model since it uses a list for the uclasses. Unless this is updated the list will become invalid. When looking for a non-existent uclass, such as when adding a new one, the loop in uclass_find() may continue forever, thus causing a hang. Add a function to correct this rather obscure bug. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
a9401b2bc9
commit
2f11cd9121
3 changed files with 20 additions and 0 deletions
|
@ -513,6 +513,9 @@ ulong spl_relocate_stack_gd(void)
|
|||
ptr = CONFIG_SPL_STACK_R_ADDR - roundup(sizeof(gd_t),16);
|
||||
new_gd = (gd_t *)ptr;
|
||||
memcpy(new_gd, (void *)gd, sizeof(gd_t));
|
||||
#if CONFIG_IS_ENABLED(DM)
|
||||
dm_fixup_for_gd_move(new_gd);
|
||||
#endif
|
||||
#if !defined(CONFIG_ARM)
|
||||
gd = new_gd;
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,13 @@ struct udevice *dm_root(void)
|
|||
return gd->dm_root;
|
||||
}
|
||||
|
||||
void dm_fixup_for_gd_move(struct global_data *new_gd)
|
||||
{
|
||||
/* The sentinel node has moved, so update things that point to it */
|
||||
new_gd->uclass_root.next->prev = &new_gd->uclass_root;
|
||||
new_gd->uclass_root.prev->next = &new_gd->uclass_root;
|
||||
}
|
||||
|
||||
fdt_addr_t dm_get_translation_offset(void)
|
||||
{
|
||||
struct udevice *root = dm_root();
|
||||
|
|
|
@ -21,6 +21,16 @@ struct udevice;
|
|||
*/
|
||||
struct udevice *dm_root(void);
|
||||
|
||||
struct global_data;
|
||||
/**
|
||||
* dm_fixup_for_gd_move() - Handle global_data moving to a new place
|
||||
*
|
||||
* The uclass list is part of global_data. Due to the way lists work, moving
|
||||
* the list will cause it to become invalid. This function fixes that up so
|
||||
* that the uclass list will work correctly.
|
||||
*/
|
||||
void dm_fixup_for_gd_move(struct global_data *new_gd);
|
||||
|
||||
/**
|
||||
* dm_scan_platdata() - Scan all platform data and bind drivers
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue