powerpc: introduce early_get_first_memblock_info
For a relocatable kernel since it can be loaded at any place, there is no any relation between the kernel start addr and the memstart_addr. So we can't calculate the memstart_addr from kernel start addr. And also we can't wait to do the relocation after we get the real memstart_addr from device tree because it is so late. So introduce a new function we can use to get the first memblock address and size in a very early stage (before machine_init). Signed-off-by: Kevin Hao <haokexin@gmail.com> Signed-off-by: Scott Wood <scottwood@freescale.com>
This commit is contained in:
parent
78a235efdc
commit
b27652dd21
|
@ -523,6 +523,20 @@ static int __init early_init_dt_scan_memory_ppc(unsigned long node,
|
|||
return early_init_dt_scan_memory(node, uname, depth, data);
|
||||
}
|
||||
|
||||
/*
|
||||
* For a relocatable kernel, we need to get the memstart_addr first,
|
||||
* then use it to calculate the virtual kernel start address. This has
|
||||
* to happen at a very early stage (before machine_init). In this case,
|
||||
* we just want to get the memstart_address and would not like to mess the
|
||||
* memblock at this stage. So introduce a variable to skip the memblock_add()
|
||||
* for this reason.
|
||||
*/
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
static int add_mem_to_memblock = 1;
|
||||
#else
|
||||
#define add_mem_to_memblock 1
|
||||
#endif
|
||||
|
||||
void __init early_init_dt_add_memory_arch(u64 base, u64 size)
|
||||
{
|
||||
#ifdef CONFIG_PPC64
|
||||
|
@ -543,7 +557,8 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
|
|||
}
|
||||
|
||||
/* Add the chunk to the MEMBLOCK list */
|
||||
memblock_add(base, size);
|
||||
if (add_mem_to_memblock)
|
||||
memblock_add(base, size);
|
||||
}
|
||||
|
||||
static void __init early_reserve_mem_dt(void)
|
||||
|
@ -740,6 +755,30 @@ void __init early_init_devtree(void *params)
|
|||
DBG(" <- early_init_devtree()\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
/*
|
||||
* This function run before early_init_devtree, so we have to init
|
||||
* initial_boot_params.
|
||||
*/
|
||||
void __init early_get_first_memblock_info(void *params, phys_addr_t *size)
|
||||
{
|
||||
/* Setup flat device-tree pointer */
|
||||
initial_boot_params = params;
|
||||
|
||||
/*
|
||||
* Scan the memory nodes and set add_mem_to_memblock to 0 to avoid
|
||||
* mess the memblock.
|
||||
*/
|
||||
add_mem_to_memblock = 0;
|
||||
of_scan_flat_dt(early_init_dt_scan_root, NULL);
|
||||
of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
|
||||
add_mem_to_memblock = 1;
|
||||
|
||||
if (size)
|
||||
*size = first_memblock_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******
|
||||
*
|
||||
* New implementation of the OF "find" APIs, return a refcounted
|
||||
|
|
|
@ -116,6 +116,7 @@ extern const void *of_flat_dt_match_machine(const void *default_match,
|
|||
extern void unflatten_device_tree(void);
|
||||
extern void unflatten_and_copy_device_tree(void);
|
||||
extern void early_init_devtree(void *);
|
||||
extern void early_get_first_memblock_info(void *, phys_addr_t *);
|
||||
#else /* CONFIG_OF_FLATTREE */
|
||||
static inline const char *of_flat_dt_get_machine_name(void) { return NULL; }
|
||||
static inline void unflatten_device_tree(void) {}
|
||||
|
|
Loading…
Reference in New Issue