aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/setup_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/setup_64.c')
-rw-r--r--arch/powerpc/kernel/setup_64.c95
1 files changed, 74 insertions, 21 deletions
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 1f6816003ebe..797ea95aae2e 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -57,11 +57,13 @@
57#include <asm/cache.h> 57#include <asm/cache.h>
58#include <asm/page.h> 58#include <asm/page.h>
59#include <asm/mmu.h> 59#include <asm/mmu.h>
60#include <asm/mmu-hash64.h>
60#include <asm/firmware.h> 61#include <asm/firmware.h>
61#include <asm/xmon.h> 62#include <asm/xmon.h>
62#include <asm/udbg.h> 63#include <asm/udbg.h>
63#include <asm/kexec.h> 64#include <asm/kexec.h>
64#include <asm/swiotlb.h> 65#include <asm/swiotlb.h>
66#include <asm/mmu_context.h>
65 67
66#include "setup.h" 68#include "setup.h"
67 69
@@ -142,11 +144,14 @@ early_param("smt-enabled", early_smt_enabled);
142#define check_smt_enabled() 144#define check_smt_enabled()
143#endif /* CONFIG_SMP */ 145#endif /* CONFIG_SMP */
144 146
145/* Put the paca pointer into r13 and SPRG3 */ 147/* Put the paca pointer into r13 and SPRG_PACA */
146void __init setup_paca(int cpu) 148void __init setup_paca(int cpu)
147{ 149{
148 local_paca = &paca[cpu]; 150 local_paca = &paca[cpu];
149 mtspr(SPRN_SPRG3, local_paca); 151 mtspr(SPRN_SPRG_PACA, local_paca);
152#ifdef CONFIG_PPC_BOOK3E
153 mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb);
154#endif
150} 155}
151 156
152/* 157/*
@@ -230,9 +235,6 @@ void early_setup_secondary(void)
230#endif /* CONFIG_SMP */ 235#endif /* CONFIG_SMP */
231 236
232#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) 237#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
233extern unsigned long __secondary_hold_spinloop;
234extern void generic_secondary_smp_init(void);
235
236void smp_release_cpus(void) 238void smp_release_cpus(void)
237{ 239{
238 unsigned long *ptr; 240 unsigned long *ptr;
@@ -453,6 +455,24 @@ static void __init irqstack_early_init(void)
453#define irqstack_early_init() 455#define irqstack_early_init()
454#endif 456#endif
455 457
458#ifdef CONFIG_PPC_BOOK3E
459static void __init exc_lvl_early_init(void)
460{
461 unsigned int i;
462
463 for_each_possible_cpu(i) {
464 critirq_ctx[i] = (struct thread_info *)
465 __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
466 dbgirq_ctx[i] = (struct thread_info *)
467 __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
468 mcheckirq_ctx[i] = (struct thread_info *)
469 __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
470 }
471}
472#else
473#define exc_lvl_early_init()
474#endif
475
456/* 476/*
457 * Stack space used when we detect a bad kernel stack pointer, and 477 * Stack space used when we detect a bad kernel stack pointer, and
458 * early in SMP boots before relocation is enabled. 478 * early in SMP boots before relocation is enabled.
@@ -512,6 +532,7 @@ void __init setup_arch(char **cmdline_p)
512 init_mm.brk = klimit; 532 init_mm.brk = klimit;
513 533
514 irqstack_early_init(); 534 irqstack_early_init();
535 exc_lvl_early_init();
515 emergency_stack_init(); 536 emergency_stack_init();
516 537
517#ifdef CONFIG_PPC_STD_MMU_64 538#ifdef CONFIG_PPC_STD_MMU_64
@@ -534,6 +555,10 @@ void __init setup_arch(char **cmdline_p)
534#endif 555#endif
535 556
536 paging_init(); 557 paging_init();
558
559 /* Initialize the MMU context management stuff */
560 mmu_context_init();
561
537 ppc64_boot_msg(0x15, "Setup Done"); 562 ppc64_boot_msg(0x15, "Setup Done");
538} 563}
539 564
@@ -569,25 +594,53 @@ void cpu_die(void)
569} 594}
570 595
571#ifdef CONFIG_SMP 596#ifdef CONFIG_SMP
572void __init setup_per_cpu_areas(void) 597#define PCPU_DYN_SIZE ()
598
599static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)
573{ 600{
574 int i; 601 return __alloc_bootmem_node(NODE_DATA(cpu_to_node(cpu)), size, align,
575 unsigned long size; 602 __pa(MAX_DMA_ADDRESS));
576 char *ptr; 603}
577
578 /* Copy section for each CPU (we discard the original) */
579 size = ALIGN(__per_cpu_end - __per_cpu_start, PAGE_SIZE);
580#ifdef CONFIG_MODULES
581 if (size < PERCPU_ENOUGH_ROOM)
582 size = PERCPU_ENOUGH_ROOM;
583#endif
584 604
585 for_each_possible_cpu(i) { 605static void __init pcpu_fc_free(void *ptr, size_t size)
586 ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size); 606{
607 free_bootmem(__pa(ptr), size);
608}
587 609
588 paca[i].data_offset = ptr - __per_cpu_start; 610static int pcpu_cpu_distance(unsigned int from, unsigned int to)
589 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); 611{
590 } 612 if (cpu_to_node(from) == cpu_to_node(to))
613 return LOCAL_DISTANCE;
614 else
615 return REMOTE_DISTANCE;
616}
617
618void __init setup_per_cpu_areas(void)
619{
620 const size_t dyn_size = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE;
621 size_t atom_size;
622 unsigned long delta;
623 unsigned int cpu;
624 int rc;
625
626 /*
627 * Linear mapping is one of 4K, 1M and 16M. For 4K, no need
628 * to group units. For larger mappings, use 1M atom which
629 * should be large enough to contain a number of units.
630 */
631 if (mmu_linear_psize == MMU_PAGE_4K)
632 atom_size = PAGE_SIZE;
633 else
634 atom_size = 1 << 20;
635
636 rc = pcpu_embed_first_chunk(0, dyn_size, atom_size, pcpu_cpu_distance,
637 pcpu_fc_alloc, pcpu_fc_free);
638 if (rc < 0)
639 panic("cannot initialize percpu area (err=%d)", rc);
640
641 delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
642 for_each_possible_cpu(cpu)
643 paca[cpu].data_offset = delta + pcpu_unit_offsets[cpu];
591} 644}
592#endif 645#endif
593 646