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
2 changed files with 41 additions and 1 deletions
|
@ -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);
|
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)
|
void __init early_init_dt_add_memory_arch(u64 base, u64 size)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PPC64
|
#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 */
|
/* 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)
|
static void __init early_reserve_mem_dt(void)
|
||||||
|
@ -740,6 +755,30 @@ void __init early_init_devtree(void *params)
|
||||||
DBG(" <- early_init_devtree()\n");
|
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
|
* 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_device_tree(void);
|
||||||
extern void unflatten_and_copy_device_tree(void);
|
extern void unflatten_and_copy_device_tree(void);
|
||||||
extern void early_init_devtree(void *);
|
extern void early_init_devtree(void *);
|
||||||
|
extern void early_get_first_memblock_info(void *, phys_addr_t *);
|
||||||
#else /* CONFIG_OF_FLATTREE */
|
#else /* CONFIG_OF_FLATTREE */
|
||||||
static inline const char *of_flat_dt_get_machine_name(void) { return NULL; }
|
static inline const char *of_flat_dt_get_machine_name(void) { return NULL; }
|
||||||
static inline void unflatten_device_tree(void) {}
|
static inline void unflatten_device_tree(void) {}
|
||||||
|
|
Loading…
Add table
Reference in a new issue