19 #include <linux/kernel.h>
20 #include <linux/string.h>
24 #include <linux/types.h>
25 #include <linux/pci.h>
29 #include <linux/bitops.h>
30 #include <linux/export.h>
31 #include <linux/kexec.h>
39 #include <asm/processor.h>
46 #include <asm/pgtable.h>
48 #include <asm/iommu.h>
49 #include <asm/btext.h>
50 #include <asm/sections.h>
51 #include <asm/machdep.h>
53 #include <asm/pci-bridge.h>
54 #include <asm/kexec.h>
61 #define DBG(fmt...) printk(KERN_ERR fmt)
75 static int __init early_parse_mem(
char *
p)
91 static inline int overlaps_initrd(
unsigned long start,
unsigned long size)
93 #ifdef CONFIG_BLK_DEV_INITRD
111 static void __init move_device_tree(
void)
116 DBG(
"-> move_device_tree\n");
123 overlaps_initrd(start, size)) {
127 DBG(
"Moved device tree to 0x%p\n", p);
130 DBG(
"<- move_device_tree\n");
146 static struct ibm_pa_feature {
148 unsigned long mmu_features;
149 unsigned int cpu_user_ftrs;
150 unsigned char pabyte;
152 unsigned char invert;
156 {0, MMU_FTR_SLB, 0, 0, 2, 0},
160 {0, MMU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0},
164 static void __init scan_features(
unsigned long node,
unsigned char *ftrs,
165 unsigned long tablelen,
166 struct ibm_pa_feature *
fp,
167 unsigned long ft_size)
185 for (i = 0; i < ft_size; ++
i, ++
fp) {
186 if (fp->pabyte >= ftrs[0])
188 bit = (ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1;
189 if (bit ^ fp->invert) {
201 static void __init check_cpu_pa_features(
unsigned long node)
203 unsigned char *pa_ftrs;
204 unsigned long tablelen;
206 pa_ftrs = of_get_flat_dt_prop(node,
"ibm,pa-features", &tablelen);
210 scan_features(node, pa_ftrs, tablelen,
211 ibm_pa_features,
ARRAY_SIZE(ibm_pa_features));
214 #ifdef CONFIG_PPC_STD_MMU_64
219 slb_size_ptr = of_get_flat_dt_prop(node,
"slb-size",
NULL);
220 if (slb_size_ptr !=
NULL) {
224 slb_size_ptr = of_get_flat_dt_prop(node,
"ibm,slb-size",
NULL);
225 if (slb_size_ptr !=
NULL) {
230 #define check_cpu_slb_size(node) do { } while(0)
233 static struct feature_property {
236 unsigned long cpu_feature;
237 unsigned long cpu_user_ftr;
238 } feature_properties[] __initdata = {
239 #ifdef CONFIG_ALTIVEC
254 #if defined(CONFIG_44x) && defined(CONFIG_PPC_FPU)
258 char *
model = of_get_flat_dt_prop(node,
"model",
NULL);
267 if (model &&
strstr(model,
"440EP")) {
270 DBG(
"Using logical pvr %x for %s\n", pvr, model);
274 #define identical_pvr_fixup(node) do { } while(0)
277 static void __init check_cpu_feature_properties(
unsigned long node)
280 struct feature_property *fp = feature_properties;
284 prop = of_get_flat_dt_prop(node, fp->name,
NULL);
285 if (prop && *prop >= fp->min_value) {
292 static int __init early_init_dt_scan_cpus(
unsigned long node,
293 const char *uname,
int depth,
296 char *
type = of_get_flat_dt_prop(node,
"device_type",
NULL);
302 int found_thread = 0;
309 intserv = of_get_flat_dt_prop(node,
"ibm,ppc-interrupt-server#s", &len);
311 nthreads = len /
sizeof(
int);
313 intserv = of_get_flat_dt_prop(node,
"reg",
NULL);
321 for (i = 0; i < nthreads; i++) {
328 found = boot_cpu_count;
337 if (of_get_flat_dt_prop(node,
339 found = boot_cpu_count;
348 DBG(
"boot cpu: logical %d physical %d\n", found,
349 intserv[found_thread]);
351 set_hard_smp_processor_id(found, intserv[found_thread]);
367 prop = of_get_flat_dt_prop(node,
"cpu-version",
NULL);
368 if (prop && (*prop & 0xff000000) == 0x0f000000)
374 check_cpu_feature_properties(node);
375 check_cpu_pa_features(node);
378 #ifdef CONFIG_PPC_PSERIES
389 int depth,
void *data)
391 unsigned long *lprop;
394 if (early_init_dt_scan_chosen(node, uname, depth, data) == 0)
399 if (of_get_flat_dt_prop(node,
"linux,iommu-off",
NULL) !=
NULL)
401 if (of_get_flat_dt_prop(node,
"linux,iommu-force-on",
NULL) !=
NULL)
406 lprop = of_get_flat_dt_prop(node,
"linux,memory-limit",
NULL);
411 lprop = of_get_flat_dt_prop(node,
"linux,tce-alloc-start",
NULL);
414 lprop = of_get_flat_dt_prop(node,
"linux,tce-alloc-end",
NULL);
420 lprop = of_get_flat_dt_prop(node,
"linux,crashkernel-base",
NULL);
424 lprop = of_get_flat_dt_prop(node,
"linux,crashkernel-size",
NULL);
433 #ifdef CONFIG_PPC_PSERIES
445 unsigned int is_kexec_kdump = 0, rngs;
447 ls = of_get_flat_dt_prop(node,
"ibm,lmb-size", &l);
452 dm = of_get_flat_dt_prop(node,
"ibm,dynamic-memory", &l);
461 usm = of_get_flat_dt_prop(node,
"linux,drconf-usable-memory",
466 for (; n != 0; --
n) {
473 if ((flags & 0x80) || !(flags & 0x8))
475 size = memblock_size;
477 if (is_kexec_kdump) {
490 if (is_kexec_kdump) {
497 if (base >= 0x80000000ul)
499 if ((base + size) > 0x80000000ul)
500 size = 0x80000000ul - base;
509 #define early_init_dt_scan_drconf_memory(node) 0
512 static int __init early_init_dt_scan_memory_ppc(
unsigned long node,
514 int depth,
void *data)
517 strcmp(uname,
"ibm,dynamic-reconfiguration-memory") == 0)
520 return early_init_dt_scan_memory(node, uname, depth, data);
527 if (base >= 0x80000000ul)
529 if ((base + size) > 0x80000000ul)
530 size = 0x80000000ul - base;
539 first_memblock_size =
size;
551 #ifdef CONFIG_BLK_DEV_INITRD
561 static void __init early_reserve_mem(
void)
565 unsigned long self_base;
566 unsigned long self_size;
569 initial_boot_params->off_mem_rsvmap);
572 self_base =
__pa((
unsigned long)initial_boot_params);
573 self_size = initial_boot_params->totalsize;
576 #ifdef CONFIG_BLK_DEV_INITRD
589 if (*reserve_map > 0xffffffffull) {
590 u32 base_32, size_32;
591 u32 *reserve_map_32 = (
u32 *)reserve_map;
594 base_32 = *(reserve_map_32++);
595 size_32 = *(reserve_map_32++);
599 if (base_32 == self_base && size_32 == self_size)
601 DBG(
"reserving: %x -> %x\n", base_32, size_32);
608 base = *(reserve_map++);
609 size = *(reserve_map++);
612 DBG(
"reserving: %llx -> %llx\n", base, size);
621 DBG(
" -> early_init_devtree(%p)\n", params);
624 initial_boot_params =
params;
626 #ifdef CONFIG_PPC_RTAS
631 #ifdef CONFIG_PPC_POWERNV
636 #ifdef CONFIG_FA_DUMP
655 of_scan_flat_dt(early_init_dt_scan_root,
NULL);
656 of_scan_flat_dt(early_init_dt_scan_memory_ppc,
NULL);
672 #ifdef CONFIG_FA_DUMP
700 DBG(
"Scanning CPUs ...\n");
705 of_scan_flat_dt(early_init_dt_scan_cpus,
NULL);
707 #if defined(CONFIG_SMP) && defined(CONFIG_PPC64)
714 DBG(
" <- early_init_devtree()\n");
759 #ifdef CONFIG_PPC_PSERIES
765 static int of_finish_dynamic_node(
struct device_node *node)
775 node->
name =
"<NULL>";
777 node->
type =
"<NULL>";
787 if (machine_is(powermac))
800 unsigned long action,
void *node)
805 case PSERIES_RECONFIG_ADD:
806 err = of_finish_dynamic_node(node);
814 return notifier_from_errno(err);
822 static int __init prom_reconfig_setup(
void)
838 hardid = get_hard_smp_processor_id(cpu);
840 for_each_node_by_type(np,
"cpu") {
842 unsigned int plen,
t;
849 if (intserv ==
NULL) {
853 if (*reg == hardid) {
860 for (t = 0; t <
plen; t++) {
861 if (hardid == intserv[t]) {
873 #if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
876 static int __init export_flat_device_tree(
void)
881 flat_dt_blob.size = initial_boot_params->totalsize;
884 powerpc_debugfs_root, &flat_dt_blob);