dm: Add support for all targets which requires MANUAL_RELOC
Targets with CONFIG_NEEDS_MANUAL_RELOC do not use REL/RELA relocation (mostly only GOT) where functions aray are not updated. This patch is fixing function pointers for DM core and serial-uclass to ensure that relocated functions are called. Signed-off-by: Michal Simek <michal.simek@xilinx.com> Acked-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
		
							parent
							
								
									99c0ae16d8
								
							
						
					
					
						commit
						484fdf5ba0
					
				|  | @ -37,6 +37,65 @@ struct udevice *dm_root(void) | |||
| 	return gd->dm_root; | ||||
| } | ||||
| 
 | ||||
| #if defined(CONFIG_NEEDS_MANUAL_RELOC) | ||||
| void fix_drivers(void) | ||||
| { | ||||
| 	struct driver *drv = | ||||
| 		ll_entry_start(struct driver, driver); | ||||
| 	const int n_ents = ll_entry_count(struct driver, driver); | ||||
| 	struct driver *entry; | ||||
| 
 | ||||
| 	for (entry = drv; entry != drv + n_ents; entry++) { | ||||
| 		if (entry->of_match) | ||||
| 			entry->of_match = (const struct udevice_id *) | ||||
| 				((u32)entry->of_match + gd->reloc_off); | ||||
| 		if (entry->bind) | ||||
| 			entry->bind += gd->reloc_off; | ||||
| 		if (entry->probe) | ||||
| 			entry->probe += gd->reloc_off; | ||||
| 		if (entry->remove) | ||||
| 			entry->remove += gd->reloc_off; | ||||
| 		if (entry->unbind) | ||||
| 			entry->unbind += gd->reloc_off; | ||||
| 		if (entry->ofdata_to_platdata) | ||||
| 			entry->ofdata_to_platdata += gd->reloc_off; | ||||
| 		if (entry->child_pre_probe) | ||||
| 			entry->child_pre_probe += gd->reloc_off; | ||||
| 		if (entry->child_post_remove) | ||||
| 			entry->child_post_remove += gd->reloc_off; | ||||
| 		/* OPS are fixed in every uclass post_probe function */ | ||||
| 		if (entry->ops) | ||||
| 			entry->ops += gd->reloc_off; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void fix_uclass(void) | ||||
| { | ||||
| 	struct uclass_driver *uclass = | ||||
| 		ll_entry_start(struct uclass_driver, uclass); | ||||
| 	const int n_ents = ll_entry_count(struct uclass_driver, uclass); | ||||
| 	struct uclass_driver *entry; | ||||
| 
 | ||||
| 	for (entry = uclass; entry != uclass + n_ents; entry++) { | ||||
| 		if (entry->post_bind) | ||||
| 			entry->post_bind += gd->reloc_off; | ||||
| 		if (entry->pre_unbind) | ||||
| 			entry->pre_unbind += gd->reloc_off; | ||||
| 		if (entry->post_probe) | ||||
| 			entry->post_probe += gd->reloc_off; | ||||
| 		if (entry->pre_remove) | ||||
| 			entry->pre_remove += gd->reloc_off; | ||||
| 		if (entry->init) | ||||
| 			entry->init += gd->reloc_off; | ||||
| 		if (entry->destroy) | ||||
| 			entry->destroy += gd->reloc_off; | ||||
| 		/* FIXME maybe also need to fix these ops */ | ||||
| 		if (entry->ops) | ||||
| 			entry->ops += gd->reloc_off; | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| int dm_init(void) | ||||
| { | ||||
| 	int ret; | ||||
|  | @ -47,6 +106,11 @@ int dm_init(void) | |||
| 	} | ||||
| 	INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST); | ||||
| 
 | ||||
| #if defined(CONFIG_NEEDS_MANUAL_RELOC) | ||||
| 	fix_drivers(); | ||||
| 	fix_uclass(); | ||||
| #endif | ||||
| 
 | ||||
| 	ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
|  |  | |||
|  | @ -258,6 +258,22 @@ static int serial_post_probe(struct udevice *dev) | |||
| #endif | ||||
| 	int ret; | ||||
| 
 | ||||
| #if defined(CONFIG_NEEDS_MANUAL_RELOC) | ||||
| 	if (ops->setbrg) | ||||
| 		ops->setbrg += gd->reloc_off; | ||||
| 	if (ops->getc) | ||||
| 		ops->getc += gd->reloc_off; | ||||
| 	if (ops->putc) | ||||
| 		ops->putc += gd->reloc_off; | ||||
| 	if (ops->pending) | ||||
| 		ops->pending += gd->reloc_off; | ||||
| 	if (ops->clear) | ||||
| 		ops->clear += gd->reloc_off; | ||||
| #if CONFIG_POST & CONFIG_SYS_POST_UART | ||||
| 	if (ops->loop) | ||||
| 		ops->loop += gd->reloc_off | ||||
| #endif | ||||
| #endif | ||||
| 	/* Set the baud rate */ | ||||
| 	if (ops->setbrg) { | ||||
| 		ret = ops->setbrg(dev, gd->baudrate); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue