aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/Makefile3
-rw-r--r--arch/arm/kernel/armksyms.c3
-rw-r--r--arch/arm/kernel/asm-offsets.c12
-rw-r--r--arch/arm/kernel/bios32.c9
-rw-r--r--arch/arm/kernel/debug.S4
-rw-r--r--arch/arm/kernel/dma.c2
-rw-r--r--arch/arm/kernel/ecard.c36
-rw-r--r--arch/arm/kernel/entry-armv.S44
-rw-r--r--arch/arm/kernel/head.S135
-rw-r--r--arch/arm/kernel/irq.c2
-rw-r--r--arch/arm/kernel/machine_kexec.c35
-rw-r--r--arch/arm/kernel/module.c2
-rw-r--r--arch/arm/kernel/process.c2
-rw-r--r--arch/arm/kernel/setup.c37
-rw-r--r--arch/arm/kernel/smp.c61
-rw-r--r--arch/arm/kernel/smp_scu.c2
-rw-r--r--arch/arm/kernel/time.c6
-rw-r--r--arch/arm/kernel/topology.c148
-rw-r--r--arch/arm/kernel/traps.c52
-rw-r--r--arch/arm/kernel/vmlinux.lds.S3
20 files changed, 411 insertions, 187 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index f7887dc53c1f..68036eece340 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -29,7 +29,7 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o
29obj-$(CONFIG_ARTHUR) += arthur.o 29obj-$(CONFIG_ARTHUR) += arthur.o
30obj-$(CONFIG_ISA_DMA) += dma-isa.o 30obj-$(CONFIG_ISA_DMA) += dma-isa.o
31obj-$(CONFIG_PCI) += bios32.o isa.o 31obj-$(CONFIG_PCI) += bios32.o isa.o
32obj-$(CONFIG_PM_SLEEP) += sleep.o 32obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o
33obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o 33obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
34obj-$(CONFIG_SMP) += smp.o smp_tlb.o 34obj-$(CONFIG_SMP) += smp.o smp_tlb.o
35obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o 35obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
@@ -66,6 +66,7 @@ obj-$(CONFIG_IWMMXT) += iwmmxt.o
66obj-$(CONFIG_CPU_HAS_PMU) += pmu.o 66obj-$(CONFIG_CPU_HAS_PMU) += pmu.o
67obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o 67obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
68AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt 68AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
69obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
69 70
70ifneq ($(CONFIG_ARCH_EBSA110),y) 71ifneq ($(CONFIG_ARCH_EBSA110),y)
71 obj-y += io.o 72 obj-y += io.o
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index aeef960ff795..8e3c6f11b0a1 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -49,9 +49,6 @@ extern void __aeabi_ulcmp(void);
49 49
50extern void fpundefinstr(void); 50extern void fpundefinstr(void);
51 51
52
53EXPORT_SYMBOL(__backtrace);
54
55 /* platform dependent support */ 52 /* platform dependent support */
56EXPORT_SYMBOL(__udelay); 53EXPORT_SYMBOL(__udelay);
57EXPORT_SYMBOL(__const_udelay); 54EXPORT_SYMBOL(__const_udelay);
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 16baba2e4369..1429d8989fb9 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -20,6 +20,7 @@
20#include <asm/thread_info.h> 20#include <asm/thread_info.h>
21#include <asm/memory.h> 21#include <asm/memory.h>
22#include <asm/procinfo.h> 22#include <asm/procinfo.h>
23#include <asm/hardware/cache-l2x0.h>
23#include <linux/kbuild.h> 24#include <linux/kbuild.h>
24 25
25/* 26/*
@@ -92,6 +93,17 @@ int main(void)
92 DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0)); 93 DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0));
93 DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs)); 94 DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
94 BLANK(); 95 BLANK();
96#ifdef CONFIG_CACHE_L2X0
97 DEFINE(L2X0_R_PHY_BASE, offsetof(struct l2x0_regs, phy_base));
98 DEFINE(L2X0_R_AUX_CTRL, offsetof(struct l2x0_regs, aux_ctrl));
99 DEFINE(L2X0_R_TAG_LATENCY, offsetof(struct l2x0_regs, tag_latency));
100 DEFINE(L2X0_R_DATA_LATENCY, offsetof(struct l2x0_regs, data_latency));
101 DEFINE(L2X0_R_FILTER_START, offsetof(struct l2x0_regs, filter_start));
102 DEFINE(L2X0_R_FILTER_END, offsetof(struct l2x0_regs, filter_end));
103 DEFINE(L2X0_R_PREFETCH_CTRL, offsetof(struct l2x0_regs, prefetch_ctrl));
104 DEFINE(L2X0_R_PWR_CTRL, offsetof(struct l2x0_regs, pwr_ctrl));
105 BLANK();
106#endif
95#ifdef CONFIG_CPU_HAS_ASID 107#ifdef CONFIG_CPU_HAS_ASID
96 DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id)); 108 DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id));
97 BLANK(); 109 BLANK();
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index d6df359408f0..c0d9203fc75e 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -412,6 +412,9 @@ void pcibios_fixup_bus(struct pci_bus *bus)
412 printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n", 412 printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n",
413 bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); 413 bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
414} 414}
415#ifdef CONFIG_HOTPLUG
416EXPORT_SYMBOL(pcibios_fixup_bus);
417#endif
415 418
416/* 419/*
417 * Convert from Linux-centric to bus-centric addresses for bridge devices. 420 * Convert from Linux-centric to bus-centric addresses for bridge devices.
@@ -431,6 +434,7 @@ pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
431 region->start = res->start - offset; 434 region->start = res->start - offset;
432 region->end = res->end - offset; 435 region->end = res->end - offset;
433} 436}
437EXPORT_SYMBOL(pcibios_resource_to_bus);
434 438
435void __devinit 439void __devinit
436pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 440pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
@@ -447,12 +451,7 @@ pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
447 res->start = region->start + offset; 451 res->start = region->start + offset;
448 res->end = region->end + offset; 452 res->end = region->end + offset;
449} 453}
450
451#ifdef CONFIG_HOTPLUG
452EXPORT_SYMBOL(pcibios_fixup_bus);
453EXPORT_SYMBOL(pcibios_resource_to_bus);
454EXPORT_SYMBOL(pcibios_bus_to_resource); 454EXPORT_SYMBOL(pcibios_bus_to_resource);
455#endif
456 455
457/* 456/*
458 * Swizzle the device pin each time we cross a bridge. 457 * Swizzle the device pin each time we cross a bridge.
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index bcd66e00bdbe..0f852d082fcf 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -151,6 +151,8 @@ printhex: adr r2, hexbuf
151 b printascii 151 b printascii
152ENDPROC(printhex2) 152ENDPROC(printhex2)
153 153
154hexbuf: .space 16
155
154 .ltorg 156 .ltorg
155 157
156ENTRY(printascii) 158ENTRY(printascii)
@@ -175,5 +177,3 @@ ENTRY(printch)
175 mov r0, #0 177 mov r0, #0
176 b 1b 178 b 1b
177ENDPROC(printch) 179ENDPROC(printch)
178
179hexbuf: .space 16
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
index 2c4a185f92cd..7b829d9663b1 100644
--- a/arch/arm/kernel/dma.c
+++ b/arch/arm/kernel/dma.c
@@ -23,7 +23,7 @@
23 23
24#include <asm/mach/dma.h> 24#include <asm/mach/dma.h>
25 25
26DEFINE_SPINLOCK(dma_spin_lock); 26DEFINE_RAW_SPINLOCK(dma_spin_lock);
27EXPORT_SYMBOL(dma_spin_lock); 27EXPORT_SYMBOL(dma_spin_lock);
28 28
29static dma_t *dma_chan[MAX_DMA_CHANNELS]; 29static dma_t *dma_chan[MAX_DMA_CHANNELS];
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index d16500110ee9..4dd0edab6a65 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -237,7 +237,7 @@ static void ecard_init_pgtables(struct mm_struct *mm)
237 237
238 memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (IO_SIZE / PGDIR_SIZE)); 238 memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (IO_SIZE / PGDIR_SIZE));
239 239
240 src_pgd = pgd_offset(mm, EASI_BASE); 240 src_pgd = pgd_offset(mm, (unsigned long)EASI_BASE);
241 dst_pgd = pgd_offset(mm, EASI_START); 241 dst_pgd = pgd_offset(mm, EASI_START);
242 242
243 memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (EASI_SIZE / PGDIR_SIZE)); 243 memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (EASI_SIZE / PGDIR_SIZE));
@@ -674,44 +674,37 @@ static int __init ecard_probeirqhw(void)
674#define ecard_probeirqhw() (0) 674#define ecard_probeirqhw() (0)
675#endif 675#endif
676 676
677#ifndef IO_EC_MEMC8_BASE 677static void __iomem *__ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
678#define IO_EC_MEMC8_BASE 0
679#endif
680
681static unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
682{ 678{
683 unsigned long address = 0; 679 void __iomem *address = NULL;
684 int slot = ec->slot_no; 680 int slot = ec->slot_no;
685 681
686 if (ec->slot_no == 8) 682 if (ec->slot_no == 8)
687 return IO_EC_MEMC8_BASE; 683 return ECARD_MEMC8_BASE;
688 684
689 ectcr &= ~(1 << slot); 685 ectcr &= ~(1 << slot);
690 686
691 switch (type) { 687 switch (type) {
692 case ECARD_MEMC: 688 case ECARD_MEMC:
693 if (slot < 4) 689 if (slot < 4)
694 address = IO_EC_MEMC_BASE + (slot << 12); 690 address = ECARD_MEMC_BASE + (slot << 14);
695 break; 691 break;
696 692
697 case ECARD_IOC: 693 case ECARD_IOC:
698 if (slot < 4) 694 if (slot < 4)
699 address = IO_EC_IOC_BASE + (slot << 12); 695 address = ECARD_IOC_BASE + (slot << 14);
700#ifdef IO_EC_IOC4_BASE
701 else 696 else
702 address = IO_EC_IOC4_BASE + ((slot - 4) << 12); 697 address = ECARD_IOC4_BASE + ((slot - 4) << 14);
703#endif
704 if (address) 698 if (address)
705 address += speed << 17; 699 address += speed << 19;
706 break; 700 break;
707 701
708#ifdef IO_EC_EASI_BASE
709 case ECARD_EASI: 702 case ECARD_EASI:
710 address = IO_EC_EASI_BASE + (slot << 22); 703 address = ECARD_EASI_BASE + (slot << 24);
711 if (speed == ECARD_FAST) 704 if (speed == ECARD_FAST)
712 ectcr |= 1 << slot; 705 ectcr |= 1 << slot;
713 break; 706 break;
714#endif 707
715 default: 708 default:
716 break; 709 break;
717 } 710 }
@@ -990,6 +983,7 @@ ecard_probe(int slot, card_type_t type)
990 ecard_t **ecp; 983 ecard_t **ecp;
991 ecard_t *ec; 984 ecard_t *ec;
992 struct ex_ecid cid; 985 struct ex_ecid cid;
986 void __iomem *addr;
993 int i, rc; 987 int i, rc;
994 988
995 ec = ecard_alloc_card(type, slot); 989 ec = ecard_alloc_card(type, slot);
@@ -999,7 +993,7 @@ ecard_probe(int slot, card_type_t type)
999 } 993 }
1000 994
1001 rc = -ENODEV; 995 rc = -ENODEV;
1002 if ((ec->podaddr = __ecard_address(ec, type, ECARD_SYNC)) == 0) 996 if ((addr = __ecard_address(ec, type, ECARD_SYNC)) == NULL)
1003 goto nodev; 997 goto nodev;
1004 998
1005 cid.r_zero = 1; 999 cid.r_zero = 1;
@@ -1019,7 +1013,7 @@ ecard_probe(int slot, card_type_t type)
1019 ec->cid.fiqmask = cid.r_fiqmask; 1013 ec->cid.fiqmask = cid.r_fiqmask;
1020 ec->cid.fiqoff = ecard_gets24(cid.r_fiqoff); 1014 ec->cid.fiqoff = ecard_gets24(cid.r_fiqoff);
1021 ec->fiqaddr = 1015 ec->fiqaddr =
1022 ec->irqaddr = (void __iomem *)ioaddr(ec->podaddr); 1016 ec->irqaddr = addr;
1023 1017
1024 if (ec->cid.is) { 1018 if (ec->cid.is) {
1025 ec->irqmask = ec->cid.irqmask; 1019 ec->irqmask = ec->cid.irqmask;
@@ -1048,10 +1042,8 @@ ecard_probe(int slot, card_type_t type)
1048 set_irq_flags(ec->irq, IRQF_VALID); 1042 set_irq_flags(ec->irq, IRQF_VALID);
1049 } 1043 }
1050 1044
1051#ifdef IO_EC_MEMC8_BASE
1052 if (slot == 8) 1045 if (slot == 8)
1053 ec->irq = 11; 1046 ec->irq = 11;
1054#endif
1055#ifdef CONFIG_ARCH_RPC 1047#ifdef CONFIG_ARCH_RPC
1056 /* On RiscPC, only first two slots have DMA capability */ 1048 /* On RiscPC, only first two slots have DMA capability */
1057 if (slot < 2) 1049 if (slot < 2)
@@ -1097,9 +1089,7 @@ static int __init ecard_init(void)
1097 ecard_probe(slot, ECARD_IOC); 1089 ecard_probe(slot, ECARD_IOC);
1098 } 1090 }
1099 1091
1100#ifdef IO_EC_MEMC8_BASE
1101 ecard_probe(8, ECARD_IOC); 1092 ecard_probe(8, ECARD_IOC);
1102#endif
1103 1093
1104 irqhw = ecard_probeirqhw(); 1094 irqhw = ecard_probeirqhw();
1105 1095
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index a87cbf889ff4..9ad50c4208ae 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -24,6 +24,7 @@
24#include <asm/unwind.h> 24#include <asm/unwind.h>
25#include <asm/unistd.h> 25#include <asm/unistd.h>
26#include <asm/tls.h> 26#include <asm/tls.h>
27#include <asm/system.h>
27 28
28#include "entry-header.S" 29#include "entry-header.S"
29#include <asm/entry-macro-multi.S> 30#include <asm/entry-macro-multi.S>
@@ -262,8 +263,7 @@ __und_svc:
262 ldr r0, [r4, #-4] 263 ldr r0, [r4, #-4]
263#else 264#else
264 ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2 265 ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2
265 and r9, r0, #0xf800 266 cmp r0, #0xe800 @ 32-bit instruction if xx >= 0
266 cmp r9, #0xe800 @ 32-bit instruction if xx >= 0
267 ldrhhs r9, [r4] @ bottom 16 bits 267 ldrhhs r9, [r4] @ bottom 16 bits
268 orrhs r0, r9, r0, lsl #16 268 orrhs r0, r9, r0, lsl #16
269#endif 269#endif
@@ -440,18 +440,46 @@ __und_usr:
440#endif 440#endif
441 beq call_fpe 441 beq call_fpe
442 @ Thumb instruction 442 @ Thumb instruction
443#if __LINUX_ARM_ARCH__ >= 7 443#if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7
444/*
445 * Thumb-2 instruction handling. Note that because pre-v6 and >= v6 platforms
446 * can never be supported in a single kernel, this code is not applicable at
447 * all when __LINUX_ARM_ARCH__ < 6. This allows simplifying assumptions to be
448 * made about .arch directives.
449 */
450#if __LINUX_ARM_ARCH__ < 7
451/* If the target CPU may not be Thumb-2-capable, a run-time check is needed: */
452#define NEED_CPU_ARCHITECTURE
453 ldr r5, .LCcpu_architecture
454 ldr r5, [r5]
455 cmp r5, #CPU_ARCH_ARMv7
456 blo __und_usr_unknown
457/*
458 * The following code won't get run unless the running CPU really is v7, so
459 * coding round the lack of ldrht on older arches is pointless. Temporarily
460 * override the assembler target arch with the minimum required instead:
461 */
462 .arch armv6t2
463#endif
4442: 4642:
445 ARM( ldrht r5, [r4], #2 ) 465 ARM( ldrht r5, [r4], #2 )
446 THUMB( ldrht r5, [r4] ) 466 THUMB( ldrht r5, [r4] )
447 THUMB( add r4, r4, #2 ) 467 THUMB( add r4, r4, #2 )
448 and r0, r5, #0xf800 @ mask bits 111x x... .... .... 468 cmp r5, #0xe800 @ 32bit instruction if xx != 0
449 cmp r0, #0xe800 @ 32bit instruction if xx != 0
450 blo __und_usr_unknown 469 blo __und_usr_unknown
4513: ldrht r0, [r4] 4703: ldrht r0, [r4]
452 add r2, r2, #2 @ r2 is PC + 2, make it PC + 4 471 add r2, r2, #2 @ r2 is PC + 2, make it PC + 4
453 orr r0, r0, r5, lsl #16 472 orr r0, r0, r5, lsl #16
473
474#if __LINUX_ARM_ARCH__ < 7
475/* If the target arch was overridden, change it back: */
476#ifdef CONFIG_CPU_32v6K
477 .arch armv6k
454#else 478#else
479 .arch armv6
480#endif
481#endif /* __LINUX_ARM_ARCH__ < 7 */
482#else /* !(CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7) */
455 b __und_usr_unknown 483 b __und_usr_unknown
456#endif 484#endif
457 UNWIND(.fnend ) 485 UNWIND(.fnend )
@@ -578,6 +606,12 @@ call_fpe:
578 movw_pc lr @ CP#14 (Debug) 606 movw_pc lr @ CP#14 (Debug)
579 movw_pc lr @ CP#15 (Control) 607 movw_pc lr @ CP#15 (Control)
580 608
609#ifdef NEED_CPU_ARCHITECTURE
610 .align 2
611.LCcpu_architecture:
612 .word __cpu_architecture
613#endif
614
581#ifdef CONFIG_NEON 615#ifdef CONFIG_NEON
582 .align 6 616 .align 6
583 617
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 742b6108a001..239703dbdf4f 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -21,6 +21,7 @@
21#include <asm/memory.h> 21#include <asm/memory.h>
22#include <asm/thread_info.h> 22#include <asm/thread_info.h>
23#include <asm/system.h> 23#include <asm/system.h>
24#include <asm/pgtable.h>
24 25
25#ifdef CONFIG_DEBUG_LL 26#ifdef CONFIG_DEBUG_LL
26#include <mach/debug-macro.S> 27#include <mach/debug-macro.S>
@@ -38,11 +39,14 @@
38#error KERNEL_RAM_VADDR must start at 0xXXXX8000 39#error KERNEL_RAM_VADDR must start at 0xXXXX8000
39#endif 40#endif
40 41
42#define PG_DIR_SIZE 0x4000
43#define PMD_ORDER 2
44
41 .globl swapper_pg_dir 45 .globl swapper_pg_dir
42 .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000 46 .equ swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
43 47
44 .macro pgtbl, rd, phys 48 .macro pgtbl, rd, phys
45 add \rd, \phys, #TEXT_OFFSET - 0x4000 49 add \rd, \phys, #TEXT_OFFSET - PG_DIR_SIZE
46 .endm 50 .endm
47 51
48#ifdef CONFIG_XIP_KERNEL 52#ifdef CONFIG_XIP_KERNEL
@@ -148,11 +152,11 @@ __create_page_tables:
148 pgtbl r4, r8 @ page table address 152 pgtbl r4, r8 @ page table address
149 153
150 /* 154 /*
151 * Clear the 16K level 1 swapper page table 155 * Clear the swapper page table
152 */ 156 */
153 mov r0, r4 157 mov r0, r4
154 mov r3, #0 158 mov r3, #0
155 add r6, r0, #0x4000 159 add r6, r0, #PG_DIR_SIZE
1561: str r3, [r0], #4 1601: str r3, [r0], #4
157 str r3, [r0], #4 161 str r3, [r0], #4
158 str r3, [r0], #4 162 str r3, [r0], #4
@@ -171,30 +175,30 @@ __create_page_tables:
171 sub r0, r0, r3 @ virt->phys offset 175 sub r0, r0, r3 @ virt->phys offset
172 add r5, r5, r0 @ phys __enable_mmu 176 add r5, r5, r0 @ phys __enable_mmu
173 add r6, r6, r0 @ phys __enable_mmu_end 177 add r6, r6, r0 @ phys __enable_mmu_end
174 mov r5, r5, lsr #20 178 mov r5, r5, lsr #SECTION_SHIFT
175 mov r6, r6, lsr #20 179 mov r6, r6, lsr #SECTION_SHIFT
176 180
1771: orr r3, r7, r5, lsl #20 @ flags + kernel base 1811: orr r3, r7, r5, lsl #SECTION_SHIFT @ flags + kernel base
178 str r3, [r4, r5, lsl #2] @ identity mapping 182 str r3, [r4, r5, lsl #PMD_ORDER] @ identity mapping
179 teq r5, r6 183 cmp r5, r6
180 addne r5, r5, #1 @ next section 184 addlo r5, r5, #1 @ next section
181 bne 1b 185 blo 1b
182 186
183 /* 187 /*
184 * Now setup the pagetables for our kernel direct 188 * Now setup the pagetables for our kernel direct
185 * mapped region. 189 * mapped region.
186 */ 190 */
187 mov r3, pc 191 mov r3, pc
188 mov r3, r3, lsr #20 192 mov r3, r3, lsr #SECTION_SHIFT
189 orr r3, r7, r3, lsl #20 193 orr r3, r7, r3, lsl #SECTION_SHIFT
190 add r0, r4, #(KERNEL_START & 0xff000000) >> 18 194 add r0, r4, #(KERNEL_START & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER)
191 str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]! 195 str r3, [r0, #((KERNEL_START & 0x00f00000) >> SECTION_SHIFT) << PMD_ORDER]!
192 ldr r6, =(KERNEL_END - 1) 196 ldr r6, =(KERNEL_END - 1)
193 add r0, r0, #4 197 add r0, r0, #1 << PMD_ORDER
194 add r6, r4, r6, lsr #18 198 add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
1951: cmp r0, r6 1991: cmp r0, r6
196 add r3, r3, #1 << 20 200 add r3, r3, #1 << SECTION_SHIFT
197 strls r3, [r0], #4 201 strls r3, [r0], #1 << PMD_ORDER
198 bls 1b 202 bls 1b
199 203
200#ifdef CONFIG_XIP_KERNEL 204#ifdef CONFIG_XIP_KERNEL
@@ -203,11 +207,11 @@ __create_page_tables:
203 */ 207 */
204 add r3, r8, #TEXT_OFFSET 208 add r3, r8, #TEXT_OFFSET
205 orr r3, r3, r7 209 orr r3, r3, r7
206 add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18 210 add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER)
207 str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]! 211 str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> (SECTION_SHIFT - PMD_ORDER)]!
208 ldr r6, =(_end - 1) 212 ldr r6, =(_end - 1)
209 add r0, r0, #4 213 add r0, r0, #4
210 add r6, r4, r6, lsr #18 214 add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
2111: cmp r0, r6 2151: cmp r0, r6
212 add r3, r3, #1 << 20 216 add r3, r3, #1 << 20
213 strls r3, [r0], #4 217 strls r3, [r0], #4
@@ -218,12 +222,12 @@ __create_page_tables:
218 * Then map boot params address in r2 or 222 * Then map boot params address in r2 or
219 * the first 1MB of ram if boot params address is not specified. 223 * the first 1MB of ram if boot params address is not specified.
220 */ 224 */
221 mov r0, r2, lsr #20 225 mov r0, r2, lsr #SECTION_SHIFT
222 movs r0, r0, lsl #20 226 movs r0, r0, lsl #SECTION_SHIFT
223 moveq r0, r8 227 moveq r0, r8
224 sub r3, r0, r8 228 sub r3, r0, r8
225 add r3, r3, #PAGE_OFFSET 229 add r3, r3, #PAGE_OFFSET
226 add r3, r4, r3, lsr #18 230 add r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER)
227 orr r6, r7, r0 231 orr r6, r7, r0
228 str r6, [r3] 232 str r6, [r3]
229 233
@@ -236,21 +240,21 @@ __create_page_tables:
236 */ 240 */
237 addruart r7, r3 241 addruart r7, r3
238 242
239 mov r3, r3, lsr #20 243 mov r3, r3, lsr #SECTION_SHIFT
240 mov r3, r3, lsl #2 244 mov r3, r3, lsl #PMD_ORDER
241 245
242 add r0, r4, r3 246 add r0, r4, r3
243 rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long) 247 rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long)
244 cmp r3, #0x0800 @ limit to 512MB 248 cmp r3, #0x0800 @ limit to 512MB
245 movhi r3, #0x0800 249 movhi r3, #0x0800
246 add r6, r0, r3 250 add r6, r0, r3
247 mov r3, r7, lsr #20 251 mov r3, r7, lsr #SECTION_SHIFT
248 ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags 252 ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
249 orr r3, r7, r3, lsl #20 253 orr r3, r7, r3, lsl #SECTION_SHIFT
2501: str r3, [r0], #4 2541: str r3, [r0], #4
251 add r3, r3, #1 << 20 255 add r3, r3, #1 << SECTION_SHIFT
252 teq r0, r6 256 cmp r0, r6
253 bne 1b 257 blo 1b
254 258
255#else /* CONFIG_DEBUG_ICEDCC */ 259#else /* CONFIG_DEBUG_ICEDCC */
256 /* we don't need any serial debugging mappings for ICEDCC */ 260 /* we don't need any serial debugging mappings for ICEDCC */
@@ -262,7 +266,7 @@ __create_page_tables:
262 * If we're using the NetWinder or CATS, we also need to map 266 * If we're using the NetWinder or CATS, we also need to map
263 * in the 16550-type serial port for the debug messages 267 * in the 16550-type serial port for the debug messages
264 */ 268 */
265 add r0, r4, #0xff000000 >> 18 269 add r0, r4, #0xff000000 >> (SECTION_SHIFT - PMD_ORDER)
266 orr r3, r7, #0x7c000000 270 orr r3, r7, #0x7c000000
267 str r3, [r0] 271 str r3, [r0]
268#endif 272#endif
@@ -272,10 +276,10 @@ __create_page_tables:
272 * Similar reasons here - for debug. This is 276 * Similar reasons here - for debug. This is
273 * only for Acorn RiscPC architectures. 277 * only for Acorn RiscPC architectures.
274 */ 278 */
275 add r0, r4, #0x02000000 >> 18 279 add r0, r4, #0x02000000 >> (SECTION_SHIFT - PMD_ORDER)
276 orr r3, r7, #0x02000000 280 orr r3, r7, #0x02000000
277 str r3, [r0] 281 str r3, [r0]
278 add r0, r4, #0xd8000000 >> 18 282 add r0, r4, #0xd8000000 >> (SECTION_SHIFT - PMD_ORDER)
279 str r3, [r0] 283 str r3, [r0]
280#endif 284#endif
281#endif 285#endif
@@ -488,13 +492,8 @@ __fixup_pv_table:
488 add r5, r5, r3 @ adjust table end address 492 add r5, r5, r3 @ adjust table end address
489 add r7, r7, r3 @ adjust __pv_phys_offset address 493 add r7, r7, r3 @ adjust __pv_phys_offset address
490 str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset 494 str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset
491#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
492 mov r6, r3, lsr #24 @ constant for add/sub instructions 495 mov r6, r3, lsr #24 @ constant for add/sub instructions
493 teq r3, r6, lsl #24 @ must be 16MiB aligned 496 teq r3, r6, lsl #24 @ must be 16MiB aligned
494#else
495 mov r6, r3, lsr #16 @ constant for add/sub instructions
496 teq r3, r6, lsl #16 @ must be 64kiB aligned
497#endif
498THUMB( it ne @ cross section branch ) 497THUMB( it ne @ cross section branch )
499 bne __error 498 bne __error
500 str r6, [r7, #4] @ save to __pv_offset 499 str r6, [r7, #4] @ save to __pv_offset
@@ -510,20 +509,8 @@ ENDPROC(__fixup_pv_table)
510 .text 509 .text
511__fixup_a_pv_table: 510__fixup_a_pv_table:
512#ifdef CONFIG_THUMB2_KERNEL 511#ifdef CONFIG_THUMB2_KERNEL
513#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT 512 lsls r6, #24
514 lsls r0, r6, #24 513 beq 2f
515 lsr r6, #8
516 beq 1f
517 clz r7, r0
518 lsr r0, #24
519 lsl r0, r7
520 bic r0, 0x0080
521 lsrs r7, #1
522 orrcs r0, #0x0080
523 orr r0, r0, r7, lsl #12
524#endif
5251: lsls r6, #24
526 beq 4f
527 clz r7, r6 514 clz r7, r6
528 lsr r6, #24 515 lsr r6, #24
529 lsl r6, r7 516 lsl r6, r7
@@ -532,43 +519,25 @@ __fixup_a_pv_table:
532 orrcs r6, #0x0080 519 orrcs r6, #0x0080
533 orr r6, r6, r7, lsl #12 520 orr r6, r6, r7, lsl #12
534 orr r6, #0x4000 521 orr r6, #0x4000
535 b 4f 522 b 2f
5362: @ at this point the C flag is always clear 5231: add r7, r3
537 add r7, r3 524 ldrh ip, [r7, #2]
538#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
539 ldrh ip, [r7]
540 tst ip, 0x0400 @ the i bit tells us LS or MS byte
541 beq 3f
542 cmp r0, #0 @ set C flag, and ...
543 biceq ip, 0x0400 @ immediate zero value has a special encoding
544 streqh ip, [r7] @ that requires the i bit cleared
545#endif
5463: ldrh ip, [r7, #2]
547 and ip, 0x8f00 525 and ip, 0x8f00
548 orrcc ip, r6 @ mask in offset bits 31-24 526 orr ip, r6 @ mask in offset bits 31-24
549 orrcs ip, r0 @ mask in offset bits 23-16
550 strh ip, [r7, #2] 527 strh ip, [r7, #2]
5514: cmp r4, r5 5282: cmp r4, r5
552 ldrcc r7, [r4], #4 @ use branch for delay slot 529 ldrcc r7, [r4], #4 @ use branch for delay slot
553 bcc 2b 530 bcc 1b
554 bx lr 531 bx lr
555#else 532#else
556#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT 533 b 2f
557 and r0, r6, #255 @ offset bits 23-16 5341: ldr ip, [r7, r3]
558 mov r6, r6, lsr #8 @ offset bits 31-24
559#else
560 mov r0, #0 @ just in case...
561#endif
562 b 3f
5632: ldr ip, [r7, r3]
564 bic ip, ip, #0x000000ff 535 bic ip, ip, #0x000000ff
565 tst ip, #0x400 @ rotate shift tells us LS or MS byte 536 orr ip, ip, r6 @ mask in offset bits 31-24
566 orrne ip, ip, r6 @ mask in offset bits 31-24
567 orreq ip, ip, r0 @ mask in offset bits 23-16
568 str ip, [r7, r3] 537 str ip, [r7, r3]
5693: cmp r4, r5 5382: cmp r4, r5
570 ldrcc r7, [r4], #4 @ use branch for delay slot 539 ldrcc r7, [r4], #4 @ use branch for delay slot
571 bcc 2b 540 bcc 1b
572 mov pc, lr 541 mov pc, lr
573#endif 542#endif
574ENDPROC(__fixup_a_pv_table) 543ENDPROC(__fixup_a_pv_table)
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index de3dcab8610b..53919b230e8b 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -35,8 +35,8 @@
35#include <linux/list.h> 35#include <linux/list.h>
36#include <linux/kallsyms.h> 36#include <linux/kallsyms.h>
37#include <linux/proc_fs.h> 37#include <linux/proc_fs.h>
38#include <linux/ftrace.h>
39 38
39#include <asm/exception.h>
40#include <asm/system.h> 40#include <asm/system.h>
41#include <asm/mach/arch.h> 41#include <asm/mach/arch.h>
42#include <asm/mach/irq.h> 42#include <asm/mach/irq.h>
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index e59bbd496c39..c1b4463dcc83 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -32,6 +32,24 @@ static atomic_t waiting_for_crash_ipi;
32 32
33int machine_kexec_prepare(struct kimage *image) 33int machine_kexec_prepare(struct kimage *image)
34{ 34{
35 unsigned long page_list;
36 void *reboot_code_buffer;
37 page_list = image->head & PAGE_MASK;
38
39 reboot_code_buffer = page_address(image->control_code_page);
40
41 /* Prepare parameters for reboot_code_buffer*/
42 kexec_start_address = image->start;
43 kexec_indirection_page = page_list;
44 kexec_mach_type = machine_arch_type;
45 kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
46
47 /* copy our kernel relocation code to the control code page */
48 memcpy(reboot_code_buffer,
49 relocate_new_kernel, relocate_new_kernel_size);
50
51 flush_icache_range((unsigned long) reboot_code_buffer,
52 (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
35 return 0; 53 return 0;
36} 54}
37 55
@@ -82,31 +100,14 @@ void (*kexec_reinit)(void);
82 100
83void machine_kexec(struct kimage *image) 101void machine_kexec(struct kimage *image)
84{ 102{
85 unsigned long page_list;
86 unsigned long reboot_code_buffer_phys; 103 unsigned long reboot_code_buffer_phys;
87 void *reboot_code_buffer; 104 void *reboot_code_buffer;
88 105
89
90 page_list = image->head & PAGE_MASK;
91
92 /* we need both effective and real address here */ 106 /* we need both effective and real address here */
93 reboot_code_buffer_phys = 107 reboot_code_buffer_phys =
94 page_to_pfn(image->control_code_page) << PAGE_SHIFT; 108 page_to_pfn(image->control_code_page) << PAGE_SHIFT;
95 reboot_code_buffer = page_address(image->control_code_page); 109 reboot_code_buffer = page_address(image->control_code_page);
96 110
97 /* Prepare parameters for reboot_code_buffer*/
98 kexec_start_address = image->start;
99 kexec_indirection_page = page_list;
100 kexec_mach_type = machine_arch_type;
101 kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
102
103 /* copy our kernel relocation code to the control code page */
104 memcpy(reboot_code_buffer,
105 relocate_new_kernel, relocate_new_kernel_size);
106
107
108 flush_icache_range((unsigned long) reboot_code_buffer,
109 (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
110 printk(KERN_INFO "Bye!\n"); 111 printk(KERN_INFO "Bye!\n");
111 112
112 if (kexec_reinit) 113 if (kexec_reinit)
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index cc2020c2c709..1e9be5d25e56 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -33,7 +33,7 @@
33 * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off. 33 * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
34 */ 34 */
35#undef MODULES_VADDR 35#undef MODULES_VADDR
36#define MODULES_VADDR (((unsigned long)_etext + ~PGDIR_MASK) & PGDIR_MASK) 36#define MODULES_VADDR (((unsigned long)_etext + ~PMD_MASK) & PMD_MASK)
37#endif 37#endif
38 38
39#ifdef CONFIG_MMU 39#ifdef CONFIG_MMU
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 1a347f481e5e..fd0814076ff6 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -319,7 +319,7 @@ void show_regs(struct pt_regs * regs)
319 printk("\n"); 319 printk("\n");
320 printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm); 320 printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm);
321 __show_regs(regs); 321 __show_regs(regs);
322 __backtrace(); 322 dump_stack();
323} 323}
324 324
325ATOMIC_NOTIFIER_HEAD(thread_notify_head); 325ATOMIC_NOTIFIER_HEAD(thread_notify_head);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index e514c76043b4..3fe93f75b55a 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -29,6 +29,8 @@
29#include <linux/fs.h> 29#include <linux/fs.h>
30#include <linux/proc_fs.h> 30#include <linux/proc_fs.h>
31#include <linux/memblock.h> 31#include <linux/memblock.h>
32#include <linux/bug.h>
33#include <linux/compiler.h>
32 34
33#include <asm/unified.h> 35#include <asm/unified.h>
34#include <asm/cpu.h> 36#include <asm/cpu.h>
@@ -42,6 +44,7 @@
42#include <asm/cacheflush.h> 44#include <asm/cacheflush.h>
43#include <asm/cachetype.h> 45#include <asm/cachetype.h>
44#include <asm/tlbflush.h> 46#include <asm/tlbflush.h>
47#include <asm/system.h>
45 48
46#include <asm/prom.h> 49#include <asm/prom.h>
47#include <asm/mach/arch.h> 50#include <asm/mach/arch.h>
@@ -115,6 +118,13 @@ struct outer_cache_fns outer_cache __read_mostly;
115EXPORT_SYMBOL(outer_cache); 118EXPORT_SYMBOL(outer_cache);
116#endif 119#endif
117 120
121/*
122 * Cached cpu_architecture() result for use by assembler code.
123 * C code should use the cpu_architecture() function instead of accessing this
124 * variable directly.
125 */
126int __cpu_architecture __read_mostly = CPU_ARCH_UNKNOWN;
127
118struct stack { 128struct stack {
119 u32 irq[3]; 129 u32 irq[3];
120 u32 abt[3]; 130 u32 abt[3];
@@ -210,7 +220,7 @@ static const char *proc_arch[] = {
210 "?(17)", 220 "?(17)",
211}; 221};
212 222
213int cpu_architecture(void) 223static int __get_cpu_architecture(void)
214{ 224{
215 int cpu_arch; 225 int cpu_arch;
216 226
@@ -243,11 +253,22 @@ int cpu_architecture(void)
243 return cpu_arch; 253 return cpu_arch;
244} 254}
245 255
256int __pure cpu_architecture(void)
257{
258 BUG_ON(__cpu_architecture == CPU_ARCH_UNKNOWN);
259
260 return __cpu_architecture;
261}
262
246static int cpu_has_aliasing_icache(unsigned int arch) 263static int cpu_has_aliasing_icache(unsigned int arch)
247{ 264{
248 int aliasing_icache; 265 int aliasing_icache;
249 unsigned int id_reg, num_sets, line_size; 266 unsigned int id_reg, num_sets, line_size;
250 267
268 /* PIPT caches never alias. */
269 if (icache_is_pipt())
270 return 0;
271
251 /* arch specifies the register format */ 272 /* arch specifies the register format */
252 switch (arch) { 273 switch (arch) {
253 case CPU_ARCH_ARMv7: 274 case CPU_ARCH_ARMv7:
@@ -282,8 +303,14 @@ static void __init cacheid_init(void)
282 /* ARMv7 register format */ 303 /* ARMv7 register format */
283 arch = CPU_ARCH_ARMv7; 304 arch = CPU_ARCH_ARMv7;
284 cacheid = CACHEID_VIPT_NONALIASING; 305 cacheid = CACHEID_VIPT_NONALIASING;
285 if ((cachetype & (3 << 14)) == 1 << 14) 306 switch (cachetype & (3 << 14)) {
307 case (1 << 14):
286 cacheid |= CACHEID_ASID_TAGGED; 308 cacheid |= CACHEID_ASID_TAGGED;
309 break;
310 case (3 << 14):
311 cacheid |= CACHEID_PIPT;
312 break;
313 }
287 } else { 314 } else {
288 arch = CPU_ARCH_ARMv6; 315 arch = CPU_ARCH_ARMv6;
289 if (cachetype & (1 << 23)) 316 if (cachetype & (1 << 23))
@@ -300,10 +327,11 @@ static void __init cacheid_init(void)
300 printk("CPU: %s data cache, %s instruction cache\n", 327 printk("CPU: %s data cache, %s instruction cache\n",
301 cache_is_vivt() ? "VIVT" : 328 cache_is_vivt() ? "VIVT" :
302 cache_is_vipt_aliasing() ? "VIPT aliasing" : 329 cache_is_vipt_aliasing() ? "VIPT aliasing" :
303 cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown", 330 cache_is_vipt_nonaliasing() ? "PIPT / VIPT nonaliasing" : "unknown",
304 cache_is_vivt() ? "VIVT" : 331 cache_is_vivt() ? "VIVT" :
305 icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" : 332 icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
306 icache_is_vipt_aliasing() ? "VIPT aliasing" : 333 icache_is_vipt_aliasing() ? "VIPT aliasing" :
334 icache_is_pipt() ? "PIPT" :
307 cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown"); 335 cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
308} 336}
309 337
@@ -414,6 +442,7 @@ static void __init setup_processor(void)
414 } 442 }
415 443
416 cpu_name = list->cpu_name; 444 cpu_name = list->cpu_name;
445 __cpu_architecture = __get_cpu_architecture();
417 446
418#ifdef MULTI_CPU 447#ifdef MULTI_CPU
419 processor = *list->proc; 448 processor = *list->proc;
@@ -861,7 +890,7 @@ static struct machine_desc * __init setup_machine_tags(unsigned int nr)
861 } 890 }
862 891
863 if (mdesc->fixup) 892 if (mdesc->fixup)
864 mdesc->fixup(mdesc, tags, &from, &meminfo); 893 mdesc->fixup(tags, &from, &meminfo);
865 894
866 if (tags->hdr.tag == ATAG_CORE) { 895 if (tags->hdr.tag == ATAG_CORE) {
867 if (meminfo.nr_banks != 0) 896 if (meminfo.nr_banks != 0)
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index d88ff0230e82..94f34a6c8610 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -16,7 +16,6 @@
16#include <linux/cache.h> 16#include <linux/cache.h>
17#include <linux/profile.h> 17#include <linux/profile.h>
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/ftrace.h>
20#include <linux/mm.h> 19#include <linux/mm.h>
21#include <linux/err.h> 20#include <linux/err.h>
22#include <linux/cpu.h> 21#include <linux/cpu.h>
@@ -31,6 +30,8 @@
31#include <asm/cacheflush.h> 30#include <asm/cacheflush.h>
32#include <asm/cpu.h> 31#include <asm/cpu.h>
33#include <asm/cputype.h> 32#include <asm/cputype.h>
33#include <asm/exception.h>
34#include <asm/topology.h>
34#include <asm/mmu_context.h> 35#include <asm/mmu_context.h>
35#include <asm/pgtable.h> 36#include <asm/pgtable.h>
36#include <asm/pgalloc.h> 37#include <asm/pgalloc.h>
@@ -39,6 +40,7 @@
39#include <asm/tlbflush.h> 40#include <asm/tlbflush.h>
40#include <asm/ptrace.h> 41#include <asm/ptrace.h>
41#include <asm/localtimer.h> 42#include <asm/localtimer.h>
43#include <asm/smp_plat.h>
42 44
43/* 45/*
44 * as from 2.5, kernels no longer have an init_tasks structure 46 * as from 2.5, kernels no longer have an init_tasks structure
@@ -259,6 +261,20 @@ void __ref cpu_die(void)
259} 261}
260#endif /* CONFIG_HOTPLUG_CPU */ 262#endif /* CONFIG_HOTPLUG_CPU */
261 263
264int __cpu_logical_map[NR_CPUS];
265
266void __init smp_setup_processor_id(void)
267{
268 int i;
269 u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0;
270
271 cpu_logical_map(0) = cpu;
272 for (i = 1; i < NR_CPUS; ++i)
273 cpu_logical_map(i) = i == cpu ? 0 : i;
274
275 printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu);
276}
277
262/* 278/*
263 * Called by both boot and secondaries to move global data into 279 * Called by both boot and secondaries to move global data into
264 * per-processor storage. 280 * per-processor storage.
@@ -268,6 +284,8 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
268 struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid); 284 struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
269 285
270 cpu_info->loops_per_jiffy = loops_per_jiffy; 286 cpu_info->loops_per_jiffy = loops_per_jiffy;
287
288 store_cpu_topology(cpuid);
271} 289}
272 290
273/* 291/*
@@ -301,17 +319,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
301 */ 319 */
302 platform_secondary_init(cpu); 320 platform_secondary_init(cpu);
303 321
304 /*
305 * Enable local interrupts.
306 */
307 notify_cpu_starting(cpu); 322 notify_cpu_starting(cpu);
308 local_irq_enable();
309 local_fiq_enable();
310
311 /*
312 * Setup the percpu timer for this CPU.
313 */
314 percpu_timer_setup();
315 323
316 calibrate_delay(); 324 calibrate_delay();
317 325
@@ -323,10 +331,23 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
323 * before we continue. 331 * before we continue.
324 */ 332 */
325 set_cpu_online(cpu, true); 333 set_cpu_online(cpu, true);
334
335 /*
336 * Setup the percpu timer for this CPU.
337 */
338 percpu_timer_setup();
339
326 while (!cpu_active(cpu)) 340 while (!cpu_active(cpu))
327 cpu_relax(); 341 cpu_relax();
328 342
329 /* 343 /*
344 * cpu_active bit is set, so it's safe to enalbe interrupts
345 * now.
346 */
347 local_irq_enable();
348 local_fiq_enable();
349
350 /*
330 * OK, it's off to the idle thread for us 351 * OK, it's off to the idle thread for us
331 */ 352 */
332 cpu_idle(); 353 cpu_idle();
@@ -358,6 +379,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
358{ 379{
359 unsigned int ncores = num_possible_cpus(); 380 unsigned int ncores = num_possible_cpus();
360 381
382 init_cpu_topology();
383
361 smp_store_cpu_info(smp_processor_id()); 384 smp_store_cpu_info(smp_processor_id());
362 385
363 /* 386 /*
@@ -460,6 +483,11 @@ static void ipi_timer(void)
460#ifdef CONFIG_LOCAL_TIMERS 483#ifdef CONFIG_LOCAL_TIMERS
461asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) 484asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
462{ 485{
486 handle_local_timer(regs);
487}
488
489void handle_local_timer(struct pt_regs *regs)
490{
463 struct pt_regs *old_regs = set_irq_regs(regs); 491 struct pt_regs *old_regs = set_irq_regs(regs);
464 int cpu = smp_processor_id(); 492 int cpu = smp_processor_id();
465 493
@@ -538,7 +566,7 @@ static void percpu_timer_stop(void)
538} 566}
539#endif 567#endif
540 568
541static DEFINE_SPINLOCK(stop_lock); 569static DEFINE_RAW_SPINLOCK(stop_lock);
542 570
543/* 571/*
544 * ipi_cpu_stop - handle IPI from smp_send_stop() 572 * ipi_cpu_stop - handle IPI from smp_send_stop()
@@ -547,10 +575,10 @@ static void ipi_cpu_stop(unsigned int cpu)
547{ 575{
548 if (system_state == SYSTEM_BOOTING || 576 if (system_state == SYSTEM_BOOTING ||
549 system_state == SYSTEM_RUNNING) { 577 system_state == SYSTEM_RUNNING) {
550 spin_lock(&stop_lock); 578 raw_spin_lock(&stop_lock);
551 printk(KERN_CRIT "CPU%u: stopping\n", cpu); 579 printk(KERN_CRIT "CPU%u: stopping\n", cpu);
552 dump_stack(); 580 dump_stack();
553 spin_unlock(&stop_lock); 581 raw_spin_unlock(&stop_lock);
554 } 582 }
555 583
556 set_cpu_online(cpu, false); 584 set_cpu_online(cpu, false);
@@ -567,6 +595,11 @@ static void ipi_cpu_stop(unsigned int cpu)
567 */ 595 */
568asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs) 596asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
569{ 597{
598 handle_IPI(ipinr, regs);
599}
600
601void handle_IPI(int ipinr, struct pt_regs *regs)
602{
570 unsigned int cpu = smp_processor_id(); 603 unsigned int cpu = smp_processor_id();
571 struct pt_regs *old_regs = set_irq_regs(regs); 604 struct pt_regs *old_regs = set_irq_regs(regs);
572 605
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index 7fcddb75c877..8f5dd7963356 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -34,7 +34,7 @@ unsigned int __init scu_get_core_count(void __iomem *scu_base)
34/* 34/*
35 * Enable the SCU 35 * Enable the SCU
36 */ 36 */
37void __init scu_enable(void __iomem *scu_base) 37void scu_enable(void __iomem *scu_base)
38{ 38{
39 u32 scu_ctrl; 39 u32 scu_ctrl;
40 40
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index cb634c3e28e9..5a54b95d6bd2 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -39,13 +39,11 @@
39 */ 39 */
40static struct sys_timer *system_timer; 40static struct sys_timer *system_timer;
41 41
42#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) 42#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || \
43 defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE)
43/* this needs a better home */ 44/* this needs a better home */
44DEFINE_SPINLOCK(rtc_lock); 45DEFINE_SPINLOCK(rtc_lock);
45
46#ifdef CONFIG_RTC_DRV_CMOS_MODULE
47EXPORT_SYMBOL(rtc_lock); 46EXPORT_SYMBOL(rtc_lock);
48#endif
49#endif /* pc-style 'CMOS' RTC support */ 47#endif /* pc-style 'CMOS' RTC support */
50 48
51/* change this if you have some constant time drift */ 49/* change this if you have some constant time drift */
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
new file mode 100644
index 000000000000..1040c00405d0
--- /dev/null
+++ b/arch/arm/kernel/topology.c
@@ -0,0 +1,148 @@
1/*
2 * arch/arm/kernel/topology.c
3 *
4 * Copyright (C) 2011 Linaro Limited.
5 * Written by: Vincent Guittot
6 *
7 * based on arch/sh/kernel/topology.c
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13
14#include <linux/cpu.h>
15#include <linux/cpumask.h>
16#include <linux/init.h>
17#include <linux/percpu.h>
18#include <linux/node.h>
19#include <linux/nodemask.h>
20#include <linux/sched.h>
21
22#include <asm/cputype.h>
23#include <asm/topology.h>
24
25#define MPIDR_SMP_BITMASK (0x3 << 30)
26#define MPIDR_SMP_VALUE (0x2 << 30)
27
28#define MPIDR_MT_BITMASK (0x1 << 24)
29
30/*
31 * These masks reflect the current use of the affinity levels.
32 * The affinity level can be up to 16 bits according to ARM ARM
33 */
34
35#define MPIDR_LEVEL0_MASK 0x3
36#define MPIDR_LEVEL0_SHIFT 0
37
38#define MPIDR_LEVEL1_MASK 0xF
39#define MPIDR_LEVEL1_SHIFT 8
40
41#define MPIDR_LEVEL2_MASK 0xFF
42#define MPIDR_LEVEL2_SHIFT 16
43
44struct cputopo_arm cpu_topology[NR_CPUS];
45
46const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
47{
48 return &cpu_topology[cpu].core_sibling;
49}
50
51/*
52 * store_cpu_topology is called at boot when only one cpu is running
53 * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
54 * which prevents simultaneous write access to cpu_topology array
55 */
56void store_cpu_topology(unsigned int cpuid)
57{
58 struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid];
59 unsigned int mpidr;
60 unsigned int cpu;
61
62 /* If the cpu topology has been already set, just return */
63 if (cpuid_topo->core_id != -1)
64 return;
65
66 mpidr = read_cpuid_mpidr();
67
68 /* create cpu topology mapping */
69 if ((mpidr & MPIDR_SMP_BITMASK) == MPIDR_SMP_VALUE) {
70 /*
71 * This is a multiprocessor system
72 * multiprocessor format & multiprocessor mode field are set
73 */
74
75 if (mpidr & MPIDR_MT_BITMASK) {
76 /* core performance interdependency */
77 cpuid_topo->thread_id = (mpidr >> MPIDR_LEVEL0_SHIFT)
78 & MPIDR_LEVEL0_MASK;
79 cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL1_SHIFT)
80 & MPIDR_LEVEL1_MASK;
81 cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL2_SHIFT)
82 & MPIDR_LEVEL2_MASK;
83 } else {
84 /* largely independent cores */
85 cpuid_topo->thread_id = -1;
86 cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL0_SHIFT)
87 & MPIDR_LEVEL0_MASK;
88 cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL1_SHIFT)
89 & MPIDR_LEVEL1_MASK;
90 }
91 } else {
92 /*
93 * This is an uniprocessor system
94 * we are in multiprocessor format but uniprocessor system
95 * or in the old uniprocessor format
96 */
97 cpuid_topo->thread_id = -1;
98 cpuid_topo->core_id = 0;
99 cpuid_topo->socket_id = -1;
100 }
101
102 /* update core and thread sibling masks */
103 for_each_possible_cpu(cpu) {
104 struct cputopo_arm *cpu_topo = &cpu_topology[cpu];
105
106 if (cpuid_topo->socket_id == cpu_topo->socket_id) {
107 cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
108 if (cpu != cpuid)
109 cpumask_set_cpu(cpu,
110 &cpuid_topo->core_sibling);
111
112 if (cpuid_topo->core_id == cpu_topo->core_id) {
113 cpumask_set_cpu(cpuid,
114 &cpu_topo->thread_sibling);
115 if (cpu != cpuid)
116 cpumask_set_cpu(cpu,
117 &cpuid_topo->thread_sibling);
118 }
119 }
120 }
121 smp_wmb();
122
123 printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
124 cpuid, cpu_topology[cpuid].thread_id,
125 cpu_topology[cpuid].core_id,
126 cpu_topology[cpuid].socket_id, mpidr);
127}
128
129/*
130 * init_cpu_topology is called at boot when only one cpu is running
131 * which prevent simultaneous write access to cpu_topology array
132 */
133void init_cpu_topology(void)
134{
135 unsigned int cpu;
136
137 /* init core mask */
138 for_each_possible_cpu(cpu) {
139 struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]);
140
141 cpu_topo->thread_id = -1;
142 cpu_topo->core_id = -1;
143 cpu_topo->socket_id = -1;
144 cpumask_clear(&cpu_topo->core_sibling);
145 cpumask_clear(&cpu_topo->thread_sibling);
146 }
147 smp_wmb();
148}
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index bc9f9da782cb..99a572702509 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -21,12 +21,14 @@
21#include <linux/kdebug.h> 21#include <linux/kdebug.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/kexec.h> 23#include <linux/kexec.h>
24#include <linux/bug.h>
24#include <linux/delay.h> 25#include <linux/delay.h>
25#include <linux/init.h> 26#include <linux/init.h>
26#include <linux/sched.h> 27#include <linux/sched.h>
27 28
28#include <linux/atomic.h> 29#include <linux/atomic.h>
29#include <asm/cacheflush.h> 30#include <asm/cacheflush.h>
31#include <asm/exception.h>
30#include <asm/system.h> 32#include <asm/system.h>
31#include <asm/unistd.h> 33#include <asm/unistd.h>
32#include <asm/traps.h> 34#include <asm/traps.h>
@@ -255,7 +257,7 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt
255 return ret; 257 return ret;
256} 258}
257 259
258static DEFINE_SPINLOCK(die_lock); 260static DEFINE_RAW_SPINLOCK(die_lock);
259 261
260/* 262/*
261 * This function is protected against re-entrancy. 263 * This function is protected against re-entrancy.
@@ -267,9 +269,11 @@ void die(const char *str, struct pt_regs *regs, int err)
267 269
268 oops_enter(); 270 oops_enter();
269 271
270 spin_lock_irq(&die_lock); 272 raw_spin_lock_irq(&die_lock);
271 console_verbose(); 273 console_verbose();
272 bust_spinlocks(1); 274 bust_spinlocks(1);
275 if (!user_mode(regs))
276 report_bug(regs->ARM_pc, regs);
273 ret = __die(str, err, thread, regs); 277 ret = __die(str, err, thread, regs);
274 278
275 if (regs && kexec_should_crash(thread->task)) 279 if (regs && kexec_should_crash(thread->task))
@@ -277,7 +281,7 @@ void die(const char *str, struct pt_regs *regs, int err)
277 281
278 bust_spinlocks(0); 282 bust_spinlocks(0);
279 add_taint(TAINT_DIE); 283 add_taint(TAINT_DIE);
280 spin_unlock_irq(&die_lock); 284 raw_spin_unlock_irq(&die_lock);
281 oops_exit(); 285 oops_exit();
282 286
283 if (in_interrupt()) 287 if (in_interrupt())
@@ -301,25 +305,43 @@ void arm_notify_die(const char *str, struct pt_regs *regs,
301 } 305 }
302} 306}
303 307
308#ifdef CONFIG_GENERIC_BUG
309
310int is_valid_bugaddr(unsigned long pc)
311{
312#ifdef CONFIG_THUMB2_KERNEL
313 unsigned short bkpt;
314#else
315 unsigned long bkpt;
316#endif
317
318 if (probe_kernel_address((unsigned *)pc, bkpt))
319 return 0;
320
321 return bkpt == BUG_INSTR_VALUE;
322}
323
324#endif
325
304static LIST_HEAD(undef_hook); 326static LIST_HEAD(undef_hook);
305static DEFINE_SPINLOCK(undef_lock); 327static DEFINE_RAW_SPINLOCK(undef_lock);
306 328
307void register_undef_hook(struct undef_hook *hook) 329void register_undef_hook(struct undef_hook *hook)
308{ 330{
309 unsigned long flags; 331 unsigned long flags;
310 332
311 spin_lock_irqsave(&undef_lock, flags); 333 raw_spin_lock_irqsave(&undef_lock, flags);
312 list_add(&hook->node, &undef_hook); 334 list_add(&hook->node, &undef_hook);
313 spin_unlock_irqrestore(&undef_lock, flags); 335 raw_spin_unlock_irqrestore(&undef_lock, flags);
314} 336}
315 337
316void unregister_undef_hook(struct undef_hook *hook) 338void unregister_undef_hook(struct undef_hook *hook)
317{ 339{
318 unsigned long flags; 340 unsigned long flags;
319 341
320 spin_lock_irqsave(&undef_lock, flags); 342 raw_spin_lock_irqsave(&undef_lock, flags);
321 list_del(&hook->node); 343 list_del(&hook->node);
322 spin_unlock_irqrestore(&undef_lock, flags); 344 raw_spin_unlock_irqrestore(&undef_lock, flags);
323} 345}
324 346
325static int call_undef_hook(struct pt_regs *regs, unsigned int instr) 347static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
@@ -328,12 +350,12 @@ static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
328 unsigned long flags; 350 unsigned long flags;
329 int (*fn)(struct pt_regs *regs, unsigned int instr) = NULL; 351 int (*fn)(struct pt_regs *regs, unsigned int instr) = NULL;
330 352
331 spin_lock_irqsave(&undef_lock, flags); 353 raw_spin_lock_irqsave(&undef_lock, flags);
332 list_for_each_entry(hook, &undef_hook, node) 354 list_for_each_entry(hook, &undef_hook, node)
333 if ((instr & hook->instr_mask) == hook->instr_val && 355 if ((instr & hook->instr_mask) == hook->instr_val &&
334 (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) 356 (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val)
335 fn = hook->fn; 357 fn = hook->fn;
336 spin_unlock_irqrestore(&undef_lock, flags); 358 raw_spin_unlock_irqrestore(&undef_lock, flags);
337 359
338 return fn ? fn(regs, instr) : 1; 360 return fn ? fn(regs, instr) : 1;
339} 361}
@@ -706,16 +728,6 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
706 arm_notify_die("unknown data abort code", regs, &info, instr, 0); 728 arm_notify_die("unknown data abort code", regs, &info, instr, 0);
707} 729}
708 730
709void __attribute__((noreturn)) __bug(const char *file, int line)
710{
711 printk(KERN_CRIT"kernel BUG at %s:%d!\n", file, line);
712 *(int *)0 = 0;
713
714 /* Avoid "noreturn function does return" */
715 for (;;);
716}
717EXPORT_SYMBOL(__bug);
718
719void __readwrite_bug(const char *fn) 731void __readwrite_bug(const char *fn)
720{ 732{
721 printk("%s called, but not implemented\n", fn); 733 printk("%s called, but not implemented\n", fn);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 4e66f62b8d41..20b3041e0860 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -21,7 +21,8 @@
21#define ARM_CPU_KEEP(x) 21#define ARM_CPU_KEEP(x)
22#endif 22#endif
23 23
24#if defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK) 24#if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \
25 defined(CONFIG_GENERIC_BUG)
25#define ARM_EXIT_KEEP(x) x 26#define ARM_EXIT_KEEP(x) x
26#define ARM_EXIT_DISCARD(x) 27#define ARM_EXIT_DISCARD(x)
27#else 28#else