Commit 3ae0af12 authored by Linus Torvalds's avatar Linus Torvalds
parents 3b44f137 7c43ee40
...@@ -599,6 +599,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID ...@@ -599,6 +599,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
def_bool y def_bool y
depends on NEED_MULTIPLE_NODES depends on NEED_MULTIPLE_NODES
config ARCH_MEMORY_PROBE
def_bool y
depends on MEMORY_HOTPLUG
# Some NUMA nodes have memory ranges that span # Some NUMA nodes have memory ranges that span
# other nodes. Even though a pfn is valid and # other nodes. Even though a pfn is valid and
# between a node's start and end pfns, it may not # between a node's start and end pfns, it may not
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
ifeq ($(CONFIG_PPC64),y) ifeq ($(CONFIG_PPC64),y)
EXTRA_CFLAGS += -mno-minimal-toc EXTRA_CFLAGS += -mno-minimal-toc
CFLAGS_ioctl32.o += -Ifs/
endif endif
ifeq ($(CONFIG_PPC32),y) ifeq ($(CONFIG_PPC32),y)
CFLAGS_prom_init.o += -fPIC CFLAGS_prom_init.o += -fPIC
...@@ -11,15 +12,21 @@ CFLAGS_btext.o += -fPIC ...@@ -11,15 +12,21 @@ CFLAGS_btext.o += -fPIC
endif endif
obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
signal_32.o pmc.o irq.o signal_32.o pmc.o
obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
signal_64.o ptrace32.o systbl.o signal_64.o ptrace32.o systbl.o \
paca.o ioctl32.o cpu_setup_power4.o \
firmware.o sysfs.o
obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
obj-$(CONFIG_POWER4) += idle_power4.o obj-$(CONFIG_POWER4) += idle_power4.o
obj-$(CONFIG_PPC_OF) += of_device.o obj-$(CONFIG_PPC_OF) += of_device.o
obj-$(CONFIG_PPC_RTAS) += rtas.o procfs-$(CONFIG_PPC64) := proc_ppc64.o
obj-$(CONFIG_PROC_FS) += $(procfs-y)
rtaspci-$(CONFIG_PPC64) := rtas_pci.o
obj-$(CONFIG_PPC_RTAS) += rtas.o $(rtaspci-y)
obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
obj-$(CONFIG_RTAS_PROC) += rtas-proc.o obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
obj-$(CONFIG_LPARCFG) += lparcfg.o
obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_IBMVIO) += vio.o
obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
......
...@@ -106,7 +106,6 @@ int main(void) ...@@ -106,7 +106,6 @@ int main(void)
DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
DEFINE(PLATFORM_LPAR, PLATFORM_LPAR); DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
/* paca */ /* paca */
......
...@@ -52,6 +52,9 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); ...@@ -52,6 +52,9 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
#define COMMON_USER (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \ #define COMMON_USER (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \
PPC_FEATURE_HAS_MMU) PPC_FEATURE_HAS_MMU)
#define COMMON_USER_PPC64 (COMMON_USER | PPC_FEATURE_64) #define COMMON_USER_PPC64 (COMMON_USER | PPC_FEATURE_64)
#define COMMON_USER_POWER4 (COMMON_USER_PPC64 | PPC_FEATURE_POWER4)
#define COMMON_USER_POWER5 (COMMON_USER_PPC64 | PPC_FEATURE_POWER5)
#define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS)
/* We only set the spe features if the kernel was compiled with /* We only set the spe features if the kernel was compiled with
...@@ -160,7 +163,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -160,7 +163,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_value = 0x00350000, .pvr_value = 0x00350000,
.cpu_name = "POWER4 (gp)", .cpu_name = "POWER4 (gp)",
.cpu_features = CPU_FTRS_POWER4, .cpu_features = CPU_FTRS_POWER4,
.cpu_user_features = COMMON_USER_PPC64, .cpu_user_features = COMMON_USER_POWER4,
.icache_bsize = 128, .icache_bsize = 128,
.dcache_bsize = 128, .dcache_bsize = 128,
.num_pmcs = 8, .num_pmcs = 8,
...@@ -175,7 +178,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -175,7 +178,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_value = 0x00380000, .pvr_value = 0x00380000,
.cpu_name = "POWER4+ (gq)", .cpu_name = "POWER4+ (gq)",
.cpu_features = CPU_FTRS_POWER4, .cpu_features = CPU_FTRS_POWER4,
.cpu_user_features = COMMON_USER_PPC64, .cpu_user_features = COMMON_USER_POWER4,
.icache_bsize = 128, .icache_bsize = 128,
.dcache_bsize = 128, .dcache_bsize = 128,
.num_pmcs = 8, .num_pmcs = 8,
...@@ -190,7 +193,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -190,7 +193,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_value = 0x00390000, .pvr_value = 0x00390000,
.cpu_name = "PPC970", .cpu_name = "PPC970",
.cpu_features = CPU_FTRS_PPC970, .cpu_features = CPU_FTRS_PPC970,
.cpu_user_features = COMMON_USER_PPC64 | .cpu_user_features = COMMON_USER_POWER4 |
PPC_FEATURE_HAS_ALTIVEC_COMP, PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 128, .icache_bsize = 128,
.dcache_bsize = 128, .dcache_bsize = 128,
...@@ -212,7 +215,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -212,7 +215,7 @@ struct cpu_spec cpu_specs[] = {
#else #else
.cpu_features = CPU_FTRS_PPC970, .cpu_features = CPU_FTRS_PPC970,
#endif #endif
.cpu_user_features = COMMON_USER_PPC64 | .cpu_user_features = COMMON_USER_POWER4 |
PPC_FEATURE_HAS_ALTIVEC_COMP, PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 128, .icache_bsize = 128,
.dcache_bsize = 128, .dcache_bsize = 128,
...@@ -230,7 +233,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -230,7 +233,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_value = 0x00440000, .pvr_value = 0x00440000,
.cpu_name = "PPC970MP", .cpu_name = "PPC970MP",
.cpu_features = CPU_FTRS_PPC970, .cpu_features = CPU_FTRS_PPC970,
.cpu_user_features = COMMON_USER_PPC64 | .cpu_user_features = COMMON_USER_POWER4 |
PPC_FEATURE_HAS_ALTIVEC_COMP, PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 128, .icache_bsize = 128,
.dcache_bsize = 128, .dcache_bsize = 128,
...@@ -245,7 +248,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -245,7 +248,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_value = 0x003a0000, .pvr_value = 0x003a0000,
.cpu_name = "POWER5 (gr)", .cpu_name = "POWER5 (gr)",
.cpu_features = CPU_FTRS_POWER5, .cpu_features = CPU_FTRS_POWER5,
.cpu_user_features = COMMON_USER_PPC64, .cpu_user_features = COMMON_USER_POWER5,
.icache_bsize = 128, .icache_bsize = 128,
.dcache_bsize = 128, .dcache_bsize = 128,
.num_pmcs = 6, .num_pmcs = 6,
...@@ -260,7 +263,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -260,7 +263,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_value = 0x003b0000, .pvr_value = 0x003b0000,
.cpu_name = "POWER5 (gs)", .cpu_name = "POWER5 (gs)",
.cpu_features = CPU_FTRS_POWER5, .cpu_features = CPU_FTRS_POWER5,
.cpu_user_features = COMMON_USER_PPC64, .cpu_user_features = COMMON_USER_POWER5_PLUS,
.icache_bsize = 128, .icache_bsize = 128,
.dcache_bsize = 128, .dcache_bsize = 128,
.num_pmcs = 6, .num_pmcs = 6,
...@@ -276,7 +279,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -276,7 +279,7 @@ struct cpu_spec cpu_specs[] = {
.cpu_name = "Cell Broadband Engine", .cpu_name = "Cell Broadband Engine",
.cpu_features = CPU_FTRS_CELL, .cpu_features = CPU_FTRS_CELL,
.cpu_user_features = COMMON_USER_PPC64 | .cpu_user_features = COMMON_USER_PPC64 |
PPC_FEATURE_HAS_ALTIVEC_COMP, PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 128, .icache_bsize = 128,
.dcache_bsize = 128, .dcache_bsize = 128,
.cpu_setup = __setup_cpu_be, .cpu_setup = __setup_cpu_be,
......
/* /*
* arch/ppc64/kernel/firmware.c
*
* Extracted from cputable.c * Extracted from cputable.c
* *
* Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
......
...@@ -41,20 +41,20 @@ _GLOBAL(load_up_fpu) ...@@ -41,20 +41,20 @@ _GLOBAL(load_up_fpu)
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
LOADBASE(r3, last_task_used_math) LOADBASE(r3, last_task_used_math)
toreal(r3) toreal(r3)
LDL r4,OFF(last_task_used_math)(r3) PPC_LL r4,OFF(last_task_used_math)(r3)
CMPI 0,r4,0 PPC_LCMPI 0,r4,0
beq 1f beq 1f
toreal(r4) toreal(r4)
addi r4,r4,THREAD /* want last_task_used_math->thread */ addi r4,r4,THREAD /* want last_task_used_math->thread */
SAVE_32FPRS(0, r4) SAVE_32FPRS(0, r4)
mffs fr0 mffs fr0
stfd fr0,THREAD_FPSCR(r4) stfd fr0,THREAD_FPSCR(r4)
LDL r5,PT_REGS(r4) PPC_LL r5,PT_REGS(r4)
toreal(r5) toreal(r5)
LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
li r10,MSR_FP|MSR_FE0|MSR_FE1 li r10,MSR_FP|MSR_FE0|MSR_FE1
andc r4,r4,r10 /* disable FP for previous task */ andc r4,r4,r10 /* disable FP for previous task */
STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1: 1:
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
/* enable use of FP after return */ /* enable use of FP after return */
...@@ -77,7 +77,7 @@ _GLOBAL(load_up_fpu) ...@@ -77,7 +77,7 @@ _GLOBAL(load_up_fpu)
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
subi r4,r5,THREAD subi r4,r5,THREAD
fromreal(r4) fromreal(r4)
STL r4,OFF(last_task_used_math)(r3) PPC_STL r4,OFF(last_task_used_math)(r3)
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
/* restore registers and return */ /* restore registers and return */
/* we haven't used ctr or xer or lr */ /* we haven't used ctr or xer or lr */
...@@ -97,24 +97,24 @@ _GLOBAL(giveup_fpu) ...@@ -97,24 +97,24 @@ _GLOBAL(giveup_fpu)
MTMSRD(r5) /* enable use of fpu now */ MTMSRD(r5) /* enable use of fpu now */
SYNC_601 SYNC_601
isync isync
CMPI 0,r3,0 PPC_LCMPI 0,r3,0
beqlr- /* if no previous owner, done */ beqlr- /* if no previous owner, done */
addi r3,r3,THREAD /* want THREAD of task */ addi r3,r3,THREAD /* want THREAD of task */
LDL r5,PT_REGS(r3) PPC_LL r5,PT_REGS(r3)
CMPI 0,r5,0 PPC_LCMPI 0,r5,0
SAVE_32FPRS(0, r3) SAVE_32FPRS(0, r3)
mffs fr0 mffs fr0
stfd fr0,THREAD_FPSCR(r3) stfd fr0,THREAD_FPSCR(r3)
beq 1f beq 1f
LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
li r3,MSR_FP|MSR_FE0|MSR_FE1 li r3,MSR_FP|MSR_FE0|MSR_FE1
andc r4,r4,r3 /* disable FP for previous task */ andc r4,r4,r3 /* disable FP for previous task */
STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1: 1:
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
li r5,0 li r5,0
LOADBASE(r4,last_task_used_math) LOADBASE(r4,last_task_used_math)
STL r5,OFF(last_task_used_math)(r4) PPC_STL r5,OFF(last_task_used_math)(r4)
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
blr blr
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include <asm/reg.h> #include <asm/reg.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/mmu.h> #include <asm/mmu.h>
#include <asm/systemcfg.h>
#include <asm/ppc_asm.h> #include <asm/ppc_asm.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#include <asm/bug.h> #include <asm/bug.h>
...@@ -1697,25 +1696,14 @@ _GLOBAL(pmac_secondary_start) ...@@ -1697,25 +1696,14 @@ _GLOBAL(pmac_secondary_start)
* SPRG3 = paca virtual address * SPRG3 = paca virtual address
*/ */
_GLOBAL(__secondary_start) _GLOBAL(__secondary_start)
/* Set thread priority to MEDIUM */
HMT_MEDIUM
HMT_MEDIUM /* Set thread priority to MEDIUM */ /* Load TOC */
ld r2,PACATOC(r13) ld r2,PACATOC(r13)
li r6,0
stb r6,PACAPROCENABLED(r13) /* Do early setup for that CPU (stab, slb, hash table pointer) */
bl .early_setup_secondary
#ifndef CONFIG_PPC_ISERIES
/* Initialize the page table pointer register. */
LOADADDR(r6,_SDR1)
ld r6,0(r6) /* get the value of _SDR1 */
mtspr SPRN_SDR1,r6 /* set the htab location */
#endif
/* Initialize the first segment table (or SLB) entry */
ld r3,PACASTABVIRT(r13) /* get addr of segment table */
BEGIN_FTR_SECTION
bl .stab_initialize
END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
bl .slb_initialize
/* Initialize the kernel stack. Just a repeat for iSeries. */ /* Initialize the kernel stack. Just a repeat for iSeries. */
LOADADDR(r3,current_set) LOADADDR(r3,current_set)
...@@ -1724,37 +1712,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) ...@@ -1724,37 +1712,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
std r1,PACAKSAVE(r13) std r1,PACAKSAVE(r13)
ld r3,PACASTABREAL(r13) /* get raddr of segment table */ /* Clear backchain so we get nice backtraces */
ori r4,r3,1 /* turn on valid bit */
#ifdef CONFIG_PPC_ISERIES
li r0,-1 /* hypervisor call */
li r3,1
sldi r3,r3,63 /* 0x8000000000000000 */
ori r3,r3,4 /* 0x8000000000000004 */
sc /* HvCall_setASR */
#else
/* set the ASR */
ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
ld r3,0(r3)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
beq 98f /* branch if result is 0 */
mfspr r3,SPRN_PVR
srwi r3,r3,16
cmpwi r3,0x37 /* SStar */
beq 97f
cmpwi r3,0x36 /* IStar */
beq 97f
cmpwi r3,0x34 /* Pulsar */
bne 98f
97: li r3,H_SET_ASR /* hcall = H_SET_ASR */
HVSC /* Invoking hcall */
b 99f
98: /* !(rpa hypervisor) || !(star) */
mtasr r4 /* set the stab location */
99:
#endif
li r7,0 li r7,0
mtlr r7 mtlr r7
...@@ -1777,6 +1735,7 @@ _GLOBAL(start_secondary_prolog) ...@@ -1777,6 +1735,7 @@ _GLOBAL(start_secondary_prolog)
li r3,0 li r3,0
std r3,0(r1) /* Zero the stack frame pointer */ std r3,0(r1) /* Zero the stack frame pointer */
bl .start_secondary bl .start_secondary
b .
#endif #endif
/* /*
...@@ -1896,40 +1855,6 @@ _STATIC(start_here_multiplatform) ...@@ -1896,40 +1855,6 @@ _STATIC(start_here_multiplatform)
mr r3,r31 mr r3,r31
bl .early_setup bl .early_setup
/* set the ASR */
ld r3,PACASTABREAL(r13)
ori r4,r3,1 /* turn on valid bit */
ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
ld r3,0(r3)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
beq 98f /* branch if result is 0 */
mfspr r3,SPRN_PVR
srwi r3,r3,16
cmpwi r3,0x37 /* SStar */
beq 97f
cmpwi r3,0x36 /* IStar */
beq 97f
cmpwi r3,0x34 /* Pulsar */
bne 98f
97: li r3,H_SET_ASR /* hcall = H_SET_ASR */
HVSC /* Invoking hcall */
b 99f
98: /* !(rpa hypervisor) || !(star) */
mtasr r4 /* set the stab location */
99:
/* Set SDR1 (hash table pointer) */
ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
ld r3,0(r3)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
/* Test if bit 0 is set (LPAR bit) */
andi. r3,r3,PLATFORM_LPAR
bne 98f /* branch if result is !0 */
LOADADDR(r6,_SDR1) /* Only if NOT LPAR */
add r6,r6,r26
ld r6,0(r6) /* get the value of _SDR1 */
mtspr SPRN_SDR1,r6 /* set the htab location */
98:
LOADADDR(r3,.start_here_common) LOADADDR(r3,.start_here_common)
SET_REG_TO_CONST(r4, MSR_KERNEL) SET_REG_TO_CONST(r4, MSR_KERNEL)
mtspr SPRN_SRR0,r3 mtspr SPRN_SRR0,r3
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <asm/time.h> #include <asm/time.h>
#include <asm/iseries/it_exp_vpd_panel.h> #include <asm/iseries/it_exp_vpd_panel.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/systemcfg.h>
#define MODULE_VERS "1.6" #define MODULE_VERS "1.6"
#define MODULE_NAME "lparcfg" #define MODULE_NAME "lparcfg"
...@@ -371,7 +372,7 @@ static int lparcfg_data(struct seq_file *m, void *v) ...@@ -371,7 +372,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", NULL); lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", NULL);
if (lrdrp == NULL) { if (lrdrp == NULL) {
partition_potential_processors = systemcfg->processorCount; partition_potential_processors = _systemcfg->processorCount;
} else { } else {
partition_potential_processors = *(lrdrp + 4); partition_potential_processors = *(lrdrp + 4);
} }
......
...@@ -519,7 +519,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) ...@@ -519,7 +519,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
* *
* flush_icache_range(unsigned long start, unsigned long stop) * flush_icache_range(unsigned long start, unsigned long stop)
*/ */
_GLOBAL(flush_icache_range) _GLOBAL(__flush_icache_range)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
blr /* for 601, do nothing */ blr /* for 601, do nothing */
END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
...@@ -607,27 +607,6 @@ _GLOBAL(invalidate_dcache_range) ...@@ -607,27 +607,6 @@ _GLOBAL(invalidate_dcache_range)
sync /* wait for dcbi's to get to ram */ sync /* wait for dcbi's to get to ram */
blr blr
#ifdef CONFIG_NOT_COHERENT_CACHE
/*
* 40x cores have 8K or 16K dcache and 32 byte line size.
* 44x has a 32K dcache and 32 byte line size.
* 8xx has 1, 2, 4, 8K variants.
* For now, cover the worst case of the 44x.
* Must be called with external interrupts disabled.
*/
#define CACHE_NWAYS 64
#define CACHE_NLINES 16
_GLOBAL(flush_dcache_all)
li r4, (2 * CACHE_NWAYS * CACHE_NLINES)
mtctr r4
lis r5, KERNELBASE@h
1: lwz r3, 0(r5) /* Load one word from every line */
addi r5, r5, L1_CACHE_BYTES
bdnz 1b
blr
#endif /* CONFIG_NOT_COHERENT_CACHE */
/* /*
* Flush a particular page from the data cache to RAM. * Flush a particular page from the data cache to RAM.
* Note: this is necessary because the instruction cache does *not* * Note: this is necessary because the instruction cache does *not*
......
...@@ -89,12 +89,12 @@ _GLOBAL(call_do_softirq) ...@@ -89,12 +89,12 @@ _GLOBAL(call_do_softirq)
mtlr r0 mtlr r0
blr blr
_GLOBAL(call_handle_IRQ_event) _GLOBAL(call___do_IRQ)
mflr r0 mflr r0
std r0,16(r1) std r0,16(r1)
stdu r1,THREAD_SIZE-112(r6) stdu r1,THREAD_SIZE-112(r5)
mr r1,r6 mr r1,r5
bl .handle_IRQ_event bl .__do_IRQ
ld r1,0(r1) ld r1,0(r1)
ld r0,16(r1) ld r0,16(r1)
mtlr r0 mtlr r0
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/systemcfg.h>
#include <asm/lppaca.h> #include <asm/lppaca.h>
#include <asm/iseries/it_lp_queue.h> #include <asm/iseries/it_lp_queue.h>
#include <asm/paca.h> #include <asm/paca.h>
...@@ -24,8 +24,7 @@ static union { ...@@ -24,8 +24,7 @@ static union {
struct systemcfg data; struct systemcfg data;
u8 page[PAGE_SIZE]; u8 page[PAGE_SIZE];
} systemcfg_store __attribute__((__section__(".data.page.aligned"))); } systemcfg_store __attribute__((__section__(".data.page.aligned")));
struct systemcfg *systemcfg = &systemcfg_store.data; struct systemcfg *_systemcfg = &systemcfg_store.data;
EXPORT_SYMBOL(systemcfg);
/* This symbol is provided by the linker - let it fill in the paca /* This symbol is provided by the linker - let it fill in the paca
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <asm/cputable.h> #include <asm/cputable.h>
#include <asm/btext.h> #include <asm/btext.h>
#include <asm/div64.h> #include <asm/div64.h>
#include <asm/signal.h>
#ifdef CONFIG_8xx #ifdef CONFIG_8xx
#include <asm/commproc.h> #include <asm/commproc.h>
...@@ -56,7 +57,6 @@ extern void machine_check_exception(struct pt_regs *regs); ...@@ -56,7 +57,6 @@ extern void machine_check_exception(struct pt_regs *regs);
extern void alignment_exception(struct pt_regs *regs); extern void alignment_exception(struct pt_regs *regs);
extern void program_check_exception(struct pt_regs *regs); extern void program_check_exception(struct pt_regs *regs);
extern void single_step_exception(struct pt_regs *regs); extern void single_step_exception(struct pt_regs *regs);
extern int do_signal(sigset_t *, struct pt_regs *);
extern int pmac_newworld; extern int pmac_newworld;
extern int sys_sigreturn(struct pt_regs *regs); extern int sys_sigreturn(struct pt_regs *regs);
...@@ -188,9 +188,6 @@ EXPORT_SYMBOL(adb_try_handler_change); ...@@ -188,9 +188,6 @@ EXPORT_SYMBOL(adb_try_handler_change);
EXPORT_SYMBOL(cuda_request); EXPORT_SYMBOL(cuda_request);
EXPORT_SYMBOL(cuda_poll); EXPORT_SYMBOL(cuda_poll);
#endif /* CONFIG_ADB_CUDA */ #endif /* CONFIG_ADB_CUDA */
#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_PPC32)
EXPORT_SYMBOL(_machine);
#endif
#ifdef CONFIG_PPC_PMAC #ifdef CONFIG_PPC_PMAC
EXPORT_SYMBOL(sys_ctrler); EXPORT_SYMBOL(sys_ctrler);
#endif #endif
......
/* /*
* arch/ppc64/kernel/proc_ppc64.c
*
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -53,7 +51,7 @@ static int __init proc_ppc64_create(void) ...@@ -53,7 +51,7 @@ static int __init proc_ppc64_create(void)
if (!root) if (!root)
return 1; return 1;
if (!(systemcfg->platform & (PLATFORM_PSERIES | PLATFORM_CELL))) if (!(platform_is_pseries() || _machine == PLATFORM_CELL))
return 0; return 0;
if (!proc_mkdir("rtas", root)) if (!proc_mkdir("rtas", root))
...@@ -74,7 +72,7 @@ static int __init proc_ppc64_init(void) ...@@ -74,7 +72,7 @@ static int __init proc_ppc64_init(void)
if (!pde) if (!pde)
return 1; return 1;
pde->nlink = 1; pde->nlink = 1;
pde->data = systemcfg; pde->data = _systemcfg;
pde->size = PAGE_SIZE; pde->size = PAGE_SIZE;
pde->proc_fops = &page_map_fops; pde->proc_fops = &page_map_fops;
......
...@@ -48,9 +48,6 @@ ...@@ -48,9 +48,6 @@
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/pSeries_reconfig.h> #include <asm/pSeries_reconfig.h>
#include <asm/pci-bridge.h> #include <asm/pci-bridge.h>
#ifdef CONFIG_PPC64
#include <asm/systemcfg.h>
#endif
#ifdef DEBUG #ifdef DEBUG
#define DBG(fmt...) printk(KERN_ERR fmt) #define DBG(fmt...) printk(KERN_ERR fmt)
...@@ -74,10 +71,6 @@ struct isa_reg_property { ...@@ -74,10 +71,6 @@ struct isa_reg_property {
typedef int interpret_func(struct device_node *, unsigned long *, typedef int interpret_func(struct device_node *, unsigned long *,
int, int, int); int, int, int);
extern struct rtas_t rtas;
extern struct lmb lmb;
extern unsigned long klimit;
static int __initdata dt_root_addr_cells; static int __initdata dt_root_addr_cells;
static int __initdata dt_root_size_cells; static int __initdata dt_root_size_cells;
...@@ -391,7 +384,7 @@ static int __devinit finish_node_interrupts(struct device_node *np, ...@@ -391,7 +384,7 @@ static int __devinit finish_node_interrupts(struct device_node *np,
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
/* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) { if (_machine == PLATFORM_POWERMAC && ic && ic->parent) {
char *name = get_property(ic->parent, "name", NULL); char *name = get_property(ic->parent, "name", NULL);
if (name && !strcmp(name, "u3")) if (name && !strcmp(name, "u3"))
np->intrs[intrcount].line += 128; np->intrs[intrcount].line += 128;
...@@ -1087,9 +1080,9 @@ void __init unflatten_device_tree(void) ...@@ -1087,9 +1080,9 @@ void __init unflatten_device_tree(void)
static int __init early_init_dt_scan_cpus(unsigned long node, static int __init early_init_dt_scan_cpus(unsigned long node,
const char *uname, int depth, void *data) const char *uname, int depth, void *data)
{ {
char *type = of_get_flat_dt_prop(node, "device_type", NULL);
u32 *prop; u32 *prop;
unsigned long size = 0; unsigned long size;
char *type = of_get_flat_dt_prop(node, "device_type", &size);
/* We are scanning "cpu" nodes only */ /* We are scanning "cpu" nodes only */
if (type == NULL || strcmp(type, "cpu") != 0) if (type == NULL || strcmp(type, "cpu") != 0)
...@@ -1115,7 +1108,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, ...@@ -1115,7 +1108,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
#ifdef CONFIG_ALTIVEC #ifdef CONFIG_ALTIVEC
/* Check if we have a VMX and eventually update CPU features */ /* Check if we have a VMX and eventually update CPU features */
prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", &size); prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", NULL);
if (prop && (*prop) > 0) { if (prop && (*prop) > 0) {
cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; 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,13 +1154,9 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL); prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
if (prop == NULL) if (prop == NULL)
return 0; return 0;
#ifdef CONFIG_PPC64
systemcfg->platform = *prop;
#else
#ifdef CONFIG_PPC_MULTIPLATFORM #ifdef CONFIG_PPC_MULTIPLATFORM
_machine = *prop; _machine = *prop;
#endif #endif
#endif
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
/* check if iommu is forced on or off */ /* check if iommu is forced on or off */
...@@ -1264,7 +1253,14 @@ static int __init early_init_dt_scan_memory(unsigned long node, ...@@ -1264,7 +1253,14 @@ static int __init early_init_dt_scan_memory(unsigned long node,
unsigned long l; unsigned long l;
/* We are scanning "memory" nodes only */ /* We are scanning "memory" nodes only */
if (type == NULL || strcmp(type, "memory") != 0) if (type == NULL) {
/*
* The longtrail doesn't have a device_type on the
* /memory node, so look for the node called /memory@0.
*/
if (depth != 1 || strcmp(uname, "memory@0") != 0)
return 0;
} else if (strcmp(type, "memory") != 0)
return 0; return 0;
reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l); reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
...@@ -1339,9 +1335,6 @@ void __init early_init_devtree(void *params) ...@@ -1339,9 +1335,6 @@ void __init early_init_devtree(void *params)
of_scan_flat_dt(early_init_dt_scan_memory, NULL); of_scan_flat_dt(early_init_dt_scan_memory, NULL);
lmb_enforce_memory_limit(memory_limit); lmb_enforce_memory_limit(memory_limit);
lmb_analyze(); lmb_analyze();
#ifdef CONFIG_PPC64
systemcfg->physicalMemorySize = lmb_phys_mem_size();
#endif
lmb_reserve(0, __pa(klimit)); lmb_reserve(0, __pa(klimit));
DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
...@@ -1908,7 +1901,7 @@ static int of_finish_dynamic_node(struct device_node *node, ...@@ -1908,7 +1901,7 @@ static int of_finish_dynamic_node(struct device_node *node,
/* We don't support that function on PowerMac, at least /* We don't support that function on PowerMac, at least
* not yet * not yet
*/ */
if (systemcfg->platform == PLATFORM_POWERMAC) if (_machine == PLATFORM_POWERMAC)
return -ENODEV; return -ENODEV;
/* fix up new node's linux_phandle field */ /* fix up new node's linux_phandle field */
...@@ -1992,9 +1985,11 @@ int prom_add_property(struct device_node* np, struct property* prop) ...@@ -1992,9 +1985,11 @@ int prom_add_property(struct device_node* np, struct property* prop)
*next = prop; *next = prop;
write_unlock(&devtree_lock); write_unlock(&devtree_lock);
#ifdef CONFIG_PROC_DEVICETREE
/* try to add to proc as well if it was initialized */ /* try to add to proc as well if it was initialized */
if (np->pde) if (np->pde)
proc_device_tree_add_prop(np->pde, prop); proc_device_tree_add_prop(np->pde, prop);
#endif /* CONFIG_PROC_DEVICETREE */
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -259,7 +259,7 @@ static int __init proc_rtas_init(void) ...@@ -259,7 +259,7 @@ static int __init proc_rtas_init(void)
{ {
struct proc_dir_entry *entry; struct proc_dir_entry *entry;
if (!(systemcfg->platform & PLATFORM_PSERIES)) if (_machine != PLATFORM_PSERIES && _machine != PLATFORM_PSERIES_LPAR)
return 1; return 1;
rtas_node = of_find_node_by_name(NULL, "rtas"); rtas_node = of_find_node_by_name(NULL, "rtas");
......
...@@ -29,9 +29,6 @@ ...@@ -29,9 +29,6 @@
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/lmb.h> #include <asm/lmb.h>
#ifdef CONFIG_PPC64
#include <asm/systemcfg.h>
#endif
struct rtas_t rtas = { struct rtas_t rtas = {
.lock = SPIN_LOCK_UNLOCKED .lock = SPIN_LOCK_UNLOCKED
...@@ -671,7 +668,7 @@ void __init rtas_initialize(void) ...@@ -671,7 +668,7 @@ void __init rtas_initialize(void)
* the stop-self token if any * the stop-self token if any
*/ */
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
if (systemcfg->platform == PLATFORM_PSERIES_LPAR) if (_machine == PLATFORM_PSERIES_LPAR)
rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
#endif #endif
rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region); rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region);
......
...@@ -47,7 +47,7 @@ static int write_pci_config; ...@@ -47,7 +47,7 @@ static int write_pci_config;
static int ibm_read_pci_config; static int ibm_read_pci_config;
static int ibm_write_pci_config; static int ibm_write_pci_config;
static int config_access_valid(struct pci_dn *dn, int where) static inline int config_access_valid(struct pci_dn *dn, int where)
{ {
if (where < 256) if (where < 256)
return 1; return 1;
...@@ -72,16 +72,14 @@ static int of_device_available(struct device_node * dn) ...@@ -72,16 +72,14 @@ static int of_device_available(struct device_node * dn)
return 0; return 0;
} }
static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val) static int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
{ {
int returnval = -1; int returnval = -1;
unsigned long buid, addr; unsigned long buid, addr;
int ret; int ret;
struct pci_dn *pdn;
if (!dn || !dn->data) if (!pdn)
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
pdn = dn->data;
if (!config_access_valid(pdn, where)) if (!config_access_valid(pdn, where))
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
...@@ -90,7 +88,7 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va ...@@ -90,7 +88,7 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va
buid = pdn->phb->buid; buid = pdn->phb->buid;
if (buid) { if (buid) {
ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
addr, buid >> 32, buid & 0xffffffff, size); addr, BUID_HI(buid), BUID_LO(buid), size);
} else { } else {
ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size); ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
} }
...@@ -100,7 +98,7 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va ...@@ -100,7 +98,7 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
if (returnval == EEH_IO_ERROR_VALUE(size) && if (returnval == EEH_IO_ERROR_VALUE(size) &&
eeh_dn_check_failure (dn, NULL)) eeh_dn_check_failure (pdn->node, NULL))
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
...@@ -118,23 +116,23 @@ static int rtas_pci_read_config(struct pci_bus *bus, ...@@ -118,23 +116,23 @@ static int rtas_pci_read_config(struct pci_bus *bus,
busdn = bus->sysdata; /* must be a phb */ busdn = bus->sysdata; /* must be a phb */
/* Search only direct children of the bus */ /* Search only direct children of the bus */
for (dn = busdn->child; dn; dn = dn->sibling) for (dn = busdn->child; dn; dn = dn->sibling) {
if (dn->data && PCI_DN(dn)->devfn == devfn struct pci_dn *pdn = PCI_DN(dn);
if (pdn && pdn->devfn == devfn
&& of_device_available(dn)) && of_device_available(dn))
return rtas_read_config(dn, where, size, val); return rtas_read_config(pdn, where, size, val);
}
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
} }
int rtas_write_config(struct device_node *dn, int where, int size, u32 val) int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
{ {
unsigned long buid, addr; unsigned long buid, addr;
int ret; int ret;
struct pci_dn *pdn;
if (!dn || !dn->data) if (!pdn)
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
pdn = dn->data;
if (!config_access_valid(pdn, where)) if (!config_access_valid(pdn, where))
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
...@@ -142,7 +140,8 @@ int rtas_write_config(struct device_node *dn, int where, int size, u32 val) ...@@ -142,7 +140,8 @@ int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
(pdn->devfn << 8) | (where & 0xff); (pdn->devfn << 8) | (where & 0xff);
buid = pdn->phb->buid; buid = pdn->phb->buid;
if (buid) { if (buid) {
ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val); ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
BUID_HI(buid), BUID_LO(buid), size, (ulong) val);
} else { } else {
ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val); ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
} }
...@@ -165,10 +164,12 @@ static int rtas_pci_write_config(struct pci_bus *bus, ...@@ -165,10 +164,12 @@ static int rtas_pci_write_config(struct pci_bus *bus,
busdn = bus->sysdata; /* must be a phb */ busdn = bus->sysdata; /* must be a phb */
/* Search only direct children of the bus */ /* Search only direct children of the bus */
for (dn = busdn->child; dn; dn = dn->sibling) for (dn = busdn->child; dn; dn = dn->sibling) {
if (dn->data && PCI_DN(dn)->devfn == devfn struct pci_dn *pdn = PCI_DN(dn);
if (pdn && pdn->devfn == devfn
&& of_device_available(dn)) && of_device_available(dn))
return rtas_write_config(dn, where, size, val); return rtas_write_config(pdn, where, size, val);
}
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/systemcfg.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/elf.h> #include <asm/elf.h>
...@@ -51,6 +52,9 @@ ...@@ -51,6 +52,9 @@
#include <asm/page.h> #include <asm/page.h>
#include <asm/mmu.h> #include <asm/mmu.h>
#include <asm/lmb.h> #include <asm/lmb.h>
#include <asm/xmon.h>
#include "setup.h"
#undef DEBUG #undef DEBUG
...@@ -60,6 +64,13 @@ ...@@ -60,6 +64,13 @@
#define DBG(fmt...) #define DBG(fmt...)
#endif #endif
#ifdef CONFIG_PPC_MULTIPLATFORM
int _machine = 0;
EXPORT_SYMBOL(_machine);
#endif
unsigned long klimit = (unsigned long) _end;
/* /*
* This still seems to be needed... -- paulus * This still seems to be needed... -- paulus
*/ */
...@@ -510,7 +521,7 @@ void __init smp_setup_cpu_maps(void) ...@@ -510,7 +521,7 @@ void __init smp_setup_cpu_maps(void)
* On pSeries LPAR, we need to know how many cpus * On pSeries LPAR, we need to know how many cpus
* could possibly be added to this partition. * could possibly be added to this partition.
*/ */
if (systemcfg->platform == PLATFORM_PSERIES_LPAR && if (_machine == PLATFORM_PSERIES_LPAR &&
(dn = of_find_node_by_path("/rtas"))) { (dn = of_find_node_by_path("/rtas"))) {
int num_addr_cell, num_size_cell, maxcpus; int num_addr_cell, num_size_cell, maxcpus;
unsigned int *ireg; unsigned int *ireg;
...@@ -555,7 +566,27 @@ void __init smp_setup_cpu_maps(void) ...@@ -555,7 +566,27 @@ void __init smp_setup_cpu_maps(void)
cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
} }
systemcfg->processorCount = num_present_cpus(); _systemcfg->processorCount = num_present_cpus();
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
} }
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
#ifdef CONFIG_XMON
static int __init early_xmon(char *p)
{
/* ensure xmon is enabled */
if (p) {
if (strncmp(p, "on", 2) == 0)
xmon_init(1);
if (strncmp(p, "off", 3) == 0)
xmon_init(0);
if (strncmp(p, "early", 5) != 0)
return 0;
}
xmon_init(1);
debugger(NULL);
return 0;
}
early_param("xmon", early_xmon);
#endif
#ifndef _POWERPC_KERNEL_SETUP_H
#define _POWERPC_KERNEL_SETUP_H
void check_for_initrd(void);
#endif /* _POWERPC_KERNEL_SETUP_H */
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#include <asm/xmon.h> #include <asm/xmon.h>
#include <asm/time.h> #include <asm/time.h>
#include "setup.h"
#define DBG(fmt...) #define DBG(fmt...)
#if defined CONFIG_KGDB #if defined CONFIG_KGDB
...@@ -70,8 +72,6 @@ unsigned int DMA_MODE_WRITE; ...@@ -70,8 +72,6 @@ unsigned int DMA_MODE_WRITE;
int have_of = 1; int have_of = 1;
#ifdef CONFIG_PPC_MULTIPLATFORM #ifdef CONFIG_PPC_MULTIPLATFORM
int _machine = 0;
extern void prep_init(void); extern void prep_init(void);
extern void pmac_init(void); extern void pmac_init(void);
extern void chrp_init(void); extern void chrp_init(void);
...@@ -279,7 +279,6 @@ arch_initcall(ppc_init); ...@@ -279,7 +279,6 @@ arch_initcall(ppc_init);
/* Warning, IO base is not yet inited */ /* Warning, IO base is not yet inited */
void __init setup_arch(char **cmdline_p) void __init setup_arch(char **cmdline_p)
{ {
extern char *klimit;
extern void do_init_bootmem(void); extern void do_init_bootmem(void);
/* so udelay does something sensible, assume <= 1000 bogomips */ /* so udelay does something sensible, assume <= 1000 bogomips */
...@@ -303,14 +302,9 @@ void __init setup_arch(char **cmdline_p) ...@@ -303,14 +302,9 @@ void __init setup_arch(char **cmdline_p)
pmac_feature_init(); /* New cool way */ pmac_feature_init(); /* New cool way */
#endif #endif
#ifdef CONFIG_XMON #ifdef CONFIG_XMON_DEFAULT
xmon_map_scc();
if (strstr(cmd_line, "xmon")) {
xmon_init(1); xmon_init(1);
debugger(NULL); #endif
}
#endif /* CONFIG_XMON */
if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab);
#if defined(CONFIG_KGDB) #if defined(CONFIG_KGDB)
if (ppc_md.kgdb_map_scc) if (ppc_md.kgdb_map_scc)
...@@ -343,7 +337,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -343,7 +337,7 @@ void __init setup_arch(char **cmdline_p)
init_mm.start_code = PAGE_OFFSET; init_mm.start_code = PAGE_OFFSET;
init_mm.end_code = (unsigned long) _etext; init_mm.end_code = (unsigned long) _etext;
init_mm.end_data = (unsigned long) _edata; init_mm.end_data = (unsigned long) _edata;
init_mm.brk = (unsigned long) klimit; init_mm.brk = klimit;
/* Save unparsed command line copy for /proc/cmdline */ /* Save unparsed command line copy for /proc/cmdline */
strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
......
...@@ -61,6 +61,8 @@ ...@@ -61,6 +61,8 @@
#include <asm/xmon.h> #include <asm/xmon.h>
#include <asm/udbg.h> #include <asm/udbg.h>
#include "setup.h"
#ifdef DEBUG #ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt) #define DBG(fmt...) udbg_printf(fmt)
#else #else
...@@ -94,15 +96,6 @@ extern void udbg_init_maple_realmode(void); ...@@ -94,15 +96,6 @@ extern void udbg_init_maple_realmode(void);
do { udbg_putc = call_rtas_display_status_delay; } while(0) do { udbg_putc = call_rtas_display_status_delay; } while(0)
#endif #endif
/* extern void *stab; */
extern unsigned long klimit;
extern void mm_init_ppc64(void);
extern void stab_initialize(unsigned long stab);
extern void htab_initialize(void);
extern void early_init_devtree(void *flat_dt);
extern void unflatten_device_tree(void);
int have_of = 1; int have_of = 1;
int boot_cpuid = 0; int boot_cpuid = 0;
int boot_cpuid_phys = 0; int boot_cpuid_phys = 0;
...@@ -254,11 +247,10 @@ void __init early_setup(unsigned long dt_ptr) ...@@ -254,11 +247,10 @@ void __init early_setup(unsigned long dt_ptr)
* Iterate all ppc_md structures until we find the proper * Iterate all ppc_md structures until we find the proper
* one for the current machine type * one for the current machine type
*/ */
DBG("Probing machine type for platform %x...\n", DBG("Probing machine type for platform %x...\n", _machine);
systemcfg->platform);
for (mach = machines; *mach; mach++) { for (mach = machines; *mach; mach++) {
if ((*mach)->probe(systemcfg->platform)) if ((*mach)->probe(_machine))
break; break;
} }
/* What can we do if we didn't find ? */ /* What can we do if we didn't find ? */
...@@ -290,6 +282,28 @@ void __init early_setup(unsigned long dt_ptr) ...@@ -290,6 +282,28 @@ void __init early_setup(unsigned long dt_ptr)
DBG(" <- early_setup()\n"); DBG(" <- early_setup()\n");
} }
#ifdef CONFIG_SMP
void early_setup_secondary(void)
{
struct paca_struct *lpaca = get_paca();
/* Mark enabled in PACA */
lpaca->proc_enabled = 0;
/* Initialize hash table for that CPU */
htab_initialize_secondary();
/* Initialize STAB/SLB. We use a virtual address as it works
* in real mode on pSeries and we want a virutal address on
* iSeries anyway
*/
if (cpu_has_feature(CPU_FTR_SLB))
slb_initialize();
else
stab_initialize(lpaca->stab_addr);
}
#endif /* CONFIG_SMP */
#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
void smp_release_cpus(void) void smp_release_cpus(void)
...@@ -315,7 +329,8 @@ void smp_release_cpus(void) ...@@ -315,7 +329,8 @@ void smp_release_cpus(void)
#endif /* CONFIG_SMP || CONFIG_KEXEC */ #endif /* CONFIG_SMP || CONFIG_KEXEC */
/* /*
* Initialize some remaining members of the ppc64_caches and systemcfg structures * Initialize some remaining members of the ppc64_caches and systemcfg
* structures
* (at least until we get rid of them completely). This is mostly some * (at least until we get rid of them completely). This is mostly some
* cache informations about the CPU that will be used by cache flush * cache informations about the CPU that will be used by cache flush
* routines and/or provided to userland * routines and/or provided to userland
...@@ -340,7 +355,7 @@ static void __init initialize_cache_info(void) ...@@ -340,7 +355,7 @@ static void __init initialize_cache_info(void)
const char *dc, *ic; const char *dc, *ic;
/* Then read cache informations */ /* Then read cache informations */
if (systemcfg->platform == PLATFORM_POWERMAC) { if (_machine == PLATFORM_POWERMAC) {
dc = "d-cache-block-size"; dc = "d-cache-block-size";
ic = "i-cache-block-size"; ic = "i-cache-block-size";
} else { } else {
...@@ -360,8 +375,8 @@ static void __init initialize_cache_info(void) ...@@ -360,8 +375,8 @@ static void __init initialize_cache_info(void)
DBG("Argh, can't find dcache properties ! " DBG("Argh, can't find dcache properties ! "
"sizep: %p, lsizep: %p\n", sizep, lsizep); "sizep: %p, lsizep: %p\n", sizep, lsizep);
systemcfg->dcache_size = ppc64_caches.dsize = size; _systemcfg->dcache_size = ppc64_caches.dsize = size;
systemcfg->dcache_line_size = _systemcfg->dcache_line_size =
ppc64_caches.dline_size = lsize; ppc64_caches.dline_size = lsize;
ppc64_caches.log_dline_size = __ilog2(lsize); ppc64_caches.log_dline_size = __ilog2(lsize);
ppc64_caches.dlines_per_page = PAGE_SIZE / lsize; ppc64_caches.dlines_per_page = PAGE_SIZE / lsize;
...@@ -378,8 +393,8 @@ static void __init initialize_cache_info(void) ...@@ -378,8 +393,8 @@ static void __init initialize_cache_info(void)
DBG("Argh, can't find icache properties ! " DBG("Argh, can't find icache properties ! "
"sizep: %p, lsizep: %p\n", sizep, lsizep); "sizep: %p, lsizep: %p\n", sizep, lsizep);
systemcfg->icache_size = ppc64_caches.isize = size; _systemcfg->icache_size = ppc64_caches.isize = size;
systemcfg->icache_line_size = _systemcfg->icache_line_size =
ppc64_caches.iline_size = lsize; ppc64_caches.iline_size = lsize;
ppc64_caches.log_iline_size = __ilog2(lsize); ppc64_caches.log_iline_size = __ilog2(lsize);
ppc64_caches.ilines_per_page = PAGE_SIZE / lsize; ppc64_caches.ilines_per_page = PAGE_SIZE / lsize;
...@@ -387,10 +402,12 @@ static void __init initialize_cache_info(void) ...@@ -387,10 +402,12 @@ static void __init initialize_cache_info(void)
} }
/* Add an eye catcher and the systemcfg layout version number */ /* Add an eye catcher and the systemcfg layout version number */
strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64"); strcpy(_systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
systemcfg->version.major = SYSTEMCFG_MAJOR; _systemcfg->version.major = SYSTEMCFG_MAJOR;
systemcfg->version.minor = SYSTEMCFG_MINOR; _systemcfg->version.minor = SYSTEMCFG_MINOR;
systemcfg->processor = mfspr(SPRN_PVR); _systemcfg->processor = mfspr(SPRN_PVR);
_systemcfg->platform = _machine;
_systemcfg->physicalMemorySize = lmb_phys_mem_size();
DBG(" <- initialize_cache_info()\n"); DBG(" <- initialize_cache_info()\n");
} }
...@@ -479,10 +496,10 @@ void __init setup_system(void) ...@@ -479,10 +496,10 @@ void __init setup_system(void)
printk("-----------------------------------------------------\n"); printk("-----------------------------------------------------\n");
printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size);
printk("ppc64_interrupt_controller = 0x%ld\n", ppc64_interrupt_controller); printk("ppc64_interrupt_controller = 0x%ld\n", ppc64_interrupt_controller);
printk("systemcfg = 0x%p\n", systemcfg); printk("systemcfg = 0x%p\n", _systemcfg);
printk("systemcfg->platform = 0x%x\n", systemcfg->platform); printk("systemcfg->platform = 0x%x\n", _systemcfg->platform);
printk("systemcfg->processorCount = 0x%lx\n", systemcfg->processorCount); printk("systemcfg->processorCount = 0x%lx\n", _systemcfg->processorCount);
printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize); printk("systemcfg->physicalMemorySize = 0x%lx\n", _systemcfg->physicalMemorySize);
printk("ppc64_caches.dcache_line_size = 0x%x\n", printk("ppc64_caches.dcache_line_size = 0x%x\n",
ppc64_caches.dline_size); ppc64_caches.dline_size);
printk("ppc64_caches.icache_line_size = 0x%x\n", printk("ppc64_caches.icache_line_size = 0x%x\n",
...@@ -564,12 +581,12 @@ void __init setup_syscall_map(void) ...@@ -564,12 +581,12 @@ void __init setup_syscall_map(void)
for (i = 0; i < __NR_syscalls; i++) { for (i = 0; i < __NR_syscalls; i++) {
if (sys_call_table[i*2] != sys_ni_syscall) { if (sys_call_table[i*2] != sys_ni_syscall) {
count64++; count64++;
systemcfg->syscall_map_64[i >> 5] |= _systemcfg->syscall_map_64[i >> 5] |=
0x80000000UL >> (i & 0x1f); 0x80000000UL >> (i & 0x1f);
} }
if (sys_call_table[i*2+1] != sys_ni_syscall) { if (sys_call_table[i*2+1] != sys_ni_syscall) {
count32++; count32++;
systemcfg->syscall_map_32[i >> 5] |= _systemcfg->syscall_map_32[i >> 5] |=
0x80000000UL >> (i & 0x1f); 0x80000000UL >> (i & 0x1f);
} }
} }
...@@ -858,26 +875,6 @@ int check_legacy_ioport(unsigned long base_port) ...@@ -858,26 +875,6 @@ int check_legacy_ioport(unsigned long base_port)
} }
EXPORT_SYMBOL(check_legacy_ioport); EXPORT_SYMBOL(check_legacy_ioport);
#ifdef CONFIG_XMON
static int __init early_xmon(char *p)
{
/* ensure xmon is enabled */
if (p) {
if (strncmp(p, "on", 2) == 0)
xmon_init(1);
if (strncmp(p, "off", 3) == 0)
xmon_init(0);
if (strncmp(p, "early", 5) != 0)
return 0;
}
xmon_init(1);
debugger(NULL);
return 0;
}
early_param("xmon", early_xmon);
#endif
void cpu_die(void) void cpu_die(void)
{ {
if (ppc_md.cpu_die) if (ppc_md.cpu_die)
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/sigcontext.h>
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
#include "ppc32.h" #include "ppc32.h"
#include <asm/unistd.h> #include <asm/unistd.h>
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <asm/cputable.h> #include <asm/cputable.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/mpic.h> #include <asm/mpic.h>
#include <asm/systemcfg.h>
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
#include <asm/paca.h> #include <asm/paca.h>
#endif #endif
...@@ -368,9 +369,11 @@ int generic_cpu_disable(void) ...@@ -368,9 +369,11 @@ int generic_cpu_disable(void)
if (cpu == boot_cpuid) if (cpu == boot_cpuid)
return -EBUSY; return -EBUSY;
systemcfg->processorCount--;
cpu_clear(cpu, cpu_online_map); cpu_clear(cpu, cpu_online_map);
#ifdef CONFIG_PPC64
_systemcfg->processorCount--;
fixup_irqs(cpu_online_map); fixup_irqs(cpu_online_map);
#endif
return 0; return 0;
} }
...@@ -388,9 +391,11 @@ int generic_cpu_enable(unsigned int cpu) ...@@ -388,9 +391,11 @@ int generic_cpu_enable(unsigned int cpu)
while (!cpu_online(cpu)) while (!cpu_online(cpu))
cpu_relax(); cpu_relax();
#ifdef CONFIG_PPC64
fixup_irqs(cpu_online_map); fixup_irqs(cpu_online_map);
/* counter the irq disable in fixup_irqs */ /* counter the irq disable in fixup_irqs */
local_irq_enable(); local_irq_enable();
#endif
return 0; return 0;
} }
...@@ -419,7 +424,9 @@ void generic_mach_cpu_die(void) ...@@ -419,7 +424,9 @@ void generic_mach_cpu_die(void)
while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
cpu_relax(); cpu_relax();
#ifdef CONFIG_PPC64
flush_tlb_pending(); flush_tlb_pending();
#endif
cpu_set(cpu, cpu_online_map); cpu_set(cpu, cpu_online_map);
local_irq_enable(); local_irq_enable();
} }
......
...@@ -52,7 +52,6 @@ ...@@ -52,7 +52,6 @@
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#include <asm/systemcfg.h>
#include <asm/ppc-pci.h> #include <asm/ppc-pci.h>
/* readdir & getdents */ /* readdir & getdents */
......
...@@ -271,13 +271,13 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, ...@@ -271,13 +271,13 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
* tb_to_xs and stamp_xsec values are consistent. If not, then it * tb_to_xs and stamp_xsec values are consistent. If not, then it
* loops back and reads them again until this criteria is met. * loops back and reads them again until this criteria is met.
*/ */
++(systemcfg->tb_update_count); ++(_systemcfg->tb_update_count);
smp_wmb(); smp_wmb();
systemcfg->tb_orig_stamp = new_tb_stamp; _systemcfg->tb_orig_stamp = new_tb_stamp;
systemcfg->stamp_xsec = new_stamp_xsec; _systemcfg->stamp_xsec = new_stamp_xsec;
systemcfg->tb_to_xs = new_tb_to_xs; _systemcfg->tb_to_xs = new_tb_to_xs;
smp_wmb(); smp_wmb();
++(systemcfg->tb_update_count); ++(_systemcfg->tb_update_count);
#endif #endif
} }
...@@ -357,8 +357,9 @@ static void iSeries_tb_recal(void) ...@@ -357,8 +357,9 @@ static void iSeries_tb_recal(void)
do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
tb_to_xs = divres.result_low; tb_to_xs = divres.result_low;
do_gtod.varp->tb_to_xs = tb_to_xs; do_gtod.varp->tb_to_xs = tb_to_xs;
systemcfg->tb_ticks_per_sec = tb_ticks_per_sec; _systemcfg->tb_ticks_per_sec =
systemcfg->tb_to_xs = tb_to_xs; tb_ticks_per_sec;
_systemcfg->tb_to_xs = tb_to_xs;
} }
else { else {
printk( "Titan recalibrate: FAILED (difference > 4 percent)\n" printk( "Titan recalibrate: FAILED (difference > 4 percent)\n"
...@@ -483,6 +484,8 @@ void __init smp_space_timers(unsigned int max_cpus) ...@@ -483,6 +484,8 @@ void __init smp_space_timers(unsigned int max_cpus)
unsigned long offset = tb_ticks_per_jiffy / max_cpus; unsigned long offset = tb_ticks_per_jiffy / max_cpus;
unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid); unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid);
/* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */
previous_tb -= tb_ticks_per_jiffy;
for_each_cpu(i) { for_each_cpu(i) {
if (i != boot_cpuid) { if (i != boot_cpuid) {
previous_tb += offset; previous_tb += offset;
...@@ -559,8 +562,8 @@ int do_settimeofday(struct timespec *tv) ...@@ -559,8 +562,8 @@ int do_settimeofday(struct timespec *tv)
update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs); update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs);
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
systemcfg->tz_minuteswest = sys_tz.tz_minuteswest; _systemcfg->tz_minuteswest = sys_tz.tz_minuteswest;
systemcfg->tz_dsttime = sys_tz.tz_dsttime; _systemcfg->tz_dsttime = sys_tz.tz_dsttime;
#endif #endif
write_sequnlock_irqrestore(&xtime_lock, flags); write_sequnlock_irqrestore(&xtime_lock, flags);
...@@ -711,11 +714,11 @@ void __init time_init(void) ...@@ -711,11 +714,11 @@ void __init time_init(void)
do_gtod.varp->tb_to_xs = tb_to_xs; do_gtod.varp->tb_to_xs = tb_to_xs;
do_gtod.tb_to_us = tb_to_us; do_gtod.tb_to_us = tb_to_us;
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
systemcfg->tb_orig_stamp = tb_last_jiffy; _systemcfg->tb_orig_stamp = tb_last_jiffy;
systemcfg->tb_update_count = 0; _systemcfg->tb_update_count = 0;
systemcfg->tb_ticks_per_sec = tb_ticks_per_sec; _systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; _systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
systemcfg->tb_to_xs = tb_to_xs; _systemcfg->tb_to_xs = tb_to_xs;
#endif #endif
time_freq = 0; time_freq = 0;
......
...@@ -129,7 +129,7 @@ int die(const char *str, struct pt_regs *regs, long err) ...@@ -129,7 +129,7 @@ int die(const char *str, struct pt_regs *regs, long err)
nl = 1; nl = 1;
#endif #endif
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
switch (systemcfg->platform) { switch (_machine) {
case PLATFORM_PSERIES: case PLATFORM_PSERIES:
printk("PSERIES "); printk("PSERIES ");
nl = 1; nl = 1;
......
...@@ -41,7 +41,7 @@ unsigned long find_next_bit(const unsigned long *addr, unsigned long size, ...@@ -41,7 +41,7 @@ unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
tmp = *p; tmp = *p;
found_first: found_first:
tmp &= (~0UL >> (64 - size)); tmp &= (~0UL >> (BITS_PER_LONG - size));
if (tmp == 0UL) /* Are any bits set? */ if (tmp == 0UL) /* Are any bits set? */
return result + size; /* Nope. */ return result + size; /* Nope. */
found_middle: found_middle:
......
...@@ -84,10 +84,11 @@ ...@@ -84,10 +84,11 @@
extern unsigned long dart_tablebase; extern unsigned long dart_tablebase;
#endif /* CONFIG_U3_DART */ #endif /* CONFIG_U3_DART */
static unsigned long _SDR1;
struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
hpte_t *htab_address; hpte_t *htab_address;
unsigned long htab_hash_mask; unsigned long htab_hash_mask;
unsigned long _SDR1;
struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
int mmu_linear_psize = MMU_PAGE_4K; int mmu_linear_psize = MMU_PAGE_4K;
int mmu_virtual_psize = MMU_PAGE_4K; int mmu_virtual_psize = MMU_PAGE_4K;
#ifdef CONFIG_HUGETLB_PAGE #ifdef CONFIG_HUGETLB_PAGE
...@@ -165,7 +166,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, ...@@ -165,7 +166,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
* normal insert callback here. * normal insert callback here.
*/ */
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
if (systemcfg->platform == PLATFORM_ISERIES_LPAR) if (_machine == PLATFORM_ISERIES_LPAR)
ret = iSeries_hpte_insert(hpteg, va, ret = iSeries_hpte_insert(hpteg, va,
virt_to_abs(paddr), virt_to_abs(paddr),
tmp_mode, tmp_mode,
...@@ -174,7 +175,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, ...@@ -174,7 +175,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
else else
#endif #endif
#ifdef CONFIG_PPC_PSERIES #ifdef CONFIG_PPC_PSERIES
if (systemcfg->platform & PLATFORM_LPAR) if (_machine & PLATFORM_LPAR)
ret = pSeries_lpar_hpte_insert(hpteg, va, ret = pSeries_lpar_hpte_insert(hpteg, va,
virt_to_abs(paddr), virt_to_abs(paddr),
tmp_mode, tmp_mode,
...@@ -293,7 +294,7 @@ static void __init htab_init_page_sizes(void) ...@@ -293,7 +294,7 @@ static void __init htab_init_page_sizes(void)
* Not in the device-tree, let's fallback on known size * Not in the device-tree, let's fallback on known size
* list for 16M capable GP & GR * list for 16M capable GP & GR
*/ */
if ((systemcfg->platform != PLATFORM_ISERIES_LPAR) && if ((_machine != PLATFORM_ISERIES_LPAR) &&
cpu_has_feature(CPU_FTR_16M_PAGE)) cpu_has_feature(CPU_FTR_16M_PAGE))
memcpy(mmu_psize_defs, mmu_psize_defaults_gp, memcpy(mmu_psize_defs, mmu_psize_defaults_gp,
sizeof(mmu_psize_defaults_gp)); sizeof(mmu_psize_defaults_gp));
...@@ -364,7 +365,7 @@ static int __init htab_dt_scan_pftsize(unsigned long node, ...@@ -364,7 +365,7 @@ static int __init htab_dt_scan_pftsize(unsigned long node,
static unsigned long __init htab_get_table_size(void) static unsigned long __init htab_get_table_size(void)
{ {
unsigned long rnd_mem_size, pteg_count; unsigned long mem_size, rnd_mem_size, pteg_count;
/* If hash size isn't already provided by the platform, we try to /* If hash size isn't already provided by the platform, we try to
* retreive it from the device-tree. If it's not there neither, we * 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,8 +377,9 @@ static unsigned long __init htab_get_table_size(void)
return 1UL << ppc64_pft_size; return 1UL << ppc64_pft_size;
/* round mem_size up to next power of 2 */ /* round mem_size up to next power of 2 */
rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize); mem_size = lmb_phys_mem_size();
if (rnd_mem_size < systemcfg->physicalMemorySize) rnd_mem_size = 1UL << __ilog2(mem_size);
if (rnd_mem_size < mem_size)
rnd_mem_size <<= 1; rnd_mem_size <<= 1;
/* # pages / 2 */ /* # pages / 2 */
...@@ -386,6 +388,15 @@ static unsigned long __init htab_get_table_size(void) ...@@ -386,6 +388,15 @@ static unsigned long __init htab_get_table_size(void)
return pteg_count << 7; return pteg_count << 7;
} }
#ifdef CONFIG_MEMORY_HOTPLUG
void create_section_mapping(unsigned long start, unsigned long end)
{
BUG_ON(htab_bolt_mapping(start, end, start,
_PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX,
mmu_linear_psize));
}
#endif /* CONFIG_MEMORY_HOTPLUG */
void __init htab_initialize(void) void __init htab_initialize(void)
{ {
unsigned long table, htab_size_bytes; unsigned long table, htab_size_bytes;
...@@ -410,7 +421,7 @@ void __init htab_initialize(void) ...@@ -410,7 +421,7 @@ void __init htab_initialize(void)
htab_hash_mask = pteg_count - 1; htab_hash_mask = pteg_count - 1;
if (systemcfg->platform & PLATFORM_LPAR) { if (platform_is_lpar()) {
/* Using a hypervisor which owns the htab */ /* Using a hypervisor which owns the htab */
htab_address = NULL; htab_address = NULL;
_SDR1 = 0; _SDR1 = 0;
...@@ -431,6 +442,9 @@ void __init htab_initialize(void) ...@@ -431,6 +442,9 @@ void __init htab_initialize(void)
/* Initialize the HPT with no entries */ /* Initialize the HPT with no entries */
memset((void *)table, 0, htab_size_bytes); memset((void *)table, 0, htab_size_bytes);
/* Set SDR1 */
mtspr(SPRN_SDR1, _SDR1);
} }
mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX; mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX;
...@@ -500,6 +514,12 @@ void __init htab_initialize(void) ...@@ -500,6 +514,12 @@ void __init htab_initialize(void)
#undef KB #undef KB
#undef MB #undef MB
void __init htab_initialize_secondary(void)
{
if (!platform_is_lpar())
mtspr(SPRN_SDR1, _SDR1);
}
/* /*
* Called by asm hashtable.S for doing lazy icache flush * Called by asm hashtable.S for doing lazy icache flush
*/ */
......
...@@ -84,9 +84,6 @@ void MMU_init(void); ...@@ -84,9 +84,6 @@ void MMU_init(void);
/* XXX should be in current.h -- paulus */ /* XXX should be in current.h -- paulus */
extern struct task_struct *current_set[NR_CPUS]; extern struct task_struct *current_set[NR_CPUS];
char *klimit = _end;
struct device_node *memory_node;
extern int init_bootmem_done; extern int init_bootmem_done;
/* /*
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
* *
*/ */
#undef DEBUG
#include <linux/config.h> #include <linux/config.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -64,6 +66,12 @@ ...@@ -64,6 +66,12 @@
#include <asm/vdso.h> #include <asm/vdso.h>
#include <asm/imalloc.h> #include <asm/imalloc.h>
#ifdef DEBUG
#define DBG(fmt...) printk(fmt)
#else
#define DBG(fmt...)
#endif
#if PGTABLE_RANGE > USER_VSID_RANGE #if PGTABLE_RANGE > USER_VSID_RANGE
#warning Limited user VSID range means pagetable space is wasted #warning Limited user VSID range means pagetable space is wasted
#endif #endif
...@@ -72,8 +80,6 @@ ...@@ -72,8 +80,6 @@
#warning TASK_SIZE is smaller than it needs to be. #warning TASK_SIZE is smaller than it needs to be.
#endif #endif
unsigned long klimit = (unsigned long)_end;
/* max amount of RAM to use */ /* max amount of RAM to use */
unsigned long __max_memory; unsigned long __max_memory;
...@@ -188,14 +194,14 @@ static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags) ...@@ -188,14 +194,14 @@ static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags)
} }
#ifdef CONFIG_PPC_64K_PAGES #ifdef CONFIG_PPC_64K_PAGES
static const int pgtable_cache_size[2] = { static const unsigned int pgtable_cache_size[3] = {
PTE_TABLE_SIZE, PGD_TABLE_SIZE PTE_TABLE_SIZE, PMD_TABLE_SIZE, PGD_TABLE_SIZE
}; };
static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
"pte_pmd_cache", "pgd_cache", "pte_pmd_cache", "pmd_cache", "pgd_cache",
}; };
#else #else
static const int pgtable_cache_size[2] = { static const unsigned int pgtable_cache_size[2] = {
PTE_TABLE_SIZE, PMD_TABLE_SIZE PTE_TABLE_SIZE, PMD_TABLE_SIZE
}; };
static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
...@@ -213,6 +219,8 @@ void pgtable_cache_init(void) ...@@ -213,6 +219,8 @@ void pgtable_cache_init(void)
int size = pgtable_cache_size[i]; int size = pgtable_cache_size[i];
const char *name = pgtable_cache_name[i]; const char *name = pgtable_cache_name[i];
DBG("Allocating page table cache %s (#%d) "
"for size: %08x...\n", name, i, size);
pgtable_cache[i] = kmem_cache_create(name, pgtable_cache[i] = kmem_cache_create(name,
size, size, size, size,
SLAB_HWCACHE_ALIGN | SLAB_HWCACHE_ALIGN |
......
...@@ -110,6 +110,7 @@ EXPORT_SYMBOL(phys_mem_access_prot); ...@@ -110,6 +110,7 @@ EXPORT_SYMBOL(phys_mem_access_prot);
void online_page(struct page *page) void online_page(struct page *page)
{ {
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 0);
free_cold_page(page); free_cold_page(page);
totalram_pages++; totalram_pages++;
num_physpages++; num_physpages++;
...@@ -127,6 +128,9 @@ int __devinit add_memory(u64 start, u64 size) ...@@ -127,6 +128,9 @@ int __devinit add_memory(u64 start, u64 size)
unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT;
start += KERNELBASE;
create_section_mapping(start, start + size);
/* this should work for most non-highmem platforms */ /* this should work for most non-highmem platforms */
zone = pgdata->node_zones; zone = pgdata->node_zones;
......
...@@ -122,8 +122,11 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags) ...@@ -122,8 +122,11 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
* *
*/ */
if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags, if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags,
mmu_virtual_psize)) mmu_virtual_psize)) {
panic("Can't map bolted IO mapping"); printk(KERN_ERR "Failed to do bolted mapping IO "
"memory at %016lx !\n", pa);
return -ENOMEM;
}
} }
return 0; return 0;
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <asm/cputable.h> #include <asm/cputable.h>
#include <asm/lmb.h> #include <asm/lmb.h>
#include <asm/abs_addr.h> #include <asm/abs_addr.h>
#include <asm/firmware.h>
struct stab_entry { struct stab_entry {
unsigned long esid_data; unsigned long esid_data;
...@@ -256,7 +257,7 @@ void stabs_alloc(void) ...@@ -256,7 +257,7 @@ void stabs_alloc(void)
paca[cpu].stab_addr = newstab; paca[cpu].stab_addr = newstab;
paca[cpu].stab_real = virt_to_abs(newstab); paca[cpu].stab_real = virt_to_abs(newstab);
printk(KERN_DEBUG "Segment table for CPU %d at 0x%lx " printk(KERN_INFO "Segment table for CPU %d at 0x%lx "
"virtual, 0x%lx absolute\n", "virtual, 0x%lx absolute\n",
cpu, paca[cpu].stab_addr, paca[cpu].stab_real); cpu, paca[cpu].stab_addr, paca[cpu].stab_real);
} }
...@@ -270,10 +271,28 @@ void stabs_alloc(void) ...@@ -270,10 +271,28 @@ void stabs_alloc(void)
void stab_initialize(unsigned long stab) void stab_initialize(unsigned long stab)
{ {
unsigned long vsid = get_kernel_vsid(KERNELBASE); unsigned long vsid = get_kernel_vsid(KERNELBASE);
unsigned long stabreal;
asm volatile("isync; slbia; isync":::"memory"); asm volatile("isync; slbia; isync":::"memory");
make_ste(stab, GET_ESID(KERNELBASE), vsid); make_ste(stab, GET_ESID(KERNELBASE), vsid);
/* Order update */ /* Order update */
asm volatile("sync":::"memory"); asm volatile("sync":::"memory");
/* Set ASR */
stabreal = get_paca()->stab_real | 0x1ul;
#ifdef CONFIG_PPC_ISERIES
if (firmware_has_feature(FW_FEATURE_ISERIES)) {
HvCall1(HvCallBaseSetASR, stabreal);
return;
}
#endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_PPC_PSERIES
if (platform_is_lpar()) {
plpar_hcall_norets(H_SET_ASR, stabreal);
return;
}
#endif
mtspr(SPRN_ASR, stabreal);
} }
...@@ -233,8 +233,7 @@ static unsigned long get_pc(struct pt_regs *regs) ...@@ -233,8 +233,7 @@ static unsigned long get_pc(struct pt_regs *regs)
mmcra = mfspr(SPRN_MMCRA); mmcra = mfspr(SPRN_MMCRA);
/* Were we in the hypervisor? */ /* Were we in the hypervisor? */
if ((systemcfg->platform == PLATFORM_PSERIES_LPAR) && if (platform_is_lpar() && (mmcra & MMCRA_SIHV))
(mmcra & MMCRA_SIHV))
/* function descriptor madness */ /* function descriptor madness */
return *((unsigned long *)hypervisor_bucket); return *((unsigned long *)hypervisor_bucket);
......
...@@ -361,7 +361,9 @@ static void __init chrp_find_openpic(void) ...@@ -361,7 +361,9 @@ static void __init chrp_find_openpic(void)
printk(KERN_INFO "OpenPIC at %lx\n", opaddr); printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */ irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */
prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS - 4); prom_get_irq_senses(init_senses, NUM_ISA_INTERRUPTS, NR_IRQS - 4);
/* i8259 cascade is always positive level */
init_senses[0] = IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE;
iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len);
if (iranges == NULL) if (iranges == NULL)
......
...@@ -103,6 +103,9 @@ static void intReceived(struct XmPciLpEvent *eventParm, ...@@ -103,6 +103,9 @@ static void intReceived(struct XmPciLpEvent *eventParm,
struct pt_regs *regsParm) struct pt_regs *regsParm)
{ {
int irq; int irq;
#ifdef CONFIG_IRQSTACKS
struct thread_info *curtp, *irqtp;
#endif
++Pci_Interrupt_Count; ++Pci_Interrupt_Count;
...@@ -110,7 +113,20 @@ static void intReceived(struct XmPciLpEvent *eventParm, ...@@ -110,7 +113,20 @@ static void intReceived(struct XmPciLpEvent *eventParm,
case XmPciLpEvent_SlotInterrupt: case XmPciLpEvent_SlotInterrupt:
irq = eventParm->hvLpEvent.xCorrelationToken; irq = eventParm->hvLpEvent.xCorrelationToken;
/* Dispatch the interrupt handlers for this irq */ /* Dispatch the interrupt handlers for this irq */
ppc_irq_dispatch_handler(regsParm, irq); #ifdef CONFIG_IRQSTACKS
/* Switch to the irq stack to handle this */
curtp = current_thread_info();
irqtp = hardirq_ctx[smp_processor_id()];
if (curtp != irqtp) {
irqtp->task = curtp->task;
irqtp->flags = 0;
call___do_IRQ(irq, regsParm, irqtp);
irqtp->task = NULL;
if (irqtp->flags)
set_bits(irqtp->flags, &curtp->flags);
} else
#endif
__do_IRQ(irq, regsParm);
HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber, HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
eventParm->eventData.slotInterrupt.subBusNumber, eventParm->eventData.slotInterrupt.subBusNumber,
eventParm->eventData.slotInterrupt.deviceId); eventParm->eventData.slotInterrupt.deviceId);
...@@ -310,10 +326,8 @@ static void iSeries_disable_IRQ(unsigned int irq) ...@@ -310,10 +326,8 @@ static void iSeries_disable_IRQ(unsigned int irq)
} }
/* /*
* Need to define this so ppc_irq_dispatch_handler will NOT call * This does nothing because there is not enough information
* enable_IRQ at the end of interrupt handling. However, this does * provided to do the EOI HvCall. This is done by XmPciLpEvent.c
* nothing because there is not enough information provided to do
* the EOI HvCall. This is done by XmPciLpEvent.c
*/ */
static void iSeries_end_IRQ(unsigned int irq) static void iSeries_end_IRQ(unsigned int irq)
{ {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#include <asm/ppc_asm.h>
.text .text
......
...@@ -39,7 +39,8 @@ ...@@ -39,7 +39,8 @@
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/iommu.h> #include <asm/iommu.h>
#include <asm/firmware.h> #include <asm/firmware.h>
#include <asm/systemcfg.h>
#include <asm/system.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/paca.h> #include <asm/paca.h>
#include <asm/cache.h> #include <asm/cache.h>
...@@ -71,7 +72,7 @@ extern void hvlog(char *fmt, ...); ...@@ -71,7 +72,7 @@ extern void hvlog(char *fmt, ...);
#endif #endif
/* Function Prototypes */ /* Function Prototypes */
static void build_iSeries_Memory_Map(void); static unsigned long build_iSeries_Memory_Map(void);
static void iseries_shared_idle(void); static void iseries_shared_idle(void);
static void iseries_dedicated_idle(void); static void iseries_dedicated_idle(void);
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
...@@ -84,7 +85,6 @@ static void iSeries_pci_final_fixup(void) { } ...@@ -84,7 +85,6 @@ static void iSeries_pci_final_fixup(void) { }
int piranha_simulator; int piranha_simulator;
extern int rd_size; /* Defined in drivers/block/rd.c */ extern int rd_size; /* Defined in drivers/block/rd.c */
extern unsigned long klimit;
extern unsigned long embedded_sysmap_start; extern unsigned long embedded_sysmap_start;
extern unsigned long embedded_sysmap_end; extern unsigned long embedded_sysmap_end;
...@@ -403,9 +403,11 @@ void mschunks_alloc(unsigned long num_chunks) ...@@ -403,9 +403,11 @@ void mschunks_alloc(unsigned long num_chunks)
* a table used to translate Linux's physical addresses to these * a table used to translate Linux's physical addresses to these
* absolute addresses. Absolute addresses are needed when * absolute addresses. Absolute addresses are needed when
* communicating with the hypervisor (e.g. to build HPT entries) * communicating with the hypervisor (e.g. to build HPT entries)
*
* Returns the physical memory size
*/ */
static void __init build_iSeries_Memory_Map(void) static unsigned long __init build_iSeries_Memory_Map(void)
{ {
u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize; u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize;
u32 nextPhysChunk; u32 nextPhysChunk;
...@@ -538,7 +540,7 @@ static void __init build_iSeries_Memory_Map(void) ...@@ -538,7 +540,7 @@ static void __init build_iSeries_Memory_Map(void)
* which should be equal to * which should be equal to
* nextPhysChunk * nextPhysChunk
*/ */
systemcfg->physicalMemorySize = chunk_to_addr(nextPhysChunk); return chunk_to_addr(nextPhysChunk);
} }
/* /*
...@@ -564,8 +566,8 @@ static void __init iSeries_setup_arch(void) ...@@ -564,8 +566,8 @@ static void __init iSeries_setup_arch(void)
printk("Max physical processors = %d\n", printk("Max physical processors = %d\n",
itVpdAreas.xSlicMaxPhysicalProcs); itVpdAreas.xSlicMaxPhysicalProcs);
systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR; _systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
printk("Processor version = %x\n", systemcfg->processor); printk("Processor version = %x\n", _systemcfg->processor);
} }
static void iSeries_show_cpuinfo(struct seq_file *m) static void iSeries_show_cpuinfo(struct seq_file *m)
...@@ -702,7 +704,6 @@ static void iseries_shared_idle(void) ...@@ -702,7 +704,6 @@ static void iseries_shared_idle(void)
static void iseries_dedicated_idle(void) static void iseries_dedicated_idle(void)
{ {
long oldval;
set_thread_flag(TIF_POLLING_NRFLAG); set_thread_flag(TIF_POLLING_NRFLAG);
while (1) { while (1) {
...@@ -929,7 +930,7 @@ void dt_cpus(struct iseries_flat_dt *dt) ...@@ -929,7 +930,7 @@ void dt_cpus(struct iseries_flat_dt *dt)
dt_end_node(dt); dt_end_node(dt);
} }
void build_flat_dt(struct iseries_flat_dt *dt) void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
{ {
u64 tmp[2]; u64 tmp[2];
...@@ -945,7 +946,7 @@ void build_flat_dt(struct iseries_flat_dt *dt) ...@@ -945,7 +946,7 @@ void build_flat_dt(struct iseries_flat_dt *dt)
dt_prop_str(dt, "name", "memory"); dt_prop_str(dt, "name", "memory");
dt_prop_str(dt, "device_type", "memory"); dt_prop_str(dt, "device_type", "memory");
tmp[0] = 0; tmp[0] = 0;
tmp[1] = systemcfg->physicalMemorySize; tmp[1] = phys_mem_size;
dt_prop_u64_list(dt, "reg", tmp, 2); dt_prop_u64_list(dt, "reg", tmp, 2);
dt_end_node(dt); dt_end_node(dt);
...@@ -965,13 +966,15 @@ void build_flat_dt(struct iseries_flat_dt *dt) ...@@ -965,13 +966,15 @@ void build_flat_dt(struct iseries_flat_dt *dt)
void * __init iSeries_early_setup(void) void * __init iSeries_early_setup(void)
{ {
unsigned long phys_mem_size;
iSeries_fixup_klimit(); iSeries_fixup_klimit();
/* /*
* Initialize the table which translate Linux physical addresses to * Initialize the table which translate Linux physical addresses to
* AS/400 absolute addresses * AS/400 absolute addresses
*/ */
build_iSeries_Memory_Map(); phys_mem_size = build_iSeries_Memory_Map();
iSeries_get_cmdline(); iSeries_get_cmdline();
...@@ -981,7 +984,7 @@ void * __init iSeries_early_setup(void) ...@@ -981,7 +984,7 @@ void * __init iSeries_early_setup(void)
/* Parse early parameters, in particular mem=x */ /* Parse early parameters, in particular mem=x */
parse_early_param(); parse_early_param();
build_flat_dt(&iseries_dt); build_flat_dt(&iseries_dt, phys_mem_size);
return (void *) __pa(&iseries_dt); return (void *) __pa(&iseries_dt);
} }
......
...@@ -380,9 +380,6 @@ void __init maple_pcibios_fixup(void) ...@@ -380,9 +380,6 @@ void __init maple_pcibios_fixup(void)
for_each_pci_dev(dev) for_each_pci_dev(dev)
pci_read_irq_line(dev); pci_read_irq_line(dev);
/* Do the mapping of the IO space */
phbs_remap_io();
DBG(" <- maple_pcibios_fixup\n"); DBG(" <- maple_pcibios_fixup\n");
} }
......
...@@ -918,9 +918,6 @@ void __init pmac_pci_init(void) ...@@ -918,9 +918,6 @@ void __init pmac_pci_init(void)
PCI_DN(np)->busno = 0xf0; PCI_DN(np)->busno = 0xf0;
} }
/* map in PCI I/O space */
phbs_remap_io();
/* pmac_check_ht_link(); */ /* pmac_check_ht_link(); */
/* Tell pci.c to not use the common resource allocation mechanism */ /* Tell pci.c to not use the common resource allocation mechanism */
......
...@@ -74,6 +74,9 @@ static DEFINE_SPINLOCK(pmac_pic_lock); ...@@ -74,6 +74,9 @@ static DEFINE_SPINLOCK(pmac_pic_lock);
#define GATWICK_IRQ_POOL_SIZE 10 #define GATWICK_IRQ_POOL_SIZE 10
static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
/* /*
* Mark an irq as "lost". This is only used on the pmac * Mark an irq as "lost". This is only used on the pmac
* since it can lose interrupts (see pmac_set_irq_mask). * since it can lose interrupts (see pmac_set_irq_mask).
......
...@@ -305,9 +305,19 @@ static int __init smp_psurge_probe(void) ...@@ -305,9 +305,19 @@ static int __init smp_psurge_probe(void)
psurge_start = ioremap(PSURGE_START, 4); psurge_start = ioremap(PSURGE_START, 4);
psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
/* this is not actually strictly necessary -- paulus. */ /*
for (i = 1; i < ncpus; ++i) * This is necessary because OF doesn't know about the
smp_hw_index[i] = i; * secondary cpu(s), and thus there aren't nodes in the
* device tree for them, and smp_setup_cpu_maps hasn't
* set their bits in cpu_possible_map and cpu_present_map.
*/
if (ncpus > NR_CPUS)
ncpus = NR_CPUS;
for (i = 1; i < ncpus ; ++i) {
cpu_set(i, cpu_present_map);
cpu_set(i, cpu_possible_map);
set_hard_smp_processor_id(i, i);
}
if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
...@@ -348,6 +358,7 @@ static void __init psurge_dual_sync_tb(int cpu_nr) ...@@ -348,6 +358,7 @@ static void __init psurge_dual_sync_tb(int cpu_nr)
int t; int t;
set_dec(tb_ticks_per_jiffy); set_dec(tb_ticks_per_jiffy);
/* XXX fixme */
set_tb(0, 0); set_tb(0, 0);
last_jiffy_stamp(cpu_nr) = 0; last_jiffy_stamp(cpu_nr) = 0;
...@@ -363,8 +374,6 @@ static void __init psurge_dual_sync_tb(int cpu_nr) ...@@ -363,8 +374,6 @@ static void __init psurge_dual_sync_tb(int cpu_nr)
/* now interrupt the secondary, starting both TBs */ /* now interrupt the secondary, starting both TBs */
psurge_set_ipi(1); psurge_set_ipi(1);
smp_tb_synchronized = 1;
} }
static struct irqaction psurge_irqaction = { static struct irqaction psurge_irqaction = {
...@@ -625,9 +634,8 @@ void smp_core99_give_timebase(void) ...@@ -625,9 +634,8 @@ void smp_core99_give_timebase(void)
for (t = 100000; t > 0 && sec_tb_reset; --t) for (t = 100000; t > 0 && sec_tb_reset; --t)
udelay(10); udelay(10);
if (sec_tb_reset) if (sec_tb_reset)
/* XXX BUG_ON here? */
printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n"); printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
else
smp_tb_synchronized = 1;
/* Now, restart the timebase by leaving the GPIO to an open collector */ /* Now, restart the timebase by leaving the GPIO to an open collector */
pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0); 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,19 +818,9 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr)
} }
/* Core99 Macs (dual G4s and G5s) */
struct smp_ops_t core99_smp_ops = {
.message_pass = smp_mpic_message_pass,
.probe = smp_core99_probe,
.kick_cpu = smp_core99_kick_cpu,
.setup_cpu = smp_core99_setup_cpu,
.give_timebase = smp_core99_give_timebase,
.take_timebase = smp_core99_take_timebase,
};
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
int __cpu_disable(void) int smp_core99_cpu_disable(void)
{ {
cpu_clear(smp_processor_id(), cpu_online_map); cpu_clear(smp_processor_id(), cpu_online_map);
...@@ -846,7 +844,7 @@ void cpu_die(void) ...@@ -846,7 +844,7 @@ void cpu_die(void)
low_cpu_die(); low_cpu_die();
} }
void __cpu_die(unsigned int cpu) void smp_core99_cpu_die(unsigned int cpu)
{ {
int timeout; int timeout;
...@@ -858,8 +856,21 @@ void __cpu_die(unsigned int cpu) ...@@ -858,8 +856,21 @@ void __cpu_die(unsigned int cpu)
} }
msleep(1); msleep(1);
} }
cpu_callin_map[cpu] = 0;
cpu_dead[cpu] = 0; cpu_dead[cpu] = 0;
} }
#endif #endif
/* Core99 Macs (dual G4s and G5s) */
struct smp_ops_t core99_smp_ops = {
.message_pass = smp_mpic_message_pass,
.probe = smp_core99_probe,
.kick_cpu = smp_core99_kick_cpu,
.setup_cpu = smp_core99_setup_cpu,
.give_timebase = smp_core99_give_timebase,
.take_timebase = smp_core99_take_timebase,
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
.cpu_disable = smp_core99_cpu_disable,
.cpu_die = smp_core99_cpu_die,
#endif
};
...@@ -3,3 +3,5 @@ obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ ...@@ -3,3 +3,5 @@ obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \
obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_IBMVIO) += vio.o
obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_XICS) += xics.o
obj-$(CONFIG_SCANLOG) += scanlog.o
obj-$(CONFIG_EEH) += eeh.o eeh_event.o
/*
* eeh_event.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Copyright (c) 2005 Linas Vepstas <linas@linas.org>
*/
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/eeh_event.h>
/** Overview:
* EEH error states may be detected within exception handlers;
* however, the recovery processing needs to occur asynchronously
* in a normal kernel context and not an interrupt context.
* This pair of routines creates an event and queues it onto a
* work-queue, where a worker thread can drive recovery.
*/
/* EEH event workqueue setup. */
static spinlock_t eeh_eventlist_lock = SPIN_LOCK_UNLOCKED;
LIST_HEAD(eeh_eventlist);
static void eeh_thread_launcher(void *);
DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL);
/**
* eeh_panic - call panic() for an eeh event that cannot be handled.
* The philosophy of this routine is that it is better to panic and
* halt the OS than it is to risk possible data corruption by
* oblivious device drivers that don't know better.
*
* @dev pci device that had an eeh event
* @reset_state current reset state of the device slot
*/
static void eeh_panic(struct pci_dev *dev, int reset_state)
{
/*
* Since the panic_on_oops sysctl is used to halt the system
* in light of potential corruption, we can use it here.
*/
if (panic_on_oops) {
panic("EEH: MMIO failure (%d) on device:%s\n", reset_state,
pci_name(dev));
}
else {
printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n",
reset_state, pci_name(dev));
}
}
/**
* eeh_event_handler - dispatch EEH events. The detection of a frozen
* slot can occur inside an interrupt, where it can be hard to do
* anything about it. The goal of this routine is to pull these
* detection events out of the context of the interrupt handler, and
* re-dispatch them for processing at a later time in a normal context.
*
* @dummy - unused
*/
static int eeh_event_handler(void * dummy)
{
unsigned long flags;
struct eeh_event *event;
daemonize ("eehd");
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
spin_lock_irqsave(&eeh_eventlist_lock, flags);
event = NULL;
if (!list_empty(&eeh_eventlist)) {
event = list_entry(eeh_eventlist.next, struct eeh_event, list);
list_del(&event->list);
}
spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
if (event == NULL)
break;
printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
pci_name(event->dev));
eeh_panic (event->dev, event->state);
kfree(event);
}
return 0;
}
/**
* eeh_thread_launcher
*
* @dummy - unused
*/
static void eeh_thread_launcher(void *dummy)
{
if (kernel_thread(eeh_event_handler, NULL, CLONE_KERNEL) < 0)
printk(KERN_ERR "Failed to start EEH daemon\n");
}
/**
* eeh_send_failure_event - generate a PCI error event
* @dev pci device
*
* This routine can be called within an interrupt context;
* the actual event will be delivered in a normal context
* (from a workqueue).
*/
int eeh_send_failure_event (struct device_node *dn,
struct pci_dev *dev,
int state,
int time_unavail)
{
unsigned long flags;
struct eeh_event *event;
event = kmalloc(sizeof(*event), GFP_ATOMIC);
if (event == NULL) {
printk (KERN_ERR "EEH: out of memory, event not handled\n");
return 1;
}
if (dev)
pci_dev_get(dev);
event->dn = dn;
event->dev = dev;
event->state = state;
event->time_unavail = time_unavail;
/* We may or may not be called in an interrupt context */
spin_lock_irqsave(&eeh_eventlist_lock, flags);
list_add(&event->list, &eeh_eventlist);
spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
schedule_work(&eeh_event_wq);
return 0;
}
/********************** END OF FILE ******************************/
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/abs_addr.h> #include <asm/abs_addr.h>
#include <asm/pSeries_reconfig.h> #include <asm/pSeries_reconfig.h>
#include <asm/systemcfg.h>
#include <asm/firmware.h> #include <asm/firmware.h>
#include <asm/tce.h> #include <asm/tce.h>
#include <asm/ppc-pci.h> #include <asm/ppc-pci.h>
...@@ -582,7 +581,7 @@ void iommu_init_early_pSeries(void) ...@@ -582,7 +581,7 @@ void iommu_init_early_pSeries(void)
return; return;
} }
if (systemcfg->platform & PLATFORM_LPAR) { if (platform_is_lpar()) {
if (firmware_has_feature(FW_FEATURE_MULTITCE)) { if (firmware_has_feature(FW_FEATURE_MULTITCE)) {
ppc_md.tce_build = tce_buildmulti_pSeriesLP; ppc_md.tce_build = tce_buildmulti_pSeriesLP;
ppc_md.tce_free = tce_freemulti_pSeriesLP; ppc_md.tce_free = tce_freemulti_pSeriesLP;
......
...@@ -107,7 +107,6 @@ static void __init pSeries_request_regions(void) ...@@ -107,7 +107,6 @@ static void __init pSeries_request_regions(void)
void __init pSeries_final_fixup(void) void __init pSeries_final_fixup(void)
{ {
phbs_remap_io();
pSeries_request_regions(); pSeries_request_regions();
pci_addr_cache_build(); pci_addr_cache_build();
...@@ -123,7 +122,7 @@ static void fixup_winbond_82c105(struct pci_dev* dev) ...@@ -123,7 +122,7 @@ static void fixup_winbond_82c105(struct pci_dev* dev)
int i; int i;
unsigned int reg; unsigned int reg;
if (!(systemcfg->platform & PLATFORM_PSERIES)) if (!platform_is_pseries())
return; return;
printk("Using INTC for W82c105 IDE controller.\n"); printk("Using INTC for W82c105 IDE controller.\n");
......
...@@ -408,7 +408,7 @@ static int proc_ppc64_create_ofdt(void) ...@@ -408,7 +408,7 @@ static int proc_ppc64_create_ofdt(void)
{ {
struct proc_dir_entry *ent; struct proc_dir_entry *ent;
if (!(systemcfg->platform & PLATFORM_PSERIES)) if (!platform_is_pseries())
return 0; return 0;
ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL); ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL);
......
...@@ -482,9 +482,11 @@ static int __init rtas_init(void) ...@@ -482,9 +482,11 @@ static int __init rtas_init(void)
{ {
struct proc_dir_entry *entry; struct proc_dir_entry *entry;
/* No RTAS, only warn if we are on a pSeries box */ if (!platform_is_pseries())
return 0;
/* No RTAS */
if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) {
if (systemcfg->platform & PLATFORM_PSERIES)
printk(KERN_INFO "rtasd: no event-scan on system\n"); printk(KERN_INFO "rtasd: no event-scan on system\n");
return 1; return 1;
} }
......
...@@ -249,7 +249,7 @@ static void __init pSeries_setup_arch(void) ...@@ -249,7 +249,7 @@ static void __init pSeries_setup_arch(void)
ppc_md.idle_loop = default_idle; ppc_md.idle_loop = default_idle;
} }
if (systemcfg->platform & PLATFORM_LPAR) if (platform_is_lpar())
ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
else else
ppc_md.enable_pmcs = power4_enable_pmcs; ppc_md.enable_pmcs = power4_enable_pmcs;
...@@ -378,7 +378,7 @@ static void __init pSeries_init_early(void) ...@@ -378,7 +378,7 @@ static void __init pSeries_init_early(void)
fw_feature_init(); fw_feature_init();
if (systemcfg->platform & PLATFORM_LPAR) if (platform_is_lpar())
hpte_init_lpar(); hpte_init_lpar();
else { else {
hpte_init_native(); hpte_init_native();
...@@ -388,7 +388,7 @@ static void __init pSeries_init_early(void) ...@@ -388,7 +388,7 @@ static void __init pSeries_init_early(void)
generic_find_legacy_serial_ports(&physport, &default_speed); generic_find_legacy_serial_ports(&physport, &default_speed);
if (systemcfg->platform & PLATFORM_LPAR) if (platform_is_lpar())
find_udbg_vterm(); find_udbg_vterm();
else if (physport) { else if (physport) {
/* Map the uart for udbg. */ /* Map the uart for udbg. */
...@@ -592,7 +592,7 @@ static void pseries_shared_idle(void) ...@@ -592,7 +592,7 @@ static void pseries_shared_idle(void)
static int pSeries_pci_probe_mode(struct pci_bus *bus) static int pSeries_pci_probe_mode(struct pci_bus *bus)
{ {
if (systemcfg->platform & PLATFORM_LPAR) if (platform_is_lpar())
return PCI_PROBE_DEVTREE; return PCI_PROBE_DEVTREE;
return PCI_PROBE_NORMAL; return PCI_PROBE_NORMAL;
} }
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <asm/rtas.h> #include <asm/rtas.h>
#include <asm/pSeries_reconfig.h> #include <asm/pSeries_reconfig.h>
#include <asm/mpic.h> #include <asm/mpic.h>
#include <asm/systemcfg.h>
#include "plpar_wrappers.h" #include "plpar_wrappers.h"
...@@ -96,7 +97,7 @@ int pSeries_cpu_disable(void) ...@@ -96,7 +97,7 @@ int pSeries_cpu_disable(void)
int cpu = smp_processor_id(); int cpu = smp_processor_id();
cpu_clear(cpu, cpu_online_map); cpu_clear(cpu, cpu_online_map);
systemcfg->processorCount--; _systemcfg->processorCount--;
/*fix boot_cpuid here*/ /*fix boot_cpuid here*/
if (cpu == boot_cpuid) if (cpu == boot_cpuid)
...@@ -441,7 +442,7 @@ void __init smp_init_pSeries(void) ...@@ -441,7 +442,7 @@ void __init smp_init_pSeries(void)
smp_ops->cpu_die = pSeries_cpu_die; smp_ops->cpu_die = pSeries_cpu_die;
/* Processors can be added/removed only on LPAR */ /* Processors can be added/removed only on LPAR */
if (systemcfg->platform == PLATFORM_PSERIES_LPAR) if (platform_is_lpar())
pSeries_reconfig_notifier_register(&pSeries_smp_nb); pSeries_reconfig_notifier_register(&pSeries_smp_nb);
#endif #endif
......
...@@ -545,7 +545,9 @@ void xics_init_IRQ(void) ...@@ -545,7 +545,9 @@ void xics_init_IRQ(void)
of_node_put(np); of_node_put(np);
} }
if (systemcfg->platform == PLATFORM_PSERIES) { if (platform_is_lpar())
ops = &pSeriesLP_ops;
else {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
for_each_cpu(i) { for_each_cpu(i) {
int hard_id; int hard_id;
...@@ -561,12 +563,11 @@ void xics_init_IRQ(void) ...@@ -561,12 +563,11 @@ void xics_init_IRQ(void)
#else #else
xics_per_cpu[0] = ioremap(intr_base, intr_size); xics_per_cpu[0] = ioremap(intr_base, intr_size);
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
} else if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
ops = &pSeriesLP_ops;
} }
xics_8259_pic.enable = i8259_pic.enable; xics_8259_pic.enable = i8259_pic.enable;
xics_8259_pic.disable = i8259_pic.disable; xics_8259_pic.disable = i8259_pic.disable;
xics_8259_pic.end = i8259_pic.end;
for (i = 0; i < 16; ++i) for (i = 0; i < 16; ++i)
get_irq_desc(i)->handler = &xics_8259_pic; get_irq_desc(i)->handler = &xics_8259_pic;
for (; i < NR_IRQS; ++i) for (; i < NR_IRQS; ++i)
......
...@@ -226,7 +226,7 @@ static void iommu_table_u3_setup(void) ...@@ -226,7 +226,7 @@ static void iommu_table_u3_setup(void)
iommu_table_u3.it_busno = 0; iommu_table_u3.it_busno = 0;
iommu_table_u3.it_offset = 0; iommu_table_u3.it_offset = 0;
/* it_size is in number of entries */ /* it_size is in number of entries */
iommu_table_u3.it_size = dart_tablesize / sizeof(u32); iommu_table_u3.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR;
/* Initialize the common IOMMU code */ /* Initialize the common IOMMU code */
iommu_table_u3.it_base = (unsigned long)dart_vbase; iommu_table_u3.it_base = (unsigned long)dart_vbase;
......
...@@ -8,4 +8,4 @@ obj-$(CONFIG_8xx) += start_8xx.o ...@@ -8,4 +8,4 @@ obj-$(CONFIG_8xx) += start_8xx.o
obj-$(CONFIG_6xx) += start_32.o obj-$(CONFIG_6xx) += start_32.o
obj-$(CONFIG_4xx) += start_32.o obj-$(CONFIG_4xx) += start_32.o
obj-$(CONFIG_PPC64) += start_64.o obj-$(CONFIG_PPC64) += start_64.o
obj-y += xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o nonstdio.o
/*
* Copyright (C) 1996-2005 Paul Mackerras.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/string.h>
#include <asm/time.h>
#include "nonstdio.h"
int xmon_putchar(int c)
{
char ch = c;
if (c == '\n')
xmon_putchar('\r');
return xmon_write(&ch, 1) == 1? c: -1;
}
static char line[256];
static char *lineptr;
static int lineleft;
int xmon_expect(const char *str, unsigned long timeout)
{
int c;
unsigned long t0;
/* assume 25MHz default timebase if tb_ticks_per_sec not set yet */
timeout *= tb_ticks_per_sec? tb_ticks_per_sec: 25000000;
t0 = get_tbl();
do {
lineptr = line;
for (;;) {
c = xmon_read_poll();
if (c == -1) {
if (get_tbl() - t0 > timeout)
return 0;
continue;
}
if (c == '\n')
break;
if (c != '\r' && lineptr < &line[sizeof(line) - 1])
*lineptr++ = c;
}
*lineptr = 0;
} while (strstr(line, str) == NULL);
return 1;
}
int xmon_getchar(void)
{
int c;
if (lineleft == 0) {
lineptr = line;
for (;;) {
c = xmon_readchar();
if (c == -1 || c == 4)
break;
if (c == '\r' || c == '\n') {
*lineptr++ = '\n';
xmon_putchar('\n');
break;
}
switch (c) {
case 0177:
case '\b':
if (lineptr > line) {
xmon_putchar('\b');
xmon_putchar(' ');
xmon_putchar('\b');
--lineptr;
}
break;
case 'U' & 0x1F:
while (lineptr > line) {
xmon_putchar('\b');
xmon_putchar(' ');
xmon_putchar('\b');
--lineptr;
}
break;
default:
if (lineptr >= &line[sizeof(line) - 1])
xmon_putchar('\a');
else {
xmon_putchar(c);
*lineptr++ = c;
}
}
}
lineleft = lineptr - line;
lineptr = line;
}
if (lineleft == 0)
return -1;
--lineleft;
return *lineptr++;
}
char *xmon_gets(char *str, int nb)
{
char *p;
int c;
for (p = str; p < str + nb - 1; ) {
c = xmon_getchar();
if (c == -1) {
if (p == str)
return NULL;
break;
}
*p++ = c;
if (c == '\n')
break;
}
*p = 0;
return str;
}
void xmon_printf(const char *format, ...)
{
va_list args;
int n;
static char xmon_outbuf[1024];
va_start(args, format);
n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
va_end(args);
xmon_write(xmon_outbuf, n);
}
typedef int FILE;
extern FILE *xmon_stdin, *xmon_stdout;
#define EOF (-1) #define EOF (-1)
#define stdin xmon_stdin
#define stdout xmon_stdout
#define printf xmon_printf #define printf xmon_printf
#define fprintf xmon_fprintf
#define fputs xmon_fputs
#define fgets xmon_fgets
#define putchar xmon_putchar #define putchar xmon_putchar
#define getchar xmon_getchar
#define putc xmon_putc
#define getc xmon_getc
#define fopen(n, m) NULL
#define fflush(f) do {} while (0)
#define fclose(f) do {} while (0)
extern char *fgets(char *, int, void *);
extern void xmon_printf(const char *, ...);
extern void xmon_fprintf(void *, const char *, ...);
extern void xmon_sprintf(char *, const char *, ...);
#define perror(s) printf("%s: no files!\n", (s)) extern int xmon_putchar(int c);
extern int xmon_getchar(void);
extern char *xmon_gets(char *, int);
extern void xmon_printf(const char *, ...);
extern void xmon_map_scc(void);
extern int xmon_expect(const char *str, unsigned long timeout);
extern int xmon_write(void *ptr, int nb);
extern int xmon_readchar(void);
extern int xmon_read_poll(void);
...@@ -14,61 +14,61 @@ ...@@ -14,61 +14,61 @@
_GLOBAL(xmon_setjmp) _GLOBAL(xmon_setjmp)
mflr r0 mflr r0
STL r0,0(r3) PPC_STL r0,0(r3)
STL r1,SZL(r3) PPC_STL r1,SZL(r3)
STL r2,2*SZL(r3) PPC_STL r2,2*SZL(r3)
mfcr r0 mfcr r0
STL r0,3*SZL(r3) PPC_STL r0,3*SZL(r3)
STL r13,4*SZL(r3) PPC_STL r13,4*SZL(r3)
STL r14,5*SZL(r3) PPC_STL r14,5*SZL(r3)
STL r15,6*SZL(r3) PPC_STL r15,6*SZL(r3)
STL r16,7*SZL(r3) PPC_STL r16,7*SZL(r3)
STL r17,8*SZL(r3) PPC_STL r17,8*SZL(r3)
STL r18,9*SZL(r3) PPC_STL r18,9*SZL(r3)
STL r19,10*SZL(r3) PPC_STL r19,10*SZL(r3)
STL r20,11*SZL(r3) PPC_STL r20,11*SZL(r3)
STL r21,12*SZL(r3) PPC_STL r21,12*SZL(r3)
STL r22,13*SZL(r3) PPC_STL r22,13*SZL(r3)
STL r23,14*SZL(r3) PPC_STL r23,14*SZL(r3)
STL r24,15*SZL(r3) PPC_STL r24,15*SZL(r3)
STL r25,16*SZL(r3) PPC_STL r25,16*SZL(r3)
STL r26,17*SZL(r3) PPC_STL r26,17*SZL(r3)
STL r27,18*SZL(r3) PPC_STL r27,18*SZL(r3)
STL r28,19*SZL(r3) PPC_STL r28,19*SZL(r3)
STL r29,20*SZL(r3) PPC_STL r29,20*SZL(r3)
STL r30,21*SZL(r3) PPC_STL r30,21*SZL(r3)
STL r31,22*SZL(r3) PPC_STL r31,22*SZL(r3)
li r3,0 li r3,0
blr blr
_GLOBAL(xmon_longjmp) _GLOBAL(xmon_longjmp)
CMPI r4,0 PPC_LCMPI r4,0
bne 1f bne 1f
li r4,1 li r4,1
1: LDL r13,4*SZL(r3) 1: PPC_LL r13,4*SZL(r3)
LDL r14,5*SZL(r3) PPC_LL r14,5*SZL(r3)
LDL r15,6*SZL(r3) PPC_LL r15,6*SZL(r3)
LDL r16,7*SZL(r3) PPC_LL r16,7*SZL(r3)
LDL r17,8*SZL(r3) PPC_LL r17,8*SZL(r3)
LDL r18,9*SZL(r3) PPC_LL r18,9*SZL(r3)
LDL r19,10*SZL(r3) PPC_LL r19,10*SZL(r3)
LDL r20,11*SZL(r3) PPC_LL r20,11*SZL(r3)
LDL r21,12*SZL(r3) PPC_LL r21,12*SZL(r3)
LDL r22,13*SZL(r3) PPC_LL r22,13*SZL(r3)
LDL r23,14*SZL(r3) PPC_LL r23,14*SZL(r3)
LDL r24,15*SZL(r3) PPC_LL r24,15*SZL(r3)
LDL r25,16*SZL(r3) PPC_LL r25,16*SZL(r3)
LDL r26,17*SZL(r3) PPC_LL r26,17*SZL(r3)
LDL r27,18*SZL(r3) PPC_LL r27,18*SZL(r3)
LDL r28,19*SZL(r3) PPC_LL r28,19*SZL(r3)
LDL r29,20*SZL(r3) PPC_LL r29,20*SZL(r3)
LDL r30,21*SZL(r3) PPC_LL r30,21*SZL(r3)
LDL r31,22*SZL(r3) PPC_LL r31,22*SZL(r3)
LDL r0,3*SZL(r3) PPC_LL r0,3*SZL(r3)
mtcrf 0x38,r0 mtcrf 0x38,r0
LDL r0,0(r3) PPC_LL r0,0(r3)
LDL r1,SZL(r3) PPC_LL r1,SZL(r3)
LDL r2,2*SZL(r3) PPC_LL r2,2*SZL(r3)
mtlr r0 mtlr r0
mr r3,r4 mr r3,r4
blr blr
...@@ -84,52 +84,52 @@ _GLOBAL(xmon_longjmp) ...@@ -84,52 +84,52 @@ _GLOBAL(xmon_longjmp)
* different ABIs, though). * different ABIs, though).
*/ */
_GLOBAL(xmon_save_regs) _GLOBAL(xmon_save_regs)
STL r0,0*SZL(r3) PPC_STL r0,0*SZL(r3)
STL r2,2*SZL(r3) PPC_STL r2,2*SZL(r3)
STL r3,3*SZL(r3) PPC_STL r3,3*SZL(r3)
STL r4,4*SZL(r3) PPC_STL r4,4*SZL(r3)
STL r5,5*SZL(r3) PPC_STL r5,5*SZL(r3)
STL r6,6*SZL(r3) PPC_STL r6,6*SZL(r3)
STL r7,7*SZL(r3) PPC_STL r7,7*SZL(r3)
STL r8,8*SZL(r3) PPC_STL r8,8*SZL(r3)
STL r9,9*SZL(r3) PPC_STL r9,9*SZL(r3)
STL r10,10*SZL(r3) PPC_STL r10,10*SZL(r3)
STL r11,11*SZL(r3) PPC_STL r11,11*SZL(r3)
STL r12,12*SZL(r3) PPC_STL r12,12*SZL(r3)
STL r13,13*SZL(r3) PPC_STL r13,13*SZL(r3)
STL r14,14*SZL(r3) PPC_STL r14,14*SZL(r3)
STL r15,15*SZL(r3) PPC_STL r15,15*SZL(r3)
STL r16,16*SZL(r3) PPC_STL r16,16*SZL(r3)
STL r17,17*SZL(r3) PPC_STL r17,17*SZL(r3)
STL r18,18*SZL(r3) PPC_STL r18,18*SZL(r3)
STL r19,19*SZL(r3) PPC_STL r19,19*SZL(r3)
STL r20,20*SZL(r3) PPC_STL r20,20*SZL(r3)
STL r21,21*SZL(r3) PPC_STL r21,21*SZL(r3)
STL r22,22*SZL(r3) PPC_STL r22,22*SZL(r3)
STL r23,23*SZL(r3) PPC_STL r23,23*SZL(r3)
STL r24,24*SZL(r3) PPC_STL r24,24*SZL(r3)
STL r25,25*SZL(r3) PPC_STL r25,25*SZL(r3)
STL r26,26*SZL(r3) PPC_STL r26,26*SZL(r3)
STL r27,27*SZL(r3) PPC_STL r27,27*SZL(r3)
STL r28,28*SZL(r3) PPC_STL r28,28*SZL(r3)
STL r29,29*SZL(r3) PPC_STL r29,29*SZL(r3)
STL r30,30*SZL(r3) PPC_STL r30,30*SZL(r3)
STL r31,31*SZL(r3) PPC_STL r31,31*SZL(r3)
/* go up one stack frame for SP */ /* go up one stack frame for SP */
LDL r4,0(r1) PPC_LL r4,0(r1)
STL r4,1*SZL(r3) PPC_STL r4,1*SZL(r3)
/* get caller's LR */ /* get caller's LR */
LDL r0,LRSAVE(r4) PPC_LL r0,LRSAVE(r4)
STL r0,_NIP-STACK_FRAME_OVERHEAD(r3) PPC_STL r0,_NIP-STACK_FRAME_OVERHEAD(r3)
STL r0,_LINK-STACK_FRAME_OVERHEAD(r3) PPC_STL r0,_LINK-STACK_FRAME_OVERHEAD(r3)
mfmsr r0 mfmsr r0
STL r0,_MSR-STACK_FRAME_OVERHEAD(r3) PPC_STL r0,_MSR-STACK_FRAME_OVERHEAD(r3)
mfctr r0 mfctr r0
STL r0,_CTR-STACK_FRAME_OVERHEAD(r3) PPC_STL r0,_CTR-STACK_FRAME_OVERHEAD(r3)
mfxer r0 mfxer r0
STL r0,_XER-STACK_FRAME_OVERHEAD(r3) PPC_STL r0,_XER-STACK_FRAME_OVERHEAD(r3)
mfcr r0 mfcr r0
STL r0,_CCR-STACK_FRAME_OVERHEAD(r3) PPC_STL r0,_CCR-STACK_FRAME_OVERHEAD(r3)
li r0,0 li r0,0
STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3) PPC_STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3)
blr blr
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <linux/cuda.h> #include <linux/cuda.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/sysrq.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <asm/xmon.h> #include <asm/xmon.h>
#include <asm/prom.h> #include <asm/prom.h>
...@@ -22,10 +21,11 @@ ...@@ -22,10 +21,11 @@
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/btext.h> #include <asm/btext.h>
#include <asm/time.h>
#include "nonstdio.h"
static volatile unsigned char __iomem *sccc, *sccd; static volatile unsigned char __iomem *sccc, *sccd;
unsigned int TXRDY, RXRDY, DLAB; unsigned int TXRDY, RXRDY, DLAB;
static int xmon_expect(const char *str, unsigned int timeout);
static int use_serial; static int use_serial;
static int use_screen; static int use_screen;
...@@ -33,16 +33,6 @@ static int via_modem; ...@@ -33,16 +33,6 @@ static int via_modem;
static int xmon_use_sccb; static int xmon_use_sccb;
static struct device_node *channel_node; static struct device_node *channel_node;
#define TB_SPEED 25000000
static inline unsigned int readtb(void)
{
unsigned int ret;
asm volatile("mftb %0" : "=r" (ret) :);
return ret;
}
void buf_access(void) void buf_access(void)
{ {
if (DLAB) if (DLAB)
...@@ -91,23 +81,7 @@ static unsigned long chrp_find_phys_io_base(void) ...@@ -91,23 +81,7 @@ static unsigned long chrp_find_phys_io_base(void)
} }
#endif /* CONFIG_PPC_CHRP */ #endif /* CONFIG_PPC_CHRP */
#ifdef CONFIG_MAGIC_SYSRQ void xmon_map_scc(void)
static void sysrq_handle_xmon(int key, struct pt_regs *regs,
struct tty_struct *tty)
{
xmon(regs);
}
static struct sysrq_key_op sysrq_xmon_op =
{
.handler = sysrq_handle_xmon,
.help_msg = "Xmon",
.action_msg = "Entering xmon",
};
#endif
void
xmon_map_scc(void)
{ {
#ifdef CONFIG_PPC_MULTIPLATFORM #ifdef CONFIG_PPC_MULTIPLATFORM
volatile unsigned char __iomem *base; volatile unsigned char __iomem *base;
...@@ -217,8 +191,6 @@ xmon_map_scc(void) ...@@ -217,8 +191,6 @@ xmon_map_scc(void)
RXRDY = 1; RXRDY = 1;
DLAB = 0x80; DLAB = 0x80;
#endif /* platform */ #endif /* platform */
register_sysrq_key('x', &sysrq_xmon_op);
} }
static int scc_initialized = 0; static int scc_initialized = 0;
...@@ -238,8 +210,7 @@ static inline void do_poll_adb(void) ...@@ -238,8 +210,7 @@ static inline void do_poll_adb(void)
#endif /* CONFIG_ADB_CUDA */ #endif /* CONFIG_ADB_CUDA */
} }
int int xmon_write(void *ptr, int nb)
xmon_write(void *handle, void *ptr, int nb)
{ {
char *p = ptr; char *p = ptr;
int i, c, ct; int i, c, ct;
...@@ -311,8 +282,7 @@ static unsigned char xmon_shift_keytab[128] = ...@@ -311,8 +282,7 @@ static unsigned char xmon_shift_keytab[128] =
"\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
"\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
static int static int xmon_get_adb_key(void)
xmon_get_adb_key(void)
{ {
int k, t, on; int k, t, on;
...@@ -350,32 +320,21 @@ xmon_get_adb_key(void) ...@@ -350,32 +320,21 @@ xmon_get_adb_key(void)
} }
#endif /* CONFIG_BOOTX_TEXT */ #endif /* CONFIG_BOOTX_TEXT */
int int xmon_readchar(void)
xmon_read(void *handle, void *ptr, int nb)
{ {
char *p = ptr;
int i;
#ifdef CONFIG_BOOTX_TEXT #ifdef CONFIG_BOOTX_TEXT
if (use_screen) { if (use_screen)
for (i = 0; i < nb; ++i) return xmon_get_adb_key();
*p++ = xmon_get_adb_key();
return i;
}
#endif #endif
if (!scc_initialized) if (!scc_initialized)
xmon_init_scc(); xmon_init_scc();
for (i = 0; i < nb; ++i) {
while ((*sccc & RXRDY) == 0) while ((*sccc & RXRDY) == 0)
do_poll_adb(); do_poll_adb();
buf_access(); buf_access();
*p++ = *sccd; return *sccd;
}
return i;
} }
int int xmon_read_poll(void)
xmon_read_poll(void)
{ {
if ((*sccc & RXRDY) == 0) { if ((*sccc & RXRDY) == 0) {
do_poll_adb(); do_poll_adb();
...@@ -395,8 +354,7 @@ static unsigned char scc_inittab[] = { ...@@ -395,8 +354,7 @@ static unsigned char scc_inittab[] = {
3, 0xc1, /* rx enable, 8 bits */ 3, 0xc1, /* rx enable, 8 bits */
}; };
void void xmon_init_scc(void)
xmon_init_scc(void)
{ {
if ( _machine == _MACH_chrp ) if ( _machine == _MACH_chrp )
{ {
...@@ -410,6 +368,7 @@ xmon_init_scc(void) ...@@ -410,6 +368,7 @@ xmon_init_scc(void)
else if ( _machine == _MACH_Pmac ) else if ( _machine == _MACH_Pmac )
{ {
int i, x; int i, x;
unsigned long timeout;
if (channel_node != 0) if (channel_node != 0)
pmac_call_feature( pmac_call_feature(
...@@ -424,8 +383,12 @@ xmon_init_scc(void) ...@@ -424,8 +383,12 @@ xmon_init_scc(void)
PMAC_FTR_MODEM_ENABLE, PMAC_FTR_MODEM_ENABLE,
channel_node, 0, 1); channel_node, 0, 1);
printk(KERN_INFO "Modem powered up by debugger !\n"); printk(KERN_INFO "Modem powered up by debugger !\n");
t0 = readtb(); t0 = get_tbl();
while (readtb() - t0 < 3*TB_SPEED) timeout = 3 * tb_ticks_per_sec;
if (timeout == 0)
/* assume 25MHz if tb_ticks_per_sec not set */
timeout = 75000000;
while (get_tbl() - t0 < timeout)
eieio(); eieio();
} }
/* use the B channel if requested */ /* use the B channel if requested */
...@@ -447,164 +410,19 @@ xmon_init_scc(void) ...@@ -447,164 +410,19 @@ xmon_init_scc(void)
scc_initialized = 1; scc_initialized = 1;
if (via_modem) { if (via_modem) {
for (;;) { for (;;) {
xmon_write(NULL, "ATE1V1\r", 7); xmon_write("ATE1V1\r", 7);
if (xmon_expect("OK", 5)) { if (xmon_expect("OK", 5)) {
xmon_write(NULL, "ATA\r", 4); xmon_write("ATA\r", 4);
if (xmon_expect("CONNECT", 40)) if (xmon_expect("CONNECT", 40))
break; break;
} }
xmon_write(NULL, "+++", 3); xmon_write("+++", 3);
xmon_expect("OK", 3); xmon_expect("OK", 3);
} }
} }
} }
void *xmon_stdin; void xmon_enter(void)
void *xmon_stdout;
void *xmon_stderr;
int xmon_putc(int c, void *f)
{
char ch = c;
if (c == '\n')
xmon_putc('\r', f);
return xmon_write(f, &ch, 1) == 1? c: -1;
}
int xmon_putchar(int c)
{
return xmon_putc(c, xmon_stdout);
}
int xmon_fputs(char *str, void *f)
{
int n = strlen(str);
return xmon_write(f, str, n) == n? 0: -1;
}
int
xmon_readchar(void)
{
char ch;
for (;;) {
switch (xmon_read(xmon_stdin, &ch, 1)) {
case 1:
return ch;
case -1:
xmon_printf("read(stdin) returned -1\r\n", 0, 0);
return -1;
}
}
}
static char line[256];
static char *lineptr;
static int lineleft;
int xmon_expect(const char *str, unsigned int timeout)
{
int c;
unsigned int t0;
timeout *= TB_SPEED;
t0 = readtb();
do {
lineptr = line;
for (;;) {
c = xmon_read_poll();
if (c == -1) {
if (readtb() - t0 > timeout)
return 0;
continue;
}
if (c == '\n')
break;
if (c != '\r' && lineptr < &line[sizeof(line) - 1])
*lineptr++ = c;
}
*lineptr = 0;
} while (strstr(line, str) == NULL);
return 1;
}
int
xmon_getchar(void)
{
int c;
if (lineleft == 0) {
lineptr = line;
for (;;) {
c = xmon_readchar();
if (c == -1 || c == 4)
break;
if (c == '\r' || c == '\n') {
*lineptr++ = '\n';
xmon_putchar('\n');
break;
}
switch (c) {
case 0177:
case '\b':
if (lineptr > line) {
xmon_putchar('\b');
xmon_putchar(' ');
xmon_putchar('\b');
--lineptr;
}
break;
case 'U' & 0x1F:
while (lineptr > line) {
xmon_putchar('\b');
xmon_putchar(' ');
xmon_putchar('\b');
--lineptr;
}
break;
default:
if (lineptr >= &line[sizeof(line) - 1])
xmon_putchar('\a');
else {
xmon_putchar(c);
*lineptr++ = c;
}
}
}
lineleft = lineptr - line;
lineptr = line;
}
if (lineleft == 0)
return -1;
--lineleft;
return *lineptr++;
}
char *
xmon_fgets(char *str, int nb, void *f)
{
char *p;
int c;
for (p = str; p < str + nb - 1; ) {
c = xmon_getchar();
if (c == -1) {
if (p == str)
return NULL;
break;
}
*p++ = c;
if (c == '\n')
break;
}
*p = 0;
return str;
}
void
xmon_enter(void)
{ {
#ifdef CONFIG_ADB_PMU #ifdef CONFIG_ADB_PMU
if (_machine == _MACH_Pmac) { if (_machine == _MACH_Pmac) {
...@@ -613,8 +431,7 @@ xmon_enter(void) ...@@ -613,8 +431,7 @@ xmon_enter(void)
#endif #endif
} }
void void xmon_leave(void)
xmon_leave(void)
{ {
#ifdef CONFIG_ADB_PMU #ifdef CONFIG_ADB_PMU
if (_machine == _MACH_Pmac) { if (_machine == _MACH_Pmac) {
......
...@@ -6,182 +6,29 @@ ...@@ -6,182 +6,29 @@
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#include <linux/config.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/sysrq.h>
#include <linux/init.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/io.h>
#include <asm/page.h>
#include <asm/prom.h>
#include <asm/processor.h>
#include <asm/udbg.h> #include <asm/udbg.h>
#include <asm/system.h>
#include "nonstdio.h" #include "nonstdio.h"
#ifdef CONFIG_MAGIC_SYSRQ void xmon_map_scc(void)
static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
struct tty_struct *tty)
{ {
/* ensure xmon is enabled */
xmon_init(1);
debugger(pt_regs);
} }
static struct sysrq_key_op sysrq_xmon_op = int xmon_write(void *ptr, int nb)
{
.handler = sysrq_handle_xmon,
.help_msg = "Xmon",
.action_msg = "Entering xmon",
};
static int __init setup_xmon_sysrq(void)
{
register_sysrq_key('x', &sysrq_xmon_op);
return 0;
}
__initcall(setup_xmon_sysrq);
#endif /* CONFIG_MAGIC_SYSRQ */
int
xmon_write(void *handle, void *ptr, int nb)
{ {
return udbg_write(ptr, nb); return udbg_write(ptr, nb);
} }
int int xmon_readchar(void)
xmon_read(void *handle, void *ptr, int nb)
{ {
return udbg_read(ptr, nb); if (udbg_getc)
return udbg_getc();
return -1;
} }
int int xmon_read_poll(void)
xmon_read_poll(void)
{ {
if (udbg_getc_poll) if (udbg_getc_poll)
return udbg_getc_poll(); return udbg_getc_poll();
return -1; return -1;
} }
FILE *xmon_stdin;
FILE *xmon_stdout;
int
xmon_putc(int c, void *f)
{
char ch = c;
if (c == '\n')
xmon_putc('\r', f);
return xmon_write(f, &ch, 1) == 1? c: -1;
}
int
xmon_putchar(int c)
{
return xmon_putc(c, xmon_stdout);
}
int
xmon_fputs(char *str, void *f)
{
int n = strlen(str);
return xmon_write(f, str, n) == n? 0: -1;
}
int
xmon_readchar(void)
{
char ch;
for (;;) {
switch (xmon_read(xmon_stdin, &ch, 1)) {
case 1:
return ch;
case -1:
xmon_printf("read(stdin) returned -1\r\n", 0, 0);
return -1;
}
}
}
static char line[256];
static char *lineptr;
static int lineleft;
int
xmon_getchar(void)
{
int c;
if (lineleft == 0) {
lineptr = line;
for (;;) {
c = xmon_readchar();
if (c == -1 || c == 4)
break;
if (c == '\r' || c == '\n') {
*lineptr++ = '\n';
xmon_putchar('\n');
break;
}
switch (c) {
case 0177:
case '\b':
if (lineptr > line) {
xmon_putchar('\b');
xmon_putchar(' ');
xmon_putchar('\b');
--lineptr;
}
break;
case 'U' & 0x1F:
while (lineptr > line) {
xmon_putchar('\b');
xmon_putchar(' ');
xmon_putchar('\b');
--lineptr;
}
break;
default:
if (lineptr >= &line[sizeof(line) - 1])
xmon_putchar('\a');
else {
xmon_putchar(c);
*lineptr++ = c;
}
}
}
lineleft = lineptr - line;
lineptr = line;
}
if (lineleft == 0)
return -1;
--lineleft;
return *lineptr++;
}
char *
xmon_fgets(char *str, int nb, void *f)
{
char *p;
int c;
for (p = str; p < str + nb - 1; ) {
c = xmon_getchar();
if (c == -1) {
if (p == str)
return NULL;
break;
}
*p++ = c;
if (c == '\n')
break;
}
*p = 0;
return str;
}
...@@ -15,273 +15,30 @@ ...@@ -15,273 +15,30 @@
#include <asm/8xx_immap.h> #include <asm/8xx_immap.h>
#include <asm/mpc8xx.h> #include <asm/mpc8xx.h>
#include <asm/commproc.h> #include <asm/commproc.h>
#include "nonstdio.h"
extern void xmon_printf(const char *fmt, ...);
extern int xmon_8xx_write(char *str, int nb); extern int xmon_8xx_write(char *str, int nb);
extern int xmon_8xx_read_poll(void); extern int xmon_8xx_read_poll(void);
extern int xmon_8xx_read_char(void); extern int xmon_8xx_read_char(void);
void prom_drawhex(uint);
void prom_drawstring(const char *str);
static int use_screen = 1; /* default */ void xmon_map_scc(void)
#define TB_SPEED 25000000
static inline unsigned int readtb(void)
{
unsigned int ret;
asm volatile("mftb %0" : "=r" (ret) :);
return ret;
}
void buf_access(void)
{
}
void
xmon_map_scc(void)
{ {
cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
use_screen = 0;
prom_drawstring("xmon uses serial port\n");
} }
static int scc_initialized = 0;
void xmon_init_scc(void); void xmon_init_scc(void);
int int xmon_write(void *ptr, int nb)
xmon_write(void *handle, void *ptr, int nb)
{ {
char *p = ptr;
int i, c, ct;
if (!scc_initialized)
xmon_init_scc();
return(xmon_8xx_write(ptr, nb)); return(xmon_8xx_write(ptr, nb));
} }
int xmon_wants_key; int xmon_readchar(void)
int
xmon_read(void *handle, void *ptr, int nb)
{ {
char *p = ptr; return xmon_8xx_read_char();
int i;
if (!scc_initialized)
xmon_init_scc();
for (i = 0; i < nb; ++i) {
*p++ = xmon_8xx_read_char();
}
return i;
} }
int int xmon_read_poll(void)
xmon_read_poll(void)
{ {
return(xmon_8xx_read_poll()); return(xmon_8xx_read_poll());
} }
void
xmon_init_scc()
{
scc_initialized = 1;
}
#if 0
extern int (*prom_entry)(void *);
int
xmon_exit(void)
{
struct prom_args {
char *service;
} args;
for (;;) {
args.service = "exit";
(*prom_entry)(&args);
}
}
#endif
void *xmon_stdin;
void *xmon_stdout;
void *xmon_stderr;
void
xmon_init(void)
{
}
int
xmon_putc(int c, void *f)
{
char ch = c;
if (c == '\n')
xmon_putc('\r', f);
return xmon_write(f, &ch, 1) == 1? c: -1;
}
int
xmon_putchar(int c)
{
return xmon_putc(c, xmon_stdout);
}
int
xmon_fputs(char *str, void *f)
{
int n = strlen(str);
return xmon_write(f, str, n) == n? 0: -1;
}
int
xmon_readchar(void)
{
char ch;
for (;;) {
switch (xmon_read(xmon_stdin, &ch, 1)) {
case 1:
return ch;
case -1:
xmon_printf("read(stdin) returned -1\r\n", 0, 0);
return -1;
}
}
}
static char line[256];
static char *lineptr;
static int lineleft;
#if 0
int xmon_expect(const char *str, unsigned int timeout)
{
int c;
unsigned int t0;
timeout *= TB_SPEED;
t0 = readtb();
do {
lineptr = line;
for (;;) {
c = xmon_read_poll();
if (c == -1) {
if (readtb() - t0 > timeout)
return 0;
continue;
}
if (c == '\n')
break;
if (c != '\r' && lineptr < &line[sizeof(line) - 1])
*lineptr++ = c;
}
*lineptr = 0;
} while (strstr(line, str) == NULL);
return 1;
}
#endif
int
xmon_getchar(void)
{
int c;
if (lineleft == 0) {
lineptr = line;
for (;;) {
c = xmon_readchar();
if (c == -1 || c == 4)
break;
if (c == '\r' || c == '\n') {
*lineptr++ = '\n';
xmon_putchar('\n');
break;
}
switch (c) {
case 0177:
case '\b':
if (lineptr > line) {
xmon_putchar('\b');
xmon_putchar(' ');
xmon_putchar('\b');
--lineptr;
}
break;
case 'U' & 0x1F:
while (lineptr > line) {
xmon_putchar('\b');
xmon_putchar(' ');
xmon_putchar('\b');
--lineptr;
}
break;
default:
if (lineptr >= &line[sizeof(line) - 1])
xmon_putchar('\a');
else {
xmon_putchar(c);
*lineptr++ = c;
}
}
}
lineleft = lineptr - line;
lineptr = line;
}
if (lineleft == 0)
return -1;
--lineleft;
return *lineptr++;
}
char *
xmon_fgets(char *str, int nb, void *f)
{
char *p;
int c;
for (p = str; p < str + nb - 1; ) {
c = xmon_getchar();
if (c == -1) {
if (p == str)
return 0;
break;
}
*p++ = c;
if (c == '\n')
break;
}
*p = 0;
return str;
}
void
prom_drawhex(uint val)
{
unsigned char buf[10];
int i;
for (i = 7; i >= 0; i--)
{
buf[i] = "0123456789abcdef"[val & 0x0f];
val >>= 4;
}
buf[8] = '\0';
xmon_fputs(buf, xmon_stdout);
}
void
prom_drawstring(const char *str)
{
xmon_fputs(str, xmon_stdout);
}
/*
* Written by Cort Dougan to replace the version originally used
* by Paul Mackerras, which came from NetBSD and thus had copyright
* conflicts with Linux.
*
* This file makes liberal use of the standard linux utility
* routines to reduce the size of the binary. We assume we can
* trust some parts of Linux inside the debugger.
* -- Cort (cort@cs.nmt.edu)
*
* Copyright (C) 1999 Cort Dougan.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/module.h>
#include <stdarg.h>
#include "nonstdio.h"
extern int xmon_write(void *, void *, int);
void xmon_vfprintf(void *f, const char *fmt, va_list ap)
{
static char xmon_buf[2048];
int n;
n = vsprintf(xmon_buf, fmt, ap);
xmon_write(f, xmon_buf, n);
}
void xmon_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
xmon_vfprintf(stdout, fmt, ap);
va_end(ap);
}
EXPORT_SYMBOL(xmon_printf);
void xmon_fprintf(void *f, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
xmon_vfprintf(f, fmt, ap);
va_end(ap);
}
/* /*
* Routines providing a simple monitor for use on the PowerMac. * Routines providing a simple monitor for use on the PowerMac.
* *
* Copyright (C) 1996 Paul Mackerras. * Copyright (C) 1996-2005 Paul Mackerras.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/kallsyms.h> #include <linux/kallsyms.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/sysrq.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/string.h> #include <asm/string.h>
...@@ -144,15 +145,10 @@ static void xmon_print_symbol(unsigned long address, const char *mid, ...@@ -144,15 +145,10 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
static const char *getvecname(unsigned long vec); static const char *getvecname(unsigned long vec);
extern int print_insn_powerpc(unsigned long, unsigned long, int); extern int print_insn_powerpc(unsigned long, unsigned long, int);
extern void printf(const char *fmt, ...);
extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
extern int xmon_putc(int c, void *f);
extern int putchar(int ch);
extern void xmon_enter(void); extern void xmon_enter(void);
extern void xmon_leave(void); extern void xmon_leave(void);
extern int xmon_read_poll(void);
extern long setjmp(long *); extern long setjmp(long *);
extern void longjmp(long *, long); extern void longjmp(long *, long);
extern void xmon_save_regs(struct pt_regs *); extern void xmon_save_regs(struct pt_regs *);
...@@ -748,7 +744,6 @@ cmds(struct pt_regs *excp) ...@@ -748,7 +744,6 @@ cmds(struct pt_regs *excp)
printf("%x:", smp_processor_id()); printf("%x:", smp_processor_id());
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
printf("mon> "); printf("mon> ");
fflush(stdout);
flush_input(); flush_input();
termch = 0; termch = 0;
cmd = skipbl(); cmd = skipbl();
...@@ -1797,7 +1792,7 @@ memex(void) ...@@ -1797,7 +1792,7 @@ memex(void)
for(;;){ for(;;){
if (!mnoread) if (!mnoread)
n = mread(adrs, val, size); n = mread(adrs, val, size);
printf("%.16x%c", adrs, brev? 'r': ' '); printf(REG"%c", adrs, brev? 'r': ' ');
if (!mnoread) { if (!mnoread) {
if (brev) if (brev)
byterev(val, size); byterev(val, size);
...@@ -1976,17 +1971,18 @@ prdump(unsigned long adrs, long ndump) ...@@ -1976,17 +1971,18 @@ prdump(unsigned long adrs, long ndump)
nr = mread(adrs, temp, r); nr = mread(adrs, temp, r);
adrs += nr; adrs += nr;
for (m = 0; m < r; ++m) { for (m = 0; m < r; ++m) {
if ((m & 7) == 0 && m > 0) if ((m & (sizeof(long) - 1)) == 0 && m > 0)
putchar(' '); putchar(' ');
if (m < nr) if (m < nr)
printf("%.2x", temp[m]); printf("%.2x", temp[m]);
else else
printf("%s", fault_chars[fault_type]); printf("%s", fault_chars[fault_type]);
} }
if (m <= 8) for (; m < 16; ++m) {
printf(" "); if ((m & (sizeof(long) - 1)) == 0)
for (; m < 16; ++m) putchar(' ');
printf(" "); printf(" ");
}
printf(" |"); printf(" |");
for (m = 0; m < r; ++m) { for (m = 0; m < r; ++m) {
if (m < nr) { if (m < nr) {
...@@ -2151,7 +2147,6 @@ memzcan(void) ...@@ -2151,7 +2147,6 @@ memzcan(void)
ok = mread(a, &v, 1); ok = mread(a, &v, 1);
if (ok && !ook) { if (ok && !ook) {
printf("%.8x .. ", a); printf("%.8x .. ", a);
fflush(stdout);
} else if (!ok && ook) } else if (!ok && ook)
printf("%.8x\n", a - mskip); printf("%.8x\n", a - mskip);
ook = ok; ook = ok;
...@@ -2372,7 +2367,7 @@ int ...@@ -2372,7 +2367,7 @@ int
inchar(void) inchar(void)
{ {
if (lineptr == NULL || *lineptr == 0) { if (lineptr == NULL || *lineptr == 0) {
if (fgets(line, sizeof(line), stdin) == NULL) { if (xmon_gets(line, sizeof(line)) == NULL) {
lineptr = NULL; lineptr = NULL;
return EOF; return EOF;
} }
...@@ -2526,4 +2521,29 @@ void xmon_init(int enable) ...@@ -2526,4 +2521,29 @@ void xmon_init(int enable)
__debugger_dabr_match = NULL; __debugger_dabr_match = NULL;
__debugger_fault_handler = NULL; __debugger_fault_handler = NULL;
} }
xmon_map_scc();
}
#ifdef CONFIG_MAGIC_SYSRQ
static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
struct tty_struct *tty)
{
/* ensure xmon is enabled */
xmon_init(1);
debugger(pt_regs);
}
static struct sysrq_key_op sysrq_xmon_op =
{
.handler = sysrq_handle_xmon,
.help_msg = "Xmon",
.action_msg = "Entering xmon",
};
static int __init setup_xmon_sysrq(void)
{
register_sysrq_key('x', &sysrq_xmon_op);
return 0;
} }
__initcall(setup_xmon_sysrq);
#endif /* CONFIG_MAGIC_SYSRQ */
...@@ -19,6 +19,9 @@ extern prom_entry of_prom_entry; ...@@ -19,6 +19,9 @@ extern prom_entry of_prom_entry;
/* function declarations */ /* function declarations */
int call_prom(const char *service, int nargs, int nret, ...);
int call_prom_ret(const char *service, int nargs, int nret,
unsigned int *rets, ...);
void * claim(unsigned int virt, unsigned int size, unsigned int align); void * claim(unsigned int virt, unsigned int size, unsigned int align);
int map(unsigned int phys, unsigned int virt, unsigned int size); int map(unsigned int phys, unsigned int virt, unsigned int size);
void enter(void); void enter(void);
......
...@@ -3,4 +3,4 @@ ...@@ -3,4 +3,4 @@
# #
lib-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o \ lib-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o \
ofstdio.o read.o release.o write.o map.o ofstdio.o read.o release.o write.o map.o call_prom.o
/*
* Copyright (C) 1996-2005 Paul Mackerras.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include "of1275.h"
#include <stdarg.h>
int call_prom(const char *service, int nargs, int nret, ...)
{
int i;
struct prom_args {
const char *service;
int nargs;
int nret;
unsigned int args[12];
} args;
va_list list;
args.service = service;
args.nargs = nargs;
args.nret = nret;
va_start(list, nret);
for (i = 0; i < nargs; i++)
args.args[i] = va_arg(list, unsigned int);
va_end(list);
for (i = 0; i < nret; i++)
args.args[nargs+i] = 0;
if (of_prom_entry(&args) < 0)
return -1;
return (nret > 0)? args.args[nargs]: 0;
}
int call_prom_ret(const char *service, int nargs, int nret,
unsigned int *rets, ...)
{
int i;
struct prom_args {
const char *service;
int nargs;
int nret;
unsigned int args[12];
} args;
va_list list;
args.service = service;
args.nargs = nargs;
args.nret = nret;
va_start(list, rets);
for (i = 0; i < nargs; i++)
args.args[i] = va_arg(list, unsigned int);
va_end(list);
for (i = 0; i < nret; i++)
args.args[nargs+i] = 0;
if (of_prom_entry(&args) < 0)
return -1;
if (rets != (void *) 0)
for (i = 1; i < nret; ++i)
rets[i-1] = args.args[nargs+i];
return (nret > 0)? args.args[nargs]: 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment