diff options
143 files changed, 2549 insertions, 2551 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 1493c7896fe3..ed31062029f7 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
| @@ -599,6 +599,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID | |||
| 599 | def_bool y | 599 | def_bool y |
| 600 | depends on NEED_MULTIPLE_NODES | 600 | depends on NEED_MULTIPLE_NODES |
| 601 | 601 | ||
| 602 | config ARCH_MEMORY_PROBE | ||
| 603 | def_bool y | ||
| 604 | depends on MEMORY_HOTPLUG | ||
| 605 | |||
| 602 | # Some NUMA nodes have memory ranges that span | 606 | # Some NUMA nodes have memory ranges that span |
| 603 | # other nodes. Even though a pfn is valid and | 607 | # other nodes. Even though a pfn is valid and |
| 604 | # between a node's start and end pfns, it may not | 608 | # between a node's start and end pfns, it may not |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index b3ae2993efb8..c04bbd320594 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | ifeq ($(CONFIG_PPC64),y) | 5 | ifeq ($(CONFIG_PPC64),y) |
| 6 | EXTRA_CFLAGS += -mno-minimal-toc | 6 | EXTRA_CFLAGS += -mno-minimal-toc |
| 7 | CFLAGS_ioctl32.o += -Ifs/ | ||
| 7 | endif | 8 | endif |
| 8 | ifeq ($(CONFIG_PPC32),y) | 9 | ifeq ($(CONFIG_PPC32),y) |
| 9 | CFLAGS_prom_init.o += -fPIC | 10 | CFLAGS_prom_init.o += -fPIC |
| @@ -11,15 +12,21 @@ CFLAGS_btext.o += -fPIC | |||
| 11 | endif | 12 | endif |
| 12 | 13 | ||
| 13 | obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ | 14 | obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ |
| 14 | signal_32.o pmc.o | 15 | irq.o signal_32.o pmc.o |
| 15 | obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ | 16 | obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ |
| 16 | signal_64.o ptrace32.o systbl.o | 17 | signal_64.o ptrace32.o systbl.o \ |
| 18 | paca.o ioctl32.o cpu_setup_power4.o \ | ||
| 19 | firmware.o sysfs.o | ||
| 17 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o | 20 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o |
| 18 | obj-$(CONFIG_POWER4) += idle_power4.o | 21 | obj-$(CONFIG_POWER4) += idle_power4.o |
| 19 | obj-$(CONFIG_PPC_OF) += of_device.o | 22 | obj-$(CONFIG_PPC_OF) += of_device.o |
| 20 | obj-$(CONFIG_PPC_RTAS) += rtas.o | 23 | procfs-$(CONFIG_PPC64) := proc_ppc64.o |
| 24 | obj-$(CONFIG_PROC_FS) += $(procfs-y) | ||
| 25 | rtaspci-$(CONFIG_PPC64) := rtas_pci.o | ||
| 26 | obj-$(CONFIG_PPC_RTAS) += rtas.o $(rtaspci-y) | ||
| 21 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o | 27 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o |
| 22 | obj-$(CONFIG_RTAS_PROC) += rtas-proc.o | 28 | obj-$(CONFIG_RTAS_PROC) += rtas-proc.o |
| 29 | obj-$(CONFIG_LPARCFG) += lparcfg.o | ||
| 23 | obj-$(CONFIG_IBMVIO) += vio.o | 30 | obj-$(CONFIG_IBMVIO) += vio.o |
| 24 | obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o | 31 | obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o |
| 25 | 32 | ||
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index b75757251994..8793102711a8 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
| @@ -106,7 +106,6 @@ int main(void) | |||
| 106 | DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); | 106 | DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); |
| 107 | DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); | 107 | DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); |
| 108 | DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); | 108 | DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); |
| 109 | DEFINE(PLATFORM, offsetof(struct systemcfg, platform)); | ||
| 110 | DEFINE(PLATFORM_LPAR, PLATFORM_LPAR); | 109 | DEFINE(PLATFORM_LPAR, PLATFORM_LPAR); |
| 111 | 110 | ||
| 112 | /* paca */ | 111 | /* paca */ |
diff --git a/arch/ppc64/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_power4.S index 1fb673c511ff..cca942fe6115 100644 --- a/arch/ppc64/kernel/cpu_setup_power4.S +++ b/arch/powerpc/kernel/cpu_setup_power4.S | |||
| @@ -114,11 +114,11 @@ _GLOBAL(__setup_cpu_ppc970) | |||
| 114 | 114 | ||
| 115 | .data | 115 | .data |
| 116 | .balign L1_CACHE_BYTES,0 | 116 | .balign L1_CACHE_BYTES,0 |
| 117 | cpu_state_storage: | 117 | cpu_state_storage: |
| 118 | .space CS_SIZE | 118 | .space CS_SIZE |
| 119 | .balign L1_CACHE_BYTES,0 | 119 | .balign L1_CACHE_BYTES,0 |
| 120 | .text | 120 | .text |
| 121 | 121 | ||
| 122 | /* Called in normal context to backup CPU 0 state. This | 122 | /* Called in normal context to backup CPU 0 state. This |
| 123 | * does not include cache settings. This function is also | 123 | * does not include cache settings. This function is also |
| 124 | * called for machine sleep. This does not include the MMU | 124 | * called for machine sleep. This does not include the MMU |
| @@ -151,7 +151,7 @@ _GLOBAL(__save_cpu_setup) | |||
| 151 | std r3,CS_HID4(r5) | 151 | std r3,CS_HID4(r5) |
| 152 | mfspr r3,SPRN_HID5 | 152 | mfspr r3,SPRN_HID5 |
| 153 | std r3,CS_HID5(r5) | 153 | std r3,CS_HID5(r5) |
| 154 | 154 | ||
| 155 | 2: | 155 | 2: |
| 156 | mtcr r7 | 156 | mtcr r7 |
| 157 | blr | 157 | blr |
| @@ -213,7 +213,7 @@ _GLOBAL(__restore_cpu_setup) | |||
| 213 | mtspr SPRN_HID1,r3 | 213 | mtspr SPRN_HID1,r3 |
| 214 | sync | 214 | sync |
| 215 | isync | 215 | isync |
| 216 | 216 | ||
| 217 | /* Restore HID4 */ | 217 | /* Restore HID4 */ |
| 218 | ld r3,CS_HID4(r5) | 218 | ld r3,CS_HID4(r5) |
| 219 | sync | 219 | sync |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index cc4e9eb1c13f..1d85cedbbb7b 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
| @@ -52,6 +52,9 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); | |||
| 52 | #define COMMON_USER (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \ | 52 | #define COMMON_USER (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \ |
| 53 | PPC_FEATURE_HAS_MMU) | 53 | PPC_FEATURE_HAS_MMU) |
| 54 | #define COMMON_USER_PPC64 (COMMON_USER | PPC_FEATURE_64) | 54 | #define COMMON_USER_PPC64 (COMMON_USER | PPC_FEATURE_64) |
| 55 | #define COMMON_USER_POWER4 (COMMON_USER_PPC64 | PPC_FEATURE_POWER4) | ||
| 56 | #define COMMON_USER_POWER5 (COMMON_USER_PPC64 | PPC_FEATURE_POWER5) | ||
| 57 | #define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS) | ||
| 55 | 58 | ||
| 56 | 59 | ||
| 57 | /* We only set the spe features if the kernel was compiled with | 60 | /* We only set the spe features if the kernel was compiled with |
| @@ -160,7 +163,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 160 | .pvr_value = 0x00350000, | 163 | .pvr_value = 0x00350000, |
| 161 | .cpu_name = "POWER4 (gp)", | 164 | .cpu_name = "POWER4 (gp)", |
| 162 | .cpu_features = CPU_FTRS_POWER4, | 165 | .cpu_features = CPU_FTRS_POWER4, |
| 163 | .cpu_user_features = COMMON_USER_PPC64, | 166 | .cpu_user_features = COMMON_USER_POWER4, |
| 164 | .icache_bsize = 128, | 167 | .icache_bsize = 128, |
| 165 | .dcache_bsize = 128, | 168 | .dcache_bsize = 128, |
| 166 | .num_pmcs = 8, | 169 | .num_pmcs = 8, |
| @@ -175,7 +178,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 175 | .pvr_value = 0x00380000, | 178 | .pvr_value = 0x00380000, |
| 176 | .cpu_name = "POWER4+ (gq)", | 179 | .cpu_name = "POWER4+ (gq)", |
| 177 | .cpu_features = CPU_FTRS_POWER4, | 180 | .cpu_features = CPU_FTRS_POWER4, |
| 178 | .cpu_user_features = COMMON_USER_PPC64, | 181 | .cpu_user_features = COMMON_USER_POWER4, |
| 179 | .icache_bsize = 128, | 182 | .icache_bsize = 128, |
| 180 | .dcache_bsize = 128, | 183 | .dcache_bsize = 128, |
| 181 | .num_pmcs = 8, | 184 | .num_pmcs = 8, |
| @@ -190,7 +193,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 190 | .pvr_value = 0x00390000, | 193 | .pvr_value = 0x00390000, |
| 191 | .cpu_name = "PPC970", | 194 | .cpu_name = "PPC970", |
| 192 | .cpu_features = CPU_FTRS_PPC970, | 195 | .cpu_features = CPU_FTRS_PPC970, |
| 193 | .cpu_user_features = COMMON_USER_PPC64 | | 196 | .cpu_user_features = COMMON_USER_POWER4 | |
| 194 | PPC_FEATURE_HAS_ALTIVEC_COMP, | 197 | PPC_FEATURE_HAS_ALTIVEC_COMP, |
| 195 | .icache_bsize = 128, | 198 | .icache_bsize = 128, |
| 196 | .dcache_bsize = 128, | 199 | .dcache_bsize = 128, |
| @@ -212,7 +215,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 212 | #else | 215 | #else |
| 213 | .cpu_features = CPU_FTRS_PPC970, | 216 | .cpu_features = CPU_FTRS_PPC970, |
| 214 | #endif | 217 | #endif |
| 215 | .cpu_user_features = COMMON_USER_PPC64 | | 218 | .cpu_user_features = COMMON_USER_POWER4 | |
| 216 | PPC_FEATURE_HAS_ALTIVEC_COMP, | 219 | PPC_FEATURE_HAS_ALTIVEC_COMP, |
| 217 | .icache_bsize = 128, | 220 | .icache_bsize = 128, |
| 218 | .dcache_bsize = 128, | 221 | .dcache_bsize = 128, |
| @@ -230,7 +233,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 230 | .pvr_value = 0x00440000, | 233 | .pvr_value = 0x00440000, |
| 231 | .cpu_name = "PPC970MP", | 234 | .cpu_name = "PPC970MP", |
| 232 | .cpu_features = CPU_FTRS_PPC970, | 235 | .cpu_features = CPU_FTRS_PPC970, |
| 233 | .cpu_user_features = COMMON_USER_PPC64 | | 236 | .cpu_user_features = COMMON_USER_POWER4 | |
| 234 | PPC_FEATURE_HAS_ALTIVEC_COMP, | 237 | PPC_FEATURE_HAS_ALTIVEC_COMP, |
| 235 | .icache_bsize = 128, | 238 | .icache_bsize = 128, |
| 236 | .dcache_bsize = 128, | 239 | .dcache_bsize = 128, |
| @@ -245,7 +248,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 245 | .pvr_value = 0x003a0000, | 248 | .pvr_value = 0x003a0000, |
| 246 | .cpu_name = "POWER5 (gr)", | 249 | .cpu_name = "POWER5 (gr)", |
| 247 | .cpu_features = CPU_FTRS_POWER5, | 250 | .cpu_features = CPU_FTRS_POWER5, |
| 248 | .cpu_user_features = COMMON_USER_PPC64, | 251 | .cpu_user_features = COMMON_USER_POWER5, |
| 249 | .icache_bsize = 128, | 252 | .icache_bsize = 128, |
| 250 | .dcache_bsize = 128, | 253 | .dcache_bsize = 128, |
| 251 | .num_pmcs = 6, | 254 | .num_pmcs = 6, |
| @@ -260,7 +263,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 260 | .pvr_value = 0x003b0000, | 263 | .pvr_value = 0x003b0000, |
| 261 | .cpu_name = "POWER5 (gs)", | 264 | .cpu_name = "POWER5 (gs)", |
| 262 | .cpu_features = CPU_FTRS_POWER5, | 265 | .cpu_features = CPU_FTRS_POWER5, |
| 263 | .cpu_user_features = COMMON_USER_PPC64, | 266 | .cpu_user_features = COMMON_USER_POWER5_PLUS, |
| 264 | .icache_bsize = 128, | 267 | .icache_bsize = 128, |
| 265 | .dcache_bsize = 128, | 268 | .dcache_bsize = 128, |
| 266 | .num_pmcs = 6, | 269 | .num_pmcs = 6, |
| @@ -276,7 +279,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 276 | .cpu_name = "Cell Broadband Engine", | 279 | .cpu_name = "Cell Broadband Engine", |
| 277 | .cpu_features = CPU_FTRS_CELL, | 280 | .cpu_features = CPU_FTRS_CELL, |
| 278 | .cpu_user_features = COMMON_USER_PPC64 | | 281 | .cpu_user_features = COMMON_USER_PPC64 | |
| 279 | PPC_FEATURE_HAS_ALTIVEC_COMP, | 282 | PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP, |
| 280 | .icache_bsize = 128, | 283 | .icache_bsize = 128, |
| 281 | .dcache_bsize = 128, | 284 | .dcache_bsize = 128, |
| 282 | .cpu_setup = __setup_cpu_be, | 285 | .cpu_setup = __setup_cpu_be, |
diff --git a/arch/ppc64/kernel/firmware.c b/arch/powerpc/kernel/firmware.c index d8432c0fb27d..65eae752a527 100644 --- a/arch/ppc64/kernel/firmware.c +++ b/arch/powerpc/kernel/firmware.c | |||
| @@ -1,6 +1,4 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * arch/ppc64/kernel/firmware.c | ||
| 3 | * | ||
| 4 | * Extracted from cputable.c | 2 | * Extracted from cputable.c |
| 5 | * | 3 | * |
| 6 | * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) | 4 | * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) |
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 4d6001fa1cf2..b780b42c95fc 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S | |||
| @@ -41,20 +41,20 @@ _GLOBAL(load_up_fpu) | |||
| 41 | #ifndef CONFIG_SMP | 41 | #ifndef CONFIG_SMP |
| 42 | LOADBASE(r3, last_task_used_math) | 42 | LOADBASE(r3, last_task_used_math) |
| 43 | toreal(r3) | 43 | toreal(r3) |
| 44 | LDL r4,OFF(last_task_used_math)(r3) | 44 | PPC_LL r4,OFF(last_task_used_math)(r3) |
| 45 | CMPI 0,r4,0 | 45 | PPC_LCMPI 0,r4,0 |
| 46 | beq 1f | 46 | beq 1f |
| 47 | toreal(r4) | 47 | toreal(r4) |
| 48 | addi r4,r4,THREAD /* want last_task_used_math->thread */ | 48 | addi r4,r4,THREAD /* want last_task_used_math->thread */ |
| 49 | SAVE_32FPRS(0, r4) | 49 | SAVE_32FPRS(0, r4) |
| 50 | mffs fr0 | 50 | mffs fr0 |
| 51 | stfd fr0,THREAD_FPSCR(r4) | 51 | stfd fr0,THREAD_FPSCR(r4) |
| 52 | LDL r5,PT_REGS(r4) | 52 | PPC_LL r5,PT_REGS(r4) |
| 53 | toreal(r5) | 53 | toreal(r5) |
| 54 | LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | 54 | PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) |
| 55 | li r10,MSR_FP|MSR_FE0|MSR_FE1 | 55 | li r10,MSR_FP|MSR_FE0|MSR_FE1 |
| 56 | andc r4,r4,r10 /* disable FP for previous task */ | 56 | andc r4,r4,r10 /* disable FP for previous task */ |
| 57 | STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | 57 | PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) |
| 58 | 1: | 58 | 1: |
| 59 | #endif /* CONFIG_SMP */ | 59 | #endif /* CONFIG_SMP */ |
| 60 | /* enable use of FP after return */ | 60 | /* enable use of FP after return */ |
| @@ -77,7 +77,7 @@ _GLOBAL(load_up_fpu) | |||
| 77 | #ifndef CONFIG_SMP | 77 | #ifndef CONFIG_SMP |
| 78 | subi r4,r5,THREAD | 78 | subi r4,r5,THREAD |
| 79 | fromreal(r4) | 79 | fromreal(r4) |
| 80 | STL r4,OFF(last_task_used_math)(r3) | 80 | PPC_STL r4,OFF(last_task_used_math)(r3) |
| 81 | #endif /* CONFIG_SMP */ | 81 | #endif /* CONFIG_SMP */ |
| 82 | /* restore registers and return */ | 82 | /* restore registers and return */ |
| 83 | /* we haven't used ctr or xer or lr */ | 83 | /* we haven't used ctr or xer or lr */ |
| @@ -97,24 +97,24 @@ _GLOBAL(giveup_fpu) | |||
| 97 | MTMSRD(r5) /* enable use of fpu now */ | 97 | MTMSRD(r5) /* enable use of fpu now */ |
| 98 | SYNC_601 | 98 | SYNC_601 |
| 99 | isync | 99 | isync |
| 100 | CMPI 0,r3,0 | 100 | PPC_LCMPI 0,r3,0 |
| 101 | beqlr- /* if no previous owner, done */ | 101 | beqlr- /* if no previous owner, done */ |
| 102 | addi r3,r3,THREAD /* want THREAD of task */ | 102 | addi r3,r3,THREAD /* want THREAD of task */ |
| 103 | LDL r5,PT_REGS(r3) | 103 | PPC_LL r5,PT_REGS(r3) |
| 104 | CMPI 0,r5,0 | 104 | PPC_LCMPI 0,r5,0 |
| 105 | SAVE_32FPRS(0, r3) | 105 | SAVE_32FPRS(0, r3) |
| 106 | mffs fr0 | 106 | mffs fr0 |
| 107 | stfd fr0,THREAD_FPSCR(r3) | 107 | stfd fr0,THREAD_FPSCR(r3) |
| 108 | beq 1f | 108 | beq 1f |
| 109 | LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | 109 | PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) |
| 110 | li r3,MSR_FP|MSR_FE0|MSR_FE1 | 110 | li r3,MSR_FP|MSR_FE0|MSR_FE1 |
| 111 | andc r4,r4,r3 /* disable FP for previous task */ | 111 | andc r4,r4,r3 /* disable FP for previous task */ |
| 112 | STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | 112 | PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) |
| 113 | 1: | 113 | 1: |
| 114 | #ifndef CONFIG_SMP | 114 | #ifndef CONFIG_SMP |
| 115 | li r5,0 | 115 | li r5,0 |
| 116 | LOADBASE(r4,last_task_used_math) | 116 | LOADBASE(r4,last_task_used_math) |
| 117 | STL r5,OFF(last_task_used_math)(r4) | 117 | PPC_STL r5,OFF(last_task_used_math)(r4) |
| 118 | #endif /* CONFIG_SMP */ | 118 | #endif /* CONFIG_SMP */ |
| 119 | blr | 119 | blr |
| 120 | 120 | ||
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 16ab40daa738..8a8bf79ef044 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #include <asm/reg.h> | 28 | #include <asm/reg.h> |
| 29 | #include <asm/page.h> | 29 | #include <asm/page.h> |
| 30 | #include <asm/mmu.h> | 30 | #include <asm/mmu.h> |
| 31 | #include <asm/systemcfg.h> | ||
| 32 | #include <asm/ppc_asm.h> | 31 | #include <asm/ppc_asm.h> |
| 33 | #include <asm/asm-offsets.h> | 32 | #include <asm/asm-offsets.h> |
| 34 | #include <asm/bug.h> | 33 | #include <asm/bug.h> |
| @@ -1697,25 +1696,14 @@ _GLOBAL(pmac_secondary_start) | |||
| 1697 | * SPRG3 = paca virtual address | 1696 | * SPRG3 = paca virtual address |
| 1698 | */ | 1697 | */ |
| 1699 | _GLOBAL(__secondary_start) | 1698 | _GLOBAL(__secondary_start) |
| 1699 | /* Set thread priority to MEDIUM */ | ||
| 1700 | HMT_MEDIUM | ||
| 1700 | 1701 | ||
| 1701 | HMT_MEDIUM /* Set thread priority to MEDIUM */ | 1702 | /* Load TOC */ |
| 1702 | |||
| 1703 | ld r2,PACATOC(r13) | 1703 | ld r2,PACATOC(r13) |
| 1704 | li r6,0 | 1704 | |
| 1705 | stb r6,PACAPROCENABLED(r13) | 1705 | /* Do early setup for that CPU (stab, slb, hash table pointer) */ |
| 1706 | 1706 | bl .early_setup_secondary | |
| 1707 | #ifndef CONFIG_PPC_ISERIES | ||
| 1708 | /* Initialize the page table pointer register. */ | ||
| 1709 | LOADADDR(r6,_SDR1) | ||
| 1710 | ld r6,0(r6) /* get the value of _SDR1 */ | ||
| 1711 | mtspr SPRN_SDR1,r6 /* set the htab location */ | ||
| 1712 | #endif | ||
| 1713 | /* Initialize the first segment table (or SLB) entry */ | ||
| 1714 | ld r3,PACASTABVIRT(r13) /* get addr of segment table */ | ||
| 1715 | BEGIN_FTR_SECTION | ||
| 1716 | bl .stab_initialize | ||
| 1717 | END_FTR_SECTION_IFCLR(CPU_FTR_SLB) | ||
| 1718 | bl .slb_initialize | ||
| 1719 | 1707 | ||
| 1720 | /* Initialize the kernel stack. Just a repeat for iSeries. */ | 1708 | /* Initialize the kernel stack. Just a repeat for iSeries. */ |
| 1721 | LOADADDR(r3,current_set) | 1709 | LOADADDR(r3,current_set) |
| @@ -1724,37 +1712,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) | |||
| 1724 | addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD | 1712 | addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD |
| 1725 | std r1,PACAKSAVE(r13) | 1713 | std r1,PACAKSAVE(r13) |
| 1726 | 1714 | ||
| 1727 | ld r3,PACASTABREAL(r13) /* get raddr of segment table */ | 1715 | /* Clear backchain so we get nice backtraces */ |
| 1728 | ori r4,r3,1 /* turn on valid bit */ | ||
| 1729 | |||
| 1730 | #ifdef CONFIG_PPC_ISERIES | ||
| 1731 | li r0,-1 /* hypervisor call */ | ||
| 1732 | li r3,1 | ||
| 1733 | sldi r3,r3,63 /* 0x8000000000000000 */ | ||
| 1734 | ori r3,r3,4 /* 0x8000000000000004 */ | ||
| 1735 | sc /* HvCall_setASR */ | ||
| 1736 | #else | ||
| 1737 | /* set the ASR */ | ||
| 1738 | ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */ | ||
| 1739 | ld r3,0(r3) | ||
| 1740 | lwz r3,PLATFORM(r3) /* r3 = platform flags */ | ||
| 1741 | andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ | ||
| 1742 | beq 98f /* branch if result is 0 */ | ||
| 1743 | mfspr r3,SPRN_PVR | ||
| 1744 | srwi r3,r3,16 | ||
| 1745 | cmpwi r3,0x37 /* SStar */ | ||
| 1746 | beq 97f | ||
| 1747 | cmpwi r3,0x36 /* IStar */ | ||
| 1748 | beq 97f | ||
| 1749 | cmpwi r3,0x34 /* Pulsar */ | ||
| 1750 | bne 98f | ||
| 1751 | 97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ | ||
| 1752 | HVSC /* Invoking hcall */ | ||
| 1753 | b 99f | ||
| 1754 | 98: /* !(rpa hypervisor) || !(star) */ | ||
| 1755 | mtasr r4 /* set the stab location */ | ||
| 1756 | 99: | ||
| 1757 | #endif | ||
| 1758 | li r7,0 | 1716 | li r7,0 |
| 1759 | mtlr r7 | 1717 | mtlr r7 |
| 1760 | 1718 | ||
| @@ -1777,6 +1735,7 @@ _GLOBAL(start_secondary_prolog) | |||
| 1777 | li r3,0 | 1735 | li r3,0 |
| 1778 | std r3,0(r1) /* Zero the stack frame pointer */ | 1736 | std r3,0(r1) /* Zero the stack frame pointer */ |
| 1779 | bl .start_secondary | 1737 | bl .start_secondary |
| 1738 | b . | ||
| 1780 | #endif | 1739 | #endif |
| 1781 | 1740 | ||
| 1782 | /* | 1741 | /* |
| @@ -1896,40 +1855,6 @@ _STATIC(start_here_multiplatform) | |||
| 1896 | mr r3,r31 | 1855 | mr r3,r31 |
| 1897 | bl .early_setup | 1856 | bl .early_setup |
| 1898 | 1857 | ||
| 1899 | /* set the ASR */ | ||
| 1900 | ld r3,PACASTABREAL(r13) | ||
| 1901 | ori r4,r3,1 /* turn on valid bit */ | ||
| 1902 | ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */ | ||
| 1903 | ld r3,0(r3) | ||
| 1904 | lwz r3,PLATFORM(r3) /* r3 = platform flags */ | ||
| 1905 | andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ | ||
| 1906 | beq 98f /* branch if result is 0 */ | ||
| 1907 | mfspr r3,SPRN_PVR | ||
| 1908 | srwi r3,r3,16 | ||
| 1909 | cmpwi r3,0x37 /* SStar */ | ||
| 1910 | beq 97f | ||
| 1911 | cmpwi r3,0x36 /* IStar */ | ||
| 1912 | beq 97f | ||
| 1913 | cmpwi r3,0x34 /* Pulsar */ | ||
| 1914 | bne 98f | ||
| 1915 | 97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ | ||
| 1916 | HVSC /* Invoking hcall */ | ||
| 1917 | b 99f | ||
| 1918 | 98: /* !(rpa hypervisor) || !(star) */ | ||
| 1919 | mtasr r4 /* set the stab location */ | ||
| 1920 | 99: | ||
| 1921 | /* Set SDR1 (hash table pointer) */ | ||
| 1922 | ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */ | ||
| 1923 | ld r3,0(r3) | ||
| 1924 | lwz r3,PLATFORM(r3) /* r3 = platform flags */ | ||
| 1925 | /* Test if bit 0 is set (LPAR bit) */ | ||
| 1926 | andi. r3,r3,PLATFORM_LPAR | ||
| 1927 | bne 98f /* branch if result is !0 */ | ||
| 1928 | LOADADDR(r6,_SDR1) /* Only if NOT LPAR */ | ||
| 1929 | add r6,r6,r26 | ||
| 1930 | ld r6,0(r6) /* get the value of _SDR1 */ | ||
| 1931 | mtspr SPRN_SDR1,r6 /* set the htab location */ | ||
| 1932 | 98: | ||
| 1933 | LOADADDR(r3,.start_here_common) | 1858 | LOADADDR(r3,.start_here_common) |
| 1934 | SET_REG_TO_CONST(r4, MSR_KERNEL) | 1859 | SET_REG_TO_CONST(r4, MSR_KERNEL) |
| 1935 | mtspr SPRN_SRR0,r3 | 1860 | mtspr SPRN_SRR0,r3 |
diff --git a/arch/ppc64/kernel/ioctl32.c b/arch/powerpc/kernel/ioctl32.c index ba4a899045c2..3fa6a93adbd0 100644 --- a/arch/ppc64/kernel/ioctl32.c +++ b/arch/powerpc/kernel/ioctl32.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * ioctl32.c: Conversion between 32bit and 64bit native ioctls. | 2 | * ioctl32.c: Conversion between 32bit and 64bit native ioctls. |
| 3 | * | 3 | * |
| 4 | * Based on sparc64 ioctl32.c by: | 4 | * Based on sparc64 ioctl32.c by: |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) | 6 | * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) |
diff --git a/arch/ppc64/kernel/irq.c b/arch/powerpc/kernel/irq.c index 87474584033f..4b7940693f3d 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
| @@ -5,12 +5,12 @@ | |||
| 5 | * Copyright (C) 1992 Linus Torvalds | 5 | * Copyright (C) 1992 Linus Torvalds |
| 6 | * Adapted from arch/i386 by Gary Thomas | 6 | * Adapted from arch/i386 by Gary Thomas |
| 7 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | 7 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) |
| 8 | * Updated and modified by Cort Dougan (cort@cs.nmt.edu) | 8 | * Updated and modified by Cort Dougan <cort@fsmlabs.com> |
| 9 | * Copyright (C) 1996 Cort Dougan | 9 | * Copyright (C) 1996-2001 Cort Dougan |
| 10 | * Adapted for Power Macintosh by Paul Mackerras | 10 | * Adapted for Power Macintosh by Paul Mackerras |
| 11 | * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) | 11 | * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) |
| 12 | * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). | 12 | * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). |
| 13 | * | 13 | * |
| 14 | * This program is free software; you can redistribute it and/or | 14 | * This program is free software; you can redistribute it and/or |
| 15 | * modify it under the terms of the GNU General Public License | 15 | * modify it under the terms of the GNU General Public License |
| 16 | * as published by the Free Software Foundation; either version | 16 | * as published by the Free Software Foundation; either version |
| @@ -21,6 +21,14 @@ | |||
| 21 | * instead of just grabbing them. Thus setups with different IRQ numbers | 21 | * instead of just grabbing them. Thus setups with different IRQ numbers |
| 22 | * shouldn't result in any weird surprises, and installing new handlers | 22 | * shouldn't result in any weird surprises, and installing new handlers |
| 23 | * should be easier. | 23 | * should be easier. |
| 24 | * | ||
| 25 | * The MPC8xx has an interrupt mask in the SIU. If a bit is set, the | ||
| 26 | * interrupt is _enabled_. As expected, IRQ0 is bit 0 in the 32-bit | ||
| 27 | * mask register (of which only 16 are defined), hence the weird shifting | ||
| 28 | * and complement of the cached_irq_mask. I want to be able to stuff | ||
| 29 | * this right into the SIU SMASK register. | ||
| 30 | * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx | ||
| 31 | * to reduce code space and undefined function references. | ||
| 24 | */ | 32 | */ |
| 25 | 33 | ||
| 26 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
| @@ -29,6 +37,7 @@ | |||
| 29 | #include <linux/kernel_stat.h> | 37 | #include <linux/kernel_stat.h> |
| 30 | #include <linux/signal.h> | 38 | #include <linux/signal.h> |
| 31 | #include <linux/sched.h> | 39 | #include <linux/sched.h> |
| 40 | #include <linux/ptrace.h> | ||
| 32 | #include <linux/ioport.h> | 41 | #include <linux/ioport.h> |
| 33 | #include <linux/interrupt.h> | 42 | #include <linux/interrupt.h> |
| 34 | #include <linux/timex.h> | 43 | #include <linux/timex.h> |
| @@ -40,9 +49,13 @@ | |||
| 40 | #include <linux/irq.h> | 49 | #include <linux/irq.h> |
| 41 | #include <linux/proc_fs.h> | 50 | #include <linux/proc_fs.h> |
| 42 | #include <linux/random.h> | 51 | #include <linux/random.h> |
| 43 | #include <linux/kallsyms.h> | 52 | #include <linux/seq_file.h> |
| 53 | #include <linux/cpumask.h> | ||
| 44 | #include <linux/profile.h> | 54 | #include <linux/profile.h> |
| 45 | #include <linux/bitops.h> | 55 | #include <linux/bitops.h> |
| 56 | #ifdef CONFIG_PPC64 | ||
| 57 | #include <linux/kallsyms.h> | ||
| 58 | #endif | ||
| 46 | 59 | ||
| 47 | #include <asm/uaccess.h> | 60 | #include <asm/uaccess.h> |
| 48 | #include <asm/system.h> | 61 | #include <asm/system.h> |
| @@ -52,35 +65,54 @@ | |||
| 52 | #include <asm/cache.h> | 65 | #include <asm/cache.h> |
| 53 | #include <asm/prom.h> | 66 | #include <asm/prom.h> |
| 54 | #include <asm/ptrace.h> | 67 | #include <asm/ptrace.h> |
| 55 | #include <asm/iseries/it_lp_queue.h> | ||
| 56 | #include <asm/machdep.h> | 68 | #include <asm/machdep.h> |
| 69 | #ifdef CONFIG_PPC64 | ||
| 70 | #include <asm/iseries/it_lp_queue.h> | ||
| 57 | #include <asm/paca.h> | 71 | #include <asm/paca.h> |
| 72 | #endif | ||
| 58 | 73 | ||
| 59 | #ifdef CONFIG_SMP | 74 | static int ppc_spurious_interrupts; |
| 60 | extern void iSeries_smp_message_recv( struct pt_regs * ); | 75 | |
| 76 | #if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP) | ||
| 77 | extern void iSeries_smp_message_recv(struct pt_regs *); | ||
| 78 | #endif | ||
| 79 | |||
| 80 | #ifdef CONFIG_PPC32 | ||
| 81 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) | ||
| 82 | |||
| 83 | unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; | ||
| 84 | atomic_t ppc_n_lost_interrupts; | ||
| 85 | |||
| 86 | #ifdef CONFIG_TAU_INT | ||
| 87 | extern int tau_initialized; | ||
| 88 | extern int tau_interrupts(int); | ||
| 89 | #endif | ||
| 90 | |||
| 91 | #if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE) | ||
| 92 | extern atomic_t ipi_recv; | ||
| 93 | extern atomic_t ipi_sent; | ||
| 61 | #endif | 94 | #endif |
| 95 | #endif /* CONFIG_PPC32 */ | ||
| 62 | 96 | ||
| 63 | extern irq_desc_t irq_desc[NR_IRQS]; | 97 | #ifdef CONFIG_PPC64 |
| 64 | EXPORT_SYMBOL(irq_desc); | 98 | EXPORT_SYMBOL(irq_desc); |
| 65 | 99 | ||
| 66 | int distribute_irqs = 1; | 100 | int distribute_irqs = 1; |
| 67 | int __irq_offset_value; | 101 | int __irq_offset_value; |
| 68 | int ppc_spurious_interrupts; | ||
| 69 | u64 ppc64_interrupt_controller; | 102 | u64 ppc64_interrupt_controller; |
| 103 | #endif /* CONFIG_PPC64 */ | ||
| 70 | 104 | ||
| 71 | int show_interrupts(struct seq_file *p, void *v) | 105 | int show_interrupts(struct seq_file *p, void *v) |
| 72 | { | 106 | { |
| 73 | int i = *(loff_t *) v, j; | 107 | int i = *(loff_t *)v, j; |
| 74 | struct irqaction * action; | 108 | struct irqaction *action; |
| 75 | irq_desc_t *desc; | 109 | irq_desc_t *desc; |
| 76 | unsigned long flags; | 110 | unsigned long flags; |
| 77 | 111 | ||
| 78 | if (i == 0) { | 112 | if (i == 0) { |
| 79 | seq_printf(p, " "); | 113 | seq_puts(p, " "); |
| 80 | for (j=0; j<NR_CPUS; j++) { | 114 | for_each_online_cpu(j) |
| 81 | if (cpu_online(j)) | 115 | seq_printf(p, "CPU%d ", j); |
| 82 | seq_printf(p, "CPU%d ",j); | ||
| 83 | } | ||
| 84 | seq_putc(p, '\n'); | 116 | seq_putc(p, '\n'); |
| 85 | } | 117 | } |
| 86 | 118 | ||
| @@ -92,26 +124,41 @@ int show_interrupts(struct seq_file *p, void *v) | |||
| 92 | goto skip; | 124 | goto skip; |
| 93 | seq_printf(p, "%3d: ", i); | 125 | seq_printf(p, "%3d: ", i); |
| 94 | #ifdef CONFIG_SMP | 126 | #ifdef CONFIG_SMP |
| 95 | for (j = 0; j < NR_CPUS; j++) { | 127 | for_each_online_cpu(j) |
| 96 | if (cpu_online(j)) | 128 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
| 97 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | ||
| 98 | } | ||
| 99 | #else | 129 | #else |
| 100 | seq_printf(p, "%10u ", kstat_irqs(i)); | 130 | seq_printf(p, "%10u ", kstat_irqs(i)); |
| 101 | #endif /* CONFIG_SMP */ | 131 | #endif /* CONFIG_SMP */ |
| 102 | if (desc->handler) | 132 | if (desc->handler) |
| 103 | seq_printf(p, " %s ", desc->handler->typename ); | 133 | seq_printf(p, " %s ", desc->handler->typename); |
| 104 | else | 134 | else |
| 105 | seq_printf(p, " None "); | 135 | seq_puts(p, " None "); |
| 106 | seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge "); | 136 | seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge "); |
| 107 | seq_printf(p, " %s",action->name); | 137 | seq_printf(p, " %s", action->name); |
| 108 | for (action=action->next; action; action = action->next) | 138 | for (action = action->next; action; action = action->next) |
| 109 | seq_printf(p, ", %s", action->name); | 139 | seq_printf(p, ", %s", action->name); |
| 110 | seq_putc(p, '\n'); | 140 | seq_putc(p, '\n'); |
| 111 | skip: | 141 | skip: |
| 112 | spin_unlock_irqrestore(&desc->lock, flags); | 142 | spin_unlock_irqrestore(&desc->lock, flags); |
| 113 | } else if (i == NR_IRQS) | 143 | } else if (i == NR_IRQS) { |
| 144 | #ifdef CONFIG_PPC32 | ||
| 145 | #ifdef CONFIG_TAU_INT | ||
| 146 | if (tau_initialized){ | ||
| 147 | seq_puts(p, "TAU: "); | ||
| 148 | for (j = 0; j < NR_CPUS; j++) | ||
| 149 | if (cpu_online(j)) | ||
| 150 | seq_printf(p, "%10u ", tau_interrupts(j)); | ||
| 151 | seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n"); | ||
| 152 | } | ||
| 153 | #endif | ||
| 154 | #if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE) | ||
| 155 | /* should this be per processor send/receive? */ | ||
| 156 | seq_printf(p, "IPI (recv/sent): %10u/%u\n", | ||
| 157 | atomic_read(&ipi_recv), atomic_read(&ipi_sent)); | ||
| 158 | #endif | ||
| 159 | #endif /* CONFIG_PPC32 */ | ||
| 114 | seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts); | 160 | seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts); |
| 161 | } | ||
| 115 | return 0; | 162 | return 0; |
| 116 | } | 163 | } |
| 117 | 164 | ||
| @@ -144,126 +191,6 @@ void fixup_irqs(cpumask_t map) | |||
| 144 | } | 191 | } |
| 145 | #endif | 192 | #endif |
| 146 | 193 | ||
| 147 | extern int noirqdebug; | ||
| 148 | |||
| 149 | /* | ||
| 150 | * Eventually, this should take an array of interrupts and an array size | ||
| 151 | * so it can dispatch multiple interrupts. | ||
| 152 | */ | ||
| 153 | void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) | ||
| 154 | { | ||
| 155 | int status; | ||
| 156 | struct irqaction *action; | ||
| 157 | int cpu = smp_processor_id(); | ||
| 158 | irq_desc_t *desc = get_irq_desc(irq); | ||
| 159 | irqreturn_t action_ret; | ||
| 160 | #ifdef CONFIG_IRQSTACKS | ||
| 161 | struct thread_info *curtp, *irqtp; | ||
| 162 | #endif | ||
| 163 | |||
| 164 | kstat_cpu(cpu).irqs[irq]++; | ||
| 165 | |||
| 166 | if (desc->status & IRQ_PER_CPU) { | ||
| 167 | /* no locking required for CPU-local interrupts: */ | ||
| 168 | ack_irq(irq); | ||
| 169 | action_ret = handle_IRQ_event(irq, regs, desc->action); | ||
| 170 | desc->handler->end(irq); | ||
| 171 | return; | ||
| 172 | } | ||
| 173 | |||
| 174 | spin_lock(&desc->lock); | ||
| 175 | ack_irq(irq); | ||
| 176 | /* | ||
| 177 | REPLAY is when Linux resends an IRQ that was dropped earlier | ||
| 178 | WAITING is used by probe to mark irqs that are being tested | ||
| 179 | */ | ||
| 180 | status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); | ||
| 181 | status |= IRQ_PENDING; /* we _want_ to handle it */ | ||
| 182 | |||
| 183 | /* | ||
| 184 | * If the IRQ is disabled for whatever reason, we cannot | ||
| 185 | * use the action we have. | ||
| 186 | */ | ||
| 187 | action = NULL; | ||
| 188 | if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) { | ||
| 189 | action = desc->action; | ||
| 190 | if (!action || !action->handler) { | ||
| 191 | ppc_spurious_interrupts++; | ||
| 192 | printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq); | ||
| 193 | /* We can't call disable_irq here, it would deadlock */ | ||
| 194 | if (!desc->depth) | ||
| 195 | desc->depth = 1; | ||
| 196 | desc->status |= IRQ_DISABLED; | ||
| 197 | /* This is not a real spurrious interrupt, we | ||
| 198 | * have to eoi it, so we jump to out | ||
| 199 | */ | ||
| 200 | mask_irq(irq); | ||
| 201 | goto out; | ||
| 202 | } | ||
| 203 | status &= ~IRQ_PENDING; /* we commit to handling */ | ||
| 204 | status |= IRQ_INPROGRESS; /* we are handling it */ | ||
| 205 | } | ||
| 206 | desc->status = status; | ||
| 207 | |||
| 208 | /* | ||
| 209 | * If there is no IRQ handler or it was disabled, exit early. | ||
| 210 | Since we set PENDING, if another processor is handling | ||
| 211 | a different instance of this same irq, the other processor | ||
| 212 | will take care of it. | ||
| 213 | */ | ||
| 214 | if (unlikely(!action)) | ||
| 215 | goto out; | ||
| 216 | |||
| 217 | /* | ||
| 218 | * Edge triggered interrupts need to remember | ||
| 219 | * pending events. | ||
| 220 | * This applies to any hw interrupts that allow a second | ||
| 221 | * instance of the same irq to arrive while we are in do_IRQ | ||
| 222 | * or in the handler. But the code here only handles the _second_ | ||
| 223 | * instance of the irq, not the third or fourth. So it is mostly | ||
| 224 | * useful for irq hardware that does not mask cleanly in an | ||
| 225 | * SMP environment. | ||
| 226 | */ | ||
| 227 | for (;;) { | ||
| 228 | spin_unlock(&desc->lock); | ||
| 229 | |||
| 230 | #ifdef CONFIG_IRQSTACKS | ||
| 231 | /* Switch to the irq stack to handle this */ | ||
| 232 | curtp = current_thread_info(); | ||
| 233 | irqtp = hardirq_ctx[smp_processor_id()]; | ||
| 234 | if (curtp != irqtp) { | ||
| 235 | irqtp->task = curtp->task; | ||
| 236 | irqtp->flags = 0; | ||
| 237 | action_ret = call_handle_IRQ_event(irq, regs, action, irqtp); | ||
| 238 | irqtp->task = NULL; | ||
| 239 | if (irqtp->flags) | ||
| 240 | set_bits(irqtp->flags, &curtp->flags); | ||
| 241 | } else | ||
| 242 | #endif | ||
| 243 | action_ret = handle_IRQ_event(irq, regs, action); | ||
| 244 | |||
| 245 | spin_lock(&desc->lock); | ||
| 246 | if (!noirqdebug) | ||
| 247 | note_interrupt(irq, desc, action_ret, regs); | ||
| 248 | if (likely(!(desc->status & IRQ_PENDING))) | ||
| 249 | break; | ||
| 250 | desc->status &= ~IRQ_PENDING; | ||
| 251 | } | ||
| 252 | out: | ||
| 253 | desc->status &= ~IRQ_INPROGRESS; | ||
| 254 | /* | ||
| 255 | * The ->end() handler has to deal with interrupts which got | ||
| 256 | * disabled while the handler was running. | ||
| 257 | */ | ||
| 258 | if (desc->handler) { | ||
| 259 | if (desc->handler->end) | ||
| 260 | desc->handler->end(irq); | ||
| 261 | else if (desc->handler->enable) | ||
| 262 | desc->handler->enable(irq); | ||
| 263 | } | ||
| 264 | spin_unlock(&desc->lock); | ||
| 265 | } | ||
| 266 | |||
| 267 | #ifdef CONFIG_PPC_ISERIES | 194 | #ifdef CONFIG_PPC_ISERIES |
| 268 | void do_IRQ(struct pt_regs *regs) | 195 | void do_IRQ(struct pt_regs *regs) |
| 269 | { | 196 | { |
| @@ -310,8 +237,11 @@ void do_IRQ(struct pt_regs *regs) | |||
| 310 | void do_IRQ(struct pt_regs *regs) | 237 | void do_IRQ(struct pt_regs *regs) |
| 311 | { | 238 | { |
| 312 | int irq; | 239 | int irq; |
| 240 | #ifdef CONFIG_IRQSTACKS | ||
| 241 | struct thread_info *curtp, *irqtp; | ||
| 242 | #endif | ||
| 313 | 243 | ||
| 314 | irq_enter(); | 244 | irq_enter(); |
| 315 | 245 | ||
| 316 | #ifdef CONFIG_DEBUG_STACKOVERFLOW | 246 | #ifdef CONFIG_DEBUG_STACKOVERFLOW |
| 317 | /* Debugging check for stack overflow: is there less than 2KB free? */ | 247 | /* Debugging check for stack overflow: is there less than 2KB free? */ |
| @@ -328,20 +258,44 @@ void do_IRQ(struct pt_regs *regs) | |||
| 328 | } | 258 | } |
| 329 | #endif | 259 | #endif |
| 330 | 260 | ||
| 261 | /* | ||
| 262 | * Every platform is required to implement ppc_md.get_irq. | ||
| 263 | * This function will either return an irq number or -1 to | ||
| 264 | * indicate there are no more pending. | ||
| 265 | * The value -2 is for buggy hardware and means that this IRQ | ||
| 266 | * has already been handled. -- Tom | ||
| 267 | */ | ||
| 331 | irq = ppc_md.get_irq(regs); | 268 | irq = ppc_md.get_irq(regs); |
| 332 | 269 | ||
| 333 | if (irq >= 0) | 270 | if (irq >= 0) { |
| 334 | ppc_irq_dispatch_handler(regs, irq); | 271 | #ifdef CONFIG_IRQSTACKS |
| 335 | else | 272 | /* Switch to the irq stack to handle this */ |
| 336 | /* That's not SMP safe ... but who cares ? */ | 273 | curtp = current_thread_info(); |
| 337 | ppc_spurious_interrupts++; | 274 | irqtp = hardirq_ctx[smp_processor_id()]; |
| 338 | 275 | if (curtp != irqtp) { | |
| 339 | irq_exit(); | 276 | irqtp->task = curtp->task; |
| 277 | irqtp->flags = 0; | ||
| 278 | call___do_IRQ(irq, regs, irqtp); | ||
| 279 | irqtp->task = NULL; | ||
| 280 | if (irqtp->flags) | ||
| 281 | set_bits(irqtp->flags, &curtp->flags); | ||
| 282 | } else | ||
| 283 | #endif | ||
| 284 | __do_IRQ(irq, regs); | ||
| 285 | } else | ||
| 286 | #ifdef CONFIG_PPC32 | ||
| 287 | if (irq != -2) | ||
| 288 | #endif | ||
| 289 | /* That's not SMP safe ... but who cares ? */ | ||
| 290 | ppc_spurious_interrupts++; | ||
| 291 | irq_exit(); | ||
| 340 | } | 292 | } |
| 293 | |||
| 341 | #endif /* CONFIG_PPC_ISERIES */ | 294 | #endif /* CONFIG_PPC_ISERIES */ |
| 342 | 295 | ||
| 343 | void __init init_IRQ(void) | 296 | void __init init_IRQ(void) |
| 344 | { | 297 | { |
| 298 | #ifdef CONFIG_PPC64 | ||
| 345 | static int once = 0; | 299 | static int once = 0; |
| 346 | 300 | ||
| 347 | if (once) | 301 | if (once) |
| @@ -349,10 +303,14 @@ void __init init_IRQ(void) | |||
| 349 | 303 | ||
| 350 | once++; | 304 | once++; |
| 351 | 305 | ||
| 306 | #endif | ||
| 352 | ppc_md.init_IRQ(); | 307 | ppc_md.init_IRQ(); |
| 308 | #ifdef CONFIG_PPC64 | ||
| 353 | irq_ctx_init(); | 309 | irq_ctx_init(); |
| 310 | #endif | ||
| 354 | } | 311 | } |
| 355 | 312 | ||
| 313 | #ifdef CONFIG_PPC64 | ||
| 356 | #ifndef CONFIG_PPC_ISERIES | 314 | #ifndef CONFIG_PPC_ISERIES |
| 357 | /* | 315 | /* |
| 358 | * Virtual IRQ mapping code, used on systems with XICS interrupt controllers. | 316 | * Virtual IRQ mapping code, used on systems with XICS interrupt controllers. |
| @@ -517,3 +475,4 @@ static int __init setup_noirqdistrib(char *str) | |||
| 517 | } | 475 | } |
| 518 | 476 | ||
| 519 | __setup("noirqdistrib", setup_noirqdistrib); | 477 | __setup("noirqdistrib", setup_noirqdistrib); |
| 478 | #endif /* CONFIG_PPC64 */ | ||
diff --git a/arch/ppc64/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 3e7b2f28ec83..5e954fae031f 100644 --- a/arch/ppc64/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <asm/time.h> | 35 | #include <asm/time.h> |
| 36 | #include <asm/iseries/it_exp_vpd_panel.h> | 36 | #include <asm/iseries/it_exp_vpd_panel.h> |
| 37 | #include <asm/prom.h> | 37 | #include <asm/prom.h> |
| 38 | #include <asm/systemcfg.h> | ||
| 38 | 39 | ||
| 39 | #define MODULE_VERS "1.6" | 40 | #define MODULE_VERS "1.6" |
| 40 | #define MODULE_NAME "lparcfg" | 41 | #define MODULE_NAME "lparcfg" |
| @@ -96,7 +97,7 @@ static unsigned long get_purr(void) | |||
| 96 | 97 | ||
| 97 | #define lparcfg_write NULL | 98 | #define lparcfg_write NULL |
| 98 | 99 | ||
| 99 | /* | 100 | /* |
| 100 | * Methods used to fetch LPAR data when running on an iSeries platform. | 101 | * Methods used to fetch LPAR data when running on an iSeries platform. |
| 101 | */ | 102 | */ |
| 102 | static int lparcfg_data(struct seq_file *m, void *v) | 103 | static int lparcfg_data(struct seq_file *m, void *v) |
| @@ -168,7 +169,7 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
| 168 | #endif /* CONFIG_PPC_ISERIES */ | 169 | #endif /* CONFIG_PPC_ISERIES */ |
| 169 | 170 | ||
| 170 | #ifdef CONFIG_PPC_PSERIES | 171 | #ifdef CONFIG_PPC_PSERIES |
| 171 | /* | 172 | /* |
| 172 | * Methods used to fetch LPAR data when running on a pSeries platform. | 173 | * Methods used to fetch LPAR data when running on a pSeries platform. |
| 173 | */ | 174 | */ |
| 174 | 175 | ||
| @@ -177,7 +178,7 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
| 177 | * entitled_capacity,unallocated_capacity, | 178 | * entitled_capacity,unallocated_capacity, |
| 178 | * aggregation, resource_capability). | 179 | * aggregation, resource_capability). |
| 179 | * | 180 | * |
| 180 | * R4 = Entitled Processor Capacity Percentage. | 181 | * R4 = Entitled Processor Capacity Percentage. |
| 181 | * R5 = Unallocated Processor Capacity Percentage. | 182 | * R5 = Unallocated Processor Capacity Percentage. |
| 182 | * R6 (AABBCCDDEEFFGGHH). | 183 | * R6 (AABBCCDDEEFFGGHH). |
| 183 | * XXXX - reserved (0) | 184 | * XXXX - reserved (0) |
| @@ -190,7 +191,7 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
| 190 | * XX - variable processor Capacity Weight | 191 | * XX - variable processor Capacity Weight |
| 191 | * XX - Unallocated Variable Processor Capacity Weight. | 192 | * XX - Unallocated Variable Processor Capacity Weight. |
| 192 | * XXXX - Active processors in Physical Processor Pool. | 193 | * XXXX - Active processors in Physical Processor Pool. |
| 193 | * XXXX - Processors active on platform. | 194 | * XXXX - Processors active on platform. |
| 194 | */ | 195 | */ |
| 195 | static unsigned int h_get_ppp(unsigned long *entitled, | 196 | static unsigned int h_get_ppp(unsigned long *entitled, |
| 196 | unsigned long *unallocated, | 197 | unsigned long *unallocated, |
| @@ -273,7 +274,7 @@ static void parse_system_parameter_string(struct seq_file *m) | |||
| 273 | if (!workbuffer) { | 274 | if (!workbuffer) { |
| 274 | printk(KERN_ERR "%s %s kmalloc failure at line %d \n", | 275 | printk(KERN_ERR "%s %s kmalloc failure at line %d \n", |
| 275 | __FILE__, __FUNCTION__, __LINE__); | 276 | __FILE__, __FUNCTION__, __LINE__); |
| 276 | kfree(local_buffer); | 277 | kfree(local_buffer); |
| 277 | return; | 278 | return; |
| 278 | } | 279 | } |
| 279 | #ifdef LPARCFG_DEBUG | 280 | #ifdef LPARCFG_DEBUG |
| @@ -371,7 +372,7 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
| 371 | lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", NULL); | 372 | lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", NULL); |
| 372 | 373 | ||
| 373 | if (lrdrp == NULL) { | 374 | if (lrdrp == NULL) { |
| 374 | partition_potential_processors = systemcfg->processorCount; | 375 | partition_potential_processors = _systemcfg->processorCount; |
| 375 | } else { | 376 | } else { |
| 376 | partition_potential_processors = *(lrdrp + 4); | 377 | partition_potential_processors = *(lrdrp + 4); |
| 377 | } | 378 | } |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 3bedb532aed9..f6d84a75ed26 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
| @@ -519,7 +519,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) | |||
| 519 | * | 519 | * |
| 520 | * flush_icache_range(unsigned long start, unsigned long stop) | 520 | * flush_icache_range(unsigned long start, unsigned long stop) |
| 521 | */ | 521 | */ |
| 522 | _GLOBAL(flush_icache_range) | 522 | _GLOBAL(__flush_icache_range) |
| 523 | BEGIN_FTR_SECTION | 523 | BEGIN_FTR_SECTION |
| 524 | blr /* for 601, do nothing */ | 524 | blr /* for 601, do nothing */ |
| 525 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) | 525 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) |
| @@ -607,27 +607,6 @@ _GLOBAL(invalidate_dcache_range) | |||
| 607 | sync /* wait for dcbi's to get to ram */ | 607 | sync /* wait for dcbi's to get to ram */ |
| 608 | blr | 608 | blr |
| 609 | 609 | ||
| 610 | #ifdef CONFIG_NOT_COHERENT_CACHE | ||
| 611 | /* | ||
| 612 | * 40x cores have 8K or 16K dcache and 32 byte line size. | ||
| 613 | * 44x has a 32K dcache and 32 byte line size. | ||
| 614 | * 8xx has 1, 2, 4, 8K variants. | ||
| 615 | * For now, cover the worst case of the 44x. | ||
| 616 | * Must be called with external interrupts disabled. | ||
| 617 | */ | ||
| 618 | #define CACHE_NWAYS 64 | ||
| 619 | #define CACHE_NLINES 16 | ||
| 620 | |||
| 621 | _GLOBAL(flush_dcache_all) | ||
| 622 | li r4, (2 * CACHE_NWAYS * CACHE_NLINES) | ||
| 623 | mtctr r4 | ||
| 624 | lis r5, KERNELBASE@h | ||
| 625 | 1: lwz r3, 0(r5) /* Load one word from every line */ | ||
| 626 | addi r5, r5, L1_CACHE_BYTES | ||
| 627 | bdnz 1b | ||
| 628 | blr | ||
| 629 | #endif /* CONFIG_NOT_COHERENT_CACHE */ | ||
| 630 | |||
| 631 | /* | 610 | /* |
| 632 | * Flush a particular page from the data cache to RAM. | 611 | * Flush a particular page from the data cache to RAM. |
| 633 | * Note: this is necessary because the instruction cache does *not* | 612 | * Note: this is necessary because the instruction cache does *not* |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index ae1433da09b2..ae48a002f81a 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
| @@ -89,12 +89,12 @@ _GLOBAL(call_do_softirq) | |||
| 89 | mtlr r0 | 89 | mtlr r0 |
| 90 | blr | 90 | blr |
| 91 | 91 | ||
| 92 | _GLOBAL(call_handle_IRQ_event) | 92 | _GLOBAL(call___do_IRQ) |
| 93 | mflr r0 | 93 | mflr r0 |
| 94 | std r0,16(r1) | 94 | std r0,16(r1) |
| 95 | stdu r1,THREAD_SIZE-112(r6) | 95 | stdu r1,THREAD_SIZE-112(r5) |
| 96 | mr r1,r6 | 96 | mr r1,r5 |
| 97 | bl .handle_IRQ_event | 97 | bl .__do_IRQ |
| 98 | ld r1,0(r1) | 98 | ld r1,0(r1) |
| 99 | ld r0,16(r1) | 99 | ld r0,16(r1) |
| 100 | mtlr r0 | 100 | mtlr r0 |
diff --git a/arch/ppc64/kernel/pacaData.c b/arch/powerpc/kernel/paca.c index 3133c72b28ec..3cf2517c5f91 100644 --- a/arch/ppc64/kernel/pacaData.c +++ b/arch/powerpc/kernel/paca.c | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
| 16 | #include <asm/ptrace.h> | 16 | #include <asm/ptrace.h> |
| 17 | #include <asm/page.h> | 17 | #include <asm/page.h> |
| 18 | 18 | #include <asm/systemcfg.h> | |
| 19 | #include <asm/lppaca.h> | 19 | #include <asm/lppaca.h> |
| 20 | #include <asm/iseries/it_lp_queue.h> | 20 | #include <asm/iseries/it_lp_queue.h> |
| 21 | #include <asm/paca.h> | 21 | #include <asm/paca.h> |
| @@ -24,15 +24,14 @@ static union { | |||
| 24 | struct systemcfg data; | 24 | struct systemcfg data; |
| 25 | u8 page[PAGE_SIZE]; | 25 | u8 page[PAGE_SIZE]; |
| 26 | } systemcfg_store __attribute__((__section__(".data.page.aligned"))); | 26 | } systemcfg_store __attribute__((__section__(".data.page.aligned"))); |
| 27 | struct systemcfg *systemcfg = &systemcfg_store.data; | 27 | struct systemcfg *_systemcfg = &systemcfg_store.data; |
| 28 | EXPORT_SYMBOL(systemcfg); | ||
| 29 | 28 | ||
| 30 | 29 | ||
| 31 | /* This symbol is provided by the linker - let it fill in the paca | 30 | /* This symbol is provided by the linker - let it fill in the paca |
| 32 | * field correctly */ | 31 | * field correctly */ |
| 33 | extern unsigned long __toc_start; | 32 | extern unsigned long __toc_start; |
| 34 | 33 | ||
| 35 | /* The Paca is an array with one entry per processor. Each contains an | 34 | /* The Paca is an array with one entry per processor. Each contains an |
| 36 | * lppaca, which contains the information shared between the | 35 | * lppaca, which contains the information shared between the |
| 37 | * hypervisor and Linux. Each also contains an ItLpRegSave area which | 36 | * hypervisor and Linux. Each also contains an ItLpRegSave area which |
| 38 | * is used by the hypervisor to save registers. | 37 | * is used by the hypervisor to save registers. |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 47d6f7e2ea9f..5dcf4ba05ee8 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <asm/cputable.h> | 44 | #include <asm/cputable.h> |
| 45 | #include <asm/btext.h> | 45 | #include <asm/btext.h> |
| 46 | #include <asm/div64.h> | 46 | #include <asm/div64.h> |
| 47 | #include <asm/signal.h> | ||
| 47 | 48 | ||
| 48 | #ifdef CONFIG_8xx | 49 | #ifdef CONFIG_8xx |
| 49 | #include <asm/commproc.h> | 50 | #include <asm/commproc.h> |
| @@ -56,7 +57,6 @@ extern void machine_check_exception(struct pt_regs *regs); | |||
| 56 | extern void alignment_exception(struct pt_regs *regs); | 57 | extern void alignment_exception(struct pt_regs *regs); |
| 57 | extern void program_check_exception(struct pt_regs *regs); | 58 | extern void program_check_exception(struct pt_regs *regs); |
| 58 | extern void single_step_exception(struct pt_regs *regs); | 59 | extern void single_step_exception(struct pt_regs *regs); |
| 59 | extern int do_signal(sigset_t *, struct pt_regs *); | ||
| 60 | extern int pmac_newworld; | 60 | extern int pmac_newworld; |
| 61 | extern int sys_sigreturn(struct pt_regs *regs); | 61 | extern int sys_sigreturn(struct pt_regs *regs); |
| 62 | 62 | ||
| @@ -188,9 +188,6 @@ EXPORT_SYMBOL(adb_try_handler_change); | |||
| 188 | EXPORT_SYMBOL(cuda_request); | 188 | EXPORT_SYMBOL(cuda_request); |
| 189 | EXPORT_SYMBOL(cuda_poll); | 189 | EXPORT_SYMBOL(cuda_poll); |
| 190 | #endif /* CONFIG_ADB_CUDA */ | 190 | #endif /* CONFIG_ADB_CUDA */ |
| 191 | #if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_PPC32) | ||
| 192 | EXPORT_SYMBOL(_machine); | ||
| 193 | #endif | ||
| 194 | #ifdef CONFIG_PPC_PMAC | 191 | #ifdef CONFIG_PPC_PMAC |
| 195 | EXPORT_SYMBOL(sys_ctrler); | 192 | EXPORT_SYMBOL(sys_ctrler); |
| 196 | #endif | 193 | #endif |
diff --git a/arch/ppc64/kernel/proc_ppc64.c b/arch/powerpc/kernel/proc_ppc64.c index 24e955ee9487..a1c19502fe8b 100644 --- a/arch/ppc64/kernel/proc_ppc64.c +++ b/arch/powerpc/kernel/proc_ppc64.c | |||
| @@ -1,18 +1,16 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * arch/ppc64/kernel/proc_ppc64.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation | 2 | * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation |
| 5 | * | 3 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation; either version 2 of the License, or | 6 | * the Free Software Foundation; either version 2 of the License, or |
| 9 | * (at your option) any later version. | 7 | * (at your option) any later version. |
| 10 | * | 8 | * |
| 11 | * This program is distributed in the hope that it will be useful, | 9 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
| 15 | * | 13 | * |
| 16 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
| 17 | * along with this program; if not, write to the Free Software | 15 | * along with this program; if not, write to the Free Software |
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| @@ -53,7 +51,7 @@ static int __init proc_ppc64_create(void) | |||
| 53 | if (!root) | 51 | if (!root) |
| 54 | return 1; | 52 | return 1; |
| 55 | 53 | ||
| 56 | if (!(systemcfg->platform & (PLATFORM_PSERIES | PLATFORM_CELL))) | 54 | if (!(platform_is_pseries() || _machine == PLATFORM_CELL)) |
| 57 | return 0; | 55 | return 0; |
| 58 | 56 | ||
| 59 | if (!proc_mkdir("rtas", root)) | 57 | if (!proc_mkdir("rtas", root)) |
| @@ -74,7 +72,7 @@ static int __init proc_ppc64_init(void) | |||
| 74 | if (!pde) | 72 | if (!pde) |
| 75 | return 1; | 73 | return 1; |
| 76 | pde->nlink = 1; | 74 | pde->nlink = 1; |
| 77 | pde->data = systemcfg; | 75 | pde->data = _systemcfg; |
| 78 | pde->size = PAGE_SIZE; | 76 | pde->size = PAGE_SIZE; |
| 79 | pde->proc_fops = &page_map_fops; | 77 | pde->proc_fops = &page_map_fops; |
| 80 | 78 | ||
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index f645adb57534..6a5b468edb4d 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
| @@ -48,9 +48,6 @@ | |||
| 48 | #include <asm/machdep.h> | 48 | #include <asm/machdep.h> |
| 49 | #include <asm/pSeries_reconfig.h> | 49 | #include <asm/pSeries_reconfig.h> |
| 50 | #include <asm/pci-bridge.h> | 50 | #include <asm/pci-bridge.h> |
| 51 | #ifdef CONFIG_PPC64 | ||
| 52 | #include <asm/systemcfg.h> | ||
| 53 | #endif | ||
| 54 | 51 | ||
| 55 | #ifdef DEBUG | 52 | #ifdef DEBUG |
| 56 | #define DBG(fmt...) printk(KERN_ERR fmt) | 53 | #define DBG(fmt...) printk(KERN_ERR fmt) |
| @@ -74,10 +71,6 @@ struct isa_reg_property { | |||
| 74 | typedef int interpret_func(struct device_node *, unsigned long *, | 71 | typedef int interpret_func(struct device_node *, unsigned long *, |
| 75 | int, int, int); | 72 | int, int, int); |
| 76 | 73 | ||
| 77 | extern struct rtas_t rtas; | ||
| 78 | extern struct lmb lmb; | ||
| 79 | extern unsigned long klimit; | ||
| 80 | |||
| 81 | static int __initdata dt_root_addr_cells; | 74 | static int __initdata dt_root_addr_cells; |
| 82 | static int __initdata dt_root_size_cells; | 75 | static int __initdata dt_root_size_cells; |
| 83 | 76 | ||
| @@ -391,7 +384,7 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
| 391 | 384 | ||
| 392 | #ifdef CONFIG_PPC64 | 385 | #ifdef CONFIG_PPC64 |
| 393 | /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ | 386 | /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ |
| 394 | if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) { | 387 | if (_machine == PLATFORM_POWERMAC && ic && ic->parent) { |
| 395 | char *name = get_property(ic->parent, "name", NULL); | 388 | char *name = get_property(ic->parent, "name", NULL); |
| 396 | if (name && !strcmp(name, "u3")) | 389 | if (name && !strcmp(name, "u3")) |
| 397 | np->intrs[intrcount].line += 128; | 390 | np->intrs[intrcount].line += 128; |
| @@ -1087,9 +1080,9 @@ void __init unflatten_device_tree(void) | |||
| 1087 | static int __init early_init_dt_scan_cpus(unsigned long node, | 1080 | static int __init early_init_dt_scan_cpus(unsigned long node, |
| 1088 | const char *uname, int depth, void *data) | 1081 | const char *uname, int depth, void *data) |
| 1089 | { | 1082 | { |
| 1090 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); | ||
| 1091 | u32 *prop; | 1083 | u32 *prop; |
| 1092 | unsigned long size = 0; | 1084 | unsigned long size; |
| 1085 | char *type = of_get_flat_dt_prop(node, "device_type", &size); | ||
| 1093 | 1086 | ||
| 1094 | /* We are scanning "cpu" nodes only */ | 1087 | /* We are scanning "cpu" nodes only */ |
| 1095 | if (type == NULL || strcmp(type, "cpu") != 0) | 1088 | if (type == NULL || strcmp(type, "cpu") != 0) |
| @@ -1115,7 +1108,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
| 1115 | 1108 | ||
| 1116 | #ifdef CONFIG_ALTIVEC | 1109 | #ifdef CONFIG_ALTIVEC |
| 1117 | /* Check if we have a VMX and eventually update CPU features */ | 1110 | /* Check if we have a VMX and eventually update CPU features */ |
| 1118 | prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", &size); | 1111 | prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", NULL); |
| 1119 | if (prop && (*prop) > 0) { | 1112 | if (prop && (*prop) > 0) { |
| 1120 | cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; | 1113 | cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; |
| 1121 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; | 1114 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; |
| @@ -1161,13 +1154,9 @@ static int __init early_init_dt_scan_chosen(unsigned long node, | |||
| 1161 | prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL); | 1154 | prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL); |
| 1162 | if (prop == NULL) | 1155 | if (prop == NULL) |
| 1163 | return 0; | 1156 | return 0; |
| 1164 | #ifdef CONFIG_PPC64 | ||
| 1165 | systemcfg->platform = *prop; | ||
| 1166 | #else | ||
| 1167 | #ifdef CONFIG_PPC_MULTIPLATFORM | 1157 | #ifdef CONFIG_PPC_MULTIPLATFORM |
| 1168 | _machine = *prop; | 1158 | _machine = *prop; |
| 1169 | #endif | 1159 | #endif |
| 1170 | #endif | ||
| 1171 | 1160 | ||
| 1172 | #ifdef CONFIG_PPC64 | 1161 | #ifdef CONFIG_PPC64 |
| 1173 | /* check if iommu is forced on or off */ | 1162 | /* check if iommu is forced on or off */ |
| @@ -1264,7 +1253,14 @@ static int __init early_init_dt_scan_memory(unsigned long node, | |||
| 1264 | unsigned long l; | 1253 | unsigned long l; |
| 1265 | 1254 | ||
| 1266 | /* We are scanning "memory" nodes only */ | 1255 | /* We are scanning "memory" nodes only */ |
| 1267 | if (type == NULL || strcmp(type, "memory") != 0) | 1256 | if (type == NULL) { |
| 1257 | /* | ||
| 1258 | * The longtrail doesn't have a device_type on the | ||
| 1259 | * /memory node, so look for the node called /memory@0. | ||
| 1260 | */ | ||
| 1261 | if (depth != 1 || strcmp(uname, "memory@0") != 0) | ||
| 1262 | return 0; | ||
| 1263 | } else if (strcmp(type, "memory") != 0) | ||
| 1268 | return 0; | 1264 | return 0; |
| 1269 | 1265 | ||
| 1270 | reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l); | 1266 | reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l); |
| @@ -1339,9 +1335,6 @@ void __init early_init_devtree(void *params) | |||
| 1339 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); | 1335 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); |
| 1340 | lmb_enforce_memory_limit(memory_limit); | 1336 | lmb_enforce_memory_limit(memory_limit); |
| 1341 | lmb_analyze(); | 1337 | lmb_analyze(); |
| 1342 | #ifdef CONFIG_PPC64 | ||
| 1343 | systemcfg->physicalMemorySize = lmb_phys_mem_size(); | ||
| 1344 | #endif | ||
| 1345 | lmb_reserve(0, __pa(klimit)); | 1338 | lmb_reserve(0, __pa(klimit)); |
| 1346 | 1339 | ||
| 1347 | DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); | 1340 | DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); |
| @@ -1908,7 +1901,7 @@ static int of_finish_dynamic_node(struct device_node *node, | |||
| 1908 | /* We don't support that function on PowerMac, at least | 1901 | /* We don't support that function on PowerMac, at least |
| 1909 | * not yet | 1902 | * not yet |
| 1910 | */ | 1903 | */ |
| 1911 | if (systemcfg->platform == PLATFORM_POWERMAC) | 1904 | if (_machine == PLATFORM_POWERMAC) |
| 1912 | return -ENODEV; | 1905 | return -ENODEV; |
| 1913 | 1906 | ||
| 1914 | /* fix up new node's linux_phandle field */ | 1907 | /* fix up new node's linux_phandle field */ |
| @@ -1992,9 +1985,11 @@ int prom_add_property(struct device_node* np, struct property* prop) | |||
| 1992 | *next = prop; | 1985 | *next = prop; |
| 1993 | write_unlock(&devtree_lock); | 1986 | write_unlock(&devtree_lock); |
| 1994 | 1987 | ||
| 1988 | #ifdef CONFIG_PROC_DEVICETREE | ||
| 1995 | /* try to add to proc as well if it was initialized */ | 1989 | /* try to add to proc as well if it was initialized */ |
| 1996 | if (np->pde) | 1990 | if (np->pde) |
| 1997 | proc_device_tree_add_prop(np->pde, prop); | 1991 | proc_device_tree_add_prop(np->pde, prop); |
| 1992 | #endif /* CONFIG_PROC_DEVICETREE */ | ||
| 1998 | 1993 | ||
| 1999 | return 0; | 1994 | return 0; |
| 2000 | } | 1995 | } |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 6dc33d19fc2a..4ce0105c308e 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
| @@ -94,11 +94,17 @@ extern const struct linux_logo logo_linux_clut224; | |||
| 94 | #ifdef CONFIG_PPC64 | 94 | #ifdef CONFIG_PPC64 |
| 95 | #define RELOC(x) (*PTRRELOC(&(x))) | 95 | #define RELOC(x) (*PTRRELOC(&(x))) |
| 96 | #define ADDR(x) (u32) add_reloc_offset((unsigned long)(x)) | 96 | #define ADDR(x) (u32) add_reloc_offset((unsigned long)(x)) |
| 97 | #define OF_WORKAROUNDS 0 | ||
| 97 | #else | 98 | #else |
| 98 | #define RELOC(x) (x) | 99 | #define RELOC(x) (x) |
| 99 | #define ADDR(x) (u32) (x) | 100 | #define ADDR(x) (u32) (x) |
| 101 | #define OF_WORKAROUNDS of_workarounds | ||
| 102 | int of_workarounds; | ||
| 100 | #endif | 103 | #endif |
| 101 | 104 | ||
| 105 | #define OF_WA_CLAIM 1 /* do phys/virt claim separately, then map */ | ||
| 106 | #define OF_WA_LONGTRAIL 2 /* work around longtrail bugs */ | ||
| 107 | |||
| 102 | #define PROM_BUG() do { \ | 108 | #define PROM_BUG() do { \ |
| 103 | prom_printf("kernel BUG at %s line 0x%x!\n", \ | 109 | prom_printf("kernel BUG at %s line 0x%x!\n", \ |
| 104 | RELOC(__FILE__), __LINE__); \ | 110 | RELOC(__FILE__), __LINE__); \ |
| @@ -111,11 +117,6 @@ extern const struct linux_logo logo_linux_clut224; | |||
| 111 | #define prom_debug(x...) | 117 | #define prom_debug(x...) |
| 112 | #endif | 118 | #endif |
| 113 | 119 | ||
| 114 | #ifdef CONFIG_PPC32 | ||
| 115 | #define PLATFORM_POWERMAC _MACH_Pmac | ||
| 116 | #define PLATFORM_CHRP _MACH_chrp | ||
| 117 | #endif | ||
| 118 | |||
| 119 | 120 | ||
| 120 | typedef u32 prom_arg_t; | 121 | typedef u32 prom_arg_t; |
| 121 | 122 | ||
| @@ -128,10 +129,11 @@ struct prom_args { | |||
| 128 | 129 | ||
| 129 | struct prom_t { | 130 | struct prom_t { |
| 130 | ihandle root; | 131 | ihandle root; |
| 131 | ihandle chosen; | 132 | phandle chosen; |
| 132 | int cpu; | 133 | int cpu; |
| 133 | ihandle stdout; | 134 | ihandle stdout; |
| 134 | ihandle mmumap; | 135 | ihandle mmumap; |
| 136 | ihandle memory; | ||
| 135 | }; | 137 | }; |
| 136 | 138 | ||
| 137 | struct mem_map_entry { | 139 | struct mem_map_entry { |
| @@ -360,16 +362,36 @@ static void __init prom_printf(const char *format, ...) | |||
| 360 | static unsigned int __init prom_claim(unsigned long virt, unsigned long size, | 362 | static unsigned int __init prom_claim(unsigned long virt, unsigned long size, |
| 361 | unsigned long align) | 363 | unsigned long align) |
| 362 | { | 364 | { |
| 363 | int ret; | ||
| 364 | struct prom_t *_prom = &RELOC(prom); | 365 | struct prom_t *_prom = &RELOC(prom); |
| 365 | 366 | ||
| 366 | ret = call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size, | 367 | if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) { |
| 367 | (prom_arg_t)align); | 368 | /* |
| 368 | if (ret != -1 && _prom->mmumap != 0) | 369 | * Old OF requires we claim physical and virtual separately |
| 369 | /* old pmacs need us to map as well */ | 370 | * and then map explicitly (assuming virtual mode) |
| 371 | */ | ||
| 372 | int ret; | ||
| 373 | prom_arg_t result; | ||
| 374 | |||
| 375 | ret = call_prom_ret("call-method", 5, 2, &result, | ||
| 376 | ADDR("claim"), _prom->memory, | ||
| 377 | align, size, virt); | ||
| 378 | if (ret != 0 || result == -1) | ||
| 379 | return -1; | ||
| 380 | ret = call_prom_ret("call-method", 5, 2, &result, | ||
| 381 | ADDR("claim"), _prom->mmumap, | ||
| 382 | align, size, virt); | ||
| 383 | if (ret != 0) { | ||
| 384 | call_prom("call-method", 4, 1, ADDR("release"), | ||
| 385 | _prom->memory, size, virt); | ||
| 386 | return -1; | ||
| 387 | } | ||
| 388 | /* the 0x12 is M (coherence) + PP == read/write */ | ||
| 370 | call_prom("call-method", 6, 1, | 389 | call_prom("call-method", 6, 1, |
| 371 | ADDR("map"), _prom->mmumap, 0, size, virt, virt); | 390 | ADDR("map"), _prom->mmumap, 0x12, size, virt, virt); |
| 372 | return ret; | 391 | return virt; |
| 392 | } | ||
| 393 | return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size, | ||
| 394 | (prom_arg_t)align); | ||
| 373 | } | 395 | } |
| 374 | 396 | ||
| 375 | static void __init __attribute__((noreturn)) prom_panic(const char *reason) | 397 | static void __init __attribute__((noreturn)) prom_panic(const char *reason) |
| @@ -415,11 +437,52 @@ static int inline prom_getproplen(phandle node, const char *pname) | |||
| 415 | return call_prom("getproplen", 2, 1, node, ADDR(pname)); | 437 | return call_prom("getproplen", 2, 1, node, ADDR(pname)); |
| 416 | } | 438 | } |
| 417 | 439 | ||
| 418 | static int inline prom_setprop(phandle node, const char *pname, | 440 | static void add_string(char **str, const char *q) |
| 419 | void *value, size_t valuelen) | ||
| 420 | { | 441 | { |
| 421 | return call_prom("setprop", 4, 1, node, ADDR(pname), | 442 | char *p = *str; |
| 422 | (u32)(unsigned long) value, (u32) valuelen); | 443 | |
| 444 | while (*q) | ||
| 445 | *p++ = *q++; | ||
| 446 | *p++ = ' '; | ||
| 447 | *str = p; | ||
| 448 | } | ||
| 449 | |||
| 450 | static char *tohex(unsigned int x) | ||
| 451 | { | ||
| 452 | static char digits[] = "0123456789abcdef"; | ||
| 453 | static char result[9]; | ||
| 454 | int i; | ||
| 455 | |||
| 456 | result[8] = 0; | ||
| 457 | i = 8; | ||
| 458 | do { | ||
| 459 | --i; | ||
| 460 | result[i] = digits[x & 0xf]; | ||
| 461 | x >>= 4; | ||
| 462 | } while (x != 0 && i > 0); | ||
| 463 | return &result[i]; | ||
| 464 | } | ||
| 465 | |||
| 466 | static int __init prom_setprop(phandle node, const char *nodename, | ||
| 467 | const char *pname, void *value, size_t valuelen) | ||
| 468 | { | ||
| 469 | char cmd[256], *p; | ||
| 470 | |||
| 471 | if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL)) | ||
| 472 | return call_prom("setprop", 4, 1, node, ADDR(pname), | ||
| 473 | (u32)(unsigned long) value, (u32) valuelen); | ||
| 474 | |||
| 475 | /* gah... setprop doesn't work on longtrail, have to use interpret */ | ||
| 476 | p = cmd; | ||
| 477 | add_string(&p, "dev"); | ||
| 478 | add_string(&p, nodename); | ||
| 479 | add_string(&p, tohex((u32)(unsigned long) value)); | ||
| 480 | add_string(&p, tohex(valuelen)); | ||
| 481 | add_string(&p, tohex(ADDR(pname))); | ||
| 482 | add_string(&p, tohex(strlen(RELOC(pname)))); | ||
| 483 | add_string(&p, "property"); | ||
| 484 | *p = 0; | ||
| 485 | return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd); | ||
| 423 | } | 486 | } |
| 424 | 487 | ||
| 425 | /* We can't use the standard versions because of RELOC headaches. */ | 488 | /* We can't use the standard versions because of RELOC headaches. */ |
| @@ -980,7 +1043,7 @@ static void __init prom_instantiate_rtas(void) | |||
| 980 | 1043 | ||
| 981 | rtas_inst = call_prom("open", 1, 1, ADDR("/rtas")); | 1044 | rtas_inst = call_prom("open", 1, 1, ADDR("/rtas")); |
| 982 | if (!IHANDLE_VALID(rtas_inst)) { | 1045 | if (!IHANDLE_VALID(rtas_inst)) { |
| 983 | prom_printf("opening rtas package failed"); | 1046 | prom_printf("opening rtas package failed (%x)\n", rtas_inst); |
| 984 | return; | 1047 | return; |
| 985 | } | 1048 | } |
| 986 | 1049 | ||
| @@ -988,7 +1051,7 @@ static void __init prom_instantiate_rtas(void) | |||
| 988 | 1051 | ||
| 989 | if (call_prom_ret("call-method", 3, 2, &entry, | 1052 | if (call_prom_ret("call-method", 3, 2, &entry, |
| 990 | ADDR("instantiate-rtas"), | 1053 | ADDR("instantiate-rtas"), |
| 991 | rtas_inst, base) == PROM_ERROR | 1054 | rtas_inst, base) != 0 |
| 992 | || entry == 0) { | 1055 | || entry == 0) { |
| 993 | prom_printf(" failed\n"); | 1056 | prom_printf(" failed\n"); |
| 994 | return; | 1057 | return; |
| @@ -997,8 +1060,10 @@ static void __init prom_instantiate_rtas(void) | |||
| 997 | 1060 | ||
| 998 | reserve_mem(base, size); | 1061 | reserve_mem(base, size); |
| 999 | 1062 | ||
| 1000 | prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base)); | 1063 | prom_setprop(rtas_node, "/rtas", "linux,rtas-base", |
| 1001 | prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry)); | 1064 | &base, sizeof(base)); |
| 1065 | prom_setprop(rtas_node, "/rtas", "linux,rtas-entry", | ||
| 1066 | &entry, sizeof(entry)); | ||
| 1002 | 1067 | ||
| 1003 | prom_debug("rtas base = 0x%x\n", base); | 1068 | prom_debug("rtas base = 0x%x\n", base); |
| 1004 | prom_debug("rtas entry = 0x%x\n", entry); | 1069 | prom_debug("rtas entry = 0x%x\n", entry); |
| @@ -1089,10 +1154,6 @@ static void __init prom_initialize_tce_table(void) | |||
| 1089 | if (base < local_alloc_bottom) | 1154 | if (base < local_alloc_bottom) |
| 1090 | local_alloc_bottom = base; | 1155 | local_alloc_bottom = base; |
| 1091 | 1156 | ||
| 1092 | /* Save away the TCE table attributes for later use. */ | ||
| 1093 | prom_setprop(node, "linux,tce-base", &base, sizeof(base)); | ||
| 1094 | prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize)); | ||
| 1095 | |||
| 1096 | /* It seems OF doesn't null-terminate the path :-( */ | 1157 | /* It seems OF doesn't null-terminate the path :-( */ |
| 1097 | memset(path, 0, sizeof(path)); | 1158 | memset(path, 0, sizeof(path)); |
| 1098 | /* Call OF to setup the TCE hardware */ | 1159 | /* Call OF to setup the TCE hardware */ |
| @@ -1101,6 +1162,10 @@ static void __init prom_initialize_tce_table(void) | |||
| 1101 | prom_printf("package-to-path failed\n"); | 1162 | prom_printf("package-to-path failed\n"); |
| 1102 | } | 1163 | } |
| 1103 | 1164 | ||
| 1165 | /* Save away the TCE table attributes for later use. */ | ||
| 1166 | prom_setprop(node, path, "linux,tce-base", &base, sizeof(base)); | ||
| 1167 | prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize)); | ||
| 1168 | |||
| 1104 | prom_debug("TCE table: %s\n", path); | 1169 | prom_debug("TCE table: %s\n", path); |
| 1105 | prom_debug("\tnode = 0x%x\n", node); | 1170 | prom_debug("\tnode = 0x%x\n", node); |
| 1106 | prom_debug("\tbase = 0x%x\n", base); | 1171 | prom_debug("\tbase = 0x%x\n", base); |
| @@ -1342,6 +1407,7 @@ static void __init prom_init_client_services(unsigned long pp) | |||
| 1342 | /* | 1407 | /* |
| 1343 | * For really old powermacs, we need to map things we claim. | 1408 | * For really old powermacs, we need to map things we claim. |
| 1344 | * For that, we need the ihandle of the mmu. | 1409 | * For that, we need the ihandle of the mmu. |
| 1410 | * Also, on the longtrail, we need to work around other bugs. | ||
| 1345 | */ | 1411 | */ |
| 1346 | static void __init prom_find_mmu(void) | 1412 | static void __init prom_find_mmu(void) |
| 1347 | { | 1413 | { |
| @@ -1355,12 +1421,19 @@ static void __init prom_find_mmu(void) | |||
| 1355 | if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0) | 1421 | if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0) |
| 1356 | return; | 1422 | return; |
| 1357 | version[sizeof(version) - 1] = 0; | 1423 | version[sizeof(version) - 1] = 0; |
| 1358 | prom_printf("OF version is '%s'\n", version); | ||
| 1359 | /* XXX might need to add other versions here */ | 1424 | /* XXX might need to add other versions here */ |
| 1360 | if (strcmp(version, "Open Firmware, 1.0.5") != 0) | 1425 | if (strcmp(version, "Open Firmware, 1.0.5") == 0) |
| 1426 | of_workarounds = OF_WA_CLAIM; | ||
| 1427 | else if (strncmp(version, "FirmWorks,3.", 12) == 0) { | ||
| 1428 | of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL; | ||
| 1429 | call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim"); | ||
| 1430 | } else | ||
| 1361 | return; | 1431 | return; |
| 1432 | _prom->memory = call_prom("open", 1, 1, ADDR("/memory")); | ||
| 1362 | prom_getprop(_prom->chosen, "mmu", &_prom->mmumap, | 1433 | prom_getprop(_prom->chosen, "mmu", &_prom->mmumap, |
| 1363 | sizeof(_prom->mmumap)); | 1434 | sizeof(_prom->mmumap)); |
| 1435 | if (!IHANDLE_VALID(_prom->memory) || !IHANDLE_VALID(_prom->mmumap)) | ||
| 1436 | of_workarounds &= ~OF_WA_CLAIM; /* hmmm */ | ||
| 1364 | } | 1437 | } |
| 1365 | #else | 1438 | #else |
| 1366 | #define prom_find_mmu() | 1439 | #define prom_find_mmu() |
| @@ -1382,16 +1455,17 @@ static void __init prom_init_stdout(void) | |||
| 1382 | memset(path, 0, 256); | 1455 | memset(path, 0, 256); |
| 1383 | call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255); | 1456 | call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255); |
| 1384 | val = call_prom("instance-to-package", 1, 1, _prom->stdout); | 1457 | val = call_prom("instance-to-package", 1, 1, _prom->stdout); |
| 1385 | prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val)); | 1458 | prom_setprop(_prom->chosen, "/chosen", "linux,stdout-package", |
| 1459 | &val, sizeof(val)); | ||
| 1386 | prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device)); | 1460 | prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device)); |
| 1387 | prom_setprop(_prom->chosen, "linux,stdout-path", | 1461 | prom_setprop(_prom->chosen, "/chosen", "linux,stdout-path", |
| 1388 | RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1); | 1462 | path, strlen(path) + 1); |
| 1389 | 1463 | ||
| 1390 | /* If it's a display, note it */ | 1464 | /* If it's a display, note it */ |
| 1391 | memset(type, 0, sizeof(type)); | 1465 | memset(type, 0, sizeof(type)); |
| 1392 | prom_getprop(val, "device_type", type, sizeof(type)); | 1466 | prom_getprop(val, "device_type", type, sizeof(type)); |
| 1393 | if (strcmp(type, RELOC("display")) == 0) | 1467 | if (strcmp(type, RELOC("display")) == 0) |
| 1394 | prom_setprop(val, "linux,boot-display", NULL, 0); | 1468 | prom_setprop(val, path, "linux,boot-display", NULL, 0); |
| 1395 | } | 1469 | } |
| 1396 | 1470 | ||
| 1397 | static void __init prom_close_stdin(void) | 1471 | static void __init prom_close_stdin(void) |
| @@ -1514,7 +1588,7 @@ static void __init prom_check_displays(void) | |||
| 1514 | 1588 | ||
| 1515 | /* Success */ | 1589 | /* Success */ |
| 1516 | prom_printf("done\n"); | 1590 | prom_printf("done\n"); |
| 1517 | prom_setprop(node, "linux,opened", NULL, 0); | 1591 | prom_setprop(node, path, "linux,opened", NULL, 0); |
| 1518 | 1592 | ||
| 1519 | /* Setup a usable color table when the appropriate | 1593 | /* Setup a usable color table when the appropriate |
| 1520 | * method is available. Should update this to set-colors */ | 1594 | * method is available. Should update this to set-colors */ |
| @@ -1884,9 +1958,11 @@ static void __init fixup_device_tree(void) | |||
| 1884 | /* interrupt on this revision of u3 is number 0 and level */ | 1958 | /* interrupt on this revision of u3 is number 0 and level */ |
| 1885 | interrupts[0] = 0; | 1959 | interrupts[0] = 0; |
| 1886 | interrupts[1] = 1; | 1960 | interrupts[1] = 1; |
| 1887 | prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts)); | 1961 | prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts", |
| 1962 | &interrupts, sizeof(interrupts)); | ||
| 1888 | parent = (u32)mpic; | 1963 | parent = (u32)mpic; |
| 1889 | prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent)); | 1964 | prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent", |
| 1965 | &parent, sizeof(parent)); | ||
| 1890 | #endif | 1966 | #endif |
| 1891 | } | 1967 | } |
| 1892 | 1968 | ||
| @@ -1922,11 +1998,11 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4) | |||
| 1922 | RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; | 1998 | RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; |
| 1923 | 1999 | ||
| 1924 | val = RELOC(prom_initrd_start); | 2000 | val = RELOC(prom_initrd_start); |
| 1925 | prom_setprop(_prom->chosen, "linux,initrd-start", &val, | 2001 | prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start", |
| 1926 | sizeof(val)); | 2002 | &val, sizeof(val)); |
| 1927 | val = RELOC(prom_initrd_end); | 2003 | val = RELOC(prom_initrd_end); |
| 1928 | prom_setprop(_prom->chosen, "linux,initrd-end", &val, | 2004 | prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end", |
| 1929 | sizeof(val)); | 2005 | &val, sizeof(val)); |
| 1930 | 2006 | ||
| 1931 | reserve_mem(RELOC(prom_initrd_start), | 2007 | reserve_mem(RELOC(prom_initrd_start), |
| 1932 | RELOC(prom_initrd_end) - RELOC(prom_initrd_start)); | 2008 | RELOC(prom_initrd_end) - RELOC(prom_initrd_start)); |
| @@ -1969,14 +2045,15 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
| 1969 | prom_init_client_services(pp); | 2045 | prom_init_client_services(pp); |
| 1970 | 2046 | ||
| 1971 | /* | 2047 | /* |
| 1972 | * Init prom stdout device | 2048 | * See if this OF is old enough that we need to do explicit maps |
| 2049 | * and other workarounds | ||
| 1973 | */ | 2050 | */ |
| 1974 | prom_init_stdout(); | 2051 | prom_find_mmu(); |
| 1975 | 2052 | ||
| 1976 | /* | 2053 | /* |
| 1977 | * See if this OF is old enough that we need to do explicit maps | 2054 | * Init prom stdout device |
| 1978 | */ | 2055 | */ |
| 1979 | prom_find_mmu(); | 2056 | prom_init_stdout(); |
| 1980 | 2057 | ||
| 1981 | /* | 2058 | /* |
| 1982 | * Check for an initrd | 2059 | * Check for an initrd |
| @@ -1989,14 +2066,15 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
| 1989 | */ | 2066 | */ |
| 1990 | RELOC(of_platform) = prom_find_machine_type(); | 2067 | RELOC(of_platform) = prom_find_machine_type(); |
| 1991 | getprop_rval = RELOC(of_platform); | 2068 | getprop_rval = RELOC(of_platform); |
| 1992 | prom_setprop(_prom->chosen, "linux,platform", | 2069 | prom_setprop(_prom->chosen, "/chosen", "linux,platform", |
| 1993 | &getprop_rval, sizeof(getprop_rval)); | 2070 | &getprop_rval, sizeof(getprop_rval)); |
| 1994 | 2071 | ||
| 1995 | #ifdef CONFIG_PPC_PSERIES | 2072 | #ifdef CONFIG_PPC_PSERIES |
| 1996 | /* | 2073 | /* |
| 1997 | * On pSeries, inform the firmware about our capabilities | 2074 | * On pSeries, inform the firmware about our capabilities |
| 1998 | */ | 2075 | */ |
| 1999 | if (RELOC(of_platform) & PLATFORM_PSERIES) | 2076 | if (RELOC(of_platform) == PLATFORM_PSERIES || |
| 2077 | RELOC(of_platform) == PLATFORM_PSERIES_LPAR) | ||
| 2000 | prom_send_capabilities(); | 2078 | prom_send_capabilities(); |
| 2001 | #endif | 2079 | #endif |
| 2002 | 2080 | ||
| @@ -2050,21 +2128,23 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
| 2050 | * Fill in some infos for use by the kernel later on | 2128 | * Fill in some infos for use by the kernel later on |
| 2051 | */ | 2129 | */ |
| 2052 | if (RELOC(prom_memory_limit)) | 2130 | if (RELOC(prom_memory_limit)) |
| 2053 | prom_setprop(_prom->chosen, "linux,memory-limit", | 2131 | prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit", |
| 2054 | &RELOC(prom_memory_limit), | 2132 | &RELOC(prom_memory_limit), |
| 2055 | sizeof(prom_memory_limit)); | 2133 | sizeof(prom_memory_limit)); |
| 2056 | #ifdef CONFIG_PPC64 | 2134 | #ifdef CONFIG_PPC64 |
| 2057 | if (RELOC(ppc64_iommu_off)) | 2135 | if (RELOC(ppc64_iommu_off)) |
| 2058 | prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0); | 2136 | prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off", |
| 2137 | NULL, 0); | ||
| 2059 | 2138 | ||
| 2060 | if (RELOC(iommu_force_on)) | 2139 | if (RELOC(iommu_force_on)) |
| 2061 | prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0); | 2140 | prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on", |
| 2141 | NULL, 0); | ||
| 2062 | 2142 | ||
| 2063 | if (RELOC(prom_tce_alloc_start)) { | 2143 | if (RELOC(prom_tce_alloc_start)) { |
| 2064 | prom_setprop(_prom->chosen, "linux,tce-alloc-start", | 2144 | prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-start", |
| 2065 | &RELOC(prom_tce_alloc_start), | 2145 | &RELOC(prom_tce_alloc_start), |
| 2066 | sizeof(prom_tce_alloc_start)); | 2146 | sizeof(prom_tce_alloc_start)); |
| 2067 | prom_setprop(_prom->chosen, "linux,tce-alloc-end", | 2147 | prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-end", |
| 2068 | &RELOC(prom_tce_alloc_end), | 2148 | &RELOC(prom_tce_alloc_end), |
| 2069 | sizeof(prom_tce_alloc_end)); | 2149 | sizeof(prom_tce_alloc_end)); |
| 2070 | } | 2150 | } |
| @@ -2081,8 +2161,13 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
| 2081 | prom_printf("copying OF device tree ...\n"); | 2161 | prom_printf("copying OF device tree ...\n"); |
| 2082 | flatten_device_tree(); | 2162 | flatten_device_tree(); |
| 2083 | 2163 | ||
| 2084 | /* in case stdin is USB and still active on IBM machines... */ | 2164 | /* |
| 2085 | prom_close_stdin(); | 2165 | * in case stdin is USB and still active on IBM machines... |
| 2166 | * Unfortunately quiesce crashes on some powermacs if we have | ||
| 2167 | * closed stdin already (in particular the powerbook 101). | ||
| 2168 | */ | ||
| 2169 | if (RELOC(of_platform) != PLATFORM_POWERMAC) | ||
| 2170 | prom_close_stdin(); | ||
| 2086 | 2171 | ||
| 2087 | /* | 2172 | /* |
| 2088 | * Call OF "quiesce" method to shut down pending DMA's from | 2173 | * Call OF "quiesce" method to shut down pending DMA's from |
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index 5bdd5b079d96..ae1a36449ccd 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c | |||
| @@ -259,7 +259,7 @@ static int __init proc_rtas_init(void) | |||
| 259 | { | 259 | { |
| 260 | struct proc_dir_entry *entry; | 260 | struct proc_dir_entry *entry; |
| 261 | 261 | ||
| 262 | if (!(systemcfg->platform & PLATFORM_PSERIES)) | 262 | if (_machine != PLATFORM_PSERIES && _machine != PLATFORM_PSERIES_LPAR) |
| 263 | return 1; | 263 | return 1; |
| 264 | 264 | ||
| 265 | rtas_node = of_find_node_by_name(NULL, "rtas"); | 265 | rtas_node = of_find_node_by_name(NULL, "rtas"); |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 9d4e07f6f1ec..4283fa33f784 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
| @@ -29,9 +29,6 @@ | |||
| 29 | #include <asm/delay.h> | 29 | #include <asm/delay.h> |
| 30 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
| 31 | #include <asm/lmb.h> | 31 | #include <asm/lmb.h> |
| 32 | #ifdef CONFIG_PPC64 | ||
| 33 | #include <asm/systemcfg.h> | ||
| 34 | #endif | ||
| 35 | 32 | ||
| 36 | struct rtas_t rtas = { | 33 | struct rtas_t rtas = { |
| 37 | .lock = SPIN_LOCK_UNLOCKED | 34 | .lock = SPIN_LOCK_UNLOCKED |
| @@ -671,7 +668,7 @@ void __init rtas_initialize(void) | |||
| 671 | * the stop-self token if any | 668 | * the stop-self token if any |
| 672 | */ | 669 | */ |
| 673 | #ifdef CONFIG_PPC64 | 670 | #ifdef CONFIG_PPC64 |
| 674 | if (systemcfg->platform == PLATFORM_PSERIES_LPAR) | 671 | if (_machine == PLATFORM_PSERIES_LPAR) |
| 675 | rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); | 672 | rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); |
| 676 | #endif | 673 | #endif |
| 677 | rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region); | 674 | rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region); |
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 3c3f19192fcc..0e5a8e116653 100644 --- a/arch/ppc64/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c | |||
| @@ -5,19 +5,19 @@ | |||
| 5 | * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM | 5 | * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM |
| 6 | * | 6 | * |
| 7 | * RTAS specific routines for PCI. | 7 | * RTAS specific routines for PCI. |
| 8 | * | 8 | * |
| 9 | * Based on code from pci.c, chrp_pci.c and pSeries_pci.c | 9 | * Based on code from pci.c, chrp_pci.c and pSeries_pci.c |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
| 13 | * the Free Software Foundation; either version 2 of the License, or | 13 | * the Free Software Foundation; either version 2 of the License, or |
| 14 | * (at your option) any later version. | 14 | * (at your option) any later version. |
| 15 | * | 15 | * |
| 16 | * This program is distributed in the hope that it will be useful, | 16 | * This program is distributed in the hope that it will be useful, |
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 19 | * GNU General Public License for more details. | 19 | * GNU General Public License for more details. |
| 20 | * | 20 | * |
| 21 | * You should have received a copy of the GNU General Public License | 21 | * You should have received a copy of the GNU General Public License |
| 22 | * along with this program; if not, write to the Free Software | 22 | * along with this program; if not, write to the Free Software |
| 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| @@ -47,7 +47,7 @@ static int write_pci_config; | |||
| 47 | static int ibm_read_pci_config; | 47 | static int ibm_read_pci_config; |
| 48 | static int ibm_write_pci_config; | 48 | static int ibm_write_pci_config; |
| 49 | 49 | ||
| 50 | static int config_access_valid(struct pci_dn *dn, int where) | 50 | static inline int config_access_valid(struct pci_dn *dn, int where) |
| 51 | { | 51 | { |
| 52 | if (where < 256) | 52 | if (where < 256) |
| 53 | return 1; | 53 | return 1; |
| @@ -72,16 +72,14 @@ static int of_device_available(struct device_node * dn) | |||
| 72 | return 0; | 72 | return 0; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val) | 75 | static int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val) |
| 76 | { | 76 | { |
| 77 | int returnval = -1; | 77 | int returnval = -1; |
| 78 | unsigned long buid, addr; | 78 | unsigned long buid, addr; |
| 79 | int ret; | 79 | int ret; |
| 80 | struct pci_dn *pdn; | ||
| 81 | 80 | ||
| 82 | if (!dn || !dn->data) | 81 | if (!pdn) |
| 83 | return PCIBIOS_DEVICE_NOT_FOUND; | 82 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 84 | pdn = dn->data; | ||
| 85 | if (!config_access_valid(pdn, where)) | 83 | if (!config_access_valid(pdn, where)) |
| 86 | return PCIBIOS_BAD_REGISTER_NUMBER; | 84 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 87 | 85 | ||
| @@ -90,7 +88,7 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va | |||
| 90 | buid = pdn->phb->buid; | 88 | buid = pdn->phb->buid; |
| 91 | if (buid) { | 89 | if (buid) { |
| 92 | ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, | 90 | ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, |
| 93 | addr, buid >> 32, buid & 0xffffffff, size); | 91 | addr, BUID_HI(buid), BUID_LO(buid), size); |
| 94 | } else { | 92 | } else { |
| 95 | ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size); | 93 | ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size); |
| 96 | } | 94 | } |
| @@ -100,7 +98,7 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va | |||
| 100 | return PCIBIOS_DEVICE_NOT_FOUND; | 98 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 101 | 99 | ||
| 102 | if (returnval == EEH_IO_ERROR_VALUE(size) && | 100 | if (returnval == EEH_IO_ERROR_VALUE(size) && |
| 103 | eeh_dn_check_failure (dn, NULL)) | 101 | eeh_dn_check_failure (pdn->node, NULL)) |
| 104 | return PCIBIOS_DEVICE_NOT_FOUND; | 102 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 105 | 103 | ||
| 106 | return PCIBIOS_SUCCESSFUL; | 104 | return PCIBIOS_SUCCESSFUL; |
| @@ -118,23 +116,23 @@ static int rtas_pci_read_config(struct pci_bus *bus, | |||
| 118 | busdn = bus->sysdata; /* must be a phb */ | 116 | busdn = bus->sysdata; /* must be a phb */ |
| 119 | 117 | ||
| 120 | /* Search only direct children of the bus */ | 118 | /* Search only direct children of the bus */ |
| 121 | for (dn = busdn->child; dn; dn = dn->sibling) | 119 | for (dn = busdn->child; dn; dn = dn->sibling) { |
| 122 | if (dn->data && PCI_DN(dn)->devfn == devfn | 120 | struct pci_dn *pdn = PCI_DN(dn); |
| 121 | if (pdn && pdn->devfn == devfn | ||
| 123 | && of_device_available(dn)) | 122 | && of_device_available(dn)) |
| 124 | return rtas_read_config(dn, where, size, val); | 123 | return rtas_read_config(pdn, where, size, val); |
| 124 | } | ||
| 125 | 125 | ||
| 126 | return PCIBIOS_DEVICE_NOT_FOUND; | 126 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | int rtas_write_config(struct device_node *dn, int where, int size, u32 val) | 129 | int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val) |
| 130 | { | 130 | { |
| 131 | unsigned long buid, addr; | 131 | unsigned long buid, addr; |
| 132 | int ret; | 132 | int ret; |
| 133 | struct pci_dn *pdn; | ||
| 134 | 133 | ||
| 135 | if (!dn || !dn->data) | 134 | if (!pdn) |
| 136 | return PCIBIOS_DEVICE_NOT_FOUND; | 135 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 137 | pdn = dn->data; | ||
| 138 | if (!config_access_valid(pdn, where)) | 136 | if (!config_access_valid(pdn, where)) |
| 139 | return PCIBIOS_BAD_REGISTER_NUMBER; | 137 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 140 | 138 | ||
| @@ -142,7 +140,8 @@ int rtas_write_config(struct device_node *dn, int where, int size, u32 val) | |||
| 142 | (pdn->devfn << 8) | (where & 0xff); | 140 | (pdn->devfn << 8) | (where & 0xff); |
| 143 | buid = pdn->phb->buid; | 141 | buid = pdn->phb->buid; |
| 144 | if (buid) { | 142 | if (buid) { |
| 145 | ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val); | 143 | ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, |
| 144 | BUID_HI(buid), BUID_LO(buid), size, (ulong) val); | ||
| 146 | } else { | 145 | } else { |
| 147 | ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val); | 146 | ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val); |
| 148 | } | 147 | } |
| @@ -165,10 +164,12 @@ static int rtas_pci_write_config(struct pci_bus *bus, | |||
| 165 | busdn = bus->sysdata; /* must be a phb */ | 164 | busdn = bus->sysdata; /* must be a phb */ |
| 166 | 165 | ||
| 167 | /* Search only direct children of the bus */ | 166 | /* Search only direct children of the bus */ |
| 168 | for (dn = busdn->child; dn; dn = dn->sibling) | 167 | for (dn = busdn->child; dn; dn = dn->sibling) { |
| 169 | if (dn->data && PCI_DN(dn)->devfn == devfn | 168 | struct pci_dn *pdn = PCI_DN(dn); |
| 169 | if (pdn && pdn->devfn == devfn | ||
| 170 | && of_device_available(dn)) | 170 | && of_device_available(dn)) |
| 171 | return rtas_write_config(dn, where, size, val); | 171 | return rtas_write_config(pdn, where, size, val); |
| 172 | } | ||
| 172 | return PCIBIOS_DEVICE_NOT_FOUND; | 173 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 173 | } | 174 | } |
| 174 | 175 | ||
| @@ -221,7 +222,7 @@ static void python_countermeasures(struct device_node *dev, | |||
| 221 | /* Python's register file is 1 MB in size. */ | 222 | /* Python's register file is 1 MB in size. */ |
| 222 | chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000); | 223 | chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000); |
| 223 | 224 | ||
| 224 | /* | 225 | /* |
| 225 | * Firmware doesn't always clear this bit which is critical | 226 | * Firmware doesn't always clear this bit which is critical |
| 226 | * for good performance - Anton | 227 | * for good performance - Anton |
| 227 | */ | 228 | */ |
| @@ -292,7 +293,7 @@ static int phb_set_bus_ranges(struct device_node *dev, | |||
| 292 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 293 | if (bus_range == NULL || len < 2 * sizeof(int)) { |
| 293 | return 1; | 294 | return 1; |
| 294 | } | 295 | } |
| 295 | 296 | ||
| 296 | phb->first_busno = bus_range[0]; | 297 | phb->first_busno = bus_range[0]; |
| 297 | phb->last_busno = bus_range[1]; | 298 | phb->last_busno = bus_range[1]; |
| 298 | 299 | ||
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index e22856ecb5a0..bae4bff138f1 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <asm/io.h> | 33 | #include <asm/io.h> |
| 34 | #include <asm/prom.h> | 34 | #include <asm/prom.h> |
| 35 | #include <asm/processor.h> | 35 | #include <asm/processor.h> |
| 36 | #include <asm/systemcfg.h> | ||
| 36 | #include <asm/pgtable.h> | 37 | #include <asm/pgtable.h> |
| 37 | #include <asm/smp.h> | 38 | #include <asm/smp.h> |
| 38 | #include <asm/elf.h> | 39 | #include <asm/elf.h> |
| @@ -51,6 +52,9 @@ | |||
| 51 | #include <asm/page.h> | 52 | #include <asm/page.h> |
| 52 | #include <asm/mmu.h> | 53 | #include <asm/mmu.h> |
| 53 | #include <asm/lmb.h> | 54 | #include <asm/lmb.h> |
| 55 | #include <asm/xmon.h> | ||
| 56 | |||
| 57 | #include "setup.h" | ||
| 54 | 58 | ||
| 55 | #undef DEBUG | 59 | #undef DEBUG |
| 56 | 60 | ||
| @@ -60,6 +64,13 @@ | |||
| 60 | #define DBG(fmt...) | 64 | #define DBG(fmt...) |
| 61 | #endif | 65 | #endif |
| 62 | 66 | ||
| 67 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
| 68 | int _machine = 0; | ||
| 69 | EXPORT_SYMBOL(_machine); | ||
| 70 | #endif | ||
| 71 | |||
| 72 | unsigned long klimit = (unsigned long) _end; | ||
| 73 | |||
| 63 | /* | 74 | /* |
| 64 | * This still seems to be needed... -- paulus | 75 | * This still seems to be needed... -- paulus |
| 65 | */ | 76 | */ |
| @@ -510,8 +521,8 @@ void __init smp_setup_cpu_maps(void) | |||
| 510 | * On pSeries LPAR, we need to know how many cpus | 521 | * On pSeries LPAR, we need to know how many cpus |
| 511 | * could possibly be added to this partition. | 522 | * could possibly be added to this partition. |
| 512 | */ | 523 | */ |
| 513 | if (systemcfg->platform == PLATFORM_PSERIES_LPAR && | 524 | if (_machine == PLATFORM_PSERIES_LPAR && |
| 514 | (dn = of_find_node_by_path("/rtas"))) { | 525 | (dn = of_find_node_by_path("/rtas"))) { |
| 515 | int num_addr_cell, num_size_cell, maxcpus; | 526 | int num_addr_cell, num_size_cell, maxcpus; |
| 516 | unsigned int *ireg; | 527 | unsigned int *ireg; |
| 517 | 528 | ||
| @@ -555,7 +566,27 @@ void __init smp_setup_cpu_maps(void) | |||
| 555 | cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); | 566 | cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); |
| 556 | } | 567 | } |
| 557 | 568 | ||
| 558 | systemcfg->processorCount = num_present_cpus(); | 569 | _systemcfg->processorCount = num_present_cpus(); |
| 559 | #endif /* CONFIG_PPC64 */ | 570 | #endif /* CONFIG_PPC64 */ |
| 560 | } | 571 | } |
| 561 | #endif /* CONFIG_SMP */ | 572 | #endif /* CONFIG_SMP */ |
| 573 | |||
| 574 | #ifdef CONFIG_XMON | ||
| 575 | static int __init early_xmon(char *p) | ||
| 576 | { | ||
| 577 | /* ensure xmon is enabled */ | ||
| 578 | if (p) { | ||
| 579 | if (strncmp(p, "on", 2) == 0) | ||
| 580 | xmon_init(1); | ||
| 581 | if (strncmp(p, "off", 3) == 0) | ||
| 582 | xmon_init(0); | ||
| 583 | if (strncmp(p, "early", 5) != 0) | ||
| 584 | return 0; | ||
| 585 | } | ||
| 586 | xmon_init(1); | ||
| 587 | debugger(NULL); | ||
| 588 | |||
| 589 | return 0; | ||
| 590 | } | ||
| 591 | early_param("xmon", early_xmon); | ||
| 592 | #endif | ||
diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h new file mode 100644 index 000000000000..2ebba755272e --- /dev/null +++ b/arch/powerpc/kernel/setup.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #ifndef _POWERPC_KERNEL_SETUP_H | ||
| 2 | #define _POWERPC_KERNEL_SETUP_H | ||
| 3 | |||
| 4 | void check_for_initrd(void); | ||
| 5 | |||
| 6 | #endif /* _POWERPC_KERNEL_SETUP_H */ | ||
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 3af2631e3fab..c98cfcc9cd9a 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
| @@ -40,6 +40,8 @@ | |||
| 40 | #include <asm/xmon.h> | 40 | #include <asm/xmon.h> |
| 41 | #include <asm/time.h> | 41 | #include <asm/time.h> |
| 42 | 42 | ||
| 43 | #include "setup.h" | ||
| 44 | |||
| 43 | #define DBG(fmt...) | 45 | #define DBG(fmt...) |
| 44 | 46 | ||
| 45 | #if defined CONFIG_KGDB | 47 | #if defined CONFIG_KGDB |
| @@ -70,8 +72,6 @@ unsigned int DMA_MODE_WRITE; | |||
| 70 | int have_of = 1; | 72 | int have_of = 1; |
| 71 | 73 | ||
| 72 | #ifdef CONFIG_PPC_MULTIPLATFORM | 74 | #ifdef CONFIG_PPC_MULTIPLATFORM |
| 73 | int _machine = 0; | ||
| 74 | |||
| 75 | extern void prep_init(void); | 75 | extern void prep_init(void); |
| 76 | extern void pmac_init(void); | 76 | extern void pmac_init(void); |
| 77 | extern void chrp_init(void); | 77 | extern void chrp_init(void); |
| @@ -279,7 +279,6 @@ arch_initcall(ppc_init); | |||
| 279 | /* Warning, IO base is not yet inited */ | 279 | /* Warning, IO base is not yet inited */ |
| 280 | void __init setup_arch(char **cmdline_p) | 280 | void __init setup_arch(char **cmdline_p) |
| 281 | { | 281 | { |
| 282 | extern char *klimit; | ||
| 283 | extern void do_init_bootmem(void); | 282 | extern void do_init_bootmem(void); |
| 284 | 283 | ||
| 285 | /* so udelay does something sensible, assume <= 1000 bogomips */ | 284 | /* so udelay does something sensible, assume <= 1000 bogomips */ |
| @@ -303,14 +302,9 @@ void __init setup_arch(char **cmdline_p) | |||
| 303 | pmac_feature_init(); /* New cool way */ | 302 | pmac_feature_init(); /* New cool way */ |
| 304 | #endif | 303 | #endif |
| 305 | 304 | ||
| 306 | #ifdef CONFIG_XMON | 305 | #ifdef CONFIG_XMON_DEFAULT |
| 307 | xmon_map_scc(); | 306 | xmon_init(1); |
| 308 | if (strstr(cmd_line, "xmon")) { | 307 | #endif |
| 309 | xmon_init(1); | ||
| 310 | debugger(NULL); | ||
| 311 | } | ||
| 312 | #endif /* CONFIG_XMON */ | ||
| 313 | if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab); | ||
| 314 | 308 | ||
| 315 | #if defined(CONFIG_KGDB) | 309 | #if defined(CONFIG_KGDB) |
| 316 | if (ppc_md.kgdb_map_scc) | 310 | if (ppc_md.kgdb_map_scc) |
| @@ -343,7 +337,7 @@ void __init setup_arch(char **cmdline_p) | |||
| 343 | init_mm.start_code = PAGE_OFFSET; | 337 | init_mm.start_code = PAGE_OFFSET; |
| 344 | init_mm.end_code = (unsigned long) _etext; | 338 | init_mm.end_code = (unsigned long) _etext; |
| 345 | init_mm.end_data = (unsigned long) _edata; | 339 | init_mm.end_data = (unsigned long) _edata; |
| 346 | init_mm.brk = (unsigned long) klimit; | 340 | init_mm.brk = klimit; |
| 347 | 341 | ||
| 348 | /* Save unparsed command line copy for /proc/cmdline */ | 342 | /* Save unparsed command line copy for /proc/cmdline */ |
| 349 | strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); | 343 | strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 0471e843b6c5..6791668213e7 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
| @@ -61,6 +61,8 @@ | |||
| 61 | #include <asm/xmon.h> | 61 | #include <asm/xmon.h> |
| 62 | #include <asm/udbg.h> | 62 | #include <asm/udbg.h> |
| 63 | 63 | ||
| 64 | #include "setup.h" | ||
| 65 | |||
| 64 | #ifdef DEBUG | 66 | #ifdef DEBUG |
| 65 | #define DBG(fmt...) udbg_printf(fmt) | 67 | #define DBG(fmt...) udbg_printf(fmt) |
| 66 | #else | 68 | #else |
| @@ -94,15 +96,6 @@ extern void udbg_init_maple_realmode(void); | |||
| 94 | do { udbg_putc = call_rtas_display_status_delay; } while(0) | 96 | do { udbg_putc = call_rtas_display_status_delay; } while(0) |
| 95 | #endif | 97 | #endif |
| 96 | 98 | ||
| 97 | /* extern void *stab; */ | ||
| 98 | extern unsigned long klimit; | ||
| 99 | |||
| 100 | extern void mm_init_ppc64(void); | ||
| 101 | extern void stab_initialize(unsigned long stab); | ||
| 102 | extern void htab_initialize(void); | ||
| 103 | extern void early_init_devtree(void *flat_dt); | ||
| 104 | extern void unflatten_device_tree(void); | ||
| 105 | |||
| 106 | int have_of = 1; | 99 | int have_of = 1; |
| 107 | int boot_cpuid = 0; | 100 | int boot_cpuid = 0; |
| 108 | int boot_cpuid_phys = 0; | 101 | int boot_cpuid_phys = 0; |
| @@ -254,11 +247,10 @@ void __init early_setup(unsigned long dt_ptr) | |||
| 254 | * Iterate all ppc_md structures until we find the proper | 247 | * Iterate all ppc_md structures until we find the proper |
| 255 | * one for the current machine type | 248 | * one for the current machine type |
| 256 | */ | 249 | */ |
| 257 | DBG("Probing machine type for platform %x...\n", | 250 | DBG("Probing machine type for platform %x...\n", _machine); |
| 258 | systemcfg->platform); | ||
| 259 | 251 | ||
| 260 | for (mach = machines; *mach; mach++) { | 252 | for (mach = machines; *mach; mach++) { |
| 261 | if ((*mach)->probe(systemcfg->platform)) | 253 | if ((*mach)->probe(_machine)) |
| 262 | break; | 254 | break; |
| 263 | } | 255 | } |
| 264 | /* What can we do if we didn't find ? */ | 256 | /* What can we do if we didn't find ? */ |
| @@ -290,6 +282,28 @@ void __init early_setup(unsigned long dt_ptr) | |||
| 290 | DBG(" <- early_setup()\n"); | 282 | DBG(" <- early_setup()\n"); |
| 291 | } | 283 | } |
| 292 | 284 | ||
| 285 | #ifdef CONFIG_SMP | ||
| 286 | void early_setup_secondary(void) | ||
| 287 | { | ||
| 288 | struct paca_struct *lpaca = get_paca(); | ||
| 289 | |||
| 290 | /* Mark enabled in PACA */ | ||
| 291 | lpaca->proc_enabled = 0; | ||
| 292 | |||
| 293 | /* Initialize hash table for that CPU */ | ||
| 294 | htab_initialize_secondary(); | ||
| 295 | |||
| 296 | /* Initialize STAB/SLB. We use a virtual address as it works | ||
| 297 | * in real mode on pSeries and we want a virutal address on | ||
| 298 | * iSeries anyway | ||
| 299 | */ | ||
| 300 | if (cpu_has_feature(CPU_FTR_SLB)) | ||
| 301 | slb_initialize(); | ||
| 302 | else | ||
| 303 | stab_initialize(lpaca->stab_addr); | ||
| 304 | } | ||
| 305 | |||
| 306 | #endif /* CONFIG_SMP */ | ||
| 293 | 307 | ||
| 294 | #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) | 308 | #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) |
| 295 | void smp_release_cpus(void) | 309 | void smp_release_cpus(void) |
| @@ -315,7 +329,8 @@ void smp_release_cpus(void) | |||
| 315 | #endif /* CONFIG_SMP || CONFIG_KEXEC */ | 329 | #endif /* CONFIG_SMP || CONFIG_KEXEC */ |
| 316 | 330 | ||
| 317 | /* | 331 | /* |
| 318 | * Initialize some remaining members of the ppc64_caches and systemcfg structures | 332 | * Initialize some remaining members of the ppc64_caches and systemcfg |
| 333 | * structures | ||
| 319 | * (at least until we get rid of them completely). This is mostly some | 334 | * (at least until we get rid of them completely). This is mostly some |
| 320 | * cache informations about the CPU that will be used by cache flush | 335 | * cache informations about the CPU that will be used by cache flush |
| 321 | * routines and/or provided to userland | 336 | * routines and/or provided to userland |
| @@ -340,7 +355,7 @@ static void __init initialize_cache_info(void) | |||
| 340 | const char *dc, *ic; | 355 | const char *dc, *ic; |
| 341 | 356 | ||
| 342 | /* Then read cache informations */ | 357 | /* Then read cache informations */ |
| 343 | if (systemcfg->platform == PLATFORM_POWERMAC) { | 358 | if (_machine == PLATFORM_POWERMAC) { |
| 344 | dc = "d-cache-block-size"; | 359 | dc = "d-cache-block-size"; |
| 345 | ic = "i-cache-block-size"; | 360 | ic = "i-cache-block-size"; |
| 346 | } else { | 361 | } else { |
| @@ -360,8 +375,8 @@ static void __init initialize_cache_info(void) | |||
| 360 | DBG("Argh, can't find dcache properties ! " | 375 | DBG("Argh, can't find dcache properties ! " |
| 361 | "sizep: %p, lsizep: %p\n", sizep, lsizep); | 376 | "sizep: %p, lsizep: %p\n", sizep, lsizep); |
| 362 | 377 | ||
| 363 | systemcfg->dcache_size = ppc64_caches.dsize = size; | 378 | _systemcfg->dcache_size = ppc64_caches.dsize = size; |
| 364 | systemcfg->dcache_line_size = | 379 | _systemcfg->dcache_line_size = |
| 365 | ppc64_caches.dline_size = lsize; | 380 | ppc64_caches.dline_size = lsize; |
| 366 | ppc64_caches.log_dline_size = __ilog2(lsize); | 381 | ppc64_caches.log_dline_size = __ilog2(lsize); |
| 367 | ppc64_caches.dlines_per_page = PAGE_SIZE / lsize; | 382 | ppc64_caches.dlines_per_page = PAGE_SIZE / lsize; |
| @@ -378,8 +393,8 @@ static void __init initialize_cache_info(void) | |||
| 378 | DBG("Argh, can't find icache properties ! " | 393 | DBG("Argh, can't find icache properties ! " |
| 379 | "sizep: %p, lsizep: %p\n", sizep, lsizep); | 394 | "sizep: %p, lsizep: %p\n", sizep, lsizep); |
| 380 | 395 | ||
| 381 | systemcfg->icache_size = ppc64_caches.isize = size; | 396 | _systemcfg->icache_size = ppc64_caches.isize = size; |
| 382 | systemcfg->icache_line_size = | 397 | _systemcfg->icache_line_size = |
| 383 | ppc64_caches.iline_size = lsize; | 398 | ppc64_caches.iline_size = lsize; |
| 384 | ppc64_caches.log_iline_size = __ilog2(lsize); | 399 | ppc64_caches.log_iline_size = __ilog2(lsize); |
| 385 | ppc64_caches.ilines_per_page = PAGE_SIZE / lsize; | 400 | ppc64_caches.ilines_per_page = PAGE_SIZE / lsize; |
| @@ -387,10 +402,12 @@ static void __init initialize_cache_info(void) | |||
| 387 | } | 402 | } |
| 388 | 403 | ||
| 389 | /* Add an eye catcher and the systemcfg layout version number */ | 404 | /* Add an eye catcher and the systemcfg layout version number */ |
| 390 | strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64"); | 405 | strcpy(_systemcfg->eye_catcher, "SYSTEMCFG:PPC64"); |
| 391 | systemcfg->version.major = SYSTEMCFG_MAJOR; | 406 | _systemcfg->version.major = SYSTEMCFG_MAJOR; |
| 392 | systemcfg->version.minor = SYSTEMCFG_MINOR; | 407 | _systemcfg->version.minor = SYSTEMCFG_MINOR; |
| 393 | systemcfg->processor = mfspr(SPRN_PVR); | 408 | _systemcfg->processor = mfspr(SPRN_PVR); |
| 409 | _systemcfg->platform = _machine; | ||
| 410 | _systemcfg->physicalMemorySize = lmb_phys_mem_size(); | ||
| 394 | 411 | ||
| 395 | DBG(" <- initialize_cache_info()\n"); | 412 | DBG(" <- initialize_cache_info()\n"); |
| 396 | } | 413 | } |
| @@ -479,10 +496,10 @@ void __init setup_system(void) | |||
| 479 | printk("-----------------------------------------------------\n"); | 496 | printk("-----------------------------------------------------\n"); |
| 480 | printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); | 497 | printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); |
| 481 | printk("ppc64_interrupt_controller = 0x%ld\n", ppc64_interrupt_controller); | 498 | printk("ppc64_interrupt_controller = 0x%ld\n", ppc64_interrupt_controller); |
| 482 | printk("systemcfg = 0x%p\n", systemcfg); | 499 | printk("systemcfg = 0x%p\n", _systemcfg); |
| 483 | printk("systemcfg->platform = 0x%x\n", systemcfg->platform); | 500 | printk("systemcfg->platform = 0x%x\n", _systemcfg->platform); |
| 484 | printk("systemcfg->processorCount = 0x%lx\n", systemcfg->processorCount); | 501 | printk("systemcfg->processorCount = 0x%lx\n", _systemcfg->processorCount); |
| 485 | printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize); | 502 | printk("systemcfg->physicalMemorySize = 0x%lx\n", _systemcfg->physicalMemorySize); |
| 486 | printk("ppc64_caches.dcache_line_size = 0x%x\n", | 503 | printk("ppc64_caches.dcache_line_size = 0x%x\n", |
| 487 | ppc64_caches.dline_size); | 504 | ppc64_caches.dline_size); |
| 488 | printk("ppc64_caches.icache_line_size = 0x%x\n", | 505 | printk("ppc64_caches.icache_line_size = 0x%x\n", |
| @@ -564,12 +581,12 @@ void __init setup_syscall_map(void) | |||
| 564 | for (i = 0; i < __NR_syscalls; i++) { | 581 | for (i = 0; i < __NR_syscalls; i++) { |
| 565 | if (sys_call_table[i*2] != sys_ni_syscall) { | 582 | if (sys_call_table[i*2] != sys_ni_syscall) { |
| 566 | count64++; | 583 | count64++; |
| 567 | systemcfg->syscall_map_64[i >> 5] |= | 584 | _systemcfg->syscall_map_64[i >> 5] |= |
| 568 | 0x80000000UL >> (i & 0x1f); | 585 | 0x80000000UL >> (i & 0x1f); |
| 569 | } | 586 | } |
| 570 | if (sys_call_table[i*2+1] != sys_ni_syscall) { | 587 | if (sys_call_table[i*2+1] != sys_ni_syscall) { |
| 571 | count32++; | 588 | count32++; |
| 572 | systemcfg->syscall_map_32[i >> 5] |= | 589 | _systemcfg->syscall_map_32[i >> 5] |= |
| 573 | 0x80000000UL >> (i & 0x1f); | 590 | 0x80000000UL >> (i & 0x1f); |
| 574 | } | 591 | } |
| 575 | } | 592 | } |
| @@ -858,26 +875,6 @@ int check_legacy_ioport(unsigned long base_port) | |||
| 858 | } | 875 | } |
| 859 | EXPORT_SYMBOL(check_legacy_ioport); | 876 | EXPORT_SYMBOL(check_legacy_ioport); |
| 860 | 877 | ||
| 861 | #ifdef CONFIG_XMON | ||
| 862 | static int __init early_xmon(char *p) | ||
| 863 | { | ||
| 864 | /* ensure xmon is enabled */ | ||
| 865 | if (p) { | ||
| 866 | if (strncmp(p, "on", 2) == 0) | ||
| 867 | xmon_init(1); | ||
| 868 | if (strncmp(p, "off", 3) == 0) | ||
| 869 | xmon_init(0); | ||
| 870 | if (strncmp(p, "early", 5) != 0) | ||
| 871 | return 0; | ||
| 872 | } | ||
| 873 | xmon_init(1); | ||
| 874 | debugger(NULL); | ||
| 875 | |||
| 876 | return 0; | ||
| 877 | } | ||
| 878 | early_param("xmon", early_xmon); | ||
| 879 | #endif | ||
| 880 | |||
| 881 | void cpu_die(void) | 878 | void cpu_die(void) |
| 882 | { | 879 | { |
| 883 | if (ppc_md.cpu_die) | 880 | if (ppc_md.cpu_die) |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 081d931eae48..a7c4515f320f 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | 42 | ||
| 43 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
| 44 | #include <asm/cacheflush.h> | 44 | #include <asm/cacheflush.h> |
| 45 | #include <asm/sigcontext.h> | ||
| 45 | #ifdef CONFIG_PPC64 | 46 | #ifdef CONFIG_PPC64 |
| 46 | #include "ppc32.h" | 47 | #include "ppc32.h" |
| 47 | #include <asm/unistd.h> | 48 | #include <asm/unistd.h> |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 36d67a8d7cbb..e28a139c29d0 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <asm/cputable.h> | 44 | #include <asm/cputable.h> |
| 45 | #include <asm/system.h> | 45 | #include <asm/system.h> |
| 46 | #include <asm/mpic.h> | 46 | #include <asm/mpic.h> |
| 47 | #include <asm/systemcfg.h> | ||
| 47 | #ifdef CONFIG_PPC64 | 48 | #ifdef CONFIG_PPC64 |
| 48 | #include <asm/paca.h> | 49 | #include <asm/paca.h> |
| 49 | #endif | 50 | #endif |
| @@ -368,9 +369,11 @@ int generic_cpu_disable(void) | |||
| 368 | if (cpu == boot_cpuid) | 369 | if (cpu == boot_cpuid) |
| 369 | return -EBUSY; | 370 | return -EBUSY; |
| 370 | 371 | ||
| 371 | systemcfg->processorCount--; | ||
| 372 | cpu_clear(cpu, cpu_online_map); | 372 | cpu_clear(cpu, cpu_online_map); |
| 373 | #ifdef CONFIG_PPC64 | ||
| 374 | _systemcfg->processorCount--; | ||
| 373 | fixup_irqs(cpu_online_map); | 375 | fixup_irqs(cpu_online_map); |
| 376 | #endif | ||
| 374 | return 0; | 377 | return 0; |
| 375 | } | 378 | } |
| 376 | 379 | ||
| @@ -388,9 +391,11 @@ int generic_cpu_enable(unsigned int cpu) | |||
| 388 | while (!cpu_online(cpu)) | 391 | while (!cpu_online(cpu)) |
| 389 | cpu_relax(); | 392 | cpu_relax(); |
| 390 | 393 | ||
| 394 | #ifdef CONFIG_PPC64 | ||
| 391 | fixup_irqs(cpu_online_map); | 395 | fixup_irqs(cpu_online_map); |
| 392 | /* counter the irq disable in fixup_irqs */ | 396 | /* counter the irq disable in fixup_irqs */ |
| 393 | local_irq_enable(); | 397 | local_irq_enable(); |
| 398 | #endif | ||
| 394 | return 0; | 399 | return 0; |
| 395 | } | 400 | } |
| 396 | 401 | ||
| @@ -419,7 +424,9 @@ void generic_mach_cpu_die(void) | |||
| 419 | while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) | 424 | while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) |
| 420 | cpu_relax(); | 425 | cpu_relax(); |
| 421 | 426 | ||
| 427 | #ifdef CONFIG_PPC64 | ||
| 422 | flush_tlb_pending(); | 428 | flush_tlb_pending(); |
| 429 | #endif | ||
| 423 | cpu_set(cpu, cpu_online_map); | 430 | cpu_set(cpu, cpu_online_map); |
| 424 | local_irq_enable(); | 431 | local_irq_enable(); |
| 425 | } | 432 | } |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index a8210ed5c686..9c921d1c4084 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
| @@ -52,7 +52,6 @@ | |||
| 52 | #include <asm/semaphore.h> | 52 | #include <asm/semaphore.h> |
| 53 | #include <asm/time.h> | 53 | #include <asm/time.h> |
| 54 | #include <asm/mmu_context.h> | 54 | #include <asm/mmu_context.h> |
| 55 | #include <asm/systemcfg.h> | ||
| 56 | #include <asm/ppc-pci.h> | 55 | #include <asm/ppc-pci.h> |
| 57 | 56 | ||
| 58 | /* readdir & getdents */ | 57 | /* readdir & getdents */ |
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index e99ec62c2c52..850af198fb5f 100644 --- a/arch/ppc64/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
| @@ -232,7 +232,7 @@ static void register_cpu_online(unsigned int cpu) | |||
| 232 | sysdev_create_file(s, &attr_pmc7); | 232 | sysdev_create_file(s, &attr_pmc7); |
| 233 | if (cur_cpu_spec->num_pmcs >= 8) | 233 | if (cur_cpu_spec->num_pmcs >= 8) |
| 234 | sysdev_create_file(s, &attr_pmc8); | 234 | sysdev_create_file(s, &attr_pmc8); |
| 235 | 235 | ||
| 236 | if (cpu_has_feature(CPU_FTR_SMT)) | 236 | if (cpu_has_feature(CPU_FTR_SMT)) |
| 237 | sysdev_create_file(s, &attr_purr); | 237 | sysdev_create_file(s, &attr_purr); |
| 238 | } | 238 | } |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index a6282b625b44..260b6ecd26a9 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
| @@ -271,13 +271,13 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, | |||
| 271 | * tb_to_xs and stamp_xsec values are consistent. If not, then it | 271 | * tb_to_xs and stamp_xsec values are consistent. If not, then it |
| 272 | * loops back and reads them again until this criteria is met. | 272 | * loops back and reads them again until this criteria is met. |
| 273 | */ | 273 | */ |
| 274 | ++(systemcfg->tb_update_count); | 274 | ++(_systemcfg->tb_update_count); |
| 275 | smp_wmb(); | 275 | smp_wmb(); |
| 276 | systemcfg->tb_orig_stamp = new_tb_stamp; | 276 | _systemcfg->tb_orig_stamp = new_tb_stamp; |
| 277 | systemcfg->stamp_xsec = new_stamp_xsec; | 277 | _systemcfg->stamp_xsec = new_stamp_xsec; |
| 278 | systemcfg->tb_to_xs = new_tb_to_xs; | 278 | _systemcfg->tb_to_xs = new_tb_to_xs; |
| 279 | smp_wmb(); | 279 | smp_wmb(); |
| 280 | ++(systemcfg->tb_update_count); | 280 | ++(_systemcfg->tb_update_count); |
| 281 | #endif | 281 | #endif |
| 282 | } | 282 | } |
| 283 | 283 | ||
| @@ -357,8 +357,9 @@ static void iSeries_tb_recal(void) | |||
| 357 | do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; | 357 | do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; |
| 358 | tb_to_xs = divres.result_low; | 358 | tb_to_xs = divres.result_low; |
| 359 | do_gtod.varp->tb_to_xs = tb_to_xs; | 359 | do_gtod.varp->tb_to_xs = tb_to_xs; |
| 360 | systemcfg->tb_ticks_per_sec = tb_ticks_per_sec; | 360 | _systemcfg->tb_ticks_per_sec = |
| 361 | systemcfg->tb_to_xs = tb_to_xs; | 361 | tb_ticks_per_sec; |
| 362 | _systemcfg->tb_to_xs = tb_to_xs; | ||
| 362 | } | 363 | } |
| 363 | else { | 364 | else { |
| 364 | printk( "Titan recalibrate: FAILED (difference > 4 percent)\n" | 365 | printk( "Titan recalibrate: FAILED (difference > 4 percent)\n" |
| @@ -483,6 +484,8 @@ void __init smp_space_timers(unsigned int max_cpus) | |||
| 483 | unsigned long offset = tb_ticks_per_jiffy / max_cpus; | 484 | unsigned long offset = tb_ticks_per_jiffy / max_cpus; |
| 484 | unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid); | 485 | unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid); |
| 485 | 486 | ||
| 487 | /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */ | ||
| 488 | previous_tb -= tb_ticks_per_jiffy; | ||
| 486 | for_each_cpu(i) { | 489 | for_each_cpu(i) { |
| 487 | if (i != boot_cpuid) { | 490 | if (i != boot_cpuid) { |
| 488 | previous_tb += offset; | 491 | previous_tb += offset; |
| @@ -559,8 +562,8 @@ int do_settimeofday(struct timespec *tv) | |||
| 559 | update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs); | 562 | update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs); |
| 560 | 563 | ||
| 561 | #ifdef CONFIG_PPC64 | 564 | #ifdef CONFIG_PPC64 |
| 562 | systemcfg->tz_minuteswest = sys_tz.tz_minuteswest; | 565 | _systemcfg->tz_minuteswest = sys_tz.tz_minuteswest; |
| 563 | systemcfg->tz_dsttime = sys_tz.tz_dsttime; | 566 | _systemcfg->tz_dsttime = sys_tz.tz_dsttime; |
| 564 | #endif | 567 | #endif |
| 565 | 568 | ||
| 566 | write_sequnlock_irqrestore(&xtime_lock, flags); | 569 | write_sequnlock_irqrestore(&xtime_lock, flags); |
| @@ -711,11 +714,11 @@ void __init time_init(void) | |||
| 711 | do_gtod.varp->tb_to_xs = tb_to_xs; | 714 | do_gtod.varp->tb_to_xs = tb_to_xs; |
| 712 | do_gtod.tb_to_us = tb_to_us; | 715 | do_gtod.tb_to_us = tb_to_us; |
| 713 | #ifdef CONFIG_PPC64 | 716 | #ifdef CONFIG_PPC64 |
| 714 | systemcfg->tb_orig_stamp = tb_last_jiffy; | 717 | _systemcfg->tb_orig_stamp = tb_last_jiffy; |
| 715 | systemcfg->tb_update_count = 0; | 718 | _systemcfg->tb_update_count = 0; |
| 716 | systemcfg->tb_ticks_per_sec = tb_ticks_per_sec; | 719 | _systemcfg->tb_ticks_per_sec = tb_ticks_per_sec; |
| 717 | systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; | 720 | _systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; |
| 718 | systemcfg->tb_to_xs = tb_to_xs; | 721 | _systemcfg->tb_to_xs = tb_to_xs; |
| 719 | #endif | 722 | #endif |
| 720 | 723 | ||
| 721 | time_freq = 0; | 724 | time_freq = 0; |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 0578f8387603..2020bb7648fb 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
| @@ -129,7 +129,7 @@ int die(const char *str, struct pt_regs *regs, long err) | |||
| 129 | nl = 1; | 129 | nl = 1; |
| 130 | #endif | 130 | #endif |
| 131 | #ifdef CONFIG_PPC64 | 131 | #ifdef CONFIG_PPC64 |
| 132 | switch (systemcfg->platform) { | 132 | switch (_machine) { |
| 133 | case PLATFORM_PSERIES: | 133 | case PLATFORM_PSERIES: |
| 134 | printk("PSERIES "); | 134 | printk("PSERIES "); |
| 135 | nl = 1; | 135 | nl = 1; |
diff --git a/arch/powerpc/lib/bitops.c b/arch/powerpc/lib/bitops.c index b67ce3004ebf..f68ad71a0187 100644 --- a/arch/powerpc/lib/bitops.c +++ b/arch/powerpc/lib/bitops.c | |||
| @@ -41,7 +41,7 @@ unsigned long find_next_bit(const unsigned long *addr, unsigned long size, | |||
| 41 | tmp = *p; | 41 | tmp = *p; |
| 42 | 42 | ||
| 43 | found_first: | 43 | found_first: |
| 44 | tmp &= (~0UL >> (64 - size)); | 44 | tmp &= (~0UL >> (BITS_PER_LONG - size)); |
| 45 | if (tmp == 0UL) /* Are any bits set? */ | 45 | if (tmp == 0UL) /* Are any bits set? */ |
| 46 | return result + size; /* Nope. */ | 46 | return result + size; /* Nope. */ |
| 47 | found_middle: | 47 | found_middle: |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 22e474876133..706e8a63ced9 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
| @@ -84,10 +84,11 @@ | |||
| 84 | extern unsigned long dart_tablebase; | 84 | extern unsigned long dart_tablebase; |
| 85 | #endif /* CONFIG_U3_DART */ | 85 | #endif /* CONFIG_U3_DART */ |
| 86 | 86 | ||
| 87 | static unsigned long _SDR1; | ||
| 88 | struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; | ||
| 89 | |||
| 87 | hpte_t *htab_address; | 90 | hpte_t *htab_address; |
| 88 | unsigned long htab_hash_mask; | 91 | unsigned long htab_hash_mask; |
| 89 | unsigned long _SDR1; | ||
| 90 | struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; | ||
| 91 | int mmu_linear_psize = MMU_PAGE_4K; | 92 | int mmu_linear_psize = MMU_PAGE_4K; |
| 92 | int mmu_virtual_psize = MMU_PAGE_4K; | 93 | int mmu_virtual_psize = MMU_PAGE_4K; |
| 93 | #ifdef CONFIG_HUGETLB_PAGE | 94 | #ifdef CONFIG_HUGETLB_PAGE |
| @@ -165,7 +166,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | |||
| 165 | * normal insert callback here. | 166 | * normal insert callback here. |
| 166 | */ | 167 | */ |
| 167 | #ifdef CONFIG_PPC_ISERIES | 168 | #ifdef CONFIG_PPC_ISERIES |
| 168 | if (systemcfg->platform == PLATFORM_ISERIES_LPAR) | 169 | if (_machine == PLATFORM_ISERIES_LPAR) |
| 169 | ret = iSeries_hpte_insert(hpteg, va, | 170 | ret = iSeries_hpte_insert(hpteg, va, |
| 170 | virt_to_abs(paddr), | 171 | virt_to_abs(paddr), |
| 171 | tmp_mode, | 172 | tmp_mode, |
| @@ -174,7 +175,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | |||
| 174 | else | 175 | else |
| 175 | #endif | 176 | #endif |
| 176 | #ifdef CONFIG_PPC_PSERIES | 177 | #ifdef CONFIG_PPC_PSERIES |
| 177 | if (systemcfg->platform & PLATFORM_LPAR) | 178 | if (_machine & PLATFORM_LPAR) |
| 178 | ret = pSeries_lpar_hpte_insert(hpteg, va, | 179 | ret = pSeries_lpar_hpte_insert(hpteg, va, |
| 179 | virt_to_abs(paddr), | 180 | virt_to_abs(paddr), |
| 180 | tmp_mode, | 181 | tmp_mode, |
| @@ -293,7 +294,7 @@ static void __init htab_init_page_sizes(void) | |||
| 293 | * Not in the device-tree, let's fallback on known size | 294 | * Not in the device-tree, let's fallback on known size |
| 294 | * list for 16M capable GP & GR | 295 | * list for 16M capable GP & GR |
| 295 | */ | 296 | */ |
| 296 | if ((systemcfg->platform != PLATFORM_ISERIES_LPAR) && | 297 | if ((_machine != PLATFORM_ISERIES_LPAR) && |
| 297 | cpu_has_feature(CPU_FTR_16M_PAGE)) | 298 | cpu_has_feature(CPU_FTR_16M_PAGE)) |
| 298 | memcpy(mmu_psize_defs, mmu_psize_defaults_gp, | 299 | memcpy(mmu_psize_defs, mmu_psize_defaults_gp, |
| 299 | sizeof(mmu_psize_defaults_gp)); | 300 | sizeof(mmu_psize_defaults_gp)); |
| @@ -364,7 +365,7 @@ static int __init htab_dt_scan_pftsize(unsigned long node, | |||
| 364 | 365 | ||
| 365 | static unsigned long __init htab_get_table_size(void) | 366 | static unsigned long __init htab_get_table_size(void) |
| 366 | { | 367 | { |
| 367 | unsigned long rnd_mem_size, pteg_count; | 368 | unsigned long mem_size, rnd_mem_size, pteg_count; |
| 368 | 369 | ||
| 369 | /* If hash size isn't already provided by the platform, we try to | 370 | /* If hash size isn't already provided by the platform, we try to |
| 370 | * retreive it from the device-tree. If it's not there neither, we | 371 | * retreive it from the device-tree. If it's not there neither, we |
| @@ -376,8 +377,9 @@ static unsigned long __init htab_get_table_size(void) | |||
| 376 | return 1UL << ppc64_pft_size; | 377 | return 1UL << ppc64_pft_size; |
| 377 | 378 | ||
| 378 | /* round mem_size up to next power of 2 */ | 379 | /* round mem_size up to next power of 2 */ |
| 379 | rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize); | 380 | mem_size = lmb_phys_mem_size(); |
| 380 | if (rnd_mem_size < systemcfg->physicalMemorySize) | 381 | rnd_mem_size = 1UL << __ilog2(mem_size); |
| 382 | if (rnd_mem_size < mem_size) | ||
| 381 | rnd_mem_size <<= 1; | 383 | rnd_mem_size <<= 1; |
| 382 | 384 | ||
| 383 | /* # pages / 2 */ | 385 | /* # pages / 2 */ |
| @@ -386,6 +388,15 @@ static unsigned long __init htab_get_table_size(void) | |||
| 386 | return pteg_count << 7; | 388 | return pteg_count << 7; |
| 387 | } | 389 | } |
| 388 | 390 | ||
| 391 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
| 392 | void create_section_mapping(unsigned long start, unsigned long end) | ||
| 393 | { | ||
| 394 | BUG_ON(htab_bolt_mapping(start, end, start, | ||
| 395 | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX, | ||
| 396 | mmu_linear_psize)); | ||
| 397 | } | ||
| 398 | #endif /* CONFIG_MEMORY_HOTPLUG */ | ||
| 399 | |||
| 389 | void __init htab_initialize(void) | 400 | void __init htab_initialize(void) |
| 390 | { | 401 | { |
| 391 | unsigned long table, htab_size_bytes; | 402 | unsigned long table, htab_size_bytes; |
| @@ -410,7 +421,7 @@ void __init htab_initialize(void) | |||
| 410 | 421 | ||
| 411 | htab_hash_mask = pteg_count - 1; | 422 | htab_hash_mask = pteg_count - 1; |
| 412 | 423 | ||
| 413 | if (systemcfg->platform & PLATFORM_LPAR) { | 424 | if (platform_is_lpar()) { |
| 414 | /* Using a hypervisor which owns the htab */ | 425 | /* Using a hypervisor which owns the htab */ |
| 415 | htab_address = NULL; | 426 | htab_address = NULL; |
| 416 | _SDR1 = 0; | 427 | _SDR1 = 0; |
| @@ -431,6 +442,9 @@ void __init htab_initialize(void) | |||
| 431 | 442 | ||
| 432 | /* Initialize the HPT with no entries */ | 443 | /* Initialize the HPT with no entries */ |
| 433 | memset((void *)table, 0, htab_size_bytes); | 444 | memset((void *)table, 0, htab_size_bytes); |
| 445 | |||
| 446 | /* Set SDR1 */ | ||
| 447 | mtspr(SPRN_SDR1, _SDR1); | ||
| 434 | } | 448 | } |
| 435 | 449 | ||
| 436 | mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX; | 450 | mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX; |
| @@ -500,6 +514,12 @@ void __init htab_initialize(void) | |||
| 500 | #undef KB | 514 | #undef KB |
| 501 | #undef MB | 515 | #undef MB |
| 502 | 516 | ||
| 517 | void __init htab_initialize_secondary(void) | ||
| 518 | { | ||
| 519 | if (!platform_is_lpar()) | ||
| 520 | mtspr(SPRN_SDR1, _SDR1); | ||
| 521 | } | ||
| 522 | |||
| 503 | /* | 523 | /* |
| 504 | * Called by asm hashtable.S for doing lazy icache flush | 524 | * Called by asm hashtable.S for doing lazy icache flush |
| 505 | */ | 525 | */ |
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 4612a79dfb6e..7d4b8b5f0606 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c | |||
| @@ -84,9 +84,6 @@ void MMU_init(void); | |||
| 84 | /* XXX should be in current.h -- paulus */ | 84 | /* XXX should be in current.h -- paulus */ |
| 85 | extern struct task_struct *current_set[NR_CPUS]; | 85 | extern struct task_struct *current_set[NR_CPUS]; |
| 86 | 86 | ||
| 87 | char *klimit = _end; | ||
| 88 | struct device_node *memory_node; | ||
| 89 | |||
| 90 | extern int init_bootmem_done; | 87 | extern int init_bootmem_done; |
| 91 | 88 | ||
| 92 | /* | 89 | /* |
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index ce974c83d88a..1134f70f231d 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c | |||
| @@ -20,6 +20,8 @@ | |||
| 20 | * | 20 | * |
| 21 | */ | 21 | */ |
| 22 | 22 | ||
| 23 | #undef DEBUG | ||
| 24 | |||
| 23 | #include <linux/config.h> | 25 | #include <linux/config.h> |
| 24 | #include <linux/signal.h> | 26 | #include <linux/signal.h> |
| 25 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
| @@ -64,6 +66,12 @@ | |||
| 64 | #include <asm/vdso.h> | 66 | #include <asm/vdso.h> |
| 65 | #include <asm/imalloc.h> | 67 | #include <asm/imalloc.h> |
| 66 | 68 | ||
| 69 | #ifdef DEBUG | ||
| 70 | #define DBG(fmt...) printk(fmt) | ||
| 71 | #else | ||
| 72 | #define DBG(fmt...) | ||
| 73 | #endif | ||
| 74 | |||
| 67 | #if PGTABLE_RANGE > USER_VSID_RANGE | 75 | #if PGTABLE_RANGE > USER_VSID_RANGE |
| 68 | #warning Limited user VSID range means pagetable space is wasted | 76 | #warning Limited user VSID range means pagetable space is wasted |
| 69 | #endif | 77 | #endif |
| @@ -72,8 +80,6 @@ | |||
| 72 | #warning TASK_SIZE is smaller than it needs to be. | 80 | #warning TASK_SIZE is smaller than it needs to be. |
| 73 | #endif | 81 | #endif |
| 74 | 82 | ||
| 75 | unsigned long klimit = (unsigned long)_end; | ||
| 76 | |||
| 77 | /* max amount of RAM to use */ | 83 | /* max amount of RAM to use */ |
| 78 | unsigned long __max_memory; | 84 | unsigned long __max_memory; |
| 79 | 85 | ||
| @@ -188,14 +194,14 @@ static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags) | |||
| 188 | } | 194 | } |
| 189 | 195 | ||
| 190 | #ifdef CONFIG_PPC_64K_PAGES | 196 | #ifdef CONFIG_PPC_64K_PAGES |
| 191 | static const int pgtable_cache_size[2] = { | 197 | static const unsigned int pgtable_cache_size[3] = { |
| 192 | PTE_TABLE_SIZE, PGD_TABLE_SIZE | 198 | PTE_TABLE_SIZE, PMD_TABLE_SIZE, PGD_TABLE_SIZE |
| 193 | }; | 199 | }; |
| 194 | static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { | 200 | static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { |
| 195 | "pte_pmd_cache", "pgd_cache", | 201 | "pte_pmd_cache", "pmd_cache", "pgd_cache", |
| 196 | }; | 202 | }; |
| 197 | #else | 203 | #else |
| 198 | static const int pgtable_cache_size[2] = { | 204 | static const unsigned int pgtable_cache_size[2] = { |
| 199 | PTE_TABLE_SIZE, PMD_TABLE_SIZE | 205 | PTE_TABLE_SIZE, PMD_TABLE_SIZE |
| 200 | }; | 206 | }; |
| 201 | static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { | 207 | static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { |
| @@ -213,6 +219,8 @@ void pgtable_cache_init(void) | |||
| 213 | int size = pgtable_cache_size[i]; | 219 | int size = pgtable_cache_size[i]; |
| 214 | const char *name = pgtable_cache_name[i]; | 220 | const char *name = pgtable_cache_name[i]; |
| 215 | 221 | ||
| 222 | DBG("Allocating page table cache %s (#%d) " | ||
| 223 | "for size: %08x...\n", name, i, size); | ||
| 216 | pgtable_cache[i] = kmem_cache_create(name, | 224 | pgtable_cache[i] = kmem_cache_create(name, |
| 217 | size, size, | 225 | size, size, |
| 218 | SLAB_HWCACHE_ALIGN | | 226 | SLAB_HWCACHE_ALIGN | |
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 6f55efd9be95..1dd3cc69a490 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c | |||
| @@ -110,6 +110,7 @@ EXPORT_SYMBOL(phys_mem_access_prot); | |||
| 110 | void online_page(struct page *page) | 110 | void online_page(struct page *page) |
| 111 | { | 111 | { |
| 112 | ClearPageReserved(page); | 112 | ClearPageReserved(page); |
| 113 | set_page_count(page, 0); | ||
| 113 | free_cold_page(page); | 114 | free_cold_page(page); |
| 114 | totalram_pages++; | 115 | totalram_pages++; |
| 115 | num_physpages++; | 116 | num_physpages++; |
| @@ -127,6 +128,9 @@ int __devinit add_memory(u64 start, u64 size) | |||
| 127 | unsigned long start_pfn = start >> PAGE_SHIFT; | 128 | unsigned long start_pfn = start >> PAGE_SHIFT; |
| 128 | unsigned long nr_pages = size >> PAGE_SHIFT; | 129 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 129 | 130 | ||
| 131 | start += KERNELBASE; | ||
| 132 | create_section_mapping(start, start + size); | ||
| 133 | |||
| 130 | /* this should work for most non-highmem platforms */ | 134 | /* this should work for most non-highmem platforms */ |
| 131 | zone = pgdata->node_zones; | 135 | zone = pgdata->node_zones; |
| 132 | 136 | ||
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 900842451bd3..c7f7bb6f30b3 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c | |||
| @@ -122,8 +122,11 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags) | |||
| 122 | * | 122 | * |
| 123 | */ | 123 | */ |
| 124 | if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags, | 124 | if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags, |
| 125 | mmu_virtual_psize)) | 125 | mmu_virtual_psize)) { |
| 126 | panic("Can't map bolted IO mapping"); | 126 | printk(KERN_ERR "Failed to do bolted mapping IO " |
| 127 | "memory at %016lx !\n", pa); | ||
| 128 | return -ENOMEM; | ||
| 129 | } | ||
| 127 | } | 130 | } |
| 128 | return 0; | 131 | return 0; |
| 129 | } | 132 | } |
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c index fa325dbf98fc..cfbb4e1f966b 100644 --- a/arch/powerpc/mm/stab.c +++ b/arch/powerpc/mm/stab.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <asm/cputable.h> | 20 | #include <asm/cputable.h> |
| 21 | #include <asm/lmb.h> | 21 | #include <asm/lmb.h> |
| 22 | #include <asm/abs_addr.h> | 22 | #include <asm/abs_addr.h> |
| 23 | #include <asm/firmware.h> | ||
| 23 | 24 | ||
| 24 | struct stab_entry { | 25 | struct stab_entry { |
| 25 | unsigned long esid_data; | 26 | unsigned long esid_data; |
| @@ -256,7 +257,7 @@ void stabs_alloc(void) | |||
| 256 | 257 | ||
| 257 | paca[cpu].stab_addr = newstab; | 258 | paca[cpu].stab_addr = newstab; |
| 258 | paca[cpu].stab_real = virt_to_abs(newstab); | 259 | paca[cpu].stab_real = virt_to_abs(newstab); |
| 259 | printk(KERN_DEBUG "Segment table for CPU %d at 0x%lx " | 260 | printk(KERN_INFO "Segment table for CPU %d at 0x%lx " |
| 260 | "virtual, 0x%lx absolute\n", | 261 | "virtual, 0x%lx absolute\n", |
| 261 | cpu, paca[cpu].stab_addr, paca[cpu].stab_real); | 262 | cpu, paca[cpu].stab_addr, paca[cpu].stab_real); |
| 262 | } | 263 | } |
| @@ -270,10 +271,28 @@ void stabs_alloc(void) | |||
| 270 | void stab_initialize(unsigned long stab) | 271 | void stab_initialize(unsigned long stab) |
| 271 | { | 272 | { |
| 272 | unsigned long vsid = get_kernel_vsid(KERNELBASE); | 273 | unsigned long vsid = get_kernel_vsid(KERNELBASE); |
| 274 | unsigned long stabreal; | ||
| 273 | 275 | ||
| 274 | asm volatile("isync; slbia; isync":::"memory"); | 276 | asm volatile("isync; slbia; isync":::"memory"); |
| 275 | make_ste(stab, GET_ESID(KERNELBASE), vsid); | 277 | make_ste(stab, GET_ESID(KERNELBASE), vsid); |
| 276 | 278 | ||
| 277 | /* Order update */ | 279 | /* Order update */ |
| 278 | asm volatile("sync":::"memory"); | 280 | asm volatile("sync":::"memory"); |
| 281 | |||
| 282 | /* Set ASR */ | ||
| 283 | stabreal = get_paca()->stab_real | 0x1ul; | ||
| 284 | |||
| 285 | #ifdef CONFIG_PPC_ISERIES | ||
| 286 | if (firmware_has_feature(FW_FEATURE_ISERIES)) { | ||
| 287 | HvCall1(HvCallBaseSetASR, stabreal); | ||
| 288 | return; | ||
| 289 | } | ||
| 290 | #endif /* CONFIG_PPC_ISERIES */ | ||
| 291 | #ifdef CONFIG_PPC_PSERIES | ||
| 292 | if (platform_is_lpar()) { | ||
| 293 | plpar_hcall_norets(H_SET_ASR, stabreal); | ||
| 294 | return; | ||
| 295 | } | ||
| 296 | #endif | ||
| 297 | mtspr(SPRN_ASR, stabreal); | ||
| 279 | } | 298 | } |
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c index c4ee5478427b..e3a024e324b6 100644 --- a/arch/powerpc/oprofile/op_model_power4.c +++ b/arch/powerpc/oprofile/op_model_power4.c | |||
| @@ -233,8 +233,7 @@ static unsigned long get_pc(struct pt_regs *regs) | |||
| 233 | mmcra = mfspr(SPRN_MMCRA); | 233 | mmcra = mfspr(SPRN_MMCRA); |
| 234 | 234 | ||
| 235 | /* Were we in the hypervisor? */ | 235 | /* Were we in the hypervisor? */ |
| 236 | if ((systemcfg->platform == PLATFORM_PSERIES_LPAR) && | 236 | if (platform_is_lpar() && (mmcra & MMCRA_SIHV)) |
| 237 | (mmcra & MMCRA_SIHV)) | ||
| 238 | /* function descriptor madness */ | 237 | /* function descriptor madness */ |
| 239 | return *((unsigned long *)hypervisor_bucket); | 238 | return *((unsigned long *)hypervisor_bucket); |
| 240 | 239 | ||
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index ecd32d5d85f4..4099ddab9205 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c | |||
| @@ -361,7 +361,9 @@ static void __init chrp_find_openpic(void) | |||
| 361 | printk(KERN_INFO "OpenPIC at %lx\n", opaddr); | 361 | printk(KERN_INFO "OpenPIC at %lx\n", opaddr); |
| 362 | 362 | ||
| 363 | irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */ | 363 | irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */ |
| 364 | prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS - 4); | 364 | prom_get_irq_senses(init_senses, NUM_ISA_INTERRUPTS, NR_IRQS - 4); |
| 365 | /* i8259 cascade is always positive level */ | ||
| 366 | init_senses[0] = IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE; | ||
| 365 | 367 | ||
| 366 | iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); | 368 | iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); |
| 367 | if (iranges == NULL) | 369 | if (iranges == NULL) |
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index a06603d84a45..01090e9ce0cf 100644 --- a/arch/powerpc/platforms/iseries/irq.c +++ b/arch/powerpc/platforms/iseries/irq.c | |||
| @@ -103,6 +103,9 @@ static void intReceived(struct XmPciLpEvent *eventParm, | |||
| 103 | struct pt_regs *regsParm) | 103 | struct pt_regs *regsParm) |
| 104 | { | 104 | { |
| 105 | int irq; | 105 | int irq; |
| 106 | #ifdef CONFIG_IRQSTACKS | ||
| 107 | struct thread_info *curtp, *irqtp; | ||
| 108 | #endif | ||
| 106 | 109 | ||
| 107 | ++Pci_Interrupt_Count; | 110 | ++Pci_Interrupt_Count; |
| 108 | 111 | ||
| @@ -110,7 +113,20 @@ static void intReceived(struct XmPciLpEvent *eventParm, | |||
| 110 | case XmPciLpEvent_SlotInterrupt: | 113 | case XmPciLpEvent_SlotInterrupt: |
| 111 | irq = eventParm->hvLpEvent.xCorrelationToken; | 114 | irq = eventParm->hvLpEvent.xCorrelationToken; |
| 112 | /* Dispatch the interrupt handlers for this irq */ | 115 | /* Dispatch the interrupt handlers for this irq */ |
| 113 | ppc_irq_dispatch_handler(regsParm, irq); | 116 | #ifdef CONFIG_IRQSTACKS |
| 117 | /* Switch to the irq stack to handle this */ | ||
| 118 | curtp = current_thread_info(); | ||
| 119 | irqtp = hardirq_ctx[smp_processor_id()]; | ||
| 120 | if (curtp != irqtp) { | ||
| 121 | irqtp->task = curtp->task; | ||
| 122 | irqtp->flags = 0; | ||
| 123 | call___do_IRQ(irq, regsParm, irqtp); | ||
| 124 | irqtp->task = NULL; | ||
| 125 | if (irqtp->flags) | ||
| 126 | set_bits(irqtp->flags, &curtp->flags); | ||
| 127 | } else | ||
| 128 | #endif | ||
| 129 | __do_IRQ(irq, regsParm); | ||
| 114 | HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber, | 130 | HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber, |
| 115 | eventParm->eventData.slotInterrupt.subBusNumber, | 131 | eventParm->eventData.slotInterrupt.subBusNumber, |
| 116 | eventParm->eventData.slotInterrupt.deviceId); | 132 | eventParm->eventData.slotInterrupt.deviceId); |
| @@ -310,10 +326,8 @@ static void iSeries_disable_IRQ(unsigned int irq) | |||
| 310 | } | 326 | } |
| 311 | 327 | ||
| 312 | /* | 328 | /* |
| 313 | * Need to define this so ppc_irq_dispatch_handler will NOT call | 329 | * This does nothing because there is not enough information |
| 314 | * enable_IRQ at the end of interrupt handling. However, this does | 330 | * provided to do the EOI HvCall. This is done by XmPciLpEvent.c |
| 315 | * nothing because there is not enough information provided to do | ||
| 316 | * the EOI HvCall. This is done by XmPciLpEvent.c | ||
| 317 | */ | 331 | */ |
| 318 | static void iSeries_end_IRQ(unsigned int irq) | 332 | static void iSeries_end_IRQ(unsigned int irq) |
| 319 | { | 333 | { |
diff --git a/arch/powerpc/platforms/iseries/misc.S b/arch/powerpc/platforms/iseries/misc.S index 09f14522e176..dfe7aa1ba098 100644 --- a/arch/powerpc/platforms/iseries/misc.S +++ b/arch/powerpc/platforms/iseries/misc.S | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | #include <asm/processor.h> | 16 | #include <asm/processor.h> |
| 17 | #include <asm/asm-offsets.h> | 17 | #include <asm/asm-offsets.h> |
| 18 | #include <asm/ppc_asm.h> | ||
| 18 | 19 | ||
| 19 | .text | 20 | .text |
| 20 | 21 | ||
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 7f8f0cda6a74..6a29f301436b 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c | |||
| @@ -39,7 +39,8 @@ | |||
| 39 | #include <asm/sections.h> | 39 | #include <asm/sections.h> |
| 40 | #include <asm/iommu.h> | 40 | #include <asm/iommu.h> |
| 41 | #include <asm/firmware.h> | 41 | #include <asm/firmware.h> |
| 42 | 42 | #include <asm/systemcfg.h> | |
| 43 | #include <asm/system.h> | ||
| 43 | #include <asm/time.h> | 44 | #include <asm/time.h> |
| 44 | #include <asm/paca.h> | 45 | #include <asm/paca.h> |
| 45 | #include <asm/cache.h> | 46 | #include <asm/cache.h> |
| @@ -71,7 +72,7 @@ extern void hvlog(char *fmt, ...); | |||
| 71 | #endif | 72 | #endif |
| 72 | 73 | ||
| 73 | /* Function Prototypes */ | 74 | /* Function Prototypes */ |
| 74 | static void build_iSeries_Memory_Map(void); | 75 | static unsigned long build_iSeries_Memory_Map(void); |
| 75 | static void iseries_shared_idle(void); | 76 | static void iseries_shared_idle(void); |
| 76 | static void iseries_dedicated_idle(void); | 77 | static void iseries_dedicated_idle(void); |
| 77 | #ifdef CONFIG_PCI | 78 | #ifdef CONFIG_PCI |
| @@ -84,7 +85,6 @@ static void iSeries_pci_final_fixup(void) { } | |||
| 84 | int piranha_simulator; | 85 | int piranha_simulator; |
| 85 | 86 | ||
| 86 | extern int rd_size; /* Defined in drivers/block/rd.c */ | 87 | extern int rd_size; /* Defined in drivers/block/rd.c */ |
| 87 | extern unsigned long klimit; | ||
| 88 | extern unsigned long embedded_sysmap_start; | 88 | extern unsigned long embedded_sysmap_start; |
| 89 | extern unsigned long embedded_sysmap_end; | 89 | extern unsigned long embedded_sysmap_end; |
| 90 | 90 | ||
| @@ -403,9 +403,11 @@ void mschunks_alloc(unsigned long num_chunks) | |||
| 403 | * a table used to translate Linux's physical addresses to these | 403 | * a table used to translate Linux's physical addresses to these |
| 404 | * absolute addresses. Absolute addresses are needed when | 404 | * absolute addresses. Absolute addresses are needed when |
| 405 | * communicating with the hypervisor (e.g. to build HPT entries) | 405 | * communicating with the hypervisor (e.g. to build HPT entries) |
| 406 | * | ||
| 407 | * Returns the physical memory size | ||
| 406 | */ | 408 | */ |
| 407 | 409 | ||
| 408 | static void __init build_iSeries_Memory_Map(void) | 410 | static unsigned long __init build_iSeries_Memory_Map(void) |
| 409 | { | 411 | { |
| 410 | u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize; | 412 | u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize; |
| 411 | u32 nextPhysChunk; | 413 | u32 nextPhysChunk; |
| @@ -538,7 +540,7 @@ static void __init build_iSeries_Memory_Map(void) | |||
| 538 | * which should be equal to | 540 | * which should be equal to |
| 539 | * nextPhysChunk | 541 | * nextPhysChunk |
| 540 | */ | 542 | */ |
| 541 | systemcfg->physicalMemorySize = chunk_to_addr(nextPhysChunk); | 543 | return chunk_to_addr(nextPhysChunk); |
| 542 | } | 544 | } |
| 543 | 545 | ||
| 544 | /* | 546 | /* |
| @@ -564,8 +566,8 @@ static void __init iSeries_setup_arch(void) | |||
| 564 | printk("Max physical processors = %d\n", | 566 | printk("Max physical processors = %d\n", |
| 565 | itVpdAreas.xSlicMaxPhysicalProcs); | 567 | itVpdAreas.xSlicMaxPhysicalProcs); |
| 566 | 568 | ||
| 567 | systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR; | 569 | _systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR; |
| 568 | printk("Processor version = %x\n", systemcfg->processor); | 570 | printk("Processor version = %x\n", _systemcfg->processor); |
| 569 | } | 571 | } |
| 570 | 572 | ||
| 571 | static void iSeries_show_cpuinfo(struct seq_file *m) | 573 | static void iSeries_show_cpuinfo(struct seq_file *m) |
| @@ -702,7 +704,6 @@ static void iseries_shared_idle(void) | |||
| 702 | 704 | ||
| 703 | static void iseries_dedicated_idle(void) | 705 | static void iseries_dedicated_idle(void) |
| 704 | { | 706 | { |
| 705 | long oldval; | ||
| 706 | set_thread_flag(TIF_POLLING_NRFLAG); | 707 | set_thread_flag(TIF_POLLING_NRFLAG); |
| 707 | 708 | ||
| 708 | while (1) { | 709 | while (1) { |
| @@ -929,7 +930,7 @@ void dt_cpus(struct iseries_flat_dt *dt) | |||
| 929 | dt_end_node(dt); | 930 | dt_end_node(dt); |
| 930 | } | 931 | } |
| 931 | 932 | ||
| 932 | void build_flat_dt(struct iseries_flat_dt *dt) | 933 | void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size) |
| 933 | { | 934 | { |
| 934 | u64 tmp[2]; | 935 | u64 tmp[2]; |
| 935 | 936 | ||
| @@ -945,7 +946,7 @@ void build_flat_dt(struct iseries_flat_dt *dt) | |||
| 945 | dt_prop_str(dt, "name", "memory"); | 946 | dt_prop_str(dt, "name", "memory"); |
| 946 | dt_prop_str(dt, "device_type", "memory"); | 947 | dt_prop_str(dt, "device_type", "memory"); |
| 947 | tmp[0] = 0; | 948 | tmp[0] = 0; |
| 948 | tmp[1] = systemcfg->physicalMemorySize; | 949 | tmp[1] = phys_mem_size; |
| 949 | dt_prop_u64_list(dt, "reg", tmp, 2); | 950 | dt_prop_u64_list(dt, "reg", tmp, 2); |
| 950 | dt_end_node(dt); | 951 | dt_end_node(dt); |
| 951 | 952 | ||
| @@ -965,13 +966,15 @@ void build_flat_dt(struct iseries_flat_dt *dt) | |||
| 965 | 966 | ||
| 966 | void * __init iSeries_early_setup(void) | 967 | void * __init iSeries_early_setup(void) |
| 967 | { | 968 | { |
| 969 | unsigned long phys_mem_size; | ||
| 970 | |||
| 968 | iSeries_fixup_klimit(); | 971 | iSeries_fixup_klimit(); |
| 969 | 972 | ||
| 970 | /* | 973 | /* |
| 971 | * Initialize the table which translate Linux physical addresses to | 974 | * Initialize the table which translate Linux physical addresses to |
| 972 | * AS/400 absolute addresses | 975 | * AS/400 absolute addresses |
| 973 | */ | 976 | */ |
| 974 | build_iSeries_Memory_Map(); | 977 | phys_mem_size = build_iSeries_Memory_Map(); |
| 975 | 978 | ||
| 976 | iSeries_get_cmdline(); | 979 | iSeries_get_cmdline(); |
| 977 | 980 | ||
| @@ -981,7 +984,7 @@ void * __init iSeries_early_setup(void) | |||
| 981 | /* Parse early parameters, in particular mem=x */ | 984 | /* Parse early parameters, in particular mem=x */ |
| 982 | parse_early_param(); | 985 | parse_early_param(); |
| 983 | 986 | ||
| 984 | build_flat_dt(&iseries_dt); | 987 | build_flat_dt(&iseries_dt, phys_mem_size); |
| 985 | 988 | ||
| 986 | return (void *) __pa(&iseries_dt); | 989 | return (void *) __pa(&iseries_dt); |
| 987 | } | 990 | } |
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 340c21caeae2..895aeb3f75d0 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c | |||
| @@ -380,9 +380,6 @@ void __init maple_pcibios_fixup(void) | |||
| 380 | for_each_pci_dev(dev) | 380 | for_each_pci_dev(dev) |
| 381 | pci_read_irq_line(dev); | 381 | pci_read_irq_line(dev); |
| 382 | 382 | ||
| 383 | /* Do the mapping of the IO space */ | ||
| 384 | phbs_remap_io(); | ||
| 385 | |||
| 386 | DBG(" <- maple_pcibios_fixup\n"); | 383 | DBG(" <- maple_pcibios_fixup\n"); |
| 387 | } | 384 | } |
| 388 | 385 | ||
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 8f818d092e2b..dfd41b9781a9 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c | |||
| @@ -918,9 +918,6 @@ void __init pmac_pci_init(void) | |||
| 918 | PCI_DN(np)->busno = 0xf0; | 918 | PCI_DN(np)->busno = 0xf0; |
| 919 | } | 919 | } |
| 920 | 920 | ||
| 921 | /* map in PCI I/O space */ | ||
| 922 | phbs_remap_io(); | ||
| 923 | |||
| 924 | /* pmac_check_ht_link(); */ | 921 | /* pmac_check_ht_link(); */ |
| 925 | 922 | ||
| 926 | /* Tell pci.c to not use the common resource allocation mechanism */ | 923 | /* Tell pci.c to not use the common resource allocation mechanism */ |
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 83a49e80ac29..90040c49494d 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
| @@ -74,6 +74,9 @@ static DEFINE_SPINLOCK(pmac_pic_lock); | |||
| 74 | #define GATWICK_IRQ_POOL_SIZE 10 | 74 | #define GATWICK_IRQ_POOL_SIZE 10 |
| 75 | static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; | 75 | static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; |
| 76 | 76 | ||
| 77 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) | ||
| 78 | static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; | ||
| 79 | |||
| 77 | /* | 80 | /* |
| 78 | * Mark an irq as "lost". This is only used on the pmac | 81 | * Mark an irq as "lost". This is only used on the pmac |
| 79 | * since it can lose interrupts (see pmac_set_irq_mask). | 82 | * since it can lose interrupts (see pmac_set_irq_mask). |
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index e1f9443cc872..957b09103422 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c | |||
| @@ -305,9 +305,19 @@ static int __init smp_psurge_probe(void) | |||
| 305 | psurge_start = ioremap(PSURGE_START, 4); | 305 | psurge_start = ioremap(PSURGE_START, 4); |
| 306 | psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); | 306 | psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); |
| 307 | 307 | ||
| 308 | /* this is not actually strictly necessary -- paulus. */ | 308 | /* |
| 309 | for (i = 1; i < ncpus; ++i) | 309 | * This is necessary because OF doesn't know about the |
| 310 | smp_hw_index[i] = i; | 310 | * secondary cpu(s), and thus there aren't nodes in the |
| 311 | * device tree for them, and smp_setup_cpu_maps hasn't | ||
| 312 | * set their bits in cpu_possible_map and cpu_present_map. | ||
| 313 | */ | ||
| 314 | if (ncpus > NR_CPUS) | ||
| 315 | ncpus = NR_CPUS; | ||
| 316 | for (i = 1; i < ncpus ; ++i) { | ||
| 317 | cpu_set(i, cpu_present_map); | ||
| 318 | cpu_set(i, cpu_possible_map); | ||
| 319 | set_hard_smp_processor_id(i, i); | ||
| 320 | } | ||
| 311 | 321 | ||
| 312 | if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); | 322 | if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); |
| 313 | 323 | ||
| @@ -348,6 +358,7 @@ static void __init psurge_dual_sync_tb(int cpu_nr) | |||
| 348 | int t; | 358 | int t; |
| 349 | 359 | ||
| 350 | set_dec(tb_ticks_per_jiffy); | 360 | set_dec(tb_ticks_per_jiffy); |
| 361 | /* XXX fixme */ | ||
| 351 | set_tb(0, 0); | 362 | set_tb(0, 0); |
| 352 | last_jiffy_stamp(cpu_nr) = 0; | 363 | last_jiffy_stamp(cpu_nr) = 0; |
| 353 | 364 | ||
| @@ -363,8 +374,6 @@ static void __init psurge_dual_sync_tb(int cpu_nr) | |||
| 363 | 374 | ||
| 364 | /* now interrupt the secondary, starting both TBs */ | 375 | /* now interrupt the secondary, starting both TBs */ |
| 365 | psurge_set_ipi(1); | 376 | psurge_set_ipi(1); |
| 366 | |||
| 367 | smp_tb_synchronized = 1; | ||
| 368 | } | 377 | } |
| 369 | 378 | ||
| 370 | static struct irqaction psurge_irqaction = { | 379 | static struct irqaction psurge_irqaction = { |
| @@ -625,9 +634,8 @@ void smp_core99_give_timebase(void) | |||
| 625 | for (t = 100000; t > 0 && sec_tb_reset; --t) | 634 | for (t = 100000; t > 0 && sec_tb_reset; --t) |
| 626 | udelay(10); | 635 | udelay(10); |
| 627 | if (sec_tb_reset) | 636 | if (sec_tb_reset) |
| 637 | /* XXX BUG_ON here? */ | ||
| 628 | printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n"); | 638 | printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n"); |
| 629 | else | ||
| 630 | smp_tb_synchronized = 1; | ||
| 631 | 639 | ||
| 632 | /* Now, restart the timebase by leaving the GPIO to an open collector */ | 640 | /* Now, restart the timebase by leaving the GPIO to an open collector */ |
| 633 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0); | 641 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0); |
| @@ -810,19 +818,9 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr) | |||
| 810 | } | 818 | } |
| 811 | 819 | ||
| 812 | 820 | ||
| 813 | /* Core99 Macs (dual G4s and G5s) */ | ||
| 814 | struct smp_ops_t core99_smp_ops = { | ||
| 815 | .message_pass = smp_mpic_message_pass, | ||
| 816 | .probe = smp_core99_probe, | ||
| 817 | .kick_cpu = smp_core99_kick_cpu, | ||
| 818 | .setup_cpu = smp_core99_setup_cpu, | ||
| 819 | .give_timebase = smp_core99_give_timebase, | ||
| 820 | .take_timebase = smp_core99_take_timebase, | ||
| 821 | }; | ||
| 822 | |||
| 823 | #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) | 821 | #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) |
| 824 | 822 | ||
| 825 | int __cpu_disable(void) | 823 | int smp_core99_cpu_disable(void) |
| 826 | { | 824 | { |
| 827 | cpu_clear(smp_processor_id(), cpu_online_map); | 825 | cpu_clear(smp_processor_id(), cpu_online_map); |
| 828 | 826 | ||
| @@ -846,7 +844,7 @@ void cpu_die(void) | |||
| 846 | low_cpu_die(); | 844 | low_cpu_die(); |
| 847 | } | 845 | } |
| 848 | 846 | ||
| 849 | void __cpu_die(unsigned int cpu) | 847 | void smp_core99_cpu_die(unsigned int cpu) |
| 850 | { | 848 | { |
| 851 | int timeout; | 849 | int timeout; |
| 852 | 850 | ||
| @@ -858,8 +856,21 @@ void __cpu_die(unsigned int cpu) | |||
| 858 | } | 856 | } |
| 859 | msleep(1); | 857 | msleep(1); |
| 860 | } | 858 | } |
| 861 | cpu_callin_map[cpu] = 0; | ||
| 862 | cpu_dead[cpu] = 0; | 859 | cpu_dead[cpu] = 0; |
| 863 | } | 860 | } |
| 864 | 861 | ||
| 865 | #endif | 862 | #endif |
| 863 | |||
| 864 | /* Core99 Macs (dual G4s and G5s) */ | ||
| 865 | struct smp_ops_t core99_smp_ops = { | ||
| 866 | .message_pass = smp_mpic_message_pass, | ||
| 867 | .probe = smp_core99_probe, | ||
| 868 | .kick_cpu = smp_core99_kick_cpu, | ||
| 869 | .setup_cpu = smp_core99_setup_cpu, | ||
| 870 | .give_timebase = smp_core99_give_timebase, | ||
| 871 | .take_timebase = smp_core99_take_timebase, | ||
| 872 | #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) | ||
| 873 | .cpu_disable = smp_core99_cpu_disable, | ||
| 874 | .cpu_die = smp_core99_cpu_die, | ||
| 875 | #endif | ||
| 876 | }; | ||
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index b9938fece781..e7ca5b1f591e 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile | |||
| @@ -3,3 +3,5 @@ obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ | |||
| 3 | obj-$(CONFIG_SMP) += smp.o | 3 | obj-$(CONFIG_SMP) += smp.o |
| 4 | obj-$(CONFIG_IBMVIO) += vio.o | 4 | obj-$(CONFIG_IBMVIO) += vio.o |
| 5 | obj-$(CONFIG_XICS) += xics.o | 5 | obj-$(CONFIG_XICS) += xics.o |
| 6 | obj-$(CONFIG_SCANLOG) += scanlog.o | ||
| 7 | obj-$(CONFIG_EEH) += eeh.o eeh_event.o | ||
diff --git a/arch/ppc64/kernel/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 035d1b14a207..79de2310e70b 100644 --- a/arch/ppc64/kernel/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
| @@ -1,39 +1,37 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * eeh.c | 2 | * eeh.c |
| 3 | * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation | 3 | * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation |
| 4 | * | 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
| 7 | * the Free Software Foundation; either version 2 of the License, or | 7 | * the Free Software Foundation; either version 2 of the License, or |
| 8 | * (at your option) any later version. | 8 | * (at your option) any later version. |
| 9 | * | 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, | 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
| 14 | * | 14 | * |
| 15 | * You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/bootmem.h> | 20 | #include <linux/delay.h> |
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
| 23 | #include <linux/mm.h> | ||
| 24 | #include <linux/notifier.h> | ||
| 25 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
| 26 | #include <linux/proc_fs.h> | 24 | #include <linux/proc_fs.h> |
| 27 | #include <linux/rbtree.h> | 25 | #include <linux/rbtree.h> |
| 28 | #include <linux/seq_file.h> | 26 | #include <linux/seq_file.h> |
| 29 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
| 28 | #include <asm/atomic.h> | ||
| 30 | #include <asm/eeh.h> | 29 | #include <asm/eeh.h> |
| 30 | #include <asm/eeh_event.h> | ||
| 31 | #include <asm/io.h> | 31 | #include <asm/io.h> |
| 32 | #include <asm/machdep.h> | 32 | #include <asm/machdep.h> |
| 33 | #include <asm/rtas.h> | ||
| 34 | #include <asm/atomic.h> | ||
| 35 | #include <asm/systemcfg.h> | ||
| 36 | #include <asm/ppc-pci.h> | 33 | #include <asm/ppc-pci.h> |
| 34 | #include <asm/rtas.h> | ||
| 37 | 35 | ||
| 38 | #undef DEBUG | 36 | #undef DEBUG |
| 39 | 37 | ||
| @@ -49,8 +47,8 @@ | |||
| 49 | * were "empty": all reads return 0xff's and all writes are silently | 47 | * were "empty": all reads return 0xff's and all writes are silently |
| 50 | * ignored. EEH slot isolation events can be triggered by parity | 48 | * ignored. EEH slot isolation events can be triggered by parity |
| 51 | * errors on the address or data busses (e.g. during posted writes), | 49 | * errors on the address or data busses (e.g. during posted writes), |
| 52 | * which in turn might be caused by dust, vibration, humidity, | 50 | * which in turn might be caused by low voltage on the bus, dust, |
| 53 | * radioactivity or plain-old failed hardware. | 51 | * vibration, humidity, radioactivity or plain-old failed hardware. |
| 54 | * | 52 | * |
| 55 | * Note, however, that one of the leading causes of EEH slot | 53 | * Note, however, that one of the leading causes of EEH slot |
| 56 | * freeze events are buggy device drivers, buggy device microcode, | 54 | * freeze events are buggy device drivers, buggy device microcode, |
| @@ -71,26 +69,15 @@ | |||
| 71 | * and sent out for processing. | 69 | * and sent out for processing. |
| 72 | */ | 70 | */ |
| 73 | 71 | ||
| 74 | /** Bus Unit ID macros; get low and hi 32-bits of the 64-bit BUID */ | 72 | /* If a device driver keeps reading an MMIO register in an interrupt |
| 75 | #define BUID_HI(buid) ((buid) >> 32) | ||
| 76 | #define BUID_LO(buid) ((buid) & 0xffffffff) | ||
| 77 | |||
| 78 | /* EEH event workqueue setup. */ | ||
| 79 | static DEFINE_SPINLOCK(eeh_eventlist_lock); | ||
| 80 | LIST_HEAD(eeh_eventlist); | ||
| 81 | static void eeh_event_handler(void *); | ||
| 82 | DECLARE_WORK(eeh_event_wq, eeh_event_handler, NULL); | ||
| 83 | |||
| 84 | static struct notifier_block *eeh_notifier_chain; | ||
| 85 | |||
| 86 | /* | ||
| 87 | * If a device driver keeps reading an MMIO register in an interrupt | ||
| 88 | * handler after a slot isolation event has occurred, we assume it | 73 | * handler after a slot isolation event has occurred, we assume it |
| 89 | * is broken and panic. This sets the threshold for how many read | 74 | * is broken and panic. This sets the threshold for how many read |
| 90 | * attempts we allow before panicking. | 75 | * attempts we allow before panicking. |
| 91 | */ | 76 | */ |
| 92 | #define EEH_MAX_FAILS 1000 | 77 | #define EEH_MAX_FAILS 100000 |
| 93 | static atomic_t eeh_fail_count; | 78 | |
| 79 | /* Misc forward declaraions */ | ||
| 80 | static void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn); | ||
| 94 | 81 | ||
| 95 | /* RTAS tokens */ | 82 | /* RTAS tokens */ |
| 96 | static int ibm_set_eeh_option; | 83 | static int ibm_set_eeh_option; |
| @@ -101,12 +88,19 @@ static int ibm_slot_error_detail; | |||
| 101 | 88 | ||
| 102 | static int eeh_subsystem_enabled; | 89 | static int eeh_subsystem_enabled; |
| 103 | 90 | ||
| 91 | /* Lock to avoid races due to multiple reports of an error */ | ||
| 92 | static DEFINE_SPINLOCK(confirm_error_lock); | ||
| 93 | |||
| 104 | /* Buffer for reporting slot-error-detail rtas calls */ | 94 | /* Buffer for reporting slot-error-detail rtas calls */ |
| 105 | static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX]; | 95 | static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX]; |
| 106 | static DEFINE_SPINLOCK(slot_errbuf_lock); | 96 | static DEFINE_SPINLOCK(slot_errbuf_lock); |
| 107 | static int eeh_error_buf_size; | 97 | static int eeh_error_buf_size; |
| 108 | 98 | ||
| 109 | /* System monitoring statistics */ | 99 | /* System monitoring statistics */ |
| 100 | static DEFINE_PER_CPU(unsigned long, no_device); | ||
| 101 | static DEFINE_PER_CPU(unsigned long, no_dn); | ||
| 102 | static DEFINE_PER_CPU(unsigned long, no_cfg_addr); | ||
| 103 | static DEFINE_PER_CPU(unsigned long, ignored_check); | ||
| 110 | static DEFINE_PER_CPU(unsigned long, total_mmio_ffs); | 104 | static DEFINE_PER_CPU(unsigned long, total_mmio_ffs); |
| 111 | static DEFINE_PER_CPU(unsigned long, false_positives); | 105 | static DEFINE_PER_CPU(unsigned long, false_positives); |
| 112 | static DEFINE_PER_CPU(unsigned long, ignored_failures); | 106 | static DEFINE_PER_CPU(unsigned long, ignored_failures); |
| @@ -224,9 +218,9 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo, | |||
| 224 | while (*p) { | 218 | while (*p) { |
| 225 | parent = *p; | 219 | parent = *p; |
| 226 | piar = rb_entry(parent, struct pci_io_addr_range, rb_node); | 220 | piar = rb_entry(parent, struct pci_io_addr_range, rb_node); |
| 227 | if (alo < piar->addr_lo) { | 221 | if (ahi < piar->addr_lo) { |
| 228 | p = &parent->rb_left; | 222 | p = &parent->rb_left; |
| 229 | } else if (ahi > piar->addr_hi) { | 223 | } else if (alo > piar->addr_hi) { |
| 230 | p = &parent->rb_right; | 224 | p = &parent->rb_right; |
| 231 | } else { | 225 | } else { |
| 232 | if (dev != piar->pcidev || | 226 | if (dev != piar->pcidev || |
| @@ -245,6 +239,11 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo, | |||
| 245 | piar->pcidev = dev; | 239 | piar->pcidev = dev; |
| 246 | piar->flags = flags; | 240 | piar->flags = flags; |
| 247 | 241 | ||
| 242 | #ifdef DEBUG | ||
| 243 | printk(KERN_DEBUG "PIAR: insert range=[%lx:%lx] dev=%s\n", | ||
| 244 | alo, ahi, pci_name (dev)); | ||
| 245 | #endif | ||
| 246 | |||
| 248 | rb_link_node(&piar->rb_node, parent, p); | 247 | rb_link_node(&piar->rb_node, parent, p); |
| 249 | rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root); | 248 | rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root); |
| 250 | 249 | ||
| @@ -260,18 +259,17 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev) | |||
| 260 | 259 | ||
| 261 | dn = pci_device_to_OF_node(dev); | 260 | dn = pci_device_to_OF_node(dev); |
| 262 | if (!dn) { | 261 | if (!dn) { |
| 263 | printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n", | 262 | printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n", pci_name(dev)); |
| 264 | pci_name(dev)); | ||
| 265 | return; | 263 | return; |
| 266 | } | 264 | } |
| 267 | 265 | ||
| 268 | /* Skip any devices for which EEH is not enabled. */ | 266 | /* Skip any devices for which EEH is not enabled. */ |
| 269 | pdn = dn->data; | 267 | pdn = PCI_DN(dn); |
| 270 | if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || | 268 | if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || |
| 271 | pdn->eeh_mode & EEH_MODE_NOCHECK) { | 269 | pdn->eeh_mode & EEH_MODE_NOCHECK) { |
| 272 | #ifdef DEBUG | 270 | #ifdef DEBUG |
| 273 | printk(KERN_INFO "PCI: skip building address cache for=%s\n", | 271 | printk(KERN_INFO "PCI: skip building address cache for=%s - %s\n", |
| 274 | pci_name(dev)); | 272 | pci_name(dev), pdn->node->full_name); |
| 275 | #endif | 273 | #endif |
| 276 | return; | 274 | return; |
| 277 | } | 275 | } |
| @@ -307,7 +305,7 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev) | |||
| 307 | * we maintain a cache of devices that can be quickly searched. | 305 | * we maintain a cache of devices that can be quickly searched. |
| 308 | * This routine adds a device to that cache. | 306 | * This routine adds a device to that cache. |
| 309 | */ | 307 | */ |
| 310 | void pci_addr_cache_insert_device(struct pci_dev *dev) | 308 | static void pci_addr_cache_insert_device(struct pci_dev *dev) |
| 311 | { | 309 | { |
| 312 | unsigned long flags; | 310 | unsigned long flags; |
| 313 | 311 | ||
| @@ -350,7 +348,7 @@ restart: | |||
| 350 | * the tree multiple times (once per resource). | 348 | * the tree multiple times (once per resource). |
| 351 | * But so what; device removal doesn't need to be that fast. | 349 | * But so what; device removal doesn't need to be that fast. |
| 352 | */ | 350 | */ |
| 353 | void pci_addr_cache_remove_device(struct pci_dev *dev) | 351 | static void pci_addr_cache_remove_device(struct pci_dev *dev) |
| 354 | { | 352 | { |
| 355 | unsigned long flags; | 353 | unsigned long flags; |
| 356 | 354 | ||
| @@ -370,8 +368,12 @@ void pci_addr_cache_remove_device(struct pci_dev *dev) | |||
| 370 | */ | 368 | */ |
| 371 | void __init pci_addr_cache_build(void) | 369 | void __init pci_addr_cache_build(void) |
| 372 | { | 370 | { |
| 371 | struct device_node *dn; | ||
| 373 | struct pci_dev *dev = NULL; | 372 | struct pci_dev *dev = NULL; |
| 374 | 373 | ||
| 374 | if (!eeh_subsystem_enabled) | ||
| 375 | return; | ||
| 376 | |||
| 375 | spin_lock_init(&pci_io_addr_cache_root.piar_lock); | 377 | spin_lock_init(&pci_io_addr_cache_root.piar_lock); |
| 376 | 378 | ||
| 377 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 379 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
| @@ -380,6 +382,10 @@ void __init pci_addr_cache_build(void) | |||
| 380 | continue; | 382 | continue; |
| 381 | } | 383 | } |
| 382 | pci_addr_cache_insert_device(dev); | 384 | pci_addr_cache_insert_device(dev); |
| 385 | |||
| 386 | /* Save the BAR's; firmware doesn't restore these after EEH reset */ | ||
| 387 | dn = pci_device_to_OF_node(dev); | ||
| 388 | eeh_save_bars(dev, PCI_DN(dn)); | ||
| 383 | } | 389 | } |
| 384 | 390 | ||
| 385 | #ifdef DEBUG | 391 | #ifdef DEBUG |
| @@ -391,22 +397,26 @@ void __init pci_addr_cache_build(void) | |||
| 391 | /* --------------------------------------------------------------- */ | 397 | /* --------------------------------------------------------------- */ |
| 392 | /* Above lies the PCI Address Cache. Below lies the EEH event infrastructure */ | 398 | /* Above lies the PCI Address Cache. Below lies the EEH event infrastructure */ |
| 393 | 399 | ||
| 394 | /** | 400 | void eeh_slot_error_detail (struct pci_dn *pdn, int severity) |
| 395 | * eeh_register_notifier - Register to find out about EEH events. | ||
| 396 | * @nb: notifier block to callback on events | ||
| 397 | */ | ||
| 398 | int eeh_register_notifier(struct notifier_block *nb) | ||
| 399 | { | 401 | { |
| 400 | return notifier_chain_register(&eeh_notifier_chain, nb); | 402 | unsigned long flags; |
| 401 | } | 403 | int rc; |
| 402 | 404 | ||
| 403 | /** | 405 | /* Log the error with the rtas logger */ |
| 404 | * eeh_unregister_notifier - Unregister to an EEH event notifier. | 406 | spin_lock_irqsave(&slot_errbuf_lock, flags); |
| 405 | * @nb: notifier block to callback on events | 407 | memset(slot_errbuf, 0, eeh_error_buf_size); |
| 406 | */ | 408 | |
| 407 | int eeh_unregister_notifier(struct notifier_block *nb) | 409 | rc = rtas_call(ibm_slot_error_detail, |
| 408 | { | 410 | 8, 1, NULL, pdn->eeh_config_addr, |
| 409 | return notifier_chain_unregister(&eeh_notifier_chain, nb); | 411 | BUID_HI(pdn->phb->buid), |
| 412 | BUID_LO(pdn->phb->buid), NULL, 0, | ||
| 413 | virt_to_phys(slot_errbuf), | ||
| 414 | eeh_error_buf_size, | ||
| 415 | severity); | ||
| 416 | |||
| 417 | if (rc == 0) | ||
| 418 | log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0); | ||
| 419 | spin_unlock_irqrestore(&slot_errbuf_lock, flags); | ||
| 410 | } | 420 | } |
| 411 | 421 | ||
| 412 | /** | 422 | /** |
| @@ -414,16 +424,16 @@ int eeh_unregister_notifier(struct notifier_block *nb) | |||
| 414 | * @dn: device node to read | 424 | * @dn: device node to read |
| 415 | * @rets: array to return results in | 425 | * @rets: array to return results in |
| 416 | */ | 426 | */ |
| 417 | static int read_slot_reset_state(struct device_node *dn, int rets[]) | 427 | static int read_slot_reset_state(struct pci_dn *pdn, int rets[]) |
| 418 | { | 428 | { |
| 419 | int token, outputs; | 429 | int token, outputs; |
| 420 | struct pci_dn *pdn = dn->data; | ||
| 421 | 430 | ||
| 422 | if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) { | 431 | if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) { |
| 423 | token = ibm_read_slot_reset_state2; | 432 | token = ibm_read_slot_reset_state2; |
| 424 | outputs = 4; | 433 | outputs = 4; |
| 425 | } else { | 434 | } else { |
| 426 | token = ibm_read_slot_reset_state; | 435 | token = ibm_read_slot_reset_state; |
| 436 | rets[2] = 0; /* fake PE Unavailable info */ | ||
| 427 | outputs = 3; | 437 | outputs = 3; |
| 428 | } | 438 | } |
| 429 | 439 | ||
| @@ -432,87 +442,84 @@ static int read_slot_reset_state(struct device_node *dn, int rets[]) | |||
| 432 | } | 442 | } |
| 433 | 443 | ||
| 434 | /** | 444 | /** |
| 435 | * eeh_panic - call panic() for an eeh event that cannot be handled. | 445 | * eeh_token_to_phys - convert EEH address token to phys address |
| 436 | * The philosophy of this routine is that it is better to panic and | 446 | * @token i/o token, should be address in the form 0xA.... |
| 437 | * halt the OS than it is to risk possible data corruption by | ||
| 438 | * oblivious device drivers that don't know better. | ||
| 439 | * | ||
| 440 | * @dev pci device that had an eeh event | ||
| 441 | * @reset_state current reset state of the device slot | ||
| 442 | */ | 447 | */ |
| 443 | static void eeh_panic(struct pci_dev *dev, int reset_state) | 448 | static inline unsigned long eeh_token_to_phys(unsigned long token) |
| 444 | { | 449 | { |
| 445 | /* | 450 | pte_t *ptep; |
| 446 | * XXX We should create a separate sysctl for this. | 451 | unsigned long pa; |
| 447 | * | 452 | |
| 448 | * Since the panic_on_oops sysctl is used to halt the system | 453 | ptep = find_linux_pte(init_mm.pgd, token); |
| 449 | * in light of potential corruption, we can use it here. | 454 | if (!ptep) |
| 450 | */ | 455 | return token; |
| 451 | if (panic_on_oops) | 456 | pa = pte_pfn(*ptep) << PAGE_SHIFT; |
| 452 | panic("EEH: MMIO failure (%d) on device:%s\n", reset_state, | 457 | |
| 453 | pci_name(dev)); | 458 | return pa | (token & (PAGE_SIZE-1)); |
| 454 | else { | ||
| 455 | __get_cpu_var(ignored_failures)++; | ||
| 456 | printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n", | ||
| 457 | reset_state, pci_name(dev)); | ||
| 458 | } | ||
| 459 | } | 459 | } |
| 460 | 460 | ||
| 461 | /** | 461 | /** |
| 462 | * eeh_event_handler - dispatch EEH events. The detection of a frozen | 462 | * Return the "partitionable endpoint" (pe) under which this device lies |
| 463 | * slot can occur inside an interrupt, where it can be hard to do | ||
| 464 | * anything about it. The goal of this routine is to pull these | ||
| 465 | * detection events out of the context of the interrupt handler, and | ||
| 466 | * re-dispatch them for processing at a later time in a normal context. | ||
| 467 | * | ||
| 468 | * @dummy - unused | ||
| 469 | */ | 463 | */ |
| 470 | static void eeh_event_handler(void *dummy) | 464 | static struct device_node * find_device_pe(struct device_node *dn) |
| 471 | { | 465 | { |
| 472 | unsigned long flags; | 466 | while ((dn->parent) && PCI_DN(dn->parent) && |
| 473 | struct eeh_event *event; | 467 | (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) { |
| 474 | 468 | dn = dn->parent; | |
| 475 | while (1) { | 469 | } |
| 476 | spin_lock_irqsave(&eeh_eventlist_lock, flags); | 470 | return dn; |
| 477 | event = NULL; | 471 | } |
| 478 | if (!list_empty(&eeh_eventlist)) { | ||
| 479 | event = list_entry(eeh_eventlist.next, struct eeh_event, list); | ||
| 480 | list_del(&event->list); | ||
| 481 | } | ||
| 482 | spin_unlock_irqrestore(&eeh_eventlist_lock, flags); | ||
| 483 | if (event == NULL) | ||
| 484 | break; | ||
| 485 | |||
| 486 | printk(KERN_INFO "EEH: MMIO failure (%d), notifiying device " | ||
| 487 | "%s\n", event->reset_state, | ||
| 488 | pci_name(event->dev)); | ||
| 489 | 472 | ||
| 490 | atomic_set(&eeh_fail_count, 0); | 473 | /** Mark all devices that are peers of this device as failed. |
| 491 | notifier_call_chain (&eeh_notifier_chain, | 474 | * Mark the device driver too, so that it can see the failure |
| 492 | EEH_NOTIFY_FREEZE, event); | 475 | * immediately; this is critical, since some drivers poll |
| 476 | * status registers in interrupts ... If a driver is polling, | ||
| 477 | * and the slot is frozen, then the driver can deadlock in | ||
| 478 | * an interrupt context, which is bad. | ||
| 479 | */ | ||
| 493 | 480 | ||
| 494 | __get_cpu_var(slot_resets)++; | 481 | static void __eeh_mark_slot (struct device_node *dn, int mode_flag) |
| 482 | { | ||
| 483 | while (dn) { | ||
| 484 | if (PCI_DN(dn)) { | ||
| 485 | PCI_DN(dn)->eeh_mode |= mode_flag; | ||
| 495 | 486 | ||
| 496 | pci_dev_put(event->dev); | 487 | if (dn->child) |
| 497 | kfree(event); | 488 | __eeh_mark_slot (dn->child, mode_flag); |
| 489 | } | ||
| 490 | dn = dn->sibling; | ||
| 498 | } | 491 | } |
| 499 | } | 492 | } |
| 500 | 493 | ||
| 501 | /** | 494 | void eeh_mark_slot (struct device_node *dn, int mode_flag) |
| 502 | * eeh_token_to_phys - convert EEH address token to phys address | ||
| 503 | * @token i/o token, should be address in the form 0xE.... | ||
| 504 | */ | ||
| 505 | static inline unsigned long eeh_token_to_phys(unsigned long token) | ||
| 506 | { | 495 | { |
| 507 | pte_t *ptep; | 496 | dn = find_device_pe (dn); |
| 508 | unsigned long pa; | 497 | PCI_DN(dn)->eeh_mode |= mode_flag; |
| 498 | __eeh_mark_slot (dn->child, mode_flag); | ||
| 499 | } | ||
| 509 | 500 | ||
| 510 | ptep = find_linux_pte(init_mm.pgd, token); | 501 | static void __eeh_clear_slot (struct device_node *dn, int mode_flag) |
| 511 | if (!ptep) | 502 | { |
| 512 | return token; | 503 | while (dn) { |
| 513 | pa = pte_pfn(*ptep) << PAGE_SHIFT; | 504 | if (PCI_DN(dn)) { |
| 505 | PCI_DN(dn)->eeh_mode &= ~mode_flag; | ||
| 506 | PCI_DN(dn)->eeh_check_count = 0; | ||
| 507 | if (dn->child) | ||
| 508 | __eeh_clear_slot (dn->child, mode_flag); | ||
| 509 | } | ||
| 510 | dn = dn->sibling; | ||
| 511 | } | ||
| 512 | } | ||
| 514 | 513 | ||
| 515 | return pa | (token & (PAGE_SIZE-1)); | 514 | void eeh_clear_slot (struct device_node *dn, int mode_flag) |
| 515 | { | ||
| 516 | unsigned long flags; | ||
| 517 | spin_lock_irqsave(&confirm_error_lock, flags); | ||
| 518 | dn = find_device_pe (dn); | ||
| 519 | PCI_DN(dn)->eeh_mode &= ~mode_flag; | ||
| 520 | PCI_DN(dn)->eeh_check_count = 0; | ||
| 521 | __eeh_clear_slot (dn->child, mode_flag); | ||
| 522 | spin_unlock_irqrestore(&confirm_error_lock, flags); | ||
| 516 | } | 523 | } |
| 517 | 524 | ||
| 518 | /** | 525 | /** |
| @@ -526,7 +533,7 @@ static inline unsigned long eeh_token_to_phys(unsigned long token) | |||
| 526 | * will query firmware for the EEH status. | 533 | * will query firmware for the EEH status. |
| 527 | * | 534 | * |
| 528 | * Returns 0 if there has not been an EEH error; otherwise returns | 535 | * Returns 0 if there has not been an EEH error; otherwise returns |
| 529 | * a non-zero value and queues up a solt isolation event notification. | 536 | * a non-zero value and queues up a slot isolation event notification. |
| 530 | * | 537 | * |
| 531 | * It is safe to call this routine in an interrupt context. | 538 | * It is safe to call this routine in an interrupt context. |
| 532 | */ | 539 | */ |
| @@ -535,42 +542,59 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) | |||
| 535 | int ret; | 542 | int ret; |
| 536 | int rets[3]; | 543 | int rets[3]; |
| 537 | unsigned long flags; | 544 | unsigned long flags; |
| 538 | int rc, reset_state; | ||
| 539 | struct eeh_event *event; | ||
| 540 | struct pci_dn *pdn; | 545 | struct pci_dn *pdn; |
| 546 | int rc = 0; | ||
| 541 | 547 | ||
| 542 | __get_cpu_var(total_mmio_ffs)++; | 548 | __get_cpu_var(total_mmio_ffs)++; |
| 543 | 549 | ||
| 544 | if (!eeh_subsystem_enabled) | 550 | if (!eeh_subsystem_enabled) |
| 545 | return 0; | 551 | return 0; |
| 546 | 552 | ||
| 547 | if (!dn) | 553 | if (!dn) { |
| 554 | __get_cpu_var(no_dn)++; | ||
| 548 | return 0; | 555 | return 0; |
| 549 | pdn = dn->data; | 556 | } |
| 557 | pdn = PCI_DN(dn); | ||
| 550 | 558 | ||
| 551 | /* Access to IO BARs might get this far and still not want checking. */ | 559 | /* Access to IO BARs might get this far and still not want checking. */ |
| 552 | if (!pdn->eeh_capable || !(pdn->eeh_mode & EEH_MODE_SUPPORTED) || | 560 | if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || |
| 553 | pdn->eeh_mode & EEH_MODE_NOCHECK) { | 561 | pdn->eeh_mode & EEH_MODE_NOCHECK) { |
| 562 | __get_cpu_var(ignored_check)++; | ||
| 563 | #ifdef DEBUG | ||
| 564 | printk ("EEH:ignored check (%x) for %s %s\n", | ||
| 565 | pdn->eeh_mode, pci_name (dev), dn->full_name); | ||
| 566 | #endif | ||
| 554 | return 0; | 567 | return 0; |
| 555 | } | 568 | } |
| 556 | 569 | ||
| 557 | if (!pdn->eeh_config_addr) { | 570 | if (!pdn->eeh_config_addr) { |
| 571 | __get_cpu_var(no_cfg_addr)++; | ||
| 558 | return 0; | 572 | return 0; |
| 559 | } | 573 | } |
| 560 | 574 | ||
| 561 | /* | 575 | /* If we already have a pending isolation event for this |
| 562 | * If we already have a pending isolation event for this | 576 | * slot, we know it's bad already, we don't need to check. |
| 563 | * slot, we know it's bad already, we don't need to check... | 577 | * Do this checking under a lock; as multiple PCI devices |
| 578 | * in one slot might report errors simultaneously, and we | ||
| 579 | * only want one error recovery routine running. | ||
| 564 | */ | 580 | */ |
| 581 | spin_lock_irqsave(&confirm_error_lock, flags); | ||
| 582 | rc = 1; | ||
| 565 | if (pdn->eeh_mode & EEH_MODE_ISOLATED) { | 583 | if (pdn->eeh_mode & EEH_MODE_ISOLATED) { |
| 566 | atomic_inc(&eeh_fail_count); | 584 | pdn->eeh_check_count ++; |
| 567 | if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) { | 585 | if (pdn->eeh_check_count >= EEH_MAX_FAILS) { |
| 586 | printk (KERN_ERR "EEH: Device driver ignored %d bad reads, panicing\n", | ||
| 587 | pdn->eeh_check_count); | ||
| 588 | dump_stack(); | ||
| 589 | |||
| 568 | /* re-read the slot reset state */ | 590 | /* re-read the slot reset state */ |
| 569 | if (read_slot_reset_state(dn, rets) != 0) | 591 | if (read_slot_reset_state(pdn, rets) != 0) |
| 570 | rets[0] = -1; /* reset state unknown */ | 592 | rets[0] = -1; /* reset state unknown */ |
| 571 | eeh_panic(dev, rets[0]); | 593 | |
| 594 | /* If we are here, then we hit an infinite loop. Stop. */ | ||
| 595 | panic("EEH: MMIO halt (%d) on device:%s\n", rets[0], pci_name(dev)); | ||
| 572 | } | 596 | } |
| 573 | return 0; | 597 | goto dn_unlock; |
| 574 | } | 598 | } |
| 575 | 599 | ||
| 576 | /* | 600 | /* |
| @@ -580,66 +604,69 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) | |||
| 580 | * function zero of a multi-function device. | 604 | * function zero of a multi-function device. |
| 581 | * In any case they must share a common PHB. | 605 | * In any case they must share a common PHB. |
| 582 | */ | 606 | */ |
| 583 | ret = read_slot_reset_state(dn, rets); | 607 | ret = read_slot_reset_state(pdn, rets); |
| 584 | if (!(ret == 0 && rets[1] == 1 && (rets[0] == 2 || rets[0] == 4))) { | 608 | |
| 609 | /* If the call to firmware failed, punt */ | ||
| 610 | if (ret != 0) { | ||
| 611 | printk(KERN_WARNING "EEH: read_slot_reset_state() failed; rc=%d dn=%s\n", | ||
| 612 | ret, dn->full_name); | ||
| 585 | __get_cpu_var(false_positives)++; | 613 | __get_cpu_var(false_positives)++; |
| 586 | return 0; | 614 | rc = 0; |
| 615 | goto dn_unlock; | ||
| 587 | } | 616 | } |
| 588 | 617 | ||
| 589 | /* prevent repeated reports of this failure */ | 618 | /* If EEH is not supported on this device, punt. */ |
| 590 | pdn->eeh_mode |= EEH_MODE_ISOLATED; | 619 | if (rets[1] != 1) { |
| 591 | 620 | printk(KERN_WARNING "EEH: event on unsupported device, rc=%d dn=%s\n", | |
| 592 | reset_state = rets[0]; | 621 | ret, dn->full_name); |
| 593 | 622 | __get_cpu_var(false_positives)++; | |
| 594 | spin_lock_irqsave(&slot_errbuf_lock, flags); | 623 | rc = 0; |
| 595 | memset(slot_errbuf, 0, eeh_error_buf_size); | 624 | goto dn_unlock; |
| 596 | 625 | } | |
| 597 | rc = rtas_call(ibm_slot_error_detail, | ||
| 598 | 8, 1, NULL, pdn->eeh_config_addr, | ||
| 599 | BUID_HI(pdn->phb->buid), | ||
| 600 | BUID_LO(pdn->phb->buid), NULL, 0, | ||
| 601 | virt_to_phys(slot_errbuf), | ||
| 602 | eeh_error_buf_size, | ||
| 603 | 1 /* Temporary Error */); | ||
| 604 | |||
| 605 | if (rc == 0) | ||
| 606 | log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0); | ||
| 607 | spin_unlock_irqrestore(&slot_errbuf_lock, flags); | ||
| 608 | 626 | ||
| 609 | printk(KERN_INFO "EEH: MMIO failure (%d) on device: %s %s\n", | 627 | /* If not the kind of error we know about, punt. */ |
| 610 | rets[0], dn->name, dn->full_name); | 628 | if (rets[0] != 2 && rets[0] != 4 && rets[0] != 5) { |
| 611 | event = kmalloc(sizeof(*event), GFP_ATOMIC); | 629 | __get_cpu_var(false_positives)++; |
| 612 | if (event == NULL) { | 630 | rc = 0; |
| 613 | eeh_panic(dev, reset_state); | 631 | goto dn_unlock; |
| 614 | return 1; | 632 | } |
| 615 | } | ||
| 616 | 633 | ||
| 617 | event->dev = dev; | 634 | /* Note that config-io to empty slots may fail; |
| 618 | event->dn = dn; | 635 | * we recognize empty because they don't have children. */ |
| 619 | event->reset_state = reset_state; | 636 | if ((rets[0] == 5) && (dn->child == NULL)) { |
| 637 | __get_cpu_var(false_positives)++; | ||
| 638 | rc = 0; | ||
| 639 | goto dn_unlock; | ||
| 640 | } | ||
| 620 | 641 | ||
| 621 | /* We may or may not be called in an interrupt context */ | 642 | __get_cpu_var(slot_resets)++; |
| 622 | spin_lock_irqsave(&eeh_eventlist_lock, flags); | 643 | |
| 623 | list_add(&event->list, &eeh_eventlist); | 644 | /* Avoid repeated reports of this failure, including problems |
| 624 | spin_unlock_irqrestore(&eeh_eventlist_lock, flags); | 645 | * with other functions on this device, and functions under |
| 646 | * bridges. */ | ||
| 647 | eeh_mark_slot (dn, EEH_MODE_ISOLATED); | ||
| 648 | spin_unlock_irqrestore(&confirm_error_lock, flags); | ||
| 625 | 649 | ||
| 650 | eeh_send_failure_event (dn, dev, rets[0], rets[2]); | ||
| 651 | |||
| 626 | /* Most EEH events are due to device driver bugs. Having | 652 | /* Most EEH events are due to device driver bugs. Having |
| 627 | * a stack trace will help the device-driver authors figure | 653 | * a stack trace will help the device-driver authors figure |
| 628 | * out what happened. So print that out. */ | 654 | * out what happened. So print that out. */ |
| 629 | dump_stack(); | 655 | if (rets[0] != 5) dump_stack(); |
| 630 | schedule_work(&eeh_event_wq); | 656 | return 1; |
| 631 | 657 | ||
| 632 | return 0; | 658 | dn_unlock: |
| 659 | spin_unlock_irqrestore(&confirm_error_lock, flags); | ||
| 660 | return rc; | ||
| 633 | } | 661 | } |
| 634 | 662 | ||
| 635 | EXPORT_SYMBOL(eeh_dn_check_failure); | 663 | EXPORT_SYMBOL_GPL(eeh_dn_check_failure); |
| 636 | 664 | ||
| 637 | /** | 665 | /** |
| 638 | * eeh_check_failure - check if all 1's data is due to EEH slot freeze | 666 | * eeh_check_failure - check if all 1's data is due to EEH slot freeze |
| 639 | * @token i/o token, should be address in the form 0xA.... | 667 | * @token i/o token, should be address in the form 0xA.... |
| 640 | * @val value, should be all 1's (XXX why do we need this arg??) | 668 | * @val value, should be all 1's (XXX why do we need this arg??) |
| 641 | * | 669 | * |
| 642 | * Check for an eeh failure at the given token address. | ||
| 643 | * Check for an EEH failure at the given token address. Call this | 670 | * Check for an EEH failure at the given token address. Call this |
| 644 | * routine if the result of a read was all 0xff's and you want to | 671 | * routine if the result of a read was all 0xff's and you want to |
| 645 | * find out if this is due to an EEH slot freeze event. This routine | 672 | * find out if this is due to an EEH slot freeze event. This routine |
| @@ -656,8 +683,10 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned lon | |||
| 656 | /* Finding the phys addr + pci device; this is pretty quick. */ | 683 | /* Finding the phys addr + pci device; this is pretty quick. */ |
| 657 | addr = eeh_token_to_phys((unsigned long __force) token); | 684 | addr = eeh_token_to_phys((unsigned long __force) token); |
| 658 | dev = pci_get_device_by_addr(addr); | 685 | dev = pci_get_device_by_addr(addr); |
| 659 | if (!dev) | 686 | if (!dev) { |
| 687 | __get_cpu_var(no_device)++; | ||
| 660 | return val; | 688 | return val; |
| 689 | } | ||
| 661 | 690 | ||
| 662 | dn = pci_device_to_OF_node(dev); | 691 | dn = pci_device_to_OF_node(dev); |
| 663 | eeh_dn_check_failure (dn, dev); | 692 | eeh_dn_check_failure (dn, dev); |
| @@ -668,6 +697,217 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned lon | |||
| 668 | 697 | ||
| 669 | EXPORT_SYMBOL(eeh_check_failure); | 698 | EXPORT_SYMBOL(eeh_check_failure); |
| 670 | 699 | ||
| 700 | /* ------------------------------------------------------------- */ | ||
| 701 | /* The code below deals with error recovery */ | ||
| 702 | |||
| 703 | /** Return negative value if a permanent error, else return | ||
| 704 | * a number of milliseconds to wait until the PCI slot is | ||
| 705 | * ready to be used. | ||
| 706 | */ | ||
| 707 | static int | ||
| 708 | eeh_slot_availability(struct pci_dn *pdn) | ||
| 709 | { | ||
| 710 | int rc; | ||
| 711 | int rets[3]; | ||
| 712 | |||
| 713 | rc = read_slot_reset_state(pdn, rets); | ||
| 714 | |||
| 715 | if (rc) return rc; | ||
| 716 | |||
| 717 | if (rets[1] == 0) return -1; /* EEH is not supported */ | ||
| 718 | if (rets[0] == 0) return 0; /* Oll Korrect */ | ||
| 719 | if (rets[0] == 5) { | ||
| 720 | if (rets[2] == 0) return -1; /* permanently unavailable */ | ||
| 721 | return rets[2]; /* number of millisecs to wait */ | ||
| 722 | } | ||
| 723 | return -1; | ||
| 724 | } | ||
| 725 | |||
| 726 | /** rtas_pci_slot_reset raises/lowers the pci #RST line | ||
| 727 | * state: 1/0 to raise/lower the #RST | ||
| 728 | * | ||
| 729 | * Clear the EEH-frozen condition on a slot. This routine | ||
| 730 | * asserts the PCI #RST line if the 'state' argument is '1', | ||
| 731 | * and drops the #RST line if 'state is '0'. This routine is | ||
| 732 | * safe to call in an interrupt context. | ||
| 733 | * | ||
| 734 | */ | ||
| 735 | |||
| 736 | static void | ||
| 737 | rtas_pci_slot_reset(struct pci_dn *pdn, int state) | ||
| 738 | { | ||
| 739 | int rc; | ||
| 740 | |||
| 741 | BUG_ON (pdn==NULL); | ||
| 742 | |||
| 743 | if (!pdn->phb) { | ||
| 744 | printk (KERN_WARNING "EEH: in slot reset, device node %s has no phb\n", | ||
| 745 | pdn->node->full_name); | ||
| 746 | return; | ||
| 747 | } | ||
| 748 | |||
| 749 | rc = rtas_call(ibm_set_slot_reset,4,1, NULL, | ||
| 750 | pdn->eeh_config_addr, | ||
| 751 | BUID_HI(pdn->phb->buid), | ||
| 752 | BUID_LO(pdn->phb->buid), | ||
| 753 | state); | ||
| 754 | if (rc) { | ||
| 755 | printk (KERN_WARNING "EEH: Unable to reset the failed slot, (%d) #RST=%d dn=%s\n", | ||
| 756 | rc, state, pdn->node->full_name); | ||
| 757 | return; | ||
| 758 | } | ||
| 759 | } | ||
| 760 | |||
| 761 | /** rtas_set_slot_reset -- assert the pci #RST line for 1/4 second | ||
| 762 | * dn -- device node to be reset. | ||
| 763 | */ | ||
| 764 | |||
| 765 | void | ||
| 766 | rtas_set_slot_reset(struct pci_dn *pdn) | ||
| 767 | { | ||
| 768 | int i, rc; | ||
| 769 | |||
| 770 | rtas_pci_slot_reset (pdn, 1); | ||
| 771 | |||
| 772 | /* The PCI bus requires that the reset be held high for at least | ||
| 773 | * a 100 milliseconds. We wait a bit longer 'just in case'. */ | ||
| 774 | |||
| 775 | #define PCI_BUS_RST_HOLD_TIME_MSEC 250 | ||
| 776 | msleep (PCI_BUS_RST_HOLD_TIME_MSEC); | ||
| 777 | |||
| 778 | /* We might get hit with another EEH freeze as soon as the | ||
| 779 | * pci slot reset line is dropped. Make sure we don't miss | ||
| 780 | * these, and clear the flag now. */ | ||
| 781 | eeh_clear_slot (pdn->node, EEH_MODE_ISOLATED); | ||
| 782 | |||
| 783 | rtas_pci_slot_reset (pdn, 0); | ||
| 784 | |||
| 785 | /* After a PCI slot has been reset, the PCI Express spec requires | ||
| 786 | * a 1.5 second idle time for the bus to stabilize, before starting | ||
| 787 | * up traffic. */ | ||
| 788 | #define PCI_BUS_SETTLE_TIME_MSEC 1800 | ||
| 789 | msleep (PCI_BUS_SETTLE_TIME_MSEC); | ||
| 790 | |||
| 791 | /* Now double check with the firmware to make sure the device is | ||
| 792 | * ready to be used; if not, wait for recovery. */ | ||
| 793 | for (i=0; i<10; i++) { | ||
| 794 | rc = eeh_slot_availability (pdn); | ||
| 795 | if (rc <= 0) break; | ||
| 796 | |||
| 797 | msleep (rc+100); | ||
| 798 | } | ||
| 799 | } | ||
| 800 | |||
| 801 | /* ------------------------------------------------------- */ | ||
| 802 | /** Save and restore of PCI BARs | ||
| 803 | * | ||
| 804 | * Although firmware will set up BARs during boot, it doesn't | ||
| 805 | * set up device BAR's after a device reset, although it will, | ||
| 806 | * if requested, set up bridge configuration. Thus, we need to | ||
| 807 | * configure the PCI devices ourselves. | ||
| 808 | */ | ||
| 809 | |||
| 810 | /** | ||
| 811 | * __restore_bars - Restore the Base Address Registers | ||
| 812 | * Loads the PCI configuration space base address registers, | ||
| 813 | * the expansion ROM base address, the latency timer, and etc. | ||
| 814 | * from the saved values in the device node. | ||
| 815 | */ | ||
| 816 | static inline void __restore_bars (struct pci_dn *pdn) | ||
| 817 | { | ||
| 818 | int i; | ||
| 819 | |||
| 820 | if (NULL==pdn->phb) return; | ||
| 821 | for (i=4; i<10; i++) { | ||
| 822 | rtas_write_config(pdn, i*4, 4, pdn->config_space[i]); | ||
| 823 | } | ||
| 824 | |||
| 825 | /* 12 == Expansion ROM Address */ | ||
| 826 | rtas_write_config(pdn, 12*4, 4, pdn->config_space[12]); | ||
| 827 | |||
| 828 | #define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF)) | ||
| 829 | #define SAVED_BYTE(OFF) (((u8 *)(pdn->config_space))[BYTE_SWAP(OFF)]) | ||
| 830 | |||
| 831 | rtas_write_config (pdn, PCI_CACHE_LINE_SIZE, 1, | ||
| 832 | SAVED_BYTE(PCI_CACHE_LINE_SIZE)); | ||
| 833 | |||
| 834 | rtas_write_config (pdn, PCI_LATENCY_TIMER, 1, | ||
| 835 | SAVED_BYTE(PCI_LATENCY_TIMER)); | ||
| 836 | |||
| 837 | /* max latency, min grant, interrupt pin and line */ | ||
| 838 | rtas_write_config(pdn, 15*4, 4, pdn->config_space[15]); | ||
| 839 | } | ||
| 840 | |||
| 841 | /** | ||
| 842 | * eeh_restore_bars - restore the PCI config space info | ||
| 843 | * | ||
| 844 | * This routine performs a recursive walk to the children | ||
| 845 | * of this device as well. | ||
| 846 | */ | ||
| 847 | void eeh_restore_bars(struct pci_dn *pdn) | ||
| 848 | { | ||
| 849 | struct device_node *dn; | ||
| 850 | if (!pdn) | ||
| 851 | return; | ||
| 852 | |||
| 853 | if (! pdn->eeh_is_bridge) | ||
| 854 | __restore_bars (pdn); | ||
| 855 | |||
| 856 | dn = pdn->node->child; | ||
| 857 | while (dn) { | ||
| 858 | eeh_restore_bars (PCI_DN(dn)); | ||
| 859 | dn = dn->sibling; | ||
| 860 | } | ||
| 861 | } | ||
| 862 | |||
| 863 | /** | ||
| 864 | * eeh_save_bars - save device bars | ||
| 865 | * | ||
| 866 | * Save the values of the device bars. Unlike the restore | ||
| 867 | * routine, this routine is *not* recursive. This is because | ||
| 868 | * PCI devices are added individuallly; but, for the restore, | ||
| 869 | * an entire slot is reset at a time. | ||
| 870 | */ | ||
| 871 | static void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn) | ||
| 872 | { | ||
| 873 | int i; | ||
| 874 | |||
| 875 | if (!pdev || !pdn ) | ||
| 876 | return; | ||
| 877 | |||
| 878 | for (i = 0; i < 16; i++) | ||
| 879 | pci_read_config_dword(pdev, i * 4, &pdn->config_space[i]); | ||
| 880 | |||
| 881 | if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) | ||
| 882 | pdn->eeh_is_bridge = 1; | ||
| 883 | } | ||
| 884 | |||
| 885 | void | ||
| 886 | rtas_configure_bridge(struct pci_dn *pdn) | ||
| 887 | { | ||
| 888 | int token = rtas_token ("ibm,configure-bridge"); | ||
| 889 | int rc; | ||
| 890 | |||
| 891 | if (token == RTAS_UNKNOWN_SERVICE) | ||
| 892 | return; | ||
| 893 | rc = rtas_call(token,3,1, NULL, | ||
| 894 | pdn->eeh_config_addr, | ||
| 895 | BUID_HI(pdn->phb->buid), | ||
| 896 | BUID_LO(pdn->phb->buid)); | ||
| 897 | if (rc) { | ||
| 898 | printk (KERN_WARNING "EEH: Unable to configure device bridge (%d) for %s\n", | ||
| 899 | rc, pdn->node->full_name); | ||
| 900 | } | ||
| 901 | } | ||
| 902 | |||
| 903 | /* ------------------------------------------------------------- */ | ||
| 904 | /* The code below deals with enabling EEH for devices during the | ||
| 905 | * early boot sequence. EEH must be enabled before any PCI probing | ||
| 906 | * can be done. | ||
| 907 | */ | ||
| 908 | |||
| 909 | #define EEH_ENABLE 1 | ||
| 910 | |||
| 671 | struct eeh_early_enable_info { | 911 | struct eeh_early_enable_info { |
| 672 | unsigned int buid_hi; | 912 | unsigned int buid_hi; |
| 673 | unsigned int buid_lo; | 913 | unsigned int buid_lo; |
| @@ -684,9 +924,11 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
| 684 | u32 *device_id = (u32 *)get_property(dn, "device-id", NULL); | 924 | u32 *device_id = (u32 *)get_property(dn, "device-id", NULL); |
| 685 | u32 *regs; | 925 | u32 *regs; |
| 686 | int enable; | 926 | int enable; |
| 687 | struct pci_dn *pdn = dn->data; | 927 | struct pci_dn *pdn = PCI_DN(dn); |
| 688 | 928 | ||
| 689 | pdn->eeh_mode = 0; | 929 | pdn->eeh_mode = 0; |
| 930 | pdn->eeh_check_count = 0; | ||
| 931 | pdn->eeh_freeze_count = 0; | ||
| 690 | 932 | ||
| 691 | if (status && strcmp(status, "ok") != 0) | 933 | if (status && strcmp(status, "ok") != 0) |
| 692 | return NULL; /* ignore devices with bad status */ | 934 | return NULL; /* ignore devices with bad status */ |
| @@ -723,8 +965,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
| 723 | /* First register entry is addr (00BBSS00) */ | 965 | /* First register entry is addr (00BBSS00) */ |
| 724 | /* Try to enable eeh */ | 966 | /* Try to enable eeh */ |
| 725 | ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL, | 967 | ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL, |
| 726 | regs[0], info->buid_hi, info->buid_lo, | 968 | regs[0], info->buid_hi, info->buid_lo, |
| 727 | EEH_ENABLE); | 969 | EEH_ENABLE); |
| 970 | |||
| 728 | if (ret == 0) { | 971 | if (ret == 0) { |
| 729 | eeh_subsystem_enabled = 1; | 972 | eeh_subsystem_enabled = 1; |
| 730 | pdn->eeh_mode |= EEH_MODE_SUPPORTED; | 973 | pdn->eeh_mode |= EEH_MODE_SUPPORTED; |
| @@ -736,7 +979,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
| 736 | 979 | ||
| 737 | /* This device doesn't support EEH, but it may have an | 980 | /* This device doesn't support EEH, but it may have an |
| 738 | * EEH parent, in which case we mark it as supported. */ | 981 | * EEH parent, in which case we mark it as supported. */ |
| 739 | if (dn->parent && dn->parent->data | 982 | if (dn->parent && PCI_DN(dn->parent) |
| 740 | && (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) { | 983 | && (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) { |
| 741 | /* Parent supports EEH. */ | 984 | /* Parent supports EEH. */ |
| 742 | pdn->eeh_mode |= EEH_MODE_SUPPORTED; | 985 | pdn->eeh_mode |= EEH_MODE_SUPPORTED; |
| @@ -749,7 +992,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
| 749 | dn->full_name); | 992 | dn->full_name); |
| 750 | } | 993 | } |
| 751 | 994 | ||
| 752 | return NULL; | 995 | return NULL; |
| 753 | } | 996 | } |
| 754 | 997 | ||
| 755 | /* | 998 | /* |
| @@ -770,6 +1013,9 @@ void __init eeh_init(void) | |||
| 770 | struct device_node *phb, *np; | 1013 | struct device_node *phb, *np; |
| 771 | struct eeh_early_enable_info info; | 1014 | struct eeh_early_enable_info info; |
| 772 | 1015 | ||
| 1016 | spin_lock_init(&confirm_error_lock); | ||
| 1017 | spin_lock_init(&slot_errbuf_lock); | ||
| 1018 | |||
| 773 | np = of_find_node_by_path("/rtas"); | 1019 | np = of_find_node_by_path("/rtas"); |
| 774 | if (np == NULL) | 1020 | if (np == NULL) |
| 775 | return; | 1021 | return; |
| @@ -797,13 +1043,11 @@ void __init eeh_init(void) | |||
| 797 | for (phb = of_find_node_by_name(NULL, "pci"); phb; | 1043 | for (phb = of_find_node_by_name(NULL, "pci"); phb; |
| 798 | phb = of_find_node_by_name(phb, "pci")) { | 1044 | phb = of_find_node_by_name(phb, "pci")) { |
| 799 | unsigned long buid; | 1045 | unsigned long buid; |
| 800 | struct pci_dn *pci; | ||
| 801 | 1046 | ||
| 802 | buid = get_phb_buid(phb); | 1047 | buid = get_phb_buid(phb); |
| 803 | if (buid == 0 || phb->data == NULL) | 1048 | if (buid == 0 || PCI_DN(phb) == NULL) |
| 804 | continue; | 1049 | continue; |
| 805 | 1050 | ||
| 806 | pci = phb->data; | ||
| 807 | info.buid_lo = BUID_LO(buid); | 1051 | info.buid_lo = BUID_LO(buid); |
| 808 | info.buid_hi = BUID_HI(buid); | 1052 | info.buid_hi = BUID_HI(buid); |
| 809 | traverse_pci_devices(phb, early_enable_eeh, &info); | 1053 | traverse_pci_devices(phb, early_enable_eeh, &info); |
| @@ -832,11 +1076,13 @@ void eeh_add_device_early(struct device_node *dn) | |||
| 832 | struct pci_controller *phb; | 1076 | struct pci_controller *phb; |
| 833 | struct eeh_early_enable_info info; | 1077 | struct eeh_early_enable_info info; |
| 834 | 1078 | ||
| 835 | if (!dn || !dn->data) | 1079 | if (!dn || !PCI_DN(dn)) |
| 836 | return; | 1080 | return; |
| 837 | phb = PCI_DN(dn)->phb; | 1081 | phb = PCI_DN(dn)->phb; |
| 838 | if (NULL == phb || 0 == phb->buid) { | 1082 | if (NULL == phb || 0 == phb->buid) { |
| 839 | printk(KERN_WARNING "EEH: Expected buid but found none\n"); | 1083 | printk(KERN_WARNING "EEH: Expected buid but found none for %s\n", |
| 1084 | dn->full_name); | ||
| 1085 | dump_stack(); | ||
| 840 | return; | 1086 | return; |
| 841 | } | 1087 | } |
| 842 | 1088 | ||
| @@ -844,7 +1090,7 @@ void eeh_add_device_early(struct device_node *dn) | |||
| 844 | info.buid_lo = BUID_LO(phb->buid); | 1090 | info.buid_lo = BUID_LO(phb->buid); |
| 845 | early_enable_eeh(dn, &info); | 1091 | early_enable_eeh(dn, &info); |
| 846 | } | 1092 | } |
| 847 | EXPORT_SYMBOL(eeh_add_device_early); | 1093 | EXPORT_SYMBOL_GPL(eeh_add_device_early); |
| 848 | 1094 | ||
| 849 | /** | 1095 | /** |
| 850 | * eeh_add_device_late - perform EEH initialization for the indicated pci device | 1096 | * eeh_add_device_late - perform EEH initialization for the indicated pci device |
| @@ -855,6 +1101,9 @@ EXPORT_SYMBOL(eeh_add_device_early); | |||
| 855 | */ | 1101 | */ |
| 856 | void eeh_add_device_late(struct pci_dev *dev) | 1102 | void eeh_add_device_late(struct pci_dev *dev) |
| 857 | { | 1103 | { |
| 1104 | struct device_node *dn; | ||
| 1105 | struct pci_dn *pdn; | ||
| 1106 | |||
| 858 | if (!dev || !eeh_subsystem_enabled) | 1107 | if (!dev || !eeh_subsystem_enabled) |
| 859 | return; | 1108 | return; |
| 860 | 1109 | ||
| @@ -862,9 +1111,15 @@ void eeh_add_device_late(struct pci_dev *dev) | |||
| 862 | printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev)); | 1111 | printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev)); |
| 863 | #endif | 1112 | #endif |
| 864 | 1113 | ||
| 1114 | pci_dev_get (dev); | ||
| 1115 | dn = pci_device_to_OF_node(dev); | ||
| 1116 | pdn = PCI_DN(dn); | ||
| 1117 | pdn->pcidev = dev; | ||
| 1118 | |||
| 865 | pci_addr_cache_insert_device (dev); | 1119 | pci_addr_cache_insert_device (dev); |
| 1120 | eeh_save_bars(dev, pdn); | ||
| 866 | } | 1121 | } |
| 867 | EXPORT_SYMBOL(eeh_add_device_late); | 1122 | EXPORT_SYMBOL_GPL(eeh_add_device_late); |
| 868 | 1123 | ||
| 869 | /** | 1124 | /** |
| 870 | * eeh_remove_device - undo EEH setup for the indicated pci device | 1125 | * eeh_remove_device - undo EEH setup for the indicated pci device |
| @@ -875,6 +1130,7 @@ EXPORT_SYMBOL(eeh_add_device_late); | |||
| 875 | */ | 1130 | */ |
| 876 | void eeh_remove_device(struct pci_dev *dev) | 1131 | void eeh_remove_device(struct pci_dev *dev) |
| 877 | { | 1132 | { |
| 1133 | struct device_node *dn; | ||
| 878 | if (!dev || !eeh_subsystem_enabled) | 1134 | if (!dev || !eeh_subsystem_enabled) |
| 879 | return; | 1135 | return; |
| 880 | 1136 | ||
| @@ -883,20 +1139,29 @@ void eeh_remove_device(struct pci_dev *dev) | |||
| 883 | printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev)); | 1139 | printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev)); |
| 884 | #endif | 1140 | #endif |
| 885 | pci_addr_cache_remove_device(dev); | 1141 | pci_addr_cache_remove_device(dev); |
| 1142 | |||
| 1143 | dn = pci_device_to_OF_node(dev); | ||
| 1144 | PCI_DN(dn)->pcidev = NULL; | ||
| 1145 | pci_dev_put (dev); | ||
| 886 | } | 1146 | } |
| 887 | EXPORT_SYMBOL(eeh_remove_device); | 1147 | EXPORT_SYMBOL_GPL(eeh_remove_device); |
| 888 | 1148 | ||
| 889 | static int proc_eeh_show(struct seq_file *m, void *v) | 1149 | static int proc_eeh_show(struct seq_file *m, void *v) |
| 890 | { | 1150 | { |
| 891 | unsigned int cpu; | 1151 | unsigned int cpu; |
| 892 | unsigned long ffs = 0, positives = 0, failures = 0; | 1152 | unsigned long ffs = 0, positives = 0, failures = 0; |
| 893 | unsigned long resets = 0; | 1153 | unsigned long resets = 0; |
| 1154 | unsigned long no_dev = 0, no_dn = 0, no_cfg = 0, no_check = 0; | ||
| 894 | 1155 | ||
| 895 | for_each_cpu(cpu) { | 1156 | for_each_cpu(cpu) { |
| 896 | ffs += per_cpu(total_mmio_ffs, cpu); | 1157 | ffs += per_cpu(total_mmio_ffs, cpu); |
| 897 | positives += per_cpu(false_positives, cpu); | 1158 | positives += per_cpu(false_positives, cpu); |
| 898 | failures += per_cpu(ignored_failures, cpu); | 1159 | failures += per_cpu(ignored_failures, cpu); |
| 899 | resets += per_cpu(slot_resets, cpu); | 1160 | resets += per_cpu(slot_resets, cpu); |
| 1161 | no_dev += per_cpu(no_device, cpu); | ||
| 1162 | no_dn += per_cpu(no_dn, cpu); | ||
| 1163 | no_cfg += per_cpu(no_cfg_addr, cpu); | ||
| 1164 | no_check += per_cpu(ignored_check, cpu); | ||
| 900 | } | 1165 | } |
| 901 | 1166 | ||
| 902 | if (0 == eeh_subsystem_enabled) { | 1167 | if (0 == eeh_subsystem_enabled) { |
| @@ -904,13 +1169,17 @@ static int proc_eeh_show(struct seq_file *m, void *v) | |||
| 904 | seq_printf(m, "eeh_total_mmio_ffs=%ld\n", ffs); | 1169 | seq_printf(m, "eeh_total_mmio_ffs=%ld\n", ffs); |
| 905 | } else { | 1170 | } else { |
| 906 | seq_printf(m, "EEH Subsystem is enabled\n"); | 1171 | seq_printf(m, "EEH Subsystem is enabled\n"); |
| 907 | seq_printf(m, "eeh_total_mmio_ffs=%ld\n" | 1172 | seq_printf(m, |
| 908 | "eeh_false_positives=%ld\n" | 1173 | "no device=%ld\n" |
| 909 | "eeh_ignored_failures=%ld\n" | 1174 | "no device node=%ld\n" |
| 910 | "eeh_slot_resets=%ld\n" | 1175 | "no config address=%ld\n" |
| 911 | "eeh_fail_count=%d\n", | 1176 | "check not wanted=%ld\n" |
| 912 | ffs, positives, failures, resets, | 1177 | "eeh_total_mmio_ffs=%ld\n" |
| 913 | eeh_fail_count.counter); | 1178 | "eeh_false_positives=%ld\n" |
| 1179 | "eeh_ignored_failures=%ld\n" | ||
| 1180 | "eeh_slot_resets=%ld\n", | ||
| 1181 | no_dev, no_dn, no_cfg, no_check, | ||
| 1182 | ffs, positives, failures, resets); | ||
| 914 | } | 1183 | } |
| 915 | 1184 | ||
| 916 | return 0; | 1185 | return 0; |
| @@ -932,7 +1201,7 @@ static int __init eeh_init_proc(void) | |||
| 932 | { | 1201 | { |
| 933 | struct proc_dir_entry *e; | 1202 | struct proc_dir_entry *e; |
| 934 | 1203 | ||
| 935 | if (systemcfg->platform & PLATFORM_PSERIES) { | 1204 | if (platform_is_pseries()) { |
| 936 | e = create_proc_entry("ppc64/eeh", 0, NULL); | 1205 | e = create_proc_entry("ppc64/eeh", 0, NULL); |
| 937 | if (e) | 1206 | if (e) |
| 938 | e->proc_fops = &proc_eeh_operations; | 1207 | e->proc_fops = &proc_eeh_operations; |
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c new file mode 100644 index 000000000000..92497333c2b6 --- /dev/null +++ b/arch/powerpc/platforms/pseries/eeh_event.c | |||
| @@ -0,0 +1,155 @@ | |||
| 1 | /* | ||
| 2 | * eeh_event.c | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 17 | * | ||
| 18 | * Copyright (c) 2005 Linas Vepstas <linas@linas.org> | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/list.h> | ||
| 22 | #include <linux/pci.h> | ||
| 23 | #include <asm/eeh_event.h> | ||
| 24 | |||
| 25 | /** Overview: | ||
| 26 | * EEH error states may be detected within exception handlers; | ||
| 27 | * however, the recovery processing needs to occur asynchronously | ||
| 28 | * in a normal kernel context and not an interrupt context. | ||
| 29 | * This pair of routines creates an event and queues it onto a | ||
| 30 | * work-queue, where a worker thread can drive recovery. | ||
| 31 | */ | ||
| 32 | |||
| 33 | /* EEH event workqueue setup. */ | ||
| 34 | static spinlock_t eeh_eventlist_lock = SPIN_LOCK_UNLOCKED; | ||
| 35 | LIST_HEAD(eeh_eventlist); | ||
| 36 | static void eeh_thread_launcher(void *); | ||
| 37 | DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL); | ||
| 38 | |||
| 39 | /** | ||
| 40 | * eeh_panic - call panic() for an eeh event that cannot be handled. | ||
| 41 | * The philosophy of this routine is that it is better to panic and | ||
| 42 | * halt the OS than it is to risk possible data corruption by | ||
| 43 | * oblivious device drivers that don't know better. | ||
| 44 | * | ||
| 45 | * @dev pci device that had an eeh event | ||
| 46 | * @reset_state current reset state of the device slot | ||
| 47 | */ | ||
| 48 | static void eeh_panic(struct pci_dev *dev, int reset_state) | ||
| 49 | { | ||
| 50 | /* | ||
| 51 | * Since the panic_on_oops sysctl is used to halt the system | ||
| 52 | * in light of potential corruption, we can use it here. | ||
| 53 | */ | ||
| 54 | if (panic_on_oops) { | ||
| 55 | panic("EEH: MMIO failure (%d) on device:%s\n", reset_state, | ||
| 56 | pci_name(dev)); | ||
| 57 | } | ||
| 58 | else { | ||
| 59 | printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n", | ||
| 60 | reset_state, pci_name(dev)); | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | /** | ||
| 65 | * eeh_event_handler - dispatch EEH events. The detection of a frozen | ||
| 66 | * slot can occur inside an interrupt, where it can be hard to do | ||
| 67 | * anything about it. The goal of this routine is to pull these | ||
| 68 | * detection events out of the context of the interrupt handler, and | ||
| 69 | * re-dispatch them for processing at a later time in a normal context. | ||
| 70 | * | ||
| 71 | * @dummy - unused | ||
| 72 | */ | ||
| 73 | static int eeh_event_handler(void * dummy) | ||
| 74 | { | ||
| 75 | unsigned long flags; | ||
| 76 | struct eeh_event *event; | ||
| 77 | |||
| 78 | daemonize ("eehd"); | ||
| 79 | |||
| 80 | while (1) { | ||
| 81 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 82 | |||
| 83 | spin_lock_irqsave(&eeh_eventlist_lock, flags); | ||
| 84 | event = NULL; | ||
| 85 | if (!list_empty(&eeh_eventlist)) { | ||
| 86 | event = list_entry(eeh_eventlist.next, struct eeh_event, list); | ||
| 87 | list_del(&event->list); | ||
| 88 | } | ||
| 89 | spin_unlock_irqrestore(&eeh_eventlist_lock, flags); | ||
| 90 | if (event == NULL) | ||
| 91 | break; | ||
| 92 | |||
| 93 | printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n", | ||
| 94 | pci_name(event->dev)); | ||
| 95 | |||
| 96 | eeh_panic (event->dev, event->state); | ||
| 97 | |||
| 98 | kfree(event); | ||
| 99 | } | ||
| 100 | |||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | /** | ||
| 105 | * eeh_thread_launcher | ||
| 106 | * | ||
| 107 | * @dummy - unused | ||
| 108 | */ | ||
| 109 | static void eeh_thread_launcher(void *dummy) | ||
| 110 | { | ||
| 111 | if (kernel_thread(eeh_event_handler, NULL, CLONE_KERNEL) < 0) | ||
| 112 | printk(KERN_ERR "Failed to start EEH daemon\n"); | ||
| 113 | } | ||
| 114 | |||
| 115 | /** | ||
| 116 | * eeh_send_failure_event - generate a PCI error event | ||
| 117 | * @dev pci device | ||
| 118 | * | ||
| 119 | * This routine can be called within an interrupt context; | ||
| 120 | * the actual event will be delivered in a normal context | ||
| 121 | * (from a workqueue). | ||
| 122 | */ | ||
| 123 | int eeh_send_failure_event (struct device_node *dn, | ||
| 124 | struct pci_dev *dev, | ||
| 125 | int state, | ||
| 126 | int time_unavail) | ||
| 127 | { | ||
| 128 | unsigned long flags; | ||
| 129 | struct eeh_event *event; | ||
| 130 | |||
| 131 | event = kmalloc(sizeof(*event), GFP_ATOMIC); | ||
| 132 | if (event == NULL) { | ||
| 133 | printk (KERN_ERR "EEH: out of memory, event not handled\n"); | ||
| 134 | return 1; | ||
| 135 | } | ||
| 136 | |||
| 137 | if (dev) | ||
| 138 | pci_dev_get(dev); | ||
| 139 | |||
| 140 | event->dn = dn; | ||
| 141 | event->dev = dev; | ||
| 142 | event->state = state; | ||
| 143 | event->time_unavail = time_unavail; | ||
| 144 | |||
| 145 | /* We may or may not be called in an interrupt context */ | ||
| 146 | spin_lock_irqsave(&eeh_eventlist_lock, flags); | ||
| 147 | list_add(&event->list, &eeh_eventlist); | ||
| 148 | spin_unlock_irqrestore(&eeh_eventlist_lock, flags); | ||
| 149 | |||
| 150 | schedule_work(&eeh_event_wq); | ||
| 151 | |||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | /********************** END OF FILE ******************************/ | ||
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index fcc50bfd43fd..97ba5214417f 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
| @@ -42,7 +42,6 @@ | |||
| 42 | #include <asm/machdep.h> | 42 | #include <asm/machdep.h> |
| 43 | #include <asm/abs_addr.h> | 43 | #include <asm/abs_addr.h> |
| 44 | #include <asm/pSeries_reconfig.h> | 44 | #include <asm/pSeries_reconfig.h> |
| 45 | #include <asm/systemcfg.h> | ||
| 46 | #include <asm/firmware.h> | 45 | #include <asm/firmware.h> |
| 47 | #include <asm/tce.h> | 46 | #include <asm/tce.h> |
| 48 | #include <asm/ppc-pci.h> | 47 | #include <asm/ppc-pci.h> |
| @@ -582,7 +581,7 @@ void iommu_init_early_pSeries(void) | |||
| 582 | return; | 581 | return; |
| 583 | } | 582 | } |
| 584 | 583 | ||
| 585 | if (systemcfg->platform & PLATFORM_LPAR) { | 584 | if (platform_is_lpar()) { |
| 586 | if (firmware_has_feature(FW_FEATURE_MULTITCE)) { | 585 | if (firmware_has_feature(FW_FEATURE_MULTITCE)) { |
| 587 | ppc_md.tce_build = tce_buildmulti_pSeriesLP; | 586 | ppc_md.tce_build = tce_buildmulti_pSeriesLP; |
| 588 | ppc_md.tce_free = tce_freemulti_pSeriesLP; | 587 | ppc_md.tce_free = tce_freemulti_pSeriesLP; |
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index c198656a3bb5..999a9620b5ce 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c | |||
| @@ -107,7 +107,6 @@ static void __init pSeries_request_regions(void) | |||
| 107 | 107 | ||
| 108 | void __init pSeries_final_fixup(void) | 108 | void __init pSeries_final_fixup(void) |
| 109 | { | 109 | { |
| 110 | phbs_remap_io(); | ||
| 111 | pSeries_request_regions(); | 110 | pSeries_request_regions(); |
| 112 | 111 | ||
| 113 | pci_addr_cache_build(); | 112 | pci_addr_cache_build(); |
| @@ -123,7 +122,7 @@ static void fixup_winbond_82c105(struct pci_dev* dev) | |||
| 123 | int i; | 122 | int i; |
| 124 | unsigned int reg; | 123 | unsigned int reg; |
| 125 | 124 | ||
| 126 | if (!(systemcfg->platform & PLATFORM_PSERIES)) | 125 | if (!platform_is_pseries()) |
| 127 | return; | 126 | return; |
| 128 | 127 | ||
| 129 | printk("Using INTC for W82c105 IDE controller.\n"); | 128 | printk("Using INTC for W82c105 IDE controller.\n"); |
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index d7d400339458..d8864164dbe8 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c | |||
| @@ -408,7 +408,7 @@ static int proc_ppc64_create_ofdt(void) | |||
| 408 | { | 408 | { |
| 409 | struct proc_dir_entry *ent; | 409 | struct proc_dir_entry *ent; |
| 410 | 410 | ||
| 411 | if (!(systemcfg->platform & PLATFORM_PSERIES)) | 411 | if (!platform_is_pseries()) |
| 412 | return 0; | 412 | return 0; |
| 413 | 413 | ||
| 414 | ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL); | 414 | ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL); |
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c index e26b0420b6dd..00cf331a1dc4 100644 --- a/arch/powerpc/platforms/pseries/rtasd.c +++ b/arch/powerpc/platforms/pseries/rtasd.c | |||
| @@ -482,10 +482,12 @@ static int __init rtas_init(void) | |||
| 482 | { | 482 | { |
| 483 | struct proc_dir_entry *entry; | 483 | struct proc_dir_entry *entry; |
| 484 | 484 | ||
| 485 | /* No RTAS, only warn if we are on a pSeries box */ | 485 | if (!platform_is_pseries()) |
| 486 | return 0; | ||
| 487 | |||
| 488 | /* No RTAS */ | ||
| 486 | if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { | 489 | if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { |
| 487 | if (systemcfg->platform & PLATFORM_PSERIES) | 490 | printk(KERN_INFO "rtasd: no event-scan on system\n"); |
| 488 | printk(KERN_INFO "rtasd: no event-scan on system\n"); | ||
| 489 | return 1; | 491 | return 1; |
| 490 | } | 492 | } |
| 491 | 493 | ||
diff --git a/arch/ppc64/kernel/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c index 2edc947f7c44..2edc947f7c44 100644 --- a/arch/ppc64/kernel/scanlog.c +++ b/arch/powerpc/platforms/pseries/scanlog.c | |||
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index a093a0d4dd69..e94247c28d42 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
| @@ -249,7 +249,7 @@ static void __init pSeries_setup_arch(void) | |||
| 249 | ppc_md.idle_loop = default_idle; | 249 | ppc_md.idle_loop = default_idle; |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | if (systemcfg->platform & PLATFORM_LPAR) | 252 | if (platform_is_lpar()) |
| 253 | ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; | 253 | ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; |
| 254 | else | 254 | else |
| 255 | ppc_md.enable_pmcs = power4_enable_pmcs; | 255 | ppc_md.enable_pmcs = power4_enable_pmcs; |
| @@ -378,7 +378,7 @@ static void __init pSeries_init_early(void) | |||
| 378 | 378 | ||
| 379 | fw_feature_init(); | 379 | fw_feature_init(); |
| 380 | 380 | ||
| 381 | if (systemcfg->platform & PLATFORM_LPAR) | 381 | if (platform_is_lpar()) |
| 382 | hpte_init_lpar(); | 382 | hpte_init_lpar(); |
| 383 | else { | 383 | else { |
| 384 | hpte_init_native(); | 384 | hpte_init_native(); |
| @@ -388,7 +388,7 @@ static void __init pSeries_init_early(void) | |||
| 388 | 388 | ||
| 389 | generic_find_legacy_serial_ports(&physport, &default_speed); | 389 | generic_find_legacy_serial_ports(&physport, &default_speed); |
| 390 | 390 | ||
| 391 | if (systemcfg->platform & PLATFORM_LPAR) | 391 | if (platform_is_lpar()) |
| 392 | find_udbg_vterm(); | 392 | find_udbg_vterm(); |
| 393 | else if (physport) { | 393 | else if (physport) { |
| 394 | /* Map the uart for udbg. */ | 394 | /* Map the uart for udbg. */ |
| @@ -592,7 +592,7 @@ static void pseries_shared_idle(void) | |||
| 592 | 592 | ||
| 593 | static int pSeries_pci_probe_mode(struct pci_bus *bus) | 593 | static int pSeries_pci_probe_mode(struct pci_bus *bus) |
| 594 | { | 594 | { |
| 595 | if (systemcfg->platform & PLATFORM_LPAR) | 595 | if (platform_is_lpar()) |
| 596 | return PCI_PROBE_DEVTREE; | 596 | return PCI_PROBE_DEVTREE; |
| 597 | return PCI_PROBE_NORMAL; | 597 | return PCI_PROBE_NORMAL; |
| 598 | } | 598 | } |
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 7a243e8ccd7e..3ba794ca3288 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | #include <asm/rtas.h> | 46 | #include <asm/rtas.h> |
| 47 | #include <asm/pSeries_reconfig.h> | 47 | #include <asm/pSeries_reconfig.h> |
| 48 | #include <asm/mpic.h> | 48 | #include <asm/mpic.h> |
| 49 | #include <asm/systemcfg.h> | ||
| 49 | 50 | ||
| 50 | #include "plpar_wrappers.h" | 51 | #include "plpar_wrappers.h" |
| 51 | 52 | ||
| @@ -96,7 +97,7 @@ int pSeries_cpu_disable(void) | |||
| 96 | int cpu = smp_processor_id(); | 97 | int cpu = smp_processor_id(); |
| 97 | 98 | ||
| 98 | cpu_clear(cpu, cpu_online_map); | 99 | cpu_clear(cpu, cpu_online_map); |
| 99 | systemcfg->processorCount--; | 100 | _systemcfg->processorCount--; |
| 100 | 101 | ||
| 101 | /*fix boot_cpuid here*/ | 102 | /*fix boot_cpuid here*/ |
| 102 | if (cpu == boot_cpuid) | 103 | if (cpu == boot_cpuid) |
| @@ -441,7 +442,7 @@ void __init smp_init_pSeries(void) | |||
| 441 | smp_ops->cpu_die = pSeries_cpu_die; | 442 | smp_ops->cpu_die = pSeries_cpu_die; |
| 442 | 443 | ||
| 443 | /* Processors can be added/removed only on LPAR */ | 444 | /* Processors can be added/removed only on LPAR */ |
| 444 | if (systemcfg->platform == PLATFORM_PSERIES_LPAR) | 445 | if (platform_is_lpar()) |
| 445 | pSeries_reconfig_notifier_register(&pSeries_smp_nb); | 446 | pSeries_reconfig_notifier_register(&pSeries_smp_nb); |
| 446 | #endif | 447 | #endif |
| 447 | 448 | ||
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index c72c86f05cb6..72ac18067ece 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
| @@ -545,7 +545,9 @@ nextnode: | |||
| 545 | of_node_put(np); | 545 | of_node_put(np); |
| 546 | } | 546 | } |
| 547 | 547 | ||
| 548 | if (systemcfg->platform == PLATFORM_PSERIES) { | 548 | if (platform_is_lpar()) |
| 549 | ops = &pSeriesLP_ops; | ||
| 550 | else { | ||
| 549 | #ifdef CONFIG_SMP | 551 | #ifdef CONFIG_SMP |
| 550 | for_each_cpu(i) { | 552 | for_each_cpu(i) { |
| 551 | int hard_id; | 553 | int hard_id; |
| @@ -561,12 +563,11 @@ nextnode: | |||
| 561 | #else | 563 | #else |
| 562 | xics_per_cpu[0] = ioremap(intr_base, intr_size); | 564 | xics_per_cpu[0] = ioremap(intr_base, intr_size); |
| 563 | #endif /* CONFIG_SMP */ | 565 | #endif /* CONFIG_SMP */ |
| 564 | } else if (systemcfg->platform == PLATFORM_PSERIES_LPAR) { | ||
| 565 | ops = &pSeriesLP_ops; | ||
| 566 | } | 566 | } |
| 567 | 567 | ||
| 568 | xics_8259_pic.enable = i8259_pic.enable; | 568 | xics_8259_pic.enable = i8259_pic.enable; |
| 569 | xics_8259_pic.disable = i8259_pic.disable; | 569 | xics_8259_pic.disable = i8259_pic.disable; |
| 570 | xics_8259_pic.end = i8259_pic.end; | ||
| 570 | for (i = 0; i < 16; ++i) | 571 | for (i = 0; i < 16; ++i) |
| 571 | get_irq_desc(i)->handler = &xics_8259_pic; | 572 | get_irq_desc(i)->handler = &xics_8259_pic; |
| 572 | for (; i < NR_IRQS; ++i) | 573 | for (; i < NR_IRQS; ++i) |
diff --git a/arch/powerpc/sysdev/u3_iommu.c b/arch/powerpc/sysdev/u3_iommu.c index 543d65909812..f32baf7f4693 100644 --- a/arch/powerpc/sysdev/u3_iommu.c +++ b/arch/powerpc/sysdev/u3_iommu.c | |||
| @@ -226,7 +226,7 @@ static void iommu_table_u3_setup(void) | |||
| 226 | iommu_table_u3.it_busno = 0; | 226 | iommu_table_u3.it_busno = 0; |
| 227 | iommu_table_u3.it_offset = 0; | 227 | iommu_table_u3.it_offset = 0; |
| 228 | /* it_size is in number of entries */ | 228 | /* it_size is in number of entries */ |
| 229 | iommu_table_u3.it_size = dart_tablesize / sizeof(u32); | 229 | iommu_table_u3.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR; |
| 230 | 230 | ||
| 231 | /* Initialize the common IOMMU code */ | 231 | /* Initialize the common IOMMU code */ |
| 232 | iommu_table_u3.it_base = (unsigned long)dart_vbase; | 232 | iommu_table_u3.it_base = (unsigned long)dart_vbase; |
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile index 79a784f0e7a9..b20312e5ed27 100644 --- a/arch/powerpc/xmon/Makefile +++ b/arch/powerpc/xmon/Makefile | |||
| @@ -8,4 +8,4 @@ obj-$(CONFIG_8xx) += start_8xx.o | |||
| 8 | obj-$(CONFIG_6xx) += start_32.o | 8 | obj-$(CONFIG_6xx) += start_32.o |
| 9 | obj-$(CONFIG_4xx) += start_32.o | 9 | obj-$(CONFIG_4xx) += start_32.o |
| 10 | obj-$(CONFIG_PPC64) += start_64.o | 10 | obj-$(CONFIG_PPC64) += start_64.o |
| 11 | obj-y += xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o | 11 | obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o nonstdio.o |
diff --git a/arch/powerpc/xmon/nonstdio.c b/arch/powerpc/xmon/nonstdio.c new file mode 100644 index 000000000000..78765833f4c0 --- /dev/null +++ b/arch/powerpc/xmon/nonstdio.c | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 1996-2005 Paul Mackerras. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version | ||
| 7 | * 2 of the License, or (at your option) any later version. | ||
| 8 | */ | ||
| 9 | #include <linux/string.h> | ||
| 10 | #include <asm/time.h> | ||
| 11 | #include "nonstdio.h" | ||
| 12 | |||
| 13 | int xmon_putchar(int c) | ||
| 14 | { | ||
| 15 | char ch = c; | ||
| 16 | |||
| 17 | if (c == '\n') | ||
| 18 | xmon_putchar('\r'); | ||
| 19 | return xmon_write(&ch, 1) == 1? c: -1; | ||
| 20 | } | ||
| 21 | |||
| 22 | static char line[256]; | ||
| 23 | static char *lineptr; | ||
| 24 | static int lineleft; | ||
| 25 | |||
| 26 | int xmon_expect(const char *str, unsigned long timeout) | ||
| 27 | { | ||
| 28 | int c; | ||
| 29 | unsigned long t0; | ||
| 30 | |||
| 31 | /* assume 25MHz default timebase if tb_ticks_per_sec not set yet */ | ||
| 32 | timeout *= tb_ticks_per_sec? tb_ticks_per_sec: 25000000; | ||
| 33 | t0 = get_tbl(); | ||
| 34 | do { | ||
| 35 | lineptr = line; | ||
| 36 | for (;;) { | ||
| 37 | c = xmon_read_poll(); | ||
| 38 | if (c == -1) { | ||
| 39 | if (get_tbl() - t0 > timeout) | ||
| 40 | return 0; | ||
| 41 | continue; | ||
| 42 | } | ||
| 43 | if (c == '\n') | ||
| 44 | break; | ||
| 45 | if (c != '\r' && lineptr < &line[sizeof(line) - 1]) | ||
| 46 | *lineptr++ = c; | ||
| 47 | } | ||
| 48 | *lineptr = 0; | ||
| 49 | } while (strstr(line, str) == NULL); | ||
| 50 | return 1; | ||
| 51 | } | ||
| 52 | |||
| 53 | int xmon_getchar(void) | ||
| 54 | { | ||
| 55 | int c; | ||
| 56 | |||
| 57 | if (lineleft == 0) { | ||
| 58 | lineptr = line; | ||
| 59 | for (;;) { | ||
| 60 | c = xmon_readchar(); | ||
| 61 | if (c == -1 || c == 4) | ||
| 62 | break; | ||
| 63 | if (c == '\r' || c == '\n') { | ||
| 64 | *lineptr++ = '\n'; | ||
| 65 | xmon_putchar('\n'); | ||
| 66 | break; | ||
| 67 | } | ||
| 68 | switch (c) { | ||
| 69 | case 0177: | ||
| 70 | case '\b': | ||
| 71 | if (lineptr > line) { | ||
| 72 | xmon_putchar('\b'); | ||
| 73 | xmon_putchar(' '); | ||
| 74 | xmon_putchar('\b'); | ||
| 75 | --lineptr; | ||
| 76 | } | ||
| 77 | break; | ||
| 78 | case 'U' & 0x1F: | ||
| 79 | while (lineptr > line) { | ||
| 80 | xmon_putchar('\b'); | ||
| 81 | xmon_putchar(' '); | ||
| 82 | xmon_putchar('\b'); | ||
| 83 | --lineptr; | ||
| 84 | } | ||
| 85 | break; | ||
| 86 | default: | ||
| 87 | if (lineptr >= &line[sizeof(line) - 1]) | ||
| 88 | xmon_putchar('\a'); | ||
| 89 | else { | ||
| 90 | xmon_putchar(c); | ||
| 91 | *lineptr++ = c; | ||
| 92 | } | ||
| 93 | } | ||
| 94 | } | ||
| 95 | lineleft = lineptr - line; | ||
| 96 | lineptr = line; | ||
| 97 | } | ||
| 98 | if (lineleft == 0) | ||
| 99 | return -1; | ||
| 100 | --lineleft; | ||
| 101 | return *lineptr++; | ||
| 102 | } | ||
| 103 | |||
| 104 | char *xmon_gets(char *str, int nb) | ||
| 105 | { | ||
| 106 | char *p; | ||
| 107 | int c; | ||
| 108 | |||
| 109 | for (p = str; p < str + nb - 1; ) { | ||
| 110 | c = xmon_getchar(); | ||
| 111 | if (c == -1) { | ||
| 112 | if (p == str) | ||
| 113 | return NULL; | ||
| 114 | break; | ||
| 115 | } | ||
| 116 | *p++ = c; | ||
| 117 | if (c == '\n') | ||
| 118 | break; | ||
| 119 | } | ||
| 120 | *p = 0; | ||
| 121 | return str; | ||
| 122 | } | ||
| 123 | |||
| 124 | void xmon_printf(const char *format, ...) | ||
| 125 | { | ||
| 126 | va_list args; | ||
| 127 | int n; | ||
| 128 | static char xmon_outbuf[1024]; | ||
| 129 | |||
| 130 | va_start(args, format); | ||
| 131 | n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args); | ||
| 132 | va_end(args); | ||
| 133 | xmon_write(xmon_outbuf, n); | ||
| 134 | } | ||
diff --git a/arch/powerpc/xmon/nonstdio.h b/arch/powerpc/xmon/nonstdio.h index 84211a21c6f4..47cebbd2b1b1 100644 --- a/arch/powerpc/xmon/nonstdio.h +++ b/arch/powerpc/xmon/nonstdio.h | |||
| @@ -1,22 +1,14 @@ | |||
| 1 | typedef int FILE; | ||
| 2 | extern FILE *xmon_stdin, *xmon_stdout; | ||
| 3 | #define EOF (-1) | 1 | #define EOF (-1) |
| 4 | #define stdin xmon_stdin | 2 | |
| 5 | #define stdout xmon_stdout | ||
| 6 | #define printf xmon_printf | 3 | #define printf xmon_printf |
| 7 | #define fprintf xmon_fprintf | ||
| 8 | #define fputs xmon_fputs | ||
| 9 | #define fgets xmon_fgets | ||
| 10 | #define putchar xmon_putchar | 4 | #define putchar xmon_putchar |
| 11 | #define getchar xmon_getchar | ||
| 12 | #define putc xmon_putc | ||
| 13 | #define getc xmon_getc | ||
| 14 | #define fopen(n, m) NULL | ||
| 15 | #define fflush(f) do {} while (0) | ||
| 16 | #define fclose(f) do {} while (0) | ||
| 17 | extern char *fgets(char *, int, void *); | ||
| 18 | extern void xmon_printf(const char *, ...); | ||
| 19 | extern void xmon_fprintf(void *, const char *, ...); | ||
| 20 | extern void xmon_sprintf(char *, const char *, ...); | ||
| 21 | 5 | ||
| 22 | #define perror(s) printf("%s: no files!\n", (s)) | 6 | extern int xmon_putchar(int c); |
| 7 | extern int xmon_getchar(void); | ||
| 8 | extern char *xmon_gets(char *, int); | ||
| 9 | extern void xmon_printf(const char *, ...); | ||
| 10 | extern void xmon_map_scc(void); | ||
| 11 | extern int xmon_expect(const char *str, unsigned long timeout); | ||
| 12 | extern int xmon_write(void *ptr, int nb); | ||
| 13 | extern int xmon_readchar(void); | ||
| 14 | extern int xmon_read_poll(void); | ||
diff --git a/arch/powerpc/xmon/setjmp.S b/arch/powerpc/xmon/setjmp.S index f8e40dfd2bff..96a91f10e2ec 100644 --- a/arch/powerpc/xmon/setjmp.S +++ b/arch/powerpc/xmon/setjmp.S | |||
| @@ -14,61 +14,61 @@ | |||
| 14 | 14 | ||
| 15 | _GLOBAL(xmon_setjmp) | 15 | _GLOBAL(xmon_setjmp) |
| 16 | mflr r0 | 16 | mflr r0 |
| 17 | STL r0,0(r3) | 17 | PPC_STL r0,0(r3) |
| 18 | STL r1,SZL(r3) | 18 | PPC_STL r1,SZL(r3) |
| 19 | STL r2,2*SZL(r3) | 19 | PPC_STL r2,2*SZL(r3) |
| 20 | mfcr r0 | 20 | mfcr r0 |
| 21 | STL r0,3*SZL(r3) | 21 | PPC_STL r0,3*SZL(r3) |
| 22 | STL r13,4*SZL(r3) | 22 | PPC_STL r13,4*SZL(r3) |
| 23 | STL r14,5*SZL(r3) | 23 | PPC_STL r14,5*SZL(r3) |
| 24 | STL r15,6*SZL(r3) | 24 | PPC_STL r15,6*SZL(r3) |
| 25 | STL r16,7*SZL(r3) | 25 | PPC_STL r16,7*SZL(r3) |
| 26 | STL r17,8*SZL(r3) | 26 | PPC_STL r17,8*SZL(r3) |
| 27 | STL r18,9*SZL(r3) | 27 | PPC_STL r18,9*SZL(r3) |
| 28 | STL r19,10*SZL(r3) | 28 | PPC_STL r19,10*SZL(r3) |
| 29 | STL r20,11*SZL(r3) | 29 | PPC_STL r20,11*SZL(r3) |
| 30 | STL r21,12*SZL(r3) | 30 | PPC_STL r21,12*SZL(r3) |
| 31 | STL r22,13*SZL(r3) | 31 | PPC_STL r22,13*SZL(r3) |
| 32 | STL r23,14*SZL(r3) | 32 | PPC_STL r23,14*SZL(r3) |
| 33 | STL r24,15*SZL(r3) | 33 | PPC_STL r24,15*SZL(r3) |
| 34 | STL r25,16*SZL(r3) | 34 | PPC_STL r25,16*SZL(r3) |
| 35 | STL r26,17*SZL(r3) | 35 | PPC_STL r26,17*SZL(r3) |
| 36 | STL r27,18*SZL(r3) | 36 | PPC_STL r27,18*SZL(r3) |
| 37 | STL r28,19*SZL(r3) | 37 | PPC_STL r28,19*SZL(r3) |
| 38 | STL r29,20*SZL(r3) | 38 | PPC_STL r29,20*SZL(r3) |
| 39 | STL r30,21*SZL(r3) | 39 | PPC_STL r30,21*SZL(r3) |
| 40 | STL r31,22*SZL(r3) | 40 | PPC_STL r31,22*SZL(r3) |
| 41 | li r3,0 | 41 | li r3,0 |
| 42 | blr | 42 | blr |
| 43 | 43 | ||
| 44 | _GLOBAL(xmon_longjmp) | 44 | _GLOBAL(xmon_longjmp) |
| 45 | CMPI r4,0 | 45 | PPC_LCMPI r4,0 |
| 46 | bne 1f | 46 | bne 1f |
| 47 | li r4,1 | 47 | li r4,1 |
| 48 | 1: LDL r13,4*SZL(r3) | 48 | 1: PPC_LL r13,4*SZL(r3) |
| 49 | LDL r14,5*SZL(r3) | 49 | PPC_LL r14,5*SZL(r3) |
| 50 | LDL r15,6*SZL(r3) | 50 | PPC_LL r15,6*SZL(r3) |
| 51 | LDL r16,7*SZL(r3) | 51 | PPC_LL r16,7*SZL(r3) |
| 52 | LDL r17,8*SZL(r3) | 52 | PPC_LL r17,8*SZL(r3) |
| 53 | LDL r18,9*SZL(r3) | 53 | PPC_LL r18,9*SZL(r3) |
| 54 | LDL r19,10*SZL(r3) | 54 | PPC_LL r19,10*SZL(r3) |
| 55 | LDL r20,11*SZL(r3) | 55 | PPC_LL r20,11*SZL(r3) |
| 56 | LDL r21,12*SZL(r3) | 56 | PPC_LL r21,12*SZL(r3) |
| 57 | LDL r22,13*SZL(r3) | 57 | PPC_LL r22,13*SZL(r3) |
| 58 | LDL r23,14*SZL(r3) | 58 | PPC_LL r23,14*SZL(r3) |
| 59 | LDL r24,15*SZL(r3) | 59 | PPC_LL r24,15*SZL(r3) |
| 60 | LDL r25,16*SZL(r3) | 60 | PPC_LL r25,16*SZL(r3) |
| 61 | LDL r26,17*SZL(r3) | 61 | PPC_LL r26,17*SZL(r3) |
| 62 | LDL r27,18*SZL(r3) | 62 | PPC_LL r27,18*SZL(r3) |
| 63 | LDL r28,19*SZL(r3) | 63 | PPC_LL r28,19*SZL(r3) |
| 64 | LDL r29,20*SZL(r3) | 64 | PPC_LL r29,20*SZL(r3) |
| 65 | LDL r30,21*SZL(r3) | 65 | PPC_LL r30,21*SZL(r3) |
| 66 | LDL r31,22*SZL(r3) | 66 | PPC_LL r31,22*SZL(r3) |
| 67 | LDL r0,3*SZL(r3) | 67 | PPC_LL r0,3*SZL(r3) |
| 68 | mtcrf 0x38,r0 | 68 | mtcrf 0x38,r0 |
| 69 | LDL r0,0(r3) | 69 | PPC_LL r0,0(r3) |
| 70 | LDL r1,SZL(r3) | 70 | PPC_LL r1,SZL(r3) |
| 71 | LDL r2,2*SZL(r3) | 71 | PPC_LL r2,2*SZL(r3) |
| 72 | mtlr r0 | 72 | mtlr r0 |
| 73 | mr r3,r4 | 73 | mr r3,r4 |
| 74 | blr | 74 | blr |
| @@ -84,52 +84,52 @@ _GLOBAL(xmon_longjmp) | |||
| 84 | * different ABIs, though). | 84 | * different ABIs, though). |
| 85 | */ | 85 | */ |
| 86 | _GLOBAL(xmon_save_regs) | 86 | _GLOBAL(xmon_save_regs) |
| 87 | STL r0,0*SZL(r3) | 87 | PPC_STL r0,0*SZL(r3) |
| 88 | STL r2,2*SZL(r3) | 88 | PPC_STL r2,2*SZL(r3) |
| 89 | STL r3,3*SZL(r3) | 89 | PPC_STL r3,3*SZL(r3) |
| 90 | STL r4,4*SZL(r3) | 90 | PPC_STL r4,4*SZL(r3) |
| 91 | STL r5,5*SZL(r3) | 91 | PPC_STL r5,5*SZL(r3) |
| 92 | STL r6,6*SZL(r3) | 92 | PPC_STL r6,6*SZL(r3) |
| 93 | STL r7,7*SZL(r3) | 93 | PPC_STL r7,7*SZL(r3) |
| 94 | STL r8,8*SZL(r3) | 94 | PPC_STL r8,8*SZL(r3) |
| 95 | STL r9,9*SZL(r3) | 95 | PPC_STL r9,9*SZL(r3) |
| 96 | STL r10,10*SZL(r3) | 96 | PPC_STL r10,10*SZL(r3) |
| 97 | STL r11,11*SZL(r3) | 97 | PPC_STL r11,11*SZL(r3) |
| 98 | STL r12,12*SZL(r3) | 98 | PPC_STL r12,12*SZL(r3) |
| 99 | STL r13,13*SZL(r3) | 99 | PPC_STL r13,13*SZL(r3) |
| 100 | STL r14,14*SZL(r3) | 100 | PPC_STL r14,14*SZL(r3) |
| 101 | STL r15,15*SZL(r3) | 101 | PPC_STL r15,15*SZL(r3) |
| 102 | STL r16,16*SZL(r3) | 102 | PPC_STL r16,16*SZL(r3) |
| 103 | STL r17,17*SZL(r3) | 103 | PPC_STL r17,17*SZL(r3) |
| 104 | STL r18,18*SZL(r3) | 104 | PPC_STL r18,18*SZL(r3) |
| 105 | STL r19,19*SZL(r3) | 105 | PPC_STL r19,19*SZL(r3) |
| 106 | STL r20,20*SZL(r3) | 106 | PPC_STL r20,20*SZL(r3) |
| 107 | STL r21,21*SZL(r3) | 107 | PPC_STL r21,21*SZL(r3) |
| 108 | STL r22,22*SZL(r3) | 108 | PPC_STL r22,22*SZL(r3) |
| 109 | STL r23,23*SZL(r3) | 109 | PPC_STL r23,23*SZL(r3) |
| 110 | STL r24,24*SZL(r3) | 110 | PPC_STL r24,24*SZL(r3) |
| 111 | STL r25,25*SZL(r3) | 111 | PPC_STL r25,25*SZL(r3) |
| 112 | STL r26,26*SZL(r3) | 112 | PPC_STL r26,26*SZL(r3) |
| 113 | STL r27,27*SZL(r3) | 113 | PPC_STL r27,27*SZL(r3) |
| 114 | STL r28,28*SZL(r3) | 114 | PPC_STL r28,28*SZL(r3) |
| 115 | STL r29,29*SZL(r3) | 115 | PPC_STL r29,29*SZL(r3) |
| 116 | STL r30,30*SZL(r3) | 116 | PPC_STL r30,30*SZL(r3) |
| 117 | STL r31,31*SZL(r3) | 117 | PPC_STL r31,31*SZL(r3) |
| 118 | /* go up one stack frame for SP */ | 118 | /* go up one stack frame for SP */ |
| 119 | LDL r4,0(r1) | 119 | PPC_LL r4,0(r1) |
| 120 | STL r4,1*SZL(r3) | 120 | PPC_STL r4,1*SZL(r3) |
| 121 | /* get caller's LR */ | 121 | /* get caller's LR */ |
| 122 | LDL r0,LRSAVE(r4) | 122 | PPC_LL r0,LRSAVE(r4) |
| 123 | STL r0,_NIP-STACK_FRAME_OVERHEAD(r3) | 123 | PPC_STL r0,_NIP-STACK_FRAME_OVERHEAD(r3) |
| 124 | STL r0,_LINK-STACK_FRAME_OVERHEAD(r3) | 124 | PPC_STL r0,_LINK-STACK_FRAME_OVERHEAD(r3) |
| 125 | mfmsr r0 | 125 | mfmsr r0 |
| 126 | STL r0,_MSR-STACK_FRAME_OVERHEAD(r3) | 126 | PPC_STL r0,_MSR-STACK_FRAME_OVERHEAD(r3) |
| 127 | mfctr r0 | 127 | mfctr r0 |
| 128 | STL r0,_CTR-STACK_FRAME_OVERHEAD(r3) | 128 | PPC_STL r0,_CTR-STACK_FRAME_OVERHEAD(r3) |
| 129 | mfxer r0 | 129 | mfxer r0 |
| 130 | STL r0,_XER-STACK_FRAME_OVERHEAD(r3) | 130 | PPC_STL r0,_XER-STACK_FRAME_OVERHEAD(r3) |
| 131 | mfcr r0 | 131 | mfcr r0 |
| 132 | STL r0,_CCR-STACK_FRAME_OVERHEAD(r3) | 132 | PPC_STL r0,_CCR-STACK_FRAME_OVERHEAD(r3) |
| 133 | li r0,0 | 133 | li r0,0 |
| 134 | STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3) | 134 | PPC_STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3) |
| 135 | blr | 135 | blr |
diff --git a/arch/powerpc/xmon/start_32.c b/arch/powerpc/xmon/start_32.c index 69b658c0f760..c2464df4217e 100644 --- a/arch/powerpc/xmon/start_32.c +++ b/arch/powerpc/xmon/start_32.c | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | #include <linux/cuda.h> | 11 | #include <linux/cuda.h> |
| 12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
| 13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
| 14 | #include <linux/sysrq.h> | ||
| 15 | #include <linux/bitops.h> | 14 | #include <linux/bitops.h> |
| 16 | #include <asm/xmon.h> | 15 | #include <asm/xmon.h> |
| 17 | #include <asm/prom.h> | 16 | #include <asm/prom.h> |
| @@ -22,10 +21,11 @@ | |||
| 22 | #include <asm/processor.h> | 21 | #include <asm/processor.h> |
| 23 | #include <asm/delay.h> | 22 | #include <asm/delay.h> |
| 24 | #include <asm/btext.h> | 23 | #include <asm/btext.h> |
| 24 | #include <asm/time.h> | ||
| 25 | #include "nonstdio.h" | ||
| 25 | 26 | ||
| 26 | static volatile unsigned char __iomem *sccc, *sccd; | 27 | static volatile unsigned char __iomem *sccc, *sccd; |
| 27 | unsigned int TXRDY, RXRDY, DLAB; | 28 | unsigned int TXRDY, RXRDY, DLAB; |
| 28 | static int xmon_expect(const char *str, unsigned int timeout); | ||
| 29 | 29 | ||
| 30 | static int use_serial; | 30 | static int use_serial; |
| 31 | static int use_screen; | 31 | static int use_screen; |
| @@ -33,16 +33,6 @@ static int via_modem; | |||
| 33 | static int xmon_use_sccb; | 33 | static int xmon_use_sccb; |
| 34 | static struct device_node *channel_node; | 34 | static struct device_node *channel_node; |
| 35 | 35 | ||
| 36 | #define TB_SPEED 25000000 | ||
| 37 | |||
| 38 | static inline unsigned int readtb(void) | ||
| 39 | { | ||
| 40 | unsigned int ret; | ||
| 41 | |||
| 42 | asm volatile("mftb %0" : "=r" (ret) :); | ||
| 43 | return ret; | ||
| 44 | } | ||
| 45 | |||
| 46 | void buf_access(void) | 36 | void buf_access(void) |
| 47 | { | 37 | { |
| 48 | if (DLAB) | 38 | if (DLAB) |
| @@ -91,23 +81,7 @@ static unsigned long chrp_find_phys_io_base(void) | |||
| 91 | } | 81 | } |
| 92 | #endif /* CONFIG_PPC_CHRP */ | 82 | #endif /* CONFIG_PPC_CHRP */ |
| 93 | 83 | ||
| 94 | #ifdef CONFIG_MAGIC_SYSRQ | 84 | void xmon_map_scc(void) |
| 95 | static void sysrq_handle_xmon(int key, struct pt_regs *regs, | ||
| 96 | struct tty_struct *tty) | ||
| 97 | { | ||
| 98 | xmon(regs); | ||
| 99 | } | ||
| 100 | |||
| 101 | static struct sysrq_key_op sysrq_xmon_op = | ||
| 102 | { | ||
| 103 | .handler = sysrq_handle_xmon, | ||
| 104 | .help_msg = "Xmon", | ||
| 105 | .action_msg = "Entering xmon", | ||
| 106 | }; | ||
| 107 | #endif | ||
| 108 | |||
| 109 | void | ||
| 110 | xmon_map_scc(void) | ||
| 111 | { | 85 | { |
| 112 | #ifdef CONFIG_PPC_MULTIPLATFORM | 86 | #ifdef CONFIG_PPC_MULTIPLATFORM |
| 113 | volatile unsigned char __iomem *base; | 87 | volatile unsigned char __iomem *base; |
| @@ -217,8 +191,6 @@ xmon_map_scc(void) | |||
| 217 | RXRDY = 1; | 191 | RXRDY = 1; |
| 218 | DLAB = 0x80; | 192 | DLAB = 0x80; |
| 219 | #endif /* platform */ | 193 | #endif /* platform */ |
| 220 | |||
| 221 | register_sysrq_key('x', &sysrq_xmon_op); | ||
| 222 | } | 194 | } |
| 223 | 195 | ||
| 224 | static int scc_initialized = 0; | 196 | static int scc_initialized = 0; |
| @@ -238,8 +210,7 @@ static inline void do_poll_adb(void) | |||
| 238 | #endif /* CONFIG_ADB_CUDA */ | 210 | #endif /* CONFIG_ADB_CUDA */ |
| 239 | } | 211 | } |
| 240 | 212 | ||
| 241 | int | 213 | int xmon_write(void *ptr, int nb) |
| 242 | xmon_write(void *handle, void *ptr, int nb) | ||
| 243 | { | 214 | { |
| 244 | char *p = ptr; | 215 | char *p = ptr; |
| 245 | int i, c, ct; | 216 | int i, c, ct; |
| @@ -311,8 +282,7 @@ static unsigned char xmon_shift_keytab[128] = | |||
| 311 | "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ | 282 | "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ |
| 312 | "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ | 283 | "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ |
| 313 | 284 | ||
| 314 | static int | 285 | static int xmon_get_adb_key(void) |
| 315 | xmon_get_adb_key(void) | ||
| 316 | { | 286 | { |
| 317 | int k, t, on; | 287 | int k, t, on; |
| 318 | 288 | ||
| @@ -350,32 +320,21 @@ xmon_get_adb_key(void) | |||
| 350 | } | 320 | } |
| 351 | #endif /* CONFIG_BOOTX_TEXT */ | 321 | #endif /* CONFIG_BOOTX_TEXT */ |
| 352 | 322 | ||
| 353 | int | 323 | int xmon_readchar(void) |
| 354 | xmon_read(void *handle, void *ptr, int nb) | ||
| 355 | { | 324 | { |
| 356 | char *p = ptr; | ||
| 357 | int i; | ||
| 358 | |||
| 359 | #ifdef CONFIG_BOOTX_TEXT | 325 | #ifdef CONFIG_BOOTX_TEXT |
| 360 | if (use_screen) { | 326 | if (use_screen) |
| 361 | for (i = 0; i < nb; ++i) | 327 | return xmon_get_adb_key(); |
| 362 | *p++ = xmon_get_adb_key(); | ||
| 363 | return i; | ||
| 364 | } | ||
| 365 | #endif | 328 | #endif |
| 366 | if (!scc_initialized) | 329 | if (!scc_initialized) |
| 367 | xmon_init_scc(); | 330 | xmon_init_scc(); |
| 368 | for (i = 0; i < nb; ++i) { | ||
| 369 | while ((*sccc & RXRDY) == 0) | 331 | while ((*sccc & RXRDY) == 0) |
| 370 | do_poll_adb(); | 332 | do_poll_adb(); |
| 371 | buf_access(); | 333 | buf_access(); |
| 372 | *p++ = *sccd; | 334 | return *sccd; |
| 373 | } | ||
| 374 | return i; | ||
| 375 | } | 335 | } |
| 376 | 336 | ||
| 377 | int | 337 | int xmon_read_poll(void) |
| 378 | xmon_read_poll(void) | ||
| 379 | { | 338 | { |
| 380 | if ((*sccc & RXRDY) == 0) { | 339 | if ((*sccc & RXRDY) == 0) { |
| 381 | do_poll_adb(); | 340 | do_poll_adb(); |
| @@ -395,8 +354,7 @@ static unsigned char scc_inittab[] = { | |||
| 395 | 3, 0xc1, /* rx enable, 8 bits */ | 354 | 3, 0xc1, /* rx enable, 8 bits */ |
| 396 | }; | 355 | }; |
| 397 | 356 | ||
| 398 | void | 357 | void xmon_init_scc(void) |
| 399 | xmon_init_scc(void) | ||
| 400 | { | 358 | { |
| 401 | if ( _machine == _MACH_chrp ) | 359 | if ( _machine == _MACH_chrp ) |
| 402 | { | 360 | { |
| @@ -410,6 +368,7 @@ xmon_init_scc(void) | |||
| 410 | else if ( _machine == _MACH_Pmac ) | 368 | else if ( _machine == _MACH_Pmac ) |
| 411 | { | 369 | { |
| 412 | int i, x; | 370 | int i, x; |
| 371 | unsigned long timeout; | ||
| 413 | 372 | ||
| 414 | if (channel_node != 0) | 373 | if (channel_node != 0) |
| 415 | pmac_call_feature( | 374 | pmac_call_feature( |
| @@ -424,8 +383,12 @@ xmon_init_scc(void) | |||
| 424 | PMAC_FTR_MODEM_ENABLE, | 383 | PMAC_FTR_MODEM_ENABLE, |
| 425 | channel_node, 0, 1); | 384 | channel_node, 0, 1); |
| 426 | printk(KERN_INFO "Modem powered up by debugger !\n"); | 385 | printk(KERN_INFO "Modem powered up by debugger !\n"); |
| 427 | t0 = readtb(); | 386 | t0 = get_tbl(); |
| 428 | while (readtb() - t0 < 3*TB_SPEED) | 387 | timeout = 3 * tb_ticks_per_sec; |
| 388 | if (timeout == 0) | ||
| 389 | /* assume 25MHz if tb_ticks_per_sec not set */ | ||
| 390 | timeout = 75000000; | ||
| 391 | while (get_tbl() - t0 < timeout) | ||
| 429 | eieio(); | 392 | eieio(); |
| 430 | } | 393 | } |
| 431 | /* use the B channel if requested */ | 394 | /* use the B channel if requested */ |
| @@ -447,164 +410,19 @@ xmon_init_scc(void) | |||
| 447 | scc_initialized = 1; | 410 | scc_initialized = 1; |
| 448 | if (via_modem) { | 411 | if (via_modem) { |
| 449 | for (;;) { | 412 | for (;;) { |
| 450 | xmon_write(NULL, "ATE1V1\r", 7); | 413 | xmon_write("ATE1V1\r", 7); |
| 451 | if (xmon_expect("OK", 5)) { | 414 | if (xmon_expect("OK", 5)) { |
| 452 | xmon_write(NULL, "ATA\r", 4); | 415 | xmon_write("ATA\r", 4); |
| 453 | if (xmon_expect("CONNECT", 40)) | 416 | if (xmon_expect("CONNECT", 40)) |
| 454 | break; | 417 | break; |
| 455 | } | 418 | } |
| 456 | xmon_write(NULL, "+++", 3); | 419 | xmon_write("+++", 3); |
| 457 | xmon_expect("OK", 3); | 420 | xmon_expect("OK", 3); |
| 458 | } | 421 | } |
| 459 | } | 422 | } |
| 460 | } | 423 | } |
| 461 | 424 | ||
| 462 | void *xmon_stdin; | 425 | void xmon_enter(void) |
| 463 | void *xmon_stdout; | ||
| 464 | void *xmon_stderr; | ||
| 465 | |||
| 466 | int xmon_putc(int c, void *f) | ||
| 467 | { | ||
| 468 | char ch = c; | ||
| 469 | |||
| 470 | if (c == '\n') | ||
| 471 | xmon_putc('\r', f); | ||
| 472 | return xmon_write(f, &ch, 1) == 1? c: -1; | ||
| 473 | } | ||
| 474 | |||
| 475 | int xmon_putchar(int c) | ||
| 476 | { | ||
| 477 | return xmon_putc(c, xmon_stdout); | ||
| 478 | } | ||
| 479 | |||
| 480 | int xmon_fputs(char *str, void *f) | ||
| 481 | { | ||
| 482 | int n = strlen(str); | ||
| 483 | |||
| 484 | return xmon_write(f, str, n) == n? 0: -1; | ||
| 485 | } | ||
| 486 | |||
| 487 | int | ||
| 488 | xmon_readchar(void) | ||
| 489 | { | ||
| 490 | char ch; | ||
| 491 | |||
| 492 | for (;;) { | ||
| 493 | switch (xmon_read(xmon_stdin, &ch, 1)) { | ||
| 494 | case 1: | ||
| 495 | return ch; | ||
| 496 | case -1: | ||
| 497 | xmon_printf("read(stdin) returned -1\r\n", 0, 0); | ||
| 498 | return -1; | ||
| 499 | } | ||
| 500 | } | ||
| 501 | } | ||
| 502 | |||
| 503 | static char line[256]; | ||
| 504 | static char *lineptr; | ||
| 505 | static int lineleft; | ||
| 506 | |||
| 507 | int xmon_expect(const char *str, unsigned int timeout) | ||
| 508 | { | ||
| 509 | int c; | ||
| 510 | unsigned int t0; | ||
| 511 | |||
| 512 | timeout *= TB_SPEED; | ||
| 513 | t0 = readtb(); | ||
| 514 | do { | ||
| 515 | lineptr = line; | ||
| 516 | for (;;) { | ||
| 517 | c = xmon_read_poll(); | ||
| 518 | if (c == -1) { | ||
| 519 | if (readtb() - t0 > timeout) | ||
| 520 | return 0; | ||
| 521 | continue; | ||
| 522 | } | ||
| 523 | if (c == '\n') | ||
| 524 | break; | ||
| 525 | if (c != '\r' && lineptr < &line[sizeof(line) - 1]) | ||
| 526 | *lineptr++ = c; | ||
| 527 | } | ||
| 528 | *lineptr = 0; | ||
| 529 | } while (strstr(line, str) == NULL); | ||
| 530 | return 1; | ||
| 531 | } | ||
| 532 | |||
| 533 | int | ||
| 534 | xmon_getchar(void) | ||
| 535 | { | ||
| 536 | int c; | ||
| 537 | |||
| 538 | if (lineleft == 0) { | ||
| 539 | lineptr = line; | ||
| 540 | for (;;) { | ||
| 541 | c = xmon_readchar(); | ||
| 542 | if (c == -1 || c == 4) | ||
| 543 | break; | ||
| 544 | if (c == '\r' || c == '\n') { | ||
| 545 | *lineptr++ = '\n'; | ||
| 546 | xmon_putchar('\n'); | ||
| 547 | break; | ||
| 548 | } | ||
| 549 | switch (c) { | ||
| 550 | case 0177: | ||
| 551 | case '\b': | ||
| 552 | if (lineptr > line) { | ||
| 553 | xmon_putchar('\b'); | ||
| 554 | xmon_putchar(' '); | ||
| 555 | xmon_putchar('\b'); | ||
| 556 | --lineptr; | ||
| 557 | } | ||
| 558 | break; | ||
| 559 | case 'U' & 0x1F: | ||
| 560 | while (lineptr > line) { | ||
| 561 | xmon_putchar('\b'); | ||
| 562 | xmon_putchar(' '); | ||
| 563 | xmon_putchar('\b'); | ||
| 564 | --lineptr; | ||
| 565 | } | ||
| 566 | break; | ||
| 567 | default: | ||
| 568 | if (lineptr >= &line[sizeof(line) - 1]) | ||
| 569 | xmon_putchar('\a'); | ||
| 570 | else { | ||
| 571 | xmon_putchar(c); | ||
| 572 | *lineptr++ = c; | ||
| 573 | } | ||
| 574 | } | ||
| 575 | } | ||
| 576 | lineleft = lineptr - line; | ||
| 577 | lineptr = line; | ||
| 578 | } | ||
| 579 | if (lineleft == 0) | ||
| 580 | return -1; | ||
| 581 | --lineleft; | ||
| 582 | return *lineptr++; | ||
| 583 | } | ||
| 584 | |||
| 585 | char * | ||
| 586 | xmon_fgets(char *str, int nb, void *f) | ||
| 587 | { | ||
| 588 | char *p; | ||
| 589 | int c; | ||
| 590 | |||
| 591 | for (p = str; p < str + nb - 1; ) { | ||
| 592 | c = xmon_getchar(); | ||
| 593 | if (c == -1) { | ||
| 594 | if (p == str) | ||
| 595 | return NULL; | ||
| 596 | break; | ||
| 597 | } | ||
| 598 | *p++ = c; | ||
| 599 | if (c == '\n') | ||
| 600 | break; | ||
| 601 | } | ||
| 602 | *p = 0; | ||
| 603 | return str; | ||
| 604 | } | ||
| 605 | |||
| 606 | void | ||
| 607 | xmon_enter(void) | ||
| 608 | { | 426 | { |
| 609 | #ifdef CONFIG_ADB_PMU | 427 | #ifdef CONFIG_ADB_PMU |
| 610 | if (_machine == _MACH_Pmac) { | 428 | if (_machine == _MACH_Pmac) { |
| @@ -613,8 +431,7 @@ xmon_enter(void) | |||
| 613 | #endif | 431 | #endif |
| 614 | } | 432 | } |
| 615 | 433 | ||
| 616 | void | 434 | void xmon_leave(void) |
| 617 | xmon_leave(void) | ||
| 618 | { | 435 | { |
| 619 | #ifdef CONFIG_ADB_PMU | 436 | #ifdef CONFIG_ADB_PMU |
| 620 | if (_machine == _MACH_Pmac) { | 437 | if (_machine == _MACH_Pmac) { |
diff --git a/arch/powerpc/xmon/start_64.c b/arch/powerpc/xmon/start_64.c index e50c158191e1..712552c4f242 100644 --- a/arch/powerpc/xmon/start_64.c +++ b/arch/powerpc/xmon/start_64.c | |||
| @@ -6,182 +6,29 @@ | |||
| 6 | * as published by the Free Software Foundation; either version | 6 | * as published by the Free Software Foundation; either version |
| 7 | * 2 of the License, or (at your option) any later version. | 7 | * 2 of the License, or (at your option) any later version. |
| 8 | */ | 8 | */ |
| 9 | #include <linux/config.h> | ||
| 10 | #include <linux/string.h> | ||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/errno.h> | ||
| 13 | #include <linux/sysrq.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <asm/machdep.h> | 9 | #include <asm/machdep.h> |
| 16 | #include <asm/io.h> | ||
| 17 | #include <asm/page.h> | ||
| 18 | #include <asm/prom.h> | ||
| 19 | #include <asm/processor.h> | ||
| 20 | #include <asm/udbg.h> | 10 | #include <asm/udbg.h> |
| 21 | #include <asm/system.h> | ||
| 22 | #include "nonstdio.h" | 11 | #include "nonstdio.h" |
| 23 | 12 | ||
| 24 | #ifdef CONFIG_MAGIC_SYSRQ | 13 | void xmon_map_scc(void) |
| 25 | |||
| 26 | static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs, | ||
| 27 | struct tty_struct *tty) | ||
| 28 | { | ||
| 29 | /* ensure xmon is enabled */ | ||
| 30 | xmon_init(1); | ||
| 31 | debugger(pt_regs); | ||
| 32 | } | ||
| 33 | |||
| 34 | static struct sysrq_key_op sysrq_xmon_op = | ||
| 35 | { | 14 | { |
| 36 | .handler = sysrq_handle_xmon, | ||
| 37 | .help_msg = "Xmon", | ||
| 38 | .action_msg = "Entering xmon", | ||
| 39 | }; | ||
| 40 | |||
| 41 | static int __init setup_xmon_sysrq(void) | ||
| 42 | { | ||
| 43 | register_sysrq_key('x', &sysrq_xmon_op); | ||
| 44 | return 0; | ||
| 45 | } | 15 | } |
| 46 | __initcall(setup_xmon_sysrq); | ||
| 47 | #endif /* CONFIG_MAGIC_SYSRQ */ | ||
| 48 | 16 | ||
| 49 | int | 17 | int xmon_write(void *ptr, int nb) |
| 50 | xmon_write(void *handle, void *ptr, int nb) | ||
| 51 | { | 18 | { |
| 52 | return udbg_write(ptr, nb); | 19 | return udbg_write(ptr, nb); |
| 53 | } | 20 | } |
| 54 | 21 | ||
| 55 | int | 22 | int xmon_readchar(void) |
| 56 | xmon_read(void *handle, void *ptr, int nb) | ||
| 57 | { | 23 | { |
| 58 | return udbg_read(ptr, nb); | 24 | if (udbg_getc) |
| 25 | return udbg_getc(); | ||
| 26 | return -1; | ||
| 59 | } | 27 | } |
| 60 | 28 | ||
| 61 | int | 29 | int xmon_read_poll(void) |
| 62 | xmon_read_poll(void) | ||
| 63 | { | 30 | { |
| 64 | if (udbg_getc_poll) | 31 | if (udbg_getc_poll) |
| 65 | return udbg_getc_poll(); | 32 | return udbg_getc_poll(); |
| 66 | return -1; | 33 | return -1; |
| 67 | } | 34 | } |
| 68 | |||
| 69 | FILE *xmon_stdin; | ||
| 70 | FILE *xmon_stdout; | ||
| 71 | |||
| 72 | int | ||
| 73 | xmon_putc(int c, void *f) | ||
| 74 | { | ||
| 75 | char ch = c; | ||
| 76 | |||
| 77 | if (c == '\n') | ||
| 78 | xmon_putc('\r', f); | ||
| 79 | return xmon_write(f, &ch, 1) == 1? c: -1; | ||
| 80 | } | ||
| 81 | |||
| 82 | int | ||
| 83 | xmon_putchar(int c) | ||
| 84 | { | ||
| 85 | return xmon_putc(c, xmon_stdout); | ||
| 86 | } | ||
| 87 | |||
| 88 | int | ||
| 89 | xmon_fputs(char *str, void *f) | ||
| 90 | { | ||
| 91 | int n = strlen(str); | ||
| 92 | |||
| 93 | return xmon_write(f, str, n) == n? 0: -1; | ||
| 94 | } | ||
| 95 | |||
| 96 | int | ||
| 97 | xmon_readchar(void) | ||
| 98 | { | ||
| 99 | char ch; | ||
| 100 | |||
| 101 | for (;;) { | ||
| 102 | switch (xmon_read(xmon_stdin, &ch, 1)) { | ||
| 103 | case 1: | ||
| 104 | return ch; | ||
| 105 | case -1: | ||
| 106 | xmon_printf("read(stdin) returned -1\r\n", 0, 0); | ||
| 107 | return -1; | ||
| 108 | } | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | static char line[256]; | ||
| 113 | static char *lineptr; | ||
| 114 | static int lineleft; | ||
| 115 | |||
| 116 | int | ||
| 117 | xmon_getchar(void) | ||
| 118 | { | ||
| 119 | int c; | ||
| 120 | |||
| 121 | if (lineleft == 0) { | ||
| 122 | lineptr = line; | ||
| 123 | for (;;) { | ||
| 124 | c = xmon_readchar(); | ||
| 125 | if (c == -1 || c == 4) | ||
| 126 | break; | ||
| 127 | if (c == '\r' || c == '\n') { | ||
| 128 | *lineptr++ = '\n'; | ||
| 129 | xmon_putchar('\n'); | ||
| 130 | break; | ||
| 131 | } | ||
| 132 | switch (c) { | ||
| 133 | case 0177: | ||
| 134 | case '\b': | ||
| 135 | if (lineptr > line) { | ||
| 136 | xmon_putchar('\b'); | ||
| 137 | xmon_putchar(' '); | ||
| 138 | xmon_putchar('\b'); | ||
| 139 | --lineptr; | ||
| 140 | } | ||
| 141 | break; | ||
| 142 | case 'U' & 0x1F: | ||
| 143 | while (lineptr > line) { | ||
| 144 | xmon_putchar('\b'); | ||
| 145 | xmon_putchar(' '); | ||
| 146 | xmon_putchar('\b'); | ||
| 147 | --lineptr; | ||
| 148 | } | ||
| 149 | break; | ||
| 150 | default: | ||
| 151 | if (lineptr >= &line[sizeof(line) - 1]) | ||
| 152 | xmon_putchar('\a'); | ||
| 153 | else { | ||
| 154 | xmon_putchar(c); | ||
| 155 | *lineptr++ = c; | ||
| 156 | } | ||
| 157 | } | ||
| 158 | } | ||
| 159 | lineleft = lineptr - line; | ||
| 160 | lineptr = line; | ||
| 161 | } | ||
| 162 | if (lineleft == 0) | ||
| 163 | return -1; | ||
| 164 | --lineleft; | ||
| 165 | return *lineptr++; | ||
| 166 | } | ||
| 167 | |||
| 168 | char * | ||
| 169 | xmon_fgets(char *str, int nb, void *f) | ||
| 170 | { | ||
| 171 | char *p; | ||
| 172 | int c; | ||
| 173 | |||
| 174 | for (p = str; p < str + nb - 1; ) { | ||
| 175 | c = xmon_getchar(); | ||
| 176 | if (c == -1) { | ||
| 177 | if (p == str) | ||
| 178 | return NULL; | ||
| 179 | break; | ||
| 180 | } | ||
| 181 | *p++ = c; | ||
| 182 | if (c == '\n') | ||
| 183 | break; | ||
| 184 | } | ||
| 185 | *p = 0; | ||
| 186 | return str; | ||
| 187 | } | ||
diff --git a/arch/powerpc/xmon/start_8xx.c b/arch/powerpc/xmon/start_8xx.c index a48bd594cf61..4c17b0486ad5 100644 --- a/arch/powerpc/xmon/start_8xx.c +++ b/arch/powerpc/xmon/start_8xx.c | |||
| @@ -15,273 +15,30 @@ | |||
| 15 | #include <asm/8xx_immap.h> | 15 | #include <asm/8xx_immap.h> |
| 16 | #include <asm/mpc8xx.h> | 16 | #include <asm/mpc8xx.h> |
| 17 | #include <asm/commproc.h> | 17 | #include <asm/commproc.h> |
| 18 | #include "nonstdio.h" | ||
| 18 | 19 | ||
| 19 | extern void xmon_printf(const char *fmt, ...); | ||
| 20 | extern int xmon_8xx_write(char *str, int nb); | 20 | extern int xmon_8xx_write(char *str, int nb); |
| 21 | extern int xmon_8xx_read_poll(void); | 21 | extern int xmon_8xx_read_poll(void); |
| 22 | extern int xmon_8xx_read_char(void); | 22 | extern int xmon_8xx_read_char(void); |
| 23 | void prom_drawhex(uint); | ||
| 24 | void prom_drawstring(const char *str); | ||
| 25 | 23 | ||
| 26 | static int use_screen = 1; /* default */ | 24 | void xmon_map_scc(void) |
| 27 | |||
| 28 | #define TB_SPEED 25000000 | ||
| 29 | |||
| 30 | static inline unsigned int readtb(void) | ||
| 31 | { | ||
| 32 | unsigned int ret; | ||
| 33 | |||
| 34 | asm volatile("mftb %0" : "=r" (ret) :); | ||
| 35 | return ret; | ||
| 36 | } | ||
| 37 | |||
| 38 | void buf_access(void) | ||
| 39 | { | ||
| 40 | } | ||
| 41 | |||
| 42 | void | ||
| 43 | xmon_map_scc(void) | ||
| 44 | { | 25 | { |
| 45 | |||
| 46 | cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); | 26 | cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); |
| 47 | use_screen = 0; | ||
| 48 | |||
| 49 | prom_drawstring("xmon uses serial port\n"); | ||
| 50 | } | 27 | } |
| 51 | 28 | ||
| 52 | static int scc_initialized = 0; | ||
| 53 | |||
| 54 | void xmon_init_scc(void); | 29 | void xmon_init_scc(void); |
| 55 | 30 | ||
| 56 | int | 31 | int xmon_write(void *ptr, int nb) |
| 57 | xmon_write(void *handle, void *ptr, int nb) | ||
| 58 | { | 32 | { |
| 59 | char *p = ptr; | ||
| 60 | int i, c, ct; | ||
| 61 | |||
| 62 | if (!scc_initialized) | ||
| 63 | xmon_init_scc(); | ||
| 64 | |||
| 65 | return(xmon_8xx_write(ptr, nb)); | 33 | return(xmon_8xx_write(ptr, nb)); |
| 66 | } | 34 | } |
| 67 | 35 | ||
| 68 | int xmon_wants_key; | 36 | int xmon_readchar(void) |
| 69 | |||
| 70 | int | ||
| 71 | xmon_read(void *handle, void *ptr, int nb) | ||
| 72 | { | 37 | { |
| 73 | char *p = ptr; | 38 | return xmon_8xx_read_char(); |
| 74 | int i; | ||
| 75 | |||
| 76 | if (!scc_initialized) | ||
| 77 | xmon_init_scc(); | ||
| 78 | |||
| 79 | for (i = 0; i < nb; ++i) { | ||
| 80 | *p++ = xmon_8xx_read_char(); | ||
| 81 | } | ||
| 82 | return i; | ||
| 83 | } | 39 | } |
| 84 | 40 | ||
| 85 | int | 41 | int xmon_read_poll(void) |
| 86 | xmon_read_poll(void) | ||
| 87 | { | 42 | { |
| 88 | return(xmon_8xx_read_poll()); | 43 | return(xmon_8xx_read_poll()); |
| 89 | } | 44 | } |
| 90 | |||
| 91 | void | ||
| 92 | xmon_init_scc() | ||
| 93 | { | ||
| 94 | scc_initialized = 1; | ||
| 95 | } | ||
| 96 | |||
| 97 | #if 0 | ||
| 98 | extern int (*prom_entry)(void *); | ||
| 99 | |||
| 100 | int | ||
| 101 | xmon_exit(void) | ||
| 102 | { | ||
| 103 | struct prom_args { | ||
| 104 | char *service; | ||
| 105 | } args; | ||
| 106 | |||
| 107 | for (;;) { | ||
| 108 | args.service = "exit"; | ||
| 109 | (*prom_entry)(&args); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | #endif | ||
| 113 | |||
| 114 | void *xmon_stdin; | ||
| 115 | void *xmon_stdout; | ||
| 116 | void *xmon_stderr; | ||
| 117 | |||
| 118 | void | ||
| 119 | xmon_init(void) | ||
| 120 | { | ||
| 121 | } | ||
| 122 | |||
| 123 | int | ||
| 124 | xmon_putc(int c, void *f) | ||
| 125 | { | ||
| 126 | char ch = c; | ||
| 127 | |||
| 128 | if (c == '\n') | ||
| 129 | xmon_putc('\r', f); | ||
| 130 | return xmon_write(f, &ch, 1) == 1? c: -1; | ||
| 131 | } | ||
| 132 | |||
| 133 | int | ||
| 134 | xmon_putchar(int c) | ||
| 135 | { | ||
| 136 | return xmon_putc(c, xmon_stdout); | ||
| 137 | } | ||
| 138 | |||
| 139 | int | ||
| 140 | xmon_fputs(char *str, void *f) | ||
| 141 | { | ||
| 142 | int n = strlen(str); | ||
| 143 | |||
| 144 | return xmon_write(f, str, n) == n? 0: -1; | ||
| 145 | } | ||
| 146 | |||
| 147 | int | ||
| 148 | xmon_readchar(void) | ||
| 149 | { | ||
| 150 | char ch; | ||
| 151 | |||
| 152 | for (;;) { | ||
| 153 | switch (xmon_read(xmon_stdin, &ch, 1)) { | ||
| 154 | case 1: | ||
| 155 | return ch; | ||
| 156 | case -1: | ||
| 157 | xmon_printf("read(stdin) returned -1\r\n", 0, 0); | ||
| 158 | return -1; | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | static char line[256]; | ||
| 164 | static char *lineptr; | ||
| 165 | static int lineleft; | ||
| 166 | |||
| 167 | #if 0 | ||
| 168 | int xmon_expect(const char *str, unsigned int timeout) | ||
| 169 | { | ||
| 170 | int c; | ||
| 171 | unsigned int t0; | ||
| 172 | |||
| 173 | timeout *= TB_SPEED; | ||
| 174 | t0 = readtb(); | ||
| 175 | do { | ||
| 176 | lineptr = line; | ||
| 177 | for (;;) { | ||
| 178 | c = xmon_read_poll(); | ||
| 179 | if (c == -1) { | ||
| 180 | if (readtb() - t0 > timeout) | ||
| 181 | return 0; | ||
| 182 | continue; | ||
| 183 | } | ||
| 184 | if (c == '\n') | ||
| 185 | break; | ||
| 186 | if (c != '\r' && lineptr < &line[sizeof(line) - 1]) | ||
| 187 | *lineptr++ = c; | ||
| 188 | } | ||
| 189 | *lineptr = 0; | ||
| 190 | } while (strstr(line, str) == NULL); | ||
| 191 | return 1; | ||
| 192 | } | ||
| 193 | #endif | ||
| 194 | |||
| 195 | int | ||
| 196 | xmon_getchar(void) | ||
| 197 | { | ||
| 198 | int c; | ||
| 199 | |||
| 200 | if (lineleft == 0) { | ||
| 201 | lineptr = line; | ||
| 202 | for (;;) { | ||
| 203 | c = xmon_readchar(); | ||
| 204 | if (c == -1 || c == 4) | ||
| 205 | break; | ||
| 206 | if (c == '\r' || c == '\n') { | ||
| 207 | *lineptr++ = '\n'; | ||
| 208 | xmon_putchar('\n'); | ||
| 209 | break; | ||
| 210 | } | ||
| 211 | switch (c) { | ||
| 212 | case 0177: | ||
| 213 | case '\b': | ||
| 214 | if (lineptr > line) { | ||
| 215 | xmon_putchar('\b'); | ||
| 216 | xmon_putchar(' '); | ||
| 217 | xmon_putchar('\b'); | ||
| 218 | --lineptr; | ||
| 219 | } | ||
| 220 | break; | ||
| 221 | case 'U' & 0x1F: | ||
| 222 | while (lineptr > line) { | ||
| 223 | xmon_putchar('\b'); | ||
| 224 | xmon_putchar(' '); | ||
| 225 | xmon_putchar('\b'); | ||
| 226 | --lineptr; | ||
| 227 | } | ||
| 228 | break; | ||
| 229 | default: | ||
| 230 | if (lineptr >= &line[sizeof(line) - 1]) | ||
| 231 | xmon_putchar('\a'); | ||
| 232 | else { | ||
| 233 | xmon_putchar(c); | ||
| 234 | *lineptr++ = c; | ||
| 235 | } | ||
| 236 | } | ||
| 237 | } | ||
| 238 | lineleft = lineptr - line; | ||
| 239 | lineptr = line; | ||
| 240 | } | ||
| 241 | if (lineleft == 0) | ||
| 242 | return -1; | ||
| 243 | --lineleft; | ||
| 244 | return *lineptr++; | ||
| 245 | } | ||
| 246 | |||
| 247 | char * | ||
| 248 | xmon_fgets(char *str, int nb, void *f) | ||
| 249 | { | ||
| 250 | char *p; | ||
| 251 | int c; | ||
| 252 | |||
| 253 | for (p = str; p < str + nb - 1; ) { | ||
| 254 | c = xmon_getchar(); | ||
| 255 | if (c == -1) { | ||
| 256 | if (p == str) | ||
| 257 | return 0; | ||
| 258 | break; | ||
| 259 | } | ||
| 260 | *p++ = c; | ||
| 261 | if (c == '\n') | ||
| 262 | break; | ||
| 263 | } | ||
| 264 | *p = 0; | ||
| 265 | return str; | ||
| 266 | } | ||
| 267 | |||
| 268 | void | ||
| 269 | prom_drawhex(uint val) | ||
| 270 | { | ||
| 271 | unsigned char buf[10]; | ||
| 272 | |||
| 273 | int i; | ||
| 274 | for (i = 7; i >= 0; i--) | ||
| 275 | { | ||
| 276 | buf[i] = "0123456789abcdef"[val & 0x0f]; | ||
| 277 | val >>= 4; | ||
| 278 | } | ||
| 279 | buf[8] = '\0'; | ||
| 280 | xmon_fputs(buf, xmon_stdout); | ||
| 281 | } | ||
| 282 | |||
| 283 | void | ||
| 284 | prom_drawstring(const char *str) | ||
| 285 | { | ||
| 286 | xmon_fputs(str, xmon_stdout); | ||
| 287 | } | ||
diff --git a/arch/powerpc/xmon/subr_prf.c b/arch/powerpc/xmon/subr_prf.c deleted file mode 100644 index b48738c6dd33..000000000000 --- a/arch/powerpc/xmon/subr_prf.c +++ /dev/null | |||
| @@ -1,54 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Written by Cort Dougan to replace the version originally used | ||
| 3 | * by Paul Mackerras, which came from NetBSD and thus had copyright | ||
| 4 | * conflicts with Linux. | ||
| 5 | * | ||
| 6 | * This file makes liberal use of the standard linux utility | ||
| 7 | * routines to reduce the size of the binary. We assume we can | ||
| 8 | * trust some parts of Linux inside the debugger. | ||
| 9 | * -- Cort (cort@cs.nmt.edu) | ||
| 10 | * | ||
| 11 | * Copyright (C) 1999 Cort Dougan. | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or | ||
| 14 | * modify it under the terms of the GNU General Public License | ||
| 15 | * as published by the Free Software Foundation; either version | ||
| 16 | * 2 of the License, or (at your option) any later version. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/string.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | #include <stdarg.h> | ||
| 23 | #include "nonstdio.h" | ||
| 24 | |||
| 25 | extern int xmon_write(void *, void *, int); | ||
| 26 | |||
| 27 | void xmon_vfprintf(void *f, const char *fmt, va_list ap) | ||
| 28 | { | ||
| 29 | static char xmon_buf[2048]; | ||
| 30 | int n; | ||
| 31 | |||
| 32 | n = vsprintf(xmon_buf, fmt, ap); | ||
| 33 | xmon_write(f, xmon_buf, n); | ||
| 34 | } | ||
| 35 | |||
| 36 | void xmon_printf(const char *fmt, ...) | ||
| 37 | { | ||
| 38 | va_list ap; | ||
| 39 | |||
| 40 | va_start(ap, fmt); | ||
| 41 | xmon_vfprintf(stdout, fmt, ap); | ||
| 42 | va_end(ap); | ||
| 43 | } | ||
| 44 | EXPORT_SYMBOL(xmon_printf); | ||
| 45 | |||
| 46 | void xmon_fprintf(void *f, const char *fmt, ...) | ||
| 47 | { | ||
| 48 | va_list ap; | ||
| 49 | |||
| 50 | va_start(ap, fmt); | ||
| 51 | xmon_vfprintf(f, fmt, ap); | ||
| 52 | va_end(ap); | ||
| 53 | } | ||
| 54 | |||
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 1124f1146202..cfcb2a56d662 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Routines providing a simple monitor for use on the PowerMac. | 2 | * Routines providing a simple monitor for use on the PowerMac. |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 1996 Paul Mackerras. | 4 | * Copyright (C) 1996-2005 Paul Mackerras. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/kallsyms.h> | 18 | #include <linux/kallsyms.h> |
| 19 | #include <linux/cpumask.h> | 19 | #include <linux/cpumask.h> |
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 21 | #include <linux/sysrq.h> | ||
| 21 | 22 | ||
| 22 | #include <asm/ptrace.h> | 23 | #include <asm/ptrace.h> |
| 23 | #include <asm/string.h> | 24 | #include <asm/string.h> |
| @@ -144,15 +145,10 @@ static void xmon_print_symbol(unsigned long address, const char *mid, | |||
| 144 | static const char *getvecname(unsigned long vec); | 145 | static const char *getvecname(unsigned long vec); |
| 145 | 146 | ||
| 146 | extern int print_insn_powerpc(unsigned long, unsigned long, int); | 147 | extern int print_insn_powerpc(unsigned long, unsigned long, int); |
| 147 | extern void printf(const char *fmt, ...); | ||
| 148 | extern void xmon_vfprintf(void *f, const char *fmt, va_list ap); | ||
| 149 | extern int xmon_putc(int c, void *f); | ||
| 150 | extern int putchar(int ch); | ||
| 151 | 148 | ||
| 152 | extern void xmon_enter(void); | 149 | extern void xmon_enter(void); |
| 153 | extern void xmon_leave(void); | 150 | extern void xmon_leave(void); |
| 154 | 151 | ||
| 155 | extern int xmon_read_poll(void); | ||
| 156 | extern long setjmp(long *); | 152 | extern long setjmp(long *); |
| 157 | extern void longjmp(long *, long); | 153 | extern void longjmp(long *, long); |
| 158 | extern void xmon_save_regs(struct pt_regs *); | 154 | extern void xmon_save_regs(struct pt_regs *); |
| @@ -748,7 +744,6 @@ cmds(struct pt_regs *excp) | |||
| 748 | printf("%x:", smp_processor_id()); | 744 | printf("%x:", smp_processor_id()); |
| 749 | #endif /* CONFIG_SMP */ | 745 | #endif /* CONFIG_SMP */ |
| 750 | printf("mon> "); | 746 | printf("mon> "); |
| 751 | fflush(stdout); | ||
| 752 | flush_input(); | 747 | flush_input(); |
| 753 | termch = 0; | 748 | termch = 0; |
| 754 | cmd = skipbl(); | 749 | cmd = skipbl(); |
| @@ -1797,7 +1792,7 @@ memex(void) | |||
| 1797 | for(;;){ | 1792 | for(;;){ |
| 1798 | if (!mnoread) | 1793 | if (!mnoread) |
| 1799 | n = mread(adrs, val, size); | 1794 | n = mread(adrs, val, size); |
| 1800 | printf("%.16x%c", adrs, brev? 'r': ' '); | 1795 | printf(REG"%c", adrs, brev? 'r': ' '); |
| 1801 | if (!mnoread) { | 1796 | if (!mnoread) { |
| 1802 | if (brev) | 1797 | if (brev) |
| 1803 | byterev(val, size); | 1798 | byterev(val, size); |
| @@ -1976,17 +1971,18 @@ prdump(unsigned long adrs, long ndump) | |||
| 1976 | nr = mread(adrs, temp, r); | 1971 | nr = mread(adrs, temp, r); |
| 1977 | adrs += nr; | 1972 | adrs += nr; |
| 1978 | for (m = 0; m < r; ++m) { | 1973 | for (m = 0; m < r; ++m) { |
| 1979 | if ((m & 7) == 0 && m > 0) | 1974 | if ((m & (sizeof(long) - 1)) == 0 && m > 0) |
| 1980 | putchar(' '); | 1975 | putchar(' '); |
| 1981 | if (m < nr) | 1976 | if (m < nr) |
| 1982 | printf("%.2x", temp[m]); | 1977 | printf("%.2x", temp[m]); |
| 1983 | else | 1978 | else |
| 1984 | printf("%s", fault_chars[fault_type]); | 1979 | printf("%s", fault_chars[fault_type]); |
| 1985 | } | 1980 | } |
| 1986 | if (m <= 8) | 1981 | for (; m < 16; ++m) { |
| 1987 | printf(" "); | 1982 | if ((m & (sizeof(long) - 1)) == 0) |
| 1988 | for (; m < 16; ++m) | 1983 | putchar(' '); |
| 1989 | printf(" "); | 1984 | printf(" "); |
| 1985 | } | ||
| 1990 | printf(" |"); | 1986 | printf(" |"); |
| 1991 | for (m = 0; m < r; ++m) { | 1987 | for (m = 0; m < r; ++m) { |
| 1992 | if (m < nr) { | 1988 | if (m < nr) { |
| @@ -2151,7 +2147,6 @@ memzcan(void) | |||
| 2151 | ok = mread(a, &v, 1); | 2147 | ok = mread(a, &v, 1); |
| 2152 | if (ok && !ook) { | 2148 | if (ok && !ook) { |
| 2153 | printf("%.8x .. ", a); | 2149 | printf("%.8x .. ", a); |
| 2154 | fflush(stdout); | ||
| 2155 | } else if (!ok && ook) | 2150 | } else if (!ok && ook) |
| 2156 | printf("%.8x\n", a - mskip); | 2151 | printf("%.8x\n", a - mskip); |
| 2157 | ook = ok; | 2152 | ook = ok; |
| @@ -2372,7 +2367,7 @@ int | |||
| 2372 | inchar(void) | 2367 | inchar(void) |
| 2373 | { | 2368 | { |
| 2374 | if (lineptr == NULL || *lineptr == 0) { | 2369 | if (lineptr == NULL || *lineptr == 0) { |
| 2375 | if (fgets(line, sizeof(line), stdin) == NULL) { | 2370 | if (xmon_gets(line, sizeof(line)) == NULL) { |
| 2376 | lineptr = NULL; | 2371 | lineptr = NULL; |
| 2377 | return EOF; | 2372 | return EOF; |
| 2378 | } | 2373 | } |
| @@ -2526,4 +2521,29 @@ void xmon_init(int enable) | |||
| 2526 | __debugger_dabr_match = NULL; | 2521 | __debugger_dabr_match = NULL; |
| 2527 | __debugger_fault_handler = NULL; | 2522 | __debugger_fault_handler = NULL; |
| 2528 | } | 2523 | } |
| 2524 | xmon_map_scc(); | ||
| 2525 | } | ||
| 2526 | |||
| 2527 | #ifdef CONFIG_MAGIC_SYSRQ | ||
| 2528 | static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs, | ||
| 2529 | struct tty_struct *tty) | ||
| 2530 | { | ||
| 2531 | /* ensure xmon is enabled */ | ||
| 2532 | xmon_init(1); | ||
| 2533 | debugger(pt_regs); | ||
| 2534 | } | ||
| 2535 | |||
| 2536 | static struct sysrq_key_op sysrq_xmon_op = | ||
| 2537 | { | ||
| 2538 | .handler = sysrq_handle_xmon, | ||
| 2539 | .help_msg = "Xmon", | ||
| 2540 | .action_msg = "Entering xmon", | ||
| 2541 | }; | ||
| 2542 | |||
| 2543 | static int __init setup_xmon_sysrq(void) | ||
| 2544 | { | ||
| 2545 | register_sysrq_key('x', &sysrq_xmon_op); | ||
| 2546 | return 0; | ||
| 2529 | } | 2547 | } |
| 2548 | __initcall(setup_xmon_sysrq); | ||
| 2549 | #endif /* CONFIG_MAGIC_SYSRQ */ | ||
diff --git a/arch/ppc/boot/include/of1275.h b/arch/ppc/boot/include/of1275.h index 69173df76db0..4ed88acfa73a 100644 --- a/arch/ppc/boot/include/of1275.h +++ b/arch/ppc/boot/include/of1275.h | |||
| @@ -19,6 +19,9 @@ extern prom_entry of_prom_entry; | |||
| 19 | 19 | ||
| 20 | /* function declarations */ | 20 | /* function declarations */ |
| 21 | 21 | ||
| 22 | int call_prom(const char *service, int nargs, int nret, ...); | ||
| 23 | int call_prom_ret(const char *service, int nargs, int nret, | ||
| 24 | unsigned int *rets, ...); | ||
| 22 | void * claim(unsigned int virt, unsigned int size, unsigned int align); | 25 | void * claim(unsigned int virt, unsigned int size, unsigned int align); |
| 23 | int map(unsigned int phys, unsigned int virt, unsigned int size); | 26 | int map(unsigned int phys, unsigned int virt, unsigned int size); |
| 24 | void enter(void); | 27 | void enter(void); |
diff --git a/arch/ppc/boot/of1275/Makefile b/arch/ppc/boot/of1275/Makefile index 02e6f235d7cb..0b979c004972 100644 --- a/arch/ppc/boot/of1275/Makefile +++ b/arch/ppc/boot/of1275/Makefile | |||
| @@ -3,4 +3,4 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | lib-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o \ | 5 | lib-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o \ |
| 6 | ofstdio.o read.o release.o write.o map.o | 6 | ofstdio.o read.o release.o write.o map.o call_prom.o |
diff --git a/arch/ppc/boot/of1275/call_prom.c b/arch/ppc/boot/of1275/call_prom.c new file mode 100644 index 000000000000..9479a3a2b8c7 --- /dev/null +++ b/arch/ppc/boot/of1275/call_prom.c | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 1996-2005 Paul Mackerras. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version | ||
| 7 | * 2 of the License, or (at your option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include "of1275.h" | ||
| 11 | #include <stdarg.h> | ||
| 12 | |||
| 13 | int call_prom(const char *service, int nargs, int nret, ...) | ||
| 14 | { | ||
| 15 | int i; | ||
| 16 | struct prom_args { | ||
| 17 | const char *service; | ||
| 18 | int nargs; | ||
| 19 | int nret; | ||
| 20 | unsigned int args[12]; | ||
| 21 | } args; | ||
| 22 | va_list list; | ||
| 23 | |||
| 24 | args.service = service; | ||
| 25 | args.nargs = nargs; | ||
| 26 | args.nret = nret; | ||
| 27 | |||
| 28 | va_start(list, nret); | ||
| 29 | for (i = 0; i < nargs; i++) | ||
| 30 | args.args[i] = va_arg(list, unsigned int); | ||
| 31 | va_end(list); | ||
| 32 | |||
| 33 | for (i = 0; i < nret; i++) | ||
| 34 | args.args[nargs+i] = 0; | ||
| 35 | |||
| 36 | if (of_prom_entry(&args) < 0) | ||
| 37 | return -1; | ||
| 38 | |||
| 39 | return (nret > 0)? args.args[nargs]: 0; | ||
| 40 | } | ||
| 41 | |||
| 42 | int call_prom_ret(const char *service, int nargs, int nret, | ||
| 43 | unsigned int *rets, ...) | ||
| 44 | { | ||
| 45 | int i; | ||
| 46 | struct prom_args { | ||
| 47 | const char *service; | ||
| 48 | int nargs; | ||
| 49 | int nret; | ||
| 50 | unsigned int args[12]; | ||
| 51 | } args; | ||
| 52 | va_list list; | ||
| 53 | |||
| 54 | args.service = service; | ||
| 55 | args.nargs = nargs; | ||
| 56 | args.nret = nret; | ||
| 57 | |||
| 58 | va_start(list, rets); | ||
| 59 | for (i = 0; i < nargs; i++) | ||
| 60 | args.args[i] = va_arg(list, unsigned int); | ||
| 61 | va_end(list); | ||
| 62 | |||
| 63 | for (i = 0; i < nret; i++) | ||
| 64 | args.args[nargs+i] = 0; | ||
| 65 | |||
| 66 | if (of_prom_entry(&args) < 0) | ||
| 67 | return -1; | ||
| 68 | |||
| 69 | if (rets != (void *) 0) | ||
| 70 | for (i = 1; i < nret; ++i) | ||
| 71 | rets[i-1] = args.args[nargs+i]; | ||
| 72 | |||
| 73 | return (nret > 0)? args.args[nargs]: 0; | ||
| 74 | } | ||
diff --git a/arch/ppc/boot/of1275/claim.c b/arch/ppc/boot/of1275/claim.c index 13169a5c4339..1ed3aeeff8ae 100644 --- a/arch/ppc/boot/of1275/claim.c +++ b/arch/ppc/boot/of1275/claim.c | |||
| @@ -9,27 +9,84 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include "of1275.h" | 11 | #include "of1275.h" |
| 12 | #include "nonstdio.h" | ||
| 12 | 13 | ||
| 13 | void * | 14 | /* |
| 14 | claim(unsigned int virt, unsigned int size, unsigned int align) | 15 | * Older OF's require that when claiming a specific range of addresses, |
| 16 | * we claim the physical space in the /memory node and the virtual | ||
| 17 | * space in the chosen mmu node, and then do a map operation to | ||
| 18 | * map virtual to physical. | ||
| 19 | */ | ||
| 20 | static int need_map = -1; | ||
| 21 | static ihandle chosen_mmu; | ||
| 22 | static phandle memory; | ||
| 23 | |||
| 24 | /* returns true if s2 is a prefix of s1 */ | ||
| 25 | static int string_match(const char *s1, const char *s2) | ||
| 26 | { | ||
| 27 | for (; *s2; ++s2) | ||
| 28 | if (*s1++ != *s2) | ||
| 29 | return 0; | ||
| 30 | return 1; | ||
| 31 | } | ||
| 32 | |||
| 33 | static int check_of_version(void) | ||
| 34 | { | ||
| 35 | phandle oprom, chosen; | ||
| 36 | char version[64]; | ||
| 37 | |||
| 38 | oprom = finddevice("/openprom"); | ||
| 39 | if (oprom == OF_INVALID_HANDLE) | ||
| 40 | return 0; | ||
| 41 | if (getprop(oprom, "model", version, sizeof(version)) <= 0) | ||
| 42 | return 0; | ||
| 43 | version[sizeof(version)-1] = 0; | ||
| 44 | printf("OF version = '%s'\n", version); | ||
| 45 | if (!string_match(version, "Open Firmware, 1.") | ||
| 46 | && !string_match(version, "FirmWorks,3.")) | ||
| 47 | return 0; | ||
| 48 | chosen = finddevice("/chosen"); | ||
| 49 | if (chosen == OF_INVALID_HANDLE) { | ||
| 50 | chosen = finddevice("/chosen@0"); | ||
| 51 | if (chosen == OF_INVALID_HANDLE) { | ||
| 52 | printf("no chosen\n"); | ||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | } | ||
| 56 | if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) { | ||
| 57 | printf("no mmu\n"); | ||
| 58 | return 0; | ||
| 59 | } | ||
| 60 | memory = (ihandle) call_prom("open", 1, 1, "/memory"); | ||
| 61 | if (memory == OF_INVALID_HANDLE) { | ||
| 62 | memory = (ihandle) call_prom("open", 1, 1, "/memory@0"); | ||
| 63 | if (memory == OF_INVALID_HANDLE) { | ||
| 64 | printf("no memory node\n"); | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | printf("old OF detected\n"); | ||
| 69 | return 1; | ||
| 70 | } | ||
| 71 | |||
| 72 | void *claim(unsigned int virt, unsigned int size, unsigned int align) | ||
| 15 | { | 73 | { |
| 16 | struct prom_args { | 74 | int ret; |
| 17 | char *service; | 75 | unsigned int result; |
| 18 | int nargs; | ||
| 19 | int nret; | ||
| 20 | unsigned int virt; | ||
| 21 | unsigned int size; | ||
| 22 | unsigned int align; | ||
| 23 | void *ret; | ||
| 24 | } args; | ||
| 25 | 76 | ||
| 26 | args.service = "claim"; | 77 | if (need_map < 0) |
| 27 | args.nargs = 3; | 78 | need_map = check_of_version(); |
| 28 | args.nret = 1; | 79 | if (align || !need_map) |
| 29 | args.virt = virt; | 80 | return (void *) call_prom("claim", 3, 1, virt, size, align); |
| 30 | args.size = size; | 81 | |
| 31 | args.align = align; | 82 | ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory, |
| 32 | args.ret = (void *) 0; | 83 | align, size, virt); |
| 33 | (*of_prom_entry)(&args); | 84 | if (ret != 0 || result == -1) |
| 34 | return args.ret; | 85 | return (void *) -1; |
| 86 | ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu, | ||
| 87 | align, size, virt); | ||
| 88 | /* 0x12 == coherent + read/write */ | ||
| 89 | ret = call_prom("call-method", 6, 1, "map", chosen_mmu, | ||
| 90 | 0x12, size, virt, virt); | ||
| 91 | return virt; | ||
| 35 | } | 92 | } |
diff --git a/arch/ppc/boot/of1275/finddevice.c b/arch/ppc/boot/of1275/finddevice.c index 2c0f7cbb793e..0dcb1201b772 100644 --- a/arch/ppc/boot/of1275/finddevice.c +++ b/arch/ppc/boot/of1275/finddevice.c | |||
| @@ -10,22 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | #include "of1275.h" | 11 | #include "of1275.h" |
| 12 | 12 | ||
| 13 | phandle | 13 | phandle finddevice(const char *name) |
| 14 | finddevice(const char *name) | ||
| 15 | { | 14 | { |
| 16 | struct prom_args { | 15 | return (phandle) call_prom("finddevice", 1, 1, name); |
| 17 | char *service; | ||
| 18 | int nargs; | ||
| 19 | int nret; | ||
| 20 | const char *devspec; | ||
| 21 | phandle device; | ||
| 22 | } args; | ||
| 23 | |||
| 24 | args.service = "finddevice"; | ||
| 25 | args.nargs = 1; | ||
| 26 | args.nret = 1; | ||
| 27 | args.devspec = name; | ||
| 28 | args.device = OF_INVALID_HANDLE; | ||
| 29 | (*of_prom_entry)(&args); | ||
| 30 | return args.device; | ||
| 31 | } | 16 | } |
diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile index 03415238fabf..83a6433459ce 100644 --- a/arch/ppc/boot/openfirmware/Makefile +++ b/arch/ppc/boot/openfirmware/Makefile | |||
| @@ -80,8 +80,7 @@ $(obj)/note: $(utils)/mknote FORCE | |||
| 80 | $(call if_changed,mknote) | 80 | $(call if_changed,mknote) |
| 81 | 81 | ||
| 82 | 82 | ||
| 83 | $(obj)/coffcrt0.o: EXTRA_AFLAGS := -traditional -DXCOFF | 83 | $(obj)/coffcrt0.o: EXTRA_AFLAGS := -DXCOFF |
| 84 | $(obj)/crt0.o: EXTRA_AFLAGS := -traditional | ||
| 85 | targets += coffcrt0.o crt0.o | 84 | targets += coffcrt0.o crt0.o |
| 86 | $(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE | 85 | $(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE |
| 87 | $(call if_changed_dep,as_o_S) | 86 | $(call if_changed_dep,as_o_S) |
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 76a55a438f23..17a4da65e275 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile | |||
| @@ -12,7 +12,7 @@ extra-$(CONFIG_6xx) += idle_6xx.o | |||
| 12 | extra-$(CONFIG_POWER4) += idle_power4.o | 12 | extra-$(CONFIG_POWER4) += idle_power4.o |
| 13 | extra-y += vmlinux.lds | 13 | extra-y += vmlinux.lds |
| 14 | 14 | ||
| 15 | obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ | 15 | obj-y := entry.o traps.o idle.o time.o misc.o \ |
| 16 | process.o align.o \ | 16 | process.o align.o \ |
| 17 | setup.o \ | 17 | setup.o \ |
| 18 | ppc_htab.o | 18 | ppc_htab.o |
| @@ -38,8 +38,7 @@ endif | |||
| 38 | # These are here while we do the architecture merge | 38 | # These are here while we do the architecture merge |
| 39 | 39 | ||
| 40 | else | 40 | else |
| 41 | obj-y := irq.o idle.o \ | 41 | obj-y := idle.o align.o |
| 42 | align.o | ||
| 43 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o | 42 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o |
| 44 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o | 43 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o |
| 45 | obj-$(CONFIG_MODULES) += module.o | 44 | obj-$(CONFIG_MODULES) += module.o |
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h index aeb349b47af3..f3d274c6b231 100644 --- a/arch/ppc/kernel/head_booke.h +++ b/arch/ppc/kernel/head_booke.h | |||
| @@ -358,6 +358,6 @@ label: | |||
| 358 | NORMAL_EXCEPTION_PROLOG; \ | 358 | NORMAL_EXCEPTION_PROLOG; \ |
| 359 | bne load_up_fpu; /* if from user, just load it up */ \ | 359 | bne load_up_fpu; /* if from user, just load it up */ \ |
| 360 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 360 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
| 361 | EXC_XFER_EE_LITE(0x800, KernelFP) | 361 | EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception) |
| 362 | 362 | ||
| 363 | #endif /* __HEAD_BOOKE_H__ */ | 363 | #endif /* __HEAD_BOOKE_H__ */ |
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c deleted file mode 100644 index fbb2b9f8922c..000000000000 --- a/arch/ppc/kernel/irq.c +++ /dev/null | |||
| @@ -1,165 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/ppc/kernel/irq.c | ||
| 3 | * | ||
| 4 | * Derived from arch/i386/kernel/irq.c | ||
| 5 | * Copyright (C) 1992 Linus Torvalds | ||
| 6 | * Adapted from arch/i386 by Gary Thomas | ||
| 7 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | ||
| 8 | * Updated and modified by Cort Dougan <cort@fsmlabs.com> | ||
| 9 | * Copyright (C) 1996-2001 Cort Dougan | ||
| 10 | * Adapted for Power Macintosh by Paul Mackerras | ||
| 11 | * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) | ||
| 12 | * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). | ||
| 13 | * | ||
| 14 | * This file contains the code used by various IRQ handling routines: | ||
| 15 | * asking for different IRQ's should be done through these routines | ||
| 16 | * instead of just grabbing them. Thus setups with different IRQ numbers | ||
| 17 | * shouldn't result in any weird surprises, and installing new handlers | ||
| 18 | * should be easier. | ||
| 19 | * | ||
| 20 | * The MPC8xx has an interrupt mask in the SIU. If a bit is set, the | ||
| 21 | * interrupt is _enabled_. As expected, IRQ0 is bit 0 in the 32-bit | ||
| 22 | * mask register (of which only 16 are defined), hence the weird shifting | ||
| 23 | * and complement of the cached_irq_mask. I want to be able to stuff | ||
| 24 | * this right into the SIU SMASK register. | ||
| 25 | * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx | ||
| 26 | * to reduce code space and undefined function references. | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include <linux/errno.h> | ||
| 30 | #include <linux/module.h> | ||
| 31 | #include <linux/threads.h> | ||
| 32 | #include <linux/kernel_stat.h> | ||
| 33 | #include <linux/signal.h> | ||
| 34 | #include <linux/sched.h> | ||
| 35 | #include <linux/ptrace.h> | ||
| 36 | #include <linux/ioport.h> | ||
| 37 | #include <linux/interrupt.h> | ||
| 38 | #include <linux/timex.h> | ||
| 39 | #include <linux/config.h> | ||
| 40 | #include <linux/init.h> | ||
| 41 | #include <linux/slab.h> | ||
| 42 | #include <linux/pci.h> | ||
| 43 | #include <linux/delay.h> | ||
| 44 | #include <linux/irq.h> | ||
| 45 | #include <linux/proc_fs.h> | ||
| 46 | #include <linux/random.h> | ||
| 47 | #include <linux/seq_file.h> | ||
| 48 | #include <linux/cpumask.h> | ||
| 49 | #include <linux/profile.h> | ||
| 50 | #include <linux/bitops.h> | ||
| 51 | |||
| 52 | #include <asm/uaccess.h> | ||
| 53 | #include <asm/system.h> | ||
| 54 | #include <asm/io.h> | ||
| 55 | #include <asm/pgtable.h> | ||
| 56 | #include <asm/irq.h> | ||
| 57 | #include <asm/cache.h> | ||
| 58 | #include <asm/prom.h> | ||
| 59 | #include <asm/ptrace.h> | ||
| 60 | #include <asm/machdep.h> | ||
| 61 | |||
| 62 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) | ||
| 63 | |||
| 64 | extern atomic_t ipi_recv; | ||
| 65 | extern atomic_t ipi_sent; | ||
| 66 | |||
| 67 | #define MAXCOUNT 10000000 | ||
| 68 | |||
| 69 | int ppc_spurious_interrupts = 0; | ||
| 70 | struct irqaction *ppc_irq_action[NR_IRQS]; | ||
| 71 | unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; | ||
| 72 | unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; | ||
| 73 | atomic_t ppc_n_lost_interrupts; | ||
| 74 | |||
| 75 | #ifdef CONFIG_TAU_INT | ||
| 76 | extern int tau_initialized; | ||
| 77 | extern int tau_interrupts(int); | ||
| 78 | #endif | ||
| 79 | |||
| 80 | int show_interrupts(struct seq_file *p, void *v) | ||
| 81 | { | ||
| 82 | int i = *(loff_t *) v, j; | ||
| 83 | struct irqaction * action; | ||
| 84 | unsigned long flags; | ||
| 85 | |||
| 86 | if (i == 0) { | ||
| 87 | seq_puts(p, " "); | ||
| 88 | for (j=0; j<NR_CPUS; j++) | ||
| 89 | if (cpu_online(j)) | ||
| 90 | seq_printf(p, "CPU%d ", j); | ||
| 91 | seq_putc(p, '\n'); | ||
| 92 | } | ||
| 93 | |||
| 94 | if (i < NR_IRQS) { | ||
| 95 | spin_lock_irqsave(&irq_desc[i].lock, flags); | ||
| 96 | action = irq_desc[i].action; | ||
| 97 | if ( !action || !action->handler ) | ||
| 98 | goto skip; | ||
| 99 | seq_printf(p, "%3d: ", i); | ||
| 100 | #ifdef CONFIG_SMP | ||
| 101 | for (j = 0; j < NR_CPUS; j++) | ||
| 102 | if (cpu_online(j)) | ||
| 103 | seq_printf(p, "%10u ", | ||
| 104 | kstat_cpu(j).irqs[i]); | ||
| 105 | #else | ||
| 106 | seq_printf(p, "%10u ", kstat_irqs(i)); | ||
| 107 | #endif /* CONFIG_SMP */ | ||
| 108 | if (irq_desc[i].handler) | ||
| 109 | seq_printf(p, " %s ", irq_desc[i].handler->typename); | ||
| 110 | else | ||
| 111 | seq_puts(p, " None "); | ||
| 112 | seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge "); | ||
| 113 | seq_printf(p, " %s", action->name); | ||
| 114 | for (action = action->next; action; action = action->next) | ||
| 115 | seq_printf(p, ", %s", action->name); | ||
| 116 | seq_putc(p, '\n'); | ||
| 117 | skip: | ||
| 118 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | ||
| 119 | } else if (i == NR_IRQS) { | ||
| 120 | #ifdef CONFIG_TAU_INT | ||
| 121 | if (tau_initialized){ | ||
| 122 | seq_puts(p, "TAU: "); | ||
| 123 | for (j = 0; j < NR_CPUS; j++) | ||
| 124 | if (cpu_online(j)) | ||
| 125 | seq_printf(p, "%10u ", tau_interrupts(j)); | ||
| 126 | seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n"); | ||
| 127 | } | ||
| 128 | #endif | ||
| 129 | #if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE) | ||
| 130 | /* should this be per processor send/receive? */ | ||
| 131 | seq_printf(p, "IPI (recv/sent): %10u/%u\n", | ||
| 132 | atomic_read(&ipi_recv), atomic_read(&ipi_sent)); | ||
| 133 | #endif | ||
| 134 | seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts); | ||
| 135 | } | ||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | void do_IRQ(struct pt_regs *regs) | ||
| 140 | { | ||
| 141 | int irq, first = 1; | ||
| 142 | irq_enter(); | ||
| 143 | |||
| 144 | /* | ||
| 145 | * Every platform is required to implement ppc_md.get_irq. | ||
| 146 | * This function will either return an irq number or -1 to | ||
| 147 | * indicate there are no more pending. But the first time | ||
| 148 | * through the loop this means there wasn't and IRQ pending. | ||
| 149 | * The value -2 is for buggy hardware and means that this IRQ | ||
| 150 | * has already been handled. -- Tom | ||
| 151 | */ | ||
| 152 | while ((irq = ppc_md.get_irq(regs)) >= 0) { | ||
| 153 | __do_IRQ(irq, regs); | ||
| 154 | first = 0; | ||
| 155 | } | ||
| 156 | if (irq != -2 && first) | ||
| 157 | /* That's not SMP safe ... but who cares ? */ | ||
| 158 | ppc_spurious_interrupts++; | ||
| 159 | irq_exit(); | ||
| 160 | } | ||
| 161 | |||
| 162 | void __init init_IRQ(void) | ||
| 163 | { | ||
| 164 | ppc_md.init_IRQ(); | ||
| 165 | } | ||
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index ae6af29938a1..5e61124581d0 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S | |||
| @@ -497,9 +497,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) | |||
| 497 | * and invalidate the corresponding instruction cache blocks. | 497 | * and invalidate the corresponding instruction cache blocks. |
| 498 | * This is a no-op on the 601. | 498 | * This is a no-op on the 601. |
| 499 | * | 499 | * |
| 500 | * flush_icache_range(unsigned long start, unsigned long stop) | 500 | * __flush_icache_range(unsigned long start, unsigned long stop) |
| 501 | */ | 501 | */ |
| 502 | _GLOBAL(flush_icache_range) | 502 | _GLOBAL(__flush_icache_range) |
| 503 | BEGIN_FTR_SECTION | 503 | BEGIN_FTR_SECTION |
| 504 | blr /* for 601, do nothing */ | 504 | blr /* for 601, do nothing */ |
| 505 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) | 505 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) |
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index e0ca61b37f4f..66073f775193 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | #include <asm/btext.h> | 46 | #include <asm/btext.h> |
| 47 | #include <asm/div64.h> | 47 | #include <asm/div64.h> |
| 48 | #include <asm/xmon.h> | 48 | #include <asm/xmon.h> |
| 49 | #include <asm/signal.h> | ||
| 49 | 50 | ||
| 50 | #ifdef CONFIG_8xx | 51 | #ifdef CONFIG_8xx |
| 51 | #include <asm/commproc.h> | 52 | #include <asm/commproc.h> |
| @@ -57,7 +58,6 @@ extern void machine_check_exception(struct pt_regs *regs); | |||
| 57 | extern void alignment_exception(struct pt_regs *regs); | 58 | extern void alignment_exception(struct pt_regs *regs); |
| 58 | extern void program_check_exception(struct pt_regs *regs); | 59 | extern void program_check_exception(struct pt_regs *regs); |
| 59 | extern void single_step_exception(struct pt_regs *regs); | 60 | extern void single_step_exception(struct pt_regs *regs); |
| 60 | extern int do_signal(sigset_t *, struct pt_regs *); | ||
| 61 | extern int pmac_newworld; | 61 | extern int pmac_newworld; |
| 62 | extern int sys_sigreturn(struct pt_regs *regs); | 62 | extern int sys_sigreturn(struct pt_regs *regs); |
| 63 | 63 | ||
| @@ -78,7 +78,6 @@ EXPORT_SYMBOL(program_check_exception); | |||
| 78 | EXPORT_SYMBOL(single_step_exception); | 78 | EXPORT_SYMBOL(single_step_exception); |
| 79 | EXPORT_SYMBOL(sys_sigreturn); | 79 | EXPORT_SYMBOL(sys_sigreturn); |
| 80 | EXPORT_SYMBOL(ppc_n_lost_interrupts); | 80 | EXPORT_SYMBOL(ppc_n_lost_interrupts); |
| 81 | EXPORT_SYMBOL(ppc_lost_interrupts); | ||
| 82 | 81 | ||
| 83 | EXPORT_SYMBOL(ISA_DMA_THRESHOLD); | 82 | EXPORT_SYMBOL(ISA_DMA_THRESHOLD); |
| 84 | EXPORT_SYMBOL(DMA_MODE_READ); | 83 | EXPORT_SYMBOL(DMA_MODE_READ); |
| @@ -176,6 +175,7 @@ EXPORT_SYMBOL(pci_bus_to_phys); | |||
| 176 | #endif /* CONFIG_PCI */ | 175 | #endif /* CONFIG_PCI */ |
| 177 | 176 | ||
| 178 | #ifdef CONFIG_NOT_COHERENT_CACHE | 177 | #ifdef CONFIG_NOT_COHERENT_CACHE |
| 178 | extern void flush_dcache_all(void); | ||
| 179 | EXPORT_SYMBOL(flush_dcache_all); | 179 | EXPORT_SYMBOL(flush_dcache_all); |
| 180 | #endif | 180 | #endif |
| 181 | 181 | ||
| @@ -217,9 +217,6 @@ EXPORT_SYMBOL(adb_try_handler_change); | |||
| 217 | EXPORT_SYMBOL(cuda_request); | 217 | EXPORT_SYMBOL(cuda_request); |
| 218 | EXPORT_SYMBOL(cuda_poll); | 218 | EXPORT_SYMBOL(cuda_poll); |
| 219 | #endif /* CONFIG_ADB_CUDA */ | 219 | #endif /* CONFIG_ADB_CUDA */ |
| 220 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
| 221 | EXPORT_SYMBOL(_machine); | ||
| 222 | #endif | ||
| 223 | #ifdef CONFIG_PPC_PMAC | 220 | #ifdef CONFIG_PPC_PMAC |
| 224 | EXPORT_SYMBOL(sys_ctrler); | 221 | EXPORT_SYMBOL(sys_ctrler); |
| 225 | EXPORT_SYMBOL(pmac_newworld); | 222 | EXPORT_SYMBOL(pmac_newworld); |
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 6bcb85d2b7fd..dc55e1abc45b 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c | |||
| @@ -76,6 +76,7 @@ unsigned int DMA_MODE_WRITE; | |||
| 76 | 76 | ||
| 77 | #ifdef CONFIG_PPC_MULTIPLATFORM | 77 | #ifdef CONFIG_PPC_MULTIPLATFORM |
| 78 | int _machine = 0; | 78 | int _machine = 0; |
| 79 | EXPORT_SYMBOL(_machine); | ||
| 79 | 80 | ||
| 80 | extern void prep_init(unsigned long r3, unsigned long r4, | 81 | extern void prep_init(unsigned long r3, unsigned long r4, |
| 81 | unsigned long r5, unsigned long r6, unsigned long r7); | 82 | unsigned long r5, unsigned long r6, unsigned long r7); |
diff --git a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c index 9f2d95ea8564..4742bf609357 100644 --- a/arch/ppc/platforms/pmac_pic.c +++ b/arch/ppc/platforms/pmac_pic.c | |||
| @@ -75,6 +75,9 @@ static DEFINE_SPINLOCK(pmac_pic_lock); | |||
| 75 | #define GATWICK_IRQ_POOL_SIZE 10 | 75 | #define GATWICK_IRQ_POOL_SIZE 10 |
| 76 | static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; | 76 | static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; |
| 77 | 77 | ||
| 78 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) | ||
| 79 | static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; | ||
| 80 | |||
| 78 | /* | 81 | /* |
| 79 | * Mark an irq as "lost". This is only used on the pmac | 82 | * Mark an irq as "lost". This is only used on the pmac |
| 80 | * since it can lose interrupts (see pmac_set_irq_mask). | 83 | * since it can lose interrupts (see pmac_set_irq_mask). |
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c index 067d7d53b81e..4415748071dc 100644 --- a/arch/ppc/platforms/prep_setup.c +++ b/arch/ppc/platforms/prep_setup.c | |||
| @@ -61,6 +61,15 @@ | |||
| 61 | #include <asm/pci-bridge.h> | 61 | #include <asm/pci-bridge.h> |
| 62 | #include <asm/todc.h> | 62 | #include <asm/todc.h> |
| 63 | 63 | ||
| 64 | /* prep registers for L2 */ | ||
| 65 | #define CACHECRBA 0x80000823 /* Cache configuration register address */ | ||
| 66 | #define L2CACHE_MASK 0x03 /* Mask for 2 L2 Cache bits */ | ||
| 67 | #define L2CACHE_512KB 0x00 /* 512KB */ | ||
| 68 | #define L2CACHE_256KB 0x01 /* 256KB */ | ||
| 69 | #define L2CACHE_1MB 0x02 /* 1MB */ | ||
| 70 | #define L2CACHE_NONE 0x03 /* NONE */ | ||
| 71 | #define L2CACHE_PARITY 0x08 /* Mask for L2 Cache Parity Protected bit */ | ||
| 72 | |||
| 64 | TODC_ALLOC(); | 73 | TODC_ALLOC(); |
| 65 | 74 | ||
| 66 | unsigned char ucSystemType; | 75 | unsigned char ucSystemType; |
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index 29552348e581..c9d32db9d76a 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig | |||
| @@ -297,6 +297,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID | |||
| 297 | def_bool y | 297 | def_bool y |
| 298 | depends on NEED_MULTIPLE_NODES | 298 | depends on NEED_MULTIPLE_NODES |
| 299 | 299 | ||
| 300 | config ARCH_MEMORY_PROBE | ||
| 301 | def_bool y | ||
| 302 | depends on MEMORY_HOTPLUG | ||
| 303 | |||
| 300 | # Some NUMA nodes have memory ranges that span | 304 | # Some NUMA nodes have memory ranges that span |
| 301 | # other nodes. Even though a pfn is valid and | 305 | # other nodes. Even though a pfn is valid and |
| 302 | # between a node's start and end pfns, it may not | 306 | # between a node's start and end pfns, it may not |
diff --git a/arch/ppc64/boot/addRamDisk.c b/arch/ppc64/boot/addRamDisk.c index 7f2c09473394..c02a99952be7 100644 --- a/arch/ppc64/boot/addRamDisk.c +++ b/arch/ppc64/boot/addRamDisk.c | |||
| @@ -5,11 +5,59 @@ | |||
| 5 | #include <sys/types.h> | 5 | #include <sys/types.h> |
| 6 | #include <sys/stat.h> | 6 | #include <sys/stat.h> |
| 7 | #include <string.h> | 7 | #include <string.h> |
| 8 | #include <elf.h> | ||
| 8 | 9 | ||
| 9 | #define ElfHeaderSize (64 * 1024) | 10 | #define ElfHeaderSize (64 * 1024) |
| 10 | #define ElfPages (ElfHeaderSize / 4096) | 11 | #define ElfPages (ElfHeaderSize / 4096) |
| 11 | #define KERNELBASE (0xc000000000000000) | 12 | #define KERNELBASE (0xc000000000000000) |
| 13 | #define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) | ||
| 12 | 14 | ||
| 15 | struct addr_range { | ||
| 16 | unsigned long long addr; | ||
| 17 | unsigned long memsize; | ||
| 18 | unsigned long offset; | ||
| 19 | }; | ||
| 20 | |||
| 21 | static int check_elf64(void *p, int size, struct addr_range *r) | ||
| 22 | { | ||
| 23 | Elf64_Ehdr *elf64 = p; | ||
| 24 | Elf64_Phdr *elf64ph; | ||
| 25 | |||
| 26 | if (elf64->e_ident[EI_MAG0] != ELFMAG0 || | ||
| 27 | elf64->e_ident[EI_MAG1] != ELFMAG1 || | ||
| 28 | elf64->e_ident[EI_MAG2] != ELFMAG2 || | ||
| 29 | elf64->e_ident[EI_MAG3] != ELFMAG3 || | ||
| 30 | elf64->e_ident[EI_CLASS] != ELFCLASS64 || | ||
| 31 | elf64->e_ident[EI_DATA] != ELFDATA2MSB || | ||
| 32 | elf64->e_type != ET_EXEC || elf64->e_machine != EM_PPC64) | ||
| 33 | return 0; | ||
| 34 | |||
| 35 | if ((elf64->e_phoff + sizeof(Elf64_Phdr)) > size) | ||
| 36 | return 0; | ||
| 37 | |||
| 38 | elf64ph = (Elf64_Phdr *) ((unsigned long)elf64 + | ||
| 39 | (unsigned long)elf64->e_phoff); | ||
| 40 | |||
| 41 | r->memsize = (unsigned long)elf64ph->p_memsz; | ||
| 42 | r->offset = (unsigned long)elf64ph->p_offset; | ||
| 43 | r->addr = (unsigned long long)elf64ph->p_vaddr; | ||
| 44 | |||
| 45 | #ifdef DEBUG | ||
| 46 | printf("PPC64 ELF file, ph:\n"); | ||
| 47 | printf("p_type 0x%08x\n", elf64ph->p_type); | ||
| 48 | printf("p_flags 0x%08x\n", elf64ph->p_flags); | ||
| 49 | printf("p_offset 0x%016llx\n", elf64ph->p_offset); | ||
| 50 | printf("p_vaddr 0x%016llx\n", elf64ph->p_vaddr); | ||
| 51 | printf("p_paddr 0x%016llx\n", elf64ph->p_paddr); | ||
| 52 | printf("p_filesz 0x%016llx\n", elf64ph->p_filesz); | ||
| 53 | printf("p_memsz 0x%016llx\n", elf64ph->p_memsz); | ||
| 54 | printf("p_align 0x%016llx\n", elf64ph->p_align); | ||
| 55 | printf("... skipping 0x%08lx bytes of ELF header\n", | ||
| 56 | (unsigned long)elf64ph->p_offset); | ||
| 57 | #endif | ||
| 58 | |||
| 59 | return 64; | ||
| 60 | } | ||
| 13 | void get4k(FILE *file, char *buf ) | 61 | void get4k(FILE *file, char *buf ) |
| 14 | { | 62 | { |
| 15 | unsigned j; | 63 | unsigned j; |
| @@ -34,97 +82,92 @@ void death(const char *msg, FILE *fdesc, const char *fname) | |||
| 34 | int main(int argc, char **argv) | 82 | int main(int argc, char **argv) |
| 35 | { | 83 | { |
| 36 | char inbuf[4096]; | 84 | char inbuf[4096]; |
| 37 | FILE *ramDisk = NULL; | 85 | struct addr_range vmlinux; |
| 38 | FILE *sysmap = NULL; | 86 | FILE *ramDisk; |
| 39 | FILE *inputVmlinux = NULL; | 87 | FILE *inputVmlinux; |
| 40 | FILE *outputVmlinux = NULL; | 88 | FILE *outputVmlinux; |
| 41 | 89 | ||
| 42 | unsigned i = 0; | 90 | char *rd_name, *lx_name, *out_name; |
| 43 | unsigned long ramFileLen = 0; | 91 | |
| 44 | unsigned long ramLen = 0; | 92 | size_t i; |
| 45 | unsigned long roundR = 0; | 93 | unsigned long ramFileLen; |
| 46 | 94 | unsigned long ramLen; | |
| 47 | unsigned long sysmapFileLen = 0; | 95 | unsigned long roundR; |
| 48 | unsigned long sysmapLen = 0; | 96 | unsigned long offset_end; |
| 49 | unsigned long sysmapPages = 0; | 97 | |
| 50 | char* ptr_end = NULL; | 98 | unsigned long kernelLen; |
| 51 | unsigned long offset_end = 0; | 99 | unsigned long actualKernelLen; |
| 52 | 100 | unsigned long round; | |
| 53 | unsigned long kernelLen = 0; | 101 | unsigned long roundedKernelLen; |
| 54 | unsigned long actualKernelLen = 0; | 102 | unsigned long ramStartOffs; |
| 55 | unsigned long round = 0; | 103 | unsigned long ramPages; |
| 56 | unsigned long roundedKernelLen = 0; | 104 | unsigned long roundedKernelPages; |
| 57 | unsigned long ramStartOffs = 0; | 105 | unsigned long hvReleaseData; |
| 58 | unsigned long ramPages = 0; | ||
| 59 | unsigned long roundedKernelPages = 0; | ||
| 60 | unsigned long hvReleaseData = 0; | ||
| 61 | u_int32_t eyeCatcher = 0xc8a5d9c4; | 106 | u_int32_t eyeCatcher = 0xc8a5d9c4; |
| 62 | unsigned long naca = 0; | 107 | unsigned long naca; |
| 63 | unsigned long xRamDisk = 0; | 108 | unsigned long xRamDisk; |
| 64 | unsigned long xRamDiskSize = 0; | 109 | unsigned long xRamDiskSize; |
| 65 | long padPages = 0; | 110 | long padPages; |
| 66 | 111 | ||
| 67 | 112 | ||
| 68 | if (argc < 2) { | 113 | if (argc < 2) { |
| 69 | fprintf(stderr, "Name of RAM disk file missing.\n"); | 114 | fprintf(stderr, "Name of RAM disk file missing.\n"); |
| 70 | exit(1); | 115 | exit(1); |
| 71 | } | 116 | } |
| 117 | rd_name = argv[1]; | ||
| 72 | 118 | ||
| 73 | if (argc < 3) { | 119 | if (argc < 3) { |
| 74 | fprintf(stderr, "Name of System Map input file is missing.\n"); | ||
| 75 | exit(1); | ||
| 76 | } | ||
| 77 | |||
| 78 | if (argc < 4) { | ||
| 79 | fprintf(stderr, "Name of vmlinux file missing.\n"); | 120 | fprintf(stderr, "Name of vmlinux file missing.\n"); |
| 80 | exit(1); | 121 | exit(1); |
| 81 | } | 122 | } |
| 123 | lx_name = argv[2]; | ||
| 82 | 124 | ||
| 83 | if (argc < 5) { | 125 | if (argc < 4) { |
| 84 | fprintf(stderr, "Name of vmlinux output file missing.\n"); | 126 | fprintf(stderr, "Name of vmlinux output file missing.\n"); |
| 85 | exit(1); | 127 | exit(1); |
| 86 | } | 128 | } |
| 129 | out_name = argv[3]; | ||
| 87 | 130 | ||
| 88 | 131 | ||
| 89 | ramDisk = fopen(argv[1], "r"); | 132 | ramDisk = fopen(rd_name, "r"); |
| 90 | if ( ! ramDisk ) { | 133 | if ( ! ramDisk ) { |
| 91 | fprintf(stderr, "RAM disk file \"%s\" failed to open.\n", argv[1]); | 134 | fprintf(stderr, "RAM disk file \"%s\" failed to open.\n", rd_name); |
| 92 | exit(1); | 135 | exit(1); |
| 93 | } | 136 | } |
| 94 | 137 | ||
| 95 | sysmap = fopen(argv[2], "r"); | 138 | inputVmlinux = fopen(lx_name, "r"); |
| 96 | if ( ! sysmap ) { | ||
| 97 | fprintf(stderr, "System Map file \"%s\" failed to open.\n", argv[2]); | ||
| 98 | exit(1); | ||
| 99 | } | ||
| 100 | |||
| 101 | inputVmlinux = fopen(argv[3], "r"); | ||
| 102 | if ( ! inputVmlinux ) { | 139 | if ( ! inputVmlinux ) { |
| 103 | fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", argv[3]); | 140 | fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", lx_name); |
| 104 | exit(1); | 141 | exit(1); |
| 105 | } | 142 | } |
| 106 | 143 | ||
| 107 | outputVmlinux = fopen(argv[4], "w+"); | 144 | outputVmlinux = fopen(out_name, "w+"); |
| 108 | if ( ! outputVmlinux ) { | 145 | if ( ! outputVmlinux ) { |
| 109 | fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", argv[4]); | 146 | fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", out_name); |
| 110 | exit(1); | 147 | exit(1); |
| 111 | } | 148 | } |
| 112 | 149 | ||
| 113 | 150 | i = fread(inbuf, 1, sizeof(inbuf), inputVmlinux); | |
| 114 | 151 | if (i != sizeof(inbuf)) { | |
| 152 | fprintf(stderr, "can not read vmlinux file %s: %u\n", lx_name, i); | ||
| 153 | exit(1); | ||
| 154 | } | ||
| 155 | |||
| 156 | i = check_elf64(inbuf, sizeof(inbuf), &vmlinux); | ||
| 157 | if (i == 0) { | ||
| 158 | fprintf(stderr, "You must have a linux kernel specified as argv[2]\n"); | ||
| 159 | exit(1); | ||
| 160 | } | ||
| 161 | |||
| 115 | /* Input Vmlinux file */ | 162 | /* Input Vmlinux file */ |
| 116 | fseek(inputVmlinux, 0, SEEK_END); | 163 | fseek(inputVmlinux, 0, SEEK_END); |
| 117 | kernelLen = ftell(inputVmlinux); | 164 | kernelLen = ftell(inputVmlinux); |
| 118 | fseek(inputVmlinux, 0, SEEK_SET); | 165 | fseek(inputVmlinux, 0, SEEK_SET); |
| 119 | printf("kernel file size = %d\n", kernelLen); | 166 | printf("kernel file size = %lu\n", kernelLen); |
| 120 | if ( kernelLen == 0 ) { | ||
| 121 | fprintf(stderr, "You must have a linux kernel specified as argv[3]\n"); | ||
| 122 | exit(1); | ||
| 123 | } | ||
| 124 | 167 | ||
| 125 | actualKernelLen = kernelLen - ElfHeaderSize; | 168 | actualKernelLen = kernelLen - ElfHeaderSize; |
| 126 | 169 | ||
| 127 | printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen); | 170 | printf("actual kernel length (minus ELF header) = %lu\n", actualKernelLen); |
| 128 | 171 | ||
| 129 | round = actualKernelLen % 4096; | 172 | round = actualKernelLen % 4096; |
| 130 | roundedKernelLen = actualKernelLen; | 173 | roundedKernelLen = actualKernelLen; |
| @@ -134,39 +177,7 @@ int main(int argc, char **argv) | |||
| 134 | roundedKernelPages = roundedKernelLen / 4096; | 177 | roundedKernelPages = roundedKernelLen / 4096; |
| 135 | printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages); | 178 | printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages); |
| 136 | 179 | ||
| 137 | 180 | offset_end = _ALIGN_UP(vmlinux.memsize, 4096); | |
| 138 | |||
| 139 | /* Input System Map file */ | ||
| 140 | /* (needs to be processed simply to determine if we need to add pad pages due to the static variables not being included in the vmlinux) */ | ||
| 141 | fseek(sysmap, 0, SEEK_END); | ||
| 142 | sysmapFileLen = ftell(sysmap); | ||
| 143 | fseek(sysmap, 0, SEEK_SET); | ||
| 144 | printf("%s file size = %ld/0x%lx \n", argv[2], sysmapFileLen, sysmapFileLen); | ||
| 145 | |||
| 146 | sysmapLen = sysmapFileLen; | ||
| 147 | |||
| 148 | roundR = 4096 - (sysmapLen % 4096); | ||
| 149 | if (roundR) { | ||
| 150 | printf("Rounding System Map file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR); | ||
| 151 | sysmapLen += roundR; | ||
| 152 | } | ||
| 153 | printf("Rounded System Map size is %ld/0x%lx \n", sysmapLen, sysmapLen); | ||
| 154 | |||
| 155 | /* Process the Sysmap file to determine where _end is */ | ||
| 156 | sysmapPages = sysmapLen / 4096; | ||
| 157 | /* read the whole file line by line, expect that it doesn't fail */ | ||
| 158 | while ( fgets(inbuf, 4096, sysmap) ) ; | ||
| 159 | /* search for _end in the last page of the system map */ | ||
| 160 | ptr_end = strstr(inbuf, " _end"); | ||
| 161 | if (!ptr_end) { | ||
| 162 | fprintf(stderr, "Unable to find _end in the sysmap file \n"); | ||
| 163 | fprintf(stderr, "inbuf: \n"); | ||
| 164 | fprintf(stderr, "%s \n", inbuf); | ||
| 165 | exit(1); | ||
| 166 | } | ||
| 167 | printf("Found _end in the last page of the sysmap - backing up 10 characters it looks like %s", ptr_end-10); | ||
| 168 | /* convert address of _end in system map to hex offset. */ | ||
| 169 | offset_end = (unsigned int)strtol(ptr_end-10, NULL, 16); | ||
| 170 | /* calc how many pages we need to insert between the vmlinux and the start of the ram disk */ | 181 | /* calc how many pages we need to insert between the vmlinux and the start of the ram disk */ |
| 171 | padPages = offset_end/4096 - roundedKernelPages; | 182 | padPages = offset_end/4096 - roundedKernelPages; |
| 172 | 183 | ||
| @@ -194,7 +205,7 @@ int main(int argc, char **argv) | |||
| 194 | fseek(ramDisk, 0, SEEK_END); | 205 | fseek(ramDisk, 0, SEEK_END); |
| 195 | ramFileLen = ftell(ramDisk); | 206 | ramFileLen = ftell(ramDisk); |
| 196 | fseek(ramDisk, 0, SEEK_SET); | 207 | fseek(ramDisk, 0, SEEK_SET); |
| 197 | printf("%s file size = %ld/0x%lx \n", argv[1], ramFileLen, ramFileLen); | 208 | printf("%s file size = %ld/0x%lx \n", rd_name, ramFileLen, ramFileLen); |
| 198 | 209 | ||
| 199 | ramLen = ramFileLen; | 210 | ramLen = ramFileLen; |
| 200 | 211 | ||
| @@ -248,19 +259,19 @@ int main(int argc, char **argv) | |||
| 248 | /* fseek to the hvReleaseData pointer */ | 259 | /* fseek to the hvReleaseData pointer */ |
| 249 | fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET); | 260 | fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET); |
| 250 | if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) { | 261 | if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) { |
| 251 | death("Could not read hvReleaseData pointer\n", outputVmlinux, argv[4]); | 262 | death("Could not read hvReleaseData pointer\n", outputVmlinux, out_name); |
| 252 | } | 263 | } |
| 253 | hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */ | 264 | hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */ |
| 254 | printf("hvReleaseData is at %08x\n", hvReleaseData); | 265 | printf("hvReleaseData is at %08lx\n", hvReleaseData); |
| 255 | 266 | ||
| 256 | /* fseek to the hvReleaseData */ | 267 | /* fseek to the hvReleaseData */ |
| 257 | fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET); | 268 | fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET); |
| 258 | if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) { | 269 | if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) { |
| 259 | death("Could not read hvReleaseData\n", outputVmlinux, argv[4]); | 270 | death("Could not read hvReleaseData\n", outputVmlinux, out_name); |
| 260 | } | 271 | } |
| 261 | /* Check hvReleaseData sanity */ | 272 | /* Check hvReleaseData sanity */ |
| 262 | if (memcmp(inbuf, &eyeCatcher, 4) != 0) { | 273 | if (memcmp(inbuf, &eyeCatcher, 4) != 0) { |
| 263 | death("hvReleaseData is invalid\n", outputVmlinux, argv[4]); | 274 | death("hvReleaseData is invalid\n", outputVmlinux, out_name); |
| 264 | } | 275 | } |
| 265 | /* Get the naca pointer */ | 276 | /* Get the naca pointer */ |
| 266 | naca = ntohl(*((u_int32_t*) &inbuf[0x0C])) - KERNELBASE; | 277 | naca = ntohl(*((u_int32_t*) &inbuf[0x0C])) - KERNELBASE; |
| @@ -269,13 +280,13 @@ int main(int argc, char **argv) | |||
| 269 | /* fseek to the naca */ | 280 | /* fseek to the naca */ |
| 270 | fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); | 281 | fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); |
| 271 | if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) { | 282 | if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) { |
| 272 | death("Could not read naca\n", outputVmlinux, argv[4]); | 283 | death("Could not read naca\n", outputVmlinux, out_name); |
| 273 | } | 284 | } |
| 274 | xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c])); | 285 | xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c])); |
| 275 | xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14])); | 286 | xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14])); |
| 276 | /* Make sure a RAM disk isn't already present */ | 287 | /* Make sure a RAM disk isn't already present */ |
| 277 | if ((xRamDisk != 0) || (xRamDiskSize != 0)) { | 288 | if ((xRamDisk != 0) || (xRamDiskSize != 0)) { |
| 278 | death("RAM disk is already attached to this kernel\n", outputVmlinux, argv[4]); | 289 | death("RAM disk is already attached to this kernel\n", outputVmlinux, out_name); |
| 279 | } | 290 | } |
| 280 | /* Fill in the values */ | 291 | /* Fill in the values */ |
| 281 | *((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs); | 292 | *((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs); |
| @@ -285,15 +296,15 @@ int main(int argc, char **argv) | |||
| 285 | fflush(outputVmlinux); | 296 | fflush(outputVmlinux); |
| 286 | fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); | 297 | fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); |
| 287 | if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) { | 298 | if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) { |
| 288 | death("Could not write naca\n", outputVmlinux, argv[4]); | 299 | death("Could not write naca\n", outputVmlinux, out_name); |
| 289 | } | 300 | } |
| 290 | printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08x\n", | 301 | printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08lx\n", |
| 291 | ramPages, ramStartOffs); | 302 | ramPages, ramStartOffs); |
| 292 | 303 | ||
| 293 | /* Done */ | 304 | /* Done */ |
| 294 | fclose(outputVmlinux); | 305 | fclose(outputVmlinux); |
| 295 | /* Set permission to executable */ | 306 | /* Set permission to executable */ |
| 296 | chmod(argv[4], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); | 307 | chmod(out_name, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); |
| 297 | 308 | ||
| 298 | return 0; | 309 | return 0; |
| 299 | } | 310 | } |
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index c441aebe7648..58b19f107656 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile | |||
| @@ -11,12 +11,11 @@ obj-y := misc.o prom.o | |||
| 11 | 11 | ||
| 12 | endif | 12 | endif |
| 13 | 13 | ||
| 14 | obj-y += irq.o idle.o dma.o \ | 14 | obj-y += idle.o dma.o \ |
| 15 | align.o pacaData.o \ | 15 | align.o \ |
| 16 | udbg.o ioctl32.o \ | 16 | udbg.o \ |
| 17 | rtc.o \ | 17 | rtc.o \ |
| 18 | cpu_setup_power4.o \ | 18 | iommu.o vdso.o |
| 19 | iommu.o sysfs.o vdso.o firmware.o | ||
| 20 | obj-y += vdso32/ vdso64/ | 19 | obj-y += vdso32/ vdso64/ |
| 21 | 20 | ||
| 22 | pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o | 21 | pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o |
| @@ -31,15 +30,10 @@ endif | |||
| 31 | obj-$(CONFIG_PPC_PSERIES) += udbg_16550.o | 30 | obj-$(CONFIG_PPC_PSERIES) += udbg_16550.o |
| 32 | 31 | ||
| 33 | obj-$(CONFIG_KEXEC) += machine_kexec.o | 32 | obj-$(CONFIG_KEXEC) += machine_kexec.o |
| 34 | obj-$(CONFIG_EEH) += eeh.o | ||
| 35 | obj-$(CONFIG_PROC_FS) += proc_ppc64.o | ||
| 36 | obj-$(CONFIG_MODULES) += module.o | 33 | obj-$(CONFIG_MODULES) += module.o |
| 37 | ifneq ($(CONFIG_PPC_MERGE),y) | 34 | ifneq ($(CONFIG_PPC_MERGE),y) |
| 38 | obj-$(CONFIG_MODULES) += ppc_ksyms.o | 35 | obj-$(CONFIG_MODULES) += ppc_ksyms.o |
| 39 | endif | 36 | endif |
| 40 | obj-$(CONFIG_PPC_RTAS) += rtas_pci.o | ||
| 41 | obj-$(CONFIG_SCANLOG) += scanlog.o | ||
| 42 | obj-$(CONFIG_LPARCFG) += lparcfg.o | ||
| 43 | obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o | 37 | obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o |
| 44 | ifneq ($(CONFIG_PPC_MERGE),y) | 38 | ifneq ($(CONFIG_PPC_MERGE),y) |
| 45 | obj-$(CONFIG_BOOTX_TEXT) += btext.o | 39 | obj-$(CONFIG_BOOTX_TEXT) += btext.o |
| @@ -52,8 +46,6 @@ obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o | |||
| 52 | 46 | ||
| 53 | obj-$(CONFIG_KPROBES) += kprobes.o | 47 | obj-$(CONFIG_KPROBES) += kprobes.o |
| 54 | 48 | ||
| 55 | CFLAGS_ioctl32.o += -Ifs/ | ||
| 56 | |||
| 57 | ifneq ($(CONFIG_PPC_MERGE),y) | 49 | ifneq ($(CONFIG_PPC_MERGE),y) |
| 58 | ifeq ($(CONFIG_PPC_ISERIES),y) | 50 | ifeq ($(CONFIG_PPC_ISERIES),y) |
| 59 | arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s | 51 | arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s |
diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c index bce9065da6cb..84ab5c18ef52 100644 --- a/arch/ppc64/kernel/asm-offsets.c +++ b/arch/ppc64/kernel/asm-offsets.c | |||
| @@ -74,7 +74,6 @@ int main(void) | |||
| 74 | DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); | 74 | DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); |
| 75 | DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); | 75 | DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); |
| 76 | DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); | 76 | DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); |
| 77 | DEFINE(PLATFORM, offsetof(struct systemcfg, platform)); | ||
| 78 | DEFINE(PLATFORM_LPAR, PLATFORM_LPAR); | 77 | DEFINE(PLATFORM_LPAR, PLATFORM_LPAR); |
| 79 | 78 | ||
| 80 | /* paca */ | 79 | /* paca */ |
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 9e8050ea1225..1c869ea72d28 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #include <asm/processor.h> | 28 | #include <asm/processor.h> |
| 29 | #include <asm/page.h> | 29 | #include <asm/page.h> |
| 30 | #include <asm/mmu.h> | 30 | #include <asm/mmu.h> |
| 31 | #include <asm/systemcfg.h> | ||
| 32 | #include <asm/ppc_asm.h> | 31 | #include <asm/ppc_asm.h> |
| 33 | #include <asm/asm-offsets.h> | 32 | #include <asm/asm-offsets.h> |
| 34 | #include <asm/bug.h> | 33 | #include <asm/bug.h> |
| @@ -1701,21 +1700,9 @@ _GLOBAL(__secondary_start) | |||
| 1701 | HMT_MEDIUM /* Set thread priority to MEDIUM */ | 1700 | HMT_MEDIUM /* Set thread priority to MEDIUM */ |
| 1702 | 1701 | ||
| 1703 | ld r2,PACATOC(r13) | 1702 | ld r2,PACATOC(r13) |
| 1704 | li r6,0 | 1703 | |
| 1705 | stb r6,PACAPROCENABLED(r13) | 1704 | /* Do early setup for that CPU */ |
| 1706 | 1705 | bl .early_setup_secondary | |
| 1707 | #ifndef CONFIG_PPC_ISERIES | ||
| 1708 | /* Initialize the page table pointer register. */ | ||
| 1709 | LOADADDR(r6,_SDR1) | ||
| 1710 | ld r6,0(r6) /* get the value of _SDR1 */ | ||
| 1711 | mtspr SPRN_SDR1,r6 /* set the htab location */ | ||
| 1712 | #endif | ||
| 1713 | /* Initialize the first segment table (or SLB) entry */ | ||
| 1714 | ld r3,PACASTABVIRT(r13) /* get addr of segment table */ | ||
| 1715 | BEGIN_FTR_SECTION | ||
| 1716 | bl .stab_initialize | ||
| 1717 | END_FTR_SECTION_IFCLR(CPU_FTR_SLB) | ||
| 1718 | bl .slb_initialize | ||
| 1719 | 1706 | ||
| 1720 | /* Initialize the kernel stack. Just a repeat for iSeries. */ | 1707 | /* Initialize the kernel stack. Just a repeat for iSeries. */ |
| 1721 | LOADADDR(r3,current_set) | 1708 | LOADADDR(r3,current_set) |
| @@ -1724,37 +1711,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) | |||
| 1724 | addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD | 1711 | addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD |
| 1725 | std r1,PACAKSAVE(r13) | 1712 | std r1,PACAKSAVE(r13) |
| 1726 | 1713 | ||
| 1727 | ld r3,PACASTABREAL(r13) /* get raddr of segment table */ | ||
| 1728 | ori r4,r3,1 /* turn on valid bit */ | ||
| 1729 | |||
| 1730 | #ifdef CONFIG_PPC_ISERIES | ||
| 1731 | li r0,-1 /* hypervisor call */ | ||
| 1732 | li r3,1 | ||
| 1733 | sldi r3,r3,63 /* 0x8000000000000000 */ | ||
| 1734 | ori r3,r3,4 /* 0x8000000000000004 */ | ||
| 1735 | sc /* HvCall_setASR */ | ||
| 1736 | #else | ||
| 1737 | /* set the ASR */ | ||
| 1738 | ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */ | ||
| 1739 | ld r3,0(r3) | ||
| 1740 | lwz r3,PLATFORM(r3) /* r3 = platform flags */ | ||
| 1741 | andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ | ||
| 1742 | beq 98f /* branch if result is 0 */ | ||
| 1743 | mfspr r3,SPRN_PVR | ||
| 1744 | srwi r3,r3,16 | ||
| 1745 | cmpwi r3,0x37 /* SStar */ | ||
| 1746 | beq 97f | ||
| 1747 | cmpwi r3,0x36 /* IStar */ | ||
| 1748 | beq 97f | ||
| 1749 | cmpwi r3,0x34 /* Pulsar */ | ||
| 1750 | bne 98f | ||
| 1751 | 97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ | ||
| 1752 | HVSC /* Invoking hcall */ | ||
| 1753 | b 99f | ||
| 1754 | 98: /* !(rpa hypervisor) || !(star) */ | ||
| 1755 | mtasr r4 /* set the stab location */ | ||
| 1756 | 99: | ||
| 1757 | #endif | ||
| 1758 | li r7,0 | 1714 | li r7,0 |
| 1759 | mtlr r7 | 1715 | mtlr r7 |
| 1760 | 1716 | ||
| @@ -1896,40 +1852,6 @@ _STATIC(start_here_multiplatform) | |||
| 1896 | mr r3,r31 | 1852 | mr r3,r31 |
| 1897 | bl .early_setup | 1853 | bl .early_setup |
| 1898 | 1854 | ||
| 1899 | /* set the ASR */ | ||
| 1900 | ld r3,PACASTABREAL(r13) | ||
| 1901 | ori r4,r3,1 /* turn on valid bit */ | ||
| 1902 | ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */ | ||
| 1903 | ld r3,0(r3) | ||
| 1904 | lwz r3,PLATFORM(r3) /* r3 = platform flags */ | ||
| 1905 | andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ | ||
| 1906 | beq 98f /* branch if result is 0 */ | ||
| 1907 | mfspr r3,SPRN_PVR | ||
| 1908 | srwi r3,r3,16 | ||
| 1909 | cmpwi r3,0x37 /* SStar */ | ||
| 1910 | beq 97f | ||
| 1911 | cmpwi r3,0x36 /* IStar */ | ||
| 1912 | beq 97f | ||
| 1913 | cmpwi r3,0x34 /* Pulsar */ | ||
| 1914 | bne 98f | ||
| 1915 | 97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ | ||
| 1916 | HVSC /* Invoking hcall */ | ||
| 1917 | b 99f | ||
| 1918 | 98: /* !(rpa hypervisor) || !(star) */ | ||
| 1919 | mtasr r4 /* set the stab location */ | ||
| 1920 | 99: | ||
| 1921 | /* Set SDR1 (hash table pointer) */ | ||
| 1922 | ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */ | ||
| 1923 | ld r3,0(r3) | ||
| 1924 | lwz r3,PLATFORM(r3) /* r3 = platform flags */ | ||
| 1925 | /* Test if bit 0 is set (LPAR bit) */ | ||
| 1926 | andi. r3,r3,PLATFORM_LPAR | ||
| 1927 | bne 98f /* branch if result is !0 */ | ||
| 1928 | LOADADDR(r6,_SDR1) /* Only if NOT LPAR */ | ||
| 1929 | sub r6,r6,r26 | ||
| 1930 | ld r6,0(r6) /* get the value of _SDR1 */ | ||
| 1931 | mtspr SPRN_SDR1,r6 /* set the htab location */ | ||
| 1932 | 98: | ||
| 1933 | LOADADDR(r3,.start_here_common) | 1855 | LOADADDR(r3,.start_here_common) |
| 1934 | SET_REG_TO_CONST(r4, MSR_KERNEL) | 1856 | SET_REG_TO_CONST(r4, MSR_KERNEL) |
| 1935 | mtspr SPRN_SRR0,r3 | 1857 | mtspr SPRN_SRR0,r3 |
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index 715bc0e71e0f..b879d3057ef8 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <asm/processor.h> | 26 | #include <asm/processor.h> |
| 27 | #include <asm/cputable.h> | 27 | #include <asm/cputable.h> |
| 28 | #include <asm/time.h> | 28 | #include <asm/time.h> |
| 29 | #include <asm/systemcfg.h> | ||
| 30 | #include <asm/machdep.h> | 29 | #include <asm/machdep.h> |
| 31 | #include <asm/smp.h> | 30 | #include <asm/smp.h> |
| 32 | 31 | ||
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index 914632ec587d..492bca6137eb 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S | |||
| @@ -78,12 +78,12 @@ _GLOBAL(call_do_softirq) | |||
| 78 | mtlr r0 | 78 | mtlr r0 |
| 79 | blr | 79 | blr |
| 80 | 80 | ||
| 81 | _GLOBAL(call_handle_IRQ_event) | 81 | _GLOBAL(call___do_IRQ) |
| 82 | mflr r0 | 82 | mflr r0 |
| 83 | std r0,16(r1) | 83 | std r0,16(r1) |
| 84 | stdu r1,THREAD_SIZE-112(r6) | 84 | stdu r1,THREAD_SIZE-112(r5) |
| 85 | mr r1,r6 | 85 | mr r1,r5 |
| 86 | bl .handle_IRQ_event | 86 | bl .__do_IRQ |
| 87 | ld r1,0(r1) | 87 | ld r1,0(r1) |
| 88 | ld r0,16(r1) | 88 | ld r0,16(r1) |
| 89 | mtlr r0 | 89 | mtlr r0 |
diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c index 4fb1a9f5060d..c0fcd29918ce 100644 --- a/arch/ppc64/kernel/nvram.c +++ b/arch/ppc64/kernel/nvram.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | #include <asm/rtas.h> | 31 | #include <asm/rtas.h> |
| 32 | #include <asm/prom.h> | 32 | #include <asm/prom.h> |
| 33 | #include <asm/machdep.h> | 33 | #include <asm/machdep.h> |
| 34 | #include <asm/systemcfg.h> | ||
| 35 | 34 | ||
| 36 | #undef DEBUG_NVRAM | 35 | #undef DEBUG_NVRAM |
| 37 | 36 | ||
| @@ -167,7 +166,7 @@ static int dev_nvram_ioctl(struct inode *inode, struct file *file, | |||
| 167 | case IOC_NVRAM_GET_OFFSET: { | 166 | case IOC_NVRAM_GET_OFFSET: { |
| 168 | int part, offset; | 167 | int part, offset; |
| 169 | 168 | ||
| 170 | if (systemcfg->platform != PLATFORM_POWERMAC) | 169 | if (_machine != PLATFORM_POWERMAC) |
| 171 | return -EINVAL; | 170 | return -EINVAL; |
| 172 | if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) | 171 | if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) |
| 173 | return -EFAULT; | 172 | return -EFAULT; |
| @@ -450,7 +449,7 @@ static int nvram_setup_partition(void) | |||
| 450 | * in our nvram, as Apple defined partitions use pretty much | 449 | * in our nvram, as Apple defined partitions use pretty much |
| 451 | * all of the space | 450 | * all of the space |
| 452 | */ | 451 | */ |
| 453 | if (systemcfg->platform == PLATFORM_POWERMAC) | 452 | if (_machine == PLATFORM_POWERMAC) |
| 454 | return -ENOSPC; | 453 | return -ENOSPC; |
| 455 | 454 | ||
| 456 | /* see if we have an OS partition that meets our needs. | 455 | /* see if we have an OS partition that meets our needs. |
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index 30247ff74972..3cef1b8f57f0 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c | |||
| @@ -548,6 +548,11 @@ static int __init pcibios_init(void) | |||
| 548 | if (ppc64_isabridge_dev != NULL) | 548 | if (ppc64_isabridge_dev != NULL) |
| 549 | printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev)); | 549 | printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev)); |
| 550 | 550 | ||
| 551 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
| 552 | /* map in PCI I/O space */ | ||
| 553 | phbs_remap_io(); | ||
| 554 | #endif | ||
| 555 | |||
| 551 | printk("PCI: Probing PCI hardware done\n"); | 556 | printk("PCI: Probing PCI hardware done\n"); |
| 552 | 557 | ||
| 553 | return 0; | 558 | return 0; |
| @@ -1277,12 +1282,9 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus, | |||
| 1277 | * G5 machines... So when something asks for bus 0 io base | 1282 | * G5 machines... So when something asks for bus 0 io base |
| 1278 | * (bus 0 is HT root), we return the AGP one instead. | 1283 | * (bus 0 is HT root), we return the AGP one instead. |
| 1279 | */ | 1284 | */ |
| 1280 | #ifdef CONFIG_PPC_PMAC | 1285 | if (machine_is_compatible("MacRISC4")) |
| 1281 | if (systemcfg->platform == PLATFORM_POWERMAC && | ||
| 1282 | machine_is_compatible("MacRISC4")) | ||
| 1283 | if (in_bus == 0) | 1286 | if (in_bus == 0) |
| 1284 | in_bus = 0xf0; | 1287 | in_bus = 0xf0; |
| 1285 | #endif /* CONFIG_PPC_PMAC */ | ||
| 1286 | 1288 | ||
| 1287 | /* That syscall isn't quite compatible with PCI domains, but it's | 1289 | /* That syscall isn't quite compatible with PCI domains, but it's |
| 1288 | * used on pre-domains setup. We return the first match | 1290 | * used on pre-domains setup. We return the first match |
diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c index 1a443a7ada4c..12c4c9e9bbc7 100644 --- a/arch/ppc64/kernel/pci_dn.c +++ b/arch/ppc64/kernel/pci_dn.c | |||
| @@ -43,7 +43,7 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data) | |||
| 43 | u32 *regs; | 43 | u32 *regs; |
| 44 | struct pci_dn *pdn; | 44 | struct pci_dn *pdn; |
| 45 | 45 | ||
| 46 | if (phb->is_dynamic) | 46 | if (mem_init_done) |
| 47 | pdn = kmalloc(sizeof(*pdn), GFP_KERNEL); | 47 | pdn = kmalloc(sizeof(*pdn), GFP_KERNEL); |
| 48 | else | 48 | else |
| 49 | pdn = alloc_bootmem(sizeof(*pdn)); | 49 | pdn = alloc_bootmem(sizeof(*pdn)); |
| @@ -120,6 +120,14 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre, | |||
| 120 | return NULL; | 120 | return NULL; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | /** | ||
| 124 | * pci_devs_phb_init_dynamic - setup pci devices under this PHB | ||
| 125 | * phb: pci-to-host bridge (top-level bridge connecting to cpu) | ||
| 126 | * | ||
| 127 | * This routine is called both during boot, (before the memory | ||
| 128 | * subsystem is set up, before kmalloc is valid) and during the | ||
| 129 | * dynamic lpar operation of adding a PHB to a running system. | ||
| 130 | */ | ||
| 123 | void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) | 131 | void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) |
| 124 | { | 132 | { |
| 125 | struct device_node * dn = (struct device_node *) phb->arch_data; | 133 | struct device_node * dn = (struct device_node *) phb->arch_data; |
| @@ -201,9 +209,14 @@ static struct notifier_block pci_dn_reconfig_nb = { | |||
| 201 | .notifier_call = pci_dn_reconfig_notifier, | 209 | .notifier_call = pci_dn_reconfig_notifier, |
| 202 | }; | 210 | }; |
| 203 | 211 | ||
| 204 | /* | 212 | /** |
| 205 | * Actually initialize the phbs. | 213 | * pci_devs_phb_init - Initialize phbs and pci devs under them. |
| 206 | * The buswalk on this phb has not happened yet. | 214 | * |
| 215 | * This routine walks over all phb's (pci-host bridges) on the | ||
| 216 | * system, and sets up assorted pci-related structures | ||
| 217 | * (including pci info in the device node structs) for each | ||
| 218 | * pci device found underneath. This routine runs once, | ||
| 219 | * early in the boot sequence. | ||
| 207 | */ | 220 | */ |
| 208 | void __init pci_devs_phb_init(void) | 221 | void __init pci_devs_phb_init(void) |
| 209 | { | 222 | { |
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index 3402fbee62c7..fbad2c360784 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c | |||
| @@ -318,7 +318,7 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ | 320 | /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ |
| 321 | if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) { | 321 | if (_machine == PLATFORM_POWERMAC && ic && ic->parent) { |
| 322 | char *name = get_property(ic->parent, "name", NULL); | 322 | char *name = get_property(ic->parent, "name", NULL); |
| 323 | if (name && !strcmp(name, "u3")) | 323 | if (name && !strcmp(name, "u3")) |
| 324 | np->intrs[intrcount].line += 128; | 324 | np->intrs[intrcount].line += 128; |
| @@ -1065,7 +1065,7 @@ static int __init early_init_dt_scan_chosen(unsigned long node, | |||
| 1065 | prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL); | 1065 | prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL); |
| 1066 | if (prop == NULL) | 1066 | if (prop == NULL) |
| 1067 | return 0; | 1067 | return 0; |
| 1068 | systemcfg->platform = *prop; | 1068 | _machine = *prop; |
| 1069 | 1069 | ||
| 1070 | /* check if iommu is forced on or off */ | 1070 | /* check if iommu is forced on or off */ |
| 1071 | if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL) | 1071 | if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL) |
| @@ -1230,11 +1230,8 @@ void __init early_init_devtree(void *params) | |||
| 1230 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); | 1230 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); |
| 1231 | lmb_enforce_memory_limit(memory_limit); | 1231 | lmb_enforce_memory_limit(memory_limit); |
| 1232 | lmb_analyze(); | 1232 | lmb_analyze(); |
| 1233 | systemcfg->physicalMemorySize = lmb_phys_mem_size(); | ||
| 1234 | lmb_reserve(0, __pa(klimit)); | 1233 | lmb_reserve(0, __pa(klimit)); |
| 1235 | 1234 | ||
| 1236 | DBG("Phys. mem: %lx\n", systemcfg->physicalMemorySize); | ||
| 1237 | |||
| 1238 | /* Reserve LMB regions used by kernel, initrd, dt, etc... */ | 1235 | /* Reserve LMB regions used by kernel, initrd, dt, etc... */ |
| 1239 | early_reserve_mem(); | 1236 | early_reserve_mem(); |
| 1240 | 1237 | ||
| @@ -1753,7 +1750,7 @@ static int of_finish_dynamic_node(struct device_node *node, | |||
| 1753 | /* We don't support that function on PowerMac, at least | 1750 | /* We don't support that function on PowerMac, at least |
| 1754 | * not yet | 1751 | * not yet |
| 1755 | */ | 1752 | */ |
| 1756 | if (systemcfg->platform == PLATFORM_POWERMAC) | 1753 | if (_machine == PLATFORM_POWERMAC) |
| 1757 | return -ENODEV; | 1754 | return -ENODEV; |
| 1758 | 1755 | ||
| 1759 | /* fix up new node's linux_phandle field */ | 1756 | /* fix up new node's linux_phandle field */ |
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c index e4c880dab997..6375f40b23db 100644 --- a/arch/ppc64/kernel/prom_init.c +++ b/arch/ppc64/kernel/prom_init.c | |||
| @@ -1934,7 +1934,8 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long | |||
| 1934 | /* | 1934 | /* |
| 1935 | * On pSeries, inform the firmware about our capabilities | 1935 | * On pSeries, inform the firmware about our capabilities |
| 1936 | */ | 1936 | */ |
| 1937 | if (RELOC(of_platform) & PLATFORM_PSERIES) | 1937 | if (RELOC(of_platform) == PLATFORM_PSERIES || |
| 1938 | RELOC(of_platform) == PLATFORM_PSERIES_LPAR) | ||
| 1938 | prom_send_capabilities(); | 1939 | prom_send_capabilities(); |
| 1939 | 1940 | ||
| 1940 | /* | 1941 | /* |
diff --git a/arch/ppc64/kernel/vdso.c b/arch/ppc64/kernel/vdso.c index 4aacf521e3e4..1bbacac44988 100644 --- a/arch/ppc64/kernel/vdso.c +++ b/arch/ppc64/kernel/vdso.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <asm/machdep.h> | 34 | #include <asm/machdep.h> |
| 35 | #include <asm/cputable.h> | 35 | #include <asm/cputable.h> |
| 36 | #include <asm/sections.h> | 36 | #include <asm/sections.h> |
| 37 | #include <asm/systemcfg.h> | ||
| 37 | #include <asm/vdso.h> | 38 | #include <asm/vdso.h> |
| 38 | 39 | ||
| 39 | #undef DEBUG | 40 | #undef DEBUG |
| @@ -179,7 +180,7 @@ static struct page * vdso_vma_nopage(struct vm_area_struct * vma, | |||
| 179 | * Last page is systemcfg. | 180 | * Last page is systemcfg. |
| 180 | */ | 181 | */ |
| 181 | if ((vma->vm_end - address) <= PAGE_SIZE) | 182 | if ((vma->vm_end - address) <= PAGE_SIZE) |
| 182 | pg = virt_to_page(systemcfg); | 183 | pg = virt_to_page(_systemcfg); |
| 183 | else | 184 | else |
| 184 | pg = virt_to_page(vbase + offset); | 185 | pg = virt_to_page(vbase + offset); |
| 185 | 186 | ||
| @@ -604,7 +605,7 @@ void __init vdso_init(void) | |||
| 604 | get_page(pg); | 605 | get_page(pg); |
| 605 | } | 606 | } |
| 606 | 607 | ||
| 607 | get_page(virt_to_page(systemcfg)); | 608 | get_page(virt_to_page(_systemcfg)); |
| 608 | } | 609 | } |
| 609 | 610 | ||
| 610 | int in_gate_area_no_task(unsigned long addr) | 611 | int in_gate_area_no_task(unsigned long addr) |
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 9342d5bc7bb4..f5d49a110654 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <linux/ethtool.h> | 37 | #include <linux/ethtool.h> |
| 38 | #include <linux/bitops.h> | 38 | #include <linux/bitops.h> |
| 39 | #include <linux/fs.h> | 39 | #include <linux/fs.h> |
| 40 | #include <linux/platform_device.h> | ||
| 40 | 41 | ||
| 41 | #include <linux/vmalloc.h> | 42 | #include <linux/vmalloc.h> |
| 42 | #include <asm/pgtable.h> | 43 | #include <asm/pgtable.h> |
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index a940b96433c7..e67b1d06611c 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/ethtool.h> | 34 | #include <linux/ethtool.h> |
| 35 | #include <linux/bitops.h> | 35 | #include <linux/bitops.h> |
| 36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
| 37 | #include <linux/platform_device.h> | ||
| 37 | 38 | ||
| 38 | #include <asm/immap_cpm2.h> | 39 | #include <asm/immap_cpm2.h> |
| 39 | #include <asm/mpc8260.h> | 40 | #include <asm/mpc8260.h> |
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index 5ef4e845a387..2e8f44469699 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/ethtool.h> | 34 | #include <linux/ethtool.h> |
| 35 | #include <linux/bitops.h> | 35 | #include <linux/bitops.h> |
| 36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
| 37 | #include <linux/platform_device.h> | ||
| 37 | 38 | ||
| 38 | #include <asm/irq.h> | 39 | #include <asm/irq.h> |
| 39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index d8c6e9cadcf5..a3897fda71fa 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/ethtool.h> | 34 | #include <linux/ethtool.h> |
| 35 | #include <linux/bitops.h> | 35 | #include <linux/bitops.h> |
| 36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
| 37 | #include <linux/platform_device.h> | ||
| 37 | 38 | ||
| 38 | #include <asm/irq.h> | 39 | #include <asm/irq.h> |
| 39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index fcb66b9a0e28..e8593a60ee89 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c | |||
| @@ -306,7 +306,7 @@ static int dlpar_add_phb(char *drc_name, struct device_node *dn) | |||
| 306 | { | 306 | { |
| 307 | struct pci_controller *phb; | 307 | struct pci_controller *phb; |
| 308 | 308 | ||
| 309 | if (PCI_DN(dn)->phb) { | 309 | if (PCI_DN(dn) && PCI_DN(dn)->phb) { |
| 310 | /* PHB already exists */ | 310 | /* PHB already exists */ |
| 311 | return -EINVAL; | 311 | return -EINVAL; |
| 312 | } | 312 | } |
diff --git a/include/asm-ppc64/abs_addr.h b/include/asm-powerpc/abs_addr.h index dc3fc3fefef2..18415108fc56 100644 --- a/include/asm-ppc64/abs_addr.h +++ b/include/asm-powerpc/abs_addr.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #ifndef _ABS_ADDR_H | 1 | #ifndef _ASM_POWERPC_ABS_ADDR_H |
| 2 | #define _ABS_ADDR_H | 2 | #define _ASM_POWERPC_ABS_ADDR_H |
| 3 | 3 | ||
| 4 | #include <linux/config.h> | 4 | #include <linux/config.h> |
| 5 | 5 | ||
| @@ -70,4 +70,4 @@ static inline unsigned long phys_to_abs(unsigned long pa) | |||
| 70 | #define iseries_hv_addr(virtaddr) \ | 70 | #define iseries_hv_addr(virtaddr) \ |
| 71 | (0x8000000000000000 | virt_to_abs(virtaddr)) | 71 | (0x8000000000000000 | virt_to_abs(virtaddr)) |
| 72 | 72 | ||
| 73 | #endif /* _ABS_ADDR_H */ | 73 | #endif /* _ASM_POWERPC_ABS_ADDR_H */ |
diff --git a/include/asm-powerpc/asm-compat.h b/include/asm-powerpc/asm-compat.h new file mode 100644 index 000000000000..8b133efc9f79 --- /dev/null +++ b/include/asm-powerpc/asm-compat.h | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | #ifndef _ASM_POWERPC_ASM_COMPAT_H | ||
| 2 | #define _ASM_POWERPC_ASM_COMPAT_H | ||
| 3 | |||
| 4 | #include <linux/config.h> | ||
| 5 | #include <asm/types.h> | ||
| 6 | |||
| 7 | #ifdef __ASSEMBLY__ | ||
| 8 | # define stringify_in_c(...) __VA_ARGS__ | ||
| 9 | # define ASM_CONST(x) x | ||
| 10 | #else | ||
| 11 | /* This version of stringify will deal with commas... */ | ||
| 12 | # define __stringify_in_c(...) #__VA_ARGS__ | ||
| 13 | # define stringify_in_c(...) __stringify_in_c(__VA_ARGS__) " " | ||
| 14 | # define __ASM_CONST(x) x##UL | ||
| 15 | # define ASM_CONST(x) __ASM_CONST(x) | ||
| 16 | #endif | ||
| 17 | |||
| 18 | #ifdef __powerpc64__ | ||
| 19 | |||
| 20 | /* operations for longs and pointers */ | ||
| 21 | #define PPC_LL stringify_in_c(ld) | ||
| 22 | #define PPC_STL stringify_in_c(std) | ||
| 23 | #define PPC_LCMPI stringify_in_c(cmpdi) | ||
| 24 | #define PPC_LONG stringify_in_c(.llong) | ||
| 25 | #define PPC_TLNEI stringify_in_c(tdnei) | ||
| 26 | #define PPC_LLARX stringify_in_c(ldarx) | ||
| 27 | #define PPC_STLCX stringify_in_c(stdcx.) | ||
| 28 | #define PPC_CNTLZL stringify_in_c(cntlzd) | ||
| 29 | |||
| 30 | #else /* 32-bit */ | ||
| 31 | |||
| 32 | /* operations for longs and pointers */ | ||
| 33 | #define PPC_LL stringify_in_c(lwz) | ||
| 34 | #define PPC_STL stringify_in_c(stw) | ||
| 35 | #define PPC_LCMPI stringify_in_c(cmpwi) | ||
| 36 | #define PPC_LONG stringify_in_c(.long) | ||
| 37 | #define PPC_TLNEI stringify_in_c(twnei) | ||
| 38 | #define PPC_LLARX stringify_in_c(lwarx) | ||
| 39 | #define PPC_STLCX stringify_in_c(stwcx.) | ||
| 40 | #define PPC_CNTLZL stringify_in_c(cntlzw) | ||
| 41 | |||
| 42 | #endif | ||
| 43 | |||
| 44 | #ifdef CONFIG_IBM405_ERR77 | ||
| 45 | /* Erratum #77 on the 405 means we need a sync or dcbt before every | ||
| 46 | * stwcx. The old ATOMIC_SYNC_FIX covered some but not all of this. | ||
| 47 | */ | ||
| 48 | #define PPC405_ERR77(ra,rb) stringify_in_c(dcbt ra, rb;) | ||
| 49 | #define PPC405_ERR77_SYNC stringify_in_c(sync;) | ||
| 50 | #else | ||
| 51 | #define PPC405_ERR77(ra,rb) | ||
| 52 | #define PPC405_ERR77_SYNC | ||
| 53 | #endif | ||
| 54 | |||
| 55 | #endif /* _ASM_POWERPC_ASM_COMPAT_H */ | ||
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h index ed4b345ed75d..9c0b372a46e1 100644 --- a/include/asm-powerpc/atomic.h +++ b/include/asm-powerpc/atomic.h | |||
| @@ -9,21 +9,13 @@ typedef struct { volatile int counter; } atomic_t; | |||
| 9 | 9 | ||
| 10 | #ifdef __KERNEL__ | 10 | #ifdef __KERNEL__ |
| 11 | #include <asm/synch.h> | 11 | #include <asm/synch.h> |
| 12 | #include <asm/asm-compat.h> | ||
| 12 | 13 | ||
| 13 | #define ATOMIC_INIT(i) { (i) } | 14 | #define ATOMIC_INIT(i) { (i) } |
| 14 | 15 | ||
| 15 | #define atomic_read(v) ((v)->counter) | 16 | #define atomic_read(v) ((v)->counter) |
| 16 | #define atomic_set(v,i) (((v)->counter) = (i)) | 17 | #define atomic_set(v,i) (((v)->counter) = (i)) |
| 17 | 18 | ||
| 18 | /* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx. | ||
| 19 | * The old ATOMIC_SYNC_FIX covered some but not all of this. | ||
| 20 | */ | ||
| 21 | #ifdef CONFIG_IBM405_ERR77 | ||
| 22 | #define PPC405_ERR77(ra,rb) "dcbt " #ra "," #rb ";" | ||
| 23 | #else | ||
| 24 | #define PPC405_ERR77(ra,rb) | ||
| 25 | #endif | ||
| 26 | |||
| 27 | static __inline__ void atomic_add(int a, atomic_t *v) | 19 | static __inline__ void atomic_add(int a, atomic_t *v) |
| 28 | { | 20 | { |
| 29 | int t; | 21 | int t; |
| @@ -205,5 +197,183 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v) | |||
| 205 | #define smp_mb__before_atomic_inc() smp_mb() | 197 | #define smp_mb__before_atomic_inc() smp_mb() |
| 206 | #define smp_mb__after_atomic_inc() smp_mb() | 198 | #define smp_mb__after_atomic_inc() smp_mb() |
| 207 | 199 | ||
| 200 | #ifdef __powerpc64__ | ||
| 201 | |||
| 202 | typedef struct { volatile long counter; } atomic64_t; | ||
| 203 | |||
| 204 | #define ATOMIC64_INIT(i) { (i) } | ||
| 205 | |||
| 206 | #define atomic64_read(v) ((v)->counter) | ||
| 207 | #define atomic64_set(v,i) (((v)->counter) = (i)) | ||
| 208 | |||
| 209 | static __inline__ void atomic64_add(long a, atomic64_t *v) | ||
| 210 | { | ||
| 211 | long t; | ||
| 212 | |||
| 213 | __asm__ __volatile__( | ||
| 214 | "1: ldarx %0,0,%3 # atomic64_add\n\ | ||
| 215 | add %0,%2,%0\n\ | ||
| 216 | stdcx. %0,0,%3 \n\ | ||
| 217 | bne- 1b" | ||
| 218 | : "=&r" (t), "=m" (v->counter) | ||
| 219 | : "r" (a), "r" (&v->counter), "m" (v->counter) | ||
| 220 | : "cc"); | ||
| 221 | } | ||
| 222 | |||
| 223 | static __inline__ long atomic64_add_return(long a, atomic64_t *v) | ||
| 224 | { | ||
| 225 | long t; | ||
| 226 | |||
| 227 | __asm__ __volatile__( | ||
| 228 | EIEIO_ON_SMP | ||
| 229 | "1: ldarx %0,0,%2 # atomic64_add_return\n\ | ||
| 230 | add %0,%1,%0\n\ | ||
| 231 | stdcx. %0,0,%2 \n\ | ||
| 232 | bne- 1b" | ||
| 233 | ISYNC_ON_SMP | ||
| 234 | : "=&r" (t) | ||
| 235 | : "r" (a), "r" (&v->counter) | ||
| 236 | : "cc", "memory"); | ||
| 237 | |||
| 238 | return t; | ||
| 239 | } | ||
| 240 | |||
| 241 | #define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) | ||
| 242 | |||
| 243 | static __inline__ void atomic64_sub(long a, atomic64_t *v) | ||
| 244 | { | ||
| 245 | long t; | ||
| 246 | |||
| 247 | __asm__ __volatile__( | ||
| 248 | "1: ldarx %0,0,%3 # atomic64_sub\n\ | ||
| 249 | subf %0,%2,%0\n\ | ||
| 250 | stdcx. %0,0,%3 \n\ | ||
| 251 | bne- 1b" | ||
| 252 | : "=&r" (t), "=m" (v->counter) | ||
| 253 | : "r" (a), "r" (&v->counter), "m" (v->counter) | ||
| 254 | : "cc"); | ||
| 255 | } | ||
| 256 | |||
| 257 | static __inline__ long atomic64_sub_return(long a, atomic64_t *v) | ||
| 258 | { | ||
| 259 | long t; | ||
| 260 | |||
| 261 | __asm__ __volatile__( | ||
| 262 | EIEIO_ON_SMP | ||
| 263 | "1: ldarx %0,0,%2 # atomic64_sub_return\n\ | ||
| 264 | subf %0,%1,%0\n\ | ||
| 265 | stdcx. %0,0,%2 \n\ | ||
| 266 | bne- 1b" | ||
| 267 | ISYNC_ON_SMP | ||
| 268 | : "=&r" (t) | ||
| 269 | : "r" (a), "r" (&v->counter) | ||
| 270 | : "cc", "memory"); | ||
| 271 | |||
| 272 | return t; | ||
| 273 | } | ||
| 274 | |||
| 275 | static __inline__ void atomic64_inc(atomic64_t *v) | ||
| 276 | { | ||
| 277 | long t; | ||
| 278 | |||
| 279 | __asm__ __volatile__( | ||
| 280 | "1: ldarx %0,0,%2 # atomic64_inc\n\ | ||
| 281 | addic %0,%0,1\n\ | ||
| 282 | stdcx. %0,0,%2 \n\ | ||
| 283 | bne- 1b" | ||
| 284 | : "=&r" (t), "=m" (v->counter) | ||
| 285 | : "r" (&v->counter), "m" (v->counter) | ||
| 286 | : "cc"); | ||
| 287 | } | ||
| 288 | |||
| 289 | static __inline__ long atomic64_inc_return(atomic64_t *v) | ||
| 290 | { | ||
| 291 | long t; | ||
| 292 | |||
| 293 | __asm__ __volatile__( | ||
| 294 | EIEIO_ON_SMP | ||
| 295 | "1: ldarx %0,0,%1 # atomic64_inc_return\n\ | ||
| 296 | addic %0,%0,1\n\ | ||
| 297 | stdcx. %0,0,%1 \n\ | ||
| 298 | bne- 1b" | ||
| 299 | ISYNC_ON_SMP | ||
| 300 | : "=&r" (t) | ||
| 301 | : "r" (&v->counter) | ||
| 302 | : "cc", "memory"); | ||
| 303 | |||
| 304 | return t; | ||
| 305 | } | ||
| 306 | |||
| 307 | /* | ||
| 308 | * atomic64_inc_and_test - increment and test | ||
| 309 | * @v: pointer of type atomic64_t | ||
| 310 | * | ||
| 311 | * Atomically increments @v by 1 | ||
| 312 | * and returns true if the result is zero, or false for all | ||
| 313 | * other cases. | ||
| 314 | */ | ||
| 315 | #define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0) | ||
| 316 | |||
| 317 | static __inline__ void atomic64_dec(atomic64_t *v) | ||
| 318 | { | ||
| 319 | long t; | ||
| 320 | |||
| 321 | __asm__ __volatile__( | ||
| 322 | "1: ldarx %0,0,%2 # atomic64_dec\n\ | ||
| 323 | addic %0,%0,-1\n\ | ||
| 324 | stdcx. %0,0,%2\n\ | ||
| 325 | bne- 1b" | ||
| 326 | : "=&r" (t), "=m" (v->counter) | ||
| 327 | : "r" (&v->counter), "m" (v->counter) | ||
| 328 | : "cc"); | ||
| 329 | } | ||
| 330 | |||
| 331 | static __inline__ long atomic64_dec_return(atomic64_t *v) | ||
| 332 | { | ||
| 333 | long t; | ||
| 334 | |||
| 335 | __asm__ __volatile__( | ||
| 336 | EIEIO_ON_SMP | ||
| 337 | "1: ldarx %0,0,%1 # atomic64_dec_return\n\ | ||
| 338 | addic %0,%0,-1\n\ | ||
| 339 | stdcx. %0,0,%1\n\ | ||
| 340 | bne- 1b" | ||
| 341 | ISYNC_ON_SMP | ||
| 342 | : "=&r" (t) | ||
| 343 | : "r" (&v->counter) | ||
| 344 | : "cc", "memory"); | ||
| 345 | |||
| 346 | return t; | ||
| 347 | } | ||
| 348 | |||
| 349 | #define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0) | ||
| 350 | #define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) | ||
| 351 | |||
| 352 | /* | ||
| 353 | * Atomically test *v and decrement if it is greater than 0. | ||
| 354 | * The function returns the old value of *v minus 1. | ||
| 355 | */ | ||
| 356 | static __inline__ long atomic64_dec_if_positive(atomic64_t *v) | ||
| 357 | { | ||
| 358 | long t; | ||
| 359 | |||
| 360 | __asm__ __volatile__( | ||
| 361 | EIEIO_ON_SMP | ||
| 362 | "1: ldarx %0,0,%1 # atomic64_dec_if_positive\n\ | ||
| 363 | addic. %0,%0,-1\n\ | ||
| 364 | blt- 2f\n\ | ||
| 365 | stdcx. %0,0,%1\n\ | ||
| 366 | bne- 1b" | ||
| 367 | ISYNC_ON_SMP | ||
| 368 | "\n\ | ||
| 369 | 2:" : "=&r" (t) | ||
| 370 | : "r" (&v->counter) | ||
| 371 | : "cc", "memory"); | ||
| 372 | |||
| 373 | return t; | ||
| 374 | } | ||
| 375 | |||
| 376 | #endif /* __powerpc64__ */ | ||
| 377 | |||
| 208 | #endif /* __KERNEL__ */ | 378 | #endif /* __KERNEL__ */ |
| 209 | #endif /* _ASM_POWERPC_ATOMIC_H_ */ | 379 | #endif /* _ASM_POWERPC_ATOMIC_H_ */ |
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h index dc25c53704d5..5727229b0444 100644 --- a/include/asm-powerpc/bitops.h +++ b/include/asm-powerpc/bitops.h | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | 40 | ||
| 41 | #include <linux/compiler.h> | 41 | #include <linux/compiler.h> |
| 42 | #include <asm/atomic.h> | 42 | #include <asm/atomic.h> |
| 43 | #include <asm/asm-compat.h> | ||
| 43 | #include <asm/synch.h> | 44 | #include <asm/synch.h> |
| 44 | 45 | ||
| 45 | /* | 46 | /* |
| @@ -52,16 +53,6 @@ | |||
| 52 | #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) | 53 | #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) |
| 53 | #define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7) | 54 | #define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7) |
| 54 | 55 | ||
| 55 | #ifdef CONFIG_PPC64 | ||
| 56 | #define LARXL "ldarx" | ||
| 57 | #define STCXL "stdcx." | ||
| 58 | #define CNTLZL "cntlzd" | ||
| 59 | #else | ||
| 60 | #define LARXL "lwarx" | ||
| 61 | #define STCXL "stwcx." | ||
| 62 | #define CNTLZL "cntlzw" | ||
| 63 | #endif | ||
| 64 | |||
| 65 | static __inline__ void set_bit(int nr, volatile unsigned long *addr) | 56 | static __inline__ void set_bit(int nr, volatile unsigned long *addr) |
| 66 | { | 57 | { |
| 67 | unsigned long old; | 58 | unsigned long old; |
| @@ -69,10 +60,10 @@ static __inline__ void set_bit(int nr, volatile unsigned long *addr) | |||
| 69 | unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | 60 | unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); |
| 70 | 61 | ||
| 71 | __asm__ __volatile__( | 62 | __asm__ __volatile__( |
| 72 | "1:" LARXL " %0,0,%3 # set_bit\n" | 63 | "1:" PPC_LLARX "%0,0,%3 # set_bit\n" |
| 73 | "or %0,%0,%2\n" | 64 | "or %0,%0,%2\n" |
| 74 | PPC405_ERR77(0,%3) | 65 | PPC405_ERR77(0,%3) |
| 75 | STCXL " %0,0,%3\n" | 66 | PPC_STLCX "%0,0,%3\n" |
| 76 | "bne- 1b" | 67 | "bne- 1b" |
| 77 | : "=&r"(old), "=m"(*p) | 68 | : "=&r"(old), "=m"(*p) |
| 78 | : "r"(mask), "r"(p), "m"(*p) | 69 | : "r"(mask), "r"(p), "m"(*p) |
| @@ -86,10 +77,10 @@ static __inline__ void clear_bit(int nr, volatile unsigned long *addr) | |||
| 86 | unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | 77 | unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); |
| 87 | 78 | ||
| 88 | __asm__ __volatile__( | 79 | __asm__ __volatile__( |
| 89 | "1:" LARXL " %0,0,%3 # set_bit\n" | 80 | "1:" PPC_LLARX "%0,0,%3 # clear_bit\n" |
| 90 | "andc %0,%0,%2\n" | 81 | "andc %0,%0,%2\n" |
| 91 | PPC405_ERR77(0,%3) | 82 | PPC405_ERR77(0,%3) |
| 92 | STCXL " %0,0,%3\n" | 83 | PPC_STLCX "%0,0,%3\n" |
| 93 | "bne- 1b" | 84 | "bne- 1b" |
| 94 | : "=&r"(old), "=m"(*p) | 85 | : "=&r"(old), "=m"(*p) |
| 95 | : "r"(mask), "r"(p), "m"(*p) | 86 | : "r"(mask), "r"(p), "m"(*p) |
| @@ -103,10 +94,10 @@ static __inline__ void change_bit(int nr, volatile unsigned long *addr) | |||
| 103 | unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | 94 | unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); |
| 104 | 95 | ||
| 105 | __asm__ __volatile__( | 96 | __asm__ __volatile__( |
| 106 | "1:" LARXL " %0,0,%3 # set_bit\n" | 97 | "1:" PPC_LLARX "%0,0,%3 # change_bit\n" |
| 107 | "xor %0,%0,%2\n" | 98 | "xor %0,%0,%2\n" |
| 108 | PPC405_ERR77(0,%3) | 99 | PPC405_ERR77(0,%3) |
| 109 | STCXL " %0,0,%3\n" | 100 | PPC_STLCX "%0,0,%3\n" |
| 110 | "bne- 1b" | 101 | "bne- 1b" |
| 111 | : "=&r"(old), "=m"(*p) | 102 | : "=&r"(old), "=m"(*p) |
| 112 | : "r"(mask), "r"(p), "m"(*p) | 103 | : "r"(mask), "r"(p), "m"(*p) |
| @@ -122,10 +113,10 @@ static __inline__ int test_and_set_bit(unsigned long nr, | |||
| 122 | 113 | ||
| 123 | __asm__ __volatile__( | 114 | __asm__ __volatile__( |
| 124 | EIEIO_ON_SMP | 115 | EIEIO_ON_SMP |
| 125 | "1:" LARXL " %0,0,%3 # test_and_set_bit\n" | 116 | "1:" PPC_LLARX "%0,0,%3 # test_and_set_bit\n" |
| 126 | "or %1,%0,%2 \n" | 117 | "or %1,%0,%2 \n" |
| 127 | PPC405_ERR77(0,%3) | 118 | PPC405_ERR77(0,%3) |
| 128 | STCXL " %1,0,%3 \n" | 119 | PPC_STLCX "%1,0,%3 \n" |
| 129 | "bne- 1b" | 120 | "bne- 1b" |
| 130 | ISYNC_ON_SMP | 121 | ISYNC_ON_SMP |
| 131 | : "=&r" (old), "=&r" (t) | 122 | : "=&r" (old), "=&r" (t) |
| @@ -144,10 +135,10 @@ static __inline__ int test_and_clear_bit(unsigned long nr, | |||
| 144 | 135 | ||
| 145 | __asm__ __volatile__( | 136 | __asm__ __volatile__( |
| 146 | EIEIO_ON_SMP | 137 | EIEIO_ON_SMP |
| 147 | "1:" LARXL " %0,0,%3 # test_and_clear_bit\n" | 138 | "1:" PPC_LLARX "%0,0,%3 # test_and_clear_bit\n" |
| 148 | "andc %1,%0,%2 \n" | 139 | "andc %1,%0,%2 \n" |
| 149 | PPC405_ERR77(0,%3) | 140 | PPC405_ERR77(0,%3) |
| 150 | STCXL " %1,0,%3 \n" | 141 | PPC_STLCX "%1,0,%3 \n" |
| 151 | "bne- 1b" | 142 | "bne- 1b" |
| 152 | ISYNC_ON_SMP | 143 | ISYNC_ON_SMP |
| 153 | : "=&r" (old), "=&r" (t) | 144 | : "=&r" (old), "=&r" (t) |
| @@ -166,10 +157,10 @@ static __inline__ int test_and_change_bit(unsigned long nr, | |||
| 166 | 157 | ||
| 167 | __asm__ __volatile__( | 158 | __asm__ __volatile__( |
| 168 | EIEIO_ON_SMP | 159 | EIEIO_ON_SMP |
| 169 | "1:" LARXL " %0,0,%3 # test_and_change_bit\n" | 160 | "1:" PPC_LLARX "%0,0,%3 # test_and_change_bit\n" |
| 170 | "xor %1,%0,%2 \n" | 161 | "xor %1,%0,%2 \n" |
| 171 | PPC405_ERR77(0,%3) | 162 | PPC405_ERR77(0,%3) |
| 172 | STCXL " %1,0,%3 \n" | 163 | PPC_STLCX "%1,0,%3 \n" |
| 173 | "bne- 1b" | 164 | "bne- 1b" |
| 174 | ISYNC_ON_SMP | 165 | ISYNC_ON_SMP |
| 175 | : "=&r" (old), "=&r" (t) | 166 | : "=&r" (old), "=&r" (t) |
| @@ -184,9 +175,9 @@ static __inline__ void set_bits(unsigned long mask, unsigned long *addr) | |||
| 184 | unsigned long old; | 175 | unsigned long old; |
| 185 | 176 | ||
| 186 | __asm__ __volatile__( | 177 | __asm__ __volatile__( |
| 187 | "1:" LARXL " %0,0,%3 # set_bit\n" | 178 | "1:" PPC_LLARX "%0,0,%3 # set_bits\n" |
| 188 | "or %0,%0,%2\n" | 179 | "or %0,%0,%2\n" |
| 189 | STCXL " %0,0,%3\n" | 180 | PPC_STLCX "%0,0,%3\n" |
| 190 | "bne- 1b" | 181 | "bne- 1b" |
| 191 | : "=&r" (old), "=m" (*addr) | 182 | : "=&r" (old), "=m" (*addr) |
| 192 | : "r" (mask), "r" (addr), "m" (*addr) | 183 | : "r" (mask), "r" (addr), "m" (*addr) |
| @@ -268,7 +259,7 @@ static __inline__ int __ilog2(unsigned long x) | |||
| 268 | { | 259 | { |
| 269 | int lz; | 260 | int lz; |
| 270 | 261 | ||
| 271 | asm (CNTLZL " %0,%1" : "=r" (lz) : "r" (x)); | 262 | asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x)); |
| 272 | return BITS_PER_LONG - 1 - lz; | 263 | return BITS_PER_LONG - 1 - lz; |
| 273 | } | 264 | } |
| 274 | 265 | ||
diff --git a/include/asm-powerpc/bug.h b/include/asm-powerpc/bug.h index d625ee55f957..b001ecb3cd99 100644 --- a/include/asm-powerpc/bug.h +++ b/include/asm-powerpc/bug.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #ifndef _ASM_POWERPC_BUG_H | 1 | #ifndef _ASM_POWERPC_BUG_H |
| 2 | #define _ASM_POWERPC_BUG_H | 2 | #define _ASM_POWERPC_BUG_H |
| 3 | 3 | ||
| 4 | #include <asm/asm-compat.h> | ||
| 4 | /* | 5 | /* |
| 5 | * Define an illegal instr to trap on the bug. | 6 | * Define an illegal instr to trap on the bug. |
| 6 | * We don't use 0 because that marks the end of a function | 7 | * We don't use 0 because that marks the end of a function |
| @@ -11,14 +12,6 @@ | |||
| 11 | 12 | ||
| 12 | #ifndef __ASSEMBLY__ | 13 | #ifndef __ASSEMBLY__ |
| 13 | 14 | ||
| 14 | #ifdef __powerpc64__ | ||
| 15 | #define BUG_TABLE_ENTRY ".llong" | ||
| 16 | #define BUG_TRAP_OP "tdnei" | ||
| 17 | #else | ||
| 18 | #define BUG_TABLE_ENTRY ".long" | ||
| 19 | #define BUG_TRAP_OP "twnei" | ||
| 20 | #endif /* __powerpc64__ */ | ||
| 21 | |||
| 22 | struct bug_entry { | 15 | struct bug_entry { |
| 23 | unsigned long bug_addr; | 16 | unsigned long bug_addr; |
| 24 | long line; | 17 | long line; |
| @@ -40,16 +33,16 @@ struct bug_entry *find_bug(unsigned long bugaddr); | |||
| 40 | __asm__ __volatile__( \ | 33 | __asm__ __volatile__( \ |
| 41 | "1: twi 31,0,0\n" \ | 34 | "1: twi 31,0,0\n" \ |
| 42 | ".section __bug_table,\"a\"\n" \ | 35 | ".section __bug_table,\"a\"\n" \ |
| 43 | "\t"BUG_TABLE_ENTRY" 1b,%0,%1,%2\n" \ | 36 | "\t"PPC_LONG" 1b,%0,%1,%2\n" \ |
| 44 | ".previous" \ | 37 | ".previous" \ |
| 45 | : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \ | 38 | : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \ |
| 46 | } while (0) | 39 | } while (0) |
| 47 | 40 | ||
| 48 | #define BUG_ON(x) do { \ | 41 | #define BUG_ON(x) do { \ |
| 49 | __asm__ __volatile__( \ | 42 | __asm__ __volatile__( \ |
| 50 | "1: "BUG_TRAP_OP" %0,0\n" \ | 43 | "1: "PPC_TLNEI" %0,0\n" \ |
| 51 | ".section __bug_table,\"a\"\n" \ | 44 | ".section __bug_table,\"a\"\n" \ |
| 52 | "\t"BUG_TABLE_ENTRY" 1b,%1,%2,%3\n" \ | 45 | "\t"PPC_LONG" 1b,%1,%2,%3\n" \ |
| 53 | ".previous" \ | 46 | ".previous" \ |
| 54 | : : "r" ((long)(x)), "i" (__LINE__), \ | 47 | : : "r" ((long)(x)), "i" (__LINE__), \ |
| 55 | "i" (__FILE__), "i" (__FUNCTION__)); \ | 48 | "i" (__FILE__), "i" (__FUNCTION__)); \ |
| @@ -57,9 +50,9 @@ struct bug_entry *find_bug(unsigned long bugaddr); | |||
| 57 | 50 | ||
| 58 | #define WARN_ON(x) do { \ | 51 | #define WARN_ON(x) do { \ |
| 59 | __asm__ __volatile__( \ | 52 | __asm__ __volatile__( \ |
| 60 | "1: "BUG_TRAP_OP" %0,0\n" \ | 53 | "1: "PPC_TLNEI" %0,0\n" \ |
| 61 | ".section __bug_table,\"a\"\n" \ | 54 | ".section __bug_table,\"a\"\n" \ |
| 62 | "\t"BUG_TABLE_ENTRY" 1b,%1,%2,%3\n" \ | 55 | "\t"PPC_LONG" 1b,%1,%2,%3\n" \ |
| 63 | ".previous" \ | 56 | ".previous" \ |
| 64 | : : "r" ((long)(x)), \ | 57 | : : "r" ((long)(x)), \ |
| 65 | "i" (__LINE__ + BUG_WARNING_TRAP), \ | 58 | "i" (__LINE__ + BUG_WARNING_TRAP), \ |
diff --git a/include/asm-powerpc/cache.h b/include/asm-powerpc/cache.h new file mode 100644 index 000000000000..26ce502e76e8 --- /dev/null +++ b/include/asm-powerpc/cache.h | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | #ifndef _ASM_POWERPC_CACHE_H | ||
| 2 | #define _ASM_POWERPC_CACHE_H | ||
| 3 | |||
| 4 | #ifdef __KERNEL__ | ||
| 5 | |||
| 6 | #include <linux/config.h> | ||
| 7 | |||
| 8 | /* bytes per L1 cache line */ | ||
| 9 | #if defined(CONFIG_8xx) || defined(CONFIG_403GCX) | ||
| 10 | #define L1_CACHE_SHIFT 4 | ||
| 11 | #define MAX_COPY_PREFETCH 1 | ||
| 12 | #elif defined(CONFIG_PPC32) | ||
| 13 | #define L1_CACHE_SHIFT 5 | ||
| 14 | #define MAX_COPY_PREFETCH 4 | ||
| 15 | #else /* CONFIG_PPC64 */ | ||
| 16 | #define L1_CACHE_SHIFT 7 | ||
| 17 | #endif | ||
| 18 | |||
| 19 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) | ||
| 20 | |||
| 21 | #define SMP_CACHE_BYTES L1_CACHE_BYTES | ||
| 22 | #define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */ | ||
| 23 | |||
| 24 | #if defined(__powerpc64__) && !defined(__ASSEMBLY__) | ||
| 25 | struct ppc64_caches { | ||
| 26 | u32 dsize; /* L1 d-cache size */ | ||
| 27 | u32 dline_size; /* L1 d-cache line size */ | ||
| 28 | u32 log_dline_size; | ||
| 29 | u32 dlines_per_page; | ||
| 30 | u32 isize; /* L1 i-cache size */ | ||
| 31 | u32 iline_size; /* L1 i-cache line size */ | ||
| 32 | u32 log_iline_size; | ||
| 33 | u32 ilines_per_page; | ||
| 34 | }; | ||
| 35 | |||
| 36 | extern struct ppc64_caches ppc64_caches; | ||
| 37 | #endif /* __powerpc64__ && ! __ASSEMBLY__ */ | ||
| 38 | |||
| 39 | #endif /* __KERNEL__ */ | ||
| 40 | #endif /* _ASM_POWERPC_CACHE_H */ | ||
diff --git a/include/asm-ppc64/cacheflush.h b/include/asm-powerpc/cacheflush.h index ffbc08be8e52..8a740c88d93d 100644 --- a/include/asm-ppc64/cacheflush.h +++ b/include/asm-powerpc/cacheflush.h | |||
| @@ -1,13 +1,20 @@ | |||
| 1 | #ifndef _PPC64_CACHEFLUSH_H | 1 | /* |
| 2 | #define _PPC64_CACHEFLUSH_H | 2 | * This program is free software; you can redistribute it and/or |
| 3 | * modify it under the terms of the GNU General Public License | ||
| 4 | * as published by the Free Software Foundation; either version | ||
| 5 | * 2 of the License, or (at your option) any later version. | ||
| 6 | */ | ||
| 7 | #ifndef _ASM_POWERPC_CACHEFLUSH_H | ||
| 8 | #define _ASM_POWERPC_CACHEFLUSH_H | ||
| 9 | |||
| 10 | #ifdef __KERNEL__ | ||
| 3 | 11 | ||
| 4 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
| 5 | #include <asm/cputable.h> | 13 | #include <asm/cputable.h> |
| 6 | 14 | ||
| 7 | /* | 15 | /* |
| 8 | * No cache flushing is required when address mappings are | 16 | * No cache flushing is required when address mappings are changed, |
| 9 | * changed, because the caches on PowerPCs are physically | 17 | * because the caches on PowerPCs are physically addressed. |
| 10 | * addressed. | ||
| 11 | */ | 18 | */ |
| 12 | #define flush_cache_all() do { } while (0) | 19 | #define flush_cache_all() do { } while (0) |
| 13 | #define flush_cache_mm(mm) do { } while (0) | 20 | #define flush_cache_mm(mm) do { } while (0) |
| @@ -22,27 +29,40 @@ extern void flush_dcache_page(struct page *page); | |||
| 22 | #define flush_dcache_mmap_unlock(mapping) do { } while (0) | 29 | #define flush_dcache_mmap_unlock(mapping) do { } while (0) |
| 23 | 30 | ||
| 24 | extern void __flush_icache_range(unsigned long, unsigned long); | 31 | extern void __flush_icache_range(unsigned long, unsigned long); |
| 32 | static inline void flush_icache_range(unsigned long start, unsigned long stop) | ||
| 33 | { | ||
| 34 | if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) | ||
| 35 | __flush_icache_range(start, stop); | ||
| 36 | } | ||
| 37 | |||
| 25 | extern void flush_icache_user_range(struct vm_area_struct *vma, | 38 | extern void flush_icache_user_range(struct vm_area_struct *vma, |
| 26 | struct page *page, unsigned long addr, | 39 | struct page *page, unsigned long addr, |
| 27 | int len); | 40 | int len); |
| 41 | extern void __flush_dcache_icache(void *page_va); | ||
| 42 | extern void flush_dcache_icache_page(struct page *page); | ||
| 43 | #if defined(CONFIG_PPC32) && !defined(CONFIG_BOOKE) | ||
| 44 | extern void __flush_dcache_icache_phys(unsigned long physaddr); | ||
| 45 | #endif /* CONFIG_PPC32 && !CONFIG_BOOKE */ | ||
| 28 | 46 | ||
| 29 | extern void flush_dcache_range(unsigned long start, unsigned long stop); | 47 | extern void flush_dcache_range(unsigned long start, unsigned long stop); |
| 30 | extern void flush_dcache_phys_range(unsigned long start, unsigned long stop); | 48 | #ifdef CONFIG_PPC32 |
| 49 | extern void clean_dcache_range(unsigned long start, unsigned long stop); | ||
| 50 | extern void invalidate_dcache_range(unsigned long start, unsigned long stop); | ||
| 51 | #endif /* CONFIG_PPC32 */ | ||
| 52 | #ifdef CONFIG_PPC64 | ||
| 31 | extern void flush_inval_dcache_range(unsigned long start, unsigned long stop); | 53 | extern void flush_inval_dcache_range(unsigned long start, unsigned long stop); |
| 54 | extern void flush_dcache_phys_range(unsigned long start, unsigned long stop); | ||
| 55 | #endif | ||
| 32 | 56 | ||
| 33 | #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ | 57 | #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ |
| 34 | do { memcpy(dst, src, len); \ | 58 | do { \ |
| 35 | flush_icache_user_range(vma, page, vaddr, len); \ | 59 | memcpy(dst, src, len); \ |
| 36 | } while (0) | 60 | flush_icache_user_range(vma, page, vaddr, len); \ |
| 61 | } while (0) | ||
| 37 | #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ | 62 | #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ |
| 38 | memcpy(dst, src, len) | 63 | memcpy(dst, src, len) |
| 39 | 64 | ||
| 40 | extern void __flush_dcache_icache(void *page_va); | ||
| 41 | 65 | ||
| 42 | static inline void flush_icache_range(unsigned long start, unsigned long stop) | 66 | #endif /* __KERNEL__ */ |
| 43 | { | ||
| 44 | if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) | ||
| 45 | __flush_icache_range(start, stop); | ||
| 46 | } | ||
| 47 | 67 | ||
| 48 | #endif /* _PPC64_CACHEFLUSH_H */ | 68 | #endif /* _ASM_POWERPC_CACHEFLUSH_H */ |
diff --git a/include/asm-ppc64/compat.h b/include/asm-powerpc/compat.h index 6ec62cd2d1d1..4db4360c4d4a 100644 --- a/include/asm-ppc64/compat.h +++ b/include/asm-powerpc/compat.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #ifndef _ASM_PPC64_COMPAT_H | 1 | #ifndef _ASM_POWERPC_COMPAT_H |
| 2 | #define _ASM_PPC64_COMPAT_H | 2 | #define _ASM_POWERPC_COMPAT_H |
| 3 | /* | 3 | /* |
| 4 | * Architecture specific compatibility types | 4 | * Architecture specific compatibility types |
| 5 | */ | 5 | */ |
| @@ -49,7 +49,7 @@ struct compat_stat { | |||
| 49 | compat_dev_t st_dev; | 49 | compat_dev_t st_dev; |
| 50 | compat_ino_t st_ino; | 50 | compat_ino_t st_ino; |
| 51 | compat_mode_t st_mode; | 51 | compat_mode_t st_mode; |
| 52 | compat_nlink_t st_nlink; | 52 | compat_nlink_t st_nlink; |
| 53 | __compat_uid32_t st_uid; | 53 | __compat_uid32_t st_uid; |
| 54 | __compat_gid32_t st_gid; | 54 | __compat_gid32_t st_gid; |
| 55 | compat_dev_t st_rdev; | 55 | compat_dev_t st_rdev; |
| @@ -202,4 +202,4 @@ struct compat_shmid64_ds { | |||
| 202 | compat_ulong_t __unused6; | 202 | compat_ulong_t __unused6; |
| 203 | }; | 203 | }; |
| 204 | 204 | ||
| 205 | #endif /* _ASM_PPC64_COMPAT_H */ | 205 | #endif /* _ASM_POWERPC_COMPAT_H */ |
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h index 79a0556a0ab8..04e2726002cf 100644 --- a/include/asm-powerpc/cputable.h +++ b/include/asm-powerpc/cputable.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | #define __ASM_POWERPC_CPUTABLE_H | 2 | #define __ASM_POWERPC_CPUTABLE_H |
| 3 | 3 | ||
| 4 | #include <linux/config.h> | 4 | #include <linux/config.h> |
| 5 | #include <asm/ppc_asm.h> /* for ASM_CONST */ | 5 | #include <asm/asm-compat.h> |
| 6 | 6 | ||
| 7 | #define PPC_FEATURE_32 0x80000000 | 7 | #define PPC_FEATURE_32 0x80000000 |
| 8 | #define PPC_FEATURE_64 0x40000000 | 8 | #define PPC_FEATURE_64 0x40000000 |
| @@ -16,6 +16,10 @@ | |||
| 16 | #define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 | 16 | #define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 |
| 17 | #define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 | 17 | #define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 |
| 18 | #define PPC_FEATURE_NO_TB 0x00100000 | 18 | #define PPC_FEATURE_NO_TB 0x00100000 |
| 19 | #define PPC_FEATURE_POWER4 0x00080000 | ||
| 20 | #define PPC_FEATURE_POWER5 0x00040000 | ||
| 21 | #define PPC_FEATURE_POWER5_PLUS 0x00020000 | ||
| 22 | #define PPC_FEATURE_CELL 0x00010000 | ||
| 19 | 23 | ||
| 20 | #ifdef __KERNEL__ | 24 | #ifdef __KERNEL__ |
| 21 | #ifndef __ASSEMBLY__ | 25 | #ifndef __ASSEMBLY__ |
diff --git a/include/asm-powerpc/current.h b/include/asm-powerpc/current.h new file mode 100644 index 000000000000..82cd4a9ca99a --- /dev/null +++ b/include/asm-powerpc/current.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | #ifndef _ASM_POWERPC_CURRENT_H | ||
| 2 | #define _ASM_POWERPC_CURRENT_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License | ||
| 7 | * as published by the Free Software Foundation; either version | ||
| 8 | * 2 of the License, or (at your option) any later version. | ||
| 9 | */ | ||
| 10 | |||
| 11 | struct task_struct; | ||
| 12 | |||
| 13 | #ifdef __powerpc64__ | ||
| 14 | #include <asm/paca.h> | ||
| 15 | |||
| 16 | #define current (get_paca()->__current) | ||
| 17 | |||
| 18 | #else | ||
| 19 | |||
| 20 | /* | ||
| 21 | * We keep `current' in r2 for speed. | ||
| 22 | */ | ||
| 23 | register struct task_struct *current asm ("r2"); | ||
| 24 | |||
| 25 | #endif | ||
| 26 | |||
| 27 | #endif /* _ASM_POWERPC_CURRENT_H */ | ||
diff --git a/include/asm-powerpc/eeh_event.h b/include/asm-powerpc/eeh_event.h new file mode 100644 index 000000000000..d168a30b3866 --- /dev/null +++ b/include/asm-powerpc/eeh_event.h | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | /* | ||
| 2 | * eeh_event.h | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 17 | * | ||
| 18 | * Copyright (c) 2005 Linas Vepstas <linas@linas.org> | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef ASM_PPC64_EEH_EVENT_H | ||
| 22 | #define ASM_PPC64_EEH_EVENT_H | ||
| 23 | |||
| 24 | /** EEH event -- structure holding pci controller data that describes | ||
| 25 | * a change in the isolation status of a PCI slot. A pointer | ||
| 26 | * to this struct is passed as the data pointer in a notify callback. | ||
| 27 | */ | ||
| 28 | struct eeh_event { | ||
| 29 | struct list_head list; | ||
| 30 | struct device_node *dn; /* struct device node */ | ||
| 31 | struct pci_dev *dev; /* affected device */ | ||
| 32 | int state; | ||
| 33 | int time_unavail; /* milliseconds until device might be available */ | ||
| 34 | }; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * eeh_send_failure_event - generate a PCI error event | ||
| 38 | * @dev pci device | ||
| 39 | * | ||
| 40 | * This routine builds a PCI error event which will be delivered | ||
| 41 | * to all listeners on the peh_notifier_chain. | ||
| 42 | * | ||
| 43 | * This routine can be called within an interrupt context; | ||
| 44 | * the actual event will be delivered in a normal context | ||
| 45 | * (from a workqueue). | ||
| 46 | */ | ||
| 47 | int eeh_send_failure_event (struct device_node *dn, | ||
| 48 | struct pci_dev *dev, | ||
| 49 | int reset_state, | ||
| 50 | int time_unavail); | ||
| 51 | |||
| 52 | #endif /* ASM_PPC64_EEH_EVENT_H */ | ||
diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h index 806c142ae9ea..12fabbcb04f0 100644 --- a/include/asm-powerpc/firmware.h +++ b/include/asm-powerpc/firmware.h | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #define FW_FEATURE_ISERIES (1UL<<21) | 43 | #define FW_FEATURE_ISERIES (1UL<<21) |
| 44 | 44 | ||
| 45 | enum { | 45 | enum { |
| 46 | #ifdef CONFIG_PPC64 | ||
| 46 | FW_FEATURE_PSERIES_POSSIBLE = FW_FEATURE_PFT | FW_FEATURE_TCE | | 47 | FW_FEATURE_PSERIES_POSSIBLE = FW_FEATURE_PFT | FW_FEATURE_TCE | |
| 47 | FW_FEATURE_SPRG0 | FW_FEATURE_DABR | FW_FEATURE_COPY | | 48 | FW_FEATURE_SPRG0 | FW_FEATURE_DABR | FW_FEATURE_COPY | |
| 48 | FW_FEATURE_ASR | FW_FEATURE_DEBUG | FW_FEATURE_TERM | | 49 | FW_FEATURE_ASR | FW_FEATURE_DEBUG | FW_FEATURE_TERM | |
| @@ -70,6 +71,11 @@ enum { | |||
| 70 | FW_FEATURE_ISERIES_ALWAYS & | 71 | FW_FEATURE_ISERIES_ALWAYS & |
| 71 | #endif | 72 | #endif |
| 72 | FW_FEATURE_POSSIBLE, | 73 | FW_FEATURE_POSSIBLE, |
| 74 | |||
| 75 | #else /* CONFIG_PPC64 */ | ||
| 76 | FW_FEATURE_POSSIBLE = 0, | ||
| 77 | FW_FEATURE_ALWAYS = 0, | ||
| 78 | #endif | ||
| 73 | }; | 79 | }; |
| 74 | 80 | ||
| 75 | /* This is used to identify firmware features which are available | 81 | /* This is used to identify firmware features which are available |
diff --git a/include/asm-powerpc/futex.h b/include/asm-powerpc/futex.h index 37c94e52ab6d..f0319d50b129 100644 --- a/include/asm-powerpc/futex.h +++ b/include/asm-powerpc/futex.h | |||
| @@ -7,13 +7,14 @@ | |||
| 7 | #include <asm/errno.h> | 7 | #include <asm/errno.h> |
| 8 | #include <asm/synch.h> | 8 | #include <asm/synch.h> |
| 9 | #include <asm/uaccess.h> | 9 | #include <asm/uaccess.h> |
| 10 | #include <asm/ppc_asm.h> | 10 | #include <asm/asm-compat.h> |
| 11 | 11 | ||
| 12 | #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ | 12 | #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ |
| 13 | __asm__ __volatile ( \ | 13 | __asm__ __volatile ( \ |
| 14 | SYNC_ON_SMP \ | 14 | SYNC_ON_SMP \ |
| 15 | "1: lwarx %0,0,%2\n" \ | 15 | "1: lwarx %0,0,%2\n" \ |
| 16 | insn \ | 16 | insn \ |
| 17 | PPC405_ERR77(0, %2) \ | ||
| 17 | "2: stwcx. %1,0,%2\n" \ | 18 | "2: stwcx. %1,0,%2\n" \ |
| 18 | "bne- 1b\n" \ | 19 | "bne- 1b\n" \ |
| 19 | "li %1,0\n" \ | 20 | "li %1,0\n" \ |
| @@ -23,7 +24,7 @@ | |||
| 23 | ".previous\n" \ | 24 | ".previous\n" \ |
| 24 | ".section __ex_table,\"a\"\n" \ | 25 | ".section __ex_table,\"a\"\n" \ |
| 25 | ".align 3\n" \ | 26 | ".align 3\n" \ |
| 26 | DATAL " 1b,4b,2b,4b\n" \ | 27 | PPC_LONG "1b,4b,2b,4b\n" \ |
| 27 | ".previous" \ | 28 | ".previous" \ |
| 28 | : "=&r" (oldval), "=&r" (ret) \ | 29 | : "=&r" (oldval), "=&r" (ret) \ |
| 29 | : "b" (uaddr), "i" (-EFAULT), "1" (oparg) \ | 30 | : "b" (uaddr), "i" (-EFAULT), "1" (oparg) \ |
diff --git a/include/asm-ppc64/hvcall.h b/include/asm-powerpc/hvcall.h index ab7c3cf24888..d36da61dbc53 100644 --- a/include/asm-ppc64/hvcall.h +++ b/include/asm-powerpc/hvcall.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #ifndef _PPC64_HVCALL_H | 1 | #ifndef _ASM_POWERPC_HVCALL_H |
| 2 | #define _PPC64_HVCALL_H | 2 | #define _ASM_POWERPC_HVCALL_H |
| 3 | 3 | ||
| 4 | #define HVSC .long 0x44000022 | 4 | #define HVSC .long 0x44000022 |
| 5 | 5 | ||
| @@ -138,7 +138,7 @@ long plpar_hcall(unsigned long opcode, | |||
| 138 | */ | 138 | */ |
| 139 | long plpar_hcall_norets(unsigned long opcode, ...); | 139 | long plpar_hcall_norets(unsigned long opcode, ...); |
| 140 | 140 | ||
| 141 | /* | 141 | /* |
| 142 | * Special hcall interface for ibmveth support. | 142 | * Special hcall interface for ibmveth support. |
| 143 | * Takes 8 input parms. Returns a rc and stores the | 143 | * Takes 8 input parms. Returns a rc and stores the |
| 144 | * R4 return value in *out1. | 144 | * R4 return value in *out1. |
| @@ -153,11 +153,11 @@ long plpar_hcall_8arg_2ret(unsigned long opcode, | |||
| 153 | unsigned long arg7, | 153 | unsigned long arg7, |
| 154 | unsigned long arg8, | 154 | unsigned long arg8, |
| 155 | unsigned long *out1); | 155 | unsigned long *out1); |
| 156 | 156 | ||
| 157 | /* plpar_hcall_4out() | 157 | /* plpar_hcall_4out() |
| 158 | * | 158 | * |
| 159 | * same as plpar_hcall except with 4 output arguments. | 159 | * same as plpar_hcall except with 4 output arguments. |
| 160 | * | 160 | * |
| 161 | */ | 161 | */ |
| 162 | long plpar_hcall_4out(unsigned long opcode, | 162 | long plpar_hcall_4out(unsigned long opcode, |
| 163 | unsigned long arg1, | 163 | unsigned long arg1, |
| @@ -170,4 +170,4 @@ long plpar_hcall_4out(unsigned long opcode, | |||
| 170 | unsigned long *out4); | 170 | unsigned long *out4); |
| 171 | 171 | ||
| 172 | #endif /* __ASSEMBLY__ */ | 172 | #endif /* __ASSEMBLY__ */ |
| 173 | #endif /* _PPC64_HVCALL_H */ | 173 | #endif /* _ASM_POWERPC_HVCALL_H */ |
diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h index c37b31b96337..26b89d859c56 100644 --- a/include/asm-powerpc/hw_irq.h +++ b/include/asm-powerpc/hw_irq.h | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | #include <asm/processor.h> | 12 | #include <asm/processor.h> |
| 13 | 13 | ||
| 14 | extern void timer_interrupt(struct pt_regs *); | 14 | extern void timer_interrupt(struct pt_regs *); |
| 15 | extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); | ||
| 16 | 15 | ||
| 17 | #ifdef CONFIG_PPC_ISERIES | 16 | #ifdef CONFIG_PPC_ISERIES |
| 18 | 17 | ||
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h index b3935ea28fff..c9fbcede0ef9 100644 --- a/include/asm-powerpc/irq.h +++ b/include/asm-powerpc/irq.h | |||
| @@ -429,7 +429,6 @@ extern u64 ppc64_interrupt_controller; | |||
| 429 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) | 429 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) |
| 430 | /* pedantic: these are long because they are used with set_bit --RR */ | 430 | /* pedantic: these are long because they are used with set_bit --RR */ |
| 431 | extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; | 431 | extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; |
| 432 | extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; | ||
| 433 | extern atomic_t ppc_n_lost_interrupts; | 432 | extern atomic_t ppc_n_lost_interrupts; |
| 434 | 433 | ||
| 435 | #define virt_irq_create_mapping(x) (x) | 434 | #define virt_irq_create_mapping(x) (x) |
| @@ -488,8 +487,8 @@ extern struct thread_info *softirq_ctx[NR_CPUS]; | |||
| 488 | 487 | ||
| 489 | extern void irq_ctx_init(void); | 488 | extern void irq_ctx_init(void); |
| 490 | extern void call_do_softirq(struct thread_info *tp); | 489 | extern void call_do_softirq(struct thread_info *tp); |
| 491 | extern int call_handle_IRQ_event(int irq, struct pt_regs *regs, | 490 | extern int call___do_IRQ(int irq, struct pt_regs *regs, |
| 492 | struct irqaction *action, struct thread_info *tp); | 491 | struct thread_info *tp); |
| 493 | 492 | ||
| 494 | #define __ARCH_HAS_DO_SOFTIRQ | 493 | #define __ARCH_HAS_DO_SOFTIRQ |
| 495 | 494 | ||
diff --git a/include/asm-ppc64/lppaca.h b/include/asm-powerpc/lppaca.h index 9e2a6c0649a0..c1bedab1515b 100644 --- a/include/asm-ppc64/lppaca.h +++ b/include/asm-powerpc/lppaca.h | |||
| @@ -16,8 +16,8 @@ | |||
| 16 | * along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 18 | */ | 18 | */ |
| 19 | #ifndef _ASM_LPPACA_H | 19 | #ifndef _ASM_POWERPC_LPPACA_H |
| 20 | #define _ASM_LPPACA_H | 20 | #define _ASM_POWERPC_LPPACA_H |
| 21 | 21 | ||
| 22 | //============================================================================= | 22 | //============================================================================= |
| 23 | // | 23 | // |
| @@ -28,8 +28,7 @@ | |||
| 28 | //---------------------------------------------------------------------------- | 28 | //---------------------------------------------------------------------------- |
| 29 | #include <asm/types.h> | 29 | #include <asm/types.h> |
| 30 | 30 | ||
| 31 | struct lppaca | 31 | struct lppaca { |
| 32 | { | ||
| 33 | //============================================================================= | 32 | //============================================================================= |
| 34 | // CACHE_LINE_1 0x0000 - 0x007F Contains read-only data | 33 | // CACHE_LINE_1 0x0000 - 0x007F Contains read-only data |
| 35 | // NOTE: The xDynXyz fields are fields that will be dynamically changed by | 34 | // NOTE: The xDynXyz fields are fields that will be dynamically changed by |
| @@ -129,4 +128,4 @@ struct lppaca | |||
| 129 | u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF | 128 | u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF |
| 130 | }; | 129 | }; |
| 131 | 130 | ||
| 132 | #endif /* _ASM_LPPACA_H */ | 131 | #endif /* _ASM_POWERPC_LPPACA_H */ |
diff --git a/include/asm-ppc64/paca.h b/include/asm-powerpc/paca.h index bccacd6aa93a..92c765c35bd0 100644 --- a/include/asm-ppc64/paca.h +++ b/include/asm-powerpc/paca.h | |||
| @@ -1,11 +1,8 @@ | |||
| 1 | #ifndef _PPC64_PACA_H | ||
| 2 | #define _PPC64_PACA_H | ||
| 3 | |||
| 4 | /* | 1 | /* |
| 5 | * include/asm-ppc64/paca.h | 2 | * include/asm-powerpc/paca.h |
| 6 | * | 3 | * |
| 7 | * This control block defines the PACA which defines the processor | 4 | * This control block defines the PACA which defines the processor |
| 8 | * specific data for each logical processor on the system. | 5 | * specific data for each logical processor on the system. |
| 9 | * There are some pointers defined that are utilized by PLIC. | 6 | * There are some pointers defined that are utilized by PLIC. |
| 10 | * | 7 | * |
| 11 | * C 2001 PPC 64 Team, IBM Corp | 8 | * C 2001 PPC 64 Team, IBM Corp |
| @@ -14,7 +11,9 @@ | |||
| 14 | * modify it under the terms of the GNU General Public License | 11 | * modify it under the terms of the GNU General Public License |
| 15 | * as published by the Free Software Foundation; either version | 12 | * as published by the Free Software Foundation; either version |
| 16 | * 2 of the License, or (at your option) any later version. | 13 | * 2 of the License, or (at your option) any later version. |
| 17 | */ | 14 | */ |
| 15 | #ifndef _ASM_POWERPC_PACA_H | ||
| 16 | #define _ASM_POWERPC_PACA_H | ||
| 18 | 17 | ||
| 19 | #include <linux/config.h> | 18 | #include <linux/config.h> |
| 20 | #include <asm/types.h> | 19 | #include <asm/types.h> |
| @@ -118,4 +117,4 @@ struct paca_struct { | |||
| 118 | 117 | ||
| 119 | extern struct paca_struct paca[]; | 118 | extern struct paca_struct paca[]; |
| 120 | 119 | ||
| 121 | #endif /* _PPC64_PACA_H */ | 120 | #endif /* _ASM_POWERPC_PACA_H */ |
diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h index 13aacff755f3..9896fade98a7 100644 --- a/include/asm-powerpc/ppc-pci.h +++ b/include/asm-powerpc/ppc-pci.h | |||
| @@ -26,6 +26,10 @@ extern unsigned long find_and_init_phbs(void); | |||
| 26 | 26 | ||
| 27 | extern struct pci_dev *ppc64_isabridge_dev; /* may be NULL if no ISA bus */ | 27 | extern struct pci_dev *ppc64_isabridge_dev; /* may be NULL if no ISA bus */ |
| 28 | 28 | ||
| 29 | /** Bus Unit ID macros; get low and hi 32-bits of the 64-bit BUID */ | ||
| 30 | #define BUID_HI(buid) ((buid) >> 32) | ||
| 31 | #define BUID_LO(buid) ((buid) & 0xffffffff) | ||
| 32 | |||
| 29 | /* PCI device_node operations */ | 33 | /* PCI device_node operations */ |
| 30 | struct device_node; | 34 | struct device_node; |
| 31 | typedef void *(*traverse_func)(struct device_node *me, void *data); | 35 | typedef void *(*traverse_func)(struct device_node *me, void *data); |
| @@ -36,10 +40,6 @@ void pci_devs_phb_init(void); | |||
| 36 | void pci_devs_phb_init_dynamic(struct pci_controller *phb); | 40 | void pci_devs_phb_init_dynamic(struct pci_controller *phb); |
| 37 | void __devinit scan_phb(struct pci_controller *hose); | 41 | void __devinit scan_phb(struct pci_controller *hose); |
| 38 | 42 | ||
| 39 | /* PCI address cache management routines */ | ||
| 40 | void pci_addr_cache_insert_device(struct pci_dev *dev); | ||
| 41 | void pci_addr_cache_remove_device(struct pci_dev *dev); | ||
| 42 | |||
| 43 | /* From rtas_pci.h */ | 43 | /* From rtas_pci.h */ |
| 44 | void init_pci_config_tokens (void); | 44 | void init_pci_config_tokens (void); |
| 45 | unsigned long get_phb_buid (struct device_node *); | 45 | unsigned long get_phb_buid (struct device_node *); |
| @@ -52,4 +52,48 @@ extern unsigned long pci_probe_only; | |||
| 52 | extern unsigned long pci_assign_all_buses; | 52 | extern unsigned long pci_assign_all_buses; |
| 53 | extern int pci_read_irq_line(struct pci_dev *pci_dev); | 53 | extern int pci_read_irq_line(struct pci_dev *pci_dev); |
| 54 | 54 | ||
| 55 | /* ---- EEH internal-use-only related routines ---- */ | ||
| 56 | #ifdef CONFIG_EEH | ||
| 57 | /** | ||
| 58 | * rtas_set_slot_reset -- unfreeze a frozen slot | ||
| 59 | * | ||
| 60 | * Clear the EEH-frozen condition on a slot. This routine | ||
| 61 | * does this by asserting the PCI #RST line for 1/8th of | ||
| 62 | * a second; this routine will sleep while the adapter is | ||
| 63 | * being reset. | ||
| 64 | */ | ||
| 65 | void rtas_set_slot_reset (struct pci_dn *); | ||
| 66 | |||
| 67 | /** | ||
| 68 | * eeh_restore_bars - Restore device configuration info. | ||
| 69 | * | ||
| 70 | * A reset of a PCI device will clear out its config space. | ||
| 71 | * This routines will restore the config space for this | ||
| 72 | * device, and is children, to values previously obtained | ||
| 73 | * from the firmware. | ||
| 74 | */ | ||
| 75 | void eeh_restore_bars(struct pci_dn *); | ||
| 76 | |||
| 77 | /** | ||
| 78 | * rtas_configure_bridge -- firmware initialization of pci bridge | ||
| 79 | * | ||
| 80 | * Ask the firmware to configure all PCI bridges devices | ||
| 81 | * located behind the indicated node. Required after a | ||
| 82 | * pci device reset. Does essentially the same hing as | ||
| 83 | * eeh_restore_bars, but for brdges, and lets firmware | ||
| 84 | * do the work. | ||
| 85 | */ | ||
| 86 | void rtas_configure_bridge(struct pci_dn *); | ||
| 87 | |||
| 88 | int rtas_write_config(struct pci_dn *, int where, int size, u32 val); | ||
| 89 | |||
| 90 | /** | ||
| 91 | * mark and clear slots: find "partition endpoint" PE and set or | ||
| 92 | * clear the flags for each subnode of the PE. | ||
| 93 | */ | ||
| 94 | void eeh_mark_slot (struct device_node *dn, int mode_flag); | ||
| 95 | void eeh_clear_slot (struct device_node *dn, int mode_flag); | ||
| 96 | |||
| 97 | #endif | ||
| 98 | |||
| 55 | #endif /* _ASM_POWERPC_PPC_PCI_H */ | 99 | #endif /* _ASM_POWERPC_PPC_PCI_H */ |
diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h index c534ca41224b..c27baa0563fe 100644 --- a/include/asm-powerpc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h | |||
| @@ -6,8 +6,13 @@ | |||
| 6 | 6 | ||
| 7 | #include <linux/stringify.h> | 7 | #include <linux/stringify.h> |
| 8 | #include <linux/config.h> | 8 | #include <linux/config.h> |
| 9 | #include <asm/asm-compat.h> | ||
| 9 | 10 | ||
| 10 | #ifdef __ASSEMBLY__ | 11 | #ifndef __ASSEMBLY__ |
| 12 | #error __FILE__ should only be used in assembler files | ||
| 13 | #else | ||
| 14 | |||
| 15 | #define SZL (BITS_PER_LONG/8) | ||
| 11 | 16 | ||
| 12 | /* | 17 | /* |
| 13 | * Macros for storing registers into and loading registers from | 18 | * Macros for storing registers into and loading registers from |
| @@ -184,12 +189,6 @@ n: | |||
| 184 | oris reg,reg,(label)@h; \ | 189 | oris reg,reg,(label)@h; \ |
| 185 | ori reg,reg,(label)@l; | 190 | ori reg,reg,(label)@l; |
| 186 | 191 | ||
| 187 | /* operations for longs and pointers */ | ||
| 188 | #define LDL ld | ||
| 189 | #define STL std | ||
| 190 | #define CMPI cmpdi | ||
| 191 | #define SZL 8 | ||
| 192 | |||
| 193 | /* offsets for stack frame layout */ | 192 | /* offsets for stack frame layout */ |
| 194 | #define LRSAVE 16 | 193 | #define LRSAVE 16 |
| 195 | 194 | ||
| @@ -203,12 +202,6 @@ n: | |||
| 203 | 202 | ||
| 204 | #define OFF(name) name@l | 203 | #define OFF(name) name@l |
| 205 | 204 | ||
| 206 | /* operations for longs and pointers */ | ||
| 207 | #define LDL lwz | ||
| 208 | #define STL stw | ||
| 209 | #define CMPI cmpwi | ||
| 210 | #define SZL 4 | ||
| 211 | |||
| 212 | /* offsets for stack frame layout */ | 205 | /* offsets for stack frame layout */ |
| 213 | #define LRSAVE 4 | 206 | #define LRSAVE 4 |
| 214 | 207 | ||
| @@ -266,15 +259,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) | |||
| 266 | #endif | 259 | #endif |
| 267 | 260 | ||
| 268 | 261 | ||
| 269 | #ifdef CONFIG_IBM405_ERR77 | ||
| 270 | #define PPC405_ERR77(ra,rb) dcbt ra, rb; | ||
| 271 | #define PPC405_ERR77_SYNC sync; | ||
| 272 | #else | ||
| 273 | #define PPC405_ERR77(ra,rb) | ||
| 274 | #define PPC405_ERR77_SYNC | ||
| 275 | #endif | ||
| 276 | |||
| 277 | |||
| 278 | #ifdef CONFIG_IBM440EP_ERR42 | 262 | #ifdef CONFIG_IBM440EP_ERR42 |
| 279 | #define PPC440EP_ERR42 isync | 263 | #define PPC440EP_ERR42 isync |
| 280 | #else | 264 | #else |
| @@ -502,17 +486,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) | |||
| 502 | #define N_SLINE 68 | 486 | #define N_SLINE 68 |
| 503 | #define N_SO 100 | 487 | #define N_SO 100 |
| 504 | 488 | ||
| 505 | #define ASM_CONST(x) x | ||
| 506 | #else | ||
| 507 | #define __ASM_CONST(x) x##UL | ||
| 508 | #define ASM_CONST(x) __ASM_CONST(x) | ||
| 509 | |||
| 510 | #ifdef CONFIG_PPC64 | ||
| 511 | #define DATAL ".llong" | ||
| 512 | #else | ||
| 513 | #define DATAL ".long" | ||
| 514 | #endif | ||
| 515 | |||
| 516 | #endif /* __ASSEMBLY__ */ | 489 | #endif /* __ASSEMBLY__ */ |
| 517 | 490 | ||
| 518 | #endif /* _ASM_POWERPC_PPC_ASM_H */ | 491 | #endif /* _ASM_POWERPC_PPC_ASM_H */ |
diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h index 1dc4bf7b52b3..f6f186b56b0f 100644 --- a/include/asm-powerpc/processor.h +++ b/include/asm-powerpc/processor.h | |||
| @@ -17,65 +17,71 @@ | |||
| 17 | #include <linux/compiler.h> | 17 | #include <linux/compiler.h> |
| 18 | #include <asm/ptrace.h> | 18 | #include <asm/ptrace.h> |
| 19 | #include <asm/types.h> | 19 | #include <asm/types.h> |
| 20 | #ifdef CONFIG_PPC64 | ||
| 21 | #include <asm/systemcfg.h> | ||
| 22 | #endif | ||
| 23 | 20 | ||
| 24 | #ifdef CONFIG_PPC32 | 21 | /* We do _not_ want to define new machine types at all, those must die |
| 25 | /* 32-bit platform types */ | 22 | * in favor of using the device-tree |
| 26 | /* We only need to define a new _MACH_xxx for machines which are part of | 23 | * -- BenH. |
| 27 | * a configuration which supports more than one type of different machine. | ||
| 28 | * This is currently limited to CONFIG_PPC_MULTIPLATFORM and CHRP/PReP/PMac. | ||
| 29 | * -- Tom | ||
| 30 | */ | 24 | */ |
| 31 | #define _MACH_prep 0x00000001 | ||
| 32 | #define _MACH_Pmac 0x00000002 /* pmac or pmac clone (non-chrp) */ | ||
| 33 | #define _MACH_chrp 0x00000004 /* chrp machine */ | ||
| 34 | 25 | ||
| 35 | /* see residual.h for these */ | 26 | /* Platforms codes (to be obsoleted) */ |
| 27 | #define PLATFORM_PSERIES 0x0100 | ||
| 28 | #define PLATFORM_PSERIES_LPAR 0x0101 | ||
| 29 | #define PLATFORM_ISERIES_LPAR 0x0201 | ||
| 30 | #define PLATFORM_LPAR 0x0001 | ||
| 31 | #define PLATFORM_POWERMAC 0x0400 | ||
| 32 | #define PLATFORM_MAPLE 0x0500 | ||
| 33 | #define PLATFORM_PREP 0x0600 | ||
| 34 | #define PLATFORM_CHRP 0x0700 | ||
| 35 | #define PLATFORM_CELL 0x1000 | ||
| 36 | |||
| 37 | /* Compat platform codes for 32 bits */ | ||
| 38 | #define _MACH_prep PLATFORM_PREP | ||
| 39 | #define _MACH_Pmac PLATFORM_POWERMAC | ||
| 40 | #define _MACH_chrp PLATFORM_CHRP | ||
| 41 | |||
| 42 | /* PREP sub-platform types see residual.h for these */ | ||
| 36 | #define _PREP_Motorola 0x01 /* motorola prep */ | 43 | #define _PREP_Motorola 0x01 /* motorola prep */ |
| 37 | #define _PREP_Firm 0x02 /* firmworks prep */ | 44 | #define _PREP_Firm 0x02 /* firmworks prep */ |
| 38 | #define _PREP_IBM 0x00 /* ibm prep */ | 45 | #define _PREP_IBM 0x00 /* ibm prep */ |
| 39 | #define _PREP_Bull 0x03 /* bull prep */ | 46 | #define _PREP_Bull 0x03 /* bull prep */ |
| 40 | 47 | ||
| 41 | /* these are arbitrary */ | 48 | /* CHRP sub-platform types. These are arbitrary */ |
| 42 | #define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */ | 49 | #define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */ |
| 43 | #define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ | 50 | #define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ |
| 44 | #define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */ | 51 | #define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */ |
| 45 | 52 | ||
| 46 | #ifdef CONFIG_PPC_MULTIPLATFORM | 53 | #define platform_is_pseries() (_machine == PLATFORM_PSERIES || \ |
| 54 | _machine == PLATFORM_PSERIES_LPAR) | ||
| 55 | #define platform_is_lpar() (!!(_machine & PLATFORM_LPAR)) | ||
| 56 | |||
| 57 | #if defined(CONFIG_PPC_MULTIPLATFORM) | ||
| 47 | extern int _machine; | 58 | extern int _machine; |
| 48 | 59 | ||
| 60 | #ifdef CONFIG_PPC32 | ||
| 61 | |||
| 49 | /* what kind of prep workstation we are */ | 62 | /* what kind of prep workstation we are */ |
| 50 | extern int _prep_type; | 63 | extern int _prep_type; |
| 51 | extern int _chrp_type; | 64 | extern int _chrp_type; |
| 52 | 65 | ||
| 53 | /* | 66 | /* |
| 54 | * This is used to identify the board type from a given PReP board | 67 | * This is used to identify the board type from a given PReP board |
| 55 | * vendor. Board revision is also made available. | 68 | * vendor. Board revision is also made available. This will be moved |
| 69 | * elsewhere soon | ||
| 56 | */ | 70 | */ |
| 57 | extern unsigned char ucSystemType; | 71 | extern unsigned char ucSystemType; |
| 58 | extern unsigned char ucBoardRev; | 72 | extern unsigned char ucBoardRev; |
| 59 | extern unsigned char ucBoardRevMaj, ucBoardRevMin; | 73 | extern unsigned char ucBoardRevMaj, ucBoardRevMin; |
| 74 | |||
| 75 | #endif /* CONFIG_PPC32 */ | ||
| 76 | |||
| 77 | #elif defined(CONFIG_PPC_ISERIES) | ||
| 78 | /* | ||
| 79 | * iSeries is soon to become MULTIPLATFORM hopefully ... | ||
| 80 | */ | ||
| 81 | #define _machine PLATFORM_ISERIES_LPAR | ||
| 60 | #else | 82 | #else |
| 61 | #define _machine 0 | 83 | #define _machine 0 |
| 62 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 84 | #endif /* CONFIG_PPC_MULTIPLATFORM */ |
| 63 | #endif /* CONFIG_PPC32 */ | ||
| 64 | |||
| 65 | #ifdef CONFIG_PPC64 | ||
| 66 | /* Platforms supported by PPC64 */ | ||
| 67 | #define PLATFORM_PSERIES 0x0100 | ||
| 68 | #define PLATFORM_PSERIES_LPAR 0x0101 | ||
| 69 | #define PLATFORM_ISERIES_LPAR 0x0201 | ||
| 70 | #define PLATFORM_LPAR 0x0001 | ||
| 71 | #define PLATFORM_POWERMAC 0x0400 | ||
| 72 | #define PLATFORM_MAPLE 0x0500 | ||
| 73 | #define PLATFORM_CELL 0x1000 | ||
| 74 | |||
| 75 | /* Compatibility with drivers coming from PPC32 world */ | ||
| 76 | #define _machine (systemcfg->platform) | ||
| 77 | #define _MACH_Pmac PLATFORM_POWERMAC | ||
| 78 | #endif | ||
| 79 | 85 | ||
| 80 | /* | 86 | /* |
| 81 | * Default implementation of macro that returns current | 87 | * Default implementation of macro that returns current |
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index 489cf4c99c21..eb392d038ed7 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h | |||
| @@ -16,7 +16,11 @@ | |||
| 16 | /* Pickup Book E specific registers. */ | 16 | /* Pickup Book E specific registers. */ |
| 17 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) | 17 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) |
| 18 | #include <asm/reg_booke.h> | 18 | #include <asm/reg_booke.h> |
| 19 | #endif | 19 | #endif /* CONFIG_BOOKE || CONFIG_40x */ |
| 20 | |||
| 21 | #ifdef CONFIG_8xx | ||
| 22 | #include <asm/reg_8xx.h> | ||
| 23 | #endif /* CONFIG_8xx */ | ||
| 20 | 24 | ||
| 21 | #define MSR_SF_LG 63 /* Enable 64 bit mode */ | 25 | #define MSR_SF_LG 63 /* Enable 64 bit mode */ |
| 22 | #define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ | 26 | #define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ |
| @@ -359,6 +363,7 @@ | |||
| 359 | #define SPRN_RPA 0x3D6 /* Required Physical Address Register */ | 363 | #define SPRN_RPA 0x3D6 /* Required Physical Address Register */ |
| 360 | #define SPRN_SDA 0x3BF /* Sampled Data Address Register */ | 364 | #define SPRN_SDA 0x3BF /* Sampled Data Address Register */ |
| 361 | #define SPRN_SDR1 0x019 /* MMU Hash Base Register */ | 365 | #define SPRN_SDR1 0x019 /* MMU Hash Base Register */ |
| 366 | #define SPRN_ASR 0x118 /* Address Space Register */ | ||
| 362 | #define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ | 367 | #define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ |
| 363 | #define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ | 368 | #define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ |
| 364 | #define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ | 369 | #define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ |
diff --git a/include/asm-ppc/cache.h b/include/asm-powerpc/reg_8xx.h index 7a157d0f4b5f..e8ea346b21d3 100644 --- a/include/asm-ppc/cache.h +++ b/include/asm-powerpc/reg_8xx.h | |||
| @@ -1,49 +1,9 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * include/asm-ppc/cache.h | 2 | * Contains register definitions common to PowerPC 8xx CPUs. Notice |
| 3 | */ | 3 | */ |
| 4 | #ifdef __KERNEL__ | 4 | #ifndef _ASM_POWERPC_REG_8xx_H |
| 5 | #ifndef __ARCH_PPC_CACHE_H | 5 | #define _ASM_POWERPC_REG_8xx_H |
| 6 | #define __ARCH_PPC_CACHE_H | ||
| 7 | 6 | ||
| 8 | #include <linux/config.h> | ||
| 9 | |||
| 10 | /* bytes per L1 cache line */ | ||
| 11 | #if defined(CONFIG_8xx) || defined(CONFIG_403GCX) | ||
| 12 | #define L1_CACHE_SHIFT 4 | ||
| 13 | #define MAX_COPY_PREFETCH 1 | ||
| 14 | #elif defined(CONFIG_PPC64BRIDGE) | ||
| 15 | #define L1_CACHE_SHIFT 7 | ||
| 16 | #define MAX_COPY_PREFETCH 1 | ||
| 17 | #else | ||
| 18 | #define L1_CACHE_SHIFT 5 | ||
| 19 | #define MAX_COPY_PREFETCH 4 | ||
| 20 | #endif | ||
| 21 | |||
| 22 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) | ||
| 23 | |||
| 24 | #define SMP_CACHE_BYTES L1_CACHE_BYTES | ||
| 25 | #define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */ | ||
| 26 | |||
| 27 | #define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) | ||
| 28 | #define L1_CACHE_PAGES 8 | ||
| 29 | |||
| 30 | #ifndef __ASSEMBLY__ | ||
| 31 | extern void clean_dcache_range(unsigned long start, unsigned long stop); | ||
| 32 | extern void flush_dcache_range(unsigned long start, unsigned long stop); | ||
| 33 | extern void invalidate_dcache_range(unsigned long start, unsigned long stop); | ||
| 34 | extern void flush_dcache_all(void); | ||
| 35 | #endif /* __ASSEMBLY__ */ | ||
| 36 | |||
| 37 | /* prep registers for L2 */ | ||
| 38 | #define CACHECRBA 0x80000823 /* Cache configuration register address */ | ||
| 39 | #define L2CACHE_MASK 0x03 /* Mask for 2 L2 Cache bits */ | ||
| 40 | #define L2CACHE_512KB 0x00 /* 512KB */ | ||
| 41 | #define L2CACHE_256KB 0x01 /* 256KB */ | ||
| 42 | #define L2CACHE_1MB 0x02 /* 1MB */ | ||
| 43 | #define L2CACHE_NONE 0x03 /* NONE */ | ||
| 44 | #define L2CACHE_PARITY 0x08 /* Mask for L2 Cache Parity Protected bit */ | ||
| 45 | |||
| 46 | #ifdef CONFIG_8xx | ||
| 47 | /* Cache control on the MPC8xx is provided through some additional | 7 | /* Cache control on the MPC8xx is provided through some additional |
| 48 | * special purpose registers. | 8 | * special purpose registers. |
| 49 | */ | 9 | */ |
| @@ -78,7 +38,5 @@ extern void flush_dcache_all(void); | |||
| 78 | 38 | ||
| 79 | #define DC_DFWT 0x40000000 /* Data cache is forced write through */ | 39 | #define DC_DFWT 0x40000000 /* Data cache is forced write through */ |
| 80 | #define DC_LES 0x20000000 /* Caches are little endian mode */ | 40 | #define DC_LES 0x20000000 /* Caches are little endian mode */ |
| 81 | #endif /* CONFIG_8xx */ | ||
| 82 | 41 | ||
| 83 | #endif | 42 | #endif /* _ASM_POWERPC_REG_8xx_H */ |
| 84 | #endif /* __KERNEL__ */ | ||
diff --git a/include/asm-ppc/signal.h b/include/asm-powerpc/signal.h index caf6ede3710f..694c8d2dab87 100644 --- a/include/asm-ppc/signal.h +++ b/include/asm-powerpc/signal.h | |||
| @@ -1,18 +1,11 @@ | |||
| 1 | #ifndef _ASMPPC_SIGNAL_H | 1 | #ifndef _ASM_POWERPC_SIGNAL_H |
| 2 | #define _ASMPPC_SIGNAL_H | 2 | #define _ASM_POWERPC_SIGNAL_H |
| 3 | 3 | ||
| 4 | #ifdef __KERNEL__ | ||
| 5 | #include <linux/types.h> | 4 | #include <linux/types.h> |
| 6 | #endif /* __KERNEL__ */ | 5 | #include <linux/config.h> |
| 7 | |||
| 8 | /* Avoid too many header ordering problems. */ | ||
| 9 | struct siginfo; | ||
| 10 | |||
| 11 | /* Most things should be clean enough to redefine this at will, if care | ||
| 12 | is taken to make libc match. */ | ||
| 13 | 6 | ||
| 14 | #define _NSIG 64 | 7 | #define _NSIG 64 |
| 15 | #define _NSIG_BPW 32 | 8 | #define _NSIG_BPW BITS_PER_LONG |
| 16 | #define _NSIG_WORDS (_NSIG / _NSIG_BPW) | 9 | #define _NSIG_WORDS (_NSIG / _NSIG_BPW) |
| 17 | 10 | ||
| 18 | typedef unsigned long old_sigset_t; /* at least 32 bits */ | 11 | typedef unsigned long old_sigset_t; /* at least 32 bits */ |
| @@ -77,19 +70,19 @@ typedef struct { | |||
| 77 | * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single | 70 | * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single |
| 78 | * Unix names RESETHAND and NODEFER respectively. | 71 | * Unix names RESETHAND and NODEFER respectively. |
| 79 | */ | 72 | */ |
| 80 | #define SA_NOCLDSTOP 0x00000001 | 73 | #define SA_NOCLDSTOP 0x00000001U |
| 81 | #define SA_NOCLDWAIT 0x00000002 | 74 | #define SA_NOCLDWAIT 0x00000002U |
| 82 | #define SA_SIGINFO 0x00000004 | 75 | #define SA_SIGINFO 0x00000004U |
| 83 | #define SA_ONSTACK 0x08000000 | 76 | #define SA_ONSTACK 0x08000000U |
| 84 | #define SA_RESTART 0x10000000 | 77 | #define SA_RESTART 0x10000000U |
| 85 | #define SA_NODEFER 0x40000000 | 78 | #define SA_NODEFER 0x40000000U |
| 86 | #define SA_RESETHAND 0x80000000 | 79 | #define SA_RESETHAND 0x80000000U |
| 87 | 80 | ||
| 88 | #define SA_NOMASK SA_NODEFER | 81 | #define SA_NOMASK SA_NODEFER |
| 89 | #define SA_ONESHOT SA_RESETHAND | 82 | #define SA_ONESHOT SA_RESETHAND |
| 90 | #define SA_INTERRUPT 0x20000000 /* dummy -- ignored */ | 83 | #define SA_INTERRUPT 0x20000000u /* dummy -- ignored */ |
| 91 | 84 | ||
| 92 | #define SA_RESTORER 0x04000000 | 85 | #define SA_RESTORER 0x04000000U |
| 93 | 86 | ||
| 94 | /* | 87 | /* |
| 95 | * sigaltstack controls | 88 | * sigaltstack controls |
| @@ -127,10 +120,13 @@ typedef struct sigaltstack { | |||
| 127 | } stack_t; | 120 | } stack_t; |
| 128 | 121 | ||
| 129 | #ifdef __KERNEL__ | 122 | #ifdef __KERNEL__ |
| 130 | #include <asm/sigcontext.h> | 123 | struct pt_regs; |
| 124 | extern int do_signal(sigset_t *oldset, struct pt_regs *regs); | ||
| 125 | extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); | ||
| 131 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) | 126 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) |
| 132 | #endif /* __KERNEL__ */ | 127 | #endif /* __KERNEL__ */ |
| 133 | 128 | ||
| 129 | #ifndef __powerpc64__ | ||
| 134 | /* | 130 | /* |
| 135 | * These are parameters to dbg_sigreturn syscall. They enable or | 131 | * These are parameters to dbg_sigreturn syscall. They enable or |
| 136 | * disable certain debugging things that can be done from signal | 132 | * disable certain debugging things that can be done from signal |
| @@ -149,5 +145,6 @@ struct sig_dbg_op { | |||
| 149 | 145 | ||
| 150 | /* Enable or disable branch tracing. The value sets the state. */ | 146 | /* Enable or disable branch tracing. The value sets the state. */ |
| 151 | #define SIG_DBG_BRANCH_TRACING 2 | 147 | #define SIG_DBG_BRANCH_TRACING 2 |
| 148 | #endif /* ! __powerpc64__ */ | ||
| 152 | 149 | ||
| 153 | #endif | 150 | #endif /* _ASM_POWERPC_SIGNAL_H */ |
diff --git a/include/asm-powerpc/sparsemem.h b/include/asm-powerpc/sparsemem.h index 1c95ab99deb3..58d2aab416f8 100644 --- a/include/asm-powerpc/sparsemem.h +++ b/include/asm-powerpc/sparsemem.h | |||
| @@ -11,6 +11,10 @@ | |||
| 11 | #define MAX_PHYSADDR_BITS 38 | 11 | #define MAX_PHYSADDR_BITS 38 |
| 12 | #define MAX_PHYSMEM_BITS 36 | 12 | #define MAX_PHYSMEM_BITS 36 |
| 13 | 13 | ||
| 14 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
| 15 | extern void create_section_mapping(unsigned long start, unsigned long end); | ||
| 16 | #endif /* CONFIG_MEMORY_HOTPLUG */ | ||
| 17 | |||
| 14 | #endif /* CONFIG_SPARSEMEM */ | 18 | #endif /* CONFIG_SPARSEMEM */ |
| 15 | 19 | ||
| 16 | #endif /* _ASM_POWERPC_SPARSEMEM_H */ | 20 | #endif /* _ASM_POWERPC_SPARSEMEM_H */ |
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h index 3536a5cd7a2d..5341b75c75cb 100644 --- a/include/asm-powerpc/system.h +++ b/include/asm-powerpc/system.h | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
| 9 | 9 | ||
| 10 | #include <asm/hw_irq.h> | 10 | #include <asm/hw_irq.h> |
| 11 | #include <asm/ppc_asm.h> | ||
| 12 | #include <asm/atomic.h> | 11 | #include <asm/atomic.h> |
| 13 | 12 | ||
| 14 | /* | 13 | /* |
| @@ -180,6 +179,7 @@ extern struct task_struct *_switch(struct thread_struct *prev, | |||
| 180 | extern unsigned int rtas_data; | 179 | extern unsigned int rtas_data; |
| 181 | extern int mem_init_done; /* set on boot once kmalloc can be called */ | 180 | extern int mem_init_done; /* set on boot once kmalloc can be called */ |
| 182 | extern unsigned long memory_limit; | 181 | extern unsigned long memory_limit; |
| 182 | extern unsigned long klimit; | ||
| 183 | 183 | ||
| 184 | extern int powersave_nap; /* set if nap mode can be used in idle loop */ | 184 | extern int powersave_nap; /* set if nap mode can be used in idle loop */ |
| 185 | 185 | ||
diff --git a/include/asm-ppc64/systemcfg.h b/include/asm-powerpc/systemcfg.h index 9b86b53129aa..36b5cbe466f1 100644 --- a/include/asm-ppc64/systemcfg.h +++ b/include/asm-powerpc/systemcfg.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | #ifndef _SYSTEMCFG_H | 1 | #ifndef _SYSTEMCFG_H |
| 2 | #define _SYSTEMCFG_H | 2 | #define _SYSTEMCFG_H |
| 3 | 3 | ||
| 4 | /* | 4 | /* |
| 5 | * Copyright (C) 2002 Peter Bergner <bergner@vnet.ibm.com>, IBM | 5 | * Copyright (C) 2002 Peter Bergner <bergner@vnet.ibm.com>, IBM |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
| @@ -12,7 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | /* Change Activity: | 13 | /* Change Activity: |
| 14 | * 2002/09/30 : bergner : Created | 14 | * 2002/09/30 : bergner : Created |
| 15 | * End Change Activity | 15 | * End Change Activity |
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | /* | 18 | /* |
| @@ -56,7 +56,7 @@ struct systemcfg { | |||
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | #ifdef __KERNEL__ | 58 | #ifdef __KERNEL__ |
| 59 | extern struct systemcfg *systemcfg; | 59 | extern struct systemcfg *_systemcfg; /* to be renamed */ |
| 60 | #endif | 60 | #endif |
| 61 | 61 | ||
| 62 | #endif /* __ASSEMBLY__ */ | 62 | #endif /* __ASSEMBLY__ */ |
diff --git a/include/asm-ppc64/tce.h b/include/asm-powerpc/tce.h index d40b6b42ab35..d099d5200f9b 100644 --- a/include/asm-ppc64/tce.h +++ b/include/asm-powerpc/tce.h | |||
| @@ -18,8 +18,8 @@ | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #ifndef _ASM_TCE_H | 21 | #ifndef _ASM_POWERPC_TCE_H |
| 22 | #define _ASM_TCE_H | 22 | #define _ASM_POWERPC_TCE_H |
| 23 | 23 | ||
| 24 | /* | 24 | /* |
| 25 | * Tces come in two formats, one for the virtual bus and a different | 25 | * Tces come in two formats, one for the virtual bus and a different |
| @@ -61,4 +61,4 @@ union tce_entry { | |||
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | 63 | ||
| 64 | #endif | 64 | #endif /* _ASM_POWERPC_TCE_H */ |
diff --git a/include/asm-powerpc/uaccess.h b/include/asm-powerpc/uaccess.h index 33af730f0d19..3872e924cdd6 100644 --- a/include/asm-powerpc/uaccess.h +++ b/include/asm-powerpc/uaccess.h | |||
| @@ -120,14 +120,6 @@ struct exception_table_entry { | |||
| 120 | 120 | ||
| 121 | extern long __put_user_bad(void); | 121 | extern long __put_user_bad(void); |
| 122 | 122 | ||
| 123 | #ifdef __powerpc64__ | ||
| 124 | #define __EX_TABLE_ALIGN "3" | ||
| 125 | #define __EX_TABLE_TYPE "llong" | ||
| 126 | #else | ||
| 127 | #define __EX_TABLE_ALIGN "2" | ||
| 128 | #define __EX_TABLE_TYPE "long" | ||
| 129 | #endif | ||
| 130 | |||
| 131 | /* | 123 | /* |
| 132 | * We don't tell gcc that we are accessing memory, but this is OK | 124 | * We don't tell gcc that we are accessing memory, but this is OK |
| 133 | * because we do not write to any memory gcc knows about, so there | 125 | * because we do not write to any memory gcc knows about, so there |
| @@ -142,11 +134,12 @@ extern long __put_user_bad(void); | |||
| 142 | " b 2b\n" \ | 134 | " b 2b\n" \ |
| 143 | ".previous\n" \ | 135 | ".previous\n" \ |
| 144 | ".section __ex_table,\"a\"\n" \ | 136 | ".section __ex_table,\"a\"\n" \ |
| 145 | " .align " __EX_TABLE_ALIGN "\n" \ | 137 | " .balign %5\n" \ |
| 146 | " ."__EX_TABLE_TYPE" 1b,3b\n" \ | 138 | PPC_LONG "1b,3b\n" \ |
| 147 | ".previous" \ | 139 | ".previous" \ |
| 148 | : "=r" (err) \ | 140 | : "=r" (err) \ |
| 149 | : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err)) | 141 | : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\ |
| 142 | "i"(sizeof(unsigned long))) | ||
| 150 | 143 | ||
| 151 | #ifdef __powerpc64__ | 144 | #ifdef __powerpc64__ |
| 152 | #define __put_user_asm2(x, ptr, retval) \ | 145 | #define __put_user_asm2(x, ptr, retval) \ |
| @@ -162,12 +155,13 @@ extern long __put_user_bad(void); | |||
| 162 | " b 3b\n" \ | 155 | " b 3b\n" \ |
| 163 | ".previous\n" \ | 156 | ".previous\n" \ |
| 164 | ".section __ex_table,\"a\"\n" \ | 157 | ".section __ex_table,\"a\"\n" \ |
| 165 | " .align " __EX_TABLE_ALIGN "\n" \ | 158 | " .balign %5\n" \ |
| 166 | " ." __EX_TABLE_TYPE " 1b,4b\n" \ | 159 | PPC_LONG "1b,4b\n" \ |
| 167 | " ." __EX_TABLE_TYPE " 2b,4b\n" \ | 160 | PPC_LONG "2b,4b\n" \ |
| 168 | ".previous" \ | 161 | ".previous" \ |
| 169 | : "=r" (err) \ | 162 | : "=r" (err) \ |
| 170 | : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err)) | 163 | : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\ |
| 164 | "i"(sizeof(unsigned long))) | ||
| 171 | #endif /* __powerpc64__ */ | 165 | #endif /* __powerpc64__ */ |
| 172 | 166 | ||
| 173 | #define __put_user_size(x, ptr, size, retval) \ | 167 | #define __put_user_size(x, ptr, size, retval) \ |
| @@ -213,11 +207,12 @@ extern long __get_user_bad(void); | |||
| 213 | " b 2b\n" \ | 207 | " b 2b\n" \ |
| 214 | ".previous\n" \ | 208 | ".previous\n" \ |
| 215 | ".section __ex_table,\"a\"\n" \ | 209 | ".section __ex_table,\"a\"\n" \ |
| 216 | " .align "__EX_TABLE_ALIGN "\n" \ | 210 | " .balign %5\n" \ |
| 217 | " ." __EX_TABLE_TYPE " 1b,3b\n" \ | 211 | PPC_LONG "1b,3b\n" \ |
| 218 | ".previous" \ | 212 | ".previous" \ |
| 219 | : "=r" (err), "=r" (x) \ | 213 | : "=r" (err), "=r" (x) \ |
| 220 | : "b" (addr), "i" (-EFAULT), "0" (err)) | 214 | : "b" (addr), "i" (-EFAULT), "0" (err), \ |
| 215 | "i"(sizeof(unsigned long))) | ||
| 221 | 216 | ||
| 222 | #ifdef __powerpc64__ | 217 | #ifdef __powerpc64__ |
| 223 | #define __get_user_asm2(x, addr, err) \ | 218 | #define __get_user_asm2(x, addr, err) \ |
| @@ -235,12 +230,13 @@ extern long __get_user_bad(void); | |||
| 235 | " b 3b\n" \ | 230 | " b 3b\n" \ |
| 236 | ".previous\n" \ | 231 | ".previous\n" \ |
| 237 | ".section __ex_table,\"a\"\n" \ | 232 | ".section __ex_table,\"a\"\n" \ |
| 238 | " .align " __EX_TABLE_ALIGN "\n" \ | 233 | " .balign %5\n" \ |
| 239 | " ." __EX_TABLE_TYPE " 1b,4b\n" \ | 234 | PPC_LONG "1b,4b\n" \ |
| 240 | " ." __EX_TABLE_TYPE " 2b,4b\n" \ | 235 | PPC_LONG "2b,4b\n" \ |
| 241 | ".previous" \ | 236 | ".previous" \ |
| 242 | : "=r" (err), "=&r" (x) \ | 237 | : "=r" (err), "=&r" (x) \ |
| 243 | : "b" (addr), "i" (-EFAULT), "0" (err)) | 238 | : "b" (addr), "i" (-EFAULT), "0" (err), \ |
| 239 | "i"(sizeof(unsigned long))) | ||
| 244 | #endif /* __powerpc64__ */ | 240 | #endif /* __powerpc64__ */ |
| 245 | 241 | ||
| 246 | #define __get_user_size(x, ptr, size, retval) \ | 242 | #define __get_user_size(x, ptr, size, retval) \ |
diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h index ace2072d4a83..43f7129984c7 100644 --- a/include/asm-powerpc/xmon.h +++ b/include/asm-powerpc/xmon.h | |||
| @@ -7,7 +7,6 @@ struct pt_regs; | |||
| 7 | extern int xmon(struct pt_regs *excp); | 7 | extern int xmon(struct pt_regs *excp); |
| 8 | extern void xmon_printf(const char *fmt, ...); | 8 | extern void xmon_printf(const char *fmt, ...); |
| 9 | extern void xmon_init(int); | 9 | extern void xmon_init(int); |
| 10 | extern void xmon_map_scc(void); | ||
| 11 | 10 | ||
| 12 | #endif | 11 | #endif |
| 13 | #endif | 12 | #endif |
diff --git a/include/asm-ppc/cacheflush.h b/include/asm-ppc/cacheflush.h deleted file mode 100644 index 6a243efb3317..000000000000 --- a/include/asm-ppc/cacheflush.h +++ /dev/null | |||
| @@ -1,49 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * include/asm-ppc/cacheflush.h | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version | ||
| 7 | * 2 of the License, or (at your option) any later version. | ||
| 8 | */ | ||
| 9 | #ifdef __KERNEL__ | ||
| 10 | #ifndef _PPC_CACHEFLUSH_H | ||
| 11 | #define _PPC_CACHEFLUSH_H | ||
| 12 | |||
| 13 | #include <linux/mm.h> | ||
| 14 | |||
| 15 | /* | ||
| 16 | * No cache flushing is required when address mappings are | ||
| 17 | * changed, because the caches on PowerPCs are physically | ||
| 18 | * addressed. -- paulus | ||
| 19 | * Also, when SMP we use the coherency (M) bit of the | ||
| 20 | * BATs and PTEs. -- Cort | ||
| 21 | */ | ||
| 22 | #define flush_cache_all() do { } while (0) | ||
| 23 | #define flush_cache_mm(mm) do { } while (0) | ||
| 24 | #define flush_cache_range(vma, a, b) do { } while (0) | ||
| 25 | #define flush_cache_page(vma, p, pfn) do { } while (0) | ||
| 26 | #define flush_icache_page(vma, page) do { } while (0) | ||
| 27 | #define flush_cache_vmap(start, end) do { } while (0) | ||
| 28 | #define flush_cache_vunmap(start, end) do { } while (0) | ||
| 29 | |||
| 30 | extern void flush_dcache_page(struct page *page); | ||
| 31 | #define flush_dcache_mmap_lock(mapping) do { } while (0) | ||
| 32 | #define flush_dcache_mmap_unlock(mapping) do { } while (0) | ||
| 33 | |||
| 34 | extern void flush_icache_range(unsigned long, unsigned long); | ||
| 35 | extern void flush_icache_user_range(struct vm_area_struct *vma, | ||
| 36 | struct page *page, unsigned long addr, int len); | ||
| 37 | |||
| 38 | #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ | ||
| 39 | do { memcpy(dst, src, len); \ | ||
| 40 | flush_icache_user_range(vma, page, vaddr, len); \ | ||
| 41 | } while (0) | ||
| 42 | #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ | ||
| 43 | memcpy(dst, src, len) | ||
| 44 | |||
| 45 | extern void __flush_dcache_icache(void *page_va); | ||
| 46 | extern void __flush_dcache_icache_phys(unsigned long physaddr); | ||
| 47 | extern void flush_dcache_icache_page(struct page *page); | ||
| 48 | #endif /* _PPC_CACHEFLUSH_H */ | ||
| 49 | #endif /* __KERNEL__ */ | ||
diff --git a/include/asm-ppc/current.h b/include/asm-ppc/current.h deleted file mode 100644 index 8d41501ba10d..000000000000 --- a/include/asm-ppc/current.h +++ /dev/null | |||
| @@ -1,11 +0,0 @@ | |||
| 1 | #ifdef __KERNEL__ | ||
| 2 | #ifndef _PPC_CURRENT_H | ||
| 3 | #define _PPC_CURRENT_H | ||
| 4 | |||
| 5 | /* | ||
| 6 | * We keep `current' in r2 for speed. | ||
| 7 | */ | ||
| 8 | register struct task_struct *current asm ("r2"); | ||
| 9 | |||
| 10 | #endif /* !(_PPC_CURRENT_H) */ | ||
| 11 | #endif /* __KERNEL__ */ | ||
diff --git a/include/asm-ppc64/cache.h b/include/asm-ppc64/cache.h deleted file mode 100644 index 92140a7efbd1..000000000000 --- a/include/asm-ppc64/cache.h +++ /dev/null | |||
| @@ -1,36 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or | ||
| 3 | * modify it under the terms of the GNU General Public License | ||
| 4 | * as published by the Free Software Foundation; either version | ||
| 5 | * 2 of the License, or (at your option) any later version. | ||
| 6 | */ | ||
| 7 | #ifndef __ARCH_PPC64_CACHE_H | ||
| 8 | #define __ARCH_PPC64_CACHE_H | ||
| 9 | |||
| 10 | #include <asm/types.h> | ||
| 11 | |||
| 12 | /* bytes per L1 cache line */ | ||
| 13 | #define L1_CACHE_SHIFT 7 | ||
| 14 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) | ||
| 15 | |||
| 16 | #define SMP_CACHE_BYTES L1_CACHE_BYTES | ||
| 17 | #define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */ | ||
| 18 | |||
| 19 | #ifndef __ASSEMBLY__ | ||
| 20 | |||
| 21 | struct ppc64_caches { | ||
| 22 | u32 dsize; /* L1 d-cache size */ | ||
| 23 | u32 dline_size; /* L1 d-cache line size */ | ||
| 24 | u32 log_dline_size; | ||
| 25 | u32 dlines_per_page; | ||
| 26 | u32 isize; /* L1 i-cache size */ | ||
| 27 | u32 iline_size; /* L1 i-cache line size */ | ||
| 28 | u32 log_iline_size; | ||
| 29 | u32 ilines_per_page; | ||
| 30 | }; | ||
| 31 | |||
| 32 | extern struct ppc64_caches ppc64_caches; | ||
| 33 | |||
| 34 | #endif | ||
| 35 | |||
| 36 | #endif | ||
diff --git a/include/asm-ppc64/current.h b/include/asm-ppc64/current.h deleted file mode 100644 index 52ddc60c8b65..000000000000 --- a/include/asm-ppc64/current.h +++ /dev/null | |||
| @@ -1,16 +0,0 @@ | |||
| 1 | #ifndef _PPC64_CURRENT_H | ||
| 2 | #define _PPC64_CURRENT_H | ||
| 3 | |||
| 4 | #include <asm/paca.h> | ||
| 5 | |||
| 6 | /* | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #define get_current() (get_paca()->__current) | ||
| 14 | #define current get_current() | ||
| 15 | |||
| 16 | #endif /* !(_PPC64_CURRENT_H) */ | ||
diff --git a/include/asm-ppc64/eeh.h b/include/asm-ppc64/eeh.h index 40c8eb57493e..89f26ab31908 100644 --- a/include/asm-ppc64/eeh.h +++ b/include/asm-ppc64/eeh.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * eeh.h | 2 | * eeh.h |
| 3 | * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation. | 3 | * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation. |
| 4 | * | 4 | * |
| @@ -6,12 +6,12 @@ | |||
| 6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
| 7 | * the Free Software Foundation; either version 2 of the License, or | 7 | * the Free Software Foundation; either version 2 of the License, or |
| 8 | * (at your option) any later version. | 8 | * (at your option) any later version. |
| 9 | * | 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, | 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
| 14 | * | 14 | * |
| 15 | * You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| @@ -27,8 +27,6 @@ | |||
| 27 | 27 | ||
| 28 | struct pci_dev; | 28 | struct pci_dev; |
| 29 | struct device_node; | 29 | struct device_node; |
| 30 | struct device_node; | ||
| 31 | struct notifier_block; | ||
| 32 | 30 | ||
| 33 | #ifdef CONFIG_EEH | 31 | #ifdef CONFIG_EEH |
| 34 | 32 | ||
| @@ -37,6 +35,10 @@ struct notifier_block; | |||
| 37 | #define EEH_MODE_NOCHECK (1<<1) | 35 | #define EEH_MODE_NOCHECK (1<<1) |
| 38 | #define EEH_MODE_ISOLATED (1<<2) | 36 | #define EEH_MODE_ISOLATED (1<<2) |
| 39 | 37 | ||
| 38 | /* Max number of EEH freezes allowed before we consider the device | ||
| 39 | * to be permanently disabled. */ | ||
| 40 | #define EEH_MAX_ALLOWED_FREEZES 5 | ||
| 41 | |||
| 40 | void __init eeh_init(void); | 42 | void __init eeh_init(void); |
| 41 | unsigned long eeh_check_failure(const volatile void __iomem *token, | 43 | unsigned long eeh_check_failure(const volatile void __iomem *token, |
| 42 | unsigned long val); | 44 | unsigned long val); |
| @@ -59,36 +61,14 @@ void eeh_add_device_late(struct pci_dev *); | |||
| 59 | * eeh_remove_device - undo EEH setup for the indicated pci device | 61 | * eeh_remove_device - undo EEH setup for the indicated pci device |
| 60 | * @dev: pci device to be removed | 62 | * @dev: pci device to be removed |
| 61 | * | 63 | * |
| 62 | * This routine should be when a device is removed from a running | 64 | * This routine should be called when a device is removed from |
| 63 | * system (e.g. by hotplug or dlpar). | 65 | * a running system (e.g. by hotplug or dlpar). It unregisters |
| 66 | * the PCI device from the EEH subsystem. I/O errors affecting | ||
| 67 | * this device will no longer be detected after this call; thus, | ||
| 68 | * i/o errors affecting this slot may leave this device unusable. | ||
| 64 | */ | 69 | */ |
| 65 | void eeh_remove_device(struct pci_dev *); | 70 | void eeh_remove_device(struct pci_dev *); |
| 66 | 71 | ||
| 67 | #define EEH_DISABLE 0 | ||
| 68 | #define EEH_ENABLE 1 | ||
| 69 | #define EEH_RELEASE_LOADSTORE 2 | ||
| 70 | #define EEH_RELEASE_DMA 3 | ||
| 71 | |||
| 72 | /** | ||
| 73 | * Notifier event flags. | ||
| 74 | */ | ||
| 75 | #define EEH_NOTIFY_FREEZE 1 | ||
| 76 | |||
| 77 | /** EEH event -- structure holding pci slot data that describes | ||
| 78 | * a change in the isolation status of a PCI slot. A pointer | ||
| 79 | * to this struct is passed as the data pointer in a notify callback. | ||
| 80 | */ | ||
| 81 | struct eeh_event { | ||
| 82 | struct list_head list; | ||
| 83 | struct pci_dev *dev; | ||
| 84 | struct device_node *dn; | ||
| 85 | int reset_state; | ||
| 86 | }; | ||
| 87 | |||
| 88 | /** Register to find out about EEH events. */ | ||
| 89 | int eeh_register_notifier(struct notifier_block *nb); | ||
| 90 | int eeh_unregister_notifier(struct notifier_block *nb); | ||
| 91 | |||
| 92 | /** | 72 | /** |
| 93 | * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. | 73 | * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. |
| 94 | * | 74 | * |
| @@ -129,7 +109,7 @@ static inline void eeh_remove_device(struct pci_dev *dev) { } | |||
| 129 | #define EEH_IO_ERROR_VALUE(size) (-1UL) | 109 | #define EEH_IO_ERROR_VALUE(size) (-1UL) |
| 130 | #endif /* CONFIG_EEH */ | 110 | #endif /* CONFIG_EEH */ |
| 131 | 111 | ||
| 132 | /* | 112 | /* |
| 133 | * MMIO read/write operations with EEH support. | 113 | * MMIO read/write operations with EEH support. |
| 134 | */ | 114 | */ |
| 135 | static inline u8 eeh_readb(const volatile void __iomem *addr) | 115 | static inline u8 eeh_readb(const volatile void __iomem *addr) |
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h index 4c18a5cb69f5..1a7e0afa2dc6 100644 --- a/include/asm-ppc64/mmu.h +++ b/include/asm-ppc64/mmu.h | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #define _PPC64_MMU_H_ | 14 | #define _PPC64_MMU_H_ |
| 15 | 15 | ||
| 16 | #include <linux/config.h> | 16 | #include <linux/config.h> |
| 17 | #include <asm/ppc_asm.h> /* for ASM_CONST */ | 17 | #include <asm/asm-compat.h> |
| 18 | #include <asm/page.h> | 18 | #include <asm/page.h> |
| 19 | 19 | ||
| 20 | /* | 20 | /* |
| @@ -224,9 +224,12 @@ extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | |||
| 224 | unsigned long pstart, unsigned long mode, | 224 | unsigned long pstart, unsigned long mode, |
| 225 | int psize); | 225 | int psize); |
| 226 | 226 | ||
| 227 | extern void htab_initialize(void); | ||
| 228 | extern void htab_initialize_secondary(void); | ||
| 227 | extern void hpte_init_native(void); | 229 | extern void hpte_init_native(void); |
| 228 | extern void hpte_init_lpar(void); | 230 | extern void hpte_init_lpar(void); |
| 229 | extern void hpte_init_iSeries(void); | 231 | extern void hpte_init_iSeries(void); |
| 232 | extern void mm_init_ppc64(void); | ||
| 230 | 233 | ||
| 231 | extern long pSeries_lpar_hpte_insert(unsigned long hpte_group, | 234 | extern long pSeries_lpar_hpte_insert(unsigned long hpte_group, |
| 232 | unsigned long va, unsigned long prpn, | 235 | unsigned long va, unsigned long prpn, |
| @@ -245,6 +248,7 @@ extern long iSeries_hpte_insert(unsigned long hpte_group, | |||
| 245 | 248 | ||
| 246 | extern void stabs_alloc(void); | 249 | extern void stabs_alloc(void); |
| 247 | extern void slb_initialize(void); | 250 | extern void slb_initialize(void); |
| 251 | extern void stab_initialize(unsigned long stab); | ||
| 248 | 252 | ||
| 249 | #endif /* __ASSEMBLY__ */ | 253 | #endif /* __ASSEMBLY__ */ |
| 250 | 254 | ||
diff --git a/include/asm-ppc64/mmzone.h b/include/asm-ppc64/mmzone.h index 80a708e7093a..15e777ce0f4a 100644 --- a/include/asm-ppc64/mmzone.h +++ b/include/asm-ppc64/mmzone.h | |||
| @@ -33,6 +33,9 @@ extern int numa_cpu_lookup_table[]; | |||
| 33 | extern char *numa_memory_lookup_table; | 33 | extern char *numa_memory_lookup_table; |
| 34 | extern cpumask_t numa_cpumask_lookup_table[]; | 34 | extern cpumask_t numa_cpumask_lookup_table[]; |
| 35 | extern int nr_cpus_in_node[]; | 35 | extern int nr_cpus_in_node[]; |
| 36 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
| 37 | extern unsigned long max_pfn; | ||
| 38 | #endif | ||
| 36 | 39 | ||
| 37 | /* 16MB regions */ | 40 | /* 16MB regions */ |
| 38 | #define MEMORY_INCREMENT_SHIFT 24 | 41 | #define MEMORY_INCREMENT_SHIFT 24 |
| @@ -45,6 +48,11 @@ static inline int pa_to_nid(unsigned long pa) | |||
| 45 | { | 48 | { |
| 46 | int nid; | 49 | int nid; |
| 47 | 50 | ||
| 51 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
| 52 | /* kludge hot added sections default to node 0 */ | ||
| 53 | if (pa >= (max_pfn << PAGE_SHIFT)) | ||
| 54 | return 0; | ||
| 55 | #endif | ||
| 48 | nid = numa_memory_lookup_table[pa >> MEMORY_INCREMENT_SHIFT]; | 56 | nid = numa_memory_lookup_table[pa >> MEMORY_INCREMENT_SHIFT]; |
| 49 | 57 | ||
| 50 | #ifdef DEBUG_NUMA | 58 | #ifdef DEBUG_NUMA |
diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h index 82ce187e5be8..e32f1187aa29 100644 --- a/include/asm-ppc64/page.h +++ b/include/asm-ppc64/page.h | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
| 14 | #include <asm/ppc_asm.h> /* for ASM_CONST */ | 14 | #include <asm/asm-compat.h> |
| 15 | 15 | ||
| 16 | /* | 16 | /* |
| 17 | * We support either 4k or 64k software page size. When using 64k pages | 17 | * We support either 4k or 64k software page size. When using 64k pages |
diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h index 60cf8c838af0..efbdaece0cf0 100644 --- a/include/asm-ppc64/pci-bridge.h +++ b/include/asm-ppc64/pci-bridge.h | |||
| @@ -63,7 +63,6 @@ struct pci_dn { | |||
| 63 | int devfn; /* for pci devices */ | 63 | int devfn; /* for pci devices */ |
| 64 | int eeh_mode; /* See eeh.h for possible EEH_MODEs */ | 64 | int eeh_mode; /* See eeh.h for possible EEH_MODEs */ |
| 65 | int eeh_config_addr; | 65 | int eeh_config_addr; |
| 66 | int eeh_capable; /* from firmware */ | ||
| 67 | int eeh_check_count; /* # times driver ignored error */ | 66 | int eeh_check_count; /* # times driver ignored error */ |
| 68 | int eeh_freeze_count; /* # times this device froze up. */ | 67 | int eeh_freeze_count; /* # times this device froze up. */ |
| 69 | int eeh_is_bridge; /* device is pci-to-pci bridge */ | 68 | int eeh_is_bridge; /* device is pci-to-pci bridge */ |
diff --git a/include/asm-ppc64/pgalloc.h b/include/asm-ppc64/pgalloc.h index 98da0e4262bd..dcf3622d1946 100644 --- a/include/asm-ppc64/pgalloc.h +++ b/include/asm-ppc64/pgalloc.h | |||
| @@ -10,8 +10,8 @@ extern kmem_cache_t *pgtable_cache[]; | |||
| 10 | 10 | ||
| 11 | #ifdef CONFIG_PPC_64K_PAGES | 11 | #ifdef CONFIG_PPC_64K_PAGES |
| 12 | #define PTE_CACHE_NUM 0 | 12 | #define PTE_CACHE_NUM 0 |
| 13 | #define PMD_CACHE_NUM 0 | 13 | #define PMD_CACHE_NUM 1 |
| 14 | #define PGD_CACHE_NUM 1 | 14 | #define PGD_CACHE_NUM 2 |
| 15 | #else | 15 | #else |
| 16 | #define PTE_CACHE_NUM 0 | 16 | #define PTE_CACHE_NUM 0 |
| 17 | #define PMD_CACHE_NUM 1 | 17 | #define PMD_CACHE_NUM 1 |
diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h index 76bb0266d67c..ddfe186589fa 100644 --- a/include/asm-ppc64/prom.h +++ b/include/asm-ppc64/prom.h | |||
| @@ -204,6 +204,8 @@ extern void of_detach_node(const struct device_node *); | |||
| 204 | extern unsigned long prom_init(unsigned long, unsigned long, unsigned long, | 204 | extern unsigned long prom_init(unsigned long, unsigned long, unsigned long, |
| 205 | unsigned long, unsigned long); | 205 | unsigned long, unsigned long); |
| 206 | extern void finish_device_tree(void); | 206 | extern void finish_device_tree(void); |
| 207 | extern void unflatten_device_tree(void); | ||
| 208 | extern void early_init_devtree(void *); | ||
| 207 | extern int device_is_compatible(struct device_node *device, const char *); | 209 | extern int device_is_compatible(struct device_node *device, const char *); |
| 208 | extern int machine_is_compatible(const char *compat); | 210 | extern int machine_is_compatible(const char *compat); |
| 209 | extern unsigned char *get_property(struct device_node *node, const char *name, | 211 | extern unsigned char *get_property(struct device_node *node, const char *name, |
diff --git a/include/asm-ppc64/signal.h b/include/asm-ppc64/signal.h deleted file mode 100644 index 432df7dd355d..000000000000 --- a/include/asm-ppc64/signal.h +++ /dev/null | |||
| @@ -1,132 +0,0 @@ | |||
| 1 | #ifndef _ASMPPC64_SIGNAL_H | ||
| 2 | #define _ASMPPC64_SIGNAL_H | ||
| 3 | |||
| 4 | #include <linux/types.h> | ||
| 5 | #include <linux/compiler.h> | ||
| 6 | #include <asm/siginfo.h> | ||
| 7 | |||
| 8 | /* Avoid too many header ordering problems. */ | ||
| 9 | struct siginfo; | ||
| 10 | |||
| 11 | #define _NSIG 64 | ||
| 12 | #define _NSIG_BPW 64 | ||
| 13 | #define _NSIG_WORDS (_NSIG / _NSIG_BPW) | ||
| 14 | |||
| 15 | typedef unsigned long old_sigset_t; /* at least 32 bits */ | ||
| 16 | |||
| 17 | typedef struct { | ||
| 18 | unsigned long sig[_NSIG_WORDS]; | ||
| 19 | } sigset_t; | ||
| 20 | |||
| 21 | #define SIGHUP 1 | ||
| 22 | #define SIGINT 2 | ||
| 23 | #define SIGQUIT 3 | ||
| 24 | #define SIGILL 4 | ||
| 25 | #define SIGTRAP 5 | ||
| 26 | #define SIGABRT 6 | ||
| 27 | #define SIGIOT 6 | ||
| 28 | #define SIGBUS 7 | ||
| 29 | #define SIGFPE 8 | ||
| 30 | #define SIGKILL 9 | ||
| 31 | #define SIGUSR1 10 | ||
| 32 | #define SIGSEGV 11 | ||
| 33 | #define SIGUSR2 12 | ||
| 34 | #define SIGPIPE 13 | ||
| 35 | #define SIGALRM 14 | ||
| 36 | #define SIGTERM 15 | ||
| 37 | #define SIGSTKFLT 16 | ||
| 38 | #define SIGCHLD 17 | ||
| 39 | #define SIGCONT 18 | ||
| 40 | #define SIGSTOP 19 | ||
| 41 | #define SIGTSTP 20 | ||
| 42 | #define SIGTTIN 21 | ||
| 43 | #define SIGTTOU 22 | ||
| 44 | #define SIGURG 23 | ||
| 45 | #define SIGXCPU 24 | ||
| 46 | #define SIGXFSZ 25 | ||
| 47 | #define SIGVTALRM 26 | ||
| 48 | #define SIGPROF 27 | ||
| 49 | #define SIGWINCH 28 | ||
| 50 | #define SIGIO 29 | ||
| 51 | #define SIGPOLL SIGIO | ||
| 52 | /* | ||
| 53 | #define SIGLOST 29 | ||
| 54 | */ | ||
| 55 | #define SIGPWR 30 | ||
| 56 | #define SIGSYS 31 | ||
| 57 | #define SIGUNUSED 31 | ||
| 58 | |||
| 59 | /* These should not be considered constants from userland. */ | ||
| 60 | #define SIGRTMIN 32 | ||
| 61 | #define SIGRTMAX _NSIG | ||
| 62 | |||
| 63 | /* | ||
| 64 | * SA_FLAGS values: | ||
| 65 | * | ||
| 66 | * SA_ONSTACK is not currently supported, but will allow sigaltstack(2). | ||
| 67 | * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the | ||
| 68 | * SA_RESTART flag to get restarting signals (which were the default long ago) | ||
| 69 | * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. | ||
| 70 | * SA_RESETHAND clears the handler when the signal is delivered. | ||
| 71 | * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. | ||
| 72 | * SA_NODEFER prevents the current signal from being masked in the handler. | ||
| 73 | * | ||
| 74 | * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single | ||
| 75 | * Unix names RESETHAND and NODEFER respectively. | ||
| 76 | */ | ||
| 77 | #define SA_NOCLDSTOP 0x00000001u | ||
| 78 | #define SA_NOCLDWAIT 0x00000002u | ||
| 79 | #define SA_SIGINFO 0x00000004u | ||
| 80 | #define SA_ONSTACK 0x08000000u | ||
| 81 | #define SA_RESTART 0x10000000u | ||
| 82 | #define SA_NODEFER 0x40000000u | ||
| 83 | #define SA_RESETHAND 0x80000000u | ||
| 84 | |||
| 85 | #define SA_NOMASK SA_NODEFER | ||
| 86 | #define SA_ONESHOT SA_RESETHAND | ||
| 87 | #define SA_INTERRUPT 0x20000000u /* dummy -- ignored */ | ||
| 88 | |||
| 89 | #define SA_RESTORER 0x04000000u | ||
| 90 | |||
| 91 | /* | ||
| 92 | * sigaltstack controls | ||
| 93 | */ | ||
| 94 | #define SS_ONSTACK 1 | ||
| 95 | #define SS_DISABLE 2 | ||
| 96 | |||
| 97 | #define MINSIGSTKSZ 2048 | ||
| 98 | #define SIGSTKSZ 8192 | ||
| 99 | |||
| 100 | #include <asm-generic/signal.h> | ||
| 101 | |||
| 102 | struct old_sigaction { | ||
| 103 | __sighandler_t sa_handler; | ||
| 104 | old_sigset_t sa_mask; | ||
| 105 | unsigned long sa_flags; | ||
| 106 | __sigrestore_t sa_restorer; | ||
| 107 | }; | ||
| 108 | |||
| 109 | struct sigaction { | ||
| 110 | __sighandler_t sa_handler; | ||
| 111 | unsigned long sa_flags; | ||
| 112 | __sigrestore_t sa_restorer; | ||
| 113 | sigset_t sa_mask; /* mask last for extensibility */ | ||
| 114 | }; | ||
| 115 | |||
| 116 | struct k_sigaction { | ||
| 117 | struct sigaction sa; | ||
| 118 | }; | ||
| 119 | |||
| 120 | typedef struct sigaltstack { | ||
| 121 | void __user *ss_sp; | ||
| 122 | int ss_flags; | ||
| 123 | size_t ss_size; | ||
| 124 | } stack_t; | ||
| 125 | |||
| 126 | struct pt_regs; | ||
| 127 | struct timespec; | ||
| 128 | extern int do_signal(sigset_t *oldset, struct pt_regs *regs); | ||
| 129 | extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); | ||
| 130 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) | ||
| 131 | |||
| 132 | #endif /* _ASMPPC64_SIGNAL_H */ | ||
diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h index 0cdd66c9f4b7..bf9a6aba19c9 100644 --- a/include/asm-ppc64/system.h +++ b/include/asm-ppc64/system.h | |||
| @@ -149,6 +149,8 @@ struct thread_struct; | |||
| 149 | extern struct task_struct * _switch(struct thread_struct *prev, | 149 | extern struct task_struct * _switch(struct thread_struct *prev, |
| 150 | struct thread_struct *next); | 150 | struct thread_struct *next); |
| 151 | 151 | ||
| 152 | extern unsigned long klimit; | ||
| 153 | |||
| 152 | extern int powersave_nap; /* set if nap mode can be used in idle loop */ | 154 | extern int powersave_nap; /* set if nap mode can be used in idle loop */ |
| 153 | 155 | ||
| 154 | /* | 156 | /* |
