aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc64/kernel/head.S30
-rw-r--r--arch/sparc64/kernel/setup.c23
-rw-r--r--arch/sparc64/kernel/smp.c16
-rw-r--r--include/asm-generic/pgtable.h11
-rw-r--r--include/asm-mips/pgtable.h10
-rw-r--r--include/asm-sparc64/pgtable.h17
6 files changed, 71 insertions, 36 deletions
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 3eadac5e171e..31c5892f5acc 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -10,6 +10,7 @@
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/version.h> 11#include <linux/version.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/threads.h>
13#include <asm/thread_info.h> 14#include <asm/thread_info.h>
14#include <asm/asi.h> 15#include <asm/asi.h>
15#include <asm/pstate.h> 16#include <asm/pstate.h>
@@ -493,6 +494,35 @@ tlb_fixup_done:
493 call prom_init 494 call prom_init
494 mov %l7, %o0 ! OpenPROM cif handler 495 mov %l7, %o0 ! OpenPROM cif handler
495 496
497 /* Initialize current_thread_info()->cpu as early as possible.
498 * In order to do that accurately we have to patch up the get_cpuid()
499 * assembler sequences. And that, in turn, requires that we know
500 * if we are on a Starfire box or not. While we're here, patch up
501 * the sun4v sequences as well.
502 */
503 call check_if_starfire
504 nop
505 call per_cpu_patch
506 nop
507 call sun4v_patch
508 nop
509
510#ifdef CONFIG_SMP
511 call hard_smp_processor_id
512 nop
513 cmp %o0, NR_CPUS
514 blu,pt %xcc, 1f
515 nop
516 call boot_cpu_id_too_large
517 nop
518 /* Not reached... */
519
5201:
521#else
522 mov 0, %o0
523#endif
524 stb %o0, [%g6 + TI_CPU]
525
496 /* Off we go.... */ 526 /* Off we go.... */
497 call start_kernel 527 call start_kernel
498 nop 528 nop
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 005167f82419..9cf1c88cd774 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -220,7 +220,7 @@ char reboot_command[COMMAND_LINE_SIZE];
220 220
221static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; 221static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 };
222 222
223static void __init per_cpu_patch(void) 223void __init per_cpu_patch(void)
224{ 224{
225 struct cpuid_patch_entry *p; 225 struct cpuid_patch_entry *p;
226 unsigned long ver; 226 unsigned long ver;
@@ -280,7 +280,7 @@ static void __init per_cpu_patch(void)
280 } 280 }
281} 281}
282 282
283static void __init sun4v_patch(void) 283void __init sun4v_patch(void)
284{ 284{
285 struct sun4v_1insn_patch_entry *p1; 285 struct sun4v_1insn_patch_entry *p1;
286 struct sun4v_2insn_patch_entry *p2; 286 struct sun4v_2insn_patch_entry *p2;
@@ -315,6 +315,15 @@ static void __init sun4v_patch(void)
315 } 315 }
316} 316}
317 317
318#ifdef CONFIG_SMP
319void __init boot_cpu_id_too_large(int cpu)
320{
321 prom_printf("Serious problem, boot cpu id (%d) >= NR_CPUS (%d)\n",
322 cpu, NR_CPUS);
323 prom_halt();
324}
325#endif
326
318void __init setup_arch(char **cmdline_p) 327void __init setup_arch(char **cmdline_p)
319{ 328{
320 /* Initialize PROM console and command line. */ 329 /* Initialize PROM console and command line. */
@@ -332,16 +341,6 @@ void __init setup_arch(char **cmdline_p)
332 conswitchp = &prom_con; 341 conswitchp = &prom_con;
333#endif 342#endif
334 343
335 /* Work out if we are starfire early on */
336 check_if_starfire();
337
338 /* Now we know enough to patch the get_cpuid sequences
339 * used by trap code.
340 */
341 per_cpu_patch();
342
343 sun4v_patch();
344
345 boot_flags_init(*cmdline_p); 344 boot_flags_init(*cmdline_p);
346 345
347 idprom_init(); 346 idprom_init();
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 90eaca3ec9a6..4e8cd79156e0 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -1264,7 +1264,6 @@ void __init smp_tick_init(void)
1264 boot_cpu_id = hard_smp_processor_id(); 1264 boot_cpu_id = hard_smp_processor_id();
1265 current_tick_offset = timer_tick_offset; 1265 current_tick_offset = timer_tick_offset;
1266 1266
1267 cpu_set(boot_cpu_id, cpu_online_map);
1268 prof_counter(boot_cpu_id) = prof_multiplier(boot_cpu_id) = 1; 1267 prof_counter(boot_cpu_id) = prof_multiplier(boot_cpu_id) = 1;
1269} 1268}
1270 1269
@@ -1345,18 +1344,6 @@ void __init smp_setup_cpu_possible_map(void)
1345 1344
1346void __devinit smp_prepare_boot_cpu(void) 1345void __devinit smp_prepare_boot_cpu(void)
1347{ 1346{
1348 int cpu = hard_smp_processor_id();
1349
1350 if (cpu >= NR_CPUS) {
1351 prom_printf("Serious problem, boot cpu id >= NR_CPUS\n");
1352 prom_halt();
1353 }
1354
1355 current_thread_info()->cpu = cpu;
1356 __local_per_cpu_offset = __per_cpu_offset(cpu);
1357
1358 cpu_set(smp_processor_id(), cpu_online_map);
1359 cpu_set(smp_processor_id(), phys_cpu_present_map);
1360} 1347}
1361 1348
1362int __devinit __cpu_up(unsigned int cpu) 1349int __devinit __cpu_up(unsigned int cpu)
@@ -1433,4 +1420,7 @@ void __init setup_per_cpu_areas(void)
1433 1420
1434 for (i = 0; i < NR_CPUS; i++, ptr += size) 1421 for (i = 0; i < NR_CPUS; i++, ptr += size)
1435 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); 1422 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
1423
1424 /* Setup %g5 for the boot cpu. */
1425 __local_per_cpu_offset = __per_cpu_offset(smp_processor_id());
1436} 1426}
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 358e4d309ceb..c2059a3a0621 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -159,17 +159,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
159#define lazy_mmu_prot_update(pte) do { } while (0) 159#define lazy_mmu_prot_update(pte) do { } while (0)
160#endif 160#endif
161 161
162#ifndef __HAVE_ARCH_MULTIPLE_ZERO_PAGE 162#ifndef __HAVE_ARCH_MOVE_PTE
163#define move_pte(pte, prot, old_addr, new_addr) (pte) 163#define move_pte(pte, prot, old_addr, new_addr) (pte)
164#else
165#define move_pte(pte, prot, old_addr, new_addr) \
166({ \
167 pte_t newpte = (pte); \
168 if (pte_present(pte) && pfn_valid(pte_pfn(pte)) && \
169 pte_page(pte) == ZERO_PAGE(old_addr)) \
170 newpte = mk_pte(ZERO_PAGE(new_addr), (prot)); \
171 newpte; \
172})
173#endif 164#endif
174 165
175/* 166/*
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
index 174a3cda8c26..f80fe75c7800 100644
--- a/include/asm-mips/pgtable.h
+++ b/include/asm-mips/pgtable.h
@@ -70,7 +70,15 @@ extern unsigned long zero_page_mask;
70#define ZERO_PAGE(vaddr) \ 70#define ZERO_PAGE(vaddr) \
71 (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask))) 71 (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))
72 72
73#define __HAVE_ARCH_MULTIPLE_ZERO_PAGE 73#define __HAVE_ARCH_MOVE_PTE
74#define move_pte(pte, prot, old_addr, new_addr) \
75({ \
76 pte_t newpte = (pte); \
77 if (pte_present(pte) && pfn_valid(pte_pfn(pte)) && \
78 pte_page(pte) == ZERO_PAGE(old_addr)) \
79 newpte = mk_pte(ZERO_PAGE(new_addr), (prot)); \
80 newpte; \
81})
74 82
75extern void paging_init(void); 83extern void paging_init(void);
76 84
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index c44e7466534e..cd464f469a2c 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -689,6 +689,23 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *p
689#define pte_clear(mm,addr,ptep) \ 689#define pte_clear(mm,addr,ptep) \
690 set_pte_at((mm), (addr), (ptep), __pte(0UL)) 690 set_pte_at((mm), (addr), (ptep), __pte(0UL))
691 691
692#ifdef DCACHE_ALIASING_POSSIBLE
693#define __HAVE_ARCH_MOVE_PTE
694#define move_pte(pte, prot, old_addr, new_addr) \
695({ \
696 pte_t newpte = (pte); \
697 if (tlb_type != hypervisor && pte_present(pte)) { \
698 unsigned long this_pfn = pte_pfn(pte); \
699 \
700 if (pfn_valid(this_pfn) && \
701 (((old_addr) ^ (new_addr)) & (1 << 13))) \
702 flush_dcache_page_all(current->mm, \
703 pfn_to_page(this_pfn)); \
704 } \
705 newpte; \
706})
707#endif
708
692extern pgd_t swapper_pg_dir[2048]; 709extern pgd_t swapper_pg_dir[2048];
693extern pmd_t swapper_low_pmd_dir[2048]; 710extern pmd_t swapper_low_pmd_dir[2048];
694 711